OmniSciDB  0bd2ec9cf4
 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  RANodeIterator
 
class  WindowFunctionDetectionVisitor
 
class  RexWindowFuncReplacementVisitor
 
class  RexInputBackpropagationVisitor
 

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::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::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::string json_node_to_string (const rapidjson::Value &node) 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 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)
 
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
 

Function Documentation

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

Definition at line 979 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

979  {
980  for (auto ra_node : nodes) {
981  const auto filter_node = std::dynamic_pointer_cast<RelFilter>(ra_node);
982  if (filter_node) {
983  CHECK_EQ(size_t(1), filter_node->inputCount());
984  auto disambiguated_condition = disambiguate_rex(
985  filter_node->getCondition(), get_node_output(filter_node->getInput(0)));
986  filter_node->setCondition(disambiguated_condition);
987  continue;
988  }
989  const auto join_node = std::dynamic_pointer_cast<RelJoin>(ra_node);
990  if (join_node) {
991  CHECK_EQ(size_t(2), join_node->inputCount());
992  auto disambiguated_condition =
993  disambiguate_rex(join_node->getCondition(), get_node_output(join_node.get()));
994  join_node->setCondition(disambiguated_condition);
995  continue;
996  }
997  const auto project_node = std::dynamic_pointer_cast<RelProject>(ra_node);
998  if (project_node) {
999  bind_project_to_input(project_node.get(),
1000  get_node_output(project_node->getInput(0)));
1001  continue;
1002  }
1003  const auto table_func_node = std::dynamic_pointer_cast<RelTableFunction>(ra_node);
1004  if (table_func_node) {
1005  bind_table_func_to_input(table_func_node.get(),
1006  get_node_output(table_func_node->getInput(0)));
1007  }
1008  }
1009 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
void bind_table_func_to_input(RelTableFunction *table_func_node, const RANodeOutput &input) noexcept
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
RANodeOutput get_node_output(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 950 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs(), and create_compound().

950  {
951  CHECK_EQ(size_t(1), project_node->inputCount());
952  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
953  for (size_t i = 0; i < project_node->size(); ++i) {
954  const auto projected_expr = project_node->getProjectAt(i);
955  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
956  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
957  } else {
958  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
959  }
960  }
961  project_node->setExpressions(disambiguated_exprs);
962 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
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 964 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs().

965  {
966  CHECK_EQ(size_t(1), table_func_node->inputCount());
967  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
968  for (size_t i = 0; i < table_func_node->getTableFuncInputsSize(); ++i) {
969  const auto target_expr = table_func_node->getTableFuncInputAt(i);
970  if (dynamic_cast<const RexSubQuery*>(target_expr)) {
971  disambiguated_exprs.emplace_back(table_func_node->getTableFuncInputAtAndRelease(i));
972  } else {
973  disambiguated_exprs.emplace_back(disambiguate_rex(target_expr, input));
974  }
975  }
976  table_func_node->setTableFuncInputs(disambiguated_exprs);
977 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
std::unique_ptr< const RexScalar > disambiguate_rex(const RexScalar *, const RANodeOutput &)
size_t getTableFuncInputsSize() const
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
const RexScalar * getTableFuncInputAt(const size_t idx) const
const size_t inputCount() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1790 of file RelAlgDagBuilder.cpp.

References CHECK(), and field().

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

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1381 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

1382  {
1383  enum class CoalesceState { Initial, Filter, FirstProject, Aggregate };
1384  std::vector<size_t> crt_pattern;
1385  CoalesceState crt_state{CoalesceState::Initial};
1386 
1387  auto reset_state = [&crt_pattern, &crt_state]() {
1388  crt_state = CoalesceState::Initial;
1389  decltype(crt_pattern)().swap(crt_pattern);
1390  };
1391 
1392  for (RANodeIterator nodeIt(nodes); !nodeIt.allVisited();) {
1393  const auto ra_node = nodeIt != nodes.end() ? *nodeIt : nullptr;
1394  switch (crt_state) {
1395  case CoalesceState::Initial: {
1396  if (std::dynamic_pointer_cast<const RelFilter>(ra_node) &&
1397  std::find(left_deep_joins.begin(), left_deep_joins.end(), ra_node.get()) ==
1398  left_deep_joins.end()) {
1399  crt_pattern.push_back(size_t(nodeIt));
1400  crt_state = CoalesceState::Filter;
1401  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1402  } else if (std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1403  crt_pattern.push_back(size_t(nodeIt));
1404  crt_state = CoalesceState::FirstProject;
1405  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1406  } else {
1407  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1408  }
1409  break;
1410  }
1411  case CoalesceState::Filter: {
1412  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1413  if (project_has_window_function_input(project_node.get())) {
1414  reset_state();
1415  break;
1416  }
1417  crt_pattern.push_back(size_t(nodeIt));
1418  crt_state = CoalesceState::FirstProject;
1419  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1420  } else {
1421  reset_state();
1422  }
1423  break;
1424  }
1425  case CoalesceState::FirstProject: {
1426  if (std::dynamic_pointer_cast<const RelAggregate>(ra_node)) {
1427  crt_pattern.push_back(size_t(nodeIt));
1428  crt_state = CoalesceState::Aggregate;
1429  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1430  } else {
1431  if (crt_pattern.size() >= 2) {
1432  create_compound(nodes, crt_pattern);
1433  }
1434  reset_state();
1435  }
1436  break;
1437  }
1438  case CoalesceState::Aggregate: {
1439  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1440  // TODO(adb): overloading the simple project terminology again here
1441  bool is_simple_project{true};
1442  for (size_t i = 0; i < project_node->size(); i++) {
1443  const auto scalar_rex = project_node->getProjectAt(i);
1444  // If the top level scalar rex is an input node, we can bypass the visitor
1445  if (auto input_rex = dynamic_cast<const RexInput*>(scalar_rex)) {
1447  input_rex->getSourceNode(), input_rex->getIndex(), true)) {
1448  is_simple_project = false;
1449  break;
1450  }
1451  continue;
1452  }
1453  CoalesceSecondaryProjectVisitor visitor;
1454  if (!visitor.visit(project_node->getProjectAt(i))) {
1455  is_simple_project = false;
1456  break;
1457  }
1458  }
1459  if (is_simple_project) {
1460  crt_pattern.push_back(size_t(nodeIt));
1461  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1462  }
1463  }
1464  CHECK_GE(crt_pattern.size(), size_t(2));
1465  create_compound(nodes, crt_pattern);
1466  reset_state();
1467  break;
1468  }
1469  default:
1470  CHECK(false);
1471  }
1472  }
1473  if (crt_state == CoalesceState::FirstProject || crt_state == CoalesceState::Aggregate) {
1474  if (crt_pattern.size() >= 2) {
1475  create_compound(nodes, crt_pattern);
1476  }
1477  CHECK(!crt_pattern.empty());
1478  }
1479 }
#define CHECK_GE(x, y)
Definition: Logger.h:206
CHECK(cgen_state)
void create_compound(std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< size_t > &pattern) noexcept
bool input_can_be_coalesced(const RelAlgNode *parent_node, const size_t index, const bool first_rex_is_input)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1071 of file RelAlgDagBuilder.cpp.

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

Referenced by coalesce_nodes().

1072  {
1073  CHECK_GE(pattern.size(), size_t(2));
1074  CHECK_LE(pattern.size(), size_t(4));
1075 
1076  std::unique_ptr<const RexScalar> filter_rex;
1077  std::vector<std::unique_ptr<const RexScalar>> scalar_sources;
1078  size_t groupby_count{0};
1079  std::vector<std::string> fields;
1080  std::vector<const RexAgg*> agg_exprs;
1081  std::vector<const Rex*> target_exprs;
1082  bool first_project{true};
1083  bool is_agg{false};
1084  RelAlgNode* last_node{nullptr};
1085 
1086  std::shared_ptr<ModifyManipulationTarget> manipulation_target;
1087 
1088  for (const auto node_idx : pattern) {
1089  const auto ra_node = nodes[node_idx];
1090  const auto ra_filter = std::dynamic_pointer_cast<RelFilter>(ra_node);
1091  if (ra_filter) {
1092  CHECK(!filter_rex);
1093  filter_rex.reset(ra_filter->getAndReleaseCondition());
1094  CHECK(filter_rex);
1095  last_node = ra_node.get();
1096  continue;
1097  }
1098  const auto ra_project = std::dynamic_pointer_cast<RelProject>(ra_node);
1099  if (ra_project) {
1100  fields = ra_project->getFields();
1101  manipulation_target = ra_project;
1102 
1103  if (first_project) {
1104  CHECK_EQ(size_t(1), ra_project->inputCount());
1105  // Rebind the input of the project to the input of the filter itself
1106  // since we know that we'll evaluate the filter on the fly, with no
1107  // intermediate buffer.
1108  const auto filter_input = dynamic_cast<const RelFilter*>(ra_project->getInput(0));
1109  if (filter_input) {
1110  CHECK_EQ(size_t(1), filter_input->inputCount());
1111  bind_project_to_input(ra_project.get(),
1112  get_node_output(filter_input->getInput(0)));
1113  }
1114  scalar_sources = ra_project->getExpressionsAndRelease();
1115  for (const auto& scalar_expr : scalar_sources) {
1116  target_exprs.push_back(scalar_expr.get());
1117  }
1118  first_project = false;
1119  } else {
1120  if (ra_project->isSimple()) {
1121  target_exprs = reproject_targets(ra_project.get(), target_exprs);
1122  } else {
1123  // TODO(adb): This is essentially a more general case of simple project, we
1124  // could likely merge the two
1125  std::vector<const Rex*> result;
1126  RexInputReplacementVisitor visitor(last_node, scalar_sources);
1127  for (size_t i = 0; i < ra_project->size(); ++i) {
1128  const auto rex = ra_project->getProjectAt(i);
1129  if (auto rex_input = dynamic_cast<const RexInput*>(rex)) {
1130  const auto index = rex_input->getIndex();
1131  CHECK_LT(index, target_exprs.size());
1132  result.push_back(target_exprs[index]);
1133  } else {
1134  scalar_sources.push_back(visitor.visit(rex));
1135  result.push_back(scalar_sources.back().get());
1136  }
1137  }
1138  target_exprs = result;
1139  }
1140  }
1141  last_node = ra_node.get();
1142  continue;
1143  }
1144  const auto ra_aggregate = std::dynamic_pointer_cast<RelAggregate>(ra_node);
1145  if (ra_aggregate) {
1146  is_agg = true;
1147  fields = ra_aggregate->getFields();
1148  agg_exprs = ra_aggregate->getAggregatesAndRelease();
1149  groupby_count = ra_aggregate->getGroupByCount();
1150  decltype(target_exprs){}.swap(target_exprs);
1151  CHECK_LE(groupby_count, scalar_sources.size());
1152  for (size_t group_idx = 0; group_idx < groupby_count; ++group_idx) {
1153  const auto rex_ref = new RexRef(group_idx + 1);
1154  target_exprs.push_back(rex_ref);
1155  scalar_sources.emplace_back(rex_ref);
1156  }
1157  for (const auto rex_agg : agg_exprs) {
1158  target_exprs.push_back(rex_agg);
1159  }
1160  last_node = ra_node.get();
1161  continue;
1162  }
1163  }
1164 
1165  auto compound_node =
1166  std::make_shared<RelCompound>(filter_rex,
1167  target_exprs,
1168  groupby_count,
1169  agg_exprs,
1170  fields,
1171  scalar_sources,
1172  is_agg,
1173  manipulation_target->isUpdateViaSelect(),
1174  manipulation_target->isDeleteViaSelect(),
1175  manipulation_target->isVarlenUpdateRequired(),
1176  manipulation_target->getModifiedTableDescriptor(),
1177  manipulation_target->getTargetColumns());
1178  auto old_node = nodes[pattern.back()];
1179  nodes[pattern.back()] = compound_node;
1180  auto first_node = nodes[pattern.front()];
1181  CHECK_EQ(size_t(1), first_node->inputCount());
1182  compound_node->addManagedInput(first_node->getAndOwnInput(0));
1183  for (size_t i = 0; i < pattern.size() - 1; ++i) {
1184  nodes[pattern[i]].reset();
1185  }
1186  for (auto node : nodes) {
1187  if (!node) {
1188  continue;
1189  }
1190  node->replaceInput(old_node, compound_node);
1191  }
1192 }
bool is_agg(const Analyzer::Expr *expr)
#define CHECK_EQ(x, y)
Definition: Logger.h:201
#define CHECK_GE(x, y)
Definition: Logger.h:206
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
CHECK(cgen_state)
#define CHECK_LT(x, y)
Definition: Logger.h:203
#define CHECK_LE(x, y)
Definition: Logger.h:204
const std::vector< std::string > & getFields() const
RANodeOutput get_node_output(const RelAlgNode *ra_node)
std::vector< const Rex * > reproject_targets(const RelProject *simple_project, const std::vector< const Rex * > &target_exprs) noexcept

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 908 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

909  {
910  std::vector<
911  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
912  disambiguated_expr_pair_list;
913  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
914  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
915  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
916  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
917  std::move(disambiguated_then));
918  }
919  std::unique_ptr<const RexScalar> disambiguated_else{
920  disambiguate_rex(rex_case->getElse(), ra_output)};
921  return std::unique_ptr<const RexCase>(
922  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
923 }
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 873 of file RelAlgDagBuilder.cpp.

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

Referenced by disambiguate_rex().

875  {
876  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
877  for (size_t i = 0; i < rex_operator->size(); ++i) {
878  auto operand = rex_operator->getOperand(i);
879  if (dynamic_cast<const RexSubQuery*>(operand)) {
880  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
881  } else {
882  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
883  }
884  }
885  const auto rex_window_function_operator =
886  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
887  if (rex_window_function_operator) {
888  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
889  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
890  for (const auto& partition_key : partition_keys) {
891  disambiguated_partition_keys.emplace_back(
892  disambiguate_rex(partition_key.get(), ra_output));
893  }
894  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
895  const auto& order_keys = rex_window_function_operator->getOrderKeys();
896  for (const auto& order_key : order_keys) {
897  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
898  }
899  return rex_window_function_operator->disambiguatedOperands(
900  disambiguated_operands,
901  disambiguated_partition_keys,
902  disambiguated_order_keys,
903  rex_window_function_operator->getCollation());
904  }
905  return rex_operator->getDisambiguated(disambiguated_operands);
906 }
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 929 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().

930  {
931  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
932  if (rex_abstract_input) {
933  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
934  return std::unique_ptr<const RexInput>(
935  new RexInput(ra_output[rex_abstract_input->getIndex()]));
936  }
937  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
938  if (rex_operator) {
939  return disambiguate_operator(rex_operator, ra_output);
940  }
941  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
942  if (rex_case) {
943  return disambiguate_case(rex_case, ra_output);
944  }
945  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
946  CHECK(rex_literal);
947  return std::unique_ptr<const RexLiteral>(new RexLiteral(*rex_literal));
948 }
CHECK(cgen_state)
#define CHECK_LT(x, y)
Definition: Logger.h:203
std::unique_ptr< const RexOperator > disambiguate_operator(const RexOperator *rex_operator, const RANodeOutput &ra_output) noexcept
std::unique_ptr< const RexCase > disambiguate_case(const RexCase *rex_case, const RANodeOutput &ra_output)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 420 of file RelAlgDagBuilder.cpp.

References CHECK(), and CHECK_EQ.

Referenced by RelSort::hasEquivCollationOf().

421  {
422  std::set<std::pair<const RelAlgNode*, int>> work_set;
423  auto walker = node;
424  auto curr_col = which_col;
425  while (true) {
426  work_set.insert(std::make_pair(walker, curr_col));
427  if (dynamic_cast<const RelScan*>(walker) || dynamic_cast<const RelJoin*>(walker)) {
428  break;
429  }
430  CHECK_EQ(size_t(1), walker->inputCount());
431  auto only_source = walker->getInput(0);
432  if (auto project = dynamic_cast<const RelProject*>(walker)) {
433  if (auto input = dynamic_cast<const RexInput*>(project->getProjectAt(curr_col))) {
434  const auto join_source = dynamic_cast<const RelJoin*>(only_source);
435  if (join_source) {
436  CHECK_EQ(size_t(2), join_source->inputCount());
437  auto lhs = join_source->getInput(0);
438  CHECK((input->getIndex() < lhs->size() && lhs == input->getSourceNode()) ||
439  join_source->getInput(1) == input->getSourceNode());
440  } else {
441  CHECK_EQ(input->getSourceNode(), only_source);
442  }
443  curr_col = input->getIndex();
444  } else {
445  break;
446  }
447  } else if (auto aggregate = dynamic_cast<const RelAggregate*>(walker)) {
448  if (curr_col >= aggregate->getGroupByCount()) {
449  break;
450  }
451  }
452  walker = only_source;
453  }
454  return work_set;
455 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
CHECK(cgen_state)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1776 of file RelAlgDagBuilder.cpp.

References CHECK_EQ, field(), kDECIMAL, and anonymous_namespace{CalciteAdapter.cpp}::parse_literal().

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

1778  {
1779  const auto it = obj.FindMember(field);
1780  if (it == obj.MemberEnd()) {
1781  return default_val;
1782  }
1783  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
1784  CHECK_EQ(kDECIMAL, lit->getType());
1785  CHECK_EQ(unsigned(0), lit->getScale());
1786  CHECK_EQ(unsigned(0), lit->getTypeScale());
1787  return lit->getVal<int64_t>();
1788 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::tuple< const rapidjson::Value *, SQLTypeInfo, SQLTypeInfo > 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 1805 of file RelAlgDagBuilder.cpp.

References field(), and strings_from_json_array().

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

1805  {
1806  const auto& fields_json = field(scan_ra, "fieldNames");
1807  return strings_from_json_array(fields_json);
1808 }
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 1795 of file RelAlgDagBuilder.cpp.

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

Referenced by anonymous_namespace{CalciteAdapter.cpp}::CalciteAdapter::CalciteAdapter(), details::RelAlgDispatcher::dispatchModify(), and details::RelAlgDispatcher::dispatchTableScan().

1796  {
1797  const auto& table_json = field(scan_ra, "table");
1798  CHECK(table_json.IsArray());
1799  CHECK_EQ(unsigned(2), table_json.Size());
1800  const auto td = cat.getMetadataForTable(table_json[1].GetString());
1801  CHECK(td);
1802  return td;
1803 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 805 of file RelAlgDagBuilder.cpp.

References CHECK(), and CHECK_GE.

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

806  {
807  CHECK(json_idx_arr.IsArray());
808  std::vector<size_t> indices;
809  for (auto json_idx_arr_it = json_idx_arr.Begin(); json_idx_arr_it != json_idx_arr.End();
810  ++json_idx_arr_it) {
811  CHECK(json_idx_arr_it->IsInt());
812  CHECK_GE(json_idx_arr_it->GetInt(), 0);
813  indices.emplace_back(json_idx_arr_it->GetInt());
814  }
815  return indices;
816 }
#define CHECK_GE(x, y)
Definition: Logger.h:206
CHECK(cgen_state)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 209 of file RelAlgDagBuilder.cpp.

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

Referenced by RelProject::isRenaming().

211  {
212  CHECK_LT(index, node->size());
213  if (auto join = dynamic_cast<const RelJoin*>(node)) {
214  CHECK_EQ(size_t(2), join->inputCount());
215  const auto lhs_size = join->getInput(0)->size();
216  if (index < lhs_size) {
217  return isRenamedInput(join->getInput(0), index, new_name);
218  }
219  CHECK_GE(index, lhs_size);
220  return isRenamedInput(join->getInput(1), index - lhs_size, new_name);
221  }
222 
223  if (auto scan = dynamic_cast<const RelScan*>(node)) {
224  return new_name != scan->getFieldName(index);
225  }
226 
227  if (auto aggregate = dynamic_cast<const RelAggregate*>(node)) {
228  return new_name != aggregate->getFieldName(index);
229  }
230 
231  if (auto project = dynamic_cast<const RelProject*>(node)) {
232  return new_name != project->getFieldName(index);
233  }
234 
235  if (auto table_func = dynamic_cast<const RelTableFunction*>(node)) {
236  return new_name != table_func->getFieldName(index);
237  }
238 
239  if (auto logical_values = dynamic_cast<const RelLogicalValues*>(node)) {
240  const auto& tuple_type = logical_values->getTupleType();
241  CHECK_LT(index, tuple_type.size());
242  return new_name != tuple_type[index].get_resname();
243  }
244 
245  CHECK(dynamic_cast<const RelSort*>(node) || dynamic_cast<const RelFilter*>(node));
246  return isRenamedInput(node->getInput(0), index, new_name);
247 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
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:206
CHECK(cgen_state)
const RelAlgNode * getInput(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:203
virtual size_t size() const =0

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 818 of file RelAlgDagBuilder.cpp.

Referenced by parse_scalar_expr().

818  {
819  rapidjson::StringBuffer buffer;
820  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
821  node.Accept(writer);
822  return buffer.GetString();
823 }

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

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by RelAlgDagBuilder::build().

1011  {
1012  for (auto node : nodes) {
1013  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
1014  if (!agg_node || agg_node->getAggExprsCount()) {
1015  continue;
1016  }
1017  CHECK_EQ(size_t(1), node->inputCount());
1018  const auto agg_input_node = dynamic_cast<const RelAggregate*>(node->getInput(0));
1019  if (agg_input_node && !agg_input_node->getAggExprsCount() &&
1020  agg_node->getGroupByCount() == agg_input_node->getGroupByCount()) {
1021  agg_node->markAsNop();
1022  }
1023  }
1024 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201

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

Referenced by get_node_output().

87  {
88  std::vector<RexInput> outputs;
89  for (size_t i = 0; i < n; ++i) {
90  outputs.emplace_back(node, i);
91  }
92  return outputs;
93 }

+ Here is the caller graph for this function:

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

Definition at line 490 of file RelAlgDagBuilder.cpp.

References field(), and json_str().

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

490  {
491  const auto& id = field(ra_node, "id");
492  return std::stoi(json_str(id));
493 }
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 499 of file RelAlgDagBuilder.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

500  {
501  const auto& input = field(expr, "input");
502  return std::unique_ptr<RexAbstractInput>(new RexAbstractInput(json_i64(input)));
503 }
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 825 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().

825  {
826  const auto agg = to_agg_kind(json_str(field(expr, "agg")));
827  const auto distinct = json_bool(field(expr, "distinct"));
828  const auto agg_ti = parse_type(field(expr, "type"));
829  const auto operands = indices_from_json_array(field(expr, "operands"));
830  if (operands.size() > 1 && (operands.size() != 2 || agg != kAPPROX_COUNT_DISTINCT)) {
831  throw QueryNotSupported("Multiple arguments for aggregates aren't supported");
832  }
833  return std::unique_ptr<const RexAgg>(new RexAgg(agg, distinct, agg_ti, operands));
834 }
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 771 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_scalar_expr().

773  {
774  const auto& operands = field(expr, "operands");
775  CHECK(operands.IsArray());
776  CHECK_GE(operands.Size(), unsigned(2));
777  std::unique_ptr<const RexScalar> else_expr;
778  std::vector<
779  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
780  expr_pair_list;
781  for (auto operands_it = operands.Begin(); operands_it != operands.End();) {
782  auto when_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
783  if (operands_it == operands.End()) {
784  else_expr = std::move(when_expr);
785  break;
786  }
787  auto then_expr = parse_scalar_expr(*operands_it++, cat, root_dag_builder);
788  expr_pair_list.emplace_back(std::move(when_expr), std::move(then_expr));
789  }
790  return std::unique_ptr<RexCase>(new RexCase(expr_pair_list, else_expr));
791 }
#define CHECK_GE(x, y)
Definition: Logger.h:206
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 592 of file RelAlgDagBuilder.cpp.

References parse_scalar_expr().

Referenced by parse_operator().

595  {
596  std::vector<std::unique_ptr<const RexScalar>> exprs;
597  for (auto it = arr.Begin(); it != arr.End(); ++it) {
598  exprs.emplace_back(parse_scalar_expr(*it, cat, root_dag_builder));
599  }
600  return exprs;
601 }
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 505 of file RelAlgDagBuilder.cpp.

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

505  {
506  CHECK(expr.IsObject());
507  const auto& literal = field(expr, "literal");
508  const auto type = to_sql_type(json_str(field(expr, "type")));
509  const auto target_type = to_sql_type(json_str(field(expr, "target_type")));
510  const auto scale = json_i64(field(expr, "scale"));
511  const auto precision = json_i64(field(expr, "precision"));
512  const auto type_scale = json_i64(field(expr, "type_scale"));
513  const auto type_precision = json_i64(field(expr, "type_precision"));
514  switch (type) {
515  case kDECIMAL:
516  case kINTERVAL_DAY_TIME:
518  case kTIME:
519  case kTIMESTAMP:
520  case kDATE:
521  return std::unique_ptr<RexLiteral>(new RexLiteral(json_i64(literal),
522  type,
523  target_type,
524  scale,
525  precision,
526  type_scale,
527  type_precision));
528  case kDOUBLE: {
529  if (literal.IsDouble()) {
530  return std::unique_ptr<RexLiteral>(new RexLiteral(json_double(literal),
531  type,
532  target_type,
533  scale,
534  precision,
535  type_scale,
536  type_precision));
537  }
538  CHECK(literal.IsInt64());
539  return std::unique_ptr<RexLiteral>(
540  new RexLiteral(static_cast<double>(json_i64(literal)),
541  type,
542  target_type,
543  scale,
544  precision,
545  type_scale,
546  type_precision));
547  }
548  case kTEXT:
549  return std::unique_ptr<RexLiteral>(new RexLiteral(json_str(literal),
550  type,
551  target_type,
552  scale,
553  precision,
554  type_scale,
555  type_precision));
556  case kBOOLEAN:
557  return std::unique_ptr<RexLiteral>(new RexLiteral(json_bool(literal),
558  type,
559  target_type,
560  scale,
561  precision,
562  type_scale,
563  type_precision));
564  case kNULLT:
565  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
566  default:
567  CHECK(false);
568  }
569  CHECK(false);
570  return nullptr;
571 }
SQLTypes to_sql_type(const std::string &type_name)
Definition: sqltypes.h:52
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
const double json_double(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:54
Definition: sqltypes.h:55
Definition: sqltypes.h:56

+ Here is the call graph for this function:

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

Definition at line 672 of file RelAlgDagBuilder.cpp.

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

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

672  {
673  return json_str(field(collation, "nulls")) == std::string("FIRST")
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<RexOperator> anonymous_namespace{RelAlgDagBuilder.cpp}::parse_operator ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgDagBuilder root_dag_builder 
)

Definition at line 725 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_scalar_expr().

727  {
728  const auto op_name = json_str(field(expr, "op"));
729  const bool is_quantifier =
730  op_name == std::string("PG_ANY") || op_name == std::string("PG_ALL");
731  const auto op = is_quantifier ? kFUNCTION : to_sql_op(op_name);
732  const auto& operators_json_arr = field(expr, "operands");
733  CHECK(operators_json_arr.IsArray());
734  auto operands = parse_expr_array(operators_json_arr, cat, root_dag_builder);
735  const auto type_it = expr.FindMember("type");
736  CHECK(type_it != expr.MemberEnd());
737  auto ti = parse_type(type_it->value);
738  if (op == kIN && expr.HasMember("subquery")) {
739  auto subquery = parse_subquery(expr, cat, root_dag_builder);
740  operands.emplace_back(std::move(subquery));
741  }
742  if (expr.FindMember("partition_keys") != expr.MemberEnd()) {
743  const auto& partition_keys_arr = field(expr, "partition_keys");
744  auto partition_keys = parse_expr_array(partition_keys_arr, cat, root_dag_builder);
745  const auto& order_keys_arr = field(expr, "order_keys");
746  auto order_keys = parse_window_order_exprs(order_keys_arr, cat, root_dag_builder);
747  const auto collation =
748  parse_window_order_collation(order_keys_arr, cat, root_dag_builder);
749  const auto kind = parse_window_function_kind(op_name);
750  const auto lower_bound =
751  parse_window_bound(field(expr, "lower_bound"), cat, root_dag_builder);
752  const auto upper_bound =
753  parse_window_bound(field(expr, "upper_bound"), cat, root_dag_builder);
754  bool is_rows = json_bool(field(expr, "is_rows"));
755  ti.set_notnull(false);
756  return std::make_unique<RexWindowFunctionOperator>(kind,
757  operands,
758  partition_keys,
759  order_keys,
760  collation,
761  lower_bound,
762  upper_bound,
763  is_rows,
764  ti);
765  }
766  return std::unique_ptr<RexOperator>(op == kFUNCTION
767  ? new RexFunctionOperator(op_name, operands, ti)
768  : new RexOperator(op, operands, ti));
769 }
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
RexWindowFunctionOperator::RexWindowBound parse_window_bound(const rapidjson::Value &window_bound_obj, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
std::vector< std::unique_ptr< const RexScalar > > parse_window_order_exprs(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
SqlWindowFunctionKind parse_window_function_kind(const std::string &name)
std::vector< std::unique_ptr< const RexScalar > > parse_expr_array(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
std::vector< SortField > parse_window_order_collation(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
SQLOps to_sql_op(const std::string &op_str)
Definition: sqldefs.h:53
std::unique_ptr< const RexSubQuery > parse_subquery(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 836 of file RelAlgDagBuilder.cpp.

References CHECK(), field(), json_node_to_string(), json_str(), parse_abstract_input(), parse_case(), anonymous_namespace{CalciteAdapter.cpp}::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().

838  {
839  CHECK(expr.IsObject());
840  if (expr.IsObject() && expr.HasMember("input")) {
841  return std::unique_ptr<const RexScalar>(parse_abstract_input(expr));
842  }
843  if (expr.IsObject() && expr.HasMember("literal")) {
844  return std::unique_ptr<const RexScalar>(parse_literal(expr));
845  }
846  if (expr.IsObject() && expr.HasMember("op")) {
847  const auto op_str = json_str(field(expr, "op"));
848  if (op_str == std::string("CASE")) {
849  return std::unique_ptr<const RexScalar>(parse_case(expr, cat, root_dag_builder));
850  }
851  if (op_str == std::string("$SCALAR_QUERY")) {
852  return std::unique_ptr<const RexScalar>(
853  parse_subquery(expr, cat, root_dag_builder));
854  }
855  return std::unique_ptr<const RexScalar>(parse_operator(expr, cat, root_dag_builder));
856  }
857  throw QueryNotSupported("Expression node " + json_node_to_string(expr) +
858  " not supported");
859 }
std::unique_ptr< RexCase > parse_case(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
std::unique_ptr< RexOperator > parse_operator(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
std::tuple< const rapidjson::Value *, SQLTypeInfo, SQLTypeInfo > parse_literal(const rapidjson::Value &expr)
std::unique_ptr< RexAbstractInput > parse_abstract_input(const rapidjson::Value &expr) noexcept
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 666 of file RelAlgDagBuilder.cpp.

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

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

666  {
667  return json_str(field(collation, "direction")) == std::string("DESCENDING")
670 }
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 711 of file RelAlgDagBuilder.cpp.

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

Referenced by parse_operator(), and parse_scalar_expr().

713  {
714  const auto& operands = field(expr, "operands");
715  CHECK(operands.IsArray());
716  CHECK_GE(operands.Size(), unsigned(0));
717  const auto& subquery_ast = field(expr, "subquery");
718 
719  RelAlgDagBuilder subquery_dag(root_dag_builder, subquery_ast, cat, nullptr);
720  auto subquery = std::make_shared<RexSubQuery>(subquery_dag.getRootNodeShPtr());
721  root_dag_builder.registerSubquery(subquery);
722  return subquery->deepCopy();
723 }
#define CHECK_GE(x, y)
Definition: Logger.h:206
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 577 of file RelAlgDagBuilder.cpp.

References CHECK(), field(), json_bool(), json_i64(), json_str(), SQLTypeInfoCore< TYPE_FACET_PACK >::set_precision(), SQLTypeInfoCore< TYPE_FACET_PACK >::set_scale(), to_sql_type(), and run_benchmark_import::type.

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

577  {
578  CHECK(type_obj.IsObject() && type_obj.MemberCount() >= 2);
579  const auto type = to_sql_type(json_str(field(type_obj, "type")));
580  const auto nullable = json_bool(field(type_obj, "nullable"));
581  const auto precision_it = type_obj.FindMember("precision");
582  const int precision =
583  precision_it != type_obj.MemberEnd() ? json_i64(precision_it->value) : 0;
584  const auto scale_it = type_obj.FindMember("scale");
585  const int scale = scale_it != type_obj.MemberEnd() ? json_i64(scale_it->value) : 0;
586  SQLTypeInfo ti(type, !nullable);
587  ti.set_precision(precision);
588  ti.set_scale(scale);
589  return ti;
590 }
SQLTypes to_sql_type(const std::string &type_name)
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39

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

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

Referenced by parse_operator().

694  {
695  CHECK(window_bound_obj.IsObject());
697  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
698  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
699  window_bound.following = json_bool(field(window_bound_obj, "following"));
700  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
701  const auto& offset_field = field(window_bound_obj, "offset");
702  if (offset_field.IsObject()) {
703  window_bound.offset = parse_scalar_expr(offset_field, cat, root_dag_builder);
704  } else {
705  CHECK(offset_field.IsNull());
706  }
707  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
708  return window_bound;
709 }
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
CHECK(cgen_state)
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgDagBuilder &root_dag_builder)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

603  {
604  if (name == "ROW_NUMBER") {
606  }
607  if (name == "RANK") {
609  }
610  if (name == "DENSE_RANK") {
612  }
613  if (name == "PERCENT_RANK") {
615  }
616  if (name == "CUME_DIST") {
618  }
619  if (name == "NTILE") {
621  }
622  if (name == "LAG") {
624  }
625  if (name == "LEAD") {
627  }
628  if (name == "FIRST_VALUE") {
630  }
631  if (name == "LAST_VALUE") {
633  }
634  if (name == "AVG") {
636  }
637  if (name == "MIN") {
639  }
640  if (name == "MAX") {
642  }
643  if (name == "SUM") {
645  }
646  if (name == "COUNT") {
648  }
649  if (name == "$SUM0") {
651  }
652  throw std::runtime_error("Unsupported window function: " + name);
653 }

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

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

680  {
681  std::vector<SortField> collation;
682  size_t field_idx = 0;
683  for (auto it = arr.Begin(); it != arr.End(); ++it, ++field_idx) {
684  const auto sort_dir = parse_sort_direction(*it);
685  const auto null_pos = parse_nulls_position(*it);
686  collation.emplace_back(field_idx, sort_dir, null_pos);
687  }
688  return collation;
689 }
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 655 of file RelAlgDagBuilder.cpp.

References field(), and parse_scalar_expr().

Referenced by parse_operator().

658  {
659  std::vector<std::unique_ptr<const RexScalar>> exprs;
660  for (auto it = arr.Begin(); it != arr.End(); ++it) {
661  exprs.emplace_back(parse_scalar_expr(field(*it, "field"), cat, root_dag_builder));
662  }
663  return exprs;
664 }
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}::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 1670 of file RelAlgDagBuilder.cpp.

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

Referenced by RelAlgDagBuilder::build().

1671  {
1672  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
1673 
1674  WindowFunctionDetectionVisitor visitor;
1675  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
1676  const auto node = *node_itr;
1677  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
1678  if (!window_func_project_node) {
1679  continue;
1680  }
1681 
1682  // map scalar expression index in the project node to wiondow function ptr
1683  std::unordered_map<size_t, const RexScalar*> embedded_window_function_expressions;
1684 
1685  // Iterate the target exprs of the project node and check for window function
1686  // expressions. If an embedded expression exists, save it in the
1687  // embedded_window_function_expressions map and split the expression into a window
1688  // function expression and a parent expression in a subsequent project node
1689  for (size_t i = 0; i < window_func_project_node->size(); i++) {
1690  const auto scalar_rex = window_func_project_node->getProjectAt(i);
1691  if (is_window_function_operator(scalar_rex)) {
1692  // top level window function exprs are fine
1693  continue;
1694  }
1695 
1696  if (const auto window_func_rex = visitor.visit(scalar_rex)) {
1697  const auto ret = embedded_window_function_expressions.insert(
1698  std::make_pair(i, window_func_rex));
1699  CHECK(ret.second);
1700  }
1701  }
1702 
1703  if (!embedded_window_function_expressions.empty()) {
1704  std::vector<std::unique_ptr<const RexScalar>> new_scalar_exprs;
1705 
1706  auto window_func_scalar_exprs =
1707  window_func_project_node->getExpressionsAndRelease();
1708  for (size_t rex_idx = 0; rex_idx < window_func_scalar_exprs.size(); ++rex_idx) {
1709  const auto embedded_window_func_expr_pair =
1710  embedded_window_function_expressions.find(rex_idx);
1711  if (embedded_window_func_expr_pair ==
1712  embedded_window_function_expressions.end()) {
1713  new_scalar_exprs.emplace_back(
1714  std::make_unique<const RexInput>(window_func_project_node.get(), rex_idx));
1715  } else {
1716  const auto window_func_rex_idx = embedded_window_func_expr_pair->first;
1717  CHECK_LT(window_func_rex_idx, window_func_scalar_exprs.size());
1718 
1719  const auto& window_func_rex = embedded_window_func_expr_pair->second;
1720 
1721  RexDeepCopyVisitor copier;
1722  auto window_func_rex_copy = copier.visit(window_func_rex);
1723 
1724  auto window_func_parent_expr =
1725  window_func_scalar_exprs[window_func_rex_idx].get();
1726 
1727  // Replace window func rex with an input rex
1728  auto window_func_result_input = std::make_unique<const RexInput>(
1729  window_func_project_node.get(), window_func_rex_idx);
1730  RexWindowFuncReplacementVisitor replacer(std::move(window_func_result_input));
1731  auto new_parent_rex = replacer.visit(window_func_parent_expr);
1732 
1733  // Put the parent expr in the new scalar exprs
1734  new_scalar_exprs.emplace_back(std::move(new_parent_rex));
1735 
1736  // Put the window func expr in cur scalar exprs
1737  window_func_scalar_exprs[window_func_rex_idx] = std::move(window_func_rex_copy);
1738  }
1739  }
1740 
1741  CHECK_EQ(window_func_scalar_exprs.size(), new_scalar_exprs.size());
1742  window_func_project_node->setExpressions(window_func_scalar_exprs);
1743 
1744  // Ensure any inputs from the node containing the expression (the "new" node)
1745  // exist on the window function project node, e.g. if we had a binary operation
1746  // involving an aggregate value or column not included in the top level
1747  // projection list.
1748  RexInputBackpropagationVisitor input_visitor(window_func_project_node.get());
1749  for (size_t i = 0; i < new_scalar_exprs.size(); i++) {
1750  if (dynamic_cast<const RexInput*>(new_scalar_exprs[i].get())) {
1751  // ignore top level inputs, these were copied directly from the previous
1752  // node
1753  continue;
1754  }
1755  new_scalar_exprs[i] = input_visitor.visit(new_scalar_exprs[i].get());
1756  }
1757 
1758  // Build the new project node and insert it into the list after the project node
1759  // containing the window function
1760  auto new_project =
1761  std::make_shared<RelProject>(new_scalar_exprs,
1762  window_func_project_node->getFields(),
1763  window_func_project_node);
1764  node_list.insert(std::next(node_itr), new_project);
1765 
1766  // Rebind all the following inputs
1767  for (auto rebind_itr = std::next(node_itr, 2); rebind_itr != node_list.end();
1768  rebind_itr++) {
1769  (*rebind_itr)->replaceInput(window_func_project_node, new_project);
1770  }
1771  }
1772  }
1773  nodes.assign(node_list.begin(), node_list.end());
1774 }
#define CHECK_EQ(x, y)
Definition: Logger.h:201
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
CHECK(cgen_state)
const RexScalar * getProjectAt(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h: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 793 of file RelAlgDagBuilder.cpp.

References CHECK().

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

794  {
795  CHECK(json_str_arr.IsArray());
796  std::vector<std::string> fields;
797  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
798  ++json_str_arr_it) {
799  CHECK(json_str_arr_it->IsString());
800  fields.emplace_back(json_str_arr_it->GetString());
801  }
802  return fields;
803 }
CHECK(cgen_state)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 861 of file RelAlgDagBuilder.cpp.

References INNER, and LEFT.

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

861  {
862  if (join_type_name == "inner") {
863  return JoinType::INNER;
864  }
865  if (join_type_name == "left") {
866  return JoinType::LEFT;
867  }
868  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
869 }

+ Here is the caller graph for this function:

Variable Documentation

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

Definition at line 38 of file RelAlgDagBuilder.cpp.

Referenced by RelAlgNode::resetRelAlgFirstId().