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

Namespaces

 anonymous_namespace{RelAlgDagBuilder.cpp}
 

Classes

class  RexRebindInputsVisitor
 
class  RexRebindReindexInputsVisitor
 
class  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, std::unordered_map< size_t, RegisteredQueryHint > &query_hints) noexcept
 
void coalesce_nodes (std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< const RelAlgNode * > &left_deep_joins, std::unordered_map< size_t, RegisteredQueryHint > &query_hints)
 
void propagate_hints_to_new_project (std::shared_ptr< RelProject > prev_node, std::shared_ptr< RelProject > new_node, std::unordered_map< size_t, RegisteredQueryHint > &query_hints)
 
void separate_window_function_expressions (std::vector< std::shared_ptr< RelAlgNode >> &nodes, std::unordered_map< size_t, RegisteredQueryHint > &query_hints)
 
void add_window_function_pre_project (std::vector< std::shared_ptr< RelAlgNode >> &nodes, const bool always_add_project_if_first_project_is_window_expr, std::unordered_map< size_t, RegisteredQueryHint > &query_hints)
 
int64_t get_int_literal_field (const rapidjson::Value &obj, const char field[], const int64_t default_val) noexcept
 
void check_empty_inputs_field (const rapidjson::Value &node) noexcept
 
const TableDescriptorgetTableFromScanNode (const Catalog_Namespace::Catalog &cat, const rapidjson::Value &scan_ra)
 
std::vector< std::string > getFieldNamesFromScanNode (const rapidjson::Value &scan_ra)
 

Variables

const unsigned FIRST_RA_NODE_ID = 1
 

Typedef Documentation

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

Definition at line 2068 of file RelAlgDagBuilder.cpp.

Function Documentation

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

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

Definition at line 2097 of file RelAlgDagBuilder.cpp.

References anonymous_namespace{Utm.h}::a, CHECK, CHECK_EQ, i, propagate_hints_to_new_project(), gpu_enabled::sort(), and RexVisitorBase< T >::visit().

Referenced by RelAlgDagBuilder::build().

2100  {
2101  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
2102  size_t project_node_counter{0};
2103  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
2104  const auto node = *node_itr;
2105 
2106  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
2107  if (!window_func_project_node) {
2108  continue;
2109  }
2110  project_node_counter++;
2111  if (!window_func_project_node->hasWindowFunctionExpr()) {
2112  // this projection node does not have a window function
2113  // expression -- skip to the next node in the DAG.
2114  continue;
2115  }
2116 
2117  const auto prev_node_itr = std::prev(node_itr);
2118  const auto prev_node = *prev_node_itr;
2119  CHECK(prev_node);
2120 
2121  auto filter_node = std::dynamic_pointer_cast<RelFilter>(prev_node);
2122 
2123  auto scan_node = std::dynamic_pointer_cast<RelScan>(prev_node);
2124  const bool has_multi_fragment_scan_input =
2125  (scan_node && (scan_node->getNumShards() > 0 || scan_node->getNumFragments() > 1))
2126  ? true
2127  : false;
2128 
2129  // We currently add a preceding project node in one of two conditions:
2130  // 1. always_add_project_if_first_project_is_window_expr = true, which
2131  // we currently only set for distributed, but could also be set to support
2132  // multi-frag window function inputs, either if we can detect that an input table
2133  // is multi-frag up front, or using a retry mechanism like we do for join filter
2134  // push down.
2135  // TODO(todd): Investigate a viable approach for the above.
2136  // 2. Regardless of #1, if the window function project node is preceded by a
2137  // filter node. This is required both for correctness and to avoid pulling
2138  // all source input columns into memory since non-coalesced filter node
2139  // inputs are currently not pruned or eliminated via dead column elimination.
2140  // Note that we expect any filter node followed by a project node to be coalesced
2141  // into a single compound node in RelAlgDagBuilder::coalesce_nodes, and that action
2142  // prunes unused inputs.
2143  // TODO(todd): Investigate whether the shotgun filter node issue affects other
2144  // query plans, i.e. filters before joins, and whether there is a more general
2145  // approach to solving this (will still need the preceding project node for
2146  // window functions preceded by filter nodes for correctness though)
2147 
2148  if (!((always_add_project_if_first_project_is_window_expr &&
2149  project_node_counter == 1) ||
2150  filter_node || has_multi_fragment_scan_input)) {
2151  continue;
2152  }
2153 
2154  RexInputSet inputs;
2155  RexInputCollector input_collector;
2156  for (size_t i = 0; i < window_func_project_node->size(); i++) {
2157  auto new_inputs = input_collector.visit(window_func_project_node->getProjectAt(i));
2158  inputs.insert(new_inputs.begin(), new_inputs.end());
2159  }
2160 
2161  // Note: Technically not required since we are mapping old inputs to new input
2162  // indices, but makes the re-mapping of inputs easier to follow.
2163  std::vector<RexInput> sorted_inputs(inputs.begin(), inputs.end());
2164  std::sort(sorted_inputs.begin(),
2165  sorted_inputs.end(),
2166  [](const auto& a, const auto& b) { return a.getIndex() < b.getIndex(); });
2167 
2168  std::vector<std::unique_ptr<const RexScalar>> scalar_exprs;
2169  std::vector<std::string> fields;
2170  std::unordered_map<unsigned, unsigned> old_index_to_new_index;
2171  for (auto& input : sorted_inputs) {
2172  CHECK_EQ(input.getSourceNode(), prev_node.get());
2173  CHECK(old_index_to_new_index
2174  .insert(std::make_pair(input.getIndex(), scalar_exprs.size()))
2175  .second);
2176  scalar_exprs.emplace_back(input.deepCopy());
2177  fields.emplace_back("");
2178  }
2179 
2180  auto new_project = std::make_shared<RelProject>(scalar_exprs, fields, prev_node);
2181  propagate_hints_to_new_project(window_func_project_node, new_project, query_hints);
2182  node_list.insert(node_itr, new_project);
2183  window_func_project_node->replaceInput(
2184  prev_node, new_project, old_index_to_new_index);
2185  }
2186 
2187  nodes.assign(node_list.begin(), node_list.end());
2188 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
constexpr double a
Definition: Utm.h:38
std::unordered_set< RexInput > RexInputSet
void propagate_hints_to_new_project(std::shared_ptr< RelProject > prev_node, std::shared_ptr< RelProject > new_node, std::unordered_map< size_t, RegisteredQueryHint > &query_hints)
#define CHECK(condition)
Definition: Logger.h:209

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

1198  {
1199  for (auto ra_node : nodes) {
1200  const auto filter_node = std::dynamic_pointer_cast<RelFilter>(ra_node);
1201  if (filter_node) {
1202  CHECK_EQ(size_t(1), filter_node->inputCount());
1203  auto disambiguated_condition = disambiguate_rex(
1204  filter_node->getCondition(), get_node_output(filter_node->getInput(0)));
1205  filter_node->setCondition(disambiguated_condition);
1206  continue;
1207  }
1208  const auto join_node = std::dynamic_pointer_cast<RelJoin>(ra_node);
1209  if (join_node) {
1210  CHECK_EQ(size_t(2), join_node->inputCount());
1211  auto disambiguated_condition =
1212  disambiguate_rex(join_node->getCondition(), get_node_output(join_node.get()));
1213  join_node->setCondition(disambiguated_condition);
1214  continue;
1215  }
1216  const auto project_node = std::dynamic_pointer_cast<RelProject>(ra_node);
1217  if (project_node) {
1218  bind_project_to_input(project_node.get(),
1219  get_node_output(project_node->getInput(0)));
1220  continue;
1221  }
1222  const auto table_func_node = std::dynamic_pointer_cast<RelTableFunction>(ra_node);
1223  if (table_func_node) {
1224  /*
1225  Collect all inputs from table function input (non-literal)
1226  arguments.
1227  */
1228  RANodeOutput input;
1229  input.reserve(table_func_node->inputCount());
1230  for (size_t i = 0; i < table_func_node->inputCount(); i++) {
1231  auto node_output = get_node_output(table_func_node->getInput(i));
1232  input.insert(input.end(), node_output.begin(), node_output.end());
1233  }
1234  bind_table_func_to_input(table_func_node.get(), input);
1235  }
1236  }
1237 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
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 1170 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, disambiguate_rex(), and i.

Referenced by bind_inputs(), and create_compound().

1170  {
1171  CHECK_EQ(size_t(1), project_node->inputCount());
1172  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1173  for (size_t i = 0; i < project_node->size(); ++i) {
1174  const auto projected_expr = project_node->getProjectAt(i);
1175  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
1176  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
1177  } else {
1178  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
1179  }
1180  }
1181  project_node->setExpressions(disambiguated_exprs);
1182 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
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 1184 of file RelAlgDagBuilder.cpp.

References disambiguate_rex(), and i.

Referenced by bind_inputs().

1185  {
1186  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
1187  for (size_t i = 0; i < table_func_node->getTableFuncInputsSize(); ++i) {
1188  const auto target_expr = table_func_node->getTableFuncInputAt(i);
1189  if (dynamic_cast<const RexSubQuery*>(target_expr)) {
1190  disambiguated_exprs.emplace_back(table_func_node->getTableFuncInputAtAndRelease(i));
1191  } else {
1192  disambiguated_exprs.emplace_back(disambiguate_rex(target_expr, input));
1193  }
1194  }
1195  table_func_node->setTableFuncInputs(disambiguated_exprs);
1196 }
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 2204 of file RelAlgDagBuilder.cpp.

References CHECK, and field().

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

2204  {
2205  const auto& inputs_json = field(node, "inputs");
2206  CHECK(inputs_json.IsArray() && !inputs_json.Size());
2207 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:209

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

1649  {
1650  enum class CoalesceState { Initial, Filter, FirstProject, Aggregate };
1651  std::vector<size_t> crt_pattern;
1652  CoalesceState crt_state{CoalesceState::Initial};
1653 
1654  auto reset_state = [&crt_pattern, &crt_state]() {
1655  crt_state = CoalesceState::Initial;
1656  std::vector<size_t>().swap(crt_pattern);
1657  };
1658 
1659  for (RANodeIterator nodeIt(nodes); !nodeIt.allVisited();) {
1660  const auto ra_node = nodeIt != nodes.end() ? *nodeIt : nullptr;
1661  switch (crt_state) {
1662  case CoalesceState::Initial: {
1663  if (std::dynamic_pointer_cast<const RelFilter>(ra_node) &&
1664  std::find(left_deep_joins.begin(), left_deep_joins.end(), ra_node.get()) ==
1665  left_deep_joins.end()) {
1666  crt_pattern.push_back(size_t(nodeIt));
1667  crt_state = CoalesceState::Filter;
1668  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1669  } else if (auto project_node =
1670  std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1671  if (project_node->hasWindowFunctionExpr()) {
1672  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1673  } else {
1674  crt_pattern.push_back(size_t(nodeIt));
1675  crt_state = CoalesceState::FirstProject;
1676  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1677  }
1678  } else {
1679  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1680  }
1681  break;
1682  }
1683  case CoalesceState::Filter: {
1684  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1685  // Given we now add preceding projects for all window functions following
1686  // RelFilter nodes, the following should never occur
1687  CHECK(!project_node->hasWindowFunctionExpr());
1688  crt_pattern.push_back(size_t(nodeIt));
1689  crt_state = CoalesceState::FirstProject;
1690  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1691  } else {
1692  reset_state();
1693  }
1694  break;
1695  }
1696  case CoalesceState::FirstProject: {
1697  if (std::dynamic_pointer_cast<const RelAggregate>(ra_node)) {
1698  crt_pattern.push_back(size_t(nodeIt));
1699  crt_state = CoalesceState::Aggregate;
1700  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1701  } else {
1702  if (crt_pattern.size() >= 2) {
1703  create_compound(nodes, crt_pattern, query_hints);
1704  }
1705  reset_state();
1706  }
1707  break;
1708  }
1709  case CoalesceState::Aggregate: {
1710  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1711  if (!project_node->hasWindowFunctionExpr()) {
1712  // TODO(adb): overloading the simple project terminology again here
1713  bool is_simple_project{true};
1714  for (size_t i = 0; i < project_node->size(); i++) {
1715  const auto scalar_rex = project_node->getProjectAt(i);
1716  // If the top level scalar rex is an input node, we can bypass the visitor
1717  if (auto input_rex = dynamic_cast<const RexInput*>(scalar_rex)) {
1719  input_rex->getSourceNode(), input_rex->getIndex(), true)) {
1720  is_simple_project = false;
1721  break;
1722  }
1723  continue;
1724  }
1725  CoalesceSecondaryProjectVisitor visitor;
1726  if (!visitor.visit(project_node->getProjectAt(i))) {
1727  is_simple_project = false;
1728  break;
1729  }
1730  }
1731  if (is_simple_project) {
1732  crt_pattern.push_back(size_t(nodeIt));
1733  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1734  }
1735  }
1736  }
1737  CHECK_GE(crt_pattern.size(), size_t(2));
1738  create_compound(nodes, crt_pattern, query_hints);
1739  reset_state();
1740  break;
1741  }
1742  default:
1743  CHECK(false);
1744  }
1745  }
1746  if (crt_state == CoalesceState::FirstProject || crt_state == CoalesceState::Aggregate) {
1747  if (crt_pattern.size() >= 2) {
1748  create_compound(nodes, crt_pattern, query_hints);
1749  }
1750  CHECK(!crt_pattern.empty());
1751  }
1752 }
void create_compound(std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< size_t > &pattern, std::unordered_map< size_t, RegisteredQueryHint > &query_hints) noexcept
#define CHECK_GE(x, y)
Definition: Logger.h:222
#define CHECK(condition)
Definition: Logger.h:209
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,
std::unordered_map< size_t, RegisteredQueryHint > &  query_hints 
)
noexcept

Definition at line 1330 of file RelAlgDagBuilder.cpp.

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

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

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

Referenced by disambiguate_rex().

1129  {
1130  std::vector<
1131  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
1132  disambiguated_expr_pair_list;
1133  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
1134  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
1135  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
1136  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
1137  std::move(disambiguated_then));
1138  }
1139  std::unique_ptr<const RexScalar> disambiguated_else{
1140  disambiguate_rex(rex_case->getElse(), ra_output)};
1141  return std::unique_ptr<const RexCase>(
1142  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
1143 }
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 1093 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

1095  {
1096  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
1097  for (size_t i = 0; i < rex_operator->size(); ++i) {
1098  auto operand = rex_operator->getOperand(i);
1099  if (dynamic_cast<const RexSubQuery*>(operand)) {
1100  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
1101  } else {
1102  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
1103  }
1104  }
1105  const auto rex_window_function_operator =
1106  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
1107  if (rex_window_function_operator) {
1108  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
1109  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
1110  for (const auto& partition_key : partition_keys) {
1111  disambiguated_partition_keys.emplace_back(
1112  disambiguate_rex(partition_key.get(), ra_output));
1113  }
1114  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
1115  const auto& order_keys = rex_window_function_operator->getOrderKeys();
1116  for (const auto& order_key : order_keys) {
1117  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
1118  }
1119  return rex_window_function_operator->disambiguatedOperands(
1120  disambiguated_operands,
1121  disambiguated_partition_keys,
1122  disambiguated_order_keys,
1123  rex_window_function_operator->getCollation());
1124  }
1125  return rex_operator->getDisambiguated(disambiguated_operands);
1126 }
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 1149 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().

1150  {
1151  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
1152  if (rex_abstract_input) {
1153  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
1154  return std::unique_ptr<const RexInput>(
1155  new RexInput(ra_output[rex_abstract_input->getIndex()]));
1156  }
1157  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
1158  if (rex_operator) {
1159  return disambiguate_operator(rex_operator, ra_output);
1160  }
1161  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
1162  if (rex_case) {
1163  return disambiguate_case(rex_case, ra_output);
1164  }
1165  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
1166  CHECK(rex_literal);
1167  return std::unique_ptr<const RexLiteral>(new RexLiteral(*rex_literal));
1168 }
#define CHECK_LT(x, y)
Definition: Logger.h:219
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:209

+ 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:217
#define CHECK(condition)
Definition: Logger.h:209

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

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

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

2192  {
2193  const auto it = obj.FindMember(field);
2194  if (it == obj.MemberEnd()) {
2195  return default_val;
2196  }
2197  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
2198  CHECK_EQ(kDECIMAL, lit->getType());
2199  CHECK_EQ(unsigned(0), lit->getScale());
2200  CHECK_EQ(unsigned(0), lit->getTargetScale());
2201  return lit->getVal<int64_t>();
2202 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
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 2219 of file RelAlgDagBuilder.cpp.

References field(), and strings_from_json_array().

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

2219  {
2220  const auto& fields_json = field(scan_ra, "fieldNames");
2221  return strings_from_json_array(fields_json);
2222 }
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 2209 of file RelAlgDagBuilder.cpp.

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

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

2210  {
2211  const auto& table_json = field(scan_ra, "table");
2212  CHECK(table_json.IsArray());
2213  CHECK_EQ(unsigned(2), table_json.Size());
2214  const auto td = cat.getMetadataForTable(table_json[1].GetString());
2215  CHECK(td);
2216  return td;
2217 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:209
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 1239 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

1240  {
1241  // query hint is delivered by the above three nodes
1242  // when a query block has top-sort node, a hint is registered to
1243  // one of the node which locates at the nearest from the sort node
1244  for (auto node : nodes) {
1245  Hints* hint_delivered = nullptr;
1246  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1247  if (agg_node) {
1248  if (agg_node->hasDeliveredHint()) {
1249  hint_delivered = agg_node->getDeliveredHints();
1250  }
1251  }
1252  const auto project_node = std::dynamic_pointer_cast<RelProject>(node);
1253  if (project_node) {
1254  if (project_node->hasDeliveredHint()) {
1255  hint_delivered = project_node->getDeliveredHints();
1256  }
1257  }
1258  const auto compound_node = std::dynamic_pointer_cast<RelCompound>(node);
1259  if (compound_node) {
1260  if (compound_node->hasDeliveredHint()) {
1261  hint_delivered = compound_node->getDeliveredHints();
1262  }
1263  }
1264  if (hint_delivered && !hint_delivered->empty()) {
1265  dag_builder->registerQueryHints(node, hint_delivered);
1266  }
1267  }
1268 }
Hints * getDeliveredHints()
void registerQueryHints(std::shared_ptr< RelAlgNode > node, Hints *hints_delivered)
Hints * getDeliveredHints()
Hints * getDeliveredHints()
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:225

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

References CHECK, and CHECK_GE.

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

1022  {
1023  CHECK(json_idx_arr.IsArray());
1024  std::vector<size_t> indices;
1025  for (auto json_idx_arr_it = json_idx_arr.Begin(); json_idx_arr_it != json_idx_arr.End();
1026  ++json_idx_arr_it) {
1027  CHECK(json_idx_arr_it->IsInt());
1028  CHECK_GE(json_idx_arr_it->GetInt(), 0);
1029  indices.emplace_back(json_idx_arr_it->GetInt());
1030  }
1031  return indices;
1032 }
#define CHECK_GE(x, y)
Definition: Logger.h:222
#define CHECK(condition)
Definition: Logger.h:209

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

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

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

686  {
687  rapidjson::StringBuffer buffer;
688  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
689  node.Accept(writer);
690  return buffer.GetString();
691 }

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

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by RelAlgDagBuilder::build().

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

+ 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 anonymous_namespace{Utm.h}::n.

Referenced by get_node_output().

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

+ Here is the caller graph for this function:

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

Definition at line 681 of file RelAlgDagBuilder.cpp.

References field(), and json_str().

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

681  {
682  const auto& id = field(ra_node, "id");
683  return std::stoi(json_str(id));
684 }
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 697 of file RelAlgDagBuilder.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

698  {
699  const auto& input = field(expr, "input");
700  return std::unique_ptr<RexAbstractInput>(new RexAbstractInput(json_i64(input)));
701 }
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 1034 of file RelAlgDagBuilder.cpp.

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

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

1034  {
1035  const auto agg_str = json_str(field(expr, "agg"));
1036  if (agg_str == "APPROX_QUANTILE") {
1037  LOG(INFO) << "APPROX_QUANTILE is deprecated. Please use APPROX_PERCENTILE instead.";
1038  }
1039  const auto agg = to_agg_kind(agg_str);
1040  const auto distinct = json_bool(field(expr, "distinct"));
1041  const auto agg_ti = parse_type(field(expr, "type"));
1042  const auto operands = indices_from_json_array(field(expr, "operands"));
1043  if (operands.size() > 1 && (operands.size() != 2 || (agg != kAPPROX_COUNT_DISTINCT &&
1044  agg != kAPPROX_QUANTILE))) {
1045  throw QueryNotSupported("Multiple arguments for aggregates aren't supported");
1046  }
1047  return std::unique_ptr<const RexAgg>(new RexAgg(agg, distinct, agg_ti, operands));
1048 }
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
SQLAgg to_agg_kind(const std::string &agg_name)
#define LOG(tag)
Definition: Logger.h:203
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 987 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_scalar_expr().

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

References parse_scalar_expr().

Referenced by parse_operator().

811  {
812  std::vector<std::unique_ptr<const RexScalar>> exprs;
813  for (auto it = arr.Begin(); it != arr.End(); ++it) {
814  exprs.emplace_back(parse_scalar_expr(*it, cat, root_dag_builder));
815  }
816  return exprs;
817 }
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 703 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().

703  {
704  CHECK(expr.IsObject());
705  const auto& literal = field(expr, "literal");
706  const auto type = to_sql_type(json_str(field(expr, "type")));
707  const auto target_type = to_sql_type(json_str(field(expr, "target_type")));
708  const auto scale = json_i64(field(expr, "scale"));
709  const auto precision = json_i64(field(expr, "precision"));
710  const auto type_scale = json_i64(field(expr, "type_scale"));
711  const auto type_precision = json_i64(field(expr, "type_precision"));
712  if (literal.IsNull()) {
713  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
714  }
715  switch (type) {
716  case kINT:
717  case kBIGINT:
718  case kDECIMAL:
719  case kINTERVAL_DAY_TIME:
721  case kTIME:
722  case kTIMESTAMP:
723  case kDATE:
724  return std::unique_ptr<RexLiteral>(new RexLiteral(json_i64(literal),
725  type,
726  target_type,
727  scale,
728  precision,
729  type_scale,
730  type_precision));
731  case kDOUBLE: {
732  if (literal.IsDouble()) {
733  return std::unique_ptr<RexLiteral>(new RexLiteral(json_double(literal),
734  type,
735  target_type,
736  scale,
737  precision,
738  type_scale,
739  type_precision));
740  } else if (literal.IsInt64()) {
741  return std::make_unique<RexLiteral>(static_cast<double>(literal.GetInt64()),
742  type,
743  target_type,
744  scale,
745  precision,
746  type_scale,
747  type_precision);
748 
749  } else if (literal.IsUint64()) {
750  return std::make_unique<RexLiteral>(static_cast<double>(literal.GetUint64()),
751  type,
752  target_type,
753  scale,
754  precision,
755  type_scale,
756  type_precision);
757  }
758  UNREACHABLE() << "Unhandled type: " << literal.GetType();
759  }
760  case kTEXT:
761  return std::unique_ptr<RexLiteral>(new RexLiteral(json_str(literal),
762  type,
763  target_type,
764  scale,
765  precision,
766  type_scale,
767  type_precision));
768  case kBOOLEAN:
769  return std::unique_ptr<RexLiteral>(new RexLiteral(json_bool(literal),
770  type,
771  target_type,
772  scale,
773  precision,
774  type_scale,
775  type_precision));
776  case kNULLT:
777  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
778  default:
779  CHECK(false);
780  }
781  CHECK(false);
782  return nullptr;
783 }
SQLTypes to_sql_type(const std::string &type_name)
Definition: sqltypes.h:49
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
#define UNREACHABLE()
Definition: Logger.h:253
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
const double json_double(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:54
Definition: sqltypes.h:52
Definition: sqltypes.h:53
#define CHECK(condition)
Definition: Logger.h:209
Definition: sqltypes.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 888 of file RelAlgDagBuilder.cpp.

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

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

888  {
889  return json_str(field(collation, "nulls")) == std::string("FIRST")
892 }
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 941 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().

943  {
944  const auto op_name = json_str(field(expr, "op"));
945  const bool is_quantifier =
946  op_name == std::string("PG_ANY") || op_name == std::string("PG_ALL");
947  const auto op = is_quantifier ? kFUNCTION : to_sql_op(op_name);
948  const auto& operators_json_arr = field(expr, "operands");
949  CHECK(operators_json_arr.IsArray());
950  auto operands = parse_expr_array(operators_json_arr, cat, root_dag_builder);
951  const auto type_it = expr.FindMember("type");
952  CHECK(type_it != expr.MemberEnd());
953  auto ti = parse_type(type_it->value);
954  if (op == kIN && expr.HasMember("subquery")) {
955  auto subquery = parse_subquery(expr, cat, root_dag_builder);
956  operands.emplace_back(std::move(subquery));
957  }
958  if (expr.FindMember("partition_keys") != expr.MemberEnd()) {
959  const auto& partition_keys_arr = field(expr, "partition_keys");
960  auto partition_keys = parse_expr_array(partition_keys_arr, cat, root_dag_builder);
961  const auto& order_keys_arr = field(expr, "order_keys");
962  auto order_keys = parse_window_order_exprs(order_keys_arr, cat, root_dag_builder);
963  const auto collation =
964  parse_window_order_collation(order_keys_arr, cat, root_dag_builder);
965  const auto kind = parse_window_function_kind(op_name);
966  const auto lower_bound =
967  parse_window_bound(field(expr, "lower_bound"), cat, root_dag_builder);
968  const auto upper_bound =
969  parse_window_bound(field(expr, "upper_bound"), cat, root_dag_builder);
970  bool is_rows = json_bool(field(expr, "is_rows"));
971  ti.set_notnull(false);
972  return std::make_unique<RexWindowFunctionOperator>(kind,
973  operands,
974  partition_keys,
975  order_keys,
976  collation,
977  lower_bound,
978  upper_bound,
979  is_rows,
980  ti);
981  }
982  return std::unique_ptr<RexOperator>(op == kFUNCTION
983  ? new RexFunctionOperator(op_name, operands, ti)
984  : new RexOperator(op, operands, ti));
985 }
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:209
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 1050 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().

1052  {
1053  CHECK(expr.IsObject());
1054  if (expr.IsObject() && expr.HasMember("input")) {
1055  return std::unique_ptr<const RexScalar>(parse_abstract_input(expr));
1056  }
1057  if (expr.IsObject() && expr.HasMember("literal")) {
1058  return std::unique_ptr<const RexScalar>(parse_literal(expr));
1059  }
1060  if (expr.IsObject() && expr.HasMember("op")) {
1061  const auto op_str = json_str(field(expr, "op"));
1062  if (op_str == std::string("CASE")) {
1063  return std::unique_ptr<const RexScalar>(parse_case(expr, cat, root_dag_builder));
1064  }
1065  if (op_str == std::string("$SCALAR_QUERY")) {
1066  return std::unique_ptr<const RexScalar>(
1067  parse_subquery(expr, cat, root_dag_builder));
1068  }
1069  return std::unique_ptr<const RexScalar>(parse_operator(expr, cat, root_dag_builder));
1070  }
1071  throw QueryNotSupported("Expression node " + json_node_to_string(expr) +
1072  " not supported");
1073 }
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:209
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 882 of file RelAlgDagBuilder.cpp.

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

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

882  {
883  return json_str(field(collation, "direction")) == std::string("DESCENDING")
886 }
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 927 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator(), and parse_scalar_expr().

929  {
930  const auto& operands = field(expr, "operands");
931  CHECK(operands.IsArray());
932  CHECK_GE(operands.Size(), unsigned(0));
933  const auto& subquery_ast = field(expr, "subquery");
934 
935  RelAlgDagBuilder subquery_dag(root_dag_builder, subquery_ast, cat, nullptr);
936  auto subquery = std::make_shared<RexSubQuery>(subquery_dag.getRootNodeShPtr());
937  root_dag_builder.registerSubquery(subquery);
938  return subquery->deepCopy();
939 }
#define CHECK_GE(x, y)
Definition: Logger.h:222
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:209

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

789  {
790  if (type_obj.IsArray()) {
791  throw QueryNotSupported("Composite types are not currently supported.");
792  }
793  CHECK(type_obj.IsObject() && type_obj.MemberCount() >= 2)
794  << json_node_to_string(type_obj);
795  const auto type = to_sql_type(json_str(field(type_obj, "type")));
796  const auto nullable = json_bool(field(type_obj, "nullable"));
797  const auto precision_it = type_obj.FindMember("precision");
798  const int precision =
799  precision_it != type_obj.MemberEnd() ? json_i64(precision_it->value) : 0;
800  const auto scale_it = type_obj.FindMember("scale");
801  const int scale = scale_it != type_obj.MemberEnd() ? json_i64(scale_it->value) : 0;
802  SQLTypeInfo ti(type, !nullable);
803  ti.set_precision(precision);
804  ti.set_scale(scale);
805  return ti;
806 }
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:209
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 907 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator().

910  {
911  CHECK(window_bound_obj.IsObject());
913  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
914  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
915  window_bound.following = json_bool(field(window_bound_obj, "following"));
916  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
917  const auto& offset_field = field(window_bound_obj, "offset");
918  if (offset_field.IsObject()) {
919  window_bound.offset = parse_scalar_expr(offset_field, cat, root_dag_builder);
920  } else {
921  CHECK(offset_field.IsNull());
922  }
923  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
924  return window_bound;
925 }
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:209
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 819 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().

819  {
820  if (name == "ROW_NUMBER") {
822  }
823  if (name == "RANK") {
825  }
826  if (name == "DENSE_RANK") {
828  }
829  if (name == "PERCENT_RANK") {
831  }
832  if (name == "CUME_DIST") {
834  }
835  if (name == "NTILE") {
837  }
838  if (name == "LAG") {
840  }
841  if (name == "LEAD") {
843  }
844  if (name == "FIRST_VALUE") {
846  }
847  if (name == "LAST_VALUE") {
849  }
850  if (name == "AVG") {
852  }
853  if (name == "MIN") {
855  }
856  if (name == "MAX") {
858  }
859  if (name == "SUM") {
861  }
862  if (name == "COUNT") {
864  }
865  if (name == "$SUM0") {
867  }
868  throw std::runtime_error("Unsupported window function: " + name);
869 }
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 894 of file RelAlgDagBuilder.cpp.

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

896  {
897  std::vector<SortField> collation;
898  size_t field_idx = 0;
899  for (auto it = arr.Begin(); it != arr.End(); ++it, ++field_idx) {
900  const auto sort_dir = parse_sort_direction(*it);
901  const auto null_pos = parse_nulls_position(*it);
902  collation.emplace_back(field_idx, sort_dir, null_pos);
903  }
904  return collation;
905 }
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 871 of file RelAlgDagBuilder.cpp.

References field(), and parse_scalar_expr().

Referenced by parse_operator().

874  {
875  std::vector<std::unique_ptr<const RexScalar>> exprs;
876  for (auto it = arr.Begin(); it != arr.End(); ++it) {
877  exprs.emplace_back(parse_scalar_expr(field(*it, "field"), cat, root_dag_builder));
878  }
879  return exprs;
880 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1928 of file RelAlgDagBuilder.cpp.

References CHECK.

Referenced by add_window_function_pre_project(), and separate_window_function_expressions().

1931  {
1932  auto delivered_hints = prev_node->getDeliveredHints();
1933  bool needs_propagate_hints = !delivered_hints->empty();
1934  if (needs_propagate_hints) {
1935  for (auto& kv : *delivered_hints) {
1936  new_node->addHint(kv.second);
1937  }
1938  auto prev_it = query_hints.find(prev_node->toHash());
1939  // query hint for the prev projection node should be registered
1940  CHECK(prev_it != query_hints.end());
1941  query_hints.emplace(new_node->toHash(), prev_it->second);
1942  }
1943 }
#define CHECK(condition)
Definition: Logger.h:209

+ 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:209
void anonymous_namespace{RelAlgDagBuilder.cpp}::separate_window_function_expressions ( std::vector< std::shared_ptr< RelAlgNode >> &  nodes,
std::unordered_map< size_t, RegisteredQueryHint > &  query_hints 
)

Detect the presence of window function operators nested inside expressions. Separate the window function operator from the expression, computing the expression as a subsequent step 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 1960 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(), propagate_hints_to_new_project(), and RexVisitorBase< T >::visit().

Referenced by RelAlgDagBuilder::build().

1962  {
1963  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
1964 
1965  WindowFunctionDetectionVisitor visitor;
1966  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
1967  const auto node = *node_itr;
1968  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
1969  if (!window_func_project_node) {
1970  continue;
1971  }
1972 
1973  // map scalar expression index in the project node to window function ptr
1974  std::unordered_map<size_t, const RexScalar*> embedded_window_function_expressions;
1975 
1976  // Iterate the target exprs of the project node and check for window function
1977  // expressions. If an embedded expression exists, save it in the
1978  // embedded_window_function_expressions map and split the expression into a window
1979  // function expression and a parent expression in a subsequent project node
1980  for (size_t i = 0; i < window_func_project_node->size(); i++) {
1981  const auto scalar_rex = window_func_project_node->getProjectAt(i);
1982  if (is_window_function_operator(scalar_rex)) {
1983  // top level window function exprs are fine
1984  continue;
1985  }
1986 
1987  if (const auto window_func_rex = visitor.visit(scalar_rex)) {
1988  const auto ret = embedded_window_function_expressions.insert(
1989  std::make_pair(i, window_func_rex));
1990  CHECK(ret.second);
1991  }
1992  }
1993 
1994  if (!embedded_window_function_expressions.empty()) {
1995  std::vector<std::unique_ptr<const RexScalar>> new_scalar_exprs;
1996 
1997  auto window_func_scalar_exprs =
1998  window_func_project_node->getExpressionsAndRelease();
1999  for (size_t rex_idx = 0; rex_idx < window_func_scalar_exprs.size(); ++rex_idx) {
2000  const auto embedded_window_func_expr_pair =
2001  embedded_window_function_expressions.find(rex_idx);
2002  if (embedded_window_func_expr_pair ==
2003  embedded_window_function_expressions.end()) {
2004  new_scalar_exprs.emplace_back(
2005  std::make_unique<const RexInput>(window_func_project_node.get(), rex_idx));
2006  } else {
2007  const auto window_func_rex_idx = embedded_window_func_expr_pair->first;
2008  CHECK_LT(window_func_rex_idx, window_func_scalar_exprs.size());
2009 
2010  const auto& window_func_rex = embedded_window_func_expr_pair->second;
2011 
2012  RexDeepCopyVisitor copier;
2013  auto window_func_rex_copy = copier.visit(window_func_rex);
2014 
2015  auto window_func_parent_expr =
2016  window_func_scalar_exprs[window_func_rex_idx].get();
2017 
2018  // Replace window func rex with an input rex
2019  auto window_func_result_input = std::make_unique<const RexInput>(
2020  window_func_project_node.get(), window_func_rex_idx);
2021  RexWindowFuncReplacementVisitor replacer(std::move(window_func_result_input));
2022  auto new_parent_rex = replacer.visit(window_func_parent_expr);
2023 
2024  // Put the parent expr in the new scalar exprs
2025  new_scalar_exprs.emplace_back(std::move(new_parent_rex));
2026 
2027  // Put the window func expr in cur scalar exprs
2028  window_func_scalar_exprs[window_func_rex_idx] = std::move(window_func_rex_copy);
2029  }
2030  }
2031 
2032  CHECK_EQ(window_func_scalar_exprs.size(), new_scalar_exprs.size());
2033  window_func_project_node->setExpressions(window_func_scalar_exprs);
2034 
2035  // Ensure any inputs from the node containing the expression (the "new" node)
2036  // exist on the window function project node, e.g. if we had a binary operation
2037  // involving an aggregate value or column not included in the top level
2038  // projection list.
2039  RexInputBackpropagationVisitor input_visitor(window_func_project_node.get());
2040  for (size_t i = 0; i < new_scalar_exprs.size(); i++) {
2041  if (dynamic_cast<const RexInput*>(new_scalar_exprs[i].get())) {
2042  // ignore top level inputs, these were copied directly from the previous
2043  // node
2044  continue;
2045  }
2046  new_scalar_exprs[i] = input_visitor.visit(new_scalar_exprs[i].get());
2047  }
2048 
2049  // Build the new project node and insert it into the list after the project node
2050  // containing the window function
2051  auto new_project =
2052  std::make_shared<RelProject>(new_scalar_exprs,
2053  window_func_project_node->getFields(),
2054  window_func_project_node);
2055  propagate_hints_to_new_project(window_func_project_node, new_project, query_hints);
2056  node_list.insert(std::next(node_itr), new_project);
2057 
2058  // Rebind all the following inputs
2059  for (auto rebind_itr = std::next(node_itr, 2); rebind_itr != node_list.end();
2060  rebind_itr++) {
2061  (*rebind_itr)->replaceInput(window_func_project_node, new_project);
2062  }
2063  }
2064  }
2065  nodes.assign(node_list.begin(), node_list.end());
2066 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
void propagate_hints_to_new_project(std::shared_ptr< RelProject > prev_node, std::shared_ptr< RelProject > new_node, std::unordered_map< size_t, RegisteredQueryHint > &query_hints)
const RexScalar * getProjectAt(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:219
#define CHECK(condition)
Definition: Logger.h:209

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

References CHECK.

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

1010  {
1011  CHECK(json_str_arr.IsArray());
1012  std::vector<std::string> fields;
1013  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
1014  ++json_str_arr_it) {
1015  CHECK(json_str_arr_it->IsString());
1016  fields.emplace_back(json_str_arr_it->GetString());
1017  }
1018  return fields;
1019 }
#define CHECK(condition)
Definition: Logger.h:209

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

References ANTI, INNER, LEFT, and SEMI.

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

1075  {
1076  if (join_type_name == "inner") {
1077  return JoinType::INNER;
1078  }
1079  if (join_type_name == "left") {
1080  return JoinType::LEFT;
1081  }
1082  if (join_type_name == "semi") {
1083  return JoinType::SEMI;
1084  }
1085  if (join_type_name == "anti") {
1086  return JoinType::ANTI;
1087  }
1088  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
1089 }

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