OmniSciDB  72180abbfe
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RelLeftDeepInnerJoin.cpp File Reference
#include "RelLeftDeepInnerJoin.h"
#include "RelAlgDagBuilder.h"
#include "RexVisitor.h"
#include "Shared/Logger.h"
#include <numeric>
+ Include dependency graph for RelLeftDeepInnerJoin.cpp:

Go to the source code of this file.

Classes

class  anonymous_namespace{RelLeftDeepInnerJoin.cpp}::RebindRexInputsFromLeftDeepJoin
 

Namespaces

 anonymous_namespace{RelLeftDeepInnerJoin.cpp}
 

Functions

void anonymous_namespace{RelLeftDeepInnerJoin.cpp}::collect_left_deep_join_inputs (std::deque< std::shared_ptr< const RelAlgNode >> &inputs, std::vector< std::shared_ptr< const RelJoin >> &original_joins, const std::shared_ptr< const RelJoin > &join)
 
std::pair< std::shared_ptr
< RelLeftDeepInnerJoin >
, std::shared_ptr< const
RelAlgNode > > 
anonymous_namespace{RelLeftDeepInnerJoin.cpp}::create_left_deep_join (const std::shared_ptr< RelAlgNode > &left_deep_join_root)
 
std::shared_ptr< const RelAlgNodeget_left_deep_join_root (const std::shared_ptr< RelAlgNode > &node)
 
void rebind_inputs_from_left_deep_join (const RexScalar *rex, const RelLeftDeepInnerJoin *left_deep_join)
 
void create_left_deep_join (std::vector< std::shared_ptr< RelAlgNode >> &nodes)
 

Function Documentation

void create_left_deep_join ( std::vector< std::shared_ptr< RelAlgNode >> &  nodes)

Definition at line 252 of file RelLeftDeepInnerJoin.cpp.

References CHECK_EQ, CHECK_GE, anonymous_namespace{RelLeftDeepInnerJoin.cpp}::create_left_deep_join(), rebind_inputs_from_left_deep_join(), and RelJoin::replaceInput().

252  {
253  std::list<std::shared_ptr<RelAlgNode>> new_nodes;
254  for (auto& left_deep_join_candidate : nodes) {
255  std::shared_ptr<RelLeftDeepInnerJoin> left_deep_join;
256  std::shared_ptr<const RelAlgNode> old_root;
257  std::tie(left_deep_join, old_root) = create_left_deep_join(left_deep_join_candidate);
258  if (!left_deep_join) {
259  continue;
260  }
261  CHECK_GE(left_deep_join->inputCount(), size_t(2));
262  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
263  ++nesting_level) {
264  const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
265  if (outer_condition) {
266  rebind_inputs_from_left_deep_join(outer_condition, left_deep_join.get());
267  }
268  }
269  rebind_inputs_from_left_deep_join(left_deep_join->getInnerCondition(),
270  left_deep_join.get());
271  for (auto& node : nodes) {
272  if (node && node->hasInput(old_root.get())) {
273  node->replaceInput(left_deep_join_candidate, left_deep_join);
274  std::shared_ptr<const RelJoin> old_join;
275  if (std::dynamic_pointer_cast<const RelJoin>(left_deep_join_candidate)) {
276  old_join = std::static_pointer_cast<const RelJoin>(left_deep_join_candidate);
277  } else {
278  CHECK_EQ(size_t(1), left_deep_join_candidate->inputCount());
279  old_join = std::dynamic_pointer_cast<const RelJoin>(
280  left_deep_join_candidate->getAndOwnInput(0));
281  }
282  while (old_join) {
283  node->replaceInput(old_join, left_deep_join);
284  old_join =
285  std::dynamic_pointer_cast<const RelJoin>(old_join->getAndOwnInput(0));
286  }
287  }
288  }
289 
290  new_nodes.emplace_back(std::move(left_deep_join));
291  }
292 
293  // insert the new left join nodes to the front of the owned RelAlgNode list.
294  // This is done to ensure all created RelAlgNodes exist in this list for later
295  // visitation, such as RelAlgDagBuilder::resetQueryExecutionState.
296  nodes.insert(nodes.begin(), new_nodes.begin(), new_nodes.end());
297 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::pair< std::shared_ptr< RelLeftDeepInnerJoin >, std::shared_ptr< const RelAlgNode > > create_left_deep_join(const std::shared_ptr< RelAlgNode > &left_deep_join_root)
#define CHECK_GE(x, y)
Definition: Logger.h:210
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
void rebind_inputs_from_left_deep_join(const RexScalar *rex, const RelLeftDeepInnerJoin *left_deep_join)

+ Here is the call graph for this function:

std::shared_ptr<const RelAlgNode> get_left_deep_join_root ( const std::shared_ptr< RelAlgNode > &  node)

Definition at line 224 of file RelLeftDeepInnerJoin.cpp.

References RelAlgNode::getAndOwnInput(), INNER, and join().

Referenced by RelAlgDagBuilder::build(), and anonymous_namespace{RelLeftDeepInnerJoin.cpp}::create_left_deep_join().

225  {
226  const auto left_deep_join_filter = dynamic_cast<const RelFilter*>(node.get());
227  if (left_deep_join_filter) {
228  const auto join = dynamic_cast<const RelJoin*>(left_deep_join_filter->getInput(0));
229  if (!join) {
230  return nullptr;
231  }
232  if (join->getJoinType() == JoinType::INNER) {
233  return node;
234  }
235  }
236  if (!node || node->inputCount() != 1) {
237  return nullptr;
238  }
239  const auto join = dynamic_cast<const RelJoin*>(node->getInput(0));
240  if (!join) {
241  return nullptr;
242  }
243  return node->getAndOwnInput(0);
244 }
std::string join(T const &container, std::string const &delim)
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rebind_inputs_from_left_deep_join ( const RexScalar rex,
const RelLeftDeepInnerJoin left_deep_join 
)

Definition at line 246 of file RelLeftDeepInnerJoin.cpp.

Referenced by create_left_deep_join(), and anonymous_namespace{RelAlgDagBuilder.cpp}::RexRebindInputsVisitor::visitInput().

247  {
248  RebindRexInputsFromLeftDeepJoin rebind_rex_inputs_from_left_deep_join(left_deep_join);
249  rebind_rex_inputs_from_left_deep_join.visit(rex);
250 }

+ Here is the caller graph for this function: