OmniSciDB  addbbd5075
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RelAlgExecutor Class Reference

#include <RelAlgExecutor.h>

+ Inheritance diagram for RelAlgExecutor:
+ Collaboration diagram for RelAlgExecutor:

Classes

struct  TableFunctionWorkUnit
 
struct  WorkUnit
 

Public Types

using TargetInfoList = std::vector< TargetInfo >
 

Public Member Functions

 RelAlgExecutor (Executor *executor, const Catalog_Namespace::Catalog &cat, std::shared_ptr< const query_state::QueryState > query_state=nullptr)
 
 RelAlgExecutor (Executor *executor, const Catalog_Namespace::Catalog &cat, const std::string &query_ra, std::shared_ptr< const query_state::QueryState > query_state=nullptr)
 
 RelAlgExecutor (Executor *executor, const Catalog_Namespace::Catalog &cat, std::unique_ptr< RelAlgDagBuilder > query_dag, std::shared_ptr< const query_state::QueryState > query_state=nullptr)
 
ExecutionResult executeRelAlgQuery (const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
 
ExecutionResult executeRelAlgQueryWithFilterPushDown (const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
 
void prepareLeafExecution (const AggregatedColRange &agg_col_range, const StringDictionaryGenerations &string_dictionary_generations, const TableGenerations &table_generations)
 
ExecutionResult executeRelAlgSeq (const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms, const bool with_existing_temp_tables=false)
 
ExecutionResult executeRelAlgSubSeq (const RaExecutionSequence &seq, const std::pair< size_t, size_t > interval, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
 
FirstStepExecutionResult executeRelAlgQuerySingleStep (const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
 
void addLeafResult (const unsigned id, const AggregatedResult &result)
 
const RelAlgNodegetRootRelAlgNode () const
 
const std::vector
< std::shared_ptr< RexSubQuery > > & 
getSubqueries () const noexcept
 
AggregatedColRange computeColRangesCache ()
 
StringDictionaryGenerations computeStringDictionaryGenerations ()
 
TableGenerations computeTableGenerations ()
 
ExecutorgetExecutor () const
 
void cleanupPostExecution ()
 

Static Public Member Functions

static std::string getErrorMessageFromCode (const int32_t error_code)
 

Private Member Functions

ExecutionResult executeRelAlgQueryNoRetry (const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
 
void executeRelAlgStep (const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
 
void executeUpdateViaCompound (const RelCompound *compound, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
 
void executeUpdateViaProject (const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
 
void executeDeleteViaCompound (const RelCompound *compound, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
 
void executeDeleteViaProject (const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
 
ExecutionResult executeCompound (const RelCompound *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
 
ExecutionResult executeAggregate (const RelAggregate *aggregate, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
 
ExecutionResult executeProject (const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count)
 
ExecutionResult executeTableFunction (const RelTableFunction *, const CompilationOptions &, const ExecutionOptions &, const int64_t queue_time_ms)
 
void computeWindow (const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo, ColumnCacheMap &column_cache_map, const int64_t queue_time_ms)
 
std::unique_ptr
< WindowFunctionContext
createWindowFunctionContext (const Analyzer::WindowFunction *window_func, const std::shared_ptr< Analyzer::BinOper > &partition_key_cond, const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &query_infos, const CompilationOptions &co, ColumnCacheMap &column_cache_map)
 
ExecutionResult executeFilter (const RelFilter *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
 
ExecutionResult executeSort (const RelSort *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
 
ExecutionResult executeLogicalValues (const RelLogicalValues *, const ExecutionOptions &)
 
ExecutionResult executeModify (const RelModify *modify, const ExecutionOptions &eo)
 
WorkUnit createSortInputWorkUnit (const RelSort *, const bool just_explain)
 
ExecutionResult executeWorkUnit (const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
 
size_t getNDVEstimation (const WorkUnit &work_unit, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo)
 
ssize_t getFilteredCountAll (const WorkUnit &work_unit, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo)
 
FilterSelectivity getFilterSelectivity (const std::vector< std::shared_ptr< Analyzer::Expr >> &filter_expressions, const CompilationOptions &co, const ExecutionOptions &eo)
 
std::vector< PushedDownFilterInfoselectFiltersToBePushedDown (const RelAlgExecutor::WorkUnit &work_unit, const CompilationOptions &co, const ExecutionOptions &eo)
 
bool isRowidLookup (const WorkUnit &work_unit)
 
ExecutionResult handleOutOfMemoryRetry (const RelAlgExecutor::WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const bool was_multifrag_kernel_launch, const int64_t queue_time_ms)
 
WorkUnit createWorkUnit (const RelAlgNode *, const SortInfo &, const bool just_explain)
 
WorkUnit createCompoundWorkUnit (const RelCompound *, const SortInfo &, const bool just_explain)
 
WorkUnit createAggregateWorkUnit (const RelAggregate *, const SortInfo &, const bool just_explain)
 
WorkUnit createProjectWorkUnit (const RelProject *, const SortInfo &, const bool just_explain)
 
WorkUnit createFilterWorkUnit (const RelFilter *, const SortInfo &, const bool just_explain)
 
WorkUnit createJoinWorkUnit (const RelJoin *, const SortInfo &, const bool just_explain)
 
TableFunctionWorkUnit createTableFunctionWorkUnit (const RelTableFunction *table_func, const bool just_explain)
 
void addTemporaryTable (const int table_id, const ResultSetPtr &result)
 
void eraseFromTemporaryTables (const int table_id)
 
void handleNop (RaExecutionDesc &ed)
 
JoinQualsPerNestingLevel translateLeftDeepJoinFilter (const RelLeftDeepInnerJoin *join, const std::vector< InputDescriptor > &input_descs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain)
 
std::list< std::shared_ptr
< Analyzer::Expr > > 
makeJoinQuals (const RexScalar *join_condition, const std::vector< JoinType > &join_types, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain) const
 
- Private Member Functions inherited from StorageIOFacility< RelAlgExecutorTraits >
 StorageIOFacility (ExecutorType *executor, CatalogType const &catalog)
 
ColumnValidationFunction yieldColumnValidator (TableDescriptorType const *table_descriptor)
 
UpdateCallback yieldUpdateCallback (UpdateTransactionParameters &update_parameters)
 
UpdateCallback yieldDeleteCallback (DeleteTransactionParameters &delete_parameters)
 

Static Private Member Functions

static void handlePersistentError (const int32_t error_code)
 

Private Attributes

Executorexecutor_
 
const Catalog_Namespace::Catalogcat_
 
std::unique_ptr< RelAlgDagBuilderquery_dag_
 
std::shared_ptr< const
query_state::QueryState
query_state_
 
TemporaryTables temporary_tables_
 
time_t now_
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
target_exprs_owned_
 
std::unordered_map< unsigned,
AggregatedResult
leaf_results_
 
int64_t queue_time_ms_
 

Static Private Attributes

static SpeculativeTopNBlacklist speculative_topn_blacklist_
 
static const size_t max_groups_buffer_entry_default_guess {16384}
 

Friends

class PendingExecutionClosure
 

Additional Inherited Members

- Private Types inherited from StorageIOFacility< RelAlgExecutorTraits >
using ExecutorType = typename RelAlgExecutorTraits::ExecutorType
 
using CatalogType = typename RelAlgExecutorTraits::CatalogType
 
using FragmentUpdaterType = UpdateLogForFragment
 
using UpdateCallback = typename FragmentUpdaterType::Callback
 
using IOFacility = DefaultIOFacet<>
 
using TableDescriptorType = typename RelAlgExecutorTraits::TableDescriptorType
 
using DeleteVictimOffsetList = typename IOFacility::DeleteVictimOffsetList
 
using UpdateTargetOffsetList = typename IOFacility::UpdateTargetOffsetList
 
using UpdateTargetTypeList = typename IOFacility::UpdateTargetTypeList
 
using UpdateTargetColumnNamesList = typename IOFacility::UpdateTargetColumnNamesList
 
using UpdateTargetColumnNameType = typename UpdateTargetColumnNamesList::value_type
 
using ColumnValidationFunction = typename IOFacility::ColumnValidationFunction
 
using StringSelector = Experimental::MetaTypeClass< Experimental::String >
 
using NonStringSelector = Experimental::UncapturedMetaTypeClass
 

Detailed Description

Definition at line 54 of file RelAlgExecutor.h.

Member Typedef Documentation

Definition at line 56 of file RelAlgExecutor.h.

Constructor & Destructor Documentation

RelAlgExecutor::RelAlgExecutor ( Executor executor,
const Catalog_Namespace::Catalog cat,
std::shared_ptr< const query_state::QueryState query_state = nullptr 
)
inline

Definition at line 58 of file RelAlgExecutor.h.

61  : StorageIOFacility(executor, cat)
62  , executor_(executor)
63  , cat_(cat)
64  , query_state_(std::move(query_state))
65  , now_(0)
66  , queue_time_ms_(0) {}
int64_t queue_time_ms_
const Catalog_Namespace::Catalog & cat_
std::shared_ptr< const query_state::QueryState > query_state_
StorageIOFacility(ExecutorType *executor, CatalogType const &catalog)
Executor * executor_
RelAlgExecutor::RelAlgExecutor ( Executor executor,
const Catalog_Namespace::Catalog cat,
const std::string &  query_ra,
std::shared_ptr< const query_state::QueryState query_state = nullptr 
)
inline

Definition at line 68 of file RelAlgExecutor.h.

72  : StorageIOFacility(executor, cat)
73  , executor_(executor)
74  , cat_(cat)
75  , query_dag_(std::make_unique<RelAlgDagBuilder>(query_ra, cat_, nullptr))
76  , query_state_(std::move(query_state))
77  , now_(0)
78  , queue_time_ms_(0) {}
int64_t queue_time_ms_
const Catalog_Namespace::Catalog & cat_
std::shared_ptr< const query_state::QueryState > query_state_
StorageIOFacility(ExecutorType *executor, CatalogType const &catalog)
std::unique_ptr< RelAlgDagBuilder > query_dag_
Executor * executor_
RelAlgExecutor::RelAlgExecutor ( Executor executor,
const Catalog_Namespace::Catalog cat,
std::unique_ptr< RelAlgDagBuilder query_dag,
std::shared_ptr< const query_state::QueryState query_state = nullptr 
)
inline

Definition at line 80 of file RelAlgExecutor.h.

84  : StorageIOFacility(executor, cat)
85  , executor_(executor)
86  , cat_(cat)
87  , query_dag_(std::move(query_dag))
88  , query_state_(std::move(query_state))
89  , now_(0)
90  , queue_time_ms_(0) {}
int64_t queue_time_ms_
const Catalog_Namespace::Catalog & cat_
std::shared_ptr< const query_state::QueryState > query_state_
StorageIOFacility(ExecutorType *executor, CatalogType const &catalog)
std::unique_ptr< RelAlgDagBuilder > query_dag_
Executor * executor_

Member Function Documentation

void RelAlgExecutor::addLeafResult ( const unsigned  id,
const AggregatedResult result 
)
inline

Definition at line 127 of file RelAlgExecutor.h.

References CHECK(), and leaf_results_.

127  {
128  const auto it_ok = leaf_results_.emplace(id, result);
129  CHECK(it_ok.second);
130  }
std::unordered_map< unsigned, AggregatedResult > leaf_results_
CHECK(cgen_state)

+ Here is the call graph for this function:

void RelAlgExecutor::addTemporaryTable ( const int  table_id,
const ResultSetPtr result 
)
inlineprivate

Definition at line 325 of file RelAlgExecutor.h.

References CHECK(), CHECK_LT, and temporary_tables_.

Referenced by executeRelAlgStep(), and handleNop().

325  {
326  CHECK_LT(size_t(0), result->colCount());
327  CHECK_LT(table_id, 0);
328  const auto it_ok = temporary_tables_.emplace(table_id, result);
329  CHECK(it_ok.second);
330  }
TemporaryTables temporary_tables_
CHECK(cgen_state)
#define CHECK_LT(x, y)
Definition: Logger.h:203

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::cleanupPostExecution ( )

Definition at line 177 of file RelAlgExecutor.cpp.

References CHECK(), and executor_.

Referenced by executeRelAlgQueryNoRetry().

177  {
178  CHECK(executor_);
179  executor_->row_set_mem_owner_ = nullptr;
180  executor_->lit_str_dict_proxy_ = nullptr;
181 }
CHECK(cgen_state)
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

AggregatedColRange RelAlgExecutor::computeColRangesCache ( )

Definition at line 157 of file RelAlgExecutor.cpp.

References cat_, executor_, get_physical_inputs(), and getRootRelAlgNode().

157  {
158  AggregatedColRange agg_col_range_cache;
159  const auto phys_inputs = get_physical_inputs(cat_, &getRootRelAlgNode());
160  return executor_->computeColRangesCache(phys_inputs);
161 }
const Catalog_Namespace::Catalog & cat_
const RelAlgNode & getRootRelAlgNode() const
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)
Executor * executor_

+ Here is the call graph for this function:

StringDictionaryGenerations RelAlgExecutor::computeStringDictionaryGenerations ( )

Definition at line 163 of file RelAlgExecutor.cpp.

References cat_, executor_, get_physical_inputs(), and getRootRelAlgNode().

163  {
164  const auto phys_inputs = get_physical_inputs(cat_, &getRootRelAlgNode());
165  return executor_->computeStringDictionaryGenerations(phys_inputs);
166 }
const Catalog_Namespace::Catalog & cat_
const RelAlgNode & getRootRelAlgNode() const
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)
Executor * executor_

+ Here is the call graph for this function:

TableGenerations RelAlgExecutor::computeTableGenerations ( )

Definition at line 168 of file RelAlgExecutor.cpp.

References executor_, get_physical_table_inputs(), and getRootRelAlgNode().

168  {
169  const auto phys_table_ids = get_physical_table_inputs(&getRootRelAlgNode());
170  return executor_->computeTableGenerations(phys_table_ids);
171 }
const RelAlgNode & getRootRelAlgNode() const
Executor * executor_
std::unordered_set< int > get_physical_table_inputs(const RelAlgNode *ra)

+ Here is the call graph for this function:

void RelAlgExecutor::computeWindow ( const RelAlgExecutionUnit ra_exe_unit,
const CompilationOptions co,
const ExecutionOptions eo,
ColumnCacheMap column_cache_map,
const int64_t  queue_time_ms 
)
private

Definition at line 1364 of file RelAlgExecutor.cpp.

References CHECK_EQ, WindowProjectNodeContext::create(), createWindowFunctionContext(), executor_, get_table_infos(), Analyzer::WindowFunction::getPartitionKeys(), RelAlgExecutionUnit::input_descs, kBOOLEAN, kBW_EQ, kONE, RelAlgExecutionUnit::target_exprs, and anonymous_namespace{RelAlgExecutor.cpp}::transform_to_inner().

Referenced by executeWorkUnit().

1368  {
1369  auto query_infos = get_table_infos(ra_exe_unit.input_descs, executor_);
1370  CHECK_EQ(query_infos.size(), size_t(1));
1371  if (query_infos.front().info.fragments.size() != 1) {
1372  throw std::runtime_error(
1373  "Only single fragment tables supported for window functions for now");
1374  }
1375  query_infos.push_back(query_infos.front());
1376  auto window_project_node_context = WindowProjectNodeContext::create();
1377  for (size_t target_index = 0; target_index < ra_exe_unit.target_exprs.size();
1378  ++target_index) {
1379  const auto& target_expr = ra_exe_unit.target_exprs[target_index];
1380  const auto window_func = dynamic_cast<const Analyzer::WindowFunction*>(target_expr);
1381  if (!window_func) {
1382  continue;
1383  }
1384  // Always use baseline layout hash tables for now, make the expression a tuple.
1385  const auto& partition_keys = window_func->getPartitionKeys();
1386  std::shared_ptr<Analyzer::Expr> partition_key_tuple;
1387  if (partition_keys.size() > 1) {
1388  partition_key_tuple = makeExpr<Analyzer::ExpressionTuple>(partition_keys);
1389  } else {
1390  if (partition_keys.empty()) {
1391  throw std::runtime_error(
1392  "Empty window function partitions are not supported yet");
1393  }
1394  CHECK_EQ(partition_keys.size(), size_t(1));
1395  partition_key_tuple = partition_keys.front();
1396  }
1397  // Creates a tautology equality with the partition expression on both sides.
1398  const auto partition_key_cond =
1399  makeExpr<Analyzer::BinOper>(kBOOLEAN,
1400  kBW_EQ,
1401  kONE,
1402  partition_key_tuple,
1403  transform_to_inner(partition_key_tuple.get()));
1404  auto context = createWindowFunctionContext(
1405  window_func, partition_key_cond, ra_exe_unit, query_infos, co, column_cache_map);
1406  context->compute();
1407  window_project_node_context->addWindowFunctionContext(std::move(context),
1408  target_index);
1409  }
1410 }
std::vector< Analyzer::Expr * > target_exprs
#define CHECK_EQ(x, y)
Definition: Logger.h:201
const std::vector< InputDescriptor > input_descs
std::shared_ptr< Analyzer::Expr > transform_to_inner(const Analyzer::Expr *expr)
static WindowProjectNodeContext * create()
Definition: sqldefs.h:69
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
Definition: sqldefs.h:31
std::unique_ptr< WindowFunctionContext > createWindowFunctionContext(const Analyzer::WindowFunction *window_func, const std::shared_ptr< Analyzer::BinOper > &partition_key_cond, const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &query_infos, const CompilationOptions &co, ColumnCacheMap &column_cache_map)
const std::vector< std::shared_ptr< Analyzer::Expr > > & getPartitionKeys() const
Definition: Analyzer.h:1400
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutor::WorkUnit RelAlgExecutor::createAggregateWorkUnit ( const RelAggregate aggregate,
const SortInfo sort_info,
const bool  just_explain 
)
private

Definition at line 2704 of file RelAlgExecutor.cpp.

References cat_, CHECK_EQ, executor_, anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_nest_levels(), anonymous_namespace{RelAlgExecutor.cpp}::get_join_type(), anonymous_namespace{RelAlgExecutor.cpp}::get_targets_meta(), RelAlgNode::getInput(), RelAlgNode::getOutputMetainfo(), RelAlgNode::inputCount(), max_groups_buffer_entry_default_guess, now_, query_state_, RelAlgNode::setOutputMetainfo(), anonymous_namespace{RelAlgExecutor.cpp}::synthesize_inputs(), target_exprs_owned_, anonymous_namespace{RelAlgExecutor.cpp}::translate_groupby_exprs(), and anonymous_namespace{RelAlgExecutor.cpp}::translate_targets().

Referenced by createWorkUnit(), and executeAggregate().

2707  {
2708  std::vector<InputDescriptor> input_descs;
2709  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2710  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
2711  const auto input_to_nest_level = get_input_nest_levels(aggregate, {});
2712  std::tie(input_descs, input_col_descs, used_inputs_owned) =
2713  get_input_desc(aggregate, input_to_nest_level, {}, cat_);
2714  const auto join_type = get_join_type(aggregate);
2715  QueryFeatureDescriptor query_features;
2716  RelAlgTranslator translator(cat_,
2717  executor_,
2718  input_to_nest_level,
2719  {join_type},
2720  now_,
2721  just_explain,
2722  query_features);
2723  CHECK_EQ(size_t(1), aggregate->inputCount());
2724  const auto source = aggregate->getInput(0);
2725  const auto& in_metainfo = source->getOutputMetainfo();
2726  const auto scalar_sources =
2727  synthesize_inputs(aggregate, size_t(0), in_metainfo, input_to_nest_level);
2728  const auto groupby_exprs = translate_groupby_exprs(aggregate, scalar_sources);
2729  const auto target_exprs = translate_targets(
2730  target_exprs_owned_, scalar_sources, groupby_exprs, aggregate, translator);
2731  const auto targets_meta = get_targets_meta(aggregate, target_exprs);
2732  aggregate->setOutputMetainfo(targets_meta);
2733  return {RelAlgExecutionUnit{input_descs,
2734  input_col_descs,
2735  {},
2736  {},
2737  {},
2738  groupby_exprs,
2739  target_exprs,
2740  nullptr,
2741  sort_info,
2742  0,
2743  query_features,
2744  false,
2745  query_state_},
2746  aggregate,
2748  nullptr};
2749 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
std::vector< std::shared_ptr< Analyzer::Expr > > synthesize_inputs(const RelAlgNode *ra_node, const size_t nest_level, const std::vector< TargetMetaInfo > &in_metainfo, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
std::vector< Analyzer::Expr * > 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)
static const size_t max_groups_buffer_entry_default_guess
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
std::list< std::shared_ptr< Analyzer::Expr > > translate_groupby_exprs(const RelCompound *compound, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
const Catalog_Namespace::Catalog & cat_
const RelAlgNode * getInput(const size_t idx) const
JoinType get_join_type(const RelAlgNode *ra)
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
std::shared_ptr< const query_state::QueryState > query_state_
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
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)
const size_t inputCount() const
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutor::WorkUnit RelAlgExecutor::createCompoundWorkUnit ( const RelCompound compound,
const SortInfo sort_info,
const bool  just_explain 
)
private

Definition at line 2429 of file RelAlgExecutor.cpp.

References cat_, CHECK_EQ, anonymous_namespace{RelAlgExecutor.cpp}::do_table_reordering(), executor_, g_from_table_reordering, anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_nest_levels(), anonymous_namespace{RelAlgExecutor.cpp}::get_join_type(), anonymous_namespace{RelAlgExecutor.cpp}::get_left_deep_join_input_sizes(), get_table_infos(), anonymous_namespace{RelAlgExecutor.cpp}::get_targets_meta(), RelAlgNode::getInput(), RelAlgNode::inputCount(), LEFT, anonymous_namespace{RelAlgExecutor.cpp}::left_deep_join_types(), max_groups_buffer_entry_default_guess, now_, query_state_, anonymous_namespace{RelAlgExecutor.cpp}::rewrite_quals(), RelAlgNode::setOutputMetainfo(), RelAlgExecutionUnit::simple_quals, RelCompound::size(), target_exprs_owned_, anonymous_namespace{RelAlgExecutor.cpp}::translate_groupby_exprs(), anonymous_namespace{RelAlgExecutor.cpp}::translate_quals(), anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources(), anonymous_namespace{RelAlgExecutor.cpp}::translate_targets(), and translateLeftDeepJoinFilter().

Referenced by createWorkUnit(), executeCompound(), executeDeleteViaCompound(), and executeUpdateViaCompound().

2432  {
2433  std::vector<InputDescriptor> input_descs;
2434  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2435  auto input_to_nest_level = get_input_nest_levels(compound, {});
2436  std::tie(input_descs, input_col_descs, std::ignore) =
2437  get_input_desc(compound, input_to_nest_level, {}, cat_);
2438  const auto query_infos = get_table_infos(input_descs, executor_);
2439  CHECK_EQ(size_t(1), compound->inputCount());
2440  const auto left_deep_join =
2441  dynamic_cast<const RelLeftDeepInnerJoin*>(compound->getInput(0));
2442  JoinQualsPerNestingLevel left_deep_join_quals;
2443  const auto join_types = left_deep_join ? left_deep_join_types(left_deep_join)
2444  : std::vector<JoinType>{get_join_type(compound)};
2445  std::vector<size_t> input_permutation;
2446  std::vector<size_t> left_deep_join_input_sizes;
2447  if (left_deep_join) {
2448  left_deep_join_input_sizes = get_left_deep_join_input_sizes(left_deep_join);
2449  left_deep_join_quals = translateLeftDeepJoinFilter(
2450  left_deep_join, input_descs, input_to_nest_level, just_explain);
2452  std::find(join_types.begin(), join_types.end(), JoinType::LEFT) ==
2453  join_types.end()) {
2454  input_permutation = do_table_reordering(input_descs,
2455  input_col_descs,
2456  left_deep_join_quals,
2457  input_to_nest_level,
2458  compound,
2459  query_infos,
2460  executor_);
2461  input_to_nest_level = get_input_nest_levels(compound, input_permutation);
2462  std::tie(input_descs, input_col_descs, std::ignore) =
2463  get_input_desc(compound, input_to_nest_level, input_permutation, cat_);
2464  left_deep_join_quals = translateLeftDeepJoinFilter(
2465  left_deep_join, input_descs, input_to_nest_level, just_explain);
2466  }
2467  }
2468  QueryFeatureDescriptor query_features;
2469  RelAlgTranslator translator(cat_,
2470  executor_,
2471  input_to_nest_level,
2472  join_types,
2473  now_,
2474  just_explain,
2475  query_features);
2476  const auto scalar_sources = translate_scalar_sources(compound, translator);
2477  const auto groupby_exprs = translate_groupby_exprs(compound, scalar_sources);
2478  const auto quals_cf = translate_quals(compound, translator);
2479  const auto target_exprs = translate_targets(
2480  target_exprs_owned_, scalar_sources, groupby_exprs, compound, translator);
2481  CHECK_EQ(compound->size(), target_exprs.size());
2482  const RelAlgExecutionUnit exe_unit = {input_descs,
2483  input_col_descs,
2484  quals_cf.simple_quals,
2485  rewrite_quals(quals_cf.quals),
2486  left_deep_join_quals,
2487  groupby_exprs,
2488  target_exprs,
2489  nullptr,
2490  sort_info,
2491  0,
2492  query_features,
2493  false,
2494  query_state_};
2495  auto query_rewriter = std::make_unique<QueryRewriter>(query_infos, executor_);
2496  const auto rewritten_exe_unit = query_rewriter->rewrite(exe_unit);
2497  const auto targets_meta = get_targets_meta(compound, rewritten_exe_unit.target_exprs);
2498  compound->setOutputMetainfo(targets_meta);
2499  return {rewritten_exe_unit,
2500  compound,
2502  std::move(query_rewriter),
2503  input_permutation,
2504  left_deep_join_input_sizes};
2505 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
std::vector< JoinType > left_deep_join_types(const RelLeftDeepInnerJoin *left_deep_join)
JoinType
Definition: sqldefs.h:107
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< 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)
size_t size() const override
static const size_t max_groups_buffer_entry_default_guess
std::vector< JoinCondition > JoinQualsPerNestingLevel
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
bool g_from_table_reordering
Definition: Execute.cpp:77
std::list< std::shared_ptr< Analyzer::Expr > > translate_groupby_exprs(const RelCompound *compound, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
const Catalog_Namespace::Catalog & cat_
const RelAlgNode * getInput(const size_t idx) const
JoinType get_join_type(const RelAlgNode *ra)
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
std::vector< std::shared_ptr< Analyzer::Expr > > translate_scalar_sources(const RA *ra_node, const RelAlgTranslator &translator)
std::shared_ptr< const query_state::QueryState > query_state_
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
QualsConjunctiveForm translate_quals(const RelCompound *compound, const RelAlgTranslator &translator)
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)
const size_t inputCount() const
Executor * executor_
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
JoinQualsPerNestingLevel translateLeftDeepJoinFilter(const RelLeftDeepInnerJoin *join, const std::vector< InputDescriptor > &input_descs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain)
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)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutor::WorkUnit RelAlgExecutor::createFilterWorkUnit ( const RelFilter filter,
const SortInfo sort_info,
const bool  just_explain 
)
private

Definition at line 2939 of file RelAlgExecutor.cpp.

References cat_, CHECK_EQ, executor_, fold_expr(), get_exprs_not_owned(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_nest_levels(), anonymous_namespace{RelAlgExecutor.cpp}::get_inputs_meta(), anonymous_namespace{RelAlgExecutor.cpp}::get_join_type(), RelFilter::getCondition(), RelAlgNode::inputCount(), max_groups_buffer_entry_default_guess, now_, rewrite_expr(), RelAlgNode::setOutputMetainfo(), and target_exprs_owned_.

Referenced by createWorkUnit(), and executeFilter().

2941  {
2942  CHECK_EQ(size_t(1), filter->inputCount());
2943  std::vector<InputDescriptor> input_descs;
2944  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2945  std::vector<TargetMetaInfo> in_metainfo;
2946  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
2947  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned;
2948 
2949  const auto input_to_nest_level = get_input_nest_levels(filter, {});
2950  std::tie(input_descs, input_col_descs, used_inputs_owned) =
2951  get_input_desc(filter, input_to_nest_level, {}, cat_);
2952  const auto join_type = get_join_type(filter);
2953  QueryFeatureDescriptor query_features;
2954  RelAlgTranslator translator(cat_,
2955  executor_,
2956  input_to_nest_level,
2957  {join_type},
2958  now_,
2959  just_explain,
2960  query_features);
2961  std::tie(in_metainfo, target_exprs_owned) =
2962  get_inputs_meta(filter, translator, used_inputs_owned, input_to_nest_level);
2963  const auto filter_expr = translator.translateScalarRex(filter->getCondition());
2964  const auto qual = fold_expr(filter_expr.get());
2965  target_exprs_owned_.insert(
2966  target_exprs_owned_.end(), target_exprs_owned.begin(), target_exprs_owned.end());
2967  const auto target_exprs = get_exprs_not_owned(target_exprs_owned);
2968  filter->setOutputMetainfo(in_metainfo);
2969  const auto rewritten_qual = rewrite_expr(qual.get());
2970  return {{input_descs,
2971  input_col_descs,
2972  {},
2973  {rewritten_qual ? rewritten_qual : qual},
2974  {},
2975  {nullptr},
2976  target_exprs,
2977  nullptr,
2978  sort_info,
2979  0},
2980  filter,
2982  nullptr};
2983 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
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)
static const size_t max_groups_buffer_entry_default_guess
const RexScalar * getCondition() const
std::vector< Analyzer::Expr * > get_exprs_not_owned(const std::vector< std::shared_ptr< Analyzer::Expr >> &exprs)
Definition: Execute.h:213
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
const Catalog_Namespace::Catalog & cat_
JoinType get_join_type(const RelAlgNode *ra)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
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)
const size_t inputCount() const
Executor * executor_
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:

WorkUnit RelAlgExecutor::createJoinWorkUnit ( const RelJoin ,
const SortInfo ,
const bool  just_explain 
)
private
RelAlgExecutor::WorkUnit RelAlgExecutor::createProjectWorkUnit ( const RelProject project,
const SortInfo sort_info,
const bool  just_explain 
)
private

Definition at line 2751 of file RelAlgExecutor.cpp.

References cat_, anonymous_namespace{RelAlgExecutor.cpp}::do_table_reordering(), executor_, g_from_table_reordering, get_exprs_not_owned(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_nest_levels(), anonymous_namespace{RelAlgExecutor.cpp}::get_join_type(), anonymous_namespace{RelAlgExecutor.cpp}::get_left_deep_join_input_sizes(), get_table_infos(), anonymous_namespace{RelAlgExecutor.cpp}::get_targets_meta(), RelAlgNode::getInput(), anonymous_namespace{RelAlgExecutor.cpp}::left_deep_join_types(), max_groups_buffer_entry_default_guess, now_, query_state_, RelAlgNode::setOutputMetainfo(), target_exprs_owned_, anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources(), and translateLeftDeepJoinFilter().

Referenced by createWorkUnit(), executeDeleteViaProject(), executeProject(), and executeUpdateViaProject().

2753  {
2754  std::vector<InputDescriptor> input_descs;
2755  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2756  auto input_to_nest_level = get_input_nest_levels(project, {});
2757  std::tie(input_descs, input_col_descs, std::ignore) =
2758  get_input_desc(project, input_to_nest_level, {}, cat_);
2759  const auto query_infos = get_table_infos(input_descs, executor_);
2760 
2761  const auto left_deep_join =
2762  dynamic_cast<const RelLeftDeepInnerJoin*>(project->getInput(0));
2763  JoinQualsPerNestingLevel left_deep_join_quals;
2764  const auto join_types = left_deep_join ? left_deep_join_types(left_deep_join)
2765  : std::vector<JoinType>{get_join_type(project)};
2766  std::vector<size_t> input_permutation;
2767  std::vector<size_t> left_deep_join_input_sizes;
2768  if (left_deep_join) {
2769  left_deep_join_input_sizes = get_left_deep_join_input_sizes(left_deep_join);
2770  const auto query_infos = get_table_infos(input_descs, executor_);
2771  left_deep_join_quals = translateLeftDeepJoinFilter(
2772  left_deep_join, input_descs, input_to_nest_level, just_explain);
2774  input_permutation = do_table_reordering(input_descs,
2775  input_col_descs,
2776  left_deep_join_quals,
2777  input_to_nest_level,
2778  project,
2779  query_infos,
2780  executor_);
2781  input_to_nest_level = get_input_nest_levels(project, input_permutation);
2782  std::tie(input_descs, input_col_descs, std::ignore) =
2783  get_input_desc(project, input_to_nest_level, input_permutation, cat_);
2784  left_deep_join_quals = translateLeftDeepJoinFilter(
2785  left_deep_join, input_descs, input_to_nest_level, just_explain);
2786  }
2787  }
2788 
2789  QueryFeatureDescriptor query_features;
2790  RelAlgTranslator translator(cat_,
2791  executor_,
2792  input_to_nest_level,
2793  join_types,
2794  now_,
2795  just_explain,
2796  query_features);
2797  const auto target_exprs_owned = translate_scalar_sources(project, translator);
2798  target_exprs_owned_.insert(
2799  target_exprs_owned_.end(), target_exprs_owned.begin(), target_exprs_owned.end());
2800  const auto target_exprs = get_exprs_not_owned(target_exprs_owned);
2801  const RelAlgExecutionUnit exe_unit = {input_descs,
2802  input_col_descs,
2803  {},
2804  {},
2805  left_deep_join_quals,
2806  {nullptr},
2807  target_exprs,
2808  nullptr,
2809  sort_info,
2810  0,
2811  query_features,
2812  false,
2813  query_state_};
2814  auto query_rewriter = std::make_unique<QueryRewriter>(query_infos, executor_);
2815  const auto rewritten_exe_unit = query_rewriter->rewrite(exe_unit);
2816  const auto targets_meta = get_targets_meta(project, rewritten_exe_unit.target_exprs);
2817  project->setOutputMetainfo(targets_meta);
2818  return {rewritten_exe_unit,
2819  project,
2821  std::move(query_rewriter),
2822  input_permutation,
2823  left_deep_join_input_sizes};
2824 }
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
std::vector< JoinType > left_deep_join_types(const RelLeftDeepInnerJoin *left_deep_join)
JoinType
Definition: sqldefs.h:107
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)
static const size_t max_groups_buffer_entry_default_guess
std::vector< JoinCondition > JoinQualsPerNestingLevel
std::vector< Analyzer::Expr * > get_exprs_not_owned(const std::vector< std::shared_ptr< Analyzer::Expr >> &exprs)
Definition: Execute.h:213
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
bool g_from_table_reordering
Definition: Execute.cpp:77
const Catalog_Namespace::Catalog & cat_
const RelAlgNode * getInput(const size_t idx) const
JoinType get_join_type(const RelAlgNode *ra)
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
std::vector< std::shared_ptr< Analyzer::Expr > > translate_scalar_sources(const RA *ra_node, const RelAlgTranslator &translator)
std::shared_ptr< const query_state::QueryState > query_state_
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
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)
Executor * executor_
JoinQualsPerNestingLevel translateLeftDeepJoinFilter(const RelLeftDeepInnerJoin *join, const std::vector< InputDescriptor > &input_descs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain)
std::vector< size_t > get_left_deep_join_input_sizes(const RelLeftDeepInnerJoin *left_deep_join)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutor::WorkUnit RelAlgExecutor::createSortInputWorkUnit ( const RelSort sort,
const bool  just_explain 
)
private

Definition at line 1669 of file RelAlgExecutor.cpp.

References RelSort::collationCount(), SpeculativeTopNBlacklist::contains(), createWorkUnit(), Default, anonymous_namespace{RelAlgExecutor.cpp}::first_oe_is_desc(), anonymous_namespace{RelAlgExecutor.cpp}::get_order_entries(), anonymous_namespace{RelAlgExecutor.cpp}::get_scan_limit(), RelAlgNode::getInput(), RelSort::getLimit(), RelSort::getOffset(), RelAlgExecutionUnit::input_descs, max_groups_buffer_entry_default_guess, RelAlgNode::setOutputMetainfo(), speculative_topn_blacklist_, SpeculativeTopN, and StreamingTopN.

Referenced by executeRelAlgQuerySingleStep(), and executeSort().

1671  {
1672  const auto source = sort->getInput(0);
1673  const size_t limit = sort->getLimit();
1674  const size_t offset = sort->getOffset();
1675  const size_t scan_limit = sort->collationCount() ? 0 : get_scan_limit(source, limit);
1676  const size_t scan_total_limit =
1677  scan_limit ? get_scan_limit(source, scan_limit + offset) : 0;
1678  size_t max_groups_buffer_entry_guess{
1679  scan_total_limit ? scan_total_limit : max_groups_buffer_entry_default_guess};
1681  const auto order_entries = get_order_entries(sort);
1682  SortInfo sort_info{order_entries, sort_algorithm, limit, offset};
1683  auto source_work_unit = createWorkUnit(source, sort_info, just_explain);
1684  const auto& source_exe_unit = source_work_unit.exe_unit;
1685  if (source_exe_unit.groupby_exprs.size() == 1) {
1686  if (!source_exe_unit.groupby_exprs.front()) {
1687  sort_algorithm = SortAlgorithm::StreamingTopN;
1688  } else {
1689  if (speculative_topn_blacklist_.contains(source_exe_unit.groupby_exprs.front(),
1690  first_oe_is_desc(order_entries))) {
1691  sort_algorithm = SortAlgorithm::Default;
1692  }
1693  }
1694  }
1695 
1696  sort->setOutputMetainfo(source->getOutputMetainfo());
1697  // NB: the `body` field of the returned `WorkUnit` needs to be the `source` node,
1698  // not the `sort`. The aggregator needs the pre-sorted result from leaves.
1699  return {RelAlgExecutionUnit{source_exe_unit.input_descs,
1700  std::move(source_exe_unit.input_col_descs),
1701  source_exe_unit.simple_quals,
1702  source_exe_unit.quals,
1703  source_exe_unit.join_quals,
1704  source_exe_unit.groupby_exprs,
1705  source_exe_unit.target_exprs,
1706  nullptr,
1707  {sort_info.order_entries, sort_algorithm, limit, offset},
1708  scan_total_limit,
1709  source_exe_unit.query_features,
1710  source_exe_unit.use_bump_allocator,
1711  source_exe_unit.query_state},
1712  source,
1713  max_groups_buffer_entry_guess,
1714  std::move(source_work_unit.query_rewriter),
1715  source_work_unit.input_permutation,
1716  source_work_unit.left_deep_join_input_sizes};
1717 }
size_t getOffset() const
bool contains(const std::shared_ptr< Analyzer::Expr > expr, const bool desc) const
WorkUnit createWorkUnit(const RelAlgNode *, const SortInfo &, const bool just_explain)
size_t get_scan_limit(const RelAlgNode *ra, const size_t limit)
static SpeculativeTopNBlacklist speculative_topn_blacklist_
static const size_t max_groups_buffer_entry_default_guess
const std::vector< InputDescriptor > input_descs
SortAlgorithm
const RelAlgNode * getInput(const size_t idx) const
size_t collationCount() const
size_t getLimit() const
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
std::list< Analyzer::OrderEntry > get_order_entries(const RelSort *sort)
bool first_oe_is_desc(const std::list< Analyzer::OrderEntry > &order_entries)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutor::TableFunctionWorkUnit RelAlgExecutor::createTableFunctionWorkUnit ( const RelTableFunction table_func,
const bool  just_explain 
)
private

Definition at line 2826 of file RelAlgExecutor.cpp.

References cat_, CHECK_EQ, CHECK_GT, executor_, table_functions::TableFunctionsFactory::get(), get_exprs_not_owned(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc(), anonymous_namespace{RelAlgExecutor.cpp}::get_input_nest_levels(), get_table_infos(), anonymous_namespace{RelAlgExecutor.cpp}::get_targets_meta(), RelTableFunction::getColInputsSize(), RelTableFunction::getFunctionName(), table_functions::TableFunction::getOutputSQLType(), RelTableFunction::getTableFuncInputAt(), RelAlgNode::inputCount(), now_, RelAlgNode::setOutputMetainfo(), TableFunctionExecutionUnit::target_exprs, target_exprs_owned_, to_string(), and anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources().

Referenced by executeTableFunction().

2828  {
2829  std::vector<InputDescriptor> input_descs;
2830  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2831  auto input_to_nest_level = get_input_nest_levels(table_func, {});
2832  std::tie(input_descs, input_col_descs, std::ignore) =
2833  get_input_desc(table_func, input_to_nest_level, {}, cat_);
2834  const auto query_infos = get_table_infos(input_descs, executor_);
2835  CHECK_EQ(size_t(1), table_func->inputCount());
2836 
2837  QueryFeatureDescriptor query_features; // TODO(adb): remove/make optional
2838  RelAlgTranslator translator(
2839  cat_, executor_, input_to_nest_level, {}, now_, just_explain, query_features);
2840  const auto input_exprs_owned = translate_scalar_sources(table_func, translator);
2841  target_exprs_owned_.insert(
2842  target_exprs_owned_.end(), input_exprs_owned.begin(), input_exprs_owned.end());
2843  const auto input_exprs = get_exprs_not_owned(input_exprs_owned);
2844 
2845  std::vector<Analyzer::ColumnVar*> input_col_exprs;
2846  for (auto input_expr : input_exprs) {
2847  if (auto col_var = dynamic_cast<Analyzer::ColumnVar*>(input_expr)) {
2848  input_col_exprs.push_back(col_var);
2849  }
2850  }
2851  CHECK_EQ(input_col_exprs.size(), table_func->getColInputsSize());
2852 
2853  const auto& table_function_impl =
2855 
2856  std::vector<Analyzer::Expr*> table_func_outputs;
2857  for (size_t i = 0; i < table_function_impl.getOutputsSize(); i++) {
2858  const auto ti = table_function_impl.getOutputSQLType(i);
2859  target_exprs_owned_.push_back(std::make_shared<Analyzer::ColumnVar>(ti, 0, i, -1));
2860  table_func_outputs.push_back(target_exprs_owned_.back().get());
2861  }
2862 
2863  std::optional<size_t> output_row_multiplier;
2864  if (table_function_impl.hasUserSpecifiedOutputMultiplier()) {
2865  const auto parameter_index = table_function_impl.getOutputRowParameter();
2866  CHECK_GT(parameter_index, size_t(0));
2867  const auto parameter_expr = table_func->getTableFuncInputAt(parameter_index - 1);
2868  const auto parameter_expr_literal = dynamic_cast<const RexLiteral*>(parameter_expr);
2869  if (!parameter_expr_literal) {
2870  throw std::runtime_error(
2871  "Provided output buffer multiplier parameter is not a literal. Only literal "
2872  "values are supported with output buffer multiplier configured table "
2873  "functions.");
2874  }
2875  int64_t literal_val = parameter_expr_literal->getVal<int64_t>();
2876  if (literal_val < 0) {
2877  throw std::runtime_error("Provided output row multiplier " +
2878  std::to_string(literal_val) +
2879  " is not valid for table functions.");
2880  }
2881  output_row_multiplier = static_cast<size_t>(literal_val);
2882  }
2883 
2884  const TableFunctionExecutionUnit exe_unit = {
2885  input_descs,
2886  input_col_descs,
2887  input_exprs, // table function inputs
2888  input_col_exprs, // table function column inputs (duplicates w/ above)
2889  table_func_outputs, // table function projected exprs
2890  output_row_multiplier, // output buffer multiplier
2891  table_func->getFunctionName()};
2892  const auto targets_meta = get_targets_meta(table_func, exe_unit.target_exprs);
2893  table_func->setOutputMetainfo(targets_meta);
2894  return {exe_unit, table_func};
2895 }
SQLTypeInfo getOutputSQLType(const size_t idx) const
#define CHECK_EQ(x, y)
Definition: Logger.h:201
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
static const TableFunction & get(const std::string &name)
std::vector< Analyzer::Expr * > get_exprs_not_owned(const std::vector< std::shared_ptr< Analyzer::Expr >> &exprs)
Definition: Execute.h:213
#define CHECK_GT(x, y)
Definition: Logger.h:205
std::string to_string(char const *&&v)
size_t getColInputsSize() const
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
const Catalog_Namespace::Catalog & cat_
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
std::vector< std::shared_ptr< Analyzer::Expr > > translate_scalar_sources(const RA *ra_node, const RelAlgTranslator &translator)
const RexScalar * getTableFuncInputAt(const size_t idx) const
std::string getFunctionName() const
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
std::vector< Analyzer::Expr * > target_exprs
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)
const size_t inputCount() const
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr< WindowFunctionContext > RelAlgExecutor::createWindowFunctionContext ( const Analyzer::WindowFunction window_func,
const std::shared_ptr< Analyzer::BinOper > &  partition_key_cond,
const RelAlgExecutionUnit ra_exe_unit,
const std::vector< InputTableInfo > &  query_infos,
const CompilationOptions co,
ColumnCacheMap column_cache_map 
)
private

Definition at line 1412 of file RelAlgExecutor.cpp.

References CHECK(), CHECK_EQ, Data_Namespace::CPU_LEVEL, CompilationOptions::device_type_, executor_, ColumnFetcher::getOneColumnFragment(), Analyzer::WindowFunction::getOrderKeys(), GPU, Data_Namespace::GPU_LEVEL, and JoinHashTableInterface::OneToMany.

Referenced by computeWindow().

1418  {
1419  const auto memory_level = co.device_type_ == ExecutorDeviceType::GPU
1422  const auto join_table_or_err =
1423  executor_->buildHashTableForQualifier(partition_key_cond,
1424  query_infos,
1425  memory_level,
1427  column_cache_map);
1428  if (!join_table_or_err.fail_reason.empty()) {
1429  throw std::runtime_error(join_table_or_err.fail_reason);
1430  }
1431  CHECK(join_table_or_err.hash_table->getHashType() ==
1433  const auto& order_keys = window_func->getOrderKeys();
1434  std::vector<std::shared_ptr<Chunk_NS::Chunk>> chunks_owner;
1435  const size_t elem_count = query_infos.front().info.fragments.front().getNumTuples();
1436  auto context = std::make_unique<WindowFunctionContext>(
1437  window_func, join_table_or_err.hash_table, elem_count, co.device_type_);
1438  for (const auto& order_key : order_keys) {
1439  const auto order_col =
1440  std::dynamic_pointer_cast<const Analyzer::ColumnVar>(order_key);
1441  if (!order_col) {
1442  throw std::runtime_error("Only order by columns supported for now");
1443  }
1444  const int8_t* column;
1445  size_t join_col_elem_count;
1446  std::tie(column, join_col_elem_count) =
1448  *order_col,
1449  query_infos.front().info.fragments.front(),
1450  memory_level,
1451  0,
1452  chunks_owner,
1453  column_cache_map);
1454  CHECK_EQ(join_col_elem_count, elem_count);
1455  context->addOrderColumn(column, order_col.get(), chunks_owner);
1456  }
1457  return context;
1458 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
const std::vector< std::shared_ptr< Analyzer::Expr > > & getOrderKeys() const
Definition: Analyzer.h:1404
CHECK(cgen_state)
static std::pair< const int8_t *, size_t > getOneColumnFragment(Executor *executor, const Analyzer::ColumnVar &hash_col, const Fragmenter_Namespace::FragmentInfo &fragment, const Data_Namespace::MemoryLevel effective_mem_lvl, const int device_id, std::vector< std::shared_ptr< Chunk_NS::Chunk >> &chunks_owner, ColumnCacheMap &column_cache)
ExecutorDeviceType device_type_
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutor::WorkUnit RelAlgExecutor::createWorkUnit ( const RelAlgNode node,
const SortInfo sort_info,
const bool  just_explain 
)
private

Definition at line 2260 of file RelAlgExecutor.cpp.

References CHECK(), createAggregateWorkUnit(), createCompoundWorkUnit(), createFilterWorkUnit(), and createProjectWorkUnit().

Referenced by createSortInputWorkUnit().

2262  {
2263  const auto compound = dynamic_cast<const RelCompound*>(node);
2264  if (compound) {
2265  return createCompoundWorkUnit(compound, sort_info, just_explain);
2266  }
2267  const auto project = dynamic_cast<const RelProject*>(node);
2268  if (project) {
2269  return createProjectWorkUnit(project, sort_info, just_explain);
2270  }
2271  const auto aggregate = dynamic_cast<const RelAggregate*>(node);
2272  if (aggregate) {
2273  return createAggregateWorkUnit(aggregate, sort_info, just_explain);
2274  }
2275  const auto filter = dynamic_cast<const RelFilter*>(node);
2276  CHECK(filter);
2277  return createFilterWorkUnit(filter, sort_info, just_explain);
2278 }
WorkUnit createProjectWorkUnit(const RelProject *, const SortInfo &, const bool just_explain)
WorkUnit createAggregateWorkUnit(const RelAggregate *, const SortInfo &, const bool just_explain)
WorkUnit createCompoundWorkUnit(const RelCompound *, const SortInfo &, const bool just_explain)
CHECK(cgen_state)
WorkUnit createFilterWorkUnit(const RelFilter *, const SortInfo &, const bool just_explain)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::eraseFromTemporaryTables ( const int  table_id)
inlineprivate

Definition at line 332 of file RelAlgExecutor.h.

References temporary_tables_.

332 { temporary_tables_.erase(table_id); }
TemporaryTables temporary_tables_
ExecutionResult RelAlgExecutor::executeAggregate ( const RelAggregate aggregate,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1237 of file RelAlgExecutor.cpp.

References createAggregateWorkUnit(), Default, executeWorkUnit(), RelAlgNode::getOutputMetainfo(), and ExecutionOptions::just_explain.

Referenced by executeRelAlgStep().

1241  {
1242  const auto work_unit = createAggregateWorkUnit(
1243  aggregate, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1244  return executeWorkUnit(work_unit,
1245  aggregate->getOutputMetainfo(),
1246  true,
1247  co,
1248  eo,
1249  render_info,
1250  queue_time_ms);
1251 }
WorkUnit createAggregateWorkUnit(const RelAggregate *, const SortInfo &, const bool just_explain)
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
const std::vector< TargetMetaInfo > & getOutputMetainfo() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeCompound ( const RelCompound compound,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1220 of file RelAlgExecutor.cpp.

References createCompoundWorkUnit(), Default, executeWorkUnit(), RelAlgNode::getOutputMetainfo(), RelCompound::isAggregate(), and ExecutionOptions::just_explain.

Referenced by executeRelAlgStep().

1224  {
1225  const auto work_unit = createCompoundWorkUnit(
1226  compound, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1227  CompilationOptions co_compound = co;
1228  return executeWorkUnit(work_unit,
1229  compound->getOutputMetainfo(),
1230  compound->isAggregate(),
1231  co_compound,
1232  eo,
1233  render_info,
1234  queue_time_ms);
1235 }
WorkUnit createCompoundWorkUnit(const RelCompound *, const SortInfo &, const bool just_explain)
bool isAggregate() const
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
const std::vector< TargetMetaInfo > & getOutputMetainfo() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::executeDeleteViaCompound ( const RelCompound compound,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1128 of file RelAlgExecutor.cpp.

References cat_, CPU, createCompoundWorkUnit(), Default, CompilationOptions::device_type_, executor_, get_table_infos(), ModifyManipulationTarget::getModifiedTableDescriptor(), logger::INFO, CacheInvalidator< CACHE_HOLDING_TYPES >::invalidateCaches(), RelCompound::isAggregate(), ExecutionOptions::just_explain, LOG, table_is_temporary(), and StorageIOFacility< RelAlgExecutorTraits >::yieldDeleteCallback().

Referenced by executeRelAlgStep().

1132  {
1133  auto* table_descriptor = compound->getModifiedTableDescriptor();
1134  if (!table_descriptor->hasDeletedCol) {
1135  throw std::runtime_error(
1136  "DELETE only supported on tables with the vacuum attribute set to 'delayed'");
1137  }
1138  if (table_is_temporary(table_descriptor)) {
1139  throw std::runtime_error("DELETE not yet supported on temporary tables.");
1140  }
1141 
1142  const auto work_unit = createCompoundWorkUnit(
1143  compound, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1144  const auto table_infos = get_table_infos(work_unit.exe_unit, executor_);
1145  CompilationOptions co_project = co;
1147 
1148  try {
1150 
1151  DeleteTransactionParameters delete_params;
1152  auto delete_callback = yieldDeleteCallback(delete_params);
1153 
1154  executor_->executeUpdate(work_unit.exe_unit,
1155  table_infos,
1156  co_project,
1157  eo,
1158  cat_,
1159  executor_->row_set_mem_owner_,
1160  delete_callback,
1161  compound->isAggregate());
1162  delete_params.finalizeTransaction();
1163  } catch (...) {
1164  LOG(INFO) << "Delete operation failed.";
1165  throw;
1166  }
1167 }
#define LOG(tag)
Definition: Logger.h:188
WorkUnit createCompoundWorkUnit(const RelCompound *, const SortInfo &, const bool just_explain)
static void invalidateCaches()
const Catalog_Namespace::Catalog & cat_
bool table_is_temporary(const TableDescriptor *td)
ExecutorDeviceType device_type_
UpdateCallback yieldDeleteCallback(DeleteTransactionParameters &delete_parameters)
bool isAggregate() const
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
Executor * executor_
TableDescriptor const * getModifiedTableDescriptor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::executeDeleteViaProject ( const RelProject project,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1169 of file RelAlgExecutor.cpp.

References cat_, CHECK(), CHECK_EQ, CPU, createProjectWorkUnit(), Default, CompilationOptions::device_type_, executor_, get_table_infos(), get_temporary_table(), RelAlgNode::getInput(), ModifyManipulationTarget::getModifiedTableDescriptor(), logger::INFO, RelAlgNode::inputCount(), CacheInvalidator< CACHE_HOLDING_TYPES >::invalidateCaches(), RelProject::isSimple(), ExecutionOptions::just_explain, LOG, table_is_temporary(), temporary_tables_, and StorageIOFacility< RelAlgExecutorTraits >::yieldDeleteCallback().

Referenced by executeRelAlgStep().

1173  {
1174  auto* table_descriptor = project->getModifiedTableDescriptor();
1175  if (!table_descriptor->hasDeletedCol) {
1176  throw std::runtime_error(
1177  "DELETE only supported on tables with the vacuum attribute set to 'delayed'");
1178  }
1179  if (table_is_temporary(table_descriptor)) {
1180  throw std::runtime_error("DELETE not yet supported on temporary tables.");
1181  }
1182 
1183  auto work_unit =
1184  createProjectWorkUnit(project, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1185  const auto table_infos = get_table_infos(work_unit.exe_unit, executor_);
1186  CompilationOptions co_project = co;
1188 
1189  if (project->isSimple()) {
1190  CHECK_EQ(size_t(1), project->inputCount());
1191  const auto input_ra = project->getInput(0);
1192  if (dynamic_cast<const RelSort*>(input_ra)) {
1193  const auto& input_table =
1194  get_temporary_table(&temporary_tables_, -input_ra->getId());
1195  CHECK(input_table);
1196  work_unit.exe_unit.scan_limit = input_table->rowCount();
1197  }
1198  }
1199 
1200  try {
1202 
1203  DeleteTransactionParameters delete_params;
1204  auto delete_callback = yieldDeleteCallback(delete_params);
1205 
1206  executor_->executeUpdate(work_unit.exe_unit,
1207  table_infos,
1208  co_project,
1209  eo,
1210  cat_,
1211  executor_->row_set_mem_owner_,
1212  delete_callback);
1213  delete_params.finalizeTransaction();
1214  } catch (...) {
1215  LOG(INFO) << "Delete operation failed.";
1216  throw;
1217  }
1218 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
WorkUnit createProjectWorkUnit(const RelProject *, const SortInfo &, const bool just_explain)
#define LOG(tag)
Definition: Logger.h:188
TemporaryTables temporary_tables_
static void invalidateCaches()
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
Definition: Execute.h:178
CHECK(cgen_state)
const Catalog_Namespace::Catalog & cat_
const RelAlgNode * getInput(const size_t idx) const
bool table_is_temporary(const TableDescriptor *td)
bool isSimple() const
ExecutorDeviceType device_type_
UpdateCallback yieldDeleteCallback(DeleteTransactionParameters &delete_parameters)
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
const size_t inputCount() const
Executor * executor_
TableDescriptor const * getModifiedTableDescriptor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeFilter ( const RelFilter filter,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1460 of file RelAlgExecutor.cpp.

References createFilterWorkUnit(), Default, executeWorkUnit(), RelAlgNode::getOutputMetainfo(), and ExecutionOptions::just_explain.

Referenced by executeRelAlgStep().

1464  {
1465  const auto work_unit =
1466  createFilterWorkUnit(filter, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1467  return executeWorkUnit(
1468  work_unit, filter->getOutputMetainfo(), false, co, eo, render_info, queue_time_ms);
1469 }
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
WorkUnit createFilterWorkUnit(const RelFilter *, const SortInfo &, const bool just_explain)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeLogicalValues ( const RelLogicalValues logical_values,
const ExecutionOptions eo 
)
private

Definition at line 1487 of file RelAlgExecutor.cpp.

References QueryMemoryDescriptor::addColSlotInfo(), CPU, executor_, RelLogicalValues::getTupleType(), ExecutionOptions::just_explain, kCOUNT, kNULLT, NonGroupedAggregate, query_mem_desc, and RelAlgNode::setOutputMetainfo().

Referenced by executeRelAlgStep().

1489  {
1490  if (eo.just_explain) {
1491  throw std::runtime_error("EXPLAIN not supported for LogicalValues");
1492  }
1494  1,
1496  /*is_table_function=*/false);
1497 
1498  const auto& tuple_type = logical_values->getTupleType();
1499  for (size_t i = 0; i < tuple_type.size(); ++i) {
1500  query_mem_desc.addColSlotInfo({std::make_tuple(8, 8)});
1501  }
1502  logical_values->setOutputMetainfo(tuple_type);
1503  std::vector<std::unique_ptr<Analyzer::ColumnVar>> owned_column_expressions;
1504  std::vector<Analyzer::Expr*> target_expressions;
1505  for (const auto& tuple_component : tuple_type) {
1506  const auto column_var =
1507  new Analyzer::ColumnVar(tuple_component.get_type_info(), 0, 0, 0);
1508  target_expressions.push_back(column_var);
1509  owned_column_expressions.emplace_back(column_var);
1510  }
1511  std::vector<TargetInfo> target_infos;
1512  for (const auto& tuple_type_component : tuple_type) {
1513  target_infos.emplace_back(TargetInfo{false,
1514  kCOUNT,
1515  tuple_type_component.get_type_info(),
1516  SQLTypeInfo(kNULLT, false),
1517  false,
1518  false});
1519  }
1520  auto rs = std::make_shared<ResultSet>(target_infos,
1523  executor_->getRowSetMemoryOwner(),
1524  executor_);
1525  return {rs, tuple_type};
1526 }
const std::vector< TargetMetaInfo > getTupleType() const
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
Definition: sqldefs.h:76
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeModify ( const RelModify modify,
const ExecutionOptions eo 
)
private

Definition at line 1471 of file RelAlgExecutor.cpp.

References CPU, executor_, and ExecutionOptions::just_explain.

Referenced by executeRelAlgStep().

1472  {
1473  if (eo.just_explain) {
1474  throw std::runtime_error("EXPLAIN not supported for ModifyTable");
1475  }
1476 
1477  auto rs = std::make_shared<ResultSet>(TargetInfoList{},
1480  executor_->getRowSetMemoryOwner(),
1481  executor_);
1482 
1483  std::vector<TargetMetaInfo> empty_targets;
1484  return {rs, empty_targets};
1485 }
std::vector< TargetInfo > TargetInfoList
Executor * executor_

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeProject ( const RelProject project,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms,
const ssize_t  previous_count 
)
private

Definition at line 1266 of file RelAlgExecutor.cpp.

References CHECK(), CHECK_EQ, CPU, createProjectWorkUnit(), Default, executeWorkUnit(), get_temporary_table(), RelAlgNode::getInput(), RelAlgNode::getOutputMetainfo(), RelAlgNode::inputCount(), RelProject::isSimple(), ExecutionOptions::just_explain, and temporary_tables_.

Referenced by executeRelAlgStep().

1271  {
1272  auto work_unit =
1273  createProjectWorkUnit(project, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1274  CompilationOptions co_project = co;
1275  if (project->isSimple()) {
1276  CHECK_EQ(size_t(1), project->inputCount());
1277  const auto input_ra = project->getInput(0);
1278  if (dynamic_cast<const RelSort*>(input_ra)) {
1279  co_project.device_type_ = ExecutorDeviceType::CPU;
1280  const auto& input_table =
1281  get_temporary_table(&temporary_tables_, -input_ra->getId());
1282  CHECK(input_table);
1283  work_unit.exe_unit.scan_limit =
1284  std::min(input_table->getLimit(), input_table->rowCount());
1285  }
1286  }
1287  return executeWorkUnit(work_unit,
1288  project->getOutputMetainfo(),
1289  false,
1290  co_project,
1291  eo,
1292  render_info,
1293  queue_time_ms,
1294  previous_count);
1295 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
WorkUnit createProjectWorkUnit(const RelProject *, const SortInfo &, const bool just_explain)
TemporaryTables temporary_tables_
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
Definition: Execute.h:178
CHECK(cgen_state)
const RelAlgNode * getInput(const size_t idx) const
bool isSimple() const
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
const size_t inputCount() const
const std::vector< TargetMetaInfo > & getOutputMetainfo() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeRelAlgQuery ( const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info 
)

Definition at line 67 of file RelAlgExecutor.cpp.

References CHECK(), CPU, DEBUG_TIMER, executeRelAlgQueryNoRetry(), CompilationOptions::explain_type_, g_allow_cpu_retry, CompilationOptions::hoist_literals_, logger::INFO, INJECT_TIMER, LOG, CompilationOptions::opt_level_, query_dag_, CompilationOptions::register_intel_jit_listener_, RenderInfo::setForceNonInSituData(), and CompilationOptions::with_dynamic_watchdog_.

69  {
71  auto timer = DEBUG_TIMER(__func__);
73  try {
74  return executeRelAlgQueryNoRetry(co, eo, render_info);
75  } catch (const QueryMustRunOnCpu&) {
76  if (!g_allow_cpu_retry) {
77  throw;
78  }
79  }
80  LOG(INFO) << "Query unable to run in GPU mode, retrying on CPU";
82  co.hoist_literals_,
83  co.opt_level_,
85  co.explain_type_,
87  if (render_info) {
88  render_info->setForceNonInSituData();
89  }
90  return executeRelAlgQueryNoRetry(co_cpu, eo, render_info);
91 }
void setForceNonInSituData()
Definition: RenderInfo.cpp:42
#define LOG(tag)
Definition: Logger.h:188
const ExecutorOptLevel opt_level_
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
const bool register_intel_jit_listener_
ExecutionResult executeRelAlgQueryNoRetry(const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
const ExecutorExplainType explain_type_
#define DEBUG_TIMER(name)
Definition: Logger.h:299
std::unique_ptr< RelAlgDagBuilder > query_dag_
bool g_allow_cpu_retry
Definition: Execute.cpp:74
const bool with_dynamic_watchdog_
ExecutionResult executeRelAlgQuery(const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)

+ Here is the call graph for this function:

ExecutionResult RelAlgExecutor::executeRelAlgQueryNoRetry ( const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info 
)
private

Definition at line 93 of file RelAlgExecutor.cpp.

References cat_, CHECK(), cleanupPostExecution(), RenderInfo::disallow_in_situ_only_if_final_ED_is_aggregate, executeRelAlgQueryWithFilterPushDown(), executeRelAlgSeq(), executor_, ExecutionOptions::find_push_down_candidates, g_enable_dynamic_watchdog, get_physical_inputs(), get_physical_table_inputs(), getSubqueries(), INJECT_TIMER, query_dag_, query_state_, run_benchmark_import::result, RenderInfo::row_set_mem_owner, RenderInfo::setInSituDataIfUnset(), timer_start(), and timer_stop().

Referenced by executeRelAlgQuery().

95  {
97 
98  query_dag_->resetQueryExecutionState();
99  const auto& ra = query_dag_->getRootNode();
100 
101  // capture the lock acquistion time
102  auto clock_begin = timer_start();
103  std::lock_guard<std::mutex> lock(executor_->execute_mutex_);
104  int64_t queue_time_ms = timer_stop(clock_begin);
106  executor_->resetInterrupt();
107  }
108  ScopeGuard row_set_holder = [this, &render_info] {
109  if (render_info) {
110  // need to hold onto the RowSetMemOwner for potential
111  // string id lookups during render vega validation
112  render_info->row_set_mem_owner = executor_->row_set_mem_owner_;
113  }
115  };
116  const auto phys_inputs = get_physical_inputs(cat_, &ra);
117  const auto phys_table_ids = get_physical_table_inputs(&ra);
118  executor_->setCatalog(&cat_);
119  executor_->setupCaching(phys_inputs, phys_table_ids);
120 
121  ScopeGuard restore_metainfo_cache = [this] { executor_->clearMetaInfoCache(); };
122  auto ed_seq = RaExecutionSequence(&ra);
123 
124  if (render_info) {
125  // set render to be non-insitu in certain situations.
127  ed_seq.size() > 1) {
128  // old logic
129  // disallow if more than one ED
130  render_info->setInSituDataIfUnset(false);
131  }
132  }
133 
134  if (eo.find_push_down_candidates) {
135  // this extra logic is mainly due to current limitations on multi-step queries
136  // and/or subqueries.
138  ed_seq, co, eo, render_info, queue_time_ms);
139  }
140 
141  // Dispatch the subqueries first
142  for (auto subquery : getSubqueries()) {
143  const auto subquery_ra = subquery->getRelAlg();
144  CHECK(subquery_ra);
145  if (subquery_ra->hasContextData()) {
146  continue;
147  }
148  // Execute the subquery and cache the result.
149  RelAlgExecutor ra_executor(executor_, cat_, query_state_);
150  RaExecutionSequence subquery_seq(subquery_ra);
151  auto result = ra_executor.executeRelAlgSeq(subquery_seq, co, eo, nullptr, 0);
152  subquery->setExecutionResult(std::make_shared<ExecutionResult>(result));
153  }
154  return executeRelAlgSeq(ed_seq, co, eo, render_info, queue_time_ms);
155 }
ExecutionResult executeRelAlgSeq(const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms, const bool with_existing_temp_tables=false)
std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner
Definition: RenderInfo.h:34
ExecutionResult executeRelAlgQueryWithFilterPushDown(const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
bool setInSituDataIfUnset(const bool is_in_situ_data)
Definition: RenderInfo.cpp:95
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:46
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:72
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const noexcept
bool disallow_in_situ_only_if_final_ED_is_aggregate
Definition: RenderInfo.h:42
const bool find_push_down_candidates
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
A container for relational algebra descriptors defining the execution order for a relational algebra ...
const Catalog_Namespace::Catalog & cat_
ExecutionResult executeRelAlgQueryNoRetry(const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
std::shared_ptr< const query_state::QueryState > query_state_
std::unique_ptr< RelAlgDagBuilder > query_dag_
void cleanupPostExecution()
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)
Executor * executor_
std::unordered_set< int > get_physical_table_inputs(const RelAlgNode *ra)
Type timer_start()
Definition: measure.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

FirstStepExecutionResult RelAlgExecutor::executeRelAlgQuerySingleStep ( const RaExecutionSequence seq,
const size_t  step_idx,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info 
)

Definition at line 195 of file RelAlgExecutor.cpp.

References CHECK(), CHECK_EQ, anonymous_namespace{RelAlgExecutor.cpp}::check_sort_node_source_constraint(), createSortInputWorkUnit(), executeRelAlgSubSeq(), executor_, RaExecutionSequence::getDescriptor(), INJECT_TIMER, ExecutionOptions::just_explain, anonymous_namespace{RelAlgExecutor.cpp}::node_is_aggregate(), queue_time_ms_, Reduce, GroupByAndAggregate::shard_count_for_top_groups(), and Union.

200  {
201  INJECT_TIMER(executeRelAlgQueryStep);
202  auto exe_desc_ptr = seq.getDescriptor(step_idx);
203  CHECK(exe_desc_ptr);
204  const auto sort = dynamic_cast<const RelSort*>(exe_desc_ptr->getBody());
205 
206  size_t shard_count{0};
207  auto merge_type = [&shard_count](const RelAlgNode* body) -> MergeType {
208  return node_is_aggregate(body) && !shard_count ? MergeType::Reduce : MergeType::Union;
209  };
210 
211  if (sort) {
213  const auto source_work_unit = createSortInputWorkUnit(sort, eo.just_explain);
215  source_work_unit.exe_unit, *executor_->getCatalog());
216  if (!shard_count) {
217  // No point in sorting on the leaf, only execute the input to the sort node.
218  CHECK_EQ(size_t(1), sort->inputCount());
219  const auto source = sort->getInput(0);
220  if (sort->collationCount() || node_is_aggregate(source)) {
221  auto temp_seq = RaExecutionSequence(std::make_unique<RaExecutionDesc>(source));
222  CHECK_EQ(temp_seq.size(), size_t(1));
223  // Use subseq to avoid clearing existing temporary tables
224  return {executeRelAlgSubSeq(temp_seq, std::make_pair(0, 1), co, eo, nullptr, 0),
225  merge_type(source),
226  source->getId(),
227  false};
228  }
229  }
230  }
231  return {executeRelAlgSubSeq(seq,
232  std::make_pair(step_idx, step_idx + 1),
233  co,
234  eo,
235  render_info,
237  merge_type(exe_desc_ptr->getBody()),
238  exe_desc_ptr->getBody()->getId(),
239  false};
240 }
int64_t queue_time_ms_
#define CHECK_EQ(x, y)
Definition: Logger.h:201
RaExecutionDesc * getDescriptor(size_t idx) const
void check_sort_node_source_constraint(const RelSort *sort)
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
MergeType
A container for relational algebra descriptors defining the execution order for a relational algebra ...
ExecutionResult executeRelAlgSubSeq(const RaExecutionSequence &seq, const std::pair< size_t, size_t > interval, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
bool node_is_aggregate(const RelAlgNode *ra)
WorkUnit createSortInputWorkUnit(const RelSort *, const bool just_explain)
Executor * executor_
static size_t shard_count_for_top_groups(const RelAlgExecutionUnit &ra_exe_unit, const Catalog_Namespace::Catalog &catalog)

+ Here is the call graph for this function:

ExecutionResult RelAlgExecutor::executeRelAlgQueryWithFilterPushDown ( const RaExecutionSequence seq,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)

Definition at line 154 of file JoinFilterPushDown.cpp.

References ExecutionOptions::allow_loop_joins, ExecutionOptions::allow_multifrag, cat_, CHECK(), ExecutionOptions::dynamic_watchdog_time_limit, executeRelAlgSeq(), executor_, ExecutionOptions::find_push_down_candidates, getSubqueries(), ExecutionOptions::gpu_input_mem_limit_percent, ExecutionOptions::jit_debug, ExecutionOptions::just_calcite_explain, ExecutionOptions::just_explain, ExecutionOptions::just_validate, ExecutionOptions::output_columnar_hint, run_benchmark_import::result, RaExecutionSequence::size(), ExecutionOptions::with_dynamic_watchdog, and ExecutionOptions::with_watchdog.

Referenced by executeRelAlgQueryNoRetry().

159  {
160  // we currently do not fully support filter push down with
161  // multi-step execution and/or with subqueries
162  // TODO(Saman): add proper caching to enable filter push down for all cases
163  const auto& subqueries = getSubqueries();
164  if (seq.size() > 1 || !subqueries.empty()) {
165  if (eo.just_calcite_explain) {
166  return ExecutionResult(std::vector<PushedDownFilterInfo>{},
168  }
169  const ExecutionOptions eo_modified{eo.output_columnar_hint,
170  eo.allow_multifrag,
171  eo.just_explain,
172  eo.allow_loop_joins,
173  eo.with_watchdog,
174  eo.jit_debug,
175  eo.just_validate,
178  /*find_push_down_candidates=*/false,
179  /*just_calcite_explain=*/false,
181 
182  // Dispatch the subqueries first
183  for (auto subquery : subqueries) {
184  // Execute the subquery and cache the result.
185  RelAlgExecutor ra_executor(executor_, cat_);
186  const auto subquery_ra = subquery->getRelAlg();
187  CHECK(subquery_ra);
188  RaExecutionSequence subquery_seq(subquery_ra);
189  auto result = ra_executor.executeRelAlgSeq(subquery_seq, co, eo, nullptr, 0);
190  subquery->setExecutionResult(std::make_shared<ExecutionResult>(result));
191  }
192  return executeRelAlgSeq(seq, co, eo_modified, render_info, queue_time_ms);
193  }
194  // else
195 
196  // Dispatch the subqueries first
197  for (auto subquery : subqueries) {
198  // Execute the subquery and cache the result.
199  RelAlgExecutor ra_executor(executor_, cat_);
200  const auto subquery_ra = subquery->getRelAlg();
201  CHECK(subquery_ra);
202  RaExecutionSequence subquery_seq(subquery_ra);
203  auto result = ra_executor.executeRelAlgSeq(subquery_seq, co, eo, nullptr, 0);
204  subquery->setExecutionResult(std::make_shared<ExecutionResult>(result));
205  }
206  return executeRelAlgSeq(seq, co, eo, render_info, queue_time_ms);
207 }
ExecutionResult executeRelAlgSeq(const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms, const bool with_existing_temp_tables=false)
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const noexcept
const bool allow_multifrag
const bool find_push_down_candidates
CHECK(cgen_state)
const bool just_validate
const bool with_dynamic_watchdog
const double gpu_input_mem_limit_percent
A container for relational algebra descriptors defining the execution order for a relational algebra ...
const Catalog_Namespace::Catalog & cat_
const bool output_columnar_hint
const bool just_calcite_explain
const bool allow_loop_joins
const unsigned dynamic_watchdog_time_limit
Executor * executor_
const bool with_watchdog

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeRelAlgSeq ( const RaExecutionSequence seq,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms,
const bool  with_existing_temp_tables = false 
)

Definition at line 258 of file RelAlgExecutor.cpp.

References cat_, CHECK(), RaExecutionSequence::empty(), executeRelAlgStep(), executor_, RaExecutionSequence::getDescriptor(), INJECT_TIMER, ExecutionOptions::just_explain, now_, RaExecutionSequence::size(), target_exprs_owned_, and temporary_tables_.

Referenced by executeRelAlgQueryNoRetry(), and executeRelAlgQueryWithFilterPushDown().

263  {
265  if (!with_existing_temp_tables) {
266  decltype(temporary_tables_)().swap(temporary_tables_);
267  }
268  decltype(target_exprs_owned_)().swap(target_exprs_owned_);
269  executor_->catalog_ = &cat_;
270  executor_->temporary_tables_ = &temporary_tables_;
271 
272  time(&now_);
273  CHECK(!seq.empty());
274  const auto exec_desc_count = eo.just_explain ? size_t(1) : seq.size();
275 
276  for (size_t i = 0; i < exec_desc_count; i++) {
277  // only render on the last step
278  executeRelAlgStep(seq,
279  i,
280  co,
281  eo,
282  (i == exec_desc_count - 1) ? render_info : nullptr,
283  queue_time_ms);
284  }
285 
286  return seq.getDescriptor(exec_desc_count - 1)->getResult();
287 }
RaExecutionDesc * getDescriptor(size_t idx) const
ExecutionResult executeRelAlgSeq(const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms, const bool with_existing_temp_tables=false)
TemporaryTables temporary_tables_
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
const Catalog_Namespace::Catalog & cat_
void executeRelAlgStep(const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::executeRelAlgStep ( const RaExecutionSequence seq,
const size_t  step_idx,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 316 of file RelAlgExecutor.cpp.

References addTemporaryTable(), ExecutionOptions::allow_loop_joins, ExecutionOptions::allow_multifrag, CHECK(), ExecutionOptions::dynamic_watchdog_time_limit, executeAggregate(), executeCompound(), executeDeleteViaCompound(), executeDeleteViaProject(), executeFilter(), executeLogicalValues(), executeModify(), executeProject(), executeSort(), executeTableFunction(), executeUpdateViaCompound(), executeUpdateViaProject(), ExecutionOptions::find_push_down_candidates, g_cluster, g_skip_intermediate_count, RaExecutionSequence::getDescriptor(), ExecutionOptions::gpu_input_mem_limit_percent, handleNop(), INJECT_TIMER, ExecutionOptions::jit_debug, ExecutionOptions::just_calcite_explain, ExecutionOptions::just_explain, ExecutionOptions::just_validate, ExecutionOptions::output_columnar_hint, WindowProjectNodeContext::reset(), ExecutionOptions::with_dynamic_watchdog, and ExecutionOptions::with_watchdog.

Referenced by executeRelAlgSeq(), and executeRelAlgSubSeq().

321  {
324  auto exec_desc_ptr = seq.getDescriptor(step_idx);
325  CHECK(exec_desc_ptr);
326  auto& exec_desc = *exec_desc_ptr;
327  const auto body = exec_desc.getBody();
328  if (body->isNop()) {
329  handleNop(exec_desc);
330  return;
331  }
332  const ExecutionOptions eo_work_unit{
334  eo.allow_multifrag,
335  eo.just_explain,
336  eo.allow_loop_joins,
337  eo.with_watchdog && (step_idx == 0 || dynamic_cast<const RelProject*>(body)),
338  eo.jit_debug,
339  eo.just_validate,
345 
346  const auto compound = dynamic_cast<const RelCompound*>(body);
347  if (compound) {
348  if (compound->isDeleteViaSelect()) {
349  executeDeleteViaCompound(compound, co, eo_work_unit, render_info, queue_time_ms);
350  } else if (compound->isUpdateViaSelect()) {
351  executeUpdateViaCompound(compound, co, eo_work_unit, render_info, queue_time_ms);
352  } else {
353  exec_desc.setResult(
354  executeCompound(compound, co, eo_work_unit, render_info, queue_time_ms));
355  if (exec_desc.getResult().isFilterPushDownEnabled()) {
356  return;
357  }
358  addTemporaryTable(-compound->getId(), exec_desc.getResult().getDataPtr());
359  }
360  return;
361  }
362  const auto project = dynamic_cast<const RelProject*>(body);
363  if (project) {
364  if (project->isDeleteViaSelect()) {
365  executeDeleteViaProject(project, co, eo_work_unit, render_info, queue_time_ms);
366  } else if (project->isUpdateViaSelect()) {
367  executeUpdateViaProject(project, co, eo_work_unit, render_info, queue_time_ms);
368  } else {
369  ssize_t prev_count = -1;
370  // Disabling the intermediate count optimization in distributed, as the previous
371  // execution descriptor will likely not hold the aggregated result.
372  if (g_skip_intermediate_count && step_idx > 0 && !g_cluster) {
373  auto prev_exec_desc = seq.getDescriptor(step_idx - 1);
374  CHECK(prev_exec_desc);
375  if (dynamic_cast<const RelCompound*>(prev_exec_desc->getBody())) {
376  const auto& prev_exe_result = prev_exec_desc->getResult();
377  const auto prev_result = prev_exe_result.getRows();
378  if (prev_result) {
379  prev_count = static_cast<ssize_t>(prev_result->rowCount());
380  }
381  }
382  }
383  exec_desc.setResult(executeProject(
384  project, co, eo_work_unit, render_info, queue_time_ms, prev_count));
385  if (exec_desc.getResult().isFilterPushDownEnabled()) {
386  return;
387  }
388  addTemporaryTable(-project->getId(), exec_desc.getResult().getDataPtr());
389  }
390  return;
391  }
392  const auto aggregate = dynamic_cast<const RelAggregate*>(body);
393  if (aggregate) {
394  exec_desc.setResult(
395  executeAggregate(aggregate, co, eo_work_unit, render_info, queue_time_ms));
396  addTemporaryTable(-aggregate->getId(), exec_desc.getResult().getDataPtr());
397  return;
398  }
399  const auto filter = dynamic_cast<const RelFilter*>(body);
400  if (filter) {
401  exec_desc.setResult(
402  executeFilter(filter, co, eo_work_unit, render_info, queue_time_ms));
403  addTemporaryTable(-filter->getId(), exec_desc.getResult().getDataPtr());
404  return;
405  }
406  const auto sort = dynamic_cast<const RelSort*>(body);
407  if (sort) {
408  exec_desc.setResult(executeSort(sort, co, eo_work_unit, render_info, queue_time_ms));
409  if (exec_desc.getResult().isFilterPushDownEnabled()) {
410  return;
411  }
412  addTemporaryTable(-sort->getId(), exec_desc.getResult().getDataPtr());
413  return;
414  }
415  const auto logical_values = dynamic_cast<const RelLogicalValues*>(body);
416  if (logical_values) {
417  exec_desc.setResult(executeLogicalValues(logical_values, eo_work_unit));
418  addTemporaryTable(-logical_values->getId(), exec_desc.getResult().getDataPtr());
419  return;
420  }
421  const auto modify = dynamic_cast<const RelModify*>(body);
422  if (modify) {
423  exec_desc.setResult(executeModify(modify, eo_work_unit));
424  return;
425  }
426  const auto table_func = dynamic_cast<const RelTableFunction*>(body);
427  if (table_func) {
428  exec_desc.setResult(
429  executeTableFunction(table_func, co, eo_work_unit, queue_time_ms));
430  addTemporaryTable(-table_func->getId(), exec_desc.getResult().getDataPtr());
431  return;
432  }
433  CHECK(false);
434 }
ExecutionResult executeAggregate(const RelAggregate *aggregate, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
RaExecutionDesc * getDescriptor(size_t idx) const
ExecutionResult executeProject(const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count)
bool g_cluster
ExecutionResult executeModify(const RelModify *modify, const ExecutionOptions &eo)
void addTemporaryTable(const int table_id, const ResultSetPtr &result)
ExecutionResult executeLogicalValues(const RelLogicalValues *, const ExecutionOptions &)
ExecutionResult executeFilter(const RelFilter *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
void handleNop(RaExecutionDesc &ed)
const bool allow_multifrag
const bool find_push_down_candidates
CHECK(cgen_state)
const bool just_validate
#define INJECT_TIMER(DESC)
Definition: measure.h:91
const bool with_dynamic_watchdog
const double gpu_input_mem_limit_percent
const bool output_columnar_hint
void executeRelAlgStep(const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
ExecutionResult executeTableFunction(const RelTableFunction *, const CompilationOptions &, const ExecutionOptions &, const int64_t queue_time_ms)
const bool just_calcite_explain
void executeDeleteViaCompound(const RelCompound *compound, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
void executeUpdateViaProject(const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
ExecutionResult executeSort(const RelSort *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
void executeDeleteViaProject(const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
const bool allow_loop_joins
bool g_skip_intermediate_count
void executeUpdateViaCompound(const RelCompound *compound, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
ExecutionResult executeCompound(const RelCompound *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
const unsigned dynamic_watchdog_time_limit
const bool with_watchdog

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeRelAlgSubSeq ( const RaExecutionSequence seq,
const std::pair< size_t, size_t >  interval,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)

Definition at line 289 of file RelAlgExecutor.cpp.

References cat_, CHECK(), executeRelAlgStep(), executor_, RaExecutionSequence::getDescriptor(), INJECT_TIMER, ExecutionOptions::just_explain, now_, and temporary_tables_.

Referenced by executeRelAlgQuerySingleStep().

295  {
297  executor_->catalog_ = &cat_;
298  executor_->temporary_tables_ = &temporary_tables_;
299 
300  time(&now_);
301  CHECK(!eo.just_explain);
302 
303  for (size_t i = interval.first; i < interval.second; i++) {
304  // only render on the last step
305  executeRelAlgStep(seq,
306  i,
307  co,
308  eo,
309  (i == interval.second - 1) ? render_info : nullptr,
310  queue_time_ms);
311  }
312 
313  return seq.getDescriptor(interval.second - 1)->getResult();
314 }
RaExecutionDesc * getDescriptor(size_t idx) const
TemporaryTables temporary_tables_
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
const Catalog_Namespace::Catalog & cat_
ExecutionResult executeRelAlgSubSeq(const RaExecutionSequence &seq, const std::pair< size_t, size_t > interval, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
void executeRelAlgStep(const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeSort ( const RelSort sort,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1558 of file RelAlgExecutor.cpp.

References SpeculativeTopNBlacklist::add(), GroupByAndAggregate::addTransientStringLiterals(), ExecutionOptions::allow_loop_joins, ExecutionOptions::allow_multifrag, CHECK(), CHECK_EQ, anonymous_namespace{RelAlgExecutor.cpp}::check_sort_node_source_constraint(), RelSort::collationCount(), createSortInputWorkUnit(), CompilationOptions::device_type_, ExecutionOptions::dynamic_watchdog_time_limit, executeWorkUnit(), executor_, ExecutionOptions::find_push_down_candidates, anonymous_namespace{RelAlgExecutor.cpp}::first_oe_is_desc(), g_cluster, anonymous_namespace{RelAlgExecutor.cpp}::get_order_entries(), RelAlgNode::getId(), RelAlgNode::getInput(), RelSort::getLimit(), RelSort::getOffset(), ExecutionResult::getRows(), ExecutionOptions::gpu_input_mem_limit_percent, RelSort::isEmptyResult(), ExecutionOptions::jit_debug, ExecutionOptions::just_calcite_explain, ExecutionOptions::just_explain, ExecutionOptions::just_validate, leaf_results_, anonymous_namespace{RelAlgExecutor.cpp}::node_is_aggregate(), ExecutionOptions::output_columnar_hint, run_benchmark_import::result, RelAlgNode::setOutputMetainfo(), speculative_topn_blacklist_, use_speculative_top_n(), ExecutionOptions::with_dynamic_watchdog, and ExecutionOptions::with_watchdog.

Referenced by executeRelAlgStep().

1562  {
1564  const auto source = sort->getInput(0);
1565  const bool is_aggregate = node_is_aggregate(source);
1566  auto it = leaf_results_.find(sort->getId());
1567  if (it != leaf_results_.end()) {
1568  // Add any transient string literals to the sdp on the agg
1569  const auto source_work_unit = createSortInputWorkUnit(sort, eo.just_explain);
1571  source_work_unit.exe_unit, executor_, executor_->row_set_mem_owner_);
1572 
1573  // Handle push-down for LIMIT for multi-node
1574  auto& aggregated_result = it->second;
1575  auto& result_rows = aggregated_result.rs;
1576  const size_t limit = sort->getLimit();
1577  const size_t offset = sort->getOffset();
1578  const auto order_entries = get_order_entries(sort);
1579  if (limit || offset) {
1580  if (!order_entries.empty()) {
1581  result_rows->sort(order_entries, limit + offset);
1582  }
1583  result_rows->dropFirstN(offset);
1584  if (limit) {
1585  result_rows->keepFirstN(limit);
1586  }
1587  }
1588  ExecutionResult result(result_rows, aggregated_result.targets_meta);
1589  sort->setOutputMetainfo(aggregated_result.targets_meta);
1590 
1591  return result;
1592  }
1593  while (true) {
1594  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1595  bool is_desc{false};
1596  try {
1597  const auto source_work_unit = createSortInputWorkUnit(sort, eo.just_explain);
1598  is_desc = first_oe_is_desc(source_work_unit.exe_unit.sort_info.order_entries);
1599  ExecutionOptions eo_copy = {
1601  eo.allow_multifrag,
1602  eo.just_explain,
1603  eo.allow_loop_joins,
1604  eo.with_watchdog,
1605  eo.jit_debug,
1606  eo.just_validate || sort->isEmptyResult(),
1612  };
1613 
1614  groupby_exprs = source_work_unit.exe_unit.groupby_exprs;
1615  auto source_result = executeWorkUnit(source_work_unit,
1616  source->getOutputMetainfo(),
1617  is_aggregate,
1618  co,
1619  eo_copy,
1620  render_info,
1621  queue_time_ms);
1622  if (render_info && render_info->isPotentialInSituRender()) {
1623  return source_result;
1624  }
1625  if (source_result.isFilterPushDownEnabled()) {
1626  return source_result;
1627  }
1628  auto rows_to_sort = source_result.getRows();
1629  if (eo.just_explain) {
1630  return {rows_to_sort, {}};
1631  }
1632  const size_t limit = sort->getLimit();
1633  const size_t offset = sort->getOffset();
1634  if (sort->collationCount() != 0 && !rows_to_sort->definitelyHasNoRows() &&
1635  !use_speculative_top_n(source_work_unit.exe_unit,
1636  rows_to_sort->getQueryMemDesc())) {
1637  rows_to_sort->sort(source_work_unit.exe_unit.sort_info.order_entries,
1638  limit + offset);
1639  }
1640  if (limit || offset) {
1641  if (g_cluster && sort->collationCount() == 0) {
1642  if (offset >= rows_to_sort->rowCount()) {
1643  rows_to_sort->dropFirstN(offset);
1644  } else {
1645  rows_to_sort->keepFirstN(limit + offset);
1646  }
1647  } else {
1648  rows_to_sort->dropFirstN(offset);
1649  if (limit) {
1650  rows_to_sort->keepFirstN(limit);
1651  }
1652  }
1653  }
1654  return {rows_to_sort, source_result.getTargetsMeta()};
1655  } catch (const SpeculativeTopNFailed&) {
1656  CHECK_EQ(size_t(1), groupby_exprs.size());
1657  speculative_topn_blacklist_.add(groupby_exprs.front(), is_desc);
1658  }
1659  }
1660  CHECK(false);
1661  return {std::make_shared<ResultSet>(std::vector<TargetInfo>{},
1662  co.device_type_,
1664  nullptr,
1665  executor_),
1666  {}};
1667 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
size_t getOffset() const
bool g_cluster
static SpeculativeTopNBlacklist speculative_topn_blacklist_
bool use_speculative_top_n(const RelAlgExecutionUnit &ra_exe_unit, const QueryMemoryDescriptor &query_mem_desc)
void check_sort_node_source_constraint(const RelSort *sort)
std::unordered_map< unsigned, AggregatedResult > leaf_results_
const bool allow_multifrag
const bool find_push_down_candidates
CHECK(cgen_state)
const bool just_validate
unsigned getId() const
const bool with_dynamic_watchdog
const double gpu_input_mem_limit_percent
const std::shared_ptr< ResultSet > & getRows() const
const RelAlgNode * getInput(const size_t idx) const
const bool output_columnar_hint
bool node_is_aggregate(const RelAlgNode *ra)
bool isEmptyResult() const
const bool just_calcite_explain
size_t collationCount() const
size_t getLimit() const
const bool allow_loop_joins
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
std::list< Analyzer::OrderEntry > get_order_entries(const RelSort *sort)
WorkUnit createSortInputWorkUnit(const RelSort *, const bool just_explain)
void add(const std::shared_ptr< Analyzer::Expr > expr, const bool desc)
const unsigned dynamic_watchdog_time_limit
Executor * executor_
const bool with_watchdog
bool first_oe_is_desc(const std::list< Analyzer::OrderEntry > &order_entries)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeTableFunction ( const RelTableFunction table_func,
const CompilationOptions co_in,
const ExecutionOptions eo,
const int64_t  queue_time_ms 
)
private

Definition at line 1297 of file RelAlgExecutor.cpp.

References cat_, CHECK(), createTableFunctionWorkUnit(), Executor::ERR_OUT_OF_GPU_MEM, executor_, g_cluster, g_enable_table_functions, get_table_infos(), QueryExecutionError::getErrorCode(), handlePersistentError(), INJECT_TIMER, ExecutionOptions::just_explain, and run_benchmark_import::result.

Referenced by executeRelAlgStep().

1300  {
1302 
1303  auto co = co_in;
1304 
1305  if (g_cluster) {
1306  throw std::runtime_error("Table functions not supported in distributed mode yet");
1307  }
1308  if (!g_enable_table_functions) {
1309  throw std::runtime_error("Table function support is disabled");
1310  }
1311 
1312  auto table_func_work_unit = createTableFunctionWorkUnit(table_func, eo.just_explain);
1313  const auto body = table_func_work_unit.body;
1314  CHECK(body);
1315 
1316  const auto table_infos =
1317  get_table_infos(table_func_work_unit.exe_unit.input_descs, executor_);
1318 
1319  ExecutionResult result{std::make_shared<ResultSet>(std::vector<TargetInfo>{},
1320  co.device_type_,
1322  nullptr,
1323  executor_),
1324  {}};
1325 
1326  try {
1327  result = {executor_->executeTableFunction(
1328  table_func_work_unit.exe_unit, table_infos, co, eo, cat_),
1329  body->getOutputMetainfo()};
1330  } catch (const QueryExecutionError& e) {
1333  throw std::runtime_error("Table function ran out of memory during execution");
1334  }
1335  result.setQueueTime(queue_time_ms);
1336  return result;
1337 }
int32_t getErrorCode() const
Definition: ErrorHandling.h:55
TableFunctionWorkUnit createTableFunctionWorkUnit(const RelTableFunction *table_func, const bool just_explain)
bool g_cluster
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
const Catalog_Namespace::Catalog & cat_
static const int32_t ERR_OUT_OF_GPU_MEM
Definition: Execute.h:972
ExecutionResult executeTableFunction(const RelTableFunction *, const CompilationOptions &, const ExecutionOptions &, const int64_t queue_time_ms)
bool g_enable_table_functions
Definition: Execute.cpp:94
static void handlePersistentError(const int32_t error_code)
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::executeUpdateViaCompound ( const RelCompound compound,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1036 of file RelAlgExecutor.cpp.

References cat_, CPU, createCompoundWorkUnit(), Default, CompilationOptions::device_type_, executor_, get_table_infos(), ModifyManipulationTarget::getModifiedTableDescriptor(), RelAlgNode::getOutputMetainfo(), ModifyManipulationTarget::getTargetColumns(), logger::INFO, CacheInvalidator< CACHE_HOLDING_TYPES >::invalidateCaches(), RelCompound::isAggregate(), ModifyManipulationTarget::isVarlenUpdateRequired(), ExecutionOptions::just_explain, LOG, ModifyManipulationTarget::validateTargetColumns(), StorageIOFacility< RelAlgExecutorTraits >::yieldColumnValidator(), and StorageIOFacility< RelAlgExecutorTraits >::yieldUpdateCallback().

Referenced by executeRelAlgStep().

1040  {
1041  if (!compound->validateTargetColumns(
1043  throw std::runtime_error(
1044  "Unsupported update operation encountered. (None-encoded string column updates "
1045  "are not supported.)");
1046  }
1047 
1048  const auto work_unit = createCompoundWorkUnit(
1049  compound, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1050  const auto table_infos = get_table_infos(work_unit.exe_unit, executor_);
1051  CompilationOptions co_project = co;
1053 
1054  try {
1056 
1057  UpdateTransactionParameters update_params(compound->getModifiedTableDescriptor(),
1058  compound->getTargetColumns(),
1059  compound->getOutputMetainfo(),
1060  compound->isVarlenUpdateRequired());
1061  auto update_callback = yieldUpdateCallback(update_params);
1062  executor_->executeUpdate(work_unit.exe_unit,
1063  table_infos,
1064  co_project,
1065  eo,
1066  cat_,
1067  executor_->row_set_mem_owner_,
1068  update_callback,
1069  compound->isAggregate());
1070  update_params.finalizeTransaction();
1071  } catch (...) {
1072  LOG(INFO) << "Update operation failed.";
1073  throw;
1074  }
1075 }
#define LOG(tag)
Definition: Logger.h:188
WorkUnit createCompoundWorkUnit(const RelCompound *, const SortInfo &, const bool just_explain)
static void invalidateCaches()
ColumnNameList const & getTargetColumns() const
const Catalog_Namespace::Catalog & cat_
ColumnValidationFunction yieldColumnValidator(TableDescriptorType const *table_descriptor)
ExecutorDeviceType device_type_
UpdateCallback yieldUpdateCallback(UpdateTransactionParameters &update_parameters)
bool isAggregate() const
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
auto const isVarlenUpdateRequired() const
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
Executor * executor_
TableDescriptor const * getModifiedTableDescriptor() const
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::executeUpdateViaProject ( const RelProject project,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms 
)
private

Definition at line 1077 of file RelAlgExecutor.cpp.

References cat_, CHECK(), CHECK_EQ, CPU, createProjectWorkUnit(), Default, CompilationOptions::device_type_, executor_, get_table_infos(), get_temporary_table(), RelAlgNode::getInput(), ModifyManipulationTarget::getModifiedTableDescriptor(), RelAlgNode::getOutputMetainfo(), ModifyManipulationTarget::getTargetColumns(), logger::INFO, RelAlgNode::inputCount(), CacheInvalidator< CACHE_HOLDING_TYPES >::invalidateCaches(), RelProject::isSimple(), ModifyManipulationTarget::isVarlenUpdateRequired(), ExecutionOptions::just_explain, LOG, temporary_tables_, ModifyManipulationTarget::validateTargetColumns(), StorageIOFacility< RelAlgExecutorTraits >::yieldColumnValidator(), and StorageIOFacility< RelAlgExecutorTraits >::yieldUpdateCallback().

Referenced by executeRelAlgStep().

1081  {
1082  if (!project->validateTargetColumns(
1084  throw std::runtime_error(
1085  "Unsupported update operation encountered. (None-encoded string column updates "
1086  "are not supported.)");
1087  }
1088 
1089  auto work_unit =
1090  createProjectWorkUnit(project, {{}, SortAlgorithm::Default, 0, 0}, eo.just_explain);
1091  const auto table_infos = get_table_infos(work_unit.exe_unit, executor_);
1092  CompilationOptions co_project = co;
1094 
1095  if (project->isSimple()) {
1096  CHECK_EQ(size_t(1), project->inputCount());
1097  const auto input_ra = project->getInput(0);
1098  if (dynamic_cast<const RelSort*>(input_ra)) {
1099  const auto& input_table =
1100  get_temporary_table(&temporary_tables_, -input_ra->getId());
1101  CHECK(input_table);
1102  work_unit.exe_unit.scan_limit = input_table->rowCount();
1103  }
1104  }
1105 
1106  try {
1108 
1109  UpdateTransactionParameters update_params(project->getModifiedTableDescriptor(),
1110  project->getTargetColumns(),
1111  project->getOutputMetainfo(),
1112  project->isVarlenUpdateRequired());
1113  auto update_callback = yieldUpdateCallback(update_params);
1114  executor_->executeUpdate(work_unit.exe_unit,
1115  table_infos,
1116  co_project,
1117  eo,
1118  cat_,
1119  executor_->row_set_mem_owner_,
1120  update_callback);
1121  update_params.finalizeTransaction();
1122  } catch (...) {
1123  LOG(INFO) << "Update operation failed.";
1124  throw;
1125  }
1126 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
WorkUnit createProjectWorkUnit(const RelProject *, const SortInfo &, const bool just_explain)
#define LOG(tag)
Definition: Logger.h:188
TemporaryTables temporary_tables_
static void invalidateCaches()
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
Definition: Execute.h:178
CHECK(cgen_state)
ColumnNameList const & getTargetColumns() const
const Catalog_Namespace::Catalog & cat_
const RelAlgNode * getInput(const size_t idx) const
ColumnValidationFunction yieldColumnValidator(TableDescriptorType const *table_descriptor)
bool isSimple() const
ExecutorDeviceType device_type_
UpdateCallback yieldUpdateCallback(UpdateTransactionParameters &update_parameters)
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
const size_t inputCount() const
auto const isVarlenUpdateRequired() const
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
Executor * executor_
TableDescriptor const * getModifiedTableDescriptor() const
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::executeWorkUnit ( const WorkUnit work_unit,
const std::vector< TargetMetaInfo > &  targets_meta,
const bool  is_agg,
const CompilationOptions co_in,
const ExecutionOptions eo,
RenderInfo render_info,
const int64_t  queue_time_ms,
const ssize_t  previous_count = -1 
)
private

Definition at line 1855 of file RelAlgExecutor.cpp.

References GroupByAndAggregate::addTransientStringLiterals(), RelAlgExecutor::WorkUnit::body, anonymous_namespace{RelAlgExecutor.cpp}::build_render_targets(), anonymous_namespace{RelAlgExecutor.cpp}::can_use_bump_allocator(), cat_, CHECK(), CHECK_EQ, CHECK_GT, anonymous_namespace{RelAlgExecutor.cpp}::compute_output_buffer_size(), computeWindow(), CPU, DEBUG_TIMER, anonymous_namespace{RelAlgExecutor.cpp}::decide_approx_count_distinct_implementation(), RelAlgExecutor::WorkUnit::exe_unit, anonymous_namespace{RelAlgExecutor.cpp}::exe_unit_has_quals(), executor_, ExecutionOptions::find_push_down_candidates, g_big_group_threshold, g_cluster, g_enable_window_functions, get_table_infos(), QueryExecutionError::getErrorCode(), getFilteredCountAll(), getNDVEstimation(), anonymous_namespace{RelAlgExecutor.cpp}::groups_approx_upper_bound(), handleOutOfMemoryRetry(), handlePersistentError(), INJECT_TIMER, anonymous_namespace{RelAlgExecutor.cpp}::is_agg(), anonymous_namespace{RelAlgExecutor.cpp}::is_window_execution_unit(), RenderInfo::isPotentialInSituRender(), isRowidLookup(), ExecutionOptions::just_calcite_explain, ExecutionOptions::just_explain, leaf_results_, RelAlgExecutor::WorkUnit::max_groups_buffer_entry_guess, run_benchmark_import::result, selectFiltersToBePushedDown(), RelAlgExecutionUnit::target_exprs, target_exprs_owned_, and QueryExecutionError::wasMultifragKernelLaunch().

Referenced by executeAggregate(), executeCompound(), executeFilter(), executeProject(), and executeSort().

1863  {
1865  auto timer = DEBUG_TIMER(__func__);
1866 
1867  auto co = co_in;
1868  ColumnCacheMap column_cache;
1869  if (is_window_execution_unit(work_unit.exe_unit)) {
1870  if (g_cluster) {
1871  throw std::runtime_error(
1872  "Window functions support not supported in distributed mode");
1873  }
1875  throw std::runtime_error("Window functions support is disabled");
1876  }
1877  co.device_type_ = ExecutorDeviceType::CPU;
1878  computeWindow(work_unit.exe_unit, co, eo, column_cache, queue_time_ms);
1879  }
1880  if (!eo.just_explain && eo.find_push_down_candidates) {
1881  // find potential candidates:
1882  auto selected_filters = selectFiltersToBePushedDown(work_unit, co, eo);
1883  if (!selected_filters.empty() || eo.just_calcite_explain) {
1884  return ExecutionResult(selected_filters, eo.find_push_down_candidates);
1885  }
1886  }
1887  const auto body = work_unit.body;
1888  CHECK(body);
1889  auto it = leaf_results_.find(body->getId());
1890  if (it != leaf_results_.end()) {
1892  work_unit.exe_unit, executor_, executor_->row_set_mem_owner_);
1893  auto& aggregated_result = it->second;
1894  auto& result_rows = aggregated_result.rs;
1895  ExecutionResult result(result_rows, aggregated_result.targets_meta);
1896  body->setOutputMetainfo(aggregated_result.targets_meta);
1897  if (render_info) {
1898  build_render_targets(*render_info, work_unit.exe_unit.target_exprs, targets_meta);
1899  }
1900  return result;
1901  }
1902  const auto table_infos = get_table_infos(work_unit.exe_unit, executor_);
1903 
1905  work_unit.exe_unit, table_infos, executor_, co.device_type_, target_exprs_owned_);
1906  auto max_groups_buffer_entry_guess = work_unit.max_groups_buffer_entry_guess;
1907  if (is_window_execution_unit(ra_exe_unit)) {
1908  CHECK_EQ(table_infos.size(), size_t(1));
1909  CHECK_EQ(table_infos.front().info.fragments.size(), size_t(1));
1910  max_groups_buffer_entry_guess =
1911  table_infos.front().info.fragments.front().getNumTuples();
1912  ra_exe_unit.scan_limit = max_groups_buffer_entry_guess;
1913  } else if (compute_output_buffer_size(ra_exe_unit) && !isRowidLookup(work_unit)) {
1914  if (previous_count > 0 && !exe_unit_has_quals(ra_exe_unit)) {
1915  ra_exe_unit.scan_limit = static_cast<size_t>(previous_count);
1916  } else {
1917  // TODO(adb): enable bump allocator path for render queries
1918  if (can_use_bump_allocator(ra_exe_unit, co, eo) && !render_info) {
1919  ra_exe_unit.scan_limit = 0;
1920  ra_exe_unit.use_bump_allocator = true;
1921  } else if (!eo.just_explain) {
1922  const auto filter_count_all = getFilteredCountAll(work_unit, true, co, eo);
1923  if (filter_count_all >= 0) {
1924  ra_exe_unit.scan_limit = std::max(filter_count_all, ssize_t(1));
1925  }
1926  }
1927  }
1928  }
1929 
1930  ExecutionResult result{std::make_shared<ResultSet>(std::vector<TargetInfo>{},
1931  co.device_type_,
1933  nullptr,
1934  executor_),
1935  {}};
1936 
1937  auto execute_and_handle_errors =
1938  [&](const auto max_groups_buffer_entry_guess_in,
1939  const bool has_cardinality_estimation) -> ExecutionResult {
1940  // Note that the groups buffer entry guess may be modified during query execution.
1941  // Create a local copy so we can track those changes if we need to attempt a retry due
1942  // to OOM
1943  auto local_groups_buffer_entry_guess = max_groups_buffer_entry_guess_in;
1944  try {
1945  return {executor_->executeWorkUnit(local_groups_buffer_entry_guess,
1946  is_agg,
1947  table_infos,
1948  ra_exe_unit,
1949  co,
1950  eo,
1951  cat_,
1952  executor_->row_set_mem_owner_,
1953  render_info,
1954  has_cardinality_estimation,
1955  column_cache),
1956  targets_meta};
1957  } catch (const QueryExecutionError& e) {
1959  return handleOutOfMemoryRetry(
1960  {ra_exe_unit, work_unit.body, local_groups_buffer_entry_guess},
1961  targets_meta,
1962  is_agg,
1963  co,
1964  eo,
1965  render_info,
1967  queue_time_ms);
1968  }
1969  };
1970 
1971  try {
1972  result = execute_and_handle_errors(
1973  max_groups_buffer_entry_guess,
1975  } catch (const CardinalityEstimationRequired&) {
1976  const auto estimated_groups_buffer_entry_guess =
1977  2 * std::min(groups_approx_upper_bound(table_infos),
1978  getNDVEstimation(work_unit, is_agg, co, eo));
1979  CHECK_GT(estimated_groups_buffer_entry_guess, size_t(0));
1980  result = execute_and_handle_errors(estimated_groups_buffer_entry_guess, true);
1981  }
1982 
1983  result.setQueueTime(queue_time_ms);
1984  if (render_info) {
1985  build_render_targets(*render_info, work_unit.exe_unit.target_exprs, targets_meta);
1986  if (render_info->isPotentialInSituRender()) {
1987  // return an empty result (with the same queue time, and zero render time)
1988  return {
1989  std::make_shared<ResultSet>(queue_time_ms, 0, executor_->row_set_mem_owner_),
1990  {}};
1991  }
1992  }
1993  return result;
1994 }
bool is_agg(const Analyzer::Expr *expr)
#define CHECK_EQ(x, y)
Definition: Logger.h:201
int32_t getErrorCode() const
Definition: ErrorHandling.h:55
bool can_use_bump_allocator(const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo)
bool g_cluster
std::vector< PushedDownFilterInfo > selectFiltersToBePushedDown(const RelAlgExecutor::WorkUnit &work_unit, const CompilationOptions &co, const ExecutionOptions &eo)
std::unordered_map< unsigned, AggregatedResult > leaf_results_
size_t getNDVEstimation(const WorkUnit &work_unit, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo)
#define CHECK_GT(x, y)
Definition: Logger.h:205
bool is_window_execution_unit(const RelAlgExecutionUnit &ra_exe_unit)
void computeWindow(const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo, ColumnCacheMap &column_cache_map, const int64_t queue_time_ms)
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
const bool find_push_down_candidates
CHECK(cgen_state)
#define INJECT_TIMER(DESC)
Definition: measure.h:91
const Catalog_Namespace::Catalog & cat_
size_t g_big_group_threshold
Definition: Execute.cpp:92
ExecutionResult handleOutOfMemoryRetry(const RelAlgExecutor::WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const bool was_multifrag_kernel_launch, const int64_t queue_time_ms)
size_t groups_approx_upper_bound(const std::vector< InputTableInfo > &table_infos)
void build_render_targets(RenderInfo &render_info, const std::vector< Analyzer::Expr * > &work_unit_target_exprs, const std::vector< TargetMetaInfo > &targets_meta)
bool g_enable_window_functions
Definition: Execute.cpp:93
ssize_t getFilteredCountAll(const WorkUnit &work_unit, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo)
const bool just_calcite_explain
bool isRowidLookup(const WorkUnit &work_unit)
bool exe_unit_has_quals(const RelAlgExecutionUnit ra_exe_unit)
static void handlePersistentError(const int32_t error_code)
bool compute_output_buffer_size(const RelAlgExecutionUnit &ra_exe_unit)
bool wasMultifragKernelLaunch() const
Definition: ErrorHandling.h:57
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
bool isPotentialInSituRender() const
Definition: RenderInfo.cpp:61
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
#define DEBUG_TIMER(name)
Definition: Logger.h:299
std::unordered_map< int, std::unordered_map< int, std::shared_ptr< const ColumnarResults > > > ColumnCacheMap
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)
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string RelAlgExecutor::getErrorMessageFromCode ( const int32_t  error_code)
static

Definition at line 2225 of file RelAlgExecutor.cpp.

References Executor::ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED, Executor::ERR_DIV_BY_ZERO, Executor::ERR_INTERRUPTED, Executor::ERR_OUT_OF_CPU_MEM, Executor::ERR_OUT_OF_GPU_MEM, Executor::ERR_OUT_OF_RENDER_MEM, Executor::ERR_OUT_OF_TIME, Executor::ERR_OVERFLOW_OR_UNDERFLOW, Executor::ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES, Executor::ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY, Executor::ERR_STRING_CONST_IN_RESULTSET, Executor::ERR_TOO_MANY_LITERALS, Executor::ERR_UNSUPPORTED_SELF_JOIN, and to_string().

Referenced by getNDVEstimation(), and handlePersistentError().

2225  {
2226  if (error_code < 0) {
2227  return "Ran out of slots in the query output buffer";
2228  }
2229  switch (error_code) {
2231  return "Division by zero";
2233  return "Query couldn't keep the entire working set of columns in GPU memory";
2235  return "Self joins not supported yet";
2237  return "Not enough host memory to execute the query";
2239  return "Overflow or underflow";
2241  return "Query execution has exceeded the time limit";
2243  return "Query execution has been interrupted";
2245  return "Columnar conversion not supported for variable length types";
2247  return "Too many literals in the query";
2249  return "NONE ENCODED String types are not supported as input result set.";
2251  return "Not enough OpenGL memory to render the query results";
2253  return "Streaming-Top-N not supported in Render Query";
2255  return "Multiple distinct values encountered";
2256  }
2257  return "Other error: code " + std::to_string(error_code);
2258 }
static const int32_t ERR_INTERRUPTED
Definition: Execute.h:980
static const int32_t ERR_TOO_MANY_LITERALS
Definition: Execute.h:982
std::string to_string(char const *&&v)
static const int32_t ERR_STRING_CONST_IN_RESULTSET
Definition: Execute.h:983
static const int32_t ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY
Definition: Execute.h:984
static const int32_t ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED
Definition: Execute.h:981
static const int32_t ERR_DIV_BY_ZERO
Definition: Execute.h:971
static const int32_t ERR_OUT_OF_RENDER_MEM
Definition: Execute.h:975
const int8_t const int64_t const uint64_t const int32_t const int64_t int64_t uint32_t const int64_t int32_t * error_code
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:977
static const int32_t ERR_OUT_OF_TIME
Definition: Execute.h:979
static const int32_t ERR_UNSUPPORTED_SELF_JOIN
Definition: Execute.h:974
static const int32_t ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES
Definition: Execute.h:985
static const int32_t ERR_OUT_OF_GPU_MEM
Definition: Execute.h:972
static const int32_t ERR_OUT_OF_CPU_MEM
Definition: Execute.h:976

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Executor * RelAlgExecutor::getExecutor ( ) const

Definition at line 173 of file RelAlgExecutor.cpp.

References executor_.

173  {
174  return executor_;
175 }
Executor * executor_
ssize_t RelAlgExecutor::getFilteredCountAll ( const WorkUnit work_unit,
const bool  is_agg,
const CompilationOptions co,
const ExecutionOptions eo 
)
private

Definition at line 1996 of file RelAlgExecutor.cpp.

References cat_, CHECK(), CHECK_EQ, CHECK_GE, create_count_all_execution_unit(), RelAlgExecutor::WorkUnit::exe_unit, executor_, g_bigint_count, get_table_infos(), kBIGINT, kCOUNT, kINT, LOG, and logger::WARNING.

Referenced by executeWorkUnit().

1999  {
2000  const auto count =
2001  makeExpr<Analyzer::AggExpr>(SQLTypeInfo(g_bigint_count ? kBIGINT : kINT, false),
2002  kCOUNT,
2003  nullptr,
2004  false,
2005  nullptr);
2006  const auto count_all_exe_unit =
2007  create_count_all_execution_unit(work_unit.exe_unit, count);
2008  size_t one{1};
2009  ResultSetPtr count_all_result;
2010  try {
2011  ColumnCacheMap column_cache;
2012  count_all_result =
2013  executor_->executeWorkUnit(one,
2014  is_agg,
2015  get_table_infos(work_unit.exe_unit, executor_),
2016  count_all_exe_unit,
2017  co,
2018  eo,
2019  cat_,
2020  executor_->row_set_mem_owner_,
2021  nullptr,
2022  false,
2023  column_cache);
2024  } catch (const std::exception& e) {
2025  LOG(WARNING) << "Failed to run pre-flight filtered count with error " << e.what();
2026  return -1;
2027  }
2028  const auto count_row = count_all_result->getNextRow(false, false);
2029  CHECK_EQ(size_t(1), count_row.size());
2030  const auto& count_tv = count_row.front();
2031  const auto count_scalar_tv = boost::get<ScalarTargetValue>(&count_tv);
2032  CHECK(count_scalar_tv);
2033  const auto count_ptr = boost::get<int64_t>(count_scalar_tv);
2034  CHECK(count_ptr);
2035  CHECK_GE(*count_ptr, 0);
2036  auto count_upper_bound = static_cast<size_t>(*count_ptr);
2037  return std::max(count_upper_bound, size_t(1));
2038 }
bool is_agg(const Analyzer::Expr *expr)
#define CHECK_EQ(x, y)
Definition: Logger.h:201
#define LOG(tag)
Definition: Logger.h:188
#define CHECK_GE(x, y)
Definition: Logger.h:206
std::shared_ptr< ResultSet > ResultSetPtr
RelAlgExecutionUnit create_count_all_execution_unit(const RelAlgExecutionUnit &ra_exe_unit, std::shared_ptr< Analyzer::Expr > replacement_target)
CHECK(cgen_state)
const Catalog_Namespace::Catalog & cat_
bool g_bigint_count
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
Definition: sqldefs.h:76
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
std::unordered_map< int, std::unordered_map< int, std::shared_ptr< const ColumnarResults > > > ColumnCacheMap
Definition: sqltypes.h:48
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

FilterSelectivity RelAlgExecutor::getFilterSelectivity ( const std::vector< std::shared_ptr< Analyzer::Expr >> &  filter_expressions,
const CompilationOptions co,
const ExecutionOptions eo 
)
private

Given a set of filter expressions for a table, it launches a new COUNT query to compute the number of passing rows, and then generates a set of statistics related to those filters. Later, these stats are used to decide whether a filter should be pushed down or not.

Definition at line 57 of file JoinFilterPushDown.cpp.

References cat_, CHECK(), CHECK_EQ, Default, executor_, g_bigint_count, get_table_infos(), kBIGINT, kCOUNT, and kINT.

Referenced by selectFiltersToBePushedDown().

60  {
61  CollectInputColumnsVisitor input_columns_visitor;
62  std::list<std::shared_ptr<Analyzer::Expr>> quals;
63  std::unordered_set<InputColDescriptor> input_column_descriptors;
64  BindFilterToOutermostVisitor bind_filter_to_outermost;
65  for (const auto& filter_expr : filter_expressions) {
66  input_column_descriptors = input_columns_visitor.aggregateResult(
67  input_column_descriptors, input_columns_visitor.visit(filter_expr.get()));
68  quals.push_back(bind_filter_to_outermost.visit(filter_expr.get()));
69  }
70  std::vector<InputDescriptor> input_descs;
71  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
72  for (const auto& input_col_desc : input_column_descriptors) {
73  if (input_descs.empty()) {
74  input_descs.push_back(input_col_desc.getScanDesc());
75  } else {
76  CHECK(input_col_desc.getScanDesc() == input_descs.front());
77  }
78  input_col_descs.push_back(std::make_shared<const InputColDescriptor>(input_col_desc));
79  }
80  const auto count_expr =
81  makeExpr<Analyzer::AggExpr>(SQLTypeInfo(g_bigint_count ? kBIGINT : kINT, false),
82  kCOUNT,
83  nullptr,
84  false,
85  nullptr);
86  RelAlgExecutionUnit ra_exe_unit{input_descs,
87  input_col_descs,
88  {},
89  quals,
90  {},
91  {},
92  {count_expr.get()},
93  nullptr,
94  {{}, SortAlgorithm::Default, 0, 0},
95  0};
96  size_t one{1};
97  ResultSetPtr filtered_result;
98  const auto table_infos = get_table_infos(input_descs, executor_);
99  CHECK_EQ(size_t(1), table_infos.size());
100  const size_t total_rows_upper_bound = table_infos.front().info.getNumTuplesUpperBound();
101  try {
102  ColumnCacheMap column_cache;
103  filtered_result = executor_->executeWorkUnit(one,
104  true,
105  table_infos,
106  ra_exe_unit,
107  co,
108  eo,
109  cat_,
110  executor_->getRowSetMemoryOwner(),
111  nullptr,
112  false,
113  column_cache);
114  } catch (...) {
115  return {false, 1.0, 0};
116  }
117  const auto count_row = filtered_result->getNextRow(false, false);
118  CHECK_EQ(size_t(1), count_row.size());
119  const auto& count_tv = count_row.front();
120  const auto count_scalar_tv = boost::get<ScalarTargetValue>(&count_tv);
121  CHECK(count_scalar_tv);
122  const auto count_ptr = boost::get<int64_t>(count_scalar_tv);
123  CHECK(count_ptr);
124  const auto rows_passing = *count_ptr;
125  const auto rows_total = std::max(total_rows_upper_bound, size_t(1));
126  return {true, static_cast<float>(rows_passing) / rows_total, total_rows_upper_bound};
127 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
std::shared_ptr< ResultSet > ResultSetPtr
CHECK(cgen_state)
const Catalog_Namespace::Catalog & cat_
bool g_bigint_count
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
Definition: sqldefs.h:76
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
std::unordered_map< int, std::unordered_map< int, std::shared_ptr< const ColumnarResults > > > ColumnCacheMap
Definition: sqltypes.h:48
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t RelAlgExecutor::getNDVEstimation ( const WorkUnit work_unit,
const bool  is_agg,
const CompilationOptions co,
const ExecutionOptions eo 
)
private

Definition at line 36 of file CardinalityEstimator.cpp.

References cat_, create_ndv_execution_unit(), Executor::ERR_INTERRUPTED, Executor::ERR_OUT_OF_TIME, RelAlgExecutor::WorkUnit::exe_unit, executor_, get_table_infos(), QueryExecutionError::getErrorCode(), getErrorMessageFromCode(), and UNREACHABLE.

Referenced by executeWorkUnit().

39  {
40  const auto estimator_exe_unit = create_ndv_execution_unit(work_unit.exe_unit);
41  size_t one{1};
42  ColumnCacheMap column_cache;
43  try {
44  const auto estimator_result =
45  executor_->executeWorkUnit(one,
46  is_agg,
47  get_table_infos(work_unit.exe_unit, executor_),
48  estimator_exe_unit,
49  co,
50  eo,
51  cat_,
52  executor_->row_set_mem_owner_,
53  nullptr,
54  false,
55  column_cache);
56  if (!estimator_result) {
57  return 1;
58  }
59  return std::max(estimator_result->getNDVEstimator(), size_t(1));
60  } catch (const QueryExecutionError& e) {
62  throw std::runtime_error("Cardinality estimation query ran out of time");
63  }
65  throw std::runtime_error("Cardinality estimation query has been interrupted");
66  }
67  throw std::runtime_error("Failed to run the cardinality estimation query: " +
69  }
70  UNREACHABLE();
71  return 1;
72 }
bool is_agg(const Analyzer::Expr *expr)
int32_t getErrorCode() const
Definition: ErrorHandling.h:55
static const int32_t ERR_INTERRUPTED
Definition: Execute.h:980
#define UNREACHABLE()
Definition: Logger.h:237
RelAlgExecutionUnit create_ndv_execution_unit(const RelAlgExecutionUnit &ra_exe_unit)
const Catalog_Namespace::Catalog & cat_
static const int32_t ERR_OUT_OF_TIME
Definition: Execute.h:979
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
static std::string getErrorMessageFromCode(const int32_t error_code)
std::unordered_map< int, std::unordered_map< int, std::shared_ptr< const ColumnarResults > > > ColumnCacheMap
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const RelAlgNode& RelAlgExecutor::getRootRelAlgNode ( ) const
inline

Definition at line 132 of file RelAlgExecutor.h.

References CHECK(), and query_dag_.

Referenced by computeColRangesCache(), computeStringDictionaryGenerations(), and computeTableGenerations().

132  {
133  CHECK(query_dag_);
134  return query_dag_->getRootNode();
135  }
CHECK(cgen_state)
std::unique_ptr< RelAlgDagBuilder > query_dag_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const std::vector<std::shared_ptr<RexSubQuery> >& RelAlgExecutor::getSubqueries ( ) const
inlinenoexcept

Definition at line 136 of file RelAlgExecutor.h.

References CHECK(), and query_dag_.

Referenced by executeRelAlgQueryNoRetry(), and executeRelAlgQueryWithFilterPushDown().

136  {
137  CHECK(query_dag_);
138  return query_dag_->getSubqueries();
139  };
CHECK(cgen_state)
std::unique_ptr< RelAlgDagBuilder > query_dag_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::handleNop ( RaExecutionDesc ed)
private

Definition at line 436 of file RelAlgExecutor.cpp.

References addTemporaryTable(), CHECK(), CHECK_EQ, RaExecutionDesc::getBody(), and temporary_tables_.

Referenced by executeRelAlgStep().

436  {
437  // just set the result of the previous node as the result of no op
438  auto body = ed.getBody();
439  CHECK(dynamic_cast<const RelAggregate*>(body));
440  CHECK_EQ(size_t(1), body->inputCount());
441  const auto input = body->getInput(0);
442  body->setOutputMetainfo(input->getOutputMetainfo());
443  const auto it = temporary_tables_.find(-input->getId());
444  CHECK(it != temporary_tables_.end());
445  // set up temp table as it could be used by the outer query or next step
446  addTemporaryTable(-body->getId(), it->second);
447 
448  ed.setResult({it->second, input->getOutputMetainfo()});
449 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
TemporaryTables temporary_tables_
void addTemporaryTable(const int table_id, const ResultSetPtr &result)
CHECK(cgen_state)
const RelAlgNode * getBody() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ExecutionResult RelAlgExecutor::handleOutOfMemoryRetry ( const RelAlgExecutor::WorkUnit work_unit,
const std::vector< TargetMetaInfo > &  targets_meta,
const bool  is_agg,
const CompilationOptions co,
const ExecutionOptions eo,
RenderInfo render_info,
const bool  was_multifrag_kernel_launch,
const int64_t  queue_time_ms 
)
private

Definition at line 2075 of file RelAlgExecutor.cpp.

References ExecutionOptions::allow_loop_joins, cat_, CHECK(), CPU, anonymous_namespace{RelAlgExecutor.cpp}::decide_approx_count_distinct_implementation(), CompilationOptions::device_type_, ExecutionOptions::dynamic_watchdog_time_limit, RelAlgExecutor::WorkUnit::exe_unit, executor_, g_enable_watchdog, get_table_infos(), QueryExecutionError::getErrorCode(), ExecutionOptions::gpu_input_mem_limit_percent, handlePersistentError(), CompilationOptions::hoist_literals_, ExecutionOptions::jit_debug, LOG, RelAlgExecutor::WorkUnit::max_groups_buffer_entry_guess, CompilationOptions::opt_level_, ExecutionOptions::output_columnar_hint, run_benchmark_import::result, RenderInfo::setForceNonInSituData(), target_exprs_owned_, RelAlgExecutionUnit::use_bump_allocator, VLOG, logger::WARNING, ExecutionOptions::with_dynamic_watchdog, CompilationOptions::with_dynamic_watchdog_, and ExecutionOptions::with_watchdog.

Referenced by executeWorkUnit().

2083  {
2084  // Disable the bump allocator
2085  // Note that this will have basically the same affect as using the bump allocator for
2086  // the kernel per fragment path. Need to unify the max_groups_buffer_entry_guess = 0
2087  // path and the bump allocator path for kernel per fragment execution.
2088  auto ra_exe_unit_in = work_unit.exe_unit;
2089  ra_exe_unit_in.use_bump_allocator = false;
2090 
2091  auto result = ExecutionResult{std::make_shared<ResultSet>(std::vector<TargetInfo>{},
2092  co.device_type_,
2094  nullptr,
2095  executor_),
2096  {}};
2097 
2098  const auto table_infos = get_table_infos(ra_exe_unit_in, executor_);
2099  auto max_groups_buffer_entry_guess = work_unit.max_groups_buffer_entry_guess;
2100  ExecutionOptions eo_no_multifrag{eo.output_columnar_hint,
2101  false,
2102  false,
2103  eo.allow_loop_joins,
2104  eo.with_watchdog,
2105  eo.jit_debug,
2106  false,
2109  false,
2110  false,
2112 
2113  if (was_multifrag_kernel_launch) {
2114  try {
2115  // Attempt to retry using the kernel per fragment path. The smaller input size
2116  // required may allow the entire kernel to execute in GPU memory.
2117  LOG(WARNING) << "Multifrag query ran out of memory, retrying with multifragment "
2118  "kernels disabled.";
2119  const auto ra_exe_unit = decide_approx_count_distinct_implementation(
2120  ra_exe_unit_in, table_infos, executor_, co.device_type_, target_exprs_owned_);
2121  ColumnCacheMap column_cache;
2122  result = {executor_->executeWorkUnit(max_groups_buffer_entry_guess,
2123  is_agg,
2124  table_infos,
2125  ra_exe_unit,
2126  co,
2127  eo_no_multifrag,
2128  cat_,
2129  executor_->row_set_mem_owner_,
2130  nullptr,
2131  true,
2132  column_cache),
2133  targets_meta};
2134  result.setQueueTime(queue_time_ms);
2135  } catch (const QueryExecutionError& e) {
2137  LOG(WARNING) << "Kernel per fragment query ran out of memory, retrying on CPU.";
2138  }
2139  }
2140 
2141  if (render_info) {
2142  render_info->setForceNonInSituData();
2143  }
2144 
2146  co.hoist_literals_,
2147  co.opt_level_,
2149 
2150  // Only reset the group buffer entry guess if we ran out of slots, which
2151  // suggests a
2152  // highly pathological input which prevented a good estimation of distinct tuple
2153  // count. For projection queries, this will force a per-fragment scan limit, which is
2154  // compatible with the CPU path
2155  VLOG(1) << "Resetting max groups buffer entry guess.";
2156  max_groups_buffer_entry_guess = 0;
2157 
2158  int iteration_ctr = -1;
2159  while (true) {
2160  iteration_ctr++;
2162  ra_exe_unit_in, table_infos, executor_, co_cpu.device_type_, target_exprs_owned_);
2163  ColumnCacheMap column_cache;
2164  try {
2165  result = {executor_->executeWorkUnit(max_groups_buffer_entry_guess,
2166  is_agg,
2167  table_infos,
2168  ra_exe_unit,
2169  co_cpu,
2170  eo_no_multifrag,
2171  cat_,
2172  executor_->row_set_mem_owner_,
2173  nullptr,
2174  true,
2175  column_cache),
2176  targets_meta};
2177  } catch (const QueryExecutionError& e) {
2178  // Ran out of slots
2179  if (e.getErrorCode() < 0) {
2180  // Even the conservative guess failed; it should only happen when we group
2181  // by a huge cardinality array. Maybe we should throw an exception instead?
2182  // Such a heavy query is entirely capable of exhausting all the host memory.
2183  CHECK(max_groups_buffer_entry_guess);
2184  // Only allow two iterations of increasingly large entry guesses up to a maximum
2185  // of 512MB per column per kernel
2186  if (g_enable_watchdog || iteration_ctr > 1) {
2187  throw std::runtime_error("Query ran out of output slots in the result");
2188  }
2189  max_groups_buffer_entry_guess *= 2;
2190  LOG(WARNING) << "Query ran out of slots in the output buffer, retrying with max "
2191  "groups buffer entry "
2192  "guess equal to "
2193  << max_groups_buffer_entry_guess;
2194  } else {
2196  }
2197  continue;
2198  }
2199  result.setQueueTime(queue_time_ms);
2200  return result;
2201  }
2202  return result;
2203 }
bool is_agg(const Analyzer::Expr *expr)
int32_t getErrorCode() const
Definition: ErrorHandling.h:55
void setForceNonInSituData()
Definition: RenderInfo.cpp:42
#define LOG(tag)
Definition: Logger.h:188
RelAlgExecutionUnit exe_unit
const ExecutorOptLevel opt_level_
bool g_enable_watchdog
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
CHECK(cgen_state)
const bool with_dynamic_watchdog
const double gpu_input_mem_limit_percent
const Catalog_Namespace::Catalog & cat_
const bool output_columnar_hint
ExecutorDeviceType device_type_
static void handlePersistentError(const int32_t error_code)
const size_t max_groups_buffer_entry_guess
const bool allow_loop_joins
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
std::unordered_map< int, std::unordered_map< int, std::shared_ptr< const ColumnarResults > > > ColumnCacheMap
const bool with_dynamic_watchdog_
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)
const unsigned dynamic_watchdog_time_limit
Executor * executor_
#define VLOG(n)
Definition: Logger.h:283
const bool with_watchdog

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::handlePersistentError ( const int32_t  error_code)
staticprivate

Definition at line 2205 of file RelAlgExecutor.cpp.

References Executor::ERR_OUT_OF_GPU_MEM, Executor::ERR_SPECULATIVE_TOP_OOM, logger::ERROR, g_allow_cpu_retry, getErrorMessageFromCode(), logger::INFO, and LOG.

Referenced by executeTableFunction(), executeWorkUnit(), and handleOutOfMemoryRetry().

2205  {
2206  LOG(ERROR) << "Query execution failed with error "
2209  throw SpeculativeTopNFailed();
2210  }
2212  // We ran out of GPU memory, this doesn't count as an error if the query is
2213  // allowed to continue on CPU because retry on CPU is explicitly allowed through
2214  // --allow-cpu-retry.
2215  LOG(INFO) << "Query ran out of GPU memory, attempting punt to CPU";
2216  if (!g_allow_cpu_retry) {
2217  throw std::runtime_error(
2218  "Query ran out of GPU memory, unable to automatically retry on CPU");
2219  }
2220  return;
2221  }
2222  throw std::runtime_error(getErrorMessageFromCode(error_code));
2223 }
#define LOG(tag)
Definition: Logger.h:188
const int8_t const int64_t const uint64_t const int32_t const int64_t int64_t uint32_t const int64_t int32_t * error_code
static const int32_t ERR_OUT_OF_GPU_MEM
Definition: Execute.h:972
static const int32_t ERR_SPECULATIVE_TOP_OOM
Definition: Execute.h:978
bool g_allow_cpu_retry
Definition: Execute.cpp:74
static std::string getErrorMessageFromCode(const int32_t error_code)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool RelAlgExecutor::isRowidLookup ( const WorkUnit work_unit)
private

Definition at line 2040 of file RelAlgExecutor.cpp.

References cat_, CHECK_EQ, RelAlgExecutor::WorkUnit::exe_unit, get_column_descriptor(), Analyzer::BinOper::get_left_operand(), RelAlgExecutionUnit::input_descs, kEQ, and TABLE.

Referenced by executeWorkUnit().

2040  {
2041  const auto& ra_exe_unit = work_unit.exe_unit;
2042  if (ra_exe_unit.input_descs.size() != 1) {
2043  return false;
2044  }
2045  const auto& table_desc = ra_exe_unit.input_descs.front();
2046  if (table_desc.getSourceType() != InputSourceType::TABLE) {
2047  return false;
2048  }
2049  const int table_id = table_desc.getTableId();
2050  for (const auto simple_qual : ra_exe_unit.simple_quals) {
2051  const auto comp_expr =
2052  std::dynamic_pointer_cast<const Analyzer::BinOper>(simple_qual);
2053  if (!comp_expr || comp_expr->get_optype() != kEQ) {
2054  return false;
2055  }
2056  const auto lhs = comp_expr->get_left_operand();
2057  const auto lhs_col = dynamic_cast<const Analyzer::ColumnVar*>(lhs);
2058  if (!lhs_col || !lhs_col->get_table_id() || lhs_col->get_rte_idx()) {
2059  return false;
2060  }
2061  const auto rhs = comp_expr->get_right_operand();
2062  const auto rhs_const = dynamic_cast<const Analyzer::Constant*>(rhs);
2063  if (!rhs_const) {
2064  return false;
2065  }
2066  auto cd = get_column_descriptor(lhs_col->get_column_id(), table_id, cat_);
2067  if (cd->isVirtualCol) {
2068  CHECK_EQ("rowid", cd->columnName);
2069  return true;
2070  }
2071  }
2072  return false;
2073 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
Definition: sqldefs.h:30
const Catalog_Namespace::Catalog & cat_
const Expr * get_left_operand() const
Definition: Analyzer.h:436
const ColumnDescriptor * get_column_descriptor(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:141

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::list< std::shared_ptr< Analyzer::Expr > > RelAlgExecutor::makeJoinQuals ( const RexScalar join_condition,
const std::vector< JoinType > &  join_types,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
const bool  just_explain 
) const
private

Definition at line 2601 of file RelAlgExecutor.cpp.

References cat_, combine_equi_join_conditions(), executor_, anonymous_namespace{RelAlgExecutor.cpp}::get_bitwise_equals_conjunction(), now_, qual_to_conjunctive_form(), anonymous_namespace{RelAlgExecutor.cpp}::reverse_logical_distribution(), anonymous_namespace{RelAlgExecutor.cpp}::rex_to_conjunctive_form(), and RelAlgTranslator::translateScalarRex().

Referenced by translateLeftDeepJoinFilter().

2605  {
2606  QueryFeatureDescriptor query_features;
2607  RelAlgTranslator translator(cat_,
2608  executor_,
2609  input_to_nest_level,
2610  join_types,
2611  now_,
2612  just_explain,
2613  query_features);
2614  const auto rex_condition_cf = rex_to_conjunctive_form(join_condition);
2615  std::list<std::shared_ptr<Analyzer::Expr>> join_condition_quals;
2616  for (const auto rex_condition_component : rex_condition_cf) {
2617  const auto bw_equals = get_bitwise_equals_conjunction(rex_condition_component);
2618  const auto join_condition =
2619  reverse_logical_distribution(translator.translateScalarRex(
2620  bw_equals ? bw_equals.get() : rex_condition_component));
2621  auto join_condition_cf = qual_to_conjunctive_form(join_condition);
2622  join_condition_quals.insert(join_condition_quals.end(),
2623  join_condition_cf.quals.begin(),
2624  join_condition_cf.quals.end());
2625  join_condition_quals.insert(join_condition_quals.end(),
2626  join_condition_cf.simple_quals.begin(),
2627  join_condition_cf.simple_quals.end());
2628  }
2629  return combine_equi_join_conditions(join_condition_quals);
2630 }
std::unique_ptr< const RexOperator > get_bitwise_equals_conjunction(const RexScalar *scalar)
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
std::vector< const RexScalar * > rex_to_conjunctive_form(const RexScalar *qual_expr)
const Catalog_Namespace::Catalog & cat_
std::shared_ptr< Analyzer::Expr > reverse_logical_distribution(const std::shared_ptr< Analyzer::Expr > &expr)
Executor * executor_
std::list< std::shared_ptr< Analyzer::Expr > > combine_equi_join_conditions(const std::list< std::shared_ptr< Analyzer::Expr >> &join_quals)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgExecutor::prepareLeafExecution ( const AggregatedColRange agg_col_range,
const StringDictionaryGenerations string_dictionary_generations,
const TableGenerations table_generations 
)

Definition at line 242 of file RelAlgExecutor.cpp.

References executor_, g_enable_dynamic_watchdog, queue_time_ms_, timer_start(), and timer_stop().

245  {
246  // capture the lock acquistion time
247  auto clock_begin = timer_start();
249  executor_->resetInterrupt();
250  }
251  queue_time_ms_ = timer_stop(clock_begin);
252  executor_->row_set_mem_owner_ = std::make_shared<RowSetMemoryOwner>();
253  executor_->table_generations_ = table_generations;
254  executor_->agg_col_range_cache_ = agg_col_range;
255  executor_->string_dictionary_generations_ = string_dictionary_generations;
256 }
int64_t queue_time_ms_
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:46
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:72
Executor * executor_
Type timer_start()
Definition: measure.h:40

+ Here is the call graph for this function:

std::vector< PushedDownFilterInfo > RelAlgExecutor::selectFiltersToBePushedDown ( const RelAlgExecutor::WorkUnit work_unit,
const CompilationOptions co,
const ExecutionOptions eo 
)
private

Goes through all candidate filters and evaluate whether they pass the selectivity criteria or not.

Definition at line 133 of file JoinFilterPushDown.cpp.

References RelAlgExecutor::WorkUnit::exe_unit, executor_, find_push_down_filters(), get_table_infos(), getFilterSelectivity(), RelAlgExecutionUnit::input_descs, RelAlgExecutor::WorkUnit::input_permutation, RelAlgExecutor::WorkUnit::left_deep_join_input_sizes, and to_gather_info_for_filter_selectivity().

Referenced by executeWorkUnit().

136  {
137  const auto all_push_down_candidates =
139  work_unit.input_permutation,
140  work_unit.left_deep_join_input_sizes);
141  std::vector<PushedDownFilterInfo> selective_push_down_candidates;
142  const auto ti = get_table_infos(work_unit.exe_unit.input_descs, executor_);
144  for (const auto& candidate : all_push_down_candidates) {
145  const auto selectivity = getFilterSelectivity(candidate.filter_expressions, co, eo);
146  if (selectivity.is_valid && selectivity.isFilterSelectiveEnough()) {
147  selective_push_down_candidates.push_back(candidate);
148  }
149  }
150  }
151  return selective_push_down_candidates;
152 }
const std::vector< size_t > left_deep_join_input_sizes
RelAlgExecutionUnit exe_unit
FilterSelectivity getFilterSelectivity(const std::vector< std::shared_ptr< Analyzer::Expr >> &filter_expressions, const CompilationOptions &co, const ExecutionOptions &eo)
const std::vector< InputDescriptor > input_descs
bool to_gather_info_for_filter_selectivity(const std::vector< InputTableInfo > &table_infos)
std::vector< PushedDownFilterInfo > find_push_down_filters(const RelAlgExecutionUnit &ra_exe_unit, const std::vector< size_t > &input_permutation, const std::vector< size_t > &left_deep_join_input_sizes)
const std::vector< size_t > input_permutation
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
Executor * executor_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

JoinQualsPerNestingLevel RelAlgExecutor::translateLeftDeepJoinFilter ( const RelLeftDeepInnerJoin join,
const std::vector< InputDescriptor > &  input_descs,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
const bool  just_explain 
)
private

Definition at line 2635 of file RelAlgExecutor.cpp.

References CHECK(), CHECK_LE, RelLeftDeepInnerJoin::getInnerCondition(), RelLeftDeepInnerJoin::getOuterCondition(), INNER, LEFT, anonymous_namespace{RelAlgExecutor.cpp}::left_deep_join_types(), makeJoinQuals(), and run_benchmark_import::result.

Referenced by createCompoundWorkUnit(), and createProjectWorkUnit().

2639  {
2640  const auto join_types = left_deep_join_types(join);
2641  const auto join_condition_quals = makeJoinQuals(
2642  join->getInnerCondition(), join_types, input_to_nest_level, just_explain);
2643  MaxRangeTableIndexVisitor rte_idx_visitor;
2644  JoinQualsPerNestingLevel result(input_descs.size() - 1);
2645  std::unordered_set<std::shared_ptr<Analyzer::Expr>> visited_quals;
2646  for (size_t rte_idx = 1; rte_idx < input_descs.size(); ++rte_idx) {
2647  const auto outer_condition = join->getOuterCondition(rte_idx);
2648  if (outer_condition) {
2649  result[rte_idx - 1].quals =
2650  makeJoinQuals(outer_condition, join_types, input_to_nest_level, just_explain);
2651  CHECK_LE(rte_idx, join_types.size());
2652  CHECK(join_types[rte_idx - 1] == JoinType::LEFT);
2653  result[rte_idx - 1].type = JoinType::LEFT;
2654  continue;
2655  }
2656  for (const auto qual : join_condition_quals) {
2657  if (visited_quals.count(qual)) {
2658  continue;
2659  }
2660  const auto qual_rte_idx = rte_idx_visitor.visit(qual.get());
2661  if (static_cast<size_t>(qual_rte_idx) <= rte_idx) {
2662  const auto it_ok = visited_quals.emplace(qual);
2663  CHECK(it_ok.second);
2664  result[rte_idx - 1].quals.push_back(qual);
2665  }
2666  }
2667  CHECK_LE(rte_idx, join_types.size());
2668  CHECK(join_types[rte_idx - 1] == JoinType::INNER);
2669  result[rte_idx - 1].type = JoinType::INNER;
2670  }
2671  return result;
2672 }
std::vector< JoinType > left_deep_join_types(const RelLeftDeepInnerJoin *left_deep_join)
const RexScalar * getOuterCondition(const size_t nesting_level) const
std::vector< JoinCondition > JoinQualsPerNestingLevel
CHECK(cgen_state)
#define CHECK_LE(x, y)
Definition: Logger.h:204
const RexScalar * getInnerCondition() const
std::list< std::shared_ptr< Analyzer::Expr > > makeJoinQuals(const RexScalar *join_condition, const std::vector< JoinType > &join_types, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Friends And Related Function Documentation

friend class PendingExecutionClosure
friend

Definition at line 362 of file RelAlgExecutor.h.

Member Data Documentation

std::unordered_map<unsigned, AggregatedResult> RelAlgExecutor::leaf_results_
private

Definition at line 357 of file RelAlgExecutor.h.

Referenced by addLeafResult(), executeSort(), and executeWorkUnit().

const size_t RelAlgExecutor::max_groups_buffer_entry_default_guess {16384}
staticprivate
std::unique_ptr<RelAlgDagBuilder> RelAlgExecutor::query_dag_
private
std::shared_ptr<const query_state::QueryState> RelAlgExecutor::query_state_
private
int64_t RelAlgExecutor::queue_time_ms_
private

Definition at line 358 of file RelAlgExecutor.h.

Referenced by executeRelAlgQuerySingleStep(), and prepareLeafExecution().

SpeculativeTopNBlacklist RelAlgExecutor::speculative_topn_blacklist_
staticprivate

Definition at line 359 of file RelAlgExecutor.h.

Referenced by createSortInputWorkUnit(), and executeSort().


The documentation for this class was generated from the following files: