OmniSciDB  04ee39c94c
anonymous_namespace{RelAlgExecutor.cpp} Namespace Reference

Classes

class  RexUsedInputsVisitor
 

Functions

bool node_is_aggregate (const RelAlgNode *ra)
 
std::unordered_set< int > get_physical_table_ids (const std::unordered_set< PhysicalInput > &phys_inputs)
 
std::unordered_set< PhysicalInputget_physical_inputs (const Catalog_Namespace::Catalog &cat, const RelAlgNode *ra)
 
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, const Catalog_Namespace::Catalog &cat)
 
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_used_inputs (const RelAggregate *aggregate, const Catalog_Namespace::Catalog &cat)
 
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_used_inputs (const RelProject *project, const Catalog_Namespace::Catalog &cat)
 
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_used_inputs (const RelFilter *filter, const Catalog_Namespace::Catalog &cat)
 
int table_id_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, const Catalog_Namespace::Catalog &cat)
 
std::vector< const RelAlgNode * > get_non_join_sequence (const RelAlgNode *ra)
 
void collect_used_input_desc (std::vector< InputDescriptor > &input_descs, const Catalog_Namespace::Catalog &cat, 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, const Catalog_Namespace::Catalog &cat)
 
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, const Catalog_Namespace::Catalog &cat)
 
size_t get_scalar_sources_size (const RelCompound *compound)
 
size_t get_scalar_sources_size (const RelProject *project)
 
const RexScalarscalar_at (const size_t i, const RelCompound *compound)
 
const RexScalarscalar_at (const size_t i, const RelProject *project)
 
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)
 
template<class RA >
std::vector< std::shared_ptr< Analyzer::Expr > > translate_scalar_sources (const RA *ra_node, const RelAlgTranslator &translator)
 
std::shared_ptr< Analyzer::Exprcast_to_column_type (std::shared_ptr< Analyzer::Expr > expr, int32_t tableId, const Catalog_Namespace::Catalog &cat, const std::string &colName)
 
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, 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)
 
std::vector< Analyzer::Expr * > translate_targets (std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned, 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)
 
std::vector< Analyzer::Expr * > translate_targets_for_update (std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned, 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, int32_t tableId, const Catalog_Namespace::Catalog &cat, const ColumnNameList &colNames, size_t starting_projection_column_idx)
 
bool is_count_distinct (const Analyzer::Expr *expr)
 
std::vector< TargetMetaInfoget_modify_manipulated_targets_meta (ModifyManipulationTarget const *manip_node, const std::vector< Analyzer::Expr *> &target_exprs)
 
template<class RA >
std::vector< TargetMetaInfoget_targets_meta (const RA *ra_node, 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)
 
std::list< Analyzer::OrderEntryget_order_entries (const RelSort *sort)
 
size_t get_scan_limit (const RelAlgNode *ra, const size_t limit)
 
bool first_oe_is_desc (const std::list< Analyzer::OrderEntry > &order_entries)
 
size_t groups_approx_upper_bound (const std::vector< InputTableInfo > &table_infos)
 
bool 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)
 
void build_render_targets (RenderInfo &render_info, const std::vector< Analyzer::Expr *> &work_unit_target_exprs, const std::vector< std::shared_ptr< Analyzer::Expr >> &owned_target_exprs, const std::vector< TargetMetaInfo > &targets_meta)
 
bool can_use_bump_allocator (const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo)
 
JoinType get_join_type (const RelAlgNode *ra)
 
std::unique_ptr< const RexOperatorget_bitwise_equals (const RexScalar *scalar)
 
std::unique_ptr< const RexOperatorget_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::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

◆ build_logical_expression()

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

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

Referenced by reverse_logical_distribution().

2668  {
2669  CHECK(!factors.empty());
2670  auto acc = factors.front();
2671  for (size_t i = 1; i < factors.size(); ++i) {
2672  acc = Parser::OperExpr::normalize(sql_op, kONE, acc, factors[i]);
2673  }
2674  return acc;
2675 }
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)
Definition: ParserNode.cpp:257
Definition: sqldefs.h:69
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ build_render_targets()

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

Definition at line 1850 of file RelAlgExecutor.cpp.

References CHECK, CHECK_EQ, CHECK_LT, and RenderInfo::targets.

Referenced by RelAlgExecutor::executeWorkUnit().

1854  {
1855  CHECK_EQ(work_unit_target_exprs.size(), targets_meta.size());
1856  render_info.targets.clear();
1857  for (size_t i = 0; i < targets_meta.size(); ++i) {
1858  // TODO(croot): find a better way to iterate through these or a better data
1859  // structure for faster lookup to avoid the double for-loop. These vectors should
1860  // be small tho and have no real impact on performance.
1861  size_t j{0};
1862  for (j = 0; j < owned_target_exprs.size(); ++j) {
1863  if (owned_target_exprs[j].get() == work_unit_target_exprs[i]) {
1864  break;
1865  }
1866  }
1867  CHECK_LT(j, owned_target_exprs.size());
1868 
1869  const auto& meta_ti = targets_meta[i].get_physical_type_info();
1870  const auto& expr_ti = owned_target_exprs[j]->get_type_info();
1871  CHECK(meta_ti == expr_ti) << targets_meta[i].get_resname() << " " << i << "," << j
1872  << ", targets meta: " << meta_ti.get_type_name() << "("
1873  << meta_ti.get_compression_name()
1874  << "), target_expr: " << expr_ti.get_type_name() << "("
1875  << expr_ti.get_compression_name() << ")";
1876  render_info.targets.emplace_back(std::make_shared<Analyzer::TargetEntry>(
1877  targets_meta[i].get_resname(), owned_target_exprs[j], false));
1878  }
1879 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::vector< std::shared_ptr< Analyzer::TargetEntry > > targets
Definition: RenderInfo.h:38
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the caller graph for this function:

◆ can_use_bump_allocator()

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

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

1883  {
1885  !eo.output_columnar_hint && ra_exe_unit.sort_info.order_entries.empty();
1886 }
const std::list< Analyzer::OrderEntry > order_entries
const SortInfo sort_info
bool g_enable_bump_allocator
Definition: Execute.cpp:96
const bool output_columnar_hint
ExecutorDeviceType device_type_
+ Here is the caller graph for this function:

◆ cast_to_column_type()

std::shared_ptr<Analyzer::Expr> anonymous_namespace{RelAlgExecutor.cpp}::cast_to_column_type ( std::shared_ptr< Analyzer::Expr expr,
int32_t  tableId,
const Catalog_Namespace::Catalog cat,
const std::string &  colName 
)

Definition at line 870 of file RelAlgExecutor.cpp.

References ColumnDescriptor::columnType, get_logical_type_info(), and Catalog_Namespace::Catalog::getMetadataForColumn().

Referenced by translate_scalar_sources_for_update(), and translate_targets_for_update().

873  {
874  const auto cd = *cat.getMetadataForColumn(tableId, colName);
875 
876  auto cast_ti = cd.columnType;
877 
878  // Type needs to be scrubbed because otherwise NULL values could get cut off or
879  // truncated
880  auto cast_logical_ti = get_logical_type_info(cast_ti);
881  if (cast_logical_ti.is_varlen() && cast_logical_ti.is_array()) {
882  return expr;
883  }
884 
885  // CastIR.cpp Executor::codegenCast() doesn't know how to cast from a ColumnVar
886  // so it CHECK's unless casting is skipped here.
887  if (std::dynamic_pointer_cast<Analyzer::ColumnVar>(expr)) {
888  return expr;
889  }
890 
891  // Cast the expression to match the type of the output column.
892  return expr->add_cast(cast_logical_ti);
893 }
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:840
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
SQLTypeInfo columnType
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ collect_used_input_desc()

void anonymous_namespace{RelAlgExecutor.cpp}::collect_used_input_desc ( std::vector< InputDescriptor > &  input_descs,
const Catalog_Namespace::Catalog cat,
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 703 of file RelAlgExecutor.cpp.

References get_data_sink(), get_non_join_sequence(), Catalog_Namespace::Catalog::getColumnIdBySpi(), and table_id_from_ra().

Referenced by get_input_desc_impl().

709  {
710  std::unordered_set<InputDescriptor> input_descs_unique(input_descs.begin(),
711  input_descs.end());
712  const auto non_join_src_seq = get_non_join_sequence(get_data_sink(ra_node));
713  std::unordered_map<const RelAlgNode*, int> non_join_to_nest_level;
714  for (const auto node : non_join_src_seq) {
715  non_join_to_nest_level.insert(std::make_pair(node, non_join_to_nest_level.size()));
716  }
717  for (const auto used_input : source_used_inputs) {
718  const auto input_ra = used_input->getSourceNode();
719  const int table_id = table_id_from_ra(input_ra);
720  const auto col_id = used_input->getIndex();
721  auto it = input_to_nest_level.find(input_ra);
722  if (it == input_to_nest_level.end()) {
723  throw std::runtime_error("Bushy joins not supported");
724  }
725  const int input_desc = it->second;
726  input_col_descs_unique.insert(std::make_shared<const InputColDescriptor>(
727  dynamic_cast<const RelScan*>(input_ra)
728  ? cat.getColumnIdBySpi(table_id, col_id + 1)
729  : col_id,
730  table_id,
731  input_desc));
732  }
733 }
int table_id_from_ra(const RelAlgNode *ra_node)
const int getColumnIdBySpi(const int tableId, const size_t spi) const
Definition: Catalog.cpp:1430
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)
std::vector< const RelAlgNode * > get_non_join_sequence(const RelAlgNode *ra)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compute_output_buffer_size()

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

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

Referenced by RelAlgExecutor::executeWorkUnit().

1762  {
1763  for (const auto target_expr : ra_exe_unit.target_exprs) {
1764  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
1765  return false;
1766  }
1767  }
1768  if (ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
1769  (!ra_exe_unit.scan_limit || ra_exe_unit.scan_limit > Executor::high_scan_limit)) {
1770  return true;
1771  }
1772  return false;
1773 }
std::vector< Analyzer::Expr * > target_exprs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
static const size_t high_scan_limit
Definition: Execute.h:465
+ Here is the caller graph for this function:

◆ decide_approx_count_distinct_implementation()

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

1785  {
1786  RelAlgExecutionUnit ra_exe_unit = ra_exe_unit_in;
1787  for (size_t i = 0; i < ra_exe_unit.target_exprs.size(); ++i) {
1788  const auto target_expr = ra_exe_unit.target_exprs[i];
1789  const auto agg_info = get_target_info(target_expr, g_bigint_count);
1790  if (agg_info.agg_kind != kAPPROX_COUNT_DISTINCT) {
1791  continue;
1792  }
1793  CHECK(dynamic_cast<const Analyzer::AggExpr*>(target_expr));
1794  const auto arg = static_cast<Analyzer::AggExpr*>(target_expr)->get_own_arg();
1795  CHECK(arg);
1796  const auto& arg_ti = arg->get_type_info();
1797  // Avoid calling getExpressionRange for variable length types (string and array),
1798  // it'd trigger an assertion since that API expects to be called only for types
1799  // for which the notion of range is well-defined. A bit of a kludge, but the
1800  // logic to reject these types anyway is at lower levels in the stack and not
1801  // really worth pulling into a separate function for now.
1802  if (!(arg_ti.is_number() || arg_ti.is_boolean() || arg_ti.is_time() ||
1803  (arg_ti.is_string() && arg_ti.get_compression() == kENCODING_DICT))) {
1804  continue;
1805  }
1806  const auto arg_range = getExpressionRange(arg.get(), table_infos, executor);
1807  if (arg_range.getType() != ExpressionRangeType::Integer) {
1808  continue;
1809  }
1810  // When running distributed, the threshold for using the precise implementation
1811  // must be consistent across all leaves, otherwise we could have a mix of precise
1812  // and approximate bitmaps and we cannot aggregate them.
1813  const auto device_type = g_cluster ? ExecutorDeviceType::GPU : device_type_in;
1814  const auto bitmap_sz_bits = arg_range.getIntMax() - arg_range.getIntMin() + 1;
1815  const auto sub_bitmap_count =
1816  get_count_distinct_sub_bitmap_count(bitmap_sz_bits, ra_exe_unit, device_type);
1817  int64_t approx_bitmap_sz_bits{0};
1818  const auto error_rate =
1819  static_cast<Analyzer::AggExpr*>(target_expr)->get_error_rate();
1820  if (error_rate) {
1821  CHECK(error_rate->get_type_info().get_type() == kINT);
1822  CHECK_GE(error_rate->get_constval().intval, 1);
1823  approx_bitmap_sz_bits = hll_size_for_rate(error_rate->get_constval().intval);
1824  } else {
1825  approx_bitmap_sz_bits = g_hll_precision_bits;
1826  }
1827  CountDistinctDescriptor approx_count_distinct_desc{CountDistinctImplType::Bitmap,
1828  arg_range.getIntMin(),
1829  approx_bitmap_sz_bits,
1830  true,
1831  device_type,
1832  sub_bitmap_count};
1833  CountDistinctDescriptor precise_count_distinct_desc{CountDistinctImplType::Bitmap,
1834  arg_range.getIntMin(),
1835  bitmap_sz_bits,
1836  false,
1837  device_type,
1838  sub_bitmap_count};
1839  if (approx_count_distinct_desc.bitmapPaddedSizeBytes() >=
1840  precise_count_distinct_desc.bitmapPaddedSizeBytes()) {
1841  auto precise_count_distinct = makeExpr<Analyzer::AggExpr>(
1842  get_agg_type(kCOUNT, arg.get()), kCOUNT, arg, true, nullptr);
1843  target_exprs_owned.push_back(precise_count_distinct);
1844  ra_exe_unit.target_exprs[i] = precise_count_distinct.get();
1845  }
1846  }
1847  return ra_exe_unit;
1848 }
std::vector< Analyzer::Expr * > target_exprs
int hll_size_for_rate(const int err_percent)
Definition: HyperLogLog.h:115
TargetInfo get_target_info(const PointerType target_expr, const bool bigint_count)
Definition: TargetInfo.h:65
#define CHECK_GE(x, y)
Definition: Logger.h:200
SQLTypeInfo get_agg_type(const SQLAgg agg_kind, const Analyzer::Expr *arg_expr)
int g_hll_precision_bits
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:71
#define CHECK(condition)
Definition: Logger.h:187
bool g_cluster
Definition: sqltypes.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_table_reordering()

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

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

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

2418  {
2419  if (g_cluster) {
2420  // Disable table reordering in distributed mode. The aggregator does not have enough
2421  // information to break ties
2422  return {};
2423  }
2424  const auto& cat = *executor->getCatalog();
2425  for (const auto& table_info : query_infos) {
2426  if (table_info.table_id < 0) {
2427  continue;
2428  }
2429  const auto td = cat.getMetadataForTable(table_info.table_id);
2430  CHECK(td);
2431  if (table_is_replicated(td)) {
2432  return {};
2433  }
2434  }
2435  const auto input_permutation =
2436  get_node_input_permutation(left_deep_join_quals, query_infos, executor);
2437  input_to_nest_level = get_input_nest_levels(node, input_permutation);
2438  std::tie(input_descs, input_col_descs, std::ignore) =
2439  get_input_desc(node, input_to_nest_level, input_permutation, cat);
2440  return input_permutation;
2441 }
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
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:187
bool g_cluster
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 Catalog_Namespace::Catalog &cat)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ exe_unit_has_quals()

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

Definition at line 1775 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

1775  {
1776  return !(ra_exe_unit.quals.empty() && ra_exe_unit.join_quals.empty() &&
1777  ra_exe_unit.simple_quals.empty());
1778 }
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:

◆ first_oe_is_desc()

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

Definition at line 1583 of file RelAlgExecutor.cpp.

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

1583  {
1584  return !order_entries.empty() && order_entries.front().is_desc;
1585 }
+ Here is the caller graph for this function:

◆ get_bitwise_equals()

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

Definition at line 2330 of file RelAlgExecutor.cpp.

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

Referenced by get_bitwise_equals_conjunction().

2330  {
2331  const auto condition = dynamic_cast<const RexOperator*>(scalar);
2332  if (!condition || condition->getOperator() != kOR || condition->size() != 2) {
2333  return nullptr;
2334  }
2335  const auto equi_join_condition =
2336  dynamic_cast<const RexOperator*>(condition->getOperand(0));
2337  if (!equi_join_condition || equi_join_condition->getOperator() != kEQ) {
2338  return nullptr;
2339  }
2340  const auto both_are_null_condition =
2341  dynamic_cast<const RexOperator*>(condition->getOperand(1));
2342  if (!both_are_null_condition || both_are_null_condition->getOperator() != kAND ||
2343  both_are_null_condition->size() != 2) {
2344  return nullptr;
2345  }
2346  const auto lhs_is_null =
2347  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(0));
2348  const auto rhs_is_null =
2349  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(1));
2350  if (!lhs_is_null || !rhs_is_null || lhs_is_null->getOperator() != kISNULL ||
2351  rhs_is_null->getOperator() != kISNULL) {
2352  return nullptr;
2353  }
2354  CHECK_EQ(size_t(1), lhs_is_null->size());
2355  CHECK_EQ(size_t(1), rhs_is_null->size());
2356  CHECK_EQ(size_t(2), equi_join_condition->size());
2357  const auto eq_lhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(0));
2358  const auto eq_rhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(1));
2359  const auto is_null_lhs = dynamic_cast<const RexInput*>(lhs_is_null->getOperand(0));
2360  const auto is_null_rhs = dynamic_cast<const RexInput*>(rhs_is_null->getOperand(0));
2361  if (!eq_lhs || !eq_rhs || !is_null_lhs || !is_null_rhs) {
2362  return nullptr;
2363  }
2364  std::vector<std::unique_ptr<const RexScalar>> eq_operands;
2365  if (*eq_lhs == *is_null_lhs && *eq_rhs == *is_null_rhs) {
2366  RexDeepCopyVisitor deep_copy_visitor;
2367  auto lhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(0));
2368  auto rhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(1));
2369  eq_operands.emplace_back(lhs_op_copy.release());
2370  eq_operands.emplace_back(rhs_op_copy.release());
2371  return boost::make_unique<const RexOperator>(
2372  kBW_EQ, eq_operands, equi_join_condition->getType());
2373  }
2374  return nullptr;
2375 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
Definition: sqldefs.h:38
Definition: sqldefs.h:30
Definition: sqldefs.h:37
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
Definition: sqldefs.h:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_bitwise_equals_conjunction()

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

Definition at line 2377 of file RelAlgExecutor.cpp.

References CHECK_GE, get_bitwise_equals(), and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

2378  {
2379  const auto condition = dynamic_cast<const RexOperator*>(scalar);
2380  if (condition && condition->getOperator() == kAND) {
2381  CHECK_GE(condition->size(), size_t(2));
2382  auto acc = get_bitwise_equals(condition->getOperand(0));
2383  if (!acc) {
2384  return nullptr;
2385  }
2386  for (size_t i = 1; i < condition->size(); ++i) {
2387  std::vector<std::unique_ptr<const RexScalar>> and_operands;
2388  and_operands.emplace_back(std::move(acc));
2389  and_operands.emplace_back(get_bitwise_equals_conjunction(condition->getOperand(i)));
2390  acc =
2391  boost::make_unique<const RexOperator>(kAND, and_operands, condition->getType());
2392  }
2393  return acc;
2394  }
2395  return get_bitwise_equals(scalar);
2396 }
std::unique_ptr< const RexOperator > get_bitwise_equals_conjunction(const RexScalar *scalar)
#define CHECK_GE(x, y)
Definition: Logger.h:200
Definition: sqldefs.h:37
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:

◆ get_data_sink()

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

Definition at line 532 of file RelAlgExecutor.cpp.

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

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

532  {
533  if (auto join = dynamic_cast<const RelJoin*>(ra_node)) {
534  CHECK_EQ(size_t(2), join->inputCount());
535  return join;
536  }
537  CHECK_EQ(size_t(1), ra_node->inputCount());
538  auto only_src = ra_node->getInput(0);
539  const bool is_join = dynamic_cast<const RelJoin*>(only_src) ||
540  dynamic_cast<const RelLeftDeepInnerJoin*>(only_src);
541  return is_join ? only_src : ra_node;
542 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::string join(T const &container, std::string const &delim)
const size_t inputCount() const
const RelAlgNode * getInput(const size_t idx) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_input_desc()

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,
const Catalog_Namespace::Catalog cat 
)

Definition at line 796 of file RelAlgExecutor.cpp.

References get_input_desc_impl(), and get_used_inputs().

Referenced by RelAlgExecutor::createAggregateWorkUnit(), RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::createModifyCompoundWorkUnit(), RelAlgExecutor::createModifyProjectWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), and do_table_reordering().

799  {
800  std::unordered_set<const RexInput*> used_inputs;
801  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
802  std::tie(used_inputs, used_inputs_owned) = get_used_inputs(ra_node, cat);
803  auto input_desc_pair = get_input_desc_impl(
804  ra_node, used_inputs, input_to_nest_level, input_permutation, cat);
805  return std::make_tuple(
806  input_desc_pair.first, input_desc_pair.second, used_inputs_owned);
807 }
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, const Catalog_Namespace::Catalog &cat)
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_used_inputs(const RelFilter *filter, const Catalog_Namespace::Catalog &cat)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_input_desc_impl()

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,
const Catalog_Namespace::Catalog cat 
)

Definition at line 738 of file RelAlgExecutor.cpp.

References collect_used_input_desc(), get_data_sink(), get_join_source_used_inputs(), InputDescriptor::getNestLevel(), and table_id_from_ra().

Referenced by get_input_desc().

742  {
743  std::vector<InputDescriptor> input_descs;
744  const auto data_sink_node = get_data_sink(ra_node);
745  for (size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
746  const auto input_node_idx =
747  input_permutation.empty() ? input_idx : input_permutation[input_idx];
748  const auto input_ra = data_sink_node->getInput(input_node_idx);
749  const int table_id = table_id_from_ra(input_ra);
750  input_descs.emplace_back(table_id, input_idx);
751  }
752  std::sort(input_descs.begin(),
753  input_descs.end(),
754  [](const InputDescriptor& lhs, const InputDescriptor& rhs) {
755  return lhs.getNestLevel() < rhs.getNestLevel();
756  });
757  std::unordered_set<std::shared_ptr<const InputColDescriptor>> input_col_descs_unique;
758  collect_used_input_desc(input_descs,
759  cat,
760  input_col_descs_unique,
761  ra_node,
762  used_inputs,
763  input_to_nest_level);
764  std::unordered_set<const RexInput*> join_source_used_inputs;
765  std::vector<std::shared_ptr<RexInput>> join_source_used_inputs_owned;
766  std::tie(join_source_used_inputs, join_source_used_inputs_owned) =
767  get_join_source_used_inputs(ra_node, cat);
768  collect_used_input_desc(input_descs,
769  cat,
770  input_col_descs_unique,
771  ra_node,
772  join_source_used_inputs,
773  input_to_nest_level);
774  std::vector<std::shared_ptr<const InputColDescriptor>> input_col_descs(
775  input_col_descs_unique.begin(), input_col_descs_unique.end());
776 
777  std::sort(
778  input_col_descs.begin(),
779  input_col_descs.end(),
780  [](std::shared_ptr<const InputColDescriptor> const& lhs,
781  std::shared_ptr<const InputColDescriptor> const& rhs) {
782  if (lhs->getScanDesc().getNestLevel() == rhs->getScanDesc().getNestLevel()) {
783  return lhs->getColId() < rhs->getColId();
784  }
785  return lhs->getScanDesc().getNestLevel() < rhs->getScanDesc().getNestLevel();
786  });
787  return {input_descs,
788  std::list<std::shared_ptr<const InputColDescriptor>>(input_col_descs.begin(),
789  input_col_descs.end())};
790 }
int getNestLevel() const
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_join_source_used_inputs(const RelAlgNode *ra_node, const Catalog_Namespace::Catalog &cat)
int table_id_from_ra(const RelAlgNode *ra_node)
void collect_used_input_desc(std::vector< InputDescriptor > &input_descs, const Catalog_Namespace::Catalog &cat, 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:

◆ get_input_nest_levels()

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

References CHECK, get_data_sink(), logger::INFO, and LOG_IF.

Referenced by RelAlgExecutor::createAggregateWorkUnit(), RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::createModifyCompoundWorkUnit(), RelAlgExecutor::createModifyProjectWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), and do_table_reordering().

636  {
637  const auto data_sink_node = get_data_sink(ra_node);
638  std::unordered_map<const RelAlgNode*, int> input_to_nest_level;
639  for (size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
640  const auto input_node_idx =
641  input_permutation.empty() ? input_idx : input_permutation[input_idx];
642  const auto input_ra = data_sink_node->getInput(input_node_idx);
643  const auto it_ok = input_to_nest_level.emplace(input_ra, input_idx);
644  CHECK(it_ok.second);
645  LOG_IF(INFO, !input_permutation.empty())
646  << "Assigned input " << input_ra->toString() << " to nest level " << input_idx;
647  }
648  return input_to_nest_level;
649 }
#define LOG_IF(severity, condition)
Definition: Logger.h:273
#define CHECK(condition)
Definition: Logger.h:187
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:

◆ get_inputs_meta()

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

References CHECK, get_data_sink(), get_exprs_not_owned(), get_targets_meta(), synthesize_inputs(), and RelAlgTranslator::translateScalarRex().

Referenced by RelAlgExecutor::createFilterWorkUnit().

3053  {
3054  std::vector<TargetMetaInfo> in_metainfo;
3055  std::vector<std::shared_ptr<Analyzer::Expr>> exprs_owned;
3056  const auto data_sink_node = get_data_sink(filter);
3057  auto input_it = inputs_owned.begin();
3058  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
3059  const auto source = data_sink_node->getInput(nest_level);
3060  const auto scan_source = dynamic_cast<const RelScan*>(source);
3061  if (scan_source) {
3062  CHECK(source->getOutputMetainfo().empty());
3063  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources_owned;
3064  for (size_t i = 0; i < scan_source->size(); ++i, ++input_it) {
3065  scalar_sources_owned.push_back(translator.translateScalarRex(input_it->get()));
3066  }
3067  const auto source_metadata =
3068  get_targets_meta(scan_source, get_exprs_not_owned(scalar_sources_owned));
3069  in_metainfo.insert(
3070  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
3071  exprs_owned.insert(
3072  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
3073  } else {
3074  const auto& source_metadata = source->getOutputMetainfo();
3075  input_it += source_metadata.size();
3076  in_metainfo.insert(
3077  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
3078  const auto scalar_sources_owned = synthesize_inputs(
3079  data_sink_node, nest_level, source_metadata, input_to_nest_level);
3080  exprs_owned.insert(
3081  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
3082  }
3083  }
3084  return std::make_pair(in_metainfo, exprs_owned);
3085 }
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< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr *> &target_exprs)
std::vector< Analyzer::Expr * > get_exprs_not_owned(const std::vector< std::shared_ptr< Analyzer::Expr >> &exprs)
Definition: Execute.h:211
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
#define CHECK(condition)
Definition: Logger.h:187
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:

◆ get_join_source_used_inputs()

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,
const Catalog_Namespace::Catalog cat 
)

Definition at line 652 of file RelAlgExecutor.cpp.

References CHECK_EQ, CHECK_GE, get_data_sink(), anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelAlgNode::inputCount(), join(), run-benchmark-import::result, and RexVisitorBase< T >::visit().

Referenced by get_input_desc_impl().

653  {
654  const auto data_sink_node = get_data_sink(ra_node);
655  if (auto join = dynamic_cast<const RelJoin*>(data_sink_node)) {
656  CHECK_EQ(join->inputCount(), 2u);
657  const auto condition = join->getCondition();
658  RexUsedInputsVisitor visitor(cat);
659  auto condition_inputs = visitor.visit(condition);
660  std::vector<std::shared_ptr<RexInput>> condition_inputs_owned(
661  visitor.get_inputs_owned());
662  return std::make_pair(condition_inputs, condition_inputs_owned);
663  }
664 
665  if (auto left_deep_join = dynamic_cast<const RelLeftDeepInnerJoin*>(data_sink_node)) {
666  CHECK_GE(left_deep_join->inputCount(), 2u);
667  const auto condition = left_deep_join->getInnerCondition();
668  RexUsedInputsVisitor visitor(cat);
669  auto result = visitor.visit(condition);
670  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
671  ++nesting_level) {
672  const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
673  if (outer_condition) {
674  const auto outer_result = visitor.visit(outer_condition);
675  result.insert(outer_result.begin(), outer_result.end());
676  }
677  }
678  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
679  return std::make_pair(result, used_inputs_owned);
680  }
681 
682  CHECK_EQ(ra_node->inputCount(), 1u);
683  return std::make_pair(std::unordered_set<const RexInput*>{},
684  std::vector<std::shared_ptr<RexInput>>{});
685 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::string join(T const &container, std::string const &delim)
#define CHECK_GE(x, y)
Definition: Logger.h:200
const size_t inputCount() const
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:

◆ get_join_type()

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

Definition at line 2318 of file RelAlgExecutor.cpp.

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

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

2318  {
2319  auto sink = get_data_sink(ra);
2320  if (auto join = dynamic_cast<const RelJoin*>(sink)) {
2321  return join->getJoinType();
2322  }
2323  if (dynamic_cast<const RelLeftDeepInnerJoin*>(sink)) {
2324  return JoinType::INNER;
2325  }
2326 
2327  return JoinType::INVALID;
2328 }
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:

◆ get_left_deep_join_input_sizes()

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

Definition at line 2443 of file RelAlgExecutor.cpp.

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

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

2444  {
2445  std::vector<size_t> input_sizes;
2446  for (size_t i = 0; i < left_deep_join->inputCount(); ++i) {
2447  const auto inputs = get_node_output(left_deep_join->getInput(i));
2448  input_sizes.push_back(inputs.size());
2449  }
2450  return input_sizes;
2451 }
const size_t inputCount() const
RANodeOutput get_node_output(const RelAlgNode *ra_node)
const RelAlgNode * getInput(const size_t idx) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_modify_manipulated_targets_meta()

std::vector<TargetMetaInfo> anonymous_namespace{RelAlgExecutor.cpp}::get_modify_manipulated_targets_meta ( ModifyManipulationTarget const *  manip_node,
const std::vector< Analyzer::Expr *> &  target_exprs 
)

Definition at line 1082 of file RelAlgExecutor.cpp.

References CHECK, ModifyManipulationTarget::getTargetColumnCount(), ModifyManipulationTarget::getTargetColumns(), is_count_distinct(), and kBIGINT.

Referenced by RelAlgExecutor::createModifyCompoundWorkUnit(), and RelAlgExecutor::createModifyProjectWorkUnit().

1084  {
1085  std::vector<TargetMetaInfo> targets_meta;
1086 
1087  for (int i = 0; i < (manip_node->getTargetColumnCount()); ++i) {
1088  CHECK(target_exprs[i]);
1089  // TODO(alex): remove the count distinct type fixup.
1090  targets_meta.emplace_back(manip_node->getTargetColumns()[i],
1091  is_count_distinct(target_exprs[i])
1092  ? SQLTypeInfo(kBIGINT, false)
1093  : target_exprs[i]->get_type_info());
1094  }
1095 
1096  return targets_meta;
1097 }
bool is_count_distinct(const Analyzer::Expr *expr)
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_non_join_sequence()

std::vector<const RelAlgNode*> anonymous_namespace{RelAlgExecutor.cpp}::get_non_join_sequence ( const RelAlgNode ra)

Definition at line 687 of file RelAlgExecutor.cpp.

References CHECK_EQ, and join().

Referenced by collect_used_input_desc().

687  {
688  std::vector<const RelAlgNode*> seq;
689  for (auto join = dynamic_cast<const RelJoin*>(ra); join;
690  join = static_cast<const RelJoin*>(join->getInput(0))) {
691  CHECK_EQ(size_t(2), join->inputCount());
692  seq.emplace_back(join->getInput(1));
693  auto lhs = join->getInput(0);
694  if (!dynamic_cast<const RelJoin*>(lhs)) {
695  seq.emplace_back(lhs);
696  break;
697  }
698  }
699  std::reverse(seq.begin(), seq.end());
700  return seq;
701 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::string join(T const &container, std::string const &delim)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_order_entries()

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

Definition at line 1563 of file RelAlgExecutor.cpp.

References RelSort::collationCount(), Descending, First, RelSort::getCollation(), and run-benchmark-import::result.

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

1563  {
1564  std::list<Analyzer::OrderEntry> result;
1565  for (size_t i = 0; i < sort->collationCount(); ++i) {
1566  const auto sort_field = sort->getCollation(i);
1567  result.emplace_back(sort_field.getField() + 1,
1568  sort_field.getSortDir() == SortDirection::Descending,
1569  sort_field.getNullsPosition() == NullSortedPosition::First);
1570  }
1571  return result;
1572 }
size_t collationCount() const
SortField getCollation(const size_t i) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_physical_inputs()

std::unordered_set<PhysicalInput> anonymous_namespace{RelAlgExecutor.cpp}::get_physical_inputs ( const Catalog_Namespace::Catalog cat,
const RelAlgNode ra 
)

Definition at line 156 of file RelAlgExecutor.cpp.

References Catalog_Namespace::Catalog::getColumnIdBySpi().

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

158  {
159  auto phys_inputs = get_physical_inputs(ra);
160  std::unordered_set<PhysicalInput> phys_inputs2;
161  for (auto& phi : phys_inputs) {
162  phys_inputs2.insert(
163  PhysicalInput{cat.getColumnIdBySpi(phi.table_id, phi.col_id), phi.table_id});
164  }
165  return phys_inputs2;
166 }
std::unordered_set< PhysicalInput > get_physical_inputs(const Catalog_Namespace::Catalog &cat, const RelAlgNode *ra)
const int getColumnIdBySpi(const int tableId, const size_t spi) const
Definition: Catalog.cpp:1430
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_physical_table_ids()

std::unordered_set<int> anonymous_namespace{RelAlgExecutor.cpp}::get_physical_table_ids ( const std::unordered_set< PhysicalInput > &  phys_inputs)

Definition at line 147 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::computeColRangesCache().

148  {
149  std::unordered_set<int> physical_table_ids;
150  for (const auto& phys_input : phys_inputs) {
151  physical_table_ids.insert(phys_input.table_id);
152  }
153  return physical_table_ids;
154 }
+ Here is the caller graph for this function:

◆ get_scalar_sources_size() [1/2]

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

Definition at line 809 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSourcesSize().

809  {
810  return compound->getScalarSourcesSize();
811 }
const size_t getScalarSourcesSize() const
+ Here is the call graph for this function:

◆ get_scalar_sources_size() [2/2]

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

Definition at line 813 of file RelAlgExecutor.cpp.

References RelProject::size().

Referenced by RelAlgExecutor::createModifyCompoundWorkUnit(), RelAlgExecutor::createModifyProjectWorkUnit(), translate_scalar_sources(), translate_scalar_sources_for_update(), and translate_targets_for_update().

813  {
814  return project->size();
815 }
size_t size() const override
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_scan_limit()

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

Definition at line 1574 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::createSortInputWorkUnit().

1574  {
1575  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
1576  if (aggregate) {
1577  return 0;
1578  }
1579  const auto compound = dynamic_cast<const RelCompound*>(ra);
1580  return (compound && compound->isAggregate()) ? 0 : limit;
1581 }
+ Here is the caller graph for this function:

◆ get_targets_meta()

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

References CHECK, get_logical_type_info(), is_count_distinct(), and kBIGINT.

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

1102  {
1103  std::vector<TargetMetaInfo> targets_meta;
1104  for (size_t i = 0; i < ra_node->size(); ++i) {
1105  CHECK(target_exprs[i]);
1106  // TODO(alex): remove the count distinct type fixup.
1107  targets_meta.emplace_back(
1108  ra_node->getFieldName(i),
1109  is_count_distinct(target_exprs[i])
1110  ? SQLTypeInfo(kBIGINT, false)
1111  : get_logical_type_info(target_exprs[i]->get_type_info()),
1112  target_exprs[i]->get_type_info());
1113  }
1114  return targets_meta;
1115 }
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:840
bool is_count_distinct(const Analyzer::Expr *expr)
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_used_inputs() [1/4]

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

Definition at line 545 of file RelAlgExecutor.cpp.

References anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelCompound::getFilterExpr(), RelCompound::getScalarSource(), RelCompound::getScalarSourcesSize(), and RexVisitorBase< T >::visit().

545  {
546  RexUsedInputsVisitor visitor(cat);
547  const auto filter_expr = compound->getFilterExpr();
548  std::unordered_set<const RexInput*> used_inputs =
549  filter_expr ? visitor.visit(filter_expr) : std::unordered_set<const RexInput*>{};
550  const auto sources_size = compound->getScalarSourcesSize();
551  for (size_t i = 0; i < sources_size; ++i) {
552  const auto source_inputs = visitor.visit(compound->getScalarSource(i));
553  used_inputs.insert(source_inputs.begin(), source_inputs.end());
554  }
555  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
556  return std::make_pair(used_inputs, used_inputs_owned);
557 }
const size_t getScalarSourcesSize() const
const RexScalar * getScalarSource(const size_t i) const
const RexScalar * getFilterExpr() const
+ Here is the call graph for this function:

◆ get_used_inputs() [2/4]

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

Definition at line 560 of file RelAlgExecutor.cpp.

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

560  {
561  CHECK_EQ(size_t(1), aggregate->inputCount());
562  std::unordered_set<const RexInput*> used_inputs;
563  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
564  const auto source = aggregate->getInput(0);
565  const auto& in_metainfo = source->getOutputMetainfo();
566  const auto group_count = aggregate->getGroupByCount();
567  CHECK_GE(in_metainfo.size(), group_count);
568  for (size_t i = 0; i < group_count; ++i) {
569  auto synthesized_used_input = new RexInput(source, i);
570  used_inputs_owned.emplace_back(synthesized_used_input);
571  used_inputs.insert(synthesized_used_input);
572  }
573  for (const auto& agg_expr : aggregate->getAggExprs()) {
574  for (size_t i = 0; i < agg_expr->size(); ++i) {
575  const auto operand_idx = agg_expr->getOperand(i);
576  CHECK_GE(in_metainfo.size(), static_cast<size_t>(operand_idx));
577  auto synthesized_used_input = new RexInput(source, operand_idx);
578  used_inputs_owned.emplace_back(synthesized_used_input);
579  used_inputs.insert(synthesized_used_input);
580  }
581  }
582  return std::make_pair(used_inputs, used_inputs_owned);
583 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
#define CHECK_GE(x, y)
Definition: Logger.h:200
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
const size_t getGroupByCount() const
const size_t inputCount() const
const RelAlgNode * getInput(const size_t idx) const
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
+ Here is the call graph for this function:

◆ get_used_inputs() [3/4]

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

Definition at line 586 of file RelAlgExecutor.cpp.

References anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelProject::getProjectAt(), RelProject::size(), and RexVisitorBase< T >::visit().

586  {
587  RexUsedInputsVisitor visitor(cat);
588  std::unordered_set<const RexInput*> used_inputs;
589  for (size_t i = 0; i < project->size(); ++i) {
590  const auto proj_inputs = visitor.visit(project->getProjectAt(i));
591  used_inputs.insert(proj_inputs.begin(), proj_inputs.end());
592  }
593  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
594  return std::make_pair(used_inputs, used_inputs_owned);
595 }
size_t size() const override
const RexScalar * getProjectAt(const size_t idx) const
+ Here is the call graph for this function:

◆ get_used_inputs() [4/4]

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

Definition at line 598 of file RelAlgExecutor.cpp.

References CHECK, and get_data_sink().

Referenced by get_input_desc().

598  {
599  std::unordered_set<const RexInput*> used_inputs;
600  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
601  const auto data_sink_node = get_data_sink(filter);
602  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
603  const auto source = data_sink_node->getInput(nest_level);
604  const auto scan_source = dynamic_cast<const RelScan*>(source);
605  if (scan_source) {
606  CHECK(source->getOutputMetainfo().empty());
607  for (size_t i = 0; i < scan_source->size(); ++i) {
608  auto synthesized_used_input = new RexInput(scan_source, i);
609  used_inputs_owned.emplace_back(synthesized_used_input);
610  used_inputs.insert(synthesized_used_input);
611  }
612  } else {
613  const auto& partial_in_metadata = source->getOutputMetainfo();
614  for (size_t i = 0; i < partial_in_metadata.size(); ++i) {
615  auto synthesized_used_input = new RexInput(source, i);
616  used_inputs_owned.emplace_back(synthesized_used_input);
617  used_inputs.insert(synthesized_used_input);
618  }
619  }
620  }
621  return std::make_pair(used_inputs, used_inputs_owned);
622 }
#define CHECK(condition)
Definition: Logger.h:187
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:

◆ groups_approx_upper_bound()

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

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

Definition at line 1744 of file RelAlgExecutor.cpp.

References CHECK.

Referenced by RelAlgExecutor::executeWorkUnit().

1744  {
1745  CHECK(!table_infos.empty());
1746  const auto& first_table = table_infos.front();
1747  size_t max_num_groups = first_table.info.getNumTuplesUpperBound();
1748  for (const auto& table_info : table_infos) {
1749  if (table_info.info.getNumTuplesUpperBound() > max_num_groups) {
1750  max_num_groups = table_info.info.getNumTuplesUpperBound();
1751  }
1752  }
1753  return std::max(max_num_groups, size_t(1));
1754 }
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the caller graph for this function:

◆ is_count_distinct()

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

Definition at line 1077 of file RelAlgExecutor.cpp.

References Analyzer::AggExpr::get_is_distinct().

Referenced by get_modify_manipulated_targets_meta(), and get_targets_meta().

1077  {
1078  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1079  return agg_expr && agg_expr->get_is_distinct();
1080 }
bool get_is_distinct() const
Definition: Analyzer.h:990
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_window_execution_unit()

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

Definition at line 1331 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::target_exprs.

Referenced by RelAlgExecutor::executeWorkUnit().

1331  {
1332  return std::any_of(ra_exe_unit.target_exprs.begin(),
1333  ra_exe_unit.target_exprs.end(),
1334  [](const Analyzer::Expr* expr) {
1335  return dynamic_cast<const Analyzer::WindowFunction*>(expr);
1336  });
1337 }
std::vector< Analyzer::Expr * > target_exprs
+ Here is the caller graph for this function:

◆ left_deep_join_types()

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

Definition at line 2398 of file RelAlgExecutor.cpp.

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

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

2398  {
2399  CHECK_GE(left_deep_join->inputCount(), size_t(2));
2400  std::vector<JoinType> join_types(left_deep_join->inputCount() - 1, JoinType::INNER);
2401  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
2402  ++nesting_level) {
2403  if (left_deep_join->getOuterCondition(nesting_level)) {
2404  join_types[nesting_level - 1] = JoinType::LEFT;
2405  }
2406  }
2407  return join_types;
2408 }
#define CHECK_GE(x, y)
Definition: Logger.h:200
const RexScalar * getOuterCondition(const size_t nesting_level) const
const size_t inputCount() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ list_contains_expression()

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

Definition at line 2678 of file RelAlgExecutor.cpp.

Referenced by reverse_logical_distribution().

2679  {
2680  for (const auto& qual : haystack) {
2681  if (*qual == *needle) {
2682  return true;
2683  }
2684  }
2685  return false;
2686 }
+ Here is the caller graph for this function:

◆ node_is_aggregate()

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

Definition at line 45 of file RelAlgExecutor.cpp.

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

45  {
46  const auto compound = dynamic_cast<const RelCompound*>(ra);
47  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
48  return ((compound && compound->isAggregate()) || aggregate);
49 }
+ Here is the caller graph for this function:

◆ reverse_logical_distribution()

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

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

2692  {
2693  const auto expr_terms = qual_to_disjunctive_form(expr);
2694  CHECK_GE(expr_terms.size(), size_t(1));
2695  const auto& first_term = expr_terms.front();
2696  const auto first_term_factors = qual_to_conjunctive_form(first_term);
2697  std::vector<std::shared_ptr<Analyzer::Expr>> common_factors;
2698  // First, collect the conjunctive components common to all the disjunctive components.
2699  // Don't do it for simple qualifiers, we only care about expensive or join qualifiers.
2700  for (const auto& first_term_factor : first_term_factors.quals) {
2701  bool is_common =
2702  expr_terms.size() > 1; // Only report common factors for disjunction.
2703  for (size_t i = 1; i < expr_terms.size(); ++i) {
2704  const auto crt_term_factors = qual_to_conjunctive_form(expr_terms[i]);
2705  if (!list_contains_expression(crt_term_factors.quals, first_term_factor)) {
2706  is_common = false;
2707  break;
2708  }
2709  }
2710  if (is_common) {
2711  common_factors.push_back(first_term_factor);
2712  }
2713  }
2714  if (common_factors.empty()) {
2715  return expr;
2716  }
2717  // Now that the common expressions are known, collect the remaining expressions.
2718  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_terms;
2719  for (const auto& term : expr_terms) {
2720  const auto term_cf = qual_to_conjunctive_form(term);
2721  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_quals(
2722  term_cf.simple_quals.begin(), term_cf.simple_quals.end());
2723  for (const auto& qual : term_cf.quals) {
2724  if (!list_contains_expression(common_factors, qual)) {
2725  remaining_quals.push_back(qual);
2726  }
2727  }
2728  if (!remaining_quals.empty()) {
2729  remaining_terms.push_back(build_logical_expression(remaining_quals, kAND));
2730  }
2731  }
2732  // Reconstruct the expression with the transformation applied.
2733  const auto common_expr = build_logical_expression(common_factors, kAND);
2734  if (remaining_terms.empty()) {
2735  return common_expr;
2736  }
2737  const auto remaining_expr = build_logical_expression(remaining_terms, kOR);
2738  return Parser::OperExpr::normalize(kAND, kONE, common_expr, remaining_expr);
2739 }
Definition: sqldefs.h:38
#define CHECK_GE(x, y)
Definition: Logger.h:200
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:37
std::shared_ptr< Analyzer::Expr > build_logical_expression(const std::vector< std::shared_ptr< Analyzer::Expr >> &factors, const SQLOps sql_op)
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)
Definition: ParserNode.cpp:257
Definition: sqldefs.h:69
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:

◆ rewrite_quals()

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

References rewrite_expr().

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

2454  {
2455  std::list<std::shared_ptr<Analyzer::Expr>> rewritten_quals;
2456  for (const auto& qual : quals) {
2457  const auto rewritten_qual = rewrite_expr(qual.get());
2458  rewritten_quals.push_back(rewritten_qual ? rewritten_qual : qual);
2459  }
2460  return rewritten_quals;
2461 }
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rex_to_conjunctive_form()

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

Definition at line 2651 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

2651  {
2652  CHECK(qual_expr);
2653  const auto bin_oper = dynamic_cast<const RexOperator*>(qual_expr);
2654  if (!bin_oper || bin_oper->getOperator() != kAND) {
2655  return {qual_expr};
2656  }
2657  CHECK_GE(bin_oper->size(), size_t(2));
2658  auto lhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(0));
2659  for (size_t i = 1; i < bin_oper->size(); ++i) {
2660  const auto rhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(i));
2661  lhs_cf.insert(lhs_cf.end(), rhs_cf.begin(), rhs_cf.end());
2662  }
2663  return lhs_cf;
2664 }
#define CHECK_GE(x, y)
Definition: Logger.h:200
std::vector< const RexScalar * > rex_to_conjunctive_form(const RexScalar *qual_expr)
Definition: sqldefs.h:37
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the caller graph for this function:

◆ scalar_at() [1/2]

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

Definition at line 817 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSource().

817  {
818  return compound->getScalarSource(i);
819 }
const RexScalar * getScalarSource(const size_t i) const
+ Here is the call graph for this function:

◆ scalar_at() [2/2]

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

Definition at line 821 of file RelAlgExecutor.cpp.

References RelProject::getProjectAt().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

821  {
822  return project->getProjectAt(i);
823 }
const RexScalar * getProjectAt(const size_t idx) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_transient_dict()

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

Definition at line 825 of file RelAlgExecutor.cpp.

References kENCODING_DICT, kENCODING_NONE, and TRANSIENT_DICT_ID.

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

826  {
827  const auto& ti = expr->get_type_info();
828  if (!ti.is_string() || ti.get_compression() != kENCODING_NONE) {
829  return expr;
830  }
831  auto transient_dict_ti = ti;
832  transient_dict_ti.set_compression(kENCODING_DICT);
833  transient_dict_ti.set_comp_param(TRANSIENT_DICT_ID);
834  transient_dict_ti.set_fixed_size();
835  return expr->add_cast(transient_dict_ti);
836 }
#define TRANSIENT_DICT_ID
Definition: sqltypes.h:186
+ Here is the caller graph for this function:

◆ set_transient_dict_maybe()

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

References fold_expr(), and set_transient_dict().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

840  {
841  try {
842  scalar_sources.push_back(set_transient_dict(fold_expr(expr.get())));
843  } catch (...) {
844  scalar_sources.push_back(fold_expr(expr.get()));
845  }
846 }
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:

◆ synthesize_inputs()

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

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

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

2822  {
2823  CHECK_LE(size_t(1), ra_node->inputCount());
2824  CHECK_GE(size_t(2), ra_node->inputCount());
2825  const auto input = ra_node->getInput(nest_level);
2826  const auto it_rte_idx = input_to_nest_level.find(input);
2827  CHECK(it_rte_idx != input_to_nest_level.end());
2828  const int rte_idx = it_rte_idx->second;
2829  const int table_id = table_id_from_ra(input);
2830  std::vector<std::shared_ptr<Analyzer::Expr>> inputs;
2831  const auto scan_ra = dynamic_cast<const RelScan*>(input);
2832  int input_idx = 0;
2833  for (const auto& input_meta : in_metainfo) {
2834  inputs.push_back(
2835  std::make_shared<Analyzer::ColumnVar>(input_meta.get_type_info(),
2836  table_id,
2837  scan_ra ? input_idx + 1 : input_idx,
2838  rte_idx));
2839  ++input_idx;
2840  }
2841  return inputs;
2842 }
#define CHECK_GE(x, y)
Definition: Logger.h:200
#define CHECK_LE(x, y)
Definition: Logger.h:198
const size_t inputCount() const
int table_id_from_ra(const RelAlgNode *ra_node)
#define CHECK(condition)
Definition: Logger.h:187
const RelAlgNode * getInput(const size_t idx) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ table_id_from_ra()

int anonymous_namespace{RelAlgExecutor.cpp}::table_id_from_ra ( const RelAlgNode ra_node)

Definition at line 624 of file RelAlgExecutor.cpp.

References CHECK, RelAlgNode::getId(), and RelScan::getTableDescriptor().

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

624  {
625  const auto scan_ra = dynamic_cast<const RelScan*>(ra_node);
626  if (scan_ra) {
627  const auto td = scan_ra->getTableDescriptor();
628  CHECK(td);
629  return td->tableId;
630  }
631  return -ra_node->getId();
632 }
const TableDescriptor * getTableDescriptor() const
unsigned getId() const
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ transform_to_inner()

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

Definition at line 1378 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::computeWindow().

1378  {
1379  const auto tuple = dynamic_cast<const Analyzer::ExpressionTuple*>(expr);
1380  if (tuple) {
1381  std::vector<std::shared_ptr<Analyzer::Expr>> transformed_tuple;
1382  for (const auto& element : tuple->getTuple()) {
1383  transformed_tuple.push_back(transform_to_inner(element.get()));
1384  }
1385  return makeExpr<Analyzer::ExpressionTuple>(transformed_tuple);
1386  }
1387  const auto col = dynamic_cast<const Analyzer::ColumnVar*>(expr);
1388  if (!col) {
1389  throw std::runtime_error("Only columns supported in the window partition for now");
1390  }
1391  return makeExpr<Analyzer::ColumnVar>(
1392  col->get_type_info(), col->get_table_id(), col->get_column_id(), 1);
1393 }
std::shared_ptr< Analyzer::Expr > transform_to_inner(const Analyzer::Expr *expr)
+ Here is the caller graph for this function:

◆ translate_groupby_exprs() [1/2]

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

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

931  {
932  if (!compound->isAggregate()) {
933  return {nullptr};
934  }
935  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
936  for (size_t group_idx = 0; group_idx < compound->getGroupByCount(); ++group_idx) {
937  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
938  }
939  return groupby_exprs;
940 }
const size_t getGroupByCount() const
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
+ Here is the call graph for this function:

◆ translate_groupby_exprs() [2/2]

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

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

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

944  {
945  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
946  for (size_t group_idx = 0; group_idx < aggregate->getGroupByCount(); ++group_idx) {
947  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
948  }
949  return groupby_exprs;
950 }
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
const size_t getGroupByCount() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ translate_quals()

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

Definition at line 952 of file RelAlgExecutor.cpp.

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

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

953  {
954  const auto filter_rex = compound->getFilterExpr();
955  const auto filter_expr =
956  filter_rex ? translator.translateScalarRex(filter_rex) : nullptr;
957  return filter_expr ? qual_to_conjunctive_form(fold_expr(filter_expr.get()))
959 }
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const RexScalar * getFilterExpr() 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:

◆ translate_scalar_sources()

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

Definition at line 849 of file RelAlgExecutor.cpp.

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

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

851  {
852  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
853  for (size_t i = 0; i < get_scalar_sources_size(ra_node); ++i) {
854  const auto scalar_rex = scalar_at(i, ra_node);
855  if (dynamic_cast<const RexRef*>(scalar_rex)) {
856  // RexRef are synthetic scalars we append at the end of the real ones
857  // for the sake of taking memory ownership, no real work needed here.
858  continue;
859  }
860 
861  const auto scalar_expr =
862  rewrite_array_elements(translator.translateScalarRex(scalar_rex).get());
863  const auto rewritten_expr = rewrite_expr(scalar_expr.get());
864  set_transient_dict_maybe(scalar_sources, rewritten_expr);
865  }
866 
867  return scalar_sources;
868 }
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const RexScalar * scalar_at(const size_t i, const RelProject *project)
size_t get_scalar_sources_size(const RelProject *project)
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:

◆ translate_scalar_sources_for_update()

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

References cast_to_column_type(), get_scalar_sources_size(), rewrite_array_elements(), rewrite_expr(), scalar_at(), set_transient_dict_maybe(), and RelAlgTranslator::translateScalarRex().

Referenced by RelAlgExecutor::createModifyCompoundWorkUnit(), and RelAlgExecutor::createModifyProjectWorkUnit().

902  {
903  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
904  for (size_t i = 0; i < get_scalar_sources_size(ra_node); ++i) {
905  const auto scalar_rex = scalar_at(i, ra_node);
906  if (dynamic_cast<const RexRef*>(scalar_rex)) {
907  // RexRef are synthetic scalars we append at the end of the real ones
908  // for the sake of taking memory ownership, no real work needed here.
909  continue;
910  }
911 
912  std::shared_ptr<Analyzer::Expr> translated_expr;
913  if (i >= starting_projection_column_idx && i < get_scalar_sources_size(ra_node) - 1) {
914  translated_expr = cast_to_column_type(translator.translateScalarRex(scalar_rex),
915  tableId,
916  cat,
917  colNames[i - starting_projection_column_idx]);
918  } else {
919  translated_expr = translator.translateScalarRex(scalar_rex);
920  }
921  const auto scalar_expr = rewrite_array_elements(translated_expr.get());
922  const auto rewritten_expr = rewrite_expr(scalar_expr.get());
923  set_transient_dict_maybe(scalar_sources, rewritten_expr);
924  }
925 
926  return scalar_sources;
927 }
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const RexScalar * scalar_at(const size_t i, const RelProject *project)
std::shared_ptr< Analyzer::Expr > cast_to_column_type(std::shared_ptr< Analyzer::Expr > expr, int32_t tableId, const Catalog_Namespace::Catalog &cat, const std::string &colName)
size_t get_scalar_sources_size(const RelProject *project)
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:

◆ translate_targets() [1/2]

std::vector<Analyzer::Expr*> anonymous_namespace{RelAlgExecutor.cpp}::translate_targets ( std::vector< std::shared_ptr< Analyzer::Expr >> &  target_exprs_owned,
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 
)

Definition at line 961 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, CHECK_LE, fold_expr(), RexRef::getIndex(), RelCompound::getTargetExpr(), Analyzer::Var::kGROUPBY, rewrite_expr(), set_transient_dict(), RelCompound::size(), RelAlgTranslator::translateAggregateRex(), RelAlgTranslator::translateScalarRex(), and var_ref().

966  {
967  std::vector<Analyzer::Expr*> target_exprs;
968  for (size_t i = 0; i < compound->size(); ++i) {
969  const auto target_rex = compound->getTargetExpr(i);
970  const auto target_rex_agg = dynamic_cast<const RexAgg*>(target_rex);
971  std::shared_ptr<Analyzer::Expr> target_expr;
972  if (target_rex_agg) {
973  target_expr =
974  RelAlgTranslator::translateAggregateRex(target_rex_agg, scalar_sources);
975  } else {
976  const auto target_rex_scalar = dynamic_cast<const RexScalar*>(target_rex);
977  const auto target_rex_ref = dynamic_cast<const RexRef*>(target_rex_scalar);
978  if (target_rex_ref) {
979  const auto ref_idx = target_rex_ref->getIndex();
980  CHECK_GE(ref_idx, size_t(1));
981  CHECK_LE(ref_idx, groupby_exprs.size());
982  const auto groupby_expr = *std::next(groupby_exprs.begin(), ref_idx - 1);
983  target_expr = var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, ref_idx);
984  } else {
985  target_expr = translator.translateScalarRex(target_rex_scalar);
986  auto rewritten_expr = rewrite_expr(target_expr.get());
987  target_expr = fold_expr(rewritten_expr.get());
988  try {
989  target_expr = set_transient_dict(target_expr);
990  } catch (...) {
991  // noop
992  }
993  }
994  }
995  CHECK(target_expr);
996  target_exprs_owned.push_back(target_expr);
997  target_exprs.push_back(target_expr.get());
998  }
999  return target_exprs;
1000 }
size_t size() const override
const Rex * getTargetExpr(const size_t i) const
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:1508
#define CHECK_GE(x, y)
Definition: Logger.h:200
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
size_t getIndex() const
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
#define CHECK_LE(x, y)
Definition: Logger.h:198
#define CHECK(condition)
Definition: Logger.h:187
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:

◆ translate_targets() [2/2]

std::vector<Analyzer::Expr*> anonymous_namespace{RelAlgExecutor.cpp}::translate_targets ( std::vector< std::shared_ptr< Analyzer::Expr >> &  target_exprs_owned,
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 1002 of file RelAlgExecutor.cpp.

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

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

1007  {
1008  std::vector<Analyzer::Expr*> target_exprs;
1009  size_t group_key_idx = 0;
1010  for (const auto& groupby_expr : groupby_exprs) {
1011  auto target_expr =
1012  var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, group_key_idx++);
1013  target_exprs_owned.push_back(target_expr);
1014  target_exprs.push_back(target_expr.get());
1015  }
1016 
1017  for (const auto& target_rex_agg : aggregate->getAggExprs()) {
1018  auto target_expr =
1019  RelAlgTranslator::translateAggregateRex(target_rex_agg.get(), scalar_sources);
1020  CHECK(target_expr);
1021  target_expr = fold_expr(target_expr.get());
1022  target_exprs_owned.push_back(target_expr);
1023  target_exprs.push_back(target_expr.get());
1024  }
1025  return target_exprs;
1026 }
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:1508
#define CHECK(condition)
Definition: Logger.h:187
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
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:

◆ translate_targets_for_update()

std::vector<Analyzer::Expr*> anonymous_namespace{RelAlgExecutor.cpp}::translate_targets_for_update ( std::vector< std::shared_ptr< Analyzer::Expr >> &  target_exprs_owned,
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,
int32_t  tableId,
const Catalog_Namespace::Catalog cat,
const ColumnNameList colNames,
size_t  starting_projection_column_idx 
)

Definition at line 1028 of file RelAlgExecutor.cpp.

References cast_to_column_type(), CHECK, CHECK_GE, CHECK_LE, fold_expr(), get_scalar_sources_size(), RexRef::getIndex(), RelCompound::getTargetExpr(), Analyzer::Var::kGROUPBY, rewrite_expr(), RelCompound::size(), RelAlgTranslator::translateAggregateRex(), RelAlgTranslator::translateScalarRex(), and var_ref().

Referenced by RelAlgExecutor::createModifyCompoundWorkUnit().

1037  {
1038  std::vector<Analyzer::Expr*> target_exprs;
1039  for (size_t i = 0; i < compound->size(); ++i) {
1040  const auto target_rex = compound->getTargetExpr(i);
1041  const auto target_rex_agg = dynamic_cast<const RexAgg*>(target_rex);
1042  std::shared_ptr<Analyzer::Expr> target_expr;
1043  if (target_rex_agg) {
1044  target_expr =
1045  RelAlgTranslator::translateAggregateRex(target_rex_agg, scalar_sources);
1046  } else {
1047  const auto target_rex_scalar = dynamic_cast<const RexScalar*>(target_rex);
1048  const auto target_rex_ref = dynamic_cast<const RexRef*>(target_rex_scalar);
1049  if (target_rex_ref) {
1050  const auto ref_idx = target_rex_ref->getIndex();
1051  CHECK_GE(ref_idx, size_t(1));
1052  CHECK_LE(ref_idx, groupby_exprs.size());
1053  const auto groupby_expr = *std::next(groupby_exprs.begin(), ref_idx - 1);
1054  target_expr = var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, ref_idx);
1055  } else {
1056  if (i >= starting_projection_column_idx &&
1057  i < get_scalar_sources_size(compound) - 1) {
1058  target_expr =
1059  cast_to_column_type(translator.translateScalarRex(target_rex_scalar),
1060  tableId,
1061  cat,
1062  colNames[i - starting_projection_column_idx]);
1063  } else {
1064  target_expr = translator.translateScalarRex(target_rex_scalar);
1065  }
1066  auto rewritten_expr = rewrite_expr(target_expr.get());
1067  target_expr = fold_expr(rewritten_expr.get());
1068  }
1069  }
1070  CHECK(target_expr);
1071  target_exprs_owned.push_back(target_expr);
1072  target_exprs.push_back(target_expr.get());
1073  }
1074  return target_exprs;
1075 }
size_t size() const override
const Rex * getTargetExpr(const size_t i) const
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:1508
#define CHECK_GE(x, y)
Definition: Logger.h:200
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
size_t getIndex() const
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
std::shared_ptr< Analyzer::Expr > cast_to_column_type(std::shared_ptr< Analyzer::Expr > expr, int32_t tableId, const Catalog_Namespace::Catalog &cat, const std::string &colName)
#define CHECK_LE(x, y)
Definition: Logger.h:198
size_t get_scalar_sources_size(const RelProject *project)
#define CHECK(condition)
Definition: Logger.h:187
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: