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

Namespaces

 anonymous_namespace{RelAlgDagBuilder.cpp}
 

Classes

class  RexRebindInputsVisitor
 
class  RexRebindReindexInputsVisitor
 
class  PushDownGenericExpressionInWindowFunction
 
class  RANodeIterator
 
class  WindowFunctionCollector
 
class  RexWindowFuncReplacementVisitor
 
class  RexInputCollector
 

Typedefs

using RexInputSet = std::unordered_set< RexInput >
 

Functions

std::vector< RexInputn_outputs (const RelAlgNode *node, const size_t n)
 
bool isRenamedInput (const RelAlgNode *node, const size_t index, const std::string &new_name)
 
std::vector< std::unique_ptr
< const RexAgg > > 
copyAggExprs (std::vector< std::unique_ptr< const RexAgg >> const &agg_exprs)
 
std::vector< std::unique_ptr
< const RexScalar > > 
copyRexScalars (std::vector< std::unique_ptr< const RexScalar >> const &scalar_sources)
 
std::vector< const Rex * > remapTargetPointers (std::vector< std::unique_ptr< const RexAgg >> const &agg_exprs_new, std::vector< std::unique_ptr< const RexScalar >> const &scalar_sources_new, std::vector< std::unique_ptr< const RexAgg >> const &agg_exprs_old, std::vector< std::unique_ptr< const RexScalar >> const &scalar_sources_old, std::vector< const Rex * > const &target_exprs_old)
 
std::set< std::pair< const
RelAlgNode *, int > > 
get_equiv_cols (const RelAlgNode *node, const size_t which_col)
 
unsigned node_id (const rapidjson::Value &ra_node) noexcept
 
std::string json_node_to_string (const rapidjson::Value &node) noexcept
 
std::unique_ptr< RexAbstractInputparse_abstract_input (const rapidjson::Value &expr) noexcept
 
std::unique_ptr< RexLiteralparse_literal (const rapidjson::Value &expr)
 
std::unique_ptr< const RexScalarparse_scalar_expr (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
SQLTypeInfo parse_type (const rapidjson::Value &type_obj)
 
std::vector< std::unique_ptr
< const RexScalar > > 
parse_expr_array (const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
SqlWindowFunctionKind parse_window_function_kind (const std::string &name)
 
std::vector< std::unique_ptr
< const RexScalar > > 
parse_window_order_exprs (const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
SortDirection parse_sort_direction (const rapidjson::Value &collation)
 
NullSortedPosition parse_nulls_position (const rapidjson::Value &collation)
 
std::vector< SortFieldparse_window_order_collation (const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
RexWindowFunctionOperator::RexWindowBound parse_window_bound (const rapidjson::Value &window_bound_obj, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
std::unique_ptr< const
RexSubQuery
parse_subquery (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
std::unique_ptr< RexOperatorparse_operator (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
std::unique_ptr< RexCaseparse_case (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
 
std::vector< std::string > strings_from_json_array (const rapidjson::Value &json_str_arr) noexcept
 
std::vector< size_t > indices_from_json_array (const rapidjson::Value &json_idx_arr) noexcept
 
std::unique_ptr< const RexAggparse_aggregate_expr (const rapidjson::Value &expr)
 
JoinType to_join_type (const std::string &join_type_name)
 
std::unique_ptr< const RexScalardisambiguate_rex (const RexScalar *, const RANodeOutput &)
 
std::unique_ptr< const
RexOperator
disambiguate_operator (const RexOperator *rex_operator, const RANodeOutput &ra_output) noexcept
 
std::unique_ptr< const RexCasedisambiguate_case (const RexCase *rex_case, const RANodeOutput &ra_output)
 
void bind_project_to_input (RelProject *project_node, const RANodeOutput &input) noexcept
 
void bind_table_func_to_input (RelTableFunction *table_func_node, const RANodeOutput &input) noexcept
 
void bind_inputs (const std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
 
void handle_query_hint (const std::vector< std::shared_ptr< RelAlgNode >> &nodes, RelAlgDagBuilder *dag_builder) noexcept
 
void compute_node_hash (const std::vector< std::shared_ptr< RelAlgNode >> &nodes)
 
void mark_nops (const std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
 
void create_compound (std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< size_t > &pattern, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints) noexcept
 
void coalesce_nodes (std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< const RelAlgNode * > &left_deep_joins, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
 
void propagate_hints_to_new_project (std::shared_ptr< RelProject > prev_node, std::shared_ptr< RelProject > new_node, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
 
void separate_window_function_expressions (std::vector< std::shared_ptr< RelAlgNode >> &nodes, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
 
void add_window_function_pre_project (std::vector< std::shared_ptr< RelAlgNode >> &nodes, const bool always_add_project_if_first_project_is_window_expr, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
 
int64_t get_int_literal_field (const rapidjson::Value &obj, const char field[], const int64_t default_val) noexcept
 
void check_empty_inputs_field (const rapidjson::Value &node) noexcept
 
const TableDescriptorgetTableFromScanNode (const Catalog_Namespace::Catalog &cat, const rapidjson::Value &scan_ra)
 
std::vector< std::string > getFieldNamesFromScanNode (const rapidjson::Value &scan_ra)
 

Variables

const unsigned FIRST_RA_NODE_ID = 1
 

Typedef Documentation

using anonymous_namespace{RelAlgDagBuilder.cpp}::RexInputSet = typedef std::unordered_set<RexInput>

Definition at line 2372 of file RelAlgDagBuilder.cpp.

Function Documentation

void anonymous_namespace{RelAlgDagBuilder.cpp}::add_window_function_pre_project ( std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
const bool  always_add_project_if_first_project_is_window_expr,
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &  query_hints 
)

Inserts a simple project before any project containing a window function node. Forces all window function inputs into a single contiguous buffer for centralized processing (e.g. in distributed mode). This is also needed when a window function node is preceded by a filter node, both for correctness (otherwise a window operator will be coalesced with its preceding filter node and be computer over unfiltered results, and for performance, as currently filter nodes that are not coalesced into projects keep all columns from the table as inputs, and hence bring everything in memory. Once the new project has been created, the inputs in the window function project must be rewritten to read from the new project, and to index off the projected exprs in the new project.

Definition at line 2401 of file RelAlgDagBuilder.cpp.

References anonymous_namespace{Utm.h}::a, CHECK, CHECK_EQ, RelAggregate::getGroupByCount(), RelProject::getProjectAt(), propagate_hints_to_new_project(), gpu_enabled::sort(), RexVisitorBase< T >::visit(), and VLOG.

Referenced by RelAlgDagBuilder::build().

2405  {
2406  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
2407  size_t project_node_counter{0};
2408  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
2409  const auto node = *node_itr;
2410 
2411  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
2412  if (!window_func_project_node) {
2413  continue;
2414  }
2415  project_node_counter++;
2416  if (!window_func_project_node->hasWindowFunctionExpr()) {
2417  // this projection node does not have a window function
2418  // expression -- skip to the next node in the DAG.
2419  continue;
2420  }
2421 
2422  auto need_pushdown_generic_expr = [&window_func_project_node]() {
2423  for (size_t i = 0; i < window_func_project_node->size(); ++i) {
2424  const auto projected_target = window_func_project_node->getProjectAt(i);
2425  if (auto window_expr =
2426  dynamic_cast<const RexWindowFunctionOperator*>(projected_target)) {
2427  for (const auto& partition_key : window_expr->getPartitionKeys()) {
2428  auto partition_input = dynamic_cast<const RexInput*>(partition_key.get());
2429  if (!partition_input) {
2430  return true;
2431  }
2432  }
2433  for (const auto& order_key : window_expr->getOrderKeys()) {
2434  auto order_input = dynamic_cast<const RexInput*>(order_key.get());
2435  if (!order_input) {
2436  return true;
2437  }
2438  }
2439  }
2440  }
2441  return false;
2442  };
2443 
2444  const auto prev_node_itr = std::prev(node_itr);
2445  const auto prev_node = *prev_node_itr;
2446  CHECK(prev_node);
2447 
2448  auto filter_node = std::dynamic_pointer_cast<RelFilter>(prev_node);
2449  auto join_node = std::dynamic_pointer_cast<RelJoin>(prev_node);
2450 
2451  auto scan_node = std::dynamic_pointer_cast<RelScan>(prev_node);
2452  const bool has_multi_fragment_scan_input =
2453  (scan_node &&
2454  (scan_node->getNumShards() > 0 || scan_node->getNumFragments() > 1));
2455  const bool needs_expr_pushdown = need_pushdown_generic_expr();
2456 
2457  // We currently add a preceding project node in one of two conditions:
2458  // 1. always_add_project_if_first_project_is_window_expr = true, which
2459  // we currently only set for distributed, but could also be set to support
2460  // multi-frag window function inputs, either if we can detect that an input table
2461  // is multi-frag up front, or using a retry mechanism like we do for join filter
2462  // push down.
2463  // TODO(todd): Investigate a viable approach for the above.
2464  // 2. Regardless of #1, if the window function project node is preceded by a
2465  // filter node. This is required both for correctness and to avoid pulling
2466  // all source input columns into memory since non-coalesced filter node
2467  // inputs are currently not pruned or eliminated via dead column elimination.
2468  // Note that we expect any filter node followed by a project node to be coalesced
2469  // into a single compound node in RelAlgDagBuilder::coalesce_nodes, and that action
2470  // prunes unused inputs.
2471  // TODO(todd): Investigate whether the shotgun filter node issue affects other
2472  // query plans, i.e. filters before joins, and whether there is a more general
2473  // approach to solving this (will still need the preceding project node for
2474  // window functions preceded by filter nodes for correctness though)
2475  // 3. Similar to the above, when the window function project node is preceded
2476  // by a join node.
2477  // 4. when partition by / order by clauses have a general expression instead of
2478  // referencing column
2479 
2480  if (!((always_add_project_if_first_project_is_window_expr &&
2481  project_node_counter == 1) ||
2482  filter_node || join_node || has_multi_fragment_scan_input ||
2483  needs_expr_pushdown)) {
2484  continue;
2485  }
2486 
2487  if (needs_expr_pushdown || join_node) {
2488  // previous logic cannot cover join_node case well, so use the newly introduced
2489  // push-down expression logic to safely add pre_project node before processing
2490  // window function
2491  std::unordered_map<size_t, size_t> expr_offset_cache;
2492  std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_for_new_project;
2493  std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_for_window_project;
2494  std::vector<std::string> fields_for_window_project;
2495  std::vector<std::string> fields_for_new_project;
2496 
2497  // step 0. create new project node with an empty scalar expr to rebind target exprs
2498  std::vector<std::unique_ptr<const RexScalar>> dummy_scalar_exprs;
2499  std::vector<std::string> dummy_fields;
2500  auto new_project =
2501  std::make_shared<RelProject>(dummy_scalar_exprs, dummy_fields, prev_node);
2502 
2503  // step 1 - 2
2504  PushDownGenericExpressionInWindowFunction visitor(new_project,
2505  scalar_exprs_for_new_project,
2506  fields_for_new_project,
2507  expr_offset_cache);
2508  for (size_t i = 0; i < window_func_project_node->size(); ++i) {
2509  auto projected_target = window_func_project_node->getProjectAt(i);
2510  auto new_projection_target = visitor.visit(projected_target);
2511  scalar_exprs_for_window_project.emplace_back(
2512  std::move(new_projection_target.release()));
2513  }
2514  new_project->setExpressions(scalar_exprs_for_new_project);
2515  new_project->setFields(std::move(fields_for_new_project));
2516  bool has_groupby = false;
2517  auto aggregate = std::dynamic_pointer_cast<RelAggregate>(prev_node);
2518  if (aggregate) {
2519  has_groupby = aggregate->getGroupByCount() > 0;
2520  }
2521  if (has_groupby && visitor.hasPartitionExpression()) {
2522  // we currently may compute incorrect result with columnar output when
2523  // 1) the window function has partition expression, and
2524  // 2) a parent node of the window function projection node has group by expression
2525  // so we force rowwise output (only) for the newly injected projection node
2526  // to prevent computing incorrect query result
2527  // todo (yoonmin) : relax this
2528  VLOG(1)
2529  << "Query output overridden to row-wise format due to presence of a window "
2530  "function with partition expression and group-by expression.";
2531  new_project->forceRowwiseOutput();
2532  }
2533  if (visitor.hasCaseExprAsWindowOperand()) {
2534  // force rowwise output
2535  VLOG(1)
2536  << "Query output overridden to row-wise format due to presence of a window "
2537  "function with a case statement as its operand.";
2538  new_project->forceRowwiseOutput();
2539  }
2540 
2541  // step 3. finalize
2542  propagate_hints_to_new_project(window_func_project_node, new_project, query_hints);
2543  node_list.insert(node_itr, new_project);
2544  window_func_project_node->replaceInput(prev_node, new_project);
2545  window_func_project_node->setExpressions(scalar_exprs_for_window_project);
2546  } else {
2547  // only push rex_inputs listed in the window function down to a new project node
2548  RexInputSet inputs;
2549  RexInputCollector input_collector;
2550  for (size_t i = 0; i < window_func_project_node->size(); i++) {
2551  auto new_inputs =
2552  input_collector.visit(window_func_project_node->getProjectAt(i));
2553  inputs.insert(new_inputs.begin(), new_inputs.end());
2554  }
2555 
2556  // Note: Technically not required since we are mapping old inputs to new input
2557  // indices, but makes the re-mapping of inputs easier to follow.
2558  std::vector<RexInput> sorted_inputs(inputs.begin(), inputs.end());
2559  std::sort(sorted_inputs.begin(),
2560  sorted_inputs.end(),
2561  [](const auto& a, const auto& b) { return a.getIndex() < b.getIndex(); });
2562 
2563  std::vector<std::unique_ptr<const RexScalar>> scalar_exprs;
2564  std::vector<std::string> fields;
2565  std::unordered_map<unsigned, unsigned> old_index_to_new_index;
2566  for (auto& input : sorted_inputs) {
2567  CHECK_EQ(input.getSourceNode(), prev_node.get());
2568  CHECK(old_index_to_new_index
2569  .insert(std::make_pair(input.getIndex(), scalar_exprs.size()))
2570  .second);
2571  scalar_exprs.emplace_back(input.deepCopy());
2572  fields.emplace_back("");
2573  }
2574 
2575  auto new_project = std::make_shared<RelProject>(scalar_exprs, fields, prev_node);
2576  propagate_hints_to_new_project(window_func_project_node, new_project, query_hints);
2577  node_list.insert(node_itr, new_project);
2578  window_func_project_node->replaceInput(
2579  prev_node, new_project, old_index_to_new_index);
2580  }
2581  }
2582  nodes.assign(node_list.begin(), node_list.end());
2583 }
const size_t getGroupByCount() const
#define CHECK_EQ(x, y)
Definition: Logger.h:231
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
constexpr double a
Definition: Utm.h:32
std::unordered_set< RexInput > RexInputSet
void propagate_hints_to_new_project(std::shared_ptr< RelProject > prev_node, std::shared_ptr< RelProject > new_node, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
const RexScalar * getProjectAt(const size_t idx) const
#define CHECK(condition)
Definition: Logger.h:223
#define VLOG(n)
Definition: Logger.h:317

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::bind_inputs ( const std::vector< std::shared_ptr< RelAlgNode >> &  nodes)
noexcept

Definition at line 1417 of file RelAlgDagBuilder.cpp.

References bind_project_to_input(), bind_table_func_to_input(), CHECK_EQ, disambiguate_rex(), and get_node_output().

Referenced by RelAlgDagBuilder::build().

1417  {
1418  for (auto ra_node : nodes) {
1419  const auto filter_node = std::dynamic_pointer_cast<RelFilter>(ra_node);
1420  if (filter_node) {
1421  CHECK_EQ(size_t(1), filter_node->inputCount());
1422  auto disambiguated_condition = disambiguate_rex(
1423  filter_node->getCondition(), get_node_output(filter_node->getInput(0)));
1424  filter_node->setCondition(disambiguated_condition);
1425  continue;
1426  }
1427  const auto join_node = std::dynamic_pointer_cast<RelJoin>(ra_node);
1428  if (join_node) {
1429  CHECK_EQ(size_t(2), join_node->inputCount());
1430  auto disambiguated_condition =
1431  disambiguate_rex(join_node->getCondition(), get_node_output(join_node.get()));
1432  join_node->setCondition(disambiguated_condition);
1433  continue;
1434  }
1435  const auto project_node = std::dynamic_pointer_cast<RelProject>(ra_node);
1436  if (project_node) {
1437  bind_project_to_input(project_node.get(),
1438  get_node_output(project_node->getInput(0)));
1439  continue;
1440  }
1441  const auto table_func_node = std::dynamic_pointer_cast<RelTableFunction>(ra_node);
1442  if (table_func_node) {
1443  /*
1444  Collect all inputs from table function input (non-literal)
1445  arguments.
1446  */
1447  RANodeOutput input;
1448  input.reserve(table_func_node->inputCount());
1449  for (size_t i = 0; i < table_func_node->inputCount(); i++) {
1450  auto node_output = get_node_output(table_func_node->getInput(i));
1451  input.insert(input.end(), node_output.begin(), node_output.end());
1452  }
1453  bind_table_func_to_input(table_func_node.get(), input);
1454  }
1455  }
1456 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
void bind_table_func_to_input(RelTableFunction *table_func_node, const RANodeOutput &input) noexcept
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
RANodeOutput get_node_output(const RelAlgNode *ra_node)
std::vector< RexInput > RANodeOutput

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::bind_project_to_input ( RelProject project_node,
const RANodeOutput input 
)
noexcept

Definition at line 1389 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs(), and create_compound().

1389  {
1390  CHECK_EQ(size_t(1), project_node->inputCount());
1391  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1392  for (size_t i = 0; i < project_node->size(); ++i) {
1393  const auto projected_expr = project_node->getProjectAt(i);
1394  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
1395  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
1396  } else {
1397  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
1398  }
1399  }
1400  project_node->setExpressions(disambiguated_exprs);
1401 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
size_t size() const override
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
const RexScalar * getProjectAtAndRelease(const size_t idx) const
const RexScalar * getProjectAt(const size_t idx) const
const size_t inputCount() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::bind_table_func_to_input ( RelTableFunction table_func_node,
const RANodeOutput input 
)
noexcept

Definition at line 1403 of file RelAlgDagBuilder.cpp.

References disambiguate_rex().

Referenced by bind_inputs().

1404  {
1405  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1406  for (size_t i = 0; i < table_func_node->getTableFuncInputsSize(); ++i) {
1407  const auto target_expr = table_func_node->getTableFuncInputAt(i);
1408  if (dynamic_cast<const RexSubQuery*>(target_expr)) {
1409  disambiguated_exprs.emplace_back(table_func_node->getTableFuncInputAtAndRelease(i));
1410  } else {
1411  disambiguated_exprs.emplace_back(disambiguate_rex(target_expr, input));
1412  }
1413  }
1414  table_func_node->setTableFuncInputs(disambiguated_exprs);
1415 }
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
size_t getTableFuncInputsSize() const
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
const RexScalar * getTableFuncInputAt(const size_t idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::check_empty_inputs_field ( const rapidjson::Value &  node)
noexcept

Definition at line 2599 of file RelAlgDagBuilder.cpp.

References CHECK, and field().

Referenced by details::RelAlgDispatcher::dispatchTableScan().

2599  {
2600  const auto& inputs_json = field(node, "inputs");
2601  CHECK(inputs_json.IsArray() && !inputs_json.Size());
2602 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::coalesce_nodes ( std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
const std::vector< const RelAlgNode * > &  left_deep_joins,
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &  query_hints 
)

Definition at line 1904 of file RelAlgDagBuilder.cpp.

References anonymous_namespace{RelAlgDagBuilder.cpp}::RANodeIterator::allVisited(), CHECK, CHECK_GE, create_compound(), anonymous_namespace{RelAlgDagBuilder.cpp}::anonymous_namespace{RelAlgDagBuilder.cpp}::input_can_be_coalesced(), and gpu_enabled::swap().

Referenced by RelAlgDagBuilder::build().

1908  {
1909  enum class CoalesceState { Initial, Filter, FirstProject, Aggregate };
1910  std::vector<size_t> crt_pattern;
1911  CoalesceState crt_state{CoalesceState::Initial};
1912 
1913  auto reset_state = [&crt_pattern, &crt_state]() {
1914  crt_state = CoalesceState::Initial;
1915  std::vector<size_t>().swap(crt_pattern);
1916  };
1917 
1918  for (RANodeIterator nodeIt(nodes); !nodeIt.allVisited();) {
1919  const auto ra_node = nodeIt != nodes.end() ? *nodeIt : nullptr;
1920  switch (crt_state) {
1921  case CoalesceState::Initial: {
1922  if (std::dynamic_pointer_cast<const RelFilter>(ra_node) &&
1923  std::find(left_deep_joins.begin(), left_deep_joins.end(), ra_node.get()) ==
1924  left_deep_joins.end()) {
1925  crt_pattern.push_back(size_t(nodeIt));
1926  crt_state = CoalesceState::Filter;
1927  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1928  } else if (auto project_node =
1929  std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1930  if (project_node->hasWindowFunctionExpr()) {
1931  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1932  } else {
1933  crt_pattern.push_back(size_t(nodeIt));
1934  crt_state = CoalesceState::FirstProject;
1935  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1936  }
1937  } else {
1938  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1939  }
1940  break;
1941  }
1942  case CoalesceState::Filter: {
1943  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1944  // Given we now add preceding projects for all window functions following
1945  // RelFilter nodes, the following should never occur
1946  CHECK(!project_node->hasWindowFunctionExpr());
1947  crt_pattern.push_back(size_t(nodeIt));
1948  crt_state = CoalesceState::FirstProject;
1949  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1950  } else {
1951  reset_state();
1952  }
1953  break;
1954  }
1955  case CoalesceState::FirstProject: {
1956  if (std::dynamic_pointer_cast<const RelAggregate>(ra_node)) {
1957  crt_pattern.push_back(size_t(nodeIt));
1958  crt_state = CoalesceState::Aggregate;
1959  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1960  } else {
1961  if (crt_pattern.size() >= 2) {
1962  create_compound(nodes, crt_pattern, query_hints);
1963  }
1964  reset_state();
1965  }
1966  break;
1967  }
1968  case CoalesceState::Aggregate: {
1969  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1970  if (!project_node->hasWindowFunctionExpr()) {
1971  // TODO(adb): overloading the simple project terminology again here
1972  bool is_simple_project{true};
1973  for (size_t i = 0; i < project_node->size(); i++) {
1974  const auto scalar_rex = project_node->getProjectAt(i);
1975  // If the top level scalar rex is an input node, we can bypass the visitor
1976  if (auto input_rex = dynamic_cast<const RexInput*>(scalar_rex)) {
1978  input_rex->getSourceNode(), input_rex->getIndex(), true)) {
1979  is_simple_project = false;
1980  break;
1981  }
1982  continue;
1983  }
1984  CoalesceSecondaryProjectVisitor visitor;
1985  if (!visitor.visit(project_node->getProjectAt(i))) {
1986  is_simple_project = false;
1987  break;
1988  }
1989  }
1990  if (is_simple_project) {
1991  crt_pattern.push_back(size_t(nodeIt));
1992  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1993  }
1994  }
1995  }
1996  CHECK_GE(crt_pattern.size(), size_t(2));
1997  create_compound(nodes, crt_pattern, query_hints);
1998  reset_state();
1999  break;
2000  }
2001  default:
2002  CHECK(false);
2003  }
2004  }
2005  if (crt_state == CoalesceState::FirstProject || crt_state == CoalesceState::Aggregate) {
2006  if (crt_pattern.size() >= 2) {
2007  create_compound(nodes, crt_pattern, query_hints);
2008  }
2009  CHECK(!crt_pattern.empty());
2010  }
2011 }
#define CHECK_GE(x, y)
Definition: Logger.h:236
void create_compound(std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< size_t > &pattern, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints) noexcept
#define CHECK(condition)
Definition: Logger.h:223
bool input_can_be_coalesced(const RelAlgNode *parent_node, const size_t index, const bool first_rex_is_input)
DEVICE void swap(ARGS &&...args)
Definition: gpu_enabled.h:114

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::compute_node_hash ( const std::vector< std::shared_ptr< RelAlgNode >> &  nodes)

Definition at line 1491 of file RelAlgDagBuilder.cpp.

References CHECK_NE.

Referenced by RelAlgDagBuilder::build().

1491  {
1492  // compute each rel node's hash value in advance to avoid inconsistency of their hash
1493  // values depending on the toHash's caller
1494  // specifically, we manipulate our logical query plan before retrieving query step
1495  // sequence but once we compute a hash value we cached it so there is no way to update
1496  // it after the plan has been changed starting from the top node, we compute the hash
1497  // value (top-down manner)
1498  std::for_each(
1499  nodes.rbegin(), nodes.rend(), [](const std::shared_ptr<RelAlgNode>& node) {
1500  auto node_hash = node->toHash();
1501  CHECK_NE(node_hash, static_cast<size_t>(0));
1502  });
1503 }
#define CHECK_NE(x, y)
Definition: Logger.h:232

+ Here is the caller graph for this function:

std::vector<std::unique_ptr<const RexAgg> > anonymous_namespace{RelAlgDagBuilder.cpp}::copyAggExprs ( std::vector< std::unique_ptr< const RexAgg >> const &  agg_exprs)

Definition at line 616 of file RelAlgDagBuilder.cpp.

617  {
618  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_copy;
619  agg_exprs_copy.reserve(agg_exprs.size());
620  for (auto const& agg_expr : agg_exprs) {
621  agg_exprs_copy.push_back(agg_expr->deepCopy());
622  }
623  return agg_exprs_copy;
624 }
std::vector<std::unique_ptr<const RexScalar> > anonymous_namespace{RelAlgDagBuilder.cpp}::copyRexScalars ( std::vector< std::unique_ptr< const RexScalar >> const &  scalar_sources)

Definition at line 626 of file RelAlgDagBuilder.cpp.

References RexVisitorBase< T >::visit().

627  {
628  std::vector<std::unique_ptr<const RexScalar>> scalar_sources_copy;
629  scalar_sources_copy.reserve(scalar_sources.size());
630  RexDeepCopyVisitor copier;
631  for (auto const& scalar_source : scalar_sources) {
632  scalar_sources_copy.push_back(copier.visit(scalar_source.get()));
633  }
634  return scalar_sources_copy;
635 }
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27

+ Here is the call graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::create_compound ( std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
const std::vector< size_t > &  pattern,
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &  query_hints 
)
noexcept

Definition at line 1565 of file RelAlgDagBuilder.cpp.

References bind_project_to_input(), CHECK, CHECK_EQ, CHECK_GE, CHECK_LE, CHECK_LT, RegisteredQueryHint::defaults(), get_node_output(), RelProject::getFields(), anonymous_namespace{RelAlgExecutor.cpp}::is_agg(), node_id(), anonymous_namespace{RelAlgDagBuilder.cpp}::anonymous_namespace{RelAlgDagBuilder.cpp}::reproject_targets(), and run_benchmark_import::result.

Referenced by coalesce_nodes().

1569  {
1570  CHECK_GE(pattern.size(), size_t(2));
1571  CHECK_LE(pattern.size(), size_t(4));
1572 
1573  std::unique_ptr<const RexScalar> filter_rex;
1574  std::vector<std::unique_ptr<const RexScalar>> scalar_sources;
1575  size_t groupby_count{0};
1576  std::vector<std::string> fields;
1577  std::vector<const RexAgg*> agg_exprs;
1578  std::vector<const Rex*> target_exprs;
1579  bool first_project{true};
1580  bool is_agg{false};
1581  RelAlgNode* last_node{nullptr};
1582 
1583  std::shared_ptr<ModifyManipulationTarget> manipulation_target;
1584  size_t node_hash{0};
1585  unsigned node_id{0};
1586  bool hint_registered{false};
1587  RegisteredQueryHint registered_query_hint = RegisteredQueryHint::defaults();
1588  for (const auto node_idx : pattern) {
1589  const auto ra_node = nodes[node_idx];
1590  auto registered_query_hint_map_it = query_hints.find(ra_node->toHash());
1591  if (registered_query_hint_map_it != query_hints.end()) {
1592  auto& registered_query_hint_map = registered_query_hint_map_it->second;
1593  auto registered_query_hint_it = registered_query_hint_map.find(ra_node->getId());
1594  if (registered_query_hint_it != registered_query_hint_map.end()) {
1595  hint_registered = true;
1596  node_hash = registered_query_hint_map_it->first;
1597  node_id = registered_query_hint_it->first;
1598  registered_query_hint = registered_query_hint_it->second;
1599  }
1600  }
1601  const auto ra_filter = std::dynamic_pointer_cast<RelFilter>(ra_node);
1602  if (ra_filter) {
1603  CHECK(!filter_rex);
1604  filter_rex.reset(ra_filter->getAndReleaseCondition());
1605  CHECK(filter_rex);
1606  last_node = ra_node.get();
1607  continue;
1608  }
1609  const auto ra_project = std::dynamic_pointer_cast<RelProject>(ra_node);
1610  if (ra_project) {
1611  fields = ra_project->getFields();
1612  manipulation_target = ra_project;
1613 
1614  if (first_project) {
1615  CHECK_EQ(size_t(1), ra_project->inputCount());
1616  // Rebind the input of the project to the input of the filter itself
1617  // since we know that we'll evaluate the filter on the fly, with no
1618  // intermediate buffer.
1619  const auto filter_input = dynamic_cast<const RelFilter*>(ra_project->getInput(0));
1620  if (filter_input) {
1621  CHECK_EQ(size_t(1), filter_input->inputCount());
1622  bind_project_to_input(ra_project.get(),
1623  get_node_output(filter_input->getInput(0)));
1624  }
1625  scalar_sources = ra_project->getExpressionsAndRelease();
1626  for (const auto& scalar_expr : scalar_sources) {
1627  target_exprs.push_back(scalar_expr.get());
1628  }
1629  first_project = false;
1630  } else {
1631  if (ra_project->isSimple()) {
1632  target_exprs = reproject_targets(ra_project.get(), target_exprs);
1633  } else {
1634  // TODO(adb): This is essentially a more general case of simple project, we
1635  // could likely merge the two
1636  std::vector<const Rex*> result;
1637  RexInputReplacementVisitor visitor(last_node, scalar_sources);
1638  for (size_t i = 0; i < ra_project->size(); ++i) {
1639  const auto rex = ra_project->getProjectAt(i);
1640  if (auto rex_input = dynamic_cast<const RexInput*>(rex)) {
1641  const auto index = rex_input->getIndex();
1642  CHECK_LT(index, target_exprs.size());
1643  result.push_back(target_exprs[index]);
1644  } else {
1645  scalar_sources.push_back(visitor.visit(rex));
1646  result.push_back(scalar_sources.back().get());
1647  }
1648  }
1649  target_exprs = result;
1650  }
1651  }
1652  last_node = ra_node.get();
1653  continue;
1654  }
1655  const auto ra_aggregate = std::dynamic_pointer_cast<RelAggregate>(ra_node);
1656  if (ra_aggregate) {
1657  is_agg = true;
1658  fields = ra_aggregate->getFields();
1659  agg_exprs = ra_aggregate->getAggregatesAndRelease();
1660  groupby_count = ra_aggregate->getGroupByCount();
1661  decltype(target_exprs){}.swap(target_exprs);
1662  CHECK_LE(groupby_count, scalar_sources.size());
1663  for (size_t group_idx = 0; group_idx < groupby_count; ++group_idx) {
1664  const auto rex_ref = new RexRef(group_idx + 1);
1665  target_exprs.push_back(rex_ref);
1666  scalar_sources.emplace_back(rex_ref);
1667  }
1668  for (const auto rex_agg : agg_exprs) {
1669  target_exprs.push_back(rex_agg);
1670  }
1671  last_node = ra_node.get();
1672  continue;
1673  }
1674  }
1675 
1676  auto compound_node =
1677  std::make_shared<RelCompound>(filter_rex,
1678  target_exprs,
1679  groupby_count,
1680  agg_exprs,
1681  fields,
1682  scalar_sources,
1683  is_agg,
1684  manipulation_target->isUpdateViaSelect(),
1685  manipulation_target->isDeleteViaSelect(),
1686  manipulation_target->isVarlenUpdateRequired(),
1687  manipulation_target->getModifiedTableDescriptor(),
1688  manipulation_target->getTargetColumns());
1689  auto old_node = nodes[pattern.back()];
1690  nodes[pattern.back()] = compound_node;
1691  auto first_node = nodes[pattern.front()];
1692  CHECK_EQ(size_t(1), first_node->inputCount());
1693  compound_node->addManagedInput(first_node->getAndOwnInput(0));
1694  if (hint_registered) {
1695  // pass the registered hint from the origin node to newly created compound node
1696  // where it is coalesced
1697  auto registered_query_hint_map_it = query_hints.find(node_hash);
1698  CHECK(registered_query_hint_map_it != query_hints.end());
1699  auto registered_query_hint_map = registered_query_hint_map_it->second;
1700  if (registered_query_hint_map.size() > 1) {
1701  registered_query_hint_map.erase(node_id);
1702  } else {
1703  CHECK_EQ(registered_query_hint_map.size(), static_cast<size_t>(1));
1704  query_hints.erase(node_hash);
1705  }
1706  std::unordered_map<unsigned, RegisteredQueryHint> hint_map;
1707  hint_map.emplace(compound_node->getId(), registered_query_hint);
1708  query_hints.emplace(compound_node->toHash(), hint_map);
1709  }
1710  for (size_t i = 0; i < pattern.size() - 1; ++i) {
1711  nodes[pattern[i]].reset();
1712  }
1713  for (auto node : nodes) {
1714  if (!node) {
1715  continue;
1716  }
1717  node->replaceInput(old_node, compound_node);
1718  }
1719 }
bool is_agg(const Analyzer::Expr *expr)
#define CHECK_EQ(x, y)
Definition: Logger.h:231
#define CHECK_GE(x, y)
Definition: Logger.h:236
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
#define CHECK_LT(x, y)
Definition: Logger.h:233
static RegisteredQueryHint defaults()
Definition: QueryHint.h:237
#define CHECK_LE(x, y)
Definition: Logger.h:234
const std::vector< std::string > & getFields() const
#define CHECK(condition)
Definition: Logger.h:223
unsigned node_id(const rapidjson::Value &ra_node) noexcept
RANodeOutput get_node_output(const RelAlgNode *ra_node)
std::vector< const Rex * > reproject_targets(const RelProject *simple_project, const std::vector< const Rex * > &target_exprs) noexcept

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<const RexCase> anonymous_namespace{RelAlgDagBuilder.cpp}::disambiguate_case ( const RexCase rex_case,
const RANodeOutput ra_output 
)

Definition at line 1342 of file RelAlgDagBuilder.cpp.

References RexCase::branchCount(), disambiguate_rex(), RexCase::getElse(), RexCase::getThen(), and RexCase::getWhen().

Referenced by disambiguate_rex().

1343  {
1344  std::vector<
1345  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
1346  disambiguated_expr_pair_list;
1347  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
1348  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
1349  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
1350  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
1351  std::move(disambiguated_then));
1352  }
1353  std::unique_ptr<const RexScalar> disambiguated_else{
1354  disambiguate_rex(rex_case->getElse(), ra_output)};
1355  return std::unique_ptr<const RexCase>(
1356  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
1357 }
const RexScalar * getThen(const size_t idx) const
const RexScalar * getElse() const
const RexScalar * getWhen(const size_t idx) const
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
size_t branchCount() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<const RexOperator> anonymous_namespace{RelAlgDagBuilder.cpp}::disambiguate_operator ( const RexOperator rex_operator,
const RANodeOutput ra_output 
)
noexcept

Definition at line 1307 of file RelAlgDagBuilder.cpp.

References disambiguate_rex(), and RexWindowFunctionOperator::getPartitionKeys().

Referenced by disambiguate_rex().

1309  {
1310  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
1311  for (size_t i = 0; i < rex_operator->size(); ++i) {
1312  auto operand = rex_operator->getOperand(i);
1313  if (dynamic_cast<const RexSubQuery*>(operand)) {
1314  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
1315  } else {
1316  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
1317  }
1318  }
1319  const auto rex_window_function_operator =
1320  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
1321  if (rex_window_function_operator) {
1322  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
1323  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
1324  for (const auto& partition_key : partition_keys) {
1325  disambiguated_partition_keys.emplace_back(
1326  disambiguate_rex(partition_key.get(), ra_output));
1327  }
1328  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
1329  const auto& order_keys = rex_window_function_operator->getOrderKeys();
1330  for (const auto& order_key : order_keys) {
1331  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
1332  }
1333  return rex_window_function_operator->disambiguatedOperands(
1334  disambiguated_operands,
1335  disambiguated_partition_keys,
1336  disambiguated_order_keys,
1337  rex_window_function_operator->getCollation());
1338  }
1339  return rex_operator->getDisambiguated(disambiguated_operands);
1340 }
size_t size() const
const RexScalar * getOperand(const size_t idx) const
const RexScalar * getOperandAndRelease(const size_t idx) const
virtual std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
const ConstRexScalarPtrVector & getPartitionKeys() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr< const RexScalar > anonymous_namespace{RelAlgDagBuilder.cpp}::disambiguate_rex ( const RexScalar rex_scalar,
const RANodeOutput ra_output 
)

Definition at line 1363 of file RelAlgDagBuilder.cpp.

References CHECK_LT, disambiguate_case(), and disambiguate_operator().

Referenced by bind_inputs(), bind_project_to_input(), bind_table_func_to_input(), disambiguate_case(), and disambiguate_operator().

1364  {
1365  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
1366  if (rex_abstract_input) {
1367  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
1368  return std::unique_ptr<const RexInput>(
1369  new RexInput(ra_output[rex_abstract_input->getIndex()]));
1370  }
1371  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
1372  if (rex_operator) {
1373  return disambiguate_operator(rex_operator, ra_output);
1374  }
1375  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
1376  if (rex_case) {
1377  return disambiguate_case(rex_case, ra_output);
1378  }
1379  if (auto const rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar)) {
1380  return rex_literal->deepCopy();
1381  } else if (auto const rex_subquery = dynamic_cast<const RexSubQuery*>(rex_scalar)) {
1382  return rex_subquery->deepCopy();
1383  } else {
1384  throw QueryNotSupported("Unable to disambiguate expression of type " +
1385  std::string(typeid(*rex_scalar).name()));
1386  }
1387 }
#define CHECK_LT(x, y)
Definition: Logger.h:233
std::unique_ptr< const RexOperator > disambiguate_operator(const RexOperator *rex_operator, const RANodeOutput &ra_output) noexcept
std::unique_ptr< const RexCase > disambiguate_case(const RexCase *rex_case, const RANodeOutput &ra_output)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::set<std::pair<const RelAlgNode*, int> > anonymous_namespace{RelAlgDagBuilder.cpp}::get_equiv_cols ( const RelAlgNode node,
const size_t  which_col 
)

Definition at line 739 of file RelAlgDagBuilder.cpp.

References CHECK, and CHECK_EQ.

Referenced by RelSort::hasEquivCollationOf().

740  {
741  std::set<std::pair<const RelAlgNode*, int>> work_set;
742  auto walker = node;
743  auto curr_col = which_col;
744  while (true) {
745  work_set.insert(std::make_pair(walker, curr_col));
746  if (dynamic_cast<const RelScan*>(walker) || dynamic_cast<const RelJoin*>(walker)) {
747  break;
748  }
749  CHECK_EQ(size_t(1), walker->inputCount());
750  auto only_source = walker->getInput(0);
751  if (auto project = dynamic_cast<const RelProject*>(walker)) {
752  if (auto input = dynamic_cast<const RexInput*>(project->getProjectAt(curr_col))) {
753  const auto join_source = dynamic_cast<const RelJoin*>(only_source);
754  if (join_source) {
755  CHECK_EQ(size_t(2), join_source->inputCount());
756  auto lhs = join_source->getInput(0);
757  CHECK((input->getIndex() < lhs->size() && lhs == input->getSourceNode()) ||
758  join_source->getInput(1) == input->getSourceNode());
759  } else {
760  CHECK_EQ(input->getSourceNode(), only_source);
761  }
762  curr_col = input->getIndex();
763  } else {
764  break;
765  }
766  } else if (auto aggregate = dynamic_cast<const RelAggregate*>(walker)) {
767  if (curr_col >= aggregate->getGroupByCount()) {
768  break;
769  }
770  }
771  walker = only_source;
772  }
773  return work_set;
774 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the caller graph for this function:

int64_t anonymous_namespace{RelAlgDagBuilder.cpp}::get_int_literal_field ( const rapidjson::Value &  obj,
const char  field[],
const int64_t  default_val 
)
noexcept

Definition at line 2585 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, field(), kDECIMAL, and parse_literal().

Referenced by details::RelAlgDispatcher::dispatchSort().

2587  {
2588  const auto it = obj.FindMember(field);
2589  if (it == obj.MemberEnd()) {
2590  return default_val;
2591  }
2592  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
2593  CHECK_EQ(kDECIMAL, lit->getType());
2594  CHECK_EQ(unsigned(0), lit->getScale());
2595  CHECK_EQ(unsigned(0), lit->getTargetScale());
2596  return lit->getVal<int64_t>();
2597 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::unique_ptr< RexLiteral > parse_literal(const rapidjson::Value &expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<std::string> anonymous_namespace{RelAlgDagBuilder.cpp}::getFieldNamesFromScanNode ( const rapidjson::Value &  scan_ra)

Definition at line 2614 of file RelAlgDagBuilder.cpp.

References field(), and strings_from_json_array().

Referenced by details::RelAlgDispatcher::dispatchTableScan().

2614  {
2615  const auto& fields_json = field(scan_ra, "fieldNames");
2616  return strings_from_json_array(fields_json);
2617 }
std::vector< std::string > strings_from_json_array(const rapidjson::Value &json_str_arr) noexcept
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const TableDescriptor* anonymous_namespace{RelAlgDagBuilder.cpp}::getTableFromScanNode ( const Catalog_Namespace::Catalog cat,
const rapidjson::Value &  scan_ra 
)

Definition at line 2604 of file RelAlgDagBuilder.cpp.

References CHECK, CHECK_EQ, field(), and Catalog_Namespace::Catalog::getMetadataForTable().

Referenced by details::RelAlgDispatcher::dispatchModify(), and details::RelAlgDispatcher::dispatchTableScan().

2605  {
2606  const auto& table_json = field(scan_ra, "table");
2607  CHECK(table_json.IsArray());
2608  CHECK_EQ(unsigned(2), table_json.Size());
2609  const auto td = cat.getMetadataForTable(table_json[1].GetString());
2610  CHECK(td);
2611  return td;
2612 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:223
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::handle_query_hint ( const std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
RelAlgDagBuilder dag_builder 
)
noexcept

Definition at line 1458 of file RelAlgDagBuilder.cpp.

References RelProject::getDeliveredHints(), RelAggregate::getDeliveredHints(), and RelCompound::getDeliveredHints().

Referenced by RelAlgDagBuilder::build().

1459  {
1460  // query hint is delivered by the above three nodes
1461  // when a query block has top-sort node, a hint is registered to
1462  // one of the node which locates at the nearest from the sort node
1463  RegisteredQueryHint global_query_hint;
1464  for (auto node : nodes) {
1465  Hints* hint_delivered = nullptr;
1466  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1467  if (agg_node) {
1468  if (agg_node->hasDeliveredHint()) {
1469  hint_delivered = agg_node->getDeliveredHints();
1470  }
1471  }
1472  const auto project_node = std::dynamic_pointer_cast<RelProject>(node);
1473  if (project_node) {
1474  if (project_node->hasDeliveredHint()) {
1475  hint_delivered = project_node->getDeliveredHints();
1476  }
1477  }
1478  const auto compound_node = std::dynamic_pointer_cast<RelCompound>(node);
1479  if (compound_node) {
1480  if (compound_node->hasDeliveredHint()) {
1481  hint_delivered = compound_node->getDeliveredHints();
1482  }
1483  }
1484  if (hint_delivered && !hint_delivered->empty()) {
1485  dag_builder->registerQueryHints(node, hint_delivered, global_query_hint);
1486  }
1487  }
1488  dag_builder->setGlobalQueryHints(global_query_hint);
1489 }
Hints * getDeliveredHints()
void registerQueryHints(std::shared_ptr< RelAlgNode > node, Hints *hints_delivered, RegisteredQueryHint &global_query_hint)
Hints * getDeliveredHints()
Hints * getDeliveredHints()
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:263
void setGlobalQueryHints(const RegisteredQueryHint &global_hints)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<size_t> anonymous_namespace{RelAlgDagBuilder.cpp}::indices_from_json_array ( const rapidjson::Value &  json_idx_arr)
noexcept

Definition at line 1235 of file RelAlgDagBuilder.cpp.

References CHECK, and CHECK_GE.

Referenced by details::RelAlgDispatcher::dispatchAggregate(), and parse_aggregate_expr().

1236  {
1237  CHECK(json_idx_arr.IsArray());
1238  std::vector<size_t> indices;
1239  for (auto json_idx_arr_it = json_idx_arr.Begin(); json_idx_arr_it != json_idx_arr.End();
1240  ++json_idx_arr_it) {
1241  CHECK(json_idx_arr_it->IsInt());
1242  CHECK_GE(json_idx_arr_it->GetInt(), 0);
1243  indices.emplace_back(json_idx_arr_it->GetInt());
1244  }
1245  return indices;
1246 }
#define CHECK_GE(x, y)
Definition: Logger.h:236
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgDagBuilder.cpp}::isRenamedInput ( const RelAlgNode node,
const size_t  index,
const std::string &  new_name 
)

Definition at line 470 of file RelAlgDagBuilder.cpp.

References CHECK, CHECK_EQ, CHECK_GE, CHECK_LT, RelAlgNode::getInput(), join(), and RelAlgNode::size().

Referenced by RelProject::isRenaming().

472  {
473  CHECK_LT(index, node->size());
474  if (auto join = dynamic_cast<const RelJoin*>(node)) {
475  CHECK_EQ(size_t(2), join->inputCount());
476  const auto lhs_size = join->getInput(0)->size();
477  if (index < lhs_size) {
478  return isRenamedInput(join->getInput(0), index, new_name);
479  }
480  CHECK_GE(index, lhs_size);
481  return isRenamedInput(join->getInput(1), index - lhs_size, new_name);
482  }
483 
484  if (auto scan = dynamic_cast<const RelScan*>(node)) {
485  return new_name != scan->getFieldName(index);
486  }
487 
488  if (auto aggregate = dynamic_cast<const RelAggregate*>(node)) {
489  return new_name != aggregate->getFieldName(index);
490  }
491 
492  if (auto project = dynamic_cast<const RelProject*>(node)) {
493  return new_name != project->getFieldName(index);
494  }
495 
496  if (auto table_func = dynamic_cast<const RelTableFunction*>(node)) {
497  return new_name != table_func->getFieldName(index);
498  }
499 
500  if (auto logical_values = dynamic_cast<const RelLogicalValues*>(node)) {
501  const auto& tuple_type = logical_values->getTupleType();
502  CHECK_LT(index, tuple_type.size());
503  return new_name != tuple_type[index].get_resname();
504  }
505 
506  CHECK(dynamic_cast<const RelSort*>(node) || dynamic_cast<const RelFilter*>(node) ||
507  dynamic_cast<const RelLogicalUnion*>(node));
508  return isRenamedInput(node->getInput(0), index, new_name);
509 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
std::string join(T const &container, std::string const &delim)
bool isRenamedInput(const RelAlgNode *node, const size_t index, const std::string &new_name)
#define CHECK_GE(x, y)
Definition: Logger.h:236
const RelAlgNode * getInput(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:233
virtual size_t size() const =0
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string anonymous_namespace{RelAlgDagBuilder.cpp}::json_node_to_string ( const rapidjson::Value &  node)
noexcept

Definition at line 900 of file RelAlgDagBuilder.cpp.

Referenced by details::RelAlgDispatcher::dispatchModify(), parse_scalar_expr(), and parse_type().

900  {
901  rapidjson::StringBuffer buffer;
902  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
903  node.Accept(writer);
904  return buffer.GetString();
905 }

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::mark_nops ( const std::vector< std::shared_ptr< RelAlgNode >> &  nodes)
noexcept

Definition at line 1505 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by RelAlgDagBuilder::build().

1505  {
1506  for (auto node : nodes) {
1507  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1508  if (!agg_node || agg_node->getAggExprsCount()) {
1509  continue;
1510  }
1511  CHECK_EQ(size_t(1), node->inputCount());
1512  const auto agg_input_node = dynamic_cast<const RelAggregate*>(node->getInput(0));
1513  if (agg_input_node && !agg_input_node->getAggExprsCount() &&
1514  agg_node->getGroupByCount() == agg_input_node->getGroupByCount()) {
1515  agg_node->markAsNop();
1516  }
1517  }
1518 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<RexInput> anonymous_namespace{RelAlgDagBuilder.cpp}::n_outputs ( const RelAlgNode node,
const size_t  n 
)

Definition at line 96 of file RelAlgDagBuilder.cpp.

References anonymous_namespace{Utm.h}::n.

Referenced by get_node_output().

96  {
97  std::vector<RexInput> outputs;
98  outputs.reserve(n);
99  for (size_t i = 0; i < n; ++i) {
100  outputs.emplace_back(node, i);
101  }
102  return outputs;
103 }
constexpr double n
Definition: Utm.h:38

+ Here is the caller graph for this function:

unsigned anonymous_namespace{RelAlgDagBuilder.cpp}::node_id ( const rapidjson::Value &  ra_node)
noexcept

Definition at line 895 of file RelAlgDagBuilder.cpp.

References field(), and json_str().

Referenced by create_compound(), details::RelAlgDispatcher::dispatchFilter(), RaExecutionSequence::extractQueryStepSkippingInfo(), QueryPlanDagExtractor::handleTranslatedJoin(), details::RelAlgDispatcher::prev(), and details::RelAlgDispatcher::run().

895  {
896  const auto& id = field(ra_node, "id");
897  return std::stoi(json_str(id));
898 }
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<RexAbstractInput> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_abstract_input ( const rapidjson::Value &  expr)
noexcept

Definition at line 911 of file RelAlgDagBuilder.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

912  {
913  const auto& input = field(expr, "input");
914  return std::unique_ptr<RexAbstractInput>(new RexAbstractInput(json_i64(input)));
915 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<const RexAgg> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_aggregate_expr ( const rapidjson::Value &  expr)

Definition at line 1248 of file RelAlgDagBuilder.cpp.

References field(), indices_from_json_array(), logger::INFO, json_bool(), json_str(), kAPPROX_COUNT_DISTINCT, kAPPROX_QUANTILE, LOG, parse_type(), and to_agg_kind().

Referenced by details::RelAlgDispatcher::dispatchAggregate().

1248  {
1249  const auto agg_str = json_str(field(expr, "agg"));
1250  if (agg_str == "APPROX_QUANTILE") {
1251  LOG(INFO) << "APPROX_QUANTILE is deprecated. Please use APPROX_PERCENTILE instead.";
1252  }
1253  const auto agg = to_agg_kind(agg_str);
1254  const auto distinct = json_bool(field(expr, "distinct"));
1255  const auto agg_ti = parse_type(field(expr, "type"));
1256  const auto operands = indices_from_json_array(field(expr, "operands"));
1257  if (operands.size() > 1 && (operands.size() != 2 || (agg != kAPPROX_COUNT_DISTINCT &&
1258  agg != kAPPROX_QUANTILE))) {
1259  throw QueryNotSupported("Multiple arguments for aggregates aren't supported");
1260  }
1261  return std::unique_ptr<const RexAgg>(new RexAgg(agg, distinct, agg_ti, operands));
1262 }
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
SQLAgg to_agg_kind(const std::string &agg_name)
#define LOG(tag)
Definition: Logger.h:217
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::vector< size_t > indices_from_json_array(const rapidjson::Value &json_idx_arr) noexcept

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<RexCase> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_case ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1201 of file RelAlgDagBuilder.cpp.

References CHECK, CHECK_GE, field(), and parse_scalar_expr().

Referenced by parse_scalar_expr().

1203  {
1204  const auto& operands = field(expr, "operands");
1205  CHECK(operands.IsArray());
1206  CHECK_GE(operands.Size(), unsigned(2));
1207  std::unique_ptr<const RexScalar> else_expr;
1208  std::vector<
1209  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
1210  expr_pair_list;
1211  for (auto operands_it = operands.Begin(); operands_it != operands.End();) {
1212  auto when_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
1213  if (operands_it == operands.End()) {
1214  else_expr = std::move(when_expr);
1215  break;
1216  }
1217  auto then_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
1218  expr_pair_list.emplace_back(std::move(when_expr), std::move(then_expr));
1219  }
1220  return std::unique_ptr<RexCase>(new RexCase(expr_pair_list, else_expr));
1221 }
#define CHECK_GE(x, y)
Definition: Logger.h:236
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:223
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<std::unique_ptr<const RexScalar> > anonymous_namespace{RelAlgDagBuilder.cpp}::parse_expr_array ( const rapidjson::Value &  arr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1022 of file RelAlgDagBuilder.cpp.

References parse_scalar_expr().

Referenced by parse_operator().

1025  {
1026  std::vector<std::unique_ptr<const RexScalar>> exprs;
1027  for (auto it = arr.Begin(); it != arr.End(); ++it) {
1028  exprs.emplace_back(parse_scalar_expr(*it, cat, root_dag_builder));
1029  }
1030  return exprs;
1031 }
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<RexLiteral> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_literal ( const rapidjson::Value &  expr)

Definition at line 917 of file RelAlgDagBuilder.cpp.

References CHECK, field(), json_bool(), json_double(), json_i64(), json_str(), kBIGINT, kBOOLEAN, kDATE, kDECIMAL, kDOUBLE, kINT, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kNULLT, kTEXT, kTIME, kTIMESTAMP, to_sql_type(), run_benchmark_import::type, and UNREACHABLE.

Referenced by details::RelAlgDispatcher::dispatchLogicalValues(), get_int_literal_field(), and parse_scalar_expr().

917  {
918  CHECK(expr.IsObject());
919  const auto& literal = field(expr, "literal");
920  const auto type = to_sql_type(json_str(field(expr, "type")));
921  const auto target_type = to_sql_type(json_str(field(expr, "target_type")));
922  const auto scale = json_i64(field(expr, "scale"));
923  const auto precision = json_i64(field(expr, "precision"));
924  const auto type_scale = json_i64(field(expr, "type_scale"));
925  const auto type_precision = json_i64(field(expr, "type_precision"));
926  if (literal.IsNull()) {
927  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
928  }
929  switch (type) {
930  case kINT:
931  case kBIGINT:
932  case kDECIMAL:
933  case kINTERVAL_DAY_TIME:
935  case kTIME:
936  case kTIMESTAMP:
937  case kDATE:
938  return std::unique_ptr<RexLiteral>(new RexLiteral(json_i64(literal),
939  type,
940  target_type,
941  scale,
942  precision,
943  type_scale,
944  type_precision));
945  case kDOUBLE: {
946  if (literal.IsDouble()) {
947  return std::unique_ptr<RexLiteral>(new RexLiteral(json_double(literal),
948  type,
949  target_type,
950  scale,
951  precision,
952  type_scale,
953  type_precision));
954  } else if (literal.IsInt64()) {
955  return std::make_unique<RexLiteral>(static_cast<double>(literal.GetInt64()),
956  type,
957  target_type,
958  scale,
959  precision,
960  type_scale,
961  type_precision);
962 
963  } else if (literal.IsUint64()) {
964  return std::make_unique<RexLiteral>(static_cast<double>(literal.GetUint64()),
965  type,
966  target_type,
967  scale,
968  precision,
969  type_scale,
970  type_precision);
971  }
972  UNREACHABLE() << "Unhandled type: " << literal.GetType();
973  }
974  case kTEXT:
975  return std::unique_ptr<RexLiteral>(new RexLiteral(json_str(literal),
976  type,
977  target_type,
978  scale,
979  precision,
980  type_scale,
981  type_precision));
982  case kBOOLEAN:
983  return std::unique_ptr<RexLiteral>(new RexLiteral(json_bool(literal),
984  type,
985  target_type,
986  scale,
987  precision,
988  type_scale,
989  type_precision));
990  case kNULLT:
991  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
992  default:
993  CHECK(false);
994  }
995  CHECK(false);
996  return nullptr;
997 }
SQLTypes to_sql_type(const std::string &type_name)
Definition: sqltypes.h:49
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
#define UNREACHABLE()
Definition: Logger.h:267
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
const double json_double(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:54
Definition: sqltypes.h:52
Definition: sqltypes.h:53
#define CHECK(condition)
Definition: Logger.h:223
Definition: sqltypes.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

NullSortedPosition anonymous_namespace{RelAlgDagBuilder.cpp}::parse_nulls_position ( const rapidjson::Value &  collation)

Definition at line 1102 of file RelAlgDagBuilder.cpp.

References field(), First, json_str(), and Last.

Referenced by details::RelAlgDispatcher::dispatchSort(), and parse_window_order_collation().

1102  {
1103  return json_str(field(collation, "nulls")) == std::string("FIRST")
1106 }
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<RexOperator> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_operator ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1155 of file RelAlgDagBuilder.cpp.

References CHECK, field(), json_bool(), json_str(), kFUNCTION, kIN, gpu_enabled::lower_bound(), parse_expr_array(), parse_subquery(), parse_type(), parse_window_bound(), parse_window_function_kind(), parse_window_order_collation(), parse_window_order_exprs(), to_sql_op(), and gpu_enabled::upper_bound().

Referenced by parse_scalar_expr().

1157  {
1158  const auto op_name = json_str(field(expr, "op"));
1159  const bool is_quantifier =
1160  op_name == std::string("PG_ANY") || op_name == std::string("PG_ALL");
1161  const auto op = is_quantifier ? kFUNCTION : to_sql_op(op_name);
1162  const auto& operators_json_arr = field(expr, "operands");
1163  CHECK(operators_json_arr.IsArray());
1164  auto operands = parse_expr_array(operators_json_arr, cat, root_dag_builder);
1165  const auto type_it = expr.FindMember("type");
1166  CHECK(type_it != expr.MemberEnd());
1167  auto ti = parse_type(type_it->value);
1168  if (op == kIN && expr.HasMember("subquery")) {
1169  auto subquery = parse_subquery(expr, cat, root_dag_builder);
1170  operands.emplace_back(std::move(subquery));
1171  }
1172  if (expr.FindMember("partition_keys") != expr.MemberEnd()) {
1173  const auto& partition_keys_arr = field(expr, "partition_keys");
1174  auto partition_keys = parse_expr_array(partition_keys_arr, cat, root_dag_builder);
1175  const auto& order_keys_arr = field(expr, "order_keys");
1176  auto order_keys = parse_window_order_exprs(order_keys_arr, cat, root_dag_builder);
1177  const auto collation =
1178  parse_window_order_collation(order_keys_arr, cat, root_dag_builder);
1179  const auto kind = parse_window_function_kind(op_name);
1180  const auto lower_bound =
1181  parse_window_bound(field(expr, "lower_bound"), cat, root_dag_builder);
1182  const auto upper_bound =
1183  parse_window_bound(field(expr, "upper_bound"), cat, root_dag_builder);
1184  bool is_rows = json_bool(field(expr, "is_rows"));
1185  ti.set_notnull(false);
1186  return std::make_unique<RexWindowFunctionOperator>(kind,
1187  operands,
1188  partition_keys,
1189  order_keys,
1190  collation,
1191  lower_bound,
1192  upper_bound,
1193  is_rows,
1194  ti);
1195  }
1196  return std::unique_ptr<RexOperator>(op == kFUNCTION
1197  ? new RexFunctionOperator(op_name, operands, ti)
1198  : new RexOperator(op, operands, ti));
1199 }
DEVICE auto upper_bound(ARGS &&...args)
Definition: gpu_enabled.h:123
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
RexWindowFunctionOperator::RexWindowBound parse_window_bound(const rapidjson::Value &window_bound_obj, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
std::vector< std::unique_ptr< const RexScalar > > parse_window_order_exprs(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
SqlWindowFunctionKind parse_window_function_kind(const std::string &name)
std::vector< std::unique_ptr< const RexScalar > > parse_expr_array(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::vector< SortField > parse_window_order_collation(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
SQLOps to_sql_op(const std::string &op_str)
DEVICE auto lower_bound(ARGS &&...args)
Definition: gpu_enabled.h:78
Definition: sqldefs.h:53
#define CHECK(condition)
Definition: Logger.h:223
std::unique_ptr< const RexSubQuery > parse_subquery(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr< const RexScalar > anonymous_namespace{RelAlgDagBuilder.cpp}::parse_scalar_expr ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1264 of file RelAlgDagBuilder.cpp.

References CHECK, field(), json_node_to_string(), json_str(), parse_abstract_input(), parse_case(), parse_literal(), parse_operator(), and parse_subquery().

Referenced by details::RelAlgDispatcher::dispatchFilter(), details::RelAlgDispatcher::dispatchJoin(), details::RelAlgDispatcher::dispatchProject(), details::RelAlgDispatcher::dispatchTableFunction(), parse_case(), parse_expr_array(), parse_window_bound(), and parse_window_order_exprs().

1266  {
1267  CHECK(expr.IsObject());
1268  if (expr.IsObject() && expr.HasMember("input")) {
1269  return std::unique_ptr<const RexScalar>(parse_abstract_input(expr));
1270  }
1271  if (expr.IsObject() && expr.HasMember("literal")) {
1272  return std::unique_ptr<const RexScalar>(parse_literal(expr));
1273  }
1274  if (expr.IsObject() && expr.HasMember("op")) {
1275  const auto op_str = json_str(field(expr, "op"));
1276  if (op_str == std::string("CASE")) {
1277  return std::unique_ptr<const RexScalar>(parse_case(expr, cat, root_dag_builder));
1278  }
1279  if (op_str == std::string("$SCALAR_QUERY")) {
1280  return std::unique_ptr<const RexScalar>(
1281  parse_subquery(expr, cat, root_dag_builder));
1282  }
1283  return std::unique_ptr<const RexScalar>(parse_operator(expr, cat, root_dag_builder));
1284  }
1285  throw QueryNotSupported("Expression node " + json_node_to_string(expr) +
1286  " not supported");
1287 }
std::unique_ptr< RexCase > parse_case(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
std::unique_ptr< RexOperator > parse_operator(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::unique_ptr< RexAbstractInput > parse_abstract_input(const rapidjson::Value &expr) noexcept
std::unique_ptr< RexLiteral > parse_literal(const rapidjson::Value &expr)
#define CHECK(condition)
Definition: Logger.h:223
std::unique_ptr< const RexSubQuery > parse_subquery(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
std::string json_node_to_string(const rapidjson::Value &node) noexcept

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

SortDirection anonymous_namespace{RelAlgDagBuilder.cpp}::parse_sort_direction ( const rapidjson::Value &  collation)

Definition at line 1096 of file RelAlgDagBuilder.cpp.

References Ascending, Descending, field(), and json_str().

Referenced by details::RelAlgDispatcher::dispatchSort(), and parse_window_order_collation().

1096  {
1097  return json_str(field(collation, "direction")) == std::string("DESCENDING")
1100 }
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<const RexSubQuery> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_subquery ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1141 of file RelAlgDagBuilder.cpp.

References CHECK, CHECK_GE, field(), RelAlgDagBuilder::getRootNodeShPtr(), and RelAlgDagBuilder::registerSubquery().

Referenced by parse_operator(), and parse_scalar_expr().

1143  {
1144  const auto& operands = field(expr, "operands");
1145  CHECK(operands.IsArray());
1146  CHECK_GE(operands.Size(), unsigned(0));
1147  const auto& subquery_ast = field(expr, "subquery");
1148 
1149  RelAlgDagBuilder subquery_dag(root_dag_builder, subquery_ast, cat, nullptr);
1150  auto subquery = std::make_shared<RexSubQuery>(subquery_dag.getRootNodeShPtr());
1151  root_dag_builder.registerSubquery(subquery);
1152  return subquery->deepCopy();
1153 }
#define CHECK_GE(x, y)
Definition: Logger.h:236
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

SQLTypeInfo anonymous_namespace{RelAlgDagBuilder.cpp}::parse_type ( const rapidjson::Value &  type_obj)

Definition at line 1003 of file RelAlgDagBuilder.cpp.

References CHECK, field(), json_bool(), json_i64(), json_node_to_string(), json_str(), SQLTypeInfo::set_precision(), SQLTypeInfo::set_scale(), to_sql_type(), and run_benchmark_import::type.

Referenced by details::RelAlgDispatcher::dispatchLogicalValues(), parse_aggregate_expr(), and parse_operator().

1003  {
1004  if (type_obj.IsArray()) {
1005  throw QueryNotSupported("Composite types are not currently supported.");
1006  }
1007  CHECK(type_obj.IsObject() && type_obj.MemberCount() >= 2)
1008  << json_node_to_string(type_obj);
1009  const auto type = to_sql_type(json_str(field(type_obj, "type")));
1010  const auto nullable = json_bool(field(type_obj, "nullable"));
1011  const auto precision_it = type_obj.FindMember("precision");
1012  const int precision =
1013  precision_it != type_obj.MemberEnd() ? json_i64(precision_it->value) : 0;
1014  const auto scale_it = type_obj.FindMember("scale");
1015  const int scale = scale_it != type_obj.MemberEnd() ? json_i64(scale_it->value) : 0;
1016  SQLTypeInfo ti(type, !nullable);
1017  ti.set_precision(precision);
1018  ti.set_scale(scale);
1019  return ti;
1020 }
SQLTypes to_sql_type(const std::string &type_name)
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
#define CHECK(condition)
Definition: Logger.h:223
std::string json_node_to_string(const rapidjson::Value &node) noexcept

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RexWindowFunctionOperator::RexWindowBound anonymous_namespace{RelAlgDagBuilder.cpp}::parse_window_bound ( const rapidjson::Value &  window_bound_obj,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1121 of file RelAlgDagBuilder.cpp.

References CHECK, field(), json_bool(), json_i64(), parse_scalar_expr(), and RexWindowFunctionOperator::RexWindowBound::unbounded.

Referenced by parse_operator().

1124  {
1125  CHECK(window_bound_obj.IsObject());
1127  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
1128  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
1129  window_bound.following = json_bool(field(window_bound_obj, "following"));
1130  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
1131  const auto& offset_field = field(window_bound_obj, "offset");
1132  if (offset_field.IsObject()) {
1133  window_bound.offset = parse_scalar_expr(offset_field, cat, root_dag_builder);
1134  } else {
1135  CHECK(offset_field.IsNull());
1136  }
1137  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
1138  return window_bound;
1139 }
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
#define CHECK(condition)
Definition: Logger.h:223
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

SqlWindowFunctionKind anonymous_namespace{RelAlgDagBuilder.cpp}::parse_window_function_kind ( const std::string &  name)

Definition at line 1033 of file RelAlgDagBuilder.cpp.

References AVG, COUNT, CUME_DIST, DENSE_RANK, FIRST_VALUE, LAG, LAST_VALUE, LEAD, MAX, MIN, NTILE, PERCENT_RANK, RANK, ROW_NUMBER, SUM, and SUM_INTERNAL.

Referenced by parse_operator().

1033  {
1034  if (name == "ROW_NUMBER") {
1036  }
1037  if (name == "RANK") {
1039  }
1040  if (name == "DENSE_RANK") {
1042  }
1043  if (name == "PERCENT_RANK") {
1045  }
1046  if (name == "CUME_DIST") {
1048  }
1049  if (name == "NTILE") {
1051  }
1052  if (name == "LAG") {
1054  }
1055  if (name == "LEAD") {
1057  }
1058  if (name == "FIRST_VALUE") {
1060  }
1061  if (name == "LAST_VALUE") {
1063  }
1064  if (name == "AVG") {
1066  }
1067  if (name == "MIN") {
1069  }
1070  if (name == "MAX") {
1072  }
1073  if (name == "SUM") {
1075  }
1076  if (name == "COUNT") {
1078  }
1079  if (name == "$SUM0") {
1081  }
1082  throw std::runtime_error("Unsupported window function: " + name);
1083 }
string name
Definition: setup.in.py:72

+ Here is the caller graph for this function:

std::vector<SortField> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_window_order_collation ( const rapidjson::Value &  arr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1108 of file RelAlgDagBuilder.cpp.

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

1110  {
1111  std::vector<SortField> collation;
1112  size_t field_idx = 0;
1113  for (auto it = arr.Begin(); it != arr.End(); ++it, ++field_idx) {
1114  const auto sort_dir = parse_sort_direction(*it);
1115  const auto null_pos = parse_nulls_position(*it);
1116  collation.emplace_back(field_idx, sort_dir, null_pos);
1117  }
1118  return collation;
1119 }
SortDirection parse_sort_direction(const rapidjson::Value &collation)
NullSortedPosition parse_nulls_position(const rapidjson::Value &collation)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<std::unique_ptr<const RexScalar> > anonymous_namespace{RelAlgDagBuilder.cpp}::parse_window_order_exprs ( const rapidjson::Value &  arr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 1085 of file RelAlgDagBuilder.cpp.

References field(), and parse_scalar_expr().

Referenced by parse_operator().

1088  {
1089  std::vector<std::unique_ptr<const RexScalar>> exprs;
1090  for (auto it = arr.Begin(); it != arr.End(); ++it) {
1091  exprs.emplace_back(parse_scalar_expr(field(*it, "field"), cat, root_dag_builder));
1092  }
1093  return exprs;
1094 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgDagBuilder.cpp}::propagate_hints_to_new_project ( std::shared_ptr< RelProject prev_node,
std::shared_ptr< RelProject new_node,
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &  query_hints 
)

Definition at line 2215 of file RelAlgDagBuilder.cpp.

References CHECK.

Referenced by add_window_function_pre_project(), and separate_window_function_expressions().

2219  {
2220  auto delivered_hints = prev_node->getDeliveredHints();
2221  bool needs_propagate_hints = !delivered_hints->empty();
2222  if (needs_propagate_hints) {
2223  for (auto& kv : *delivered_hints) {
2224  new_node->addHint(kv.second);
2225  }
2226  auto prev_it = query_hints.find(prev_node->toHash());
2227  // query hint for the prev projection node should be registered
2228  CHECK(prev_it != query_hints.end());
2229  auto prev_hint_it = prev_it->second.find(prev_node->getId());
2230  CHECK(prev_hint_it != prev_it->second.end());
2231  std::unordered_map<unsigned, RegisteredQueryHint> hint_map;
2232  hint_map.emplace(new_node->getId(), prev_hint_it->second);
2233  query_hints.emplace(new_node->toHash(), hint_map);
2234  }
2235 }
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the caller graph for this function:

std::vector<const Rex*> anonymous_namespace{RelAlgDagBuilder.cpp}::remapTargetPointers ( std::vector< std::unique_ptr< const RexAgg >> const &  agg_exprs_new,
std::vector< std::unique_ptr< const RexScalar >> const &  scalar_sources_new,
std::vector< std::unique_ptr< const RexAgg >> const &  agg_exprs_old,
std::vector< std::unique_ptr< const RexScalar >> const &  scalar_sources_old,
std::vector< const Rex * > const &  target_exprs_old 
)

Definition at line 637 of file RelAlgDagBuilder.cpp.

References CHECK.

642  {
643  std::vector<const Rex*> target_exprs(target_exprs_old);
644  std::unordered_map<const Rex*, const Rex*> old_to_new_target(target_exprs.size());
645  for (size_t i = 0; i < agg_exprs_new.size(); ++i) {
646  old_to_new_target.emplace(agg_exprs_old[i].get(), agg_exprs_new[i].get());
647  }
648  for (size_t i = 0; i < scalar_sources_new.size(); ++i) {
649  old_to_new_target.emplace(scalar_sources_old[i].get(), scalar_sources_new[i].get());
650  }
651  for (auto& target : target_exprs) {
652  auto target_it = old_to_new_target.find(target);
653  CHECK(target_it != old_to_new_target.end());
654  target = target_it->second;
655  }
656  return target_exprs;
657 }
#define CHECK(condition)
Definition: Logger.h:223
void anonymous_namespace{RelAlgDagBuilder.cpp}::separate_window_function_expressions ( std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &  query_hints 
)

Detect the presence of window function operators nested inside expressions. Separate the window function operator from the expression, computing the expression as a subsequent step by pushing the expression to a new project node, and replacing the nested window function operator with a RexInput. Also move all input nodes to the newly created project node. Overall, we have the following query plan: from: Window_Project -> Child to: Window_Project -> New_Project -> Child In pseudocode: for each rex in project list: detect nested window function expression if nested window function expression: push the nested window function expression to the new project P create a new RexInput r_i which references the w_i in P and put it to M (M: a map between nested window function expression w_i and r_i) else push it down to the new project P create a new RexInput r_i which references the rex in P and put it to M for each rex in the project list: visit the rex and find a chance to replace it (or its operand) by using M

Definition at line 2259 of file RelAlgDagBuilder.cpp.

References CHECK, anonymous_namespace{RelAlgDagBuilder.cpp}::anonymous_namespace{RelAlgDagBuilder.cpp}::is_window_function_operator(), propagate_hints_to_new_project(), and RexVisitorBase< T >::visit().

Referenced by RelAlgDagBuilder::build().

2262  {
2263  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
2264  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
2265  const auto node = *node_itr;
2266  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
2267  if (!window_func_project_node) {
2268  continue;
2269  }
2270 
2271  const auto prev_node_itr = std::prev(node_itr);
2272  const auto prev_node = *prev_node_itr;
2273  CHECK(prev_node);
2274 
2275  // map scalar expression index in the project node to window function ptr
2276  std::unordered_map<size_t, const RexScalar*> collected_window_func;
2277  WindowFunctionCollector collector(collected_window_func);
2278  // Iterate the target exprs of the project node and check for window function
2279  // expressions. If an embedded expression exists, collect it
2280  for (size_t i = 0; i < window_func_project_node->size(); i++) {
2281  const auto scalar_rex = window_func_project_node->getProjectAt(i);
2282  if (is_window_function_operator(scalar_rex)) {
2283  // top level window function exprs are fine
2284  continue;
2285  }
2286  collector.visit(scalar_rex);
2287  }
2288 
2289  if (!collected_window_func.empty()) {
2290  // we have a nested window function expression
2291  std::unordered_set<size_t> collected_window_func_hash;
2292  // the current window function needs a set of new rex input which references
2293  // expressions in the newly introduced projection node
2294  std::vector<std::unique_ptr<const RexScalar>> new_rex_input_for_window_func;
2295  // a target projection expression of the newly created projection node
2296  std::vector<std::unique_ptr<const RexScalar>> new_scalar_expr_for_window_project;
2297  // a map between nested window function (hash val) and
2298  // its rex index stored in the `new_rex_input_for_window_func`
2299  std::unordered_map<size_t, size_t> window_func_to_new_rex_input_idx_map;
2300  // a map between RexInput of the current window function projection node (hash val)
2301  // and its corresponding new RexInput which is pushed down to the new projection
2302  // node
2303  std::unordered_map<size_t, std::unique_ptr<const RexInput>>
2304  new_rex_input_from_child_node;
2305  RexDeepCopyVisitor copier;
2306 
2307  std::vector<std::unique_ptr<const RexScalar>> dummy_scalar_exprs;
2308  std::vector<std::string> dummy_fields;
2309  std::vector<std::string> new_project_field_names;
2310  // create a new project node, it will contain window function expressions
2311  auto new_project =
2312  std::make_shared<RelProject>(dummy_scalar_exprs, dummy_fields, prev_node);
2313  // insert this new project node between the current window project node and its
2314  // child node
2315  node_list.insert(node_itr, new_project);
2316 
2317  // retrieve various information to replace expressions in the current window
2318  // function project node w/ considering scalar expressions in the new project node
2319  std::for_each(collected_window_func.begin(),
2320  collected_window_func.end(),
2321  [&new_project_field_names,
2322  &collected_window_func_hash,
2323  &new_rex_input_for_window_func,
2324  &new_scalar_expr_for_window_project,
2325  &copier,
2326  &new_project,
2327  &window_func_to_new_rex_input_idx_map](const auto& kv) {
2328  // compute window function expr's hash, and create a new rex_input
2329  // for it
2330  collected_window_func_hash.insert(kv.first);
2331 
2332  // map an old expression in the window function project node
2333  // to an index of the corresponding new RexInput
2334  const auto rex_idx = new_rex_input_for_window_func.size();
2335  window_func_to_new_rex_input_idx_map.emplace(kv.first, rex_idx);
2336 
2337  // create a new RexInput and make it as one of new expression of the
2338  // newly created project node
2339  new_rex_input_for_window_func.emplace_back(
2340  std::make_unique<const RexInput>(new_project.get(), rex_idx));
2341  new_scalar_expr_for_window_project.push_back(
2342  std::move(copier.visit(kv.second)));
2343  new_project_field_names.emplace_back("");
2344  });
2345  new_project->setExpressions(new_scalar_expr_for_window_project);
2346  new_project->setFields(std::move(new_project_field_names));
2347 
2348  auto window_func_scalar_exprs =
2349  window_func_project_node->getExpressionsAndRelease();
2350  RexWindowFuncReplacementVisitor replacer(collected_window_func_hash,
2351  new_rex_input_for_window_func,
2352  window_func_to_new_rex_input_idx_map,
2353  new_project.get(),
2354  new_rex_input_from_child_node);
2355  size_t rex_idx = 0;
2356  for (auto& scalar_expr : window_func_scalar_exprs) {
2357  // try to replace the old expressions in the window function project node
2358  // with expressions of the newly created project node
2359  auto new_parent_rex = replacer.visit(scalar_expr.get());
2360  window_func_scalar_exprs[rex_idx] = std::move(new_parent_rex);
2361  rex_idx++;
2362  }
2363  // Update the previous window project node
2364  window_func_project_node->setExpressions(window_func_scalar_exprs);
2365  window_func_project_node->replaceInput(prev_node, new_project);
2366  propagate_hints_to_new_project(window_func_project_node, new_project, query_hints);
2367  }
2368  }
2369  nodes.assign(node_list.begin(), node_list.end());
2370 }
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
void propagate_hints_to_new_project(std::shared_ptr< RelProject > prev_node, std::shared_ptr< RelProject > new_node, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<std::string> anonymous_namespace{RelAlgDagBuilder.cpp}::strings_from_json_array ( const rapidjson::Value &  json_str_arr)
noexcept

Definition at line 1223 of file RelAlgDagBuilder.cpp.

References CHECK.

Referenced by details::RelAlgDispatcher::dispatchAggregate(), details::RelAlgDispatcher::dispatchProject(), getFieldNamesFromScanNode(), and details::RelAlgDispatcher::getRelAlgInputs().

1224  {
1225  CHECK(json_str_arr.IsArray());
1226  std::vector<std::string> fields;
1227  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
1228  ++json_str_arr_it) {
1229  CHECK(json_str_arr_it->IsString());
1230  fields.emplace_back(json_str_arr_it->GetString());
1231  }
1232  return fields;
1233 }
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the caller graph for this function:

JoinType anonymous_namespace{RelAlgDagBuilder.cpp}::to_join_type ( const std::string &  join_type_name)

Definition at line 1289 of file RelAlgDagBuilder.cpp.

References ANTI, INNER, LEFT, and SEMI.

Referenced by details::RelAlgDispatcher::dispatchJoin().

1289  {
1290  if (join_type_name == "inner") {
1291  return JoinType::INNER;
1292  }
1293  if (join_type_name == "left") {
1294  return JoinType::LEFT;
1295  }
1296  if (join_type_name == "semi") {
1297  return JoinType::SEMI;
1298  }
1299  if (join_type_name == "anti") {
1300  return JoinType::ANTI;
1301  }
1302  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
1303 }

+ Here is the caller graph for this function:

Variable Documentation

const unsigned anonymous_namespace{RelAlgDagBuilder.cpp}::FIRST_RA_NODE_ID = 1

Definition at line 41 of file RelAlgDagBuilder.cpp.

Referenced by RelAlgNode::resetRelAlgFirstId().