OmniSciDB  343343d194
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
anonymous_namespace{RelAlgAbstractInterpreter.cpp} Namespace Reference

Namespaces

 anonymous_namespace{RelAlgAbstractInterpreter.cpp}
 

Classes

class  RexRebindInputsVisitor
 
class  RANodeIterator
 
class  WindowFunctionDetectionVisitor
 
class  RexWindowFuncReplacementVisitor
 
class  RexInputBackpropagationVisitor
 
class  RelAlgAbstractInterpreter
 

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, RelAlgExecutor *ra_executor)
 
std::unique_ptr< const
RexSubQuery
parse_subquery (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
 
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, RelAlgExecutor *ra_executor)
 
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, RelAlgExecutor *ra_executor)
 
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, RelAlgExecutor *ra_executor)
 
RexWindowFunctionOperator::RexWindowBound parse_window_bound (const rapidjson::Value &window_bound_obj, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
 
std::unique_ptr< RexOperatorparse_operator (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
 
std::unique_ptr< RexCaseparse_case (const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
 
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_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
 
std::shared_ptr< const RelAlgNodera_interpret (const rapidjson::Value &query_ast, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor, const RenderQueryOptions *render_opts)
 

Variables

const unsigned FIRST_RA_NODE_ID = 1
 

Function Documentation

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

Definition at line 893 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::run().

893  {
894  for (auto ra_node : nodes) {
895  const auto filter_node = std::dynamic_pointer_cast<RelFilter>(ra_node);
896  if (filter_node) {
897  CHECK_EQ(size_t(1), filter_node->inputCount());
898  auto disambiguated_condition = disambiguate_rex(
899  filter_node->getCondition(), get_node_output(filter_node->getInput(0)));
900  filter_node->setCondition(disambiguated_condition);
901  continue;
902  }
903  const auto join_node = std::dynamic_pointer_cast<RelJoin>(ra_node);
904  if (join_node) {
905  CHECK_EQ(size_t(2), join_node->inputCount());
906  auto disambiguated_condition =
907  disambiguate_rex(join_node->getCondition(), get_node_output(join_node.get()));
908  join_node->setCondition(disambiguated_condition);
909  continue;
910  }
911  const auto project_node = std::dynamic_pointer_cast<RelProject>(ra_node);
912  if (project_node) {
913  bind_project_to_input(project_node.get(),
914  get_node_output(project_node->getInput(0)));
915  continue;
916  }
917  }
918 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
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{RelAlgAbstractInterpreter.cpp}::bind_project_to_input ( RelProject project_node,
const RANodeOutput input 
)
noexcept

Definition at line 879 of file RelAlgAbstractInterpreter.cpp.

References CHECK_EQ, and disambiguate_rex().

Referenced by bind_inputs(), and create_compound().

879  {
880  CHECK_EQ(size_t(1), project_node->inputCount());
881  std::vector<std::unique_ptr<const RexScalar>> disambiguated_exprs;
882  for (size_t i = 0; i < project_node->size(); ++i) {
883  const auto projected_expr = project_node->getProjectAt(i);
884  if (dynamic_cast<const RexSubQuery*>(projected_expr)) {
885  disambiguated_exprs.emplace_back(project_node->getProjectAtAndRelease(i));
886  } else {
887  disambiguated_exprs.emplace_back(disambiguate_rex(projected_expr, input));
888  }
889  }
890  project_node->setExpressions(disambiguated_exprs);
891 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
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{RelAlgAbstractInterpreter.cpp}::check_empty_inputs_field ( const rapidjson::Value &  node)
noexcept

Definition at line 1699 of file RelAlgAbstractInterpreter.cpp.

References CHECK, and field().

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchTableScan().

1699  {
1700  const auto& inputs_json = field(node, "inputs");
1701  CHECK(inputs_json.IsArray() && !inputs_json.Size());
1702 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1290 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::run().

1291  {
1292  enum class CoalesceState { Initial, Filter, FirstProject, Aggregate };
1293  std::vector<size_t> crt_pattern;
1294  CoalesceState crt_state{CoalesceState::Initial};
1295 
1296  auto reset_state = [&crt_pattern, &crt_state]() {
1297  crt_state = CoalesceState::Initial;
1298  decltype(crt_pattern)().swap(crt_pattern);
1299  };
1300 
1301  for (RANodeIterator nodeIt(nodes); !nodeIt.allVisited();) {
1302  const auto ra_node = nodeIt != nodes.end() ? *nodeIt : nullptr;
1303  switch (crt_state) {
1304  case CoalesceState::Initial: {
1305  if (std::dynamic_pointer_cast<const RelFilter>(ra_node) &&
1306  std::find(left_deep_joins.begin(), left_deep_joins.end(), ra_node.get()) ==
1307  left_deep_joins.end()) {
1308  crt_pattern.push_back(size_t(nodeIt));
1309  crt_state = CoalesceState::Filter;
1310  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1311  } else if (std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1312  crt_pattern.push_back(size_t(nodeIt));
1313  crt_state = CoalesceState::FirstProject;
1314  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1315  } else {
1316  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1317  }
1318  break;
1319  }
1320  case CoalesceState::Filter: {
1321  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1322  if (project_has_window_function_input(project_node.get())) {
1323  reset_state();
1324  break;
1325  }
1326  crt_pattern.push_back(size_t(nodeIt));
1327  crt_state = CoalesceState::FirstProject;
1328  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1329  } else {
1330  reset_state();
1331  }
1332  break;
1333  }
1334  case CoalesceState::FirstProject: {
1335  if (std::dynamic_pointer_cast<const RelAggregate>(ra_node)) {
1336  crt_pattern.push_back(size_t(nodeIt));
1337  crt_state = CoalesceState::Aggregate;
1338  nodeIt.advance(RANodeIterator::AdvancingMode::DUChain);
1339  } else {
1340  if (crt_pattern.size() >= 2) {
1341  create_compound(nodes, crt_pattern);
1342  }
1343  reset_state();
1344  }
1345  break;
1346  }
1347  case CoalesceState::Aggregate: {
1348  if (auto project_node = std::dynamic_pointer_cast<const RelProject>(ra_node)) {
1349  // TODO(adb): overloading the simple project terminology again here
1350  bool is_simple_project{true};
1351  for (size_t i = 0; i < project_node->size(); i++) {
1352  const auto scalar_rex = project_node->getProjectAt(i);
1353  // If the top level scalar rex is an input node, we can bypass the visitor
1354  if (auto input_rex = dynamic_cast<const RexInput*>(scalar_rex)) {
1356  input_rex->getSourceNode(), input_rex->getIndex(), true)) {
1357  is_simple_project = false;
1358  break;
1359  }
1360  continue;
1361  }
1362  CoalesceSecondaryProjectVisitor visitor;
1363  if (!visitor.visit(project_node->getProjectAt(i))) {
1364  is_simple_project = false;
1365  break;
1366  }
1367  }
1368  if (is_simple_project) {
1369  crt_pattern.push_back(size_t(nodeIt));
1370  nodeIt.advance(RANodeIterator::AdvancingMode::InOrder);
1371  }
1372  }
1373  CHECK_GE(crt_pattern.size(), size_t(2));
1374  create_compound(nodes, crt_pattern);
1375  reset_state();
1376  break;
1377  }
1378  default:
1379  CHECK(false);
1380  }
1381  }
1382  if (crt_state == CoalesceState::FirstProject || crt_state == CoalesceState::Aggregate) {
1383  if (crt_pattern.size() >= 2) {
1384  create_compound(nodes, crt_pattern);
1385  }
1386  CHECK(!crt_pattern.empty());
1387  }
1388 }
#define CHECK_GE(x, y)
Definition: Logger.h:200
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)
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 980 of file RelAlgAbstractInterpreter.cpp.

References bind_project_to_input(), CHECK, CHECK_EQ, CHECK_GE, CHECK_LE, CHECK_LT, get_node_output(), RelProject::getFields(), RelAggregate::getFields(), anonymous_namespace{RelAlgAbstractInterpreter.cpp}::anonymous_namespace{RelAlgAbstractInterpreter.cpp}::reproject_targets(), and run-benchmark-import::result.

Referenced by coalesce_nodes().

981  {
982  CHECK_GE(pattern.size(), size_t(2));
983  CHECK_LE(pattern.size(), size_t(4));
984 
985  std::unique_ptr<const RexScalar> filter_rex;
986  std::vector<std::unique_ptr<const RexScalar>> scalar_sources;
987  size_t groupby_count{0};
988  std::vector<std::string> fields;
989  std::vector<const RexAgg*> agg_exprs;
990  std::vector<const Rex*> target_exprs;
991  bool first_project{true};
992  bool is_agg{false};
993  RelAlgNode* last_node{nullptr};
994 
995  std::shared_ptr<ModifyManipulationTarget> manipulation_target;
996 
997  for (const auto node_idx : pattern) {
998  const auto ra_node = nodes[node_idx];
999  const auto ra_filter = std::dynamic_pointer_cast<RelFilter>(ra_node);
1000  if (ra_filter) {
1001  CHECK(!filter_rex);
1002  filter_rex.reset(ra_filter->getAndReleaseCondition());
1003  CHECK(filter_rex);
1004  last_node = ra_node.get();
1005  continue;
1006  }
1007  const auto ra_project = std::dynamic_pointer_cast<RelProject>(ra_node);
1008  if (ra_project) {
1009  fields = ra_project->getFields();
1010  manipulation_target = ra_project;
1011 
1012  if (first_project) {
1013  CHECK_EQ(size_t(1), ra_project->inputCount());
1014  // Rebind the input of the project to the input of the filter itself
1015  // since we know that we'll evaluate the filter on the fly, with no
1016  // intermediate buffer.
1017  const auto filter_input = dynamic_cast<const RelFilter*>(ra_project->getInput(0));
1018  if (filter_input) {
1019  CHECK_EQ(size_t(1), filter_input->inputCount());
1020  bind_project_to_input(ra_project.get(),
1021  get_node_output(filter_input->getInput(0)));
1022  }
1023  scalar_sources = ra_project->getExpressionsAndRelease();
1024  for (const auto& scalar_expr : scalar_sources) {
1025  target_exprs.push_back(scalar_expr.get());
1026  }
1027  first_project = false;
1028  } else {
1029  if (ra_project->isSimple()) {
1030  target_exprs = reproject_targets(ra_project.get(), target_exprs);
1031  } else {
1032  // TODO(adb): This is essentially a more general case of simple project, we
1033  // could likely merge the two
1034  std::vector<const Rex*> result;
1035  RexInputReplacementVisitor visitor(last_node, scalar_sources);
1036  for (size_t i = 0; i < ra_project->size(); ++i) {
1037  const auto rex = ra_project->getProjectAt(i);
1038  if (auto rex_input = dynamic_cast<const RexInput*>(rex)) {
1039  const auto index = rex_input->getIndex();
1040  CHECK_LT(index, target_exprs.size());
1041  result.push_back(target_exprs[index]);
1042  } else {
1043  scalar_sources.push_back(visitor.visit(rex));
1044  result.push_back(scalar_sources.back().get());
1045  }
1046  }
1047  target_exprs = result;
1048  }
1049  }
1050  last_node = ra_node.get();
1051  continue;
1052  }
1053  const auto ra_aggregate = std::dynamic_pointer_cast<RelAggregate>(ra_node);
1054  if (ra_aggregate) {
1055  is_agg = true;
1056  fields = ra_aggregate->getFields();
1057  agg_exprs = ra_aggregate->getAggregatesAndRelease();
1058  groupby_count = ra_aggregate->getGroupByCount();
1059  decltype(target_exprs){}.swap(target_exprs);
1060  CHECK_LE(groupby_count, scalar_sources.size());
1061  for (size_t group_idx = 0; group_idx < groupby_count; ++group_idx) {
1062  const auto rex_ref = new RexRef(group_idx + 1);
1063  target_exprs.push_back(rex_ref);
1064  scalar_sources.emplace_back(rex_ref);
1065  }
1066  for (const auto rex_agg : agg_exprs) {
1067  target_exprs.push_back(rex_agg);
1068  }
1069  last_node = ra_node.get();
1070  continue;
1071  }
1072  }
1073 
1074  auto compound_node =
1075  std::make_shared<RelCompound>(filter_rex,
1076  target_exprs,
1077  groupby_count,
1078  agg_exprs,
1079  fields,
1080  scalar_sources,
1081  is_agg,
1082  manipulation_target->isUpdateViaSelect(),
1083  manipulation_target->isDeleteViaSelect(),
1084  manipulation_target->isVarlenUpdateRequired(),
1085  manipulation_target->getModifiedTableDescriptor(),
1086  manipulation_target->getTargetColumns());
1087  auto old_node = nodes[pattern.back()];
1088  nodes[pattern.back()] = compound_node;
1089  auto first_node = nodes[pattern.front()];
1090  CHECK_EQ(size_t(1), first_node->inputCount());
1091  compound_node->addManagedInput(first_node->getAndOwnInput(0));
1092  for (size_t i = 0; i < pattern.size() - 1; ++i) {
1093  nodes[pattern[i]].reset();
1094  }
1095  for (auto node : nodes) {
1096  if (!node) {
1097  continue;
1098  }
1099  node->replaceInput(old_node, compound_node);
1100  }
1101 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
void bind_project_to_input(RelProject *project_node, const RANodeOutput &input) noexcept
#define CHECK_GE(x, y)
Definition: Logger.h:200
const std::vector< std::string > & getFields() const
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define CHECK_LE(x, y)
Definition: Logger.h:198
const std::vector< std::string > & getFields() const
RANodeOutput get_node_output(const RelAlgNode *ra_node)
#define CHECK(condition)
Definition: Logger.h:187
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{RelAlgAbstractInterpreter.cpp}::disambiguate_case ( const RexCase rex_case,
const RANodeOutput ra_output 
)

Definition at line 837 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by disambiguate_rex().

838  {
839  std::vector<
840  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
841  disambiguated_expr_pair_list;
842  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
843  auto disambiguated_when = disambiguate_rex(rex_case->getWhen(i), ra_output);
844  auto disambiguated_then = disambiguate_rex(rex_case->getThen(i), ra_output);
845  disambiguated_expr_pair_list.emplace_back(std::move(disambiguated_when),
846  std::move(disambiguated_then));
847  }
848  std::unique_ptr<const RexScalar> disambiguated_else{
849  disambiguate_rex(rex_case->getElse(), ra_output)};
850  return std::unique_ptr<const RexCase>(
851  new RexCase(disambiguated_expr_pair_list, disambiguated_else));
852 }
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{RelAlgAbstractInterpreter.cpp}::disambiguate_operator ( const RexOperator rex_operator,
const RANodeOutput ra_output 
)
noexcept

Definition at line 802 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by disambiguate_rex().

804  {
805  std::vector<std::unique_ptr<const RexScalar>> disambiguated_operands;
806  for (size_t i = 0; i < rex_operator->size(); ++i) {
807  auto operand = rex_operator->getOperand(i);
808  if (dynamic_cast<const RexSubQuery*>(operand)) {
809  disambiguated_operands.emplace_back(rex_operator->getOperandAndRelease(i));
810  } else {
811  disambiguated_operands.emplace_back(disambiguate_rex(operand, ra_output));
812  }
813  }
814  const auto rex_window_function_operator =
815  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
816  if (rex_window_function_operator) {
817  const auto& partition_keys = rex_window_function_operator->getPartitionKeys();
818  std::vector<std::unique_ptr<const RexScalar>> disambiguated_partition_keys;
819  for (const auto& partition_key : partition_keys) {
820  disambiguated_partition_keys.emplace_back(
821  disambiguate_rex(partition_key.get(), ra_output));
822  }
823  std::vector<std::unique_ptr<const RexScalar>> disambiguated_order_keys;
824  const auto& order_keys = rex_window_function_operator->getOrderKeys();
825  for (const auto& order_key : order_keys) {
826  disambiguated_order_keys.emplace_back(disambiguate_rex(order_key.get(), ra_output));
827  }
828  return rex_window_function_operator->disambiguatedOperands(
829  disambiguated_operands,
830  disambiguated_partition_keys,
831  disambiguated_order_keys,
832  rex_window_function_operator->getCollation());
833  }
834  return rex_operator->getDisambiguated(disambiguated_operands);
835 }
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{RelAlgAbstractInterpreter.cpp}::disambiguate_rex ( const RexScalar rex_scalar,
const RANodeOutput ra_output 
)

Definition at line 858 of file RelAlgAbstractInterpreter.cpp.

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

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

859  {
860  const auto rex_abstract_input = dynamic_cast<const RexAbstractInput*>(rex_scalar);
861  if (rex_abstract_input) {
862  CHECK_LT(static_cast<size_t>(rex_abstract_input->getIndex()), ra_output.size());
863  return std::unique_ptr<const RexInput>(
864  new RexInput(ra_output[rex_abstract_input->getIndex()]));
865  }
866  const auto rex_operator = dynamic_cast<const RexOperator*>(rex_scalar);
867  if (rex_operator) {
868  return disambiguate_operator(rex_operator, ra_output);
869  }
870  const auto rex_case = dynamic_cast<const RexCase*>(rex_scalar);
871  if (rex_case) {
872  return disambiguate_case(rex_case, ra_output);
873  }
874  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
875  CHECK(rex_literal);
876  return std::unique_ptr<const RexLiteral>(new RexLiteral(*rex_literal));
877 }
std::unique_ptr< const RexCase > disambiguate_case(const RexCase *rex_case, const RANodeOutput &ra_output)
#define CHECK_LT(x, y)
Definition: Logger.h:197
std::unique_ptr< const RexOperator > disambiguate_operator(const RexOperator *rex_operator, const RANodeOutput &ra_output) noexcept
#define CHECK(condition)
Definition: Logger.h:187

+ 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{RelAlgAbstractInterpreter.cpp}::get_equiv_cols ( const RelAlgNode node,
const size_t  which_col 
)

Definition at line 360 of file RelAlgAbstractInterpreter.cpp.

References CHECK, and CHECK_EQ.

Referenced by RelSort::hasEquivCollationOf().

361  {
362  std::set<std::pair<const RelAlgNode*, int>> work_set;
363  auto walker = node;
364  auto curr_col = which_col;
365  while (true) {
366  work_set.insert(std::make_pair(walker, curr_col));
367  if (dynamic_cast<const RelScan*>(walker) || dynamic_cast<const RelJoin*>(walker)) {
368  break;
369  }
370  CHECK_EQ(size_t(1), walker->inputCount());
371  auto only_source = walker->getInput(0);
372  if (auto project = dynamic_cast<const RelProject*>(walker)) {
373  if (auto input = dynamic_cast<const RexInput*>(project->getProjectAt(curr_col))) {
374  const auto join_source = dynamic_cast<const RelJoin*>(only_source);
375  if (join_source) {
376  CHECK_EQ(size_t(2), join_source->inputCount());
377  auto lhs = join_source->getInput(0);
378  CHECK((input->getIndex() < lhs->size() && lhs == input->getSourceNode()) ||
379  join_source->getInput(1) == input->getSourceNode());
380  } else {
381  CHECK_EQ(input->getSourceNode(), only_source);
382  }
383  curr_col = input->getIndex();
384  } else {
385  break;
386  }
387  } else if (auto aggregate = dynamic_cast<const RelAggregate*>(walker)) {
388  if (curr_col >= aggregate->getGroupByCount()) {
389  break;
390  }
391  }
392  walker = only_source;
393  }
394  return work_set;
395 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the caller graph for this function:

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

Definition at line 1685 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchSort().

1687  {
1688  const auto it = obj.FindMember(field);
1689  if (it == obj.MemberEnd()) {
1690  return default_val;
1691  }
1692  std::unique_ptr<RexLiteral> lit(parse_literal(it->value));
1693  CHECK_EQ(kDECIMAL, lit->getType());
1694  CHECK_EQ(unsigned(0), lit->getScale());
1695  CHECK_EQ(unsigned(0), lit->getTypeScale());
1696  return lit->getVal<int64_t>();
1697 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
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<size_t> anonymous_namespace{RelAlgAbstractInterpreter.cpp}::indices_from_json_array ( const rapidjson::Value &  json_idx_arr)
noexcept

Definition at line 735 of file RelAlgAbstractInterpreter.cpp.

References CHECK, and CHECK_GE.

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchAggregate(), and parse_aggregate_expr().

736  {
737  CHECK(json_idx_arr.IsArray());
738  std::vector<size_t> indices;
739  for (auto json_idx_arr_it = json_idx_arr.Begin(); json_idx_arr_it != json_idx_arr.End();
740  ++json_idx_arr_it) {
741  CHECK(json_idx_arr_it->IsInt());
742  CHECK_GE(json_idx_arr_it->GetInt(), 0);
743  indices.emplace_back(json_idx_arr_it->GetInt());
744  }
745  return indices;
746 }
#define CHECK_GE(x, y)
Definition: Logger.h:200
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the caller graph for this function:

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

Definition at line 200 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by RelProject::isRenaming().

202  {
203  CHECK_LT(index, node->size());
204  if (auto join = dynamic_cast<const RelJoin*>(node)) {
205  CHECK_EQ(size_t(2), join->inputCount());
206  const auto lhs_size = join->getInput(0)->size();
207  if (index < lhs_size) {
208  return isRenamedInput(join->getInput(0), index, new_name);
209  }
210  CHECK_GE(index, lhs_size);
211  return isRenamedInput(join->getInput(1), index - lhs_size, new_name);
212  }
213 
214  if (auto scan = dynamic_cast<const RelScan*>(node)) {
215  return new_name != scan->getFieldName(index);
216  }
217 
218  if (auto aggregate = dynamic_cast<const RelAggregate*>(node)) {
219  return new_name != aggregate->getFieldName(index);
220  }
221 
222  if (auto project = dynamic_cast<const RelProject*>(node)) {
223  return new_name != project->getFieldName(index);
224  }
225 
226  if (auto logical_values = dynamic_cast<const RelLogicalValues*>(node)) {
227  const auto& tuple_type = logical_values->getTupleType();
228  CHECK_LT(index, tuple_type.size());
229  return new_name != tuple_type[index].get_resname();
230  }
231 
232  CHECK(dynamic_cast<const RelSort*>(node) || dynamic_cast<const RelFilter*>(node));
233  return isRenamedInput(node->getInput(0), index, new_name);
234 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::string join(T const &container, std::string const &delim)
#define CHECK_GE(x, y)
Definition: Logger.h:200
bool isRenamedInput(const RelAlgNode *node, const size_t index, const std::string &new_name)
const RelAlgNode * getInput(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:197
virtual size_t size() const =0
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 748 of file RelAlgAbstractInterpreter.cpp.

Referenced by parse_scalar_expr().

748  {
749  rapidjson::StringBuffer buffer;
750  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
751  node.Accept(writer);
752  return buffer.GetString();
753 }

+ Here is the caller graph for this function:

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

Definition at line 920 of file RelAlgAbstractInterpreter.cpp.

References CHECK_EQ, and RelAlgNode::markAsNop().

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::run().

920  {
921  for (auto node : nodes) {
922  const auto agg_node = std::dynamic_pointer_cast<RelAggregate>(node);
923  if (!agg_node || agg_node->getAggExprsCount()) {
924  continue;
925  }
926  CHECK_EQ(size_t(1), node->inputCount());
927  const auto agg_input_node = dynamic_cast<const RelAggregate*>(node->getInput(0));
928  if (agg_input_node && !agg_input_node->getAggExprsCount() &&
929  agg_node->getGroupByCount() == agg_input_node->getGroupByCount()) {
930  agg_node->markAsNop();
931  }
932  }
933 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 84 of file RelAlgAbstractInterpreter.cpp.

Referenced by get_node_output().

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

+ Here is the caller graph for this function:

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

Definition at line 430 of file RelAlgAbstractInterpreter.cpp.

References field(), and json_str().

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchFilter(), anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchNodes(), and anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::prev().

430  {
431  const auto& id = field(ra_node, "id");
432  return std::stoi(json_str(id));
433 }
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{RelAlgAbstractInterpreter.cpp}::parse_abstract_input ( const rapidjson::Value &  expr)
noexcept

Definition at line 439 of file RelAlgAbstractInterpreter.cpp.

References field(), and json_i64().

Referenced by parse_scalar_expr().

440  {
441  const auto& input = field(expr, "input");
442  return std::unique_ptr<RexAbstractInput>(new RexAbstractInput(json_i64(input)));
443 }
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{RelAlgAbstractInterpreter.cpp}::parse_aggregate_expr ( const rapidjson::Value &  expr)

Definition at line 755 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchAggregate().

755  {
756  const auto agg = to_agg_kind(json_str(field(expr, "agg")));
757  const auto distinct = json_bool(field(expr, "distinct"));
758  const auto agg_ti = parse_type(field(expr, "type"));
759  const auto operands = indices_from_json_array(field(expr, "operands"));
760  if (operands.size() > 1 && (operands.size() != 2 || agg != kAPPROX_COUNT_DISTINCT)) {
761  throw QueryNotSupported("Multiple arguments for aggregates aren't supported");
762  }
763  return std::unique_ptr<const RexAgg>(new RexAgg(agg, distinct, agg_ti, operands));
764 }
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
std::vector< size_t > indices_from_json_array(const rapidjson::Value &json_idx_arr) noexcept
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<RexCase> anonymous_namespace{RelAlgAbstractInterpreter.cpp}::parse_case ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor 
)

Definition at line 701 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by parse_scalar_expr().

703  {
704  const auto& operands = field(expr, "operands");
705  CHECK(operands.IsArray());
706  CHECK_GE(operands.Size(), unsigned(2));
707  std::unique_ptr<const RexScalar> else_expr;
708  std::vector<
709  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
710  expr_pair_list;
711  for (auto operands_it = operands.Begin(); operands_it != operands.End();) {
712  auto when_expr = parse_scalar_expr(*operands_it++, cat, ra_executor);
713  if (operands_it == operands.End()) {
714  else_expr = std::move(when_expr);
715  break;
716  }
717  auto then_expr = parse_scalar_expr(*operands_it++, cat, ra_executor);
718  expr_pair_list.emplace_back(std::move(when_expr), std::move(then_expr));
719  }
720  return std::unique_ptr<RexCase>(new RexCase(expr_pair_list, else_expr));
721 }
#define CHECK_GE(x, y)
Definition: Logger.h:200
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, RelAlgExecutor *ra_executor)
#define CHECK(condition)
Definition: Logger.h:187

+ 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{RelAlgAbstractInterpreter.cpp}::parse_expr_array ( const rapidjson::Value &  arr,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor 
)

Definition at line 537 of file RelAlgAbstractInterpreter.cpp.

References parse_scalar_expr().

Referenced by parse_operator().

540  {
541  std::vector<std::unique_ptr<const RexScalar>> exprs;
542  for (auto it = arr.Begin(); it != arr.End(); ++it) {
543  exprs.emplace_back(parse_scalar_expr(*it, cat, ra_executor));
544  }
545  return exprs;
546 }
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 445 of file RelAlgAbstractInterpreter.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.

445  {
446  CHECK(expr.IsObject());
447  const auto& literal = field(expr, "literal");
448  const auto type = to_sql_type(json_str(field(expr, "type")));
449  const auto target_type = to_sql_type(json_str(field(expr, "target_type")));
450  const auto scale = json_i64(field(expr, "scale"));
451  const auto precision = json_i64(field(expr, "precision"));
452  const auto type_scale = json_i64(field(expr, "type_scale"));
453  const auto type_precision = json_i64(field(expr, "type_precision"));
454  switch (type) {
455  case kDECIMAL:
456  case kINTERVAL_DAY_TIME:
458  case kTIME:
459  case kTIMESTAMP:
460  case kDATE:
461  return std::unique_ptr<RexLiteral>(new RexLiteral(json_i64(literal),
462  type,
463  target_type,
464  scale,
465  precision,
466  type_scale,
467  type_precision));
468  case kDOUBLE: {
469  if (literal.IsDouble()) {
470  return std::unique_ptr<RexLiteral>(new RexLiteral(json_double(literal),
471  type,
472  target_type,
473  scale,
474  precision,
475  type_scale,
476  type_precision));
477  }
478  CHECK(literal.IsInt64());
479  return std::unique_ptr<RexLiteral>(
480  new RexLiteral(static_cast<double>(json_i64(literal)),
481  type,
482  target_type,
483  scale,
484  precision,
485  type_scale,
486  type_precision));
487  }
488  case kTEXT:
489  return std::unique_ptr<RexLiteral>(new RexLiteral(json_str(literal),
490  type,
491  target_type,
492  scale,
493  precision,
494  type_scale,
495  type_precision));
496  case kBOOLEAN:
497  return std::unique_ptr<RexLiteral>(new RexLiteral(json_bool(literal),
498  type,
499  target_type,
500  scale,
501  precision,
502  type_scale,
503  type_precision));
504  case kNULLT:
505  return std::unique_ptr<RexLiteral>(new RexLiteral(target_type));
506  default:
507  CHECK(false);
508  }
509  CHECK(false);
510  return nullptr;
511 }
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
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
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

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

Definition at line 617 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchSort(), and parse_window_order_collation().

617  {
618  return json_str(field(collation, "nulls")) == std::string("FIRST")
621 }
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{RelAlgAbstractInterpreter.cpp}::parse_operator ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor 
)

Definition at line 656 of file RelAlgAbstractInterpreter.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().

658  {
659  const auto op_name = json_str(field(expr, "op"));
660  const bool is_quantifier =
661  op_name == std::string("PG_ANY") || op_name == std::string("PG_ALL");
662  const auto op = is_quantifier ? kFUNCTION : to_sql_op(op_name);
663  const auto& operators_json_arr = field(expr, "operands");
664  CHECK(operators_json_arr.IsArray());
665  auto operands = parse_expr_array(operators_json_arr, cat, ra_executor);
666  const auto type_it = expr.FindMember("type");
667  CHECK(type_it != expr.MemberEnd());
668  auto ti = parse_type(type_it->value);
669  if (op == kIN && expr.HasMember("subquery")) {
670  auto subquery = parse_subquery(expr, cat, ra_executor);
671  operands.emplace_back(std::move(subquery));
672  }
673  if (expr.FindMember("partition_keys") != expr.MemberEnd()) {
674  const auto& partition_keys_arr = field(expr, "partition_keys");
675  auto partition_keys = parse_expr_array(partition_keys_arr, cat, ra_executor);
676  const auto& order_keys_arr = field(expr, "order_keys");
677  auto order_keys = parse_window_order_exprs(order_keys_arr, cat, ra_executor);
678  const auto collation = parse_window_order_collation(order_keys_arr, cat, ra_executor);
679  const auto kind = parse_window_function_kind(op_name);
680  const auto lower_bound =
681  parse_window_bound(field(expr, "lower_bound"), cat, ra_executor);
682  const auto upper_bound =
683  parse_window_bound(field(expr, "upper_bound"), cat, ra_executor);
684  bool is_rows = json_bool(field(expr, "is_rows"));
685  ti.set_notnull(false);
686  return std::make_unique<RexWindowFunctionOperator>(kind,
687  operands,
688  partition_keys,
689  order_keys,
690  collation,
691  lower_bound,
692  upper_bound,
693  is_rows,
694  ti);
695  }
696  return std::unique_ptr<RexOperator>(op == kFUNCTION
697  ? new RexFunctionOperator(op_name, operands, ti)
698  : new RexOperator(op, operands, ti));
699 }
std::unique_ptr< const RexSubQuery > parse_subquery(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
std::vector< std::unique_ptr< const RexScalar > > parse_window_order_exprs(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
std::vector< std::unique_ptr< const RexScalar > > parse_expr_array(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
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
SqlWindowFunctionKind parse_window_function_kind(const std::string &name)
std::vector< SortField > parse_window_order_collation(const rapidjson::Value &arr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
SQLOps to_sql_op(const std::string &op_str)
RexWindowFunctionOperator::RexWindowBound parse_window_bound(const rapidjson::Value &window_bound_obj, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
SQLTypeInfo parse_type(const rapidjson::Value &type_obj)
Definition: sqldefs.h:53
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 766 of file RelAlgAbstractInterpreter.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 anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchFilter(), anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchJoin(), anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchProject(), parse_case(), parse_expr_array(), parse_window_bound(), and parse_window_order_exprs().

768  {
769  CHECK(expr.IsObject());
770  if (expr.IsObject() && expr.HasMember("input")) {
771  return std::unique_ptr<const RexScalar>(parse_abstract_input(expr));
772  }
773  if (expr.IsObject() && expr.HasMember("literal")) {
774  return std::unique_ptr<const RexScalar>(parse_literal(expr));
775  }
776  if (expr.IsObject() && expr.HasMember("op")) {
777  const auto op_str = json_str(field(expr, "op"));
778  if (op_str == std::string("CASE")) {
779  return std::unique_ptr<const RexScalar>(parse_case(expr, cat, ra_executor));
780  }
781  if (op_str == std::string("$SCALAR_QUERY")) {
782  return std::unique_ptr<const RexScalar>(parse_subquery(expr, cat, ra_executor));
783  }
784  return std::unique_ptr<const RexScalar>(parse_operator(expr, cat, ra_executor));
785  }
786  throw QueryNotSupported("Expression node " + json_node_to_string(expr) +
787  " not supported");
788 }
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, RelAlgExecutor *ra_executor)
std::string json_node_to_string(const rapidjson::Value &node) noexcept
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, RelAlgExecutor *ra_executor)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::unique_ptr< RexCase > parse_case(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
std::tuple< const rapidjson::Value *, SQLTypeInfo, SQLTypeInfo > parse_literal(const rapidjson::Value &expr)
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 611 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchSort(), and parse_window_order_collation().

611  {
612  return json_str(field(collation, "direction")) == std::string("DESCENDING")
615 }
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{RelAlgAbstractInterpreter.cpp}::parse_subquery ( const rapidjson::Value &  expr,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor 
)

Definition at line 1999 of file RelAlgAbstractInterpreter.cpp.

References CHECK, CHECK_GE, field(), ra_interpret(), and RelAlgExecutor::registerSubquery().

Referenced by parse_operator(), and parse_scalar_expr().

2001  {
2002  const auto& operands = field(expr, "operands");
2003  CHECK(operands.IsArray());
2004  CHECK_GE(operands.Size(), unsigned(0));
2005  const auto& subquery_ast = field(expr, "subquery");
2006 
2007  const auto ra = ra_interpret(subquery_ast, cat, ra_executor, nullptr);
2008  auto subquery = std::make_shared<RexSubQuery>(ra);
2009  ra_executor->registerSubquery(subquery);
2010  return subquery->deepCopy();
2011 }
void registerSubquery(std::shared_ptr< RexSubQuery > subquery) noexcept
#define CHECK_GE(x, y)
Definition: Logger.h:200
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
std::shared_ptr< const RelAlgNode > ra_interpret(const rapidjson::Value &query_ast, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor, const RenderQueryOptions *render_opts)
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 521 of file RelAlgAbstractInterpreter.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 anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchLogicalValues(), parse_aggregate_expr(), and parse_operator().

521  {
522  CHECK(type_obj.IsObject() &&
523  (type_obj.MemberCount() >= 2 && type_obj.MemberCount() <= 4));
524  const auto type = to_sql_type(json_str(field(type_obj, "type")));
525  const auto nullable = json_bool(field(type_obj, "nullable"));
526  const auto precision_it = type_obj.FindMember("precision");
527  const int precision =
528  precision_it != type_obj.MemberEnd() ? json_i64(precision_it->value) : 0;
529  const auto scale_it = type_obj.FindMember("scale");
530  const int scale = scale_it != type_obj.MemberEnd() ? json_i64(scale_it->value) : 0;
531  SQLTypeInfo ti(type, !nullable);
532  ti.set_precision(precision);
533  ti.set_scale(scale);
534  return ti;
535 }
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:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RexWindowFunctionOperator::RexWindowBound anonymous_namespace{RelAlgAbstractInterpreter.cpp}::parse_window_bound ( const rapidjson::Value &  window_bound_obj,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor 
)

Definition at line 636 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by parse_operator().

639  {
640  CHECK(window_bound_obj.IsObject());
642  window_bound.unbounded = json_bool(field(window_bound_obj, "unbounded"));
643  window_bound.preceding = json_bool(field(window_bound_obj, "preceding"));
644  window_bound.following = json_bool(field(window_bound_obj, "following"));
645  window_bound.is_current_row = json_bool(field(window_bound_obj, "is_current_row"));
646  const auto& offset_field = field(window_bound_obj, "offset");
647  if (offset_field.IsObject()) {
648  window_bound.offset = parse_scalar_expr(offset_field, cat, ra_executor);
649  } else {
650  CHECK(offset_field.IsNull());
651  }
652  window_bound.order_key = json_i64(field(window_bound_obj, "order_key"));
653  return window_bound;
654 }
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
std::unique_ptr< const RexScalar > parse_scalar_expr(const rapidjson::Value &expr, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor)
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 548 of file RelAlgAbstractInterpreter.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().

548  {
549  if (name == "ROW_NUMBER") {
551  }
552  if (name == "RANK") {
554  }
555  if (name == "DENSE_RANK") {
557  }
558  if (name == "PERCENT_RANK") {
560  }
561  if (name == "CUME_DIST") {
563  }
564  if (name == "NTILE") {
566  }
567  if (name == "LAG") {
569  }
570  if (name == "LEAD") {
572  }
573  if (name == "FIRST_VALUE") {
575  }
576  if (name == "LAST_VALUE") {
578  }
579  if (name == "AVG") {
581  }
582  if (name == "MIN") {
584  }
585  if (name == "MAX") {
587  }
588  if (name == "SUM") {
590  }
591  if (name == "COUNT") {
593  }
594  if (name == "$SUM0") {
596  }
597  throw std::runtime_error("Unsupported window function: " + name);
598 }

+ Here is the caller graph for this function:

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

Definition at line 623 of file RelAlgAbstractInterpreter.cpp.

References parse_nulls_position(), and parse_sort_direction().

Referenced by parse_operator().

625  {
626  std::vector<SortField> collation;
627  size_t field_idx = 0;
628  for (auto it = arr.Begin(); it != arr.End(); ++it, ++field_idx) {
629  const auto sort_dir = parse_sort_direction(*it);
630  const auto null_pos = parse_nulls_position(*it);
631  collation.emplace_back(field_idx, sort_dir, null_pos);
632  }
633  return collation;
634 }
NullSortedPosition parse_nulls_position(const rapidjson::Value &collation)
SortDirection parse_sort_direction(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{RelAlgAbstractInterpreter.cpp}::parse_window_order_exprs ( const rapidjson::Value &  arr,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor 
)

Definition at line 600 of file RelAlgAbstractInterpreter.cpp.

References field(), and parse_scalar_expr().

Referenced by parse_operator().

603  {
604  std::vector<std::unique_ptr<const RexScalar>> exprs;
605  for (auto it = arr.Begin(); it != arr.End(); ++it) {
606  exprs.emplace_back(parse_scalar_expr(field(*it, "field"), cat, ra_executor));
607  }
608  return exprs;
609 }
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, RelAlgExecutor *ra_executor)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr<const RelAlgNode> anonymous_namespace{RelAlgAbstractInterpreter.cpp}::ra_interpret ( const rapidjson::Value &  query_ast,
const Catalog_Namespace::Catalog cat,
RelAlgExecutor ra_executor,
const RenderQueryOptions render_opts 
)

Definition at line 1991 of file RelAlgAbstractInterpreter.cpp.

References anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::run().

Referenced by deserialize_ra_dag(), and parse_subquery().

1994  {
1995  RelAlgAbstractInterpreter interp(query_ast, cat, ra_executor, render_opts);
1996  return interp.run();
1997 }

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgAbstractInterpreter.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 1579 of file RelAlgAbstractInterpreter.cpp.

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

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::run().

1580  {
1581  std::list<std::shared_ptr<RelAlgNode>> node_list(nodes.begin(), nodes.end());
1582 
1583  WindowFunctionDetectionVisitor visitor;
1584  for (auto node_itr = node_list.begin(); node_itr != node_list.end(); ++node_itr) {
1585  const auto node = *node_itr;
1586  auto window_func_project_node = std::dynamic_pointer_cast<RelProject>(node);
1587  if (!window_func_project_node) {
1588  continue;
1589  }
1590 
1591  // map scalar expression index in the project node to wiondow function ptr
1592  std::unordered_map<size_t, const RexScalar*> embedded_window_function_expressions;
1593 
1594  // Iterate the target exprs of the project node and check for window function
1595  // expressions. If an embedded expression exists, save it in the
1596  // embedded_window_function_expressions map and split the expression into a window
1597  // function expression and a parent expression in a subsequent project node
1598  for (size_t i = 0; i < window_func_project_node->size(); i++) {
1599  const auto scalar_rex = window_func_project_node->getProjectAt(i);
1600  if (is_window_function_operator(scalar_rex)) {
1601  // top level window function exprs are fine
1602  continue;
1603  }
1604 
1605  if (const auto window_func_rex = visitor.visit(scalar_rex)) {
1606  const auto ret = embedded_window_function_expressions.insert(
1607  std::make_pair(i, window_func_rex));
1608  CHECK(ret.second);
1609  }
1610  }
1611 
1612  if (!embedded_window_function_expressions.empty()) {
1613  std::vector<std::unique_ptr<const RexScalar>> new_scalar_exprs;
1614 
1615  auto window_func_scalar_exprs =
1616  window_func_project_node->getExpressionsAndRelease();
1617  for (size_t rex_idx = 0; rex_idx < window_func_scalar_exprs.size(); ++rex_idx) {
1618  const auto embedded_window_func_expr_pair =
1619  embedded_window_function_expressions.find(rex_idx);
1620  if (embedded_window_func_expr_pair ==
1621  embedded_window_function_expressions.end()) {
1622  new_scalar_exprs.emplace_back(
1623  std::make_unique<const RexInput>(window_func_project_node.get(), rex_idx));
1624  } else {
1625  const auto window_func_rex_idx = embedded_window_func_expr_pair->first;
1626  CHECK_LT(window_func_rex_idx, window_func_scalar_exprs.size());
1627 
1628  const auto& window_func_rex = embedded_window_func_expr_pair->second;
1629 
1630  RexDeepCopyVisitor copier;
1631  auto window_func_rex_copy = copier.visit(window_func_rex);
1632 
1633  auto window_func_parent_expr =
1634  window_func_scalar_exprs[window_func_rex_idx].get();
1635 
1636  // Replace window func rex with an input rex
1637  auto window_func_result_input = std::make_unique<const RexInput>(
1638  window_func_project_node.get(), window_func_rex_idx);
1639  RexWindowFuncReplacementVisitor replacer(std::move(window_func_result_input));
1640  auto new_parent_rex = replacer.visit(window_func_parent_expr);
1641 
1642  // Put the parent expr in the new scalar exprs
1643  new_scalar_exprs.emplace_back(std::move(new_parent_rex));
1644 
1645  // Put the window func expr in cur scalar exprs
1646  window_func_scalar_exprs[window_func_rex_idx] = std::move(window_func_rex_copy);
1647  }
1648  }
1649 
1650  CHECK_EQ(window_func_scalar_exprs.size(), new_scalar_exprs.size());
1651  window_func_project_node->setExpressions(window_func_scalar_exprs);
1652 
1653  // Ensure any inputs from the node containing the expression (the "new" node)
1654  // exist on the window function project node, e.g. if we had a binary operation
1655  // involving an aggregate value or column not included in the top level
1656  // projection list.
1657  RexInputBackpropagationVisitor input_visitor(window_func_project_node.get());
1658  for (size_t i = 0; i < new_scalar_exprs.size(); i++) {
1659  if (dynamic_cast<const RexInput*>(new_scalar_exprs[i].get())) {
1660  // ignore top level inputs, these were copied directly from the previous
1661  // node
1662  continue;
1663  }
1664  new_scalar_exprs[i] = input_visitor.visit(new_scalar_exprs[i].get());
1665  }
1666 
1667  // Build the new project node and insert it into the list after the project node
1668  // containing the window function
1669  auto new_project =
1670  std::make_shared<RelProject>(new_scalar_exprs,
1671  window_func_project_node->getFields(),
1672  window_func_project_node);
1673  node_list.insert(std::next(node_itr), new_project);
1674 
1675  // Rebind all the following inputs
1676  for (auto rebind_itr = std::next(node_itr, 2); rebind_itr != node_list.end();
1677  rebind_itr++) {
1678  (*rebind_itr)->replaceInput(window_func_project_node, new_project);
1679  }
1680  }
1681  }
1682  nodes.assign(node_list.begin(), node_list.end());
1683 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
const RexScalar * getProjectAt(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 723 of file RelAlgAbstractInterpreter.cpp.

References CHECK.

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchAggregate(), anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchProject(), anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::getFieldNamesFromScanNode(), and anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::getRelAlgInputs().

724  {
725  CHECK(json_str_arr.IsArray());
726  std::vector<std::string> fields;
727  for (auto json_str_arr_it = json_str_arr.Begin(); json_str_arr_it != json_str_arr.End();
728  ++json_str_arr_it) {
729  CHECK(json_str_arr_it->IsString());
730  fields.emplace_back(json_str_arr_it->GetString());
731  }
732  return fields;
733 }
#define CHECK(condition)
Definition: Logger.h:187

+ Here is the caller graph for this function:

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

Definition at line 790 of file RelAlgAbstractInterpreter.cpp.

References INNER, and LEFT.

Referenced by anonymous_namespace{RelAlgAbstractInterpreter.cpp}::RelAlgAbstractInterpreter::dispatchJoin().

790  {
791  if (join_type_name == "inner") {
792  return JoinType::INNER;
793  }
794  if (join_type_name == "left") {
795  return JoinType::LEFT;
796  }
797  throw QueryNotSupported("Join type (" + join_type_name + ") not supported");
798 }

+ Here is the caller graph for this function:

Variable Documentation

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

Definition at line 35 of file RelAlgAbstractInterpreter.cpp.

Referenced by RelAlgNode::resetRelAlgFirstId().