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

Namespaces

 anonymous_namespace{RelAlgDagBuilder.cpp}
 

Classes

class  RexRebindInputsVisitor
 
class  RexRebindReindexInputsVisitor
 
class  RANodeIterator
 
class  WindowFunctionDetectionVisitor
 
class  RexWindowFuncReplacementVisitor
 
class  RexInputBackpropagationVisitor
 
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 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

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

Definition at line 1988 of file RelAlgDagBuilder.cpp.

Function Documentation

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

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

Referenced by RelAlgDagBuilder::build().

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

+ 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 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  bind_table_func_to_input(table_func_node.get(),
1186  get_node_output(table_func_node->getInput(0)));
1187  }
1188  }
1189 }
#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)

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

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs(), and create_compound().

1130  {
1131  CHECK_EQ(size_t(1), project_node->inputCount());
1132  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1133  for (size_t i = 0; i < project_node->size(); ++i) {
1134  const auto projected_expr = project_node->getProjectAt(i);
1135  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
1136  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
1137  } else {
1138  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
1139  }
1140  }
1141  project_node->setExpressions(disambiguated_exprs);
1142 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 1144 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs().

1145  {
1146  CHECK_EQ(size_t(1), table_func_node->inputCount());
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 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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
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}::check_empty_inputs_field ( const rapidjson::Value &  node)
noexcept

Definition at line 2082 of file RelAlgDagBuilder.cpp.

References CHECK(), and field().

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

2082  {
2083  const auto& inputs_json = field(node, "inputs");
2084  CHECK(inputs_json.IsArray() && !inputs_json.Size());
2085 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)

+ 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 
)

Definition at line 1593 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

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

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

399  {
400  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_copy;
401  agg_exprs_copy.reserve(agg_exprs.size());
402  for (auto const& agg_expr : agg_exprs) {
403  agg_exprs_copy.push_back(agg_expr->deepCopy());
404  }
405  return agg_exprs_copy;
406 }
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 408 of file RelAlgDagBuilder.cpp.

References RexVisitorBase< T >::visit().

409  {
410  std::vector<std::unique_ptr<const RexScalar>> scalar_sources_copy;
411  scalar_sources_copy.reserve(scalar_sources.size());
412  RexDeepCopyVisitor copier;
413  for (auto const& scalar_source : scalar_sources) {
414  scalar_sources_copy.push_back(copier.visit(scalar_source.get()));
415  }
416  return scalar_sources_copy;
417 }
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 
)
noexcept

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

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

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

Referenced by disambiguate_rex().

1089  {
1090  std::vector<
1091  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
1092  disambiguated_expr_pair_list;
1093  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
1094  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
1095  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
1096  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
1097  std::move(disambiguated_then));
1098  }
1099  std::unique_ptr<const RexScalar> disambiguated_else{
1100  disambiguate_rex(rex_case->getElse(), ra_output)};
1101  return std::unique_ptr<const RexCase>(
1102  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
1103 }
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 1053 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

1055  {
1056  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
1057  for (size_t i = 0; i < rex_operator->size(); ++i) {
1058  auto operand = rex_operator->getOperand(i);
1059  if (dynamic_cast<const RexSubQuery*>(operand)) {
1060  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
1061  } else {
1062  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
1063  }
1064  }
1065  const auto rex_window_function_operator =
1066  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
1067  if (rex_window_function_operator) {
1068  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
1069  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
1070  for (const auto& partition_key : partition_keys) {
1071  disambiguated_partition_keys.emplace_back(
1072  disambiguate_rex(partition_key.get(), ra_output));
1073  }
1074  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
1075  const auto& order_keys = rex_window_function_operator->getOrderKeys();
1076  for (const auto& order_key : order_keys) {
1077  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
1078  }
1079  return rex_window_function_operator->disambiguatedOperands(
1080  disambiguated_operands,
1081  disambiguated_partition_keys,
1082  disambiguated_order_keys,
1083  rex_window_function_operator->getCollation());
1084  }
1085  return rex_operator->getDisambiguated(disambiguated_operands);
1086 }
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 1109 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(), and disambiguate_operator().

1110  {
1111  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
1112  if (rex_abstract_input) {
1113  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
1114  return std::unique_ptr<const RexInput>(
1115  new RexInput(ra_output[rex_abstract_input->getIndex()]));
1116  }
1117  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
1118  if (rex_operator) {
1119  return disambiguate_operator(rex_operator, ra_output);
1120  }
1121  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
1122  if (rex_case) {
1123  return disambiguate_case(rex_case, ra_output);
1124  }
1125  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
1126  CHECK(rex_literal);
1127  return std::unique_ptr<const RexLiteral>(new RexLiteral(*rex_literal));
1128 }
CHECK(cgen_state)
#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)

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

References CHECK(), and CHECK_EQ.

Referenced by RelSort::hasEquivCollationOf().

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

+ Here is the call graph for this function:

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

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

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

2070  {
2071  const auto it = obj.FindMember(field);
2072  if (it == obj.MemberEnd()) {
2073  return default_val;
2074  }
2075  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
2076  CHECK_EQ(kDECIMAL, lit->getType());
2077  CHECK_EQ(unsigned(0), lit->getScale());
2078  CHECK_EQ(unsigned(0), lit->getTypeScale());
2079  return lit->getVal<int64_t>();
2080 }
#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:

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

Definition at line 2097 of file RelAlgDagBuilder.cpp.

References field(), and strings_from_json_array().

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

2097  {
2098  const auto& fields_json = field(scan_ra, "fieldNames");
2099  return strings_from_json_array(fields_json);
2100 }
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 2087 of file RelAlgDagBuilder.cpp.

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

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

2088  {
2089  const auto& table_json = field(scan_ra, "table");
2090  CHECK(table_json.IsArray());
2091  CHECK_EQ(unsigned(2), table_json.Size());
2092  const auto td = cat.getMetadataForTable(table_json[1].GetString());
2093  CHECK(td);
2094  return td;
2095 }
#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
CHECK(cgen_state)
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}::handleQueryHint ( const std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
RelAlgDagBuilder dag_builder 
)
noexcept

Definition at line 1191 of file RelAlgDagBuilder.cpp.

References QueryHint::cpu_mode, and VLOG.

Referenced by RelAlgDagBuilder::build().

1192  {
1193  QueryHint query_hints;
1194  for (auto node : nodes) {
1195  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1196  if (agg_node) {
1197  if (agg_node->hasHintEnabled("cpu_mode")) {
1198  query_hints.cpu_mode = true;
1199  }
1200  }
1201  const auto project_node = std::dynamic_pointer_cast<RelProject>(node);
1202  if (project_node) {
1203  if (project_node->hasHintEnabled("cpu_mode")) {
1204  query_hints.cpu_mode = true;
1205  }
1206  }
1207  const auto scan_node = std::dynamic_pointer_cast<RelScan>(node);
1208  if (scan_node) {
1209  if (scan_node->hasHintEnabled("cpu_mode")) {
1210  query_hints.cpu_mode = true;
1211  }
1212  }
1213  const auto join_node = std::dynamic_pointer_cast<RelJoin>(node);
1214  if (join_node) {
1215  if (join_node->hasHintEnabled("cpu_mode")) {
1216  query_hints.cpu_mode = true;
1217  }
1218  }
1219  const auto compound_node = std::dynamic_pointer_cast<RelCompound>(node);
1220  if (compound_node) {
1221  if (compound_node->hasHintEnabled("cpu_mode")) {
1222  query_hints.cpu_mode = true;
1223  }
1224  }
1225  }
1226  if (query_hints.cpu_mode) {
1227  VLOG(1) << "A user forces to run the query on the CPU execution mode";
1228  }
1229  dag_builder->registerQueryHints(query_hints);
1230 }
bool cpu_mode
Definition: QueryHint.h:21
void registerQueryHints(QueryHint &query_hint)
#define VLOG(n)
Definition: Logger.h:291

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

References CHECK(), and CHECK_GE.

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

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

+ Here is the call graph for this function:

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

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

Referenced by RelProject::isRenaming().

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

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

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

668  {
669  rapidjson::StringBuffer buffer;
670  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
671  node.Accept(writer);
672  return buffer.GetString();
673 }

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

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by RelAlgDagBuilder::build().

1232  {
1233  for (auto node : nodes) {
1234  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1235  if (!agg_node || agg_node->getAggExprsCount()) {
1236  continue;
1237  }
1238  CHECK_EQ(size_t(1), node->inputCount());
1239  const auto agg_input_node = dynamic_cast<const RelAggregate*>(node->getInput(0));
1240  if (agg_input_node && !agg_input_node->getAggExprsCount() &&
1241  agg_node->getGroupByCount() == agg_input_node->getGroupByCount()) {
1242  agg_node->markAsNop();
1243  }
1244  }
1245 }
#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:

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:

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

Definition at line 663 of file RelAlgDagBuilder.cpp.

References field(), and json_str().

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

663  {
664  const auto& id = field(ra_node, "id");
665  return std::stoi(json_str(id));
666 }
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 679 of file RelAlgDagBuilder.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

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

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

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

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

Referenced by parse_scalar_expr().

960  {
961  const auto& operands = field(expr, "operands");
962  CHECK(operands.IsArray());
963  CHECK_GE(operands.Size(), unsigned(2));
964  std::unique_ptr<const RexScalar> else_expr;
965  std::vector<
966  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
967  expr_pair_list;
968  for (auto operands_it = operands.Begin(); operands_it != operands.End();) {
969  auto when_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
970  if (operands_it == operands.End()) {
971  else_expr = std::move(when_expr);
972  break;
973  }
974  auto then_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
975  expr_pair_list.emplace_back(std::move(when_expr), std::move(then_expr));
976  }
977  return std::unique_ptr<RexCase>(new RexCase(expr_pair_list, else_expr));
978 }
#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
CHECK(cgen_state)
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 779 of file RelAlgDagBuilder.cpp.

References parse_scalar_expr().

Referenced by parse_operator().

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

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

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

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

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

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

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

859  {
860  return json_str(field(collation, "nulls")) == std::string("FIRST")
863 }
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 912 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_scalar_expr().

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

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

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

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

853  {
854  return json_str(field(collation, "direction")) == std::string("DESCENDING")
857 }
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 898 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator(), and parse_scalar_expr().

900  {
901  const auto& operands = field(expr, "operands");
902  CHECK(operands.IsArray());
903  CHECK_GE(operands.Size(), unsigned(0));
904  const auto& subquery_ast = field(expr, "subquery");
905 
906  RelAlgDagBuilder subquery_dag(root_dag_builder, subquery_ast, cat, nullptr);
907  auto subquery = std::make_shared<RexSubQuery>(subquery_dag.getRootNodeShPtr());
908  root_dag_builder.registerSubquery(subquery);
909  return subquery->deepCopy();
910 }
#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
CHECK(cgen_state)
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)

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

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

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

Referenced by parse_operator().

881  {
882  CHECK(window_bound_obj.IsObject());
884  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
885  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
886  window_bound.following = json_bool(field(window_bound_obj, "following"));
887  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
888  const auto& offset_field = field(window_bound_obj, "offset");
889  if (offset_field.IsObject()) {
890  window_bound.offset = parse_scalar_expr(offset_field, cat, root_dag_builder);
891  } else {
892  CHECK(offset_field.IsNull());
893  }
894  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
895  return window_bound;
896 }
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
CHECK(cgen_state)
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
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 790 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().

790  {
791  if (name == "ROW_NUMBER") {
793  }
794  if (name == "RANK") {
796  }
797  if (name == "DENSE_RANK") {
799  }
800  if (name == "PERCENT_RANK") {
802  }
803  if (name == "CUME_DIST") {
805  }
806  if (name == "NTILE") {
808  }
809  if (name == "LAG") {
811  }
812  if (name == "LEAD") {
814  }
815  if (name == "FIRST_VALUE") {
817  }
818  if (name == "LAST_VALUE") {
820  }
821  if (name == "AVG") {
823  }
824  if (name == "MIN") {
826  }
827  if (name == "MAX") {
829  }
830  if (name == "SUM") {
832  }
833  if (name == "COUNT") {
835  }
836  if (name == "$SUM0") {
838  }
839  throw std::runtime_error("Unsupported window function: " + name);
840 }

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

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

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

References field(), and parse_scalar_expr().

Referenced by parse_operator().

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

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

References CHECK().

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

+ Here is the call graph for this function:

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

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

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

References CHECK().

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

981  {
982  CHECK(json_str_arr.IsArray());
983  std::vector<std::string> fields;
984  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
985  ++json_str_arr_it) {
986  CHECK(json_str_arr_it->IsString());
987  fields.emplace_back(json_str_arr_it->GetString());
988  }
989  return fields;
990 }
CHECK(cgen_state)

+ Here is the call graph for this function:

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

References INNER, and LEFT.

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

1041  {
1042  if (join_type_name == "inner") {
1043  return JoinType::INNER;
1044  }
1045  if (join_type_name == "left") {
1046  return JoinType::LEFT;
1047  }
1048  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
1049 }

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