OmniSciDB  0264ff685a
anonymous_namespace{RelAlgDagBuilder.cpp} Namespace Reference

Namespaces

 anonymous_namespace{RelAlgDagBuilder.cpp}
 

Classes

class  RANodeIterator
 
class  RexInputBackpropagationVisitor
 
class  RexInputCollector
 
class  RexRebindInputsVisitor
 
class  RexRebindReindexInputsVisitor
 
class  RexWindowFuncReplacementVisitor
 
class  WindowFunctionDetectionVisitor
 

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 RexSubQueryparse_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 RexOperatordisambiguate_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 handleQueryHint (const std::vector< std::shared_ptr< RelAlgNode >> &nodes, RelAlgDagBuilder *dag_builder) noexcept
 
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) noexcept
 
void coalesce_nodes (std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< const RelAlgNode *> &left_deep_joins)
 
void separate_window_function_expressions (std::vector< std::shared_ptr< RelAlgNode >> &nodes)
 
void add_window_function_pre_project (std::vector< std::shared_ptr< RelAlgNode >> &nodes)
 
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

◆ RexInputSet

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

Definition at line 2001 of file RelAlgDagBuilder.cpp.

Function Documentation

◆ add_window_function_pre_project()

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

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). 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 2025 of file RelAlgDagBuilder.cpp.

References CHECK, CHECK_EQ, gpu_enabled::sort(), and RexVisitorBase< T >::visit().

Referenced by RelAlgDagBuilder::build().

2025  {
2026  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
2027 
2028  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
2029  const auto node = *node_itr;
2030  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
2031  if (!window_func_project_node) {
2032  continue;
2033  }
2034  if (!window_func_project_node->hasWindowFunctionExpr()) {
2035  // the first projection node in the query plan does not have a window function
2036  // expression -- this step is not requierd.
2037  return;
2038  }
2039 
2040  const auto prev_node_itr = std::prev(node_itr);
2041  const auto prev_node = *prev_node_itr;
2042  CHECK(prev_node);
2043 
2044  RexInputSet inputs;
2045  RexInputCollector input_collector;
2046  for (size_t i = 0; i < window_func_project_node->size(); i++) {
2047  auto new_inputs = input_collector.visit(window_func_project_node->getProjectAt(i));
2048  inputs.insert(new_inputs.begin(), new_inputs.end());
2049  }
2050 
2051  // Note: Technically not required since we are mapping old inputs to new input
2052  // indices, but makes the re-mapping of inputs easier to follow.
2053  std::vector<RexInput> sorted_inputs(inputs.begin(), inputs.end());
2054  std::sort(sorted_inputs.begin(),
2055  sorted_inputs.end(),
2056  [](const auto& a, const auto& b) { return a.getIndex() < b.getIndex(); });
2057 
2058  std::vector<std::unique_ptr<const RexScalar>> scalar_exprs;
2059  std::vector<std::string> fields;
2060  std::unordered_map<unsigned, unsigned> old_index_to_new_index;
2061  for (auto& input : sorted_inputs) {
2062  CHECK_EQ(input.getSourceNode(), prev_node.get());
2063  CHECK(old_index_to_new_index
2064  .insert(std::make_pair(input.getIndex(), scalar_exprs.size()))
2065  .second);
2066  scalar_exprs.emplace_back(input.deepCopy());
2067  fields.emplace_back("");
2068  }
2069 
2070  auto new_project = std::make_shared<RelProject>(scalar_exprs, fields, prev_node);
2071  node_list.insert(node_itr, new_project);
2072  window_func_project_node->replaceInput(
2073  prev_node, new_project, old_index_to_new_index);
2074 
2075  break;
2076  }
2077 
2078  nodes.assign(node_list.begin(), node_list.end());
2079 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
DEVICE void sort(ARGS &&... args)
Definition: gpu_enabled.h:105
std::unordered_set< RexInput > RexInputSet
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bind_inputs()

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

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

1159  {
1160  for (auto ra_node : nodes) {
1161  const auto filter_node = std::dynamic_pointer_cast<RelFilter>(ra_node);
1162  if (filter_node) {
1163  CHECK_EQ(size_t(1), filter_node->inputCount());
1164  auto disambiguated_condition = disambiguate_rex(
1165  filter_node->getCondition(), get_node_output(filter_node->getInput(0)));
1166  filter_node->setCondition(disambiguated_condition);
1167  continue;
1168  }
1169  const auto join_node = std::dynamic_pointer_cast<RelJoin>(ra_node);
1170  if (join_node) {
1171  CHECK_EQ(size_t(2), join_node->inputCount());
1172  auto disambiguated_condition =
1173  disambiguate_rex(join_node->getCondition(), get_node_output(join_node.get()));
1174  join_node->setCondition(disambiguated_condition);
1175  continue;
1176  }
1177  const auto project_node = std::dynamic_pointer_cast<RelProject>(ra_node);
1178  if (project_node) {
1179  bind_project_to_input(project_node.get(),
1180  get_node_output(project_node->getInput(0)));
1181  continue;
1182  }
1183  const auto table_func_node = std::dynamic_pointer_cast<RelTableFunction>(ra_node);
1184  if (table_func_node) {
1185  /*
1186  Collect all inputs from table function input (non-literal)
1187  arguments.
1188  */
1189  RANodeOutput input;
1190  input.reserve(table_func_node->inputCount());
1191  for (size_t i = 0; i < table_func_node->inputCount(); i++) {
1192  auto node_output = get_node_output(table_func_node->getInput(i));
1193  input.insert(input.end(), node_output.begin(), node_output.end());
1194  }
1195  bind_table_func_to_input(table_func_node.get(), input);
1196  }
1197  }
1198 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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:

◆ bind_project_to_input()

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

Definition at line 1131 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs(), and create_compound().

1131  {
1132  CHECK_EQ(size_t(1), project_node->inputCount());
1133  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1134  for (size_t i = 0; i < project_node->size(); ++i) {
1135  const auto projected_expr = project_node->getProjectAt(i);
1136  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
1137  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
1138  } else {
1139  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
1140  }
1141  }
1142  project_node->setExpressions(disambiguated_exprs);
1143 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
size_t size() const override
const RexScalar * getProjectAt(const size_t idx) const
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
const RexScalar * getProjectAtAndRelease(const size_t idx) const
const size_t inputCount() const
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bind_table_func_to_input()

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

Definition at line 1145 of file RelAlgDagBuilder.cpp.

References disambiguate_rex().

Referenced by bind_inputs().

1146  {
1147  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1148  for (size_t i = 0; i < table_func_node->getTableFuncInputsSize(); ++i) {
1149  const auto target_expr = table_func_node->getTableFuncInputAt(i);
1150  if (dynamic_cast<const RexSubQuery*>(target_expr)) {
1151  disambiguated_exprs.emplace_back(table_func_node->getTableFuncInputAtAndRelease(i));
1152  } else {
1153  disambiguated_exprs.emplace_back(disambiguate_rex(target_expr, input));
1154  }
1155  }
1156  table_func_node->setTableFuncInputs(disambiguated_exprs);
1157 }
const RexScalar * getTableFuncInputAt(const size_t idx) const
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
size_t getTableFuncInputsSize() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_empty_inputs_field()

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

Definition at line 2095 of file RelAlgDagBuilder.cpp.

References CHECK, and field().

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

2095  {
2096  const auto& inputs_json = field(node, "inputs");
2097  CHECK(inputs_json.IsArray() && !inputs_json.Size());
2098 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ coalesce_nodes()

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

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

1607  {
1608  enum class CoalesceState { Initial, Filter, FirstProject, Aggregate };
1609  std::vector<size_t> crt_pattern;
1610  CoalesceState crt_state{CoalesceState::Initial};
1611 
1612  auto reset_state = [&crt_pattern, &crt_state]() {
1613  crt_state = CoalesceState::Initial;
1614  decltype(crt_pattern)().swap(crt_pattern);
1615  };
1616 
1617  for (RANodeIterator nodeIt(nodes); !nodeIt.allVisited();) {
1618  const auto ra_node = nodeIt != nodes.end() ? *nodeIt : nullptr;
1619  switch (crt_state) {
1620  case CoalesceState::Initial: {
1621  if (std::dynamic_pointer_cast<const RelFilter>(ra_node) &&
1622  std::find(left_deep_joins.begin(), left_deep_joins.end(), ra_node.get()) ==
1623  left_deep_joins.end()) {
1624  crt_pattern.push_back(size_t(nodeIt));
1625  crt_state = CoalesceState::Filter;
1626  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1627  } else if (std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1628  crt_pattern.push_back(size_t(nodeIt));
1629  crt_state = CoalesceState::FirstProject;
1630  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1631  } else {
1632  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1633  }
1634  break;
1635  }
1636  case CoalesceState::Filter: {
1637  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1638  if (project_node->hasWindowFunctionExpr()) {
1639  reset_state();
1640  break;
1641  }
1642  crt_pattern.push_back(size_t(nodeIt));
1643  crt_state = CoalesceState::FirstProject;
1644  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1645  } else {
1646  reset_state();
1647  }
1648  break;
1649  }
1650  case CoalesceState::FirstProject: {
1651  if (std::dynamic_pointer_cast<const RelAggregate>(ra_node)) {
1652  crt_pattern.push_back(size_t(nodeIt));
1653  crt_state = CoalesceState::Aggregate;
1654  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1655  } else {
1656  if (crt_pattern.size() >= 2) {
1657  create_compound(nodes, crt_pattern);
1658  }
1659  reset_state();
1660  }
1661  break;
1662  }
1663  case CoalesceState::Aggregate: {
1664  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1665  // TODO(adb): overloading the simple project terminology again here
1666  bool is_simple_project{true};
1667  for (size_t i = 0; i < project_node->size(); i++) {
1668  const auto scalar_rex = project_node->getProjectAt(i);
1669  // If the top level scalar rex is an input node, we can bypass the visitor
1670  if (auto input_rex = dynamic_cast<const RexInput*>(scalar_rex)) {
1672  input_rex->getSourceNode(), input_rex->getIndex(), true)) {
1673  is_simple_project = false;
1674  break;
1675  }
1676  continue;
1677  }
1678  CoalesceSecondaryProjectVisitor visitor;
1679  if (!visitor.visit(project_node->getProjectAt(i))) {
1680  is_simple_project = false;
1681  break;
1682  }
1683  }
1684  if (is_simple_project) {
1685  crt_pattern.push_back(size_t(nodeIt));
1686  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1687  }
1688  }
1689  CHECK_GE(crt_pattern.size(), size_t(2));
1690  create_compound(nodes, crt_pattern);
1691  reset_state();
1692  break;
1693  }
1694  default:
1695  CHECK(false);
1696  }
1697  }
1698  if (crt_state == CoalesceState::FirstProject || crt_state == CoalesceState::Aggregate) {
1699  if (crt_pattern.size() >= 2) {
1700  create_compound(nodes, crt_pattern);
1701  }
1702  CHECK(!crt_pattern.empty());
1703  }
1704 }
#define CHECK_GE(x, y)
Definition: Logger.h:210
#define CHECK(condition)
Definition: Logger.h:197
void create_compound(std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< size_t > &pattern) noexcept
DEVICE void swap(ARGS &&... args)
Definition: gpu_enabled.h:114
bool input_can_be_coalesced(const RelAlgNode *parent_node, const size_t index, const bool first_rex_is_input)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ copyAggExprs()

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 397 of file RelAlgDagBuilder.cpp.

398  {
399  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_copy;
400  agg_exprs_copy.reserve(agg_exprs.size());
401  for (auto const& agg_expr : agg_exprs) {
402  agg_exprs_copy.push_back(agg_expr->deepCopy());
403  }
404  return agg_exprs_copy;
405 }

◆ copyRexScalars()

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 407 of file RelAlgDagBuilder.cpp.

References RexVisitorBase< T >::visit().

408  {
409  std::vector<std::unique_ptr<const RexScalar>> scalar_sources_copy;
410  scalar_sources_copy.reserve(scalar_sources.size());
411  RexDeepCopyVisitor copier;
412  for (auto const& scalar_source : scalar_sources) {
413  scalar_sources_copy.push_back(copier.visit(scalar_source.get()));
414  }
415  return scalar_sources_copy;
416 }
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
+ Here is the call graph for this function:

◆ create_compound()

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

Definition at line 1305 of file RelAlgDagBuilder.cpp.

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

Referenced by coalesce_nodes().

1306  {
1307  CHECK_GE(pattern.size(), size_t(2));
1308  CHECK_LE(pattern.size(), size_t(4));
1309 
1310  std::unique_ptr<const RexScalar> filter_rex;
1311  std::vector<std::unique_ptr<const RexScalar>> scalar_sources;
1312  size_t groupby_count{0};
1313  std::vector<std::string> fields;
1314  std::vector<const RexAgg*> agg_exprs;
1315  std::vector<const Rex*> target_exprs;
1316  bool first_project{true};
1317  bool is_agg{false};
1318  RelAlgNode* last_node{nullptr};
1319 
1320  std::shared_ptr<ModifyManipulationTarget> manipulation_target;
1321 
1322  for (const auto node_idx : pattern) {
1323  const auto ra_node = nodes[node_idx];
1324  const auto ra_filter = std::dynamic_pointer_cast<RelFilter>(ra_node);
1325  if (ra_filter) {
1326  CHECK(!filter_rex);
1327  filter_rex.reset(ra_filter->getAndReleaseCondition());
1328  CHECK(filter_rex);
1329  last_node = ra_node.get();
1330  continue;
1331  }
1332  const auto ra_project = std::dynamic_pointer_cast<RelProject>(ra_node);
1333  if (ra_project) {
1334  fields = ra_project->getFields();
1335  manipulation_target = ra_project;
1336 
1337  if (first_project) {
1338  CHECK_EQ(size_t(1), ra_project->inputCount());
1339  // Rebind the input of the project to the input of the filter itself
1340  // since we know that we'll evaluate the filter on the fly, with no
1341  // intermediate buffer.
1342  const auto filter_input = dynamic_cast<const RelFilter*>(ra_project->getInput(0));
1343  if (filter_input) {
1344  CHECK_EQ(size_t(1), filter_input->inputCount());
1345  bind_project_to_input(ra_project.get(),
1346  get_node_output(filter_input->getInput(0)));
1347  }
1348  scalar_sources = ra_project->getExpressionsAndRelease();
1349  for (const auto& scalar_expr : scalar_sources) {
1350  target_exprs.push_back(scalar_expr.get());
1351  }
1352  first_project = false;
1353  } else {
1354  if (ra_project->isSimple()) {
1355  target_exprs = reproject_targets(ra_project.get(), target_exprs);
1356  } else {
1357  // TODO(adb): This is essentially a more general case of simple project, we
1358  // could likely merge the two
1359  std::vector<const Rex*> result;
1360  RexInputReplacementVisitor visitor(last_node, scalar_sources);
1361  for (size_t i = 0; i < ra_project->size(); ++i) {
1362  const auto rex = ra_project->getProjectAt(i);
1363  if (auto rex_input = dynamic_cast<const RexInput*>(rex)) {
1364  const auto index = rex_input->getIndex();
1365  CHECK_LT(index, target_exprs.size());
1366  result.push_back(target_exprs[index]);
1367  } else {
1368  scalar_sources.push_back(visitor.visit(rex));
1369  result.push_back(scalar_sources.back().get());
1370  }
1371  }
1372  target_exprs = result;
1373  }
1374  }
1375  last_node = ra_node.get();
1376  continue;
1377  }
1378  const auto ra_aggregate = std::dynamic_pointer_cast<RelAggregate>(ra_node);
1379  if (ra_aggregate) {
1380  is_agg = true;
1381  fields = ra_aggregate->getFields();
1382  agg_exprs = ra_aggregate->getAggregatesAndRelease();
1383  groupby_count = ra_aggregate->getGroupByCount();
1384  decltype(target_exprs){}.swap(target_exprs);
1385  CHECK_LE(groupby_count, scalar_sources.size());
1386  for (size_t group_idx = 0; group_idx < groupby_count; ++group_idx) {
1387  const auto rex_ref = new RexRef(group_idx + 1);
1388  target_exprs.push_back(rex_ref);
1389  scalar_sources.emplace_back(rex_ref);
1390  }
1391  for (const auto rex_agg : agg_exprs) {
1392  target_exprs.push_back(rex_agg);
1393  }
1394  last_node = ra_node.get();
1395  continue;
1396  }
1397  }
1398 
1399  auto compound_node =
1400  std::make_shared<RelCompound>(filter_rex,
1401  target_exprs,
1402  groupby_count,
1403  agg_exprs,
1404  fields,
1405  scalar_sources,
1406  is_agg,
1407  manipulation_target->isUpdateViaSelect(),
1408  manipulation_target->isDeleteViaSelect(),
1409  manipulation_target->isVarlenUpdateRequired(),
1410  manipulation_target->getModifiedTableDescriptor(),
1411  manipulation_target->getTargetColumns());
1412  auto old_node = nodes[pattern.back()];
1413  nodes[pattern.back()] = compound_node;
1414  auto first_node = nodes[pattern.front()];
1415  CHECK_EQ(size_t(1), first_node->inputCount());
1416  compound_node->addManagedInput(first_node->getAndOwnInput(0));
1417  for (size_t i = 0; i < pattern.size() - 1; ++i) {
1418  nodes[pattern[i]].reset();
1419  }
1420  for (auto node : nodes) {
1421  if (!node) {
1422  continue;
1423  }
1424  node->replaceInput(old_node, compound_node);
1425  }
1426 }
bool is_agg(const Analyzer::Expr *expr)
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define CHECK_GE(x, y)
Definition: Logger.h:210
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
std::vector< const Rex * > reproject_targets(const RelProject *simple_project, const std::vector< const Rex *> &target_exprs) noexcept
#define CHECK_LT(x, y)
Definition: Logger.h:207
#define CHECK_LE(x, y)
Definition: Logger.h:208
#define CHECK(condition)
Definition: Logger.h:197
RANodeOutput get_node_output(const RelAlgNode *ra_node)
const std::vector< std::string > & getFields() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ disambiguate_case()

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

Definition at line 1089 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

1090  {
1091  std::vector<
1092  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
1093  disambiguated_expr_pair_list;
1094  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
1095  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
1096  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
1097  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
1098  std::move(disambiguated_then));
1099  }
1100  std::unique_ptr<const RexScalar> disambiguated_else{
1101  disambiguate_rex(rex_case->getElse(), ra_output)};
1102  return std::unique_ptr<const RexCase>(
1103  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
1104 }
size_t branchCount() const
const RexScalar * getWhen(const size_t idx) const
const RexScalar * getThen(const size_t idx) const
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
const RexScalar * getElse() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ disambiguate_operator()

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

Definition at line 1054 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

1056  {
1057  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
1058  for (size_t i = 0; i < rex_operator->size(); ++i) {
1059  auto operand = rex_operator->getOperand(i);
1060  if (dynamic_cast<const RexSubQuery*>(operand)) {
1061  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
1062  } else {
1063  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
1064  }
1065  }
1066  const auto rex_window_function_operator =
1067  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
1068  if (rex_window_function_operator) {
1069  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
1070  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
1071  for (const auto& partition_key : partition_keys) {
1072  disambiguated_partition_keys.emplace_back(
1073  disambiguate_rex(partition_key.get(), ra_output));
1074  }
1075  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
1076  const auto& order_keys = rex_window_function_operator->getOrderKeys();
1077  for (const auto& order_key : order_keys) {
1078  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
1079  }
1080  return rex_window_function_operator->disambiguatedOperands(
1081  disambiguated_operands,
1082  disambiguated_partition_keys,
1083  disambiguated_order_keys,
1084  rex_window_function_operator->getCollation());
1085  }
1086  return rex_operator->getDisambiguated(disambiguated_operands);
1087 }
const ConstRexScalarPtrVector & getPartitionKeys() const
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
virtual std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const
const RexScalar * getOperand(const size_t idx) const
const RexScalar * getOperandAndRelease(const size_t idx) const
size_t size() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ disambiguate_rex()

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

Definition at line 1110 of file RelAlgDagBuilder.cpp.

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

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

1111  {
1112  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
1113  if (rex_abstract_input) {
1114  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
1115  return std::unique_ptr<const RexInput>(
1116  new RexInput(ra_output[rex_abstract_input->getIndex()]));
1117  }
1118  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
1119  if (rex_operator) {
1120  return disambiguate_operator(rex_operator, ra_output);
1121  }
1122  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
1123  if (rex_case) {
1124  return disambiguate_case(rex_case, ra_output);
1125  }
1126  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
1127  CHECK(rex_literal);
1128  return std::unique_ptr<const RexLiteral>(new RexLiteral(*rex_literal));
1129 }
#define CHECK_LT(x, y)
Definition: Logger.h:207
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)
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_equiv_cols()

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 509 of file RelAlgDagBuilder.cpp.

References CHECK, and CHECK_EQ.

Referenced by RelSort::hasEquivCollationOf().

510  {
511  std::set<std::pair<const RelAlgNode*, int>> work_set;
512  auto walker = node;
513  auto curr_col = which_col;
514  while (true) {
515  work_set.insert(std::make_pair(walker, curr_col));
516  if (dynamic_cast<const RelScan*>(walker) || dynamic_cast<const RelJoin*>(walker)) {
517  break;
518  }
519  CHECK_EQ(size_t(1), walker->inputCount());
520  auto only_source = walker->getInput(0);
521  if (auto project = dynamic_cast<const RelProject*>(walker)) {
522  if (auto input = dynamic_cast<const RexInput*>(project->getProjectAt(curr_col))) {
523  const auto join_source = dynamic_cast<const RelJoin*>(only_source);
524  if (join_source) {
525  CHECK_EQ(size_t(2), join_source->inputCount());
526  auto lhs = join_source->getInput(0);
527  CHECK((input->getIndex() < lhs->size() && lhs == input->getSourceNode()) ||
528  join_source->getInput(1) == input->getSourceNode());
529  } else {
530  CHECK_EQ(input->getSourceNode(), only_source);
531  }
532  curr_col = input->getIndex();
533  } else {
534  break;
535  }
536  } else if (auto aggregate = dynamic_cast<const RelAggregate*>(walker)) {
537  if (curr_col >= aggregate->getGroupByCount()) {
538  break;
539  }
540  }
541  walker = only_source;
542  }
543  return work_set;
544 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ get_int_literal_field()

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 2081 of file RelAlgDagBuilder.cpp.

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

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

2083  {
2084  const auto it = obj.FindMember(field);
2085  if (it == obj.MemberEnd()) {
2086  return default_val;
2087  }
2088  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
2089  CHECK_EQ(kDECIMAL, lit->getType());
2090  CHECK_EQ(unsigned(0), lit->getScale());
2091  CHECK_EQ(unsigned(0), lit->getTypeScale());
2092  return lit->getVal<int64_t>();
2093 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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:

◆ getFieldNamesFromScanNode()

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

Definition at line 2110 of file RelAlgDagBuilder.cpp.

References field(), and strings_from_json_array().

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

2110  {
2111  const auto& fields_json = field(scan_ra, "fieldNames");
2112  return strings_from_json_array(fields_json);
2113 }
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:

◆ getTableFromScanNode()

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

Definition at line 2100 of file RelAlgDagBuilder.cpp.

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

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

2101  {
2102  const auto& table_json = field(scan_ra, "table");
2103  CHECK(table_json.IsArray());
2104  CHECK_EQ(unsigned(2), table_json.Size());
2105  const auto td = cat.getMetadataForTable(table_json[1].GetString());
2106  CHECK(td);
2107  return td;
2108 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handleQueryHint()

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

Definition at line 1200 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

1201  {
1202  Hints* hint_delivered = nullptr;
1203  for (auto node : nodes) {
1204  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1205  if (agg_node) {
1206  if (agg_node->hasDeliveredHint()) {
1207  hint_delivered = agg_node->getDeliveredHints();
1208  break;
1209  }
1210  }
1211  const auto project_node = std::dynamic_pointer_cast<RelProject>(node);
1212  if (project_node) {
1213  if (project_node->hasDeliveredHint()) {
1214  hint_delivered = project_node->getDeliveredHints();
1215  break;
1216  }
1217  }
1218  const auto scan_node = std::dynamic_pointer_cast<RelScan>(node);
1219  if (scan_node) {
1220  if (scan_node->hasDeliveredHint()) {
1221  hint_delivered = scan_node->getDeliveredHints();
1222  break;
1223  }
1224  }
1225  const auto join_node = std::dynamic_pointer_cast<RelJoin>(node);
1226  if (join_node) {
1227  if (join_node->hasDeliveredHint()) {
1228  hint_delivered = join_node->getDeliveredHints();
1229  break;
1230  }
1231  }
1232  const auto compound_node = std::dynamic_pointer_cast<RelCompound>(node);
1233  if (compound_node) {
1234  if (compound_node->hasDeliveredHint()) {
1235  hint_delivered = compound_node->getDeliveredHints();
1236  break;
1237  }
1238  }
1239  }
1240  if (hint_delivered && !hint_delivered->empty()) {
1241  dag_builder->registerQueryHints(hint_delivered);
1242  }
1243 }
Hints * getDeliveredHints()
Hints * getDeliveredHints()
void registerQueryHints(Hints *hints_delivered)
Hints * getDeliveredHints()
Hints * getDeliveredHints()
std::unordered_map< std::string, HintExplained > Hints
Hints * getDeliveredHints()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ indices_from_json_array()

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

Definition at line 993 of file RelAlgDagBuilder.cpp.

References CHECK, and CHECK_GE.

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

994  {
995  CHECK(json_idx_arr.IsArray());
996  std::vector<size_t> indices;
997  for (auto json_idx_arr_it = json_idx_arr.Begin(); json_idx_arr_it != json_idx_arr.End();
998  ++json_idx_arr_it) {
999  CHECK(json_idx_arr_it->IsInt());
1000  CHECK_GE(json_idx_arr_it->GetInt(), 0);
1001  indices.emplace_back(json_idx_arr_it->GetInt());
1002  }
1003  return indices;
1004 }
#define CHECK_GE(x, y)
Definition: Logger.h:210
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ isRenamedInput()

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

Definition at line 251 of file RelAlgDagBuilder.cpp.

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

Referenced by RelProject::isRenaming().

253  {
254  CHECK_LT(index, node->size());
255  if (auto join = dynamic_cast<const RelJoin*>(node)) {
256  CHECK_EQ(size_t(2), join->inputCount());
257  const auto lhs_size = join->getInput(0)->size();
258  if (index < lhs_size) {
259  return isRenamedInput(join->getInput(0), index, new_name);
260  }
261  CHECK_GE(index, lhs_size);
262  return isRenamedInput(join->getInput(1), index - lhs_size, new_name);
263  }
264 
265  if (auto scan = dynamic_cast<const RelScan*>(node)) {
266  return new_name != scan->getFieldName(index);
267  }
268 
269  if (auto aggregate = dynamic_cast<const RelAggregate*>(node)) {
270  return new_name != aggregate->getFieldName(index);
271  }
272 
273  if (auto project = dynamic_cast<const RelProject*>(node)) {
274  return new_name != project->getFieldName(index);
275  }
276 
277  if (auto table_func = dynamic_cast<const RelTableFunction*>(node)) {
278  return new_name != table_func->getFieldName(index);
279  }
280 
281  if (auto logical_values = dynamic_cast<const RelLogicalValues*>(node)) {
282  const auto& tuple_type = logical_values->getTupleType();
283  CHECK_LT(index, tuple_type.size());
284  return new_name != tuple_type[index].get_resname();
285  }
286 
287  CHECK(dynamic_cast<const RelSort*>(node) || dynamic_cast<const RelFilter*>(node) ||
288  dynamic_cast<const RelLogicalUnion*>(node));
289  return isRenamedInput(node->getInput(0), index, new_name);
290 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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:210
#define CHECK_LT(x, y)
Definition: Logger.h:207
virtual size_t size() const =0
#define CHECK(condition)
Definition: Logger.h:197
const RelAlgNode * getInput(const size_t idx) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ json_node_to_string()

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

Definition at line 667 of file RelAlgDagBuilder.cpp.

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

667  {
668  rapidjson::StringBuffer buffer;
669  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
670  node.Accept(writer);
671  return buffer.GetString();
672 }
+ Here is the caller graph for this function:

◆ mark_nops()

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

Definition at line 1245 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by RelAlgDagBuilder::build().

1245  {
1246  for (auto node : nodes) {
1247  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1248  if (!agg_node || agg_node->getAggExprsCount()) {
1249  continue;
1250  }
1251  CHECK_EQ(size_t(1), node->inputCount());
1252  const auto agg_input_node = dynamic_cast<const RelAggregate*>(node->getInput(0));
1253  if (agg_input_node && !agg_input_node->getAggExprsCount() &&
1254  agg_node->getGroupByCount() == agg_input_node->getGroupByCount()) {
1255  agg_node->markAsNop();
1256  }
1257  }
1258 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ n_outputs()

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

Definition at line 96 of file RelAlgDagBuilder.cpp.

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 }
+ Here is the caller graph for this function:

◆ node_id()

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

Definition at line 662 of file RelAlgDagBuilder.cpp.

References field(), and json_str().

Referenced by details::RelAlgDispatcher::dispatchFilter(), details::RelAlgDispatcher::prev(), and details::RelAlgDispatcher::run().

662  {
663  const auto& id = field(ra_node, "id");
664  return std::stoi(json_str(id));
665 }
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:

◆ parse_abstract_input()

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

Definition at line 678 of file RelAlgDagBuilder.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

679  {
680  const auto& input = field(expr, "input");
681  return std::unique_ptr<RexAbstractInput>(new RexAbstractInput(json_i64(input)));
682 }
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:

◆ parse_aggregate_expr()

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

Definition at line 1006 of file RelAlgDagBuilder.cpp.

References field(), indices_from_json_array(), json_bool(), json_str(), kAPPROX_COUNT_DISTINCT, parse_type(), and to_agg_kind().

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

1006  {
1007  const auto agg = to_agg_kind(json_str(field(expr, "agg")));
1008  const auto distinct = json_bool(field(expr, "distinct"));
1009  const auto agg_ti = parse_type(field(expr, "type"));
1010  const auto operands = indices_from_json_array(field(expr, "operands"));
1011  if (operands.size() > 1 && (operands.size() != 2 || agg != kAPPROX_COUNT_DISTINCT)) {
1012  throw QueryNotSupported("Multiple arguments for aggregates aren't supported");
1013  }
1014  return std::unique_ptr<const RexAgg>(new RexAgg(agg, distinct, agg_ti, operands));
1015 }
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
SQLAgg to_agg_kind(const std::string &agg_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
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:

◆ parse_case()

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 959 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_scalar_expr().

961  {
962  const auto& operands = field(expr, "operands");
963  CHECK(operands.IsArray());
964  CHECK_GE(operands.Size(), unsigned(2));
965  std::unique_ptr<const RexScalar> else_expr;
966  std::vector<
967  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
968  expr_pair_list;
969  for (auto operands_it = operands.Begin(); operands_it != operands.End();) {
970  auto when_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
971  if (operands_it == operands.End()) {
972  else_expr = std::move(when_expr);
973  break;
974  }
975  auto then_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
976  expr_pair_list.emplace_back(std::move(when_expr), std::move(then_expr));
977  }
978  return std::unique_ptr<RexCase>(new RexCase(expr_pair_list, else_expr));
979 }
#define CHECK_GE(x, y)
Definition: Logger.h:210
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:197
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:

◆ parse_expr_array()

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 780 of file RelAlgDagBuilder.cpp.

References parse_scalar_expr().

Referenced by parse_operator().

783  {
784  std::vector<std::unique_ptr<const RexScalar>> exprs;
785  for (auto it = arr.Begin(); it != arr.End(); ++it) {
786  exprs.emplace_back(parse_scalar_expr(*it, cat, root_dag_builder));
787  }
788  return exprs;
789 }
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:

◆ parse_literal()

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

Definition at line 684 of file RelAlgDagBuilder.cpp.

References cat(), 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, parse_scalar_expr(), to_sql_type(), and run_benchmark_import::type.

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

684  {
685  CHECK(expr.IsObject());
686  const auto& literal = field(expr, "literal");
687  const auto type = to_sql_type(json_str(field(expr, "type")));
688  const auto target_type = to_sql_type(json_str(field(expr, "target_type")));
689  const auto scale = json_i64(field(expr, "scale"));
690  const auto precision = json_i64(field(expr, "precision"));
691  const auto type_scale = json_i64(field(expr, "type_scale"));
692  const auto type_precision = json_i64(field(expr, "type_precision"));
693  if (literal.IsNull()) {
694  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
695  }
696  switch (type) {
697  case kINT:
698  case kBIGINT:
699  case kDECIMAL:
700  case kINTERVAL_DAY_TIME:
702  case kTIME:
703  case kTIMESTAMP:
704  case kDATE:
705  return std::unique_ptr<RexLiteral>(new RexLiteral(json_i64(literal),
706  type,
707  target_type,
708  scale,
709  precision,
710  type_scale,
711  type_precision));
712  case kDOUBLE: {
713  if (literal.IsDouble()) {
714  return std::unique_ptr<RexLiteral>(new RexLiteral(json_double(literal),
715  type,
716  target_type,
717  scale,
718  precision,
719  type_scale,
720  type_precision));
721  }
722  CHECK(literal.IsInt64());
723  return std::unique_ptr<RexLiteral>(
724  new RexLiteral(static_cast<double>(json_i64(literal)),
725  type,
726  target_type,
727  scale,
728  precision,
729  type_scale,
730  type_precision));
731  }
732  case kTEXT:
733  return std::unique_ptr<RexLiteral>(new RexLiteral(json_str(literal),
734  type,
735  target_type,
736  scale,
737  precision,
738  type_scale,
739  type_precision));
740  case kBOOLEAN:
741  return std::unique_ptr<RexLiteral>(new RexLiteral(json_bool(literal),
742  type,
743  target_type,
744  scale,
745  precision,
746  type_scale,
747  type_precision));
748  case kNULLT:
749  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
750  default:
751  CHECK(false);
752  }
753  CHECK(false);
754  return nullptr;
755 }
SQLTypes to_sql_type(const std::string &type_name)
Definition: sqltypes.h:48
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
const double json_double(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:54
Definition: sqltypes.h:51
Definition: sqltypes.h:52
#define CHECK(condition)
Definition: Logger.h:197
Definition: sqltypes.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_nulls_position()

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

Definition at line 860 of file RelAlgDagBuilder.cpp.

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

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

860  {
861  return json_str(field(collation, "nulls")) == std::string("FIRST")
864 }
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:

◆ parse_operator()

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

915  {
916  const auto op_name = json_str(field(expr, "op"));
917  const bool is_quantifier =
918  op_name == std::string("PG_ANY") || op_name == std::string("PG_ALL");
919  const auto op = is_quantifier ? kFUNCTION : to_sql_op(op_name);
920  const auto& operators_json_arr = field(expr, "operands");
921  CHECK(operators_json_arr.IsArray());
922  auto operands = parse_expr_array(operators_json_arr, cat, root_dag_builder);
923  const auto type_it = expr.FindMember("type");
924  CHECK(type_it != expr.MemberEnd());
925  auto ti = parse_type(type_it->value);
926  if (op == kIN && expr.HasMember("subquery")) {
927  auto subquery = parse_subquery(expr, cat, root_dag_builder);
928  operands.emplace_back(std::move(subquery));
929  }
930  if (expr.FindMember("partition_keys") != expr.MemberEnd()) {
931  const auto& partition_keys_arr = field(expr, "partition_keys");
932  auto partition_keys = parse_expr_array(partition_keys_arr, cat, root_dag_builder);
933  const auto& order_keys_arr = field(expr, "order_keys");
934  auto order_keys = parse_window_order_exprs(order_keys_arr, cat, root_dag_builder);
935  const auto collation =
936  parse_window_order_collation(order_keys_arr, cat, root_dag_builder);
937  const auto kind = parse_window_function_kind(op_name);
938  const auto lower_bound =
939  parse_window_bound(field(expr, "lower_bound"), cat, root_dag_builder);
940  const auto upper_bound =
941  parse_window_bound(field(expr, "upper_bound"), cat, root_dag_builder);
942  bool is_rows = json_bool(field(expr, "is_rows"));
943  ti.set_notnull(false);
944  return std::make_unique<RexWindowFunctionOperator>(kind,
945  operands,
946  partition_keys,
947  order_keys,
948  collation,
949  lower_bound,
950  upper_bound,
951  is_rows,
952  ti);
953  }
954  return std::unique_ptr<RexOperator>(op == kFUNCTION
955  ? new RexFunctionOperator(op_name, operands, ti)
956  : new RexOperator(op, operands, ti));
957 }
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)
DEVICE auto lower_bound(ARGS &&... args)
Definition: gpu_enabled.h:78
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
DEVICE auto upper_bound(ARGS &&... args)
Definition: gpu_enabled.h:123
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)
Definition: sqldefs.h:53
#define CHECK(condition)
Definition: Logger.h:197
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:

◆ parse_scalar_expr()

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 1017 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_literal(), parse_window_bound(), and parse_window_order_exprs().

1019  {
1020  CHECK(expr.IsObject());
1021  if (expr.IsObject() && expr.HasMember("input")) {
1022  return std::unique_ptr<const RexScalar>(parse_abstract_input(expr));
1023  }
1024  if (expr.IsObject() && expr.HasMember("literal")) {
1025  return std::unique_ptr<const RexScalar>(parse_literal(expr));
1026  }
1027  if (expr.IsObject() && expr.HasMember("op")) {
1028  const auto op_str = json_str(field(expr, "op"));
1029  if (op_str == std::string("CASE")) {
1030  return std::unique_ptr<const RexScalar>(parse_case(expr, cat, root_dag_builder));
1031  }
1032  if (op_str == std::string("$SCALAR_QUERY")) {
1033  return std::unique_ptr<const RexScalar>(
1034  parse_subquery(expr, cat, root_dag_builder));
1035  }
1036  return std::unique_ptr<const RexScalar>(parse_operator(expr, cat, root_dag_builder));
1037  }
1038  throw QueryNotSupported("Expression node " + json_node_to_string(expr) +
1039  " not supported");
1040 }
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:197
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:

◆ parse_sort_direction()

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

Definition at line 854 of file RelAlgDagBuilder.cpp.

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

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

854  {
855  return json_str(field(collation, "direction")) == std::string("DESCENDING")
858 }
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:

◆ parse_subquery()

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 899 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator(), and parse_scalar_expr().

901  {
902  const auto& operands = field(expr, "operands");
903  CHECK(operands.IsArray());
904  CHECK_GE(operands.Size(), unsigned(0));
905  const auto& subquery_ast = field(expr, "subquery");
906 
907  RelAlgDagBuilder subquery_dag(root_dag_builder, subquery_ast, cat, nullptr);
908  auto subquery = std::make_shared<RexSubQuery>(subquery_dag.getRootNodeShPtr());
909  root_dag_builder.registerSubquery(subquery);
910  return subquery->deepCopy();
911 }
#define CHECK_GE(x, y)
Definition: Logger.h:210
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:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_type()

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

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

761  {
762  if (type_obj.IsArray()) {
763  throw QueryNotSupported("Composite types are not currently supported.");
764  }
765  CHECK(type_obj.IsObject() && type_obj.MemberCount() >= 2)
766  << json_node_to_string(type_obj);
767  const auto type = to_sql_type(json_str(field(type_obj, "type")));
768  const auto nullable = json_bool(field(type_obj, "nullable"));
769  const auto precision_it = type_obj.FindMember("precision");
770  const int precision =
771  precision_it != type_obj.MemberEnd() ? json_i64(precision_it->value) : 0;
772  const auto scale_it = type_obj.FindMember("scale");
773  const int scale = scale_it != type_obj.MemberEnd() ? json_i64(scale_it->value) : 0;
774  SQLTypeInfo ti(type, !nullable);
775  ti.set_precision(precision);
776  ti.set_scale(scale);
777  return ti;
778 }
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:197
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:

◆ parse_window_bound()

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 879 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator().

882  {
883  CHECK(window_bound_obj.IsObject());
885  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
886  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
887  window_bound.following = json_bool(field(window_bound_obj, "following"));
888  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
889  const auto& offset_field = field(window_bound_obj, "offset");
890  if (offset_field.IsObject()) {
891  window_bound.offset = parse_scalar_expr(offset_field, cat, root_dag_builder);
892  } else {
893  CHECK(offset_field.IsNull());
894  }
895  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
896  return window_bound;
897 }
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:197
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:

◆ parse_window_function_kind()

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

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

791  {
792  if (name == "ROW_NUMBER") {
794  }
795  if (name == "RANK") {
797  }
798  if (name == "DENSE_RANK") {
800  }
801  if (name == "PERCENT_RANK") {
803  }
804  if (name == "CUME_DIST") {
806  }
807  if (name == "NTILE") {
809  }
810  if (name == "LAG") {
812  }
813  if (name == "LEAD") {
815  }
816  if (name == "FIRST_VALUE") {
818  }
819  if (name == "LAST_VALUE") {
821  }
822  if (name == "AVG") {
824  }
825  if (name == "MIN") {
827  }
828  if (name == "MAX") {
830  }
831  if (name == "SUM") {
833  }
834  if (name == "COUNT") {
836  }
837  if (name == "$SUM0") {
839  }
840  throw std::runtime_error("Unsupported window function: " + name);
841 }
name
Definition: setup.py:35
+ Here is the caller graph for this function:

◆ parse_window_order_collation()

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 866 of file RelAlgDagBuilder.cpp.

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

868  {
869  std::vector<SortField> collation;
870  size_t field_idx = 0;
871  for (auto it = arr.Begin(); it != arr.End(); ++it, ++field_idx) {
872  const auto sort_dir = parse_sort_direction(*it);
873  const auto null_pos = parse_nulls_position(*it);
874  collation.emplace_back(field_idx, sort_dir, null_pos);
875  }
876  return collation;
877 }
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:

◆ parse_window_order_exprs()

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 843 of file RelAlgDagBuilder.cpp.

References field(), and parse_scalar_expr().

Referenced by parse_operator().

846  {
847  std::vector<std::unique_ptr<const RexScalar>> exprs;
848  for (auto it = arr.Begin(); it != arr.End(); ++it) {
849  exprs.emplace_back(parse_scalar_expr(field(*it, "field"), cat, root_dag_builder));
850  }
851  return exprs;
852 }
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:

◆ remapTargetPointers()

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 418 of file RelAlgDagBuilder.cpp.

References CHECK.

423  {
424  std::vector<const Rex*> target_exprs(target_exprs_old);
425  std::unordered_map<const Rex*, const Rex*> old_to_new_target(target_exprs.size());
426  for (size_t i = 0; i < agg_exprs_new.size(); ++i) {
427  old_to_new_target.emplace(agg_exprs_old[i].get(), agg_exprs_new[i].get());
428  }
429  for (size_t i = 0; i < scalar_sources_new.size(); ++i) {
430  old_to_new_target.emplace(scalar_sources_old[i].get(), scalar_sources_new[i].get());
431  }
432  for (auto& target : target_exprs) {
433  auto target_it = old_to_new_target.find(target);
434  CHECK(target_it != old_to_new_target.end());
435  target = target_it->second;
436  }
437  return target_exprs;
438 }
#define CHECK(condition)
Definition: Logger.h:197

◆ separate_window_function_expressions()

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

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 and replacing the window function operator with a RexInput. Also move all input nodes to the newly created project node. In pseudocode: for each rex in project list: detect window function expression if window function expression: copy window function expression replace window function expression in base expression w/ input add base expression to new project node after the current node replace base expression in current project node with the window function expression copy

Definition at line 1895 of file RelAlgDagBuilder.cpp.

References CHECK, CHECK_EQ, CHECK_LT, RelProject::getProjectAt(), anonymous_namespace{RelAlgDagBuilder.cpp}::anonymous_namespace{RelAlgDagBuilder.cpp}::is_window_function_operator(), and RexVisitorBase< T >::visit().

Referenced by RelAlgDagBuilder::build().

1896  {
1897  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
1898 
1899  WindowFunctionDetectionVisitor visitor;
1900  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
1901  const auto node = *node_itr;
1902  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
1903  if (!window_func_project_node) {
1904  continue;
1905  }
1906 
1907  // map scalar expression index in the project node to wiondow function ptr
1908  std::unordered_map<size_t, const RexScalar*> embedded_window_function_expressions;
1909 
1910  // Iterate the target exprs of the project node and check for window function
1911  // expressions. If an embedded expression exists, save it in the
1912  // embedded_window_function_expressions map and split the expression into a window
1913  // function expression and a parent expression in a subsequent project node
1914  for (size_t i = 0; i < window_func_project_node->size(); i++) {
1915  const auto scalar_rex = window_func_project_node->getProjectAt(i);
1916  if (is_window_function_operator(scalar_rex)) {
1917  // top level window function exprs are fine
1918  continue;
1919  }
1920 
1921  if (const auto window_func_rex = visitor.visit(scalar_rex)) {
1922  const auto ret = embedded_window_function_expressions.insert(
1923  std::make_pair(i, window_func_rex));
1924  CHECK(ret.second);
1925  }
1926  }
1927 
1928  if (!embedded_window_function_expressions.empty()) {
1929  std::vector<std::unique_ptr<const RexScalar>> new_scalar_exprs;
1930 
1931  auto window_func_scalar_exprs =
1932  window_func_project_node->getExpressionsAndRelease();
1933  for (size_t rex_idx = 0; rex_idx < window_func_scalar_exprs.size(); ++rex_idx) {
1934  const auto embedded_window_func_expr_pair =
1935  embedded_window_function_expressions.find(rex_idx);
1936  if (embedded_window_func_expr_pair ==
1937  embedded_window_function_expressions.end()) {
1938  new_scalar_exprs.emplace_back(
1939  std::make_unique<const RexInput>(window_func_project_node.get(), rex_idx));
1940  } else {
1941  const auto window_func_rex_idx = embedded_window_func_expr_pair->first;
1942  CHECK_LT(window_func_rex_idx, window_func_scalar_exprs.size());
1943 
1944  const auto& window_func_rex = embedded_window_func_expr_pair->second;
1945 
1946  RexDeepCopyVisitor copier;
1947  auto window_func_rex_copy = copier.visit(window_func_rex);
1948 
1949  auto window_func_parent_expr =
1950  window_func_scalar_exprs[window_func_rex_idx].get();
1951 
1952  // Replace window func rex with an input rex
1953  auto window_func_result_input = std::make_unique<const RexInput>(
1954  window_func_project_node.get(), window_func_rex_idx);
1955  RexWindowFuncReplacementVisitor replacer(std::move(window_func_result_input));
1956  auto new_parent_rex = replacer.visit(window_func_parent_expr);
1957 
1958  // Put the parent expr in the new scalar exprs
1959  new_scalar_exprs.emplace_back(std::move(new_parent_rex));
1960 
1961  // Put the window func expr in cur scalar exprs
1962  window_func_scalar_exprs[window_func_rex_idx] = std::move(window_func_rex_copy);
1963  }
1964  }
1965 
1966  CHECK_EQ(window_func_scalar_exprs.size(), new_scalar_exprs.size());
1967  window_func_project_node->setExpressions(window_func_scalar_exprs);
1968 
1969  // Ensure any inputs from the node containing the expression (the "new" node)
1970  // exist on the window function project node, e.g. if we had a binary operation
1971  // involving an aggregate value or column not included in the top level
1972  // projection list.
1973  RexInputBackpropagationVisitor input_visitor(window_func_project_node.get());
1974  for (size_t i = 0; i < new_scalar_exprs.size(); i++) {
1975  if (dynamic_cast<const RexInput*>(new_scalar_exprs[i].get())) {
1976  // ignore top level inputs, these were copied directly from the previous
1977  // node
1978  continue;
1979  }
1980  new_scalar_exprs[i] = input_visitor.visit(new_scalar_exprs[i].get());
1981  }
1982 
1983  // Build the new project node and insert it into the list after the project node
1984  // containing the window function
1985  auto new_project =
1986  std::make_shared<RelProject>(new_scalar_exprs,
1987  window_func_project_node->getFields(),
1988  window_func_project_node);
1989  node_list.insert(std::next(node_itr), new_project);
1990 
1991  // Rebind all the following inputs
1992  for (auto rebind_itr = std::next(node_itr, 2); rebind_itr != node_list.end();
1993  rebind_itr++) {
1994  (*rebind_itr)->replaceInput(window_func_project_node, new_project);
1995  }
1996  }
1997  }
1998  nodes.assign(node_list.begin(), node_list.end());
1999 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const RexScalar * getProjectAt(const size_t idx) const
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
#define CHECK_LT(x, y)
Definition: Logger.h:207
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ strings_from_json_array()

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

Definition at line 981 of file RelAlgDagBuilder.cpp.

References CHECK.

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

982  {
983  CHECK(json_str_arr.IsArray());
984  std::vector<std::string> fields;
985  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
986  ++json_str_arr_it) {
987  CHECK(json_str_arr_it->IsString());
988  fields.emplace_back(json_str_arr_it->GetString());
989  }
990  return fields;
991 }
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ to_join_type()

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

Definition at line 1042 of file RelAlgDagBuilder.cpp.

References disambiguate_rex(), INNER, and LEFT.

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

1042  {
1043  if (join_type_name == "inner") {
1044  return JoinType::INNER;
1045  }
1046  if (join_type_name == "left") {
1047  return JoinType::LEFT;
1048  }
1049  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
1050 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ FIRST_RA_NODE_ID

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

Definition at line 41 of file RelAlgDagBuilder.cpp.

Referenced by RelAlgNode::resetRelAlgFirstId().