OmniSciDB  fe05a0c208
 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 2021 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 2045 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

2045  {
2046  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
2047 
2048  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
2049  const auto node = *node_itr;
2050  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
2051  if (!window_func_project_node) {
2052  continue;
2053  }
2054  if (!window_func_project_node->hasWindowFunctionExpr()) {
2055  // the first projection node in the query plan does not have a window function
2056  // expression -- this step is not requierd.
2057  return;
2058  }
2059 
2060  const auto prev_node_itr = std::prev(node_itr);
2061  const auto prev_node = *prev_node_itr;
2062  CHECK(prev_node);
2063 
2064  RexInputSet inputs;
2065  RexInputCollector input_collector;
2066  for (size_t i = 0; i < window_func_project_node->size(); i++) {
2067  auto new_inputs = input_collector.visit(window_func_project_node->getProjectAt(i));
2068  inputs.insert(new_inputs.begin(), new_inputs.end());
2069  }
2070 
2071  // Note: Technically not required since we are mapping old inputs to new input
2072  // indices, but makes the re-mapping of inputs easier to follow.
2073  std::vector<RexInput> sorted_inputs(inputs.begin(), inputs.end());
2074  std::sort(sorted_inputs.begin(),
2075  sorted_inputs.end(),
2076  [](const auto& a, const auto& b) { return a.getIndex() < b.getIndex(); });
2077 
2078  std::vector<std::unique_ptr<const RexScalar>> scalar_exprs;
2079  std::vector<std::string> fields;
2080  std::unordered_map<unsigned, unsigned> old_index_to_new_index;
2081  for (auto& input : sorted_inputs) {
2082  CHECK_EQ(input.getSourceNode(), prev_node.get());
2083  CHECK(old_index_to_new_index
2084  .insert(std::make_pair(input.getIndex(), scalar_exprs.size()))
2085  .second);
2086  scalar_exprs.emplace_back(input.deepCopy());
2087  fields.emplace_back("");
2088  }
2089 
2090  auto new_project = std::make_shared<RelProject>(scalar_exprs, fields, prev_node);
2091  node_list.insert(node_itr, new_project);
2092  window_func_project_node->replaceInput(
2093  prev_node, new_project, old_index_to_new_index);
2094 
2095  break;
2096  }
2097 
2098  nodes.assign(node_list.begin(), node_list.end());
2099 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
std::unordered_set< RexInput > RexInputSet
#define CHECK(condition)
Definition: Logger.h:203

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

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

Referenced by RelAlgDagBuilder::build().

1179  {
1180  for (auto ra_node : nodes) {
1181  const auto filter_node = std::dynamic_pointer_cast<RelFilter>(ra_node);
1182  if (filter_node) {
1183  CHECK_EQ(size_t(1), filter_node->inputCount());
1184  auto disambiguated_condition = disambiguate_rex(
1185  filter_node->getCondition(), get_node_output(filter_node->getInput(0)));
1186  filter_node->setCondition(disambiguated_condition);
1187  continue;
1188  }
1189  const auto join_node = std::dynamic_pointer_cast<RelJoin>(ra_node);
1190  if (join_node) {
1191  CHECK_EQ(size_t(2), join_node->inputCount());
1192  auto disambiguated_condition =
1193  disambiguate_rex(join_node->getCondition(), get_node_output(join_node.get()));
1194  join_node->setCondition(disambiguated_condition);
1195  continue;
1196  }
1197  const auto project_node = std::dynamic_pointer_cast<RelProject>(ra_node);
1198  if (project_node) {
1199  bind_project_to_input(project_node.get(),
1200  get_node_output(project_node->getInput(0)));
1201  continue;
1202  }
1203  const auto table_func_node = std::dynamic_pointer_cast<RelTableFunction>(ra_node);
1204  if (table_func_node) {
1205  /*
1206  Collect all inputs from table function input (non-literal)
1207  arguments.
1208  */
1209  RANodeOutput input;
1210  input.reserve(table_func_node->inputCount());
1211  for (size_t i = 0; i < table_func_node->inputCount(); i++) {
1212  auto node_output = get_node_output(table_func_node->getInput(i));
1213  input.insert(input.end(), node_output.begin(), node_output.end());
1214  }
1215  bind_table_func_to_input(table_func_node.get(), input);
1216  }
1217  }
1218 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
void bind_table_func_to_input(RelTableFunction *table_func_node, const RANodeOutput &input) noexcept
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
RANodeOutput get_node_output(const RelAlgNode *ra_node)
std::vector< RexInput > RANodeOutput

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1151 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, disambiguate_rex(), and i.

Referenced by bind_inputs(), and create_compound().

1151  {
1152  CHECK_EQ(size_t(1), project_node->inputCount());
1153  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1154  for (size_t i = 0; i < project_node->size(); ++i) {
1155  const auto projected_expr = project_node->getProjectAt(i);
1156  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
1157  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
1158  } else {
1159  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
1160  }
1161  }
1162  project_node->setExpressions(disambiguated_exprs);
1163 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
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 1165 of file RelAlgDagBuilder.cpp.

References disambiguate_rex(), and i.

Referenced by bind_inputs().

1166  {
1167  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1168  for (size_t i = 0; i < table_func_node->getTableFuncInputsSize(); ++i) {
1169  const auto target_expr = table_func_node->getTableFuncInputAt(i);
1170  if (dynamic_cast<const RexSubQuery*>(target_expr)) {
1171  disambiguated_exprs.emplace_back(table_func_node->getTableFuncInputAtAndRelease(i));
1172  } else {
1173  disambiguated_exprs.emplace_back(disambiguate_rex(target_expr, input));
1174  }
1175  }
1176  table_func_node->setTableFuncInputs(disambiguated_exprs);
1177 }
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
size_t getTableFuncInputsSize() const
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
const RexScalar * getTableFuncInputAt(const size_t idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 2115 of file RelAlgDagBuilder.cpp.

References CHECK, and field().

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

2115  {
2116  const auto& inputs_json = field(node, "inputs");
2117  CHECK(inputs_json.IsArray() && !inputs_json.Size());
2118 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:203

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

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

Referenced by RelAlgDagBuilder::build().

1627  {
1628  enum class CoalesceState { Initial, Filter, FirstProject, Aggregate };
1629  std::vector<size_t> crt_pattern;
1630  CoalesceState crt_state{CoalesceState::Initial};
1631 
1632  auto reset_state = [&crt_pattern, &crt_state]() {
1633  crt_state = CoalesceState::Initial;
1634  std::vector<size_t>().swap(crt_pattern);
1635  };
1636 
1637  for (RANodeIterator nodeIt(nodes); !nodeIt.allVisited();) {
1638  const auto ra_node = nodeIt != nodes.end() ? *nodeIt : nullptr;
1639  switch (crt_state) {
1640  case CoalesceState::Initial: {
1641  if (std::dynamic_pointer_cast<const RelFilter>(ra_node) &&
1642  std::find(left_deep_joins.begin(), left_deep_joins.end(), ra_node.get()) ==
1643  left_deep_joins.end()) {
1644  crt_pattern.push_back(size_t(nodeIt));
1645  crt_state = CoalesceState::Filter;
1646  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1647  } else if (std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1648  crt_pattern.push_back(size_t(nodeIt));
1649  crt_state = CoalesceState::FirstProject;
1650  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1651  } else {
1652  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1653  }
1654  break;
1655  }
1656  case CoalesceState::Filter: {
1657  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1658  if (project_node->hasWindowFunctionExpr()) {
1659  reset_state();
1660  break;
1661  }
1662  crt_pattern.push_back(size_t(nodeIt));
1663  crt_state = CoalesceState::FirstProject;
1664  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1665  } else {
1666  reset_state();
1667  }
1668  break;
1669  }
1670  case CoalesceState::FirstProject: {
1671  if (std::dynamic_pointer_cast<const RelAggregate>(ra_node)) {
1672  crt_pattern.push_back(size_t(nodeIt));
1673  crt_state = CoalesceState::Aggregate;
1674  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1675  } else {
1676  if (crt_pattern.size() >= 2) {
1677  create_compound(nodes, crt_pattern);
1678  }
1679  reset_state();
1680  }
1681  break;
1682  }
1683  case CoalesceState::Aggregate: {
1684  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1685  // TODO(adb): overloading the simple project terminology again here
1686  bool is_simple_project{true};
1687  for (size_t i = 0; i < project_node->size(); i++) {
1688  const auto scalar_rex = project_node->getProjectAt(i);
1689  // If the top level scalar rex is an input node, we can bypass the visitor
1690  if (auto input_rex = dynamic_cast<const RexInput*>(scalar_rex)) {
1692  input_rex->getSourceNode(), input_rex->getIndex(), true)) {
1693  is_simple_project = false;
1694  break;
1695  }
1696  continue;
1697  }
1698  CoalesceSecondaryProjectVisitor visitor;
1699  if (!visitor.visit(project_node->getProjectAt(i))) {
1700  is_simple_project = false;
1701  break;
1702  }
1703  }
1704  if (is_simple_project) {
1705  crt_pattern.push_back(size_t(nodeIt));
1706  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1707  }
1708  }
1709  CHECK_GE(crt_pattern.size(), size_t(2));
1710  create_compound(nodes, crt_pattern);
1711  reset_state();
1712  break;
1713  }
1714  default:
1715  CHECK(false);
1716  }
1717  }
1718  if (crt_state == CoalesceState::FirstProject || crt_state == CoalesceState::Aggregate) {
1719  if (crt_pattern.size() >= 2) {
1720  create_compound(nodes, crt_pattern);
1721  }
1722  CHECK(!crt_pattern.empty());
1723  }
1724 }
#define CHECK_GE(x, y)
Definition: Logger.h:216
#define CHECK(condition)
Definition: Logger.h:203
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)
DEVICE void swap(ARGS &&...args)
Definition: gpu_enabled.h:114

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 }
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:

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

Definition at line 1325 of file RelAlgDagBuilder.cpp.

References bind_project_to_input(), CHECK, CHECK_EQ, CHECK_GE, CHECK_LE, CHECK_LT, get_node_output(), RelProject::getFields(), i, 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().

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

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

Referenced by disambiguate_rex().

1110  {
1111  std::vector<
1112  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
1113  disambiguated_expr_pair_list;
1114  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
1115  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
1116  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
1117  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
1118  std::move(disambiguated_then));
1119  }
1120  std::unique_ptr<const RexScalar> disambiguated_else{
1121  disambiguate_rex(rex_case->getElse(), ra_output)};
1122  return std::unique_ptr<const RexCase>(
1123  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
1124 }
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 1074 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

1076  {
1077  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
1078  for (size_t i = 0; i < rex_operator->size(); ++i) {
1079  auto operand = rex_operator->getOperand(i);
1080  if (dynamic_cast<const RexSubQuery*>(operand)) {
1081  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
1082  } else {
1083  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
1084  }
1085  }
1086  const auto rex_window_function_operator =
1087  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
1088  if (rex_window_function_operator) {
1089  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
1090  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
1091  for (const auto& partition_key : partition_keys) {
1092  disambiguated_partition_keys.emplace_back(
1093  disambiguate_rex(partition_key.get(), ra_output));
1094  }
1095  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
1096  const auto& order_keys = rex_window_function_operator->getOrderKeys();
1097  for (const auto& order_key : order_keys) {
1098  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
1099  }
1100  return rex_window_function_operator->disambiguatedOperands(
1101  disambiguated_operands,
1102  disambiguated_partition_keys,
1103  disambiguated_order_keys,
1104  rex_window_function_operator->getCollation());
1105  }
1106  return rex_operator->getDisambiguated(disambiguated_operands);
1107 }
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 1130 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().

1131  {
1132  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
1133  if (rex_abstract_input) {
1134  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
1135  return std::unique_ptr<const RexInput>(
1136  new RexInput(ra_output[rex_abstract_input->getIndex()]));
1137  }
1138  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
1139  if (rex_operator) {
1140  return disambiguate_operator(rex_operator, ra_output);
1141  }
1142  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
1143  if (rex_case) {
1144  return disambiguate_case(rex_case, ra_output);
1145  }
1146  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
1147  CHECK(rex_literal);
1148  return std::unique_ptr<const RexLiteral>(new RexLiteral(*rex_literal));
1149 }
#define CHECK_LT(x, y)
Definition: Logger.h:213
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:203

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

References CHECK, and CHECK_EQ.

Referenced by RelSort::hasEquivCollationOf().

521  {
522  std::set<std::pair<const RelAlgNode*, int>> work_set;
523  auto walker = node;
524  auto curr_col = which_col;
525  while (true) {
526  work_set.insert(std::make_pair(walker, curr_col));
527  if (dynamic_cast<const RelScan*>(walker) || dynamic_cast<const RelJoin*>(walker)) {
528  break;
529  }
530  CHECK_EQ(size_t(1), walker->inputCount());
531  auto only_source = walker->getInput(0);
532  if (auto project = dynamic_cast<const RelProject*>(walker)) {
533  if (auto input = dynamic_cast<const RexInput*>(project->getProjectAt(curr_col))) {
534  const auto join_source = dynamic_cast<const RelJoin*>(only_source);
535  if (join_source) {
536  CHECK_EQ(size_t(2), join_source->inputCount());
537  auto lhs = join_source->getInput(0);
538  CHECK((input->getIndex() < lhs->size() && lhs == input->getSourceNode()) ||
539  join_source->getInput(1) == input->getSourceNode());
540  } else {
541  CHECK_EQ(input->getSourceNode(), only_source);
542  }
543  curr_col = input->getIndex();
544  } else {
545  break;
546  }
547  } else if (auto aggregate = dynamic_cast<const RelAggregate*>(walker)) {
548  if (curr_col >= aggregate->getGroupByCount()) {
549  break;
550  }
551  }
552  walker = only_source;
553  }
554  return work_set;
555 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
#define CHECK(condition)
Definition: Logger.h:203

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

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

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

2103  {
2104  const auto it = obj.FindMember(field);
2105  if (it == obj.MemberEnd()) {
2106  return default_val;
2107  }
2108  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
2109  CHECK_EQ(kDECIMAL, lit->getType());
2110  CHECK_EQ(unsigned(0), lit->getScale());
2111  CHECK_EQ(unsigned(0), lit->getTypeScale());
2112  return lit->getVal<int64_t>();
2113 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
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 2130 of file RelAlgDagBuilder.cpp.

References field(), and strings_from_json_array().

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

2130  {
2131  const auto& fields_json = field(scan_ra, "fieldNames");
2132  return strings_from_json_array(fields_json);
2133 }
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 2120 of file RelAlgDagBuilder.cpp.

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

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

2121  {
2122  const auto& table_json = field(scan_ra, "table");
2123  CHECK(table_json.IsArray());
2124  CHECK_EQ(unsigned(2), table_json.Size());
2125  const auto td = cat.getMetadataForTable(table_json[1].GetString());
2126  CHECK(td);
2127  return td;
2128 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:203
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 1220 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

1221  {
1222  Hints* hint_delivered = nullptr;
1223  for (auto node : nodes) {
1224  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1225  if (agg_node) {
1226  if (agg_node->hasDeliveredHint()) {
1227  hint_delivered = agg_node->getDeliveredHints();
1228  break;
1229  }
1230  }
1231  const auto project_node = std::dynamic_pointer_cast<RelProject>(node);
1232  if (project_node) {
1233  if (project_node->hasDeliveredHint()) {
1234  hint_delivered = project_node->getDeliveredHints();
1235  break;
1236  }
1237  }
1238  const auto scan_node = std::dynamic_pointer_cast<RelScan>(node);
1239  if (scan_node) {
1240  if (scan_node->hasDeliveredHint()) {
1241  hint_delivered = scan_node->getDeliveredHints();
1242  break;
1243  }
1244  }
1245  const auto join_node = std::dynamic_pointer_cast<RelJoin>(node);
1246  if (join_node) {
1247  if (join_node->hasDeliveredHint()) {
1248  hint_delivered = join_node->getDeliveredHints();
1249  break;
1250  }
1251  }
1252  const auto compound_node = std::dynamic_pointer_cast<RelCompound>(node);
1253  if (compound_node) {
1254  if (compound_node->hasDeliveredHint()) {
1255  hint_delivered = compound_node->getDeliveredHints();
1256  break;
1257  }
1258  }
1259  }
1260  if (hint_delivered && !hint_delivered->empty()) {
1261  dag_builder->registerQueryHints(hint_delivered);
1262  }
1263 }
Hints * getDeliveredHints()
Hints * getDeliveredHints()
void registerQueryHints(Hints *hints_delivered)
Hints * getDeliveredHints()
Hints * getDeliveredHints()
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:213
Hints * getDeliveredHints()

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1013 of file RelAlgDagBuilder.cpp.

References CHECK, and CHECK_GE.

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

1014  {
1015  CHECK(json_idx_arr.IsArray());
1016  std::vector<size_t> indices;
1017  for (auto json_idx_arr_it = json_idx_arr.Begin(); json_idx_arr_it != json_idx_arr.End();
1018  ++json_idx_arr_it) {
1019  CHECK(json_idx_arr_it->IsInt());
1020  CHECK_GE(json_idx_arr_it->GetInt(), 0);
1021  indices.emplace_back(json_idx_arr_it->GetInt());
1022  }
1023  return indices;
1024 }
#define CHECK_GE(x, y)
Definition: Logger.h:216
#define CHECK(condition)
Definition: Logger.h:203

+ 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 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:211
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:216
const RelAlgNode * getInput(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:213
virtual size_t size() const =0
#define CHECK(condition)
Definition: Logger.h:203

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

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

678  {
679  rapidjson::StringBuffer buffer;
680  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
681  node.Accept(writer);
682  return buffer.GetString();
683 }

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

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by RelAlgDagBuilder::build().

1265  {
1266  for (auto node : nodes) {
1267  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1268  if (!agg_node || agg_node->getAggExprsCount()) {
1269  continue;
1270  }
1271  CHECK_EQ(size_t(1), node->inputCount());
1272  const auto agg_input_node = dynamic_cast<const RelAggregate*>(node->getInput(0));
1273  if (agg_input_node && !agg_input_node->getAggExprsCount() &&
1274  agg_node->getGroupByCount() == agg_input_node->getGroupByCount()) {
1275  agg_node->markAsNop();
1276  }
1277  }
1278 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 96 of file RelAlgDagBuilder.cpp.

References i, and generate_TableFunctionsFactory_init::outputs.

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

References field(), and json_str().

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

673  {
674  const auto& id = field(ra_node, "id");
675  return std::stoi(json_str(id));
676 }
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 689 of file RelAlgDagBuilder.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

690  {
691  const auto& input = field(expr, "input");
692  return std::unique_ptr<RexAbstractInput>(new RexAbstractInput(json_i64(input)));
693 }
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 1026 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().

1026  {
1027  const auto agg = to_agg_kind(json_str(field(expr, "agg")));
1028  const auto distinct = json_bool(field(expr, "distinct"));
1029  const auto agg_ti = parse_type(field(expr, "type"));
1030  const auto operands = indices_from_json_array(field(expr, "operands"));
1031  if (operands.size() > 1 && (operands.size() != 2 || agg != kAPPROX_COUNT_DISTINCT)) {
1032  throw QueryNotSupported("Multiple arguments for aggregates aren't supported");
1033  }
1034  return std::unique_ptr<const RexAgg>(new RexAgg(agg, distinct, agg_ti, operands));
1035 }
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 979 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_scalar_expr().

981  {
982  const auto& operands = field(expr, "operands");
983  CHECK(operands.IsArray());
984  CHECK_GE(operands.Size(), unsigned(2));
985  std::unique_ptr<const RexScalar> else_expr;
986  std::vector<
987  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
988  expr_pair_list;
989  for (auto operands_it = operands.Begin(); operands_it != operands.End();) {
990  auto when_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
991  if (operands_it == operands.End()) {
992  else_expr = std::move(when_expr);
993  break;
994  }
995  auto then_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
996  expr_pair_list.emplace_back(std::move(when_expr), std::move(then_expr));
997  }
998  return std::unique_ptr<RexCase>(new RexCase(expr_pair_list, else_expr));
999 }
#define CHECK_GE(x, y)
Definition: Logger.h:216
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:203
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 800 of file RelAlgDagBuilder.cpp.

References parse_scalar_expr().

Referenced by parse_operator().

803  {
804  std::vector<std::unique_ptr<const RexScalar>> exprs;
805  for (auto it = arr.Begin(); it != arr.End(); ++it) {
806  exprs.emplace_back(parse_scalar_expr(*it, cat, root_dag_builder));
807  }
808  return exprs;
809 }
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 695 of file RelAlgDagBuilder.cpp.

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

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

695  {
696  CHECK(expr.IsObject());
697  const auto& literal = field(expr, "literal");
698  const auto type = to_sql_type(json_str(field(expr, "type")));
699  const auto target_type = to_sql_type(json_str(field(expr, "target_type")));
700  const auto scale = json_i64(field(expr, "scale"));
701  const auto precision = json_i64(field(expr, "precision"));
702  const auto type_scale = json_i64(field(expr, "type_scale"));
703  const auto type_precision = json_i64(field(expr, "type_precision"));
704  if (literal.IsNull()) {
705  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
706  }
707  switch (type) {
708  case kINT:
709  case kBIGINT:
710  case kDECIMAL:
711  case kINTERVAL_DAY_TIME:
713  case kTIME:
714  case kTIMESTAMP:
715  case kDATE:
716  return std::unique_ptr<RexLiteral>(new RexLiteral(json_i64(literal),
717  type,
718  target_type,
719  scale,
720  precision,
721  type_scale,
722  type_precision));
723  case kDOUBLE: {
724  if (literal.IsDouble()) {
725  return std::unique_ptr<RexLiteral>(new RexLiteral(json_double(literal),
726  type,
727  target_type,
728  scale,
729  precision,
730  type_scale,
731  type_precision));
732  } else if (literal.IsInt64()) {
733  return std::make_unique<RexLiteral>(static_cast<double>(literal.GetInt64()),
734  type,
735  target_type,
736  scale,
737  precision,
738  type_scale,
739  type_precision);
740 
741  } else if (literal.IsUint64()) {
742  return std::make_unique<RexLiteral>(static_cast<double>(literal.GetUint64()),
743  type,
744  target_type,
745  scale,
746  precision,
747  type_scale,
748  type_precision);
749  }
750  UNREACHABLE() << "Unhandled type: " << literal.GetType();
751  }
752  case kTEXT:
753  return std::unique_ptr<RexLiteral>(new RexLiteral(json_str(literal),
754  type,
755  target_type,
756  scale,
757  precision,
758  type_scale,
759  type_precision));
760  case kBOOLEAN:
761  return std::unique_ptr<RexLiteral>(new RexLiteral(json_bool(literal),
762  type,
763  target_type,
764  scale,
765  precision,
766  type_scale,
767  type_precision));
768  case kNULLT:
769  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
770  default:
771  CHECK(false);
772  }
773  CHECK(false);
774  return nullptr;
775 }
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
#define UNREACHABLE()
Definition: Logger.h:247
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:203
Definition: sqltypes.h:44

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

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

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

880  {
881  return json_str(field(collation, "nulls")) == std::string("FIRST")
884 }
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 933 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().

935  {
936  const auto op_name = json_str(field(expr, "op"));
937  const bool is_quantifier =
938  op_name == std::string("PG_ANY") || op_name == std::string("PG_ALL");
939  const auto op = is_quantifier ? kFUNCTION : to_sql_op(op_name);
940  const auto& operators_json_arr = field(expr, "operands");
941  CHECK(operators_json_arr.IsArray());
942  auto operands = parse_expr_array(operators_json_arr, cat, root_dag_builder);
943  const auto type_it = expr.FindMember("type");
944  CHECK(type_it != expr.MemberEnd());
945  auto ti = parse_type(type_it->value);
946  if (op == kIN && expr.HasMember("subquery")) {
947  auto subquery = parse_subquery(expr, cat, root_dag_builder);
948  operands.emplace_back(std::move(subquery));
949  }
950  if (expr.FindMember("partition_keys") != expr.MemberEnd()) {
951  const auto& partition_keys_arr = field(expr, "partition_keys");
952  auto partition_keys = parse_expr_array(partition_keys_arr, cat, root_dag_builder);
953  const auto& order_keys_arr = field(expr, "order_keys");
954  auto order_keys = parse_window_order_exprs(order_keys_arr, cat, root_dag_builder);
955  const auto collation =
956  parse_window_order_collation(order_keys_arr, cat, root_dag_builder);
957  const auto kind = parse_window_function_kind(op_name);
958  const auto lower_bound =
959  parse_window_bound(field(expr, "lower_bound"), cat, root_dag_builder);
960  const auto upper_bound =
961  parse_window_bound(field(expr, "upper_bound"), cat, root_dag_builder);
962  bool is_rows = json_bool(field(expr, "is_rows"));
963  ti.set_notnull(false);
964  return std::make_unique<RexWindowFunctionOperator>(kind,
965  operands,
966  partition_keys,
967  order_keys,
968  collation,
969  lower_bound,
970  upper_bound,
971  is_rows,
972  ti);
973  }
974  return std::unique_ptr<RexOperator>(op == kFUNCTION
975  ? new RexFunctionOperator(op_name, operands, ti)
976  : new RexOperator(op, operands, ti));
977 }
DEVICE auto upper_bound(ARGS &&...args)
Definition: gpu_enabled.h:123
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
RexWindowFunctionOperator::RexWindowBound parse_window_bound(const rapidjson::Value &window_bound_obj, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
std::vector< std::unique_ptr< const RexScalar > > parse_window_order_exprs(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
SqlWindowFunctionKind parse_window_function_kind(const std::string &name)
std::vector< std::unique_ptr< const RexScalar > > parse_expr_array(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::vector< SortField > parse_window_order_collation(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
SQLOps to_sql_op(const std::string &op_str)
DEVICE auto lower_bound(ARGS &&...args)
Definition: gpu_enabled.h:78
Definition: sqldefs.h:53
#define CHECK(condition)
Definition: Logger.h:203
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 1037 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().

1039  {
1040  CHECK(expr.IsObject());
1041  if (expr.IsObject() && expr.HasMember("input")) {
1042  return std::unique_ptr<const RexScalar>(parse_abstract_input(expr));
1043  }
1044  if (expr.IsObject() && expr.HasMember("literal")) {
1045  return std::unique_ptr<const RexScalar>(parse_literal(expr));
1046  }
1047  if (expr.IsObject() && expr.HasMember("op")) {
1048  const auto op_str = json_str(field(expr, "op"));
1049  if (op_str == std::string("CASE")) {
1050  return std::unique_ptr<const RexScalar>(parse_case(expr, cat, root_dag_builder));
1051  }
1052  if (op_str == std::string("$SCALAR_QUERY")) {
1053  return std::unique_ptr<const RexScalar>(
1054  parse_subquery(expr, cat, root_dag_builder));
1055  }
1056  return std::unique_ptr<const RexScalar>(parse_operator(expr, cat, root_dag_builder));
1057  }
1058  throw QueryNotSupported("Expression node " + json_node_to_string(expr) +
1059  " not supported");
1060 }
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:203
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 874 of file RelAlgDagBuilder.cpp.

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

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

874  {
875  return json_str(field(collation, "direction")) == std::string("DESCENDING")
878 }
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 919 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator(), and parse_scalar_expr().

921  {
922  const auto& operands = field(expr, "operands");
923  CHECK(operands.IsArray());
924  CHECK_GE(operands.Size(), unsigned(0));
925  const auto& subquery_ast = field(expr, "subquery");
926 
927  RelAlgDagBuilder subquery_dag(root_dag_builder, subquery_ast, cat, nullptr);
928  auto subquery = std::make_shared<RexSubQuery>(subquery_dag.getRootNodeShPtr());
929  root_dag_builder.registerSubquery(subquery);
930  return subquery->deepCopy();
931 }
#define CHECK_GE(x, y)
Definition: Logger.h:216
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:203

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

781  {
782  if (type_obj.IsArray()) {
783  throw QueryNotSupported("Composite types are not currently supported.");
784  }
785  CHECK(type_obj.IsObject() && type_obj.MemberCount() >= 2)
786  << json_node_to_string(type_obj);
787  const auto type = to_sql_type(json_str(field(type_obj, "type")));
788  const auto nullable = json_bool(field(type_obj, "nullable"));
789  const auto precision_it = type_obj.FindMember("precision");
790  const int precision =
791  precision_it != type_obj.MemberEnd() ? json_i64(precision_it->value) : 0;
792  const auto scale_it = type_obj.FindMember("scale");
793  const int scale = scale_it != type_obj.MemberEnd() ? json_i64(scale_it->value) : 0;
794  SQLTypeInfo ti(type, !nullable);
795  ti.set_precision(precision);
796  ti.set_scale(scale);
797  return ti;
798 }
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:203
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 899 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator().

902  {
903  CHECK(window_bound_obj.IsObject());
905  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
906  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
907  window_bound.following = json_bool(field(window_bound_obj, "following"));
908  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
909  const auto& offset_field = field(window_bound_obj, "offset");
910  if (offset_field.IsObject()) {
911  window_bound.offset = parse_scalar_expr(offset_field, cat, root_dag_builder);
912  } else {
913  CHECK(offset_field.IsNull());
914  }
915  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
916  return window_bound;
917 }
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:203
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 811 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().

811  {
812  if (name == "ROW_NUMBER") {
814  }
815  if (name == "RANK") {
817  }
818  if (name == "DENSE_RANK") {
820  }
821  if (name == "PERCENT_RANK") {
823  }
824  if (name == "CUME_DIST") {
826  }
827  if (name == "NTILE") {
829  }
830  if (name == "LAG") {
832  }
833  if (name == "LEAD") {
835  }
836  if (name == "FIRST_VALUE") {
838  }
839  if (name == "LAST_VALUE") {
841  }
842  if (name == "AVG") {
844  }
845  if (name == "MIN") {
847  }
848  if (name == "MAX") {
850  }
851  if (name == "SUM") {
853  }
854  if (name == "COUNT") {
856  }
857  if (name == "$SUM0") {
859  }
860  throw std::runtime_error("Unsupported window function: " + name);
861 }
string name
Definition: setup.in.py:72

+ Here is the caller graph for this function:

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

Definition at line 886 of file RelAlgDagBuilder.cpp.

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

888  {
889  std::vector<SortField> collation;
890  size_t field_idx = 0;
891  for (auto it = arr.Begin(); it != arr.End(); ++it, ++field_idx) {
892  const auto sort_dir = parse_sort_direction(*it);
893  const auto null_pos = parse_nulls_position(*it);
894  collation.emplace_back(field_idx, sort_dir, null_pos);
895  }
896  return collation;
897 }
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 863 of file RelAlgDagBuilder.cpp.

References field(), and parse_scalar_expr().

Referenced by parse_operator().

866  {
867  std::vector<std::unique_ptr<const RexScalar>> exprs;
868  for (auto it = arr.Begin(); it != arr.End(); ++it) {
869  exprs.emplace_back(parse_scalar_expr(field(*it, "field"), cat, root_dag_builder));
870  }
871  return exprs;
872 }
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 418 of file RelAlgDagBuilder.cpp.

References CHECK, and i.

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:203
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 1915 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

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

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

References CHECK.

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

1002  {
1003  CHECK(json_str_arr.IsArray());
1004  std::vector<std::string> fields;
1005  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
1006  ++json_str_arr_it) {
1007  CHECK(json_str_arr_it->IsString());
1008  fields.emplace_back(json_str_arr_it->GetString());
1009  }
1010  return fields;
1011 }
#define CHECK(condition)
Definition: Logger.h:203

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

References INNER, and LEFT.

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

1062  {
1063  if (join_type_name == "inner") {
1064  return JoinType::INNER;
1065  }
1066  if (join_type_name == "left") {
1067  return JoinType::LEFT;
1068  }
1069  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
1070 }

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