OmniSciDB  cde582ebc3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RelLeftDeepInnerJoin.cpp File Reference
#include "RelLeftDeepInnerJoin.h"
#include "Logger/Logger.h"
#include "RelAlgDag.h"
#include "RexVisitor.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 293 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().

293  {
294  std::list<std::shared_ptr<RelAlgNode>> new_nodes;
295  for (auto& left_deep_join_candidate : nodes) {
296  std::shared_ptr<RelLeftDeepInnerJoin> left_deep_join;
297  std::shared_ptr<const RelAlgNode> old_root;
298  std::tie(left_deep_join, old_root) = create_left_deep_join(left_deep_join_candidate);
299  if (!left_deep_join) {
300  continue;
301  }
302  CHECK_GE(left_deep_join->inputCount(), size_t(2));
303  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
304  ++nesting_level) {
305  const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
306  if (outer_condition) {
307  rebind_inputs_from_left_deep_join(outer_condition, left_deep_join.get());
308  }
309  }
310  rebind_inputs_from_left_deep_join(left_deep_join->getInnerCondition(),
311  left_deep_join.get());
312  for (auto& node : nodes) {
313  if (node && node->hasInput(old_root.get())) {
314  node->replaceInput(left_deep_join_candidate, left_deep_join);
315  std::shared_ptr<const RelJoin> old_join;
316  if (std::dynamic_pointer_cast<const RelJoin>(left_deep_join_candidate)) {
317  old_join = std::static_pointer_cast<const RelJoin>(left_deep_join_candidate);
318  } else {
319  CHECK_EQ(size_t(1), left_deep_join_candidate->inputCount());
320  old_join = std::dynamic_pointer_cast<const RelJoin>(
321  left_deep_join_candidate->getAndOwnInput(0));
322  }
323  while (old_join) {
324  node->replaceInput(old_join, left_deep_join);
325  old_join =
326  std::dynamic_pointer_cast<const RelJoin>(old_join->getAndOwnInput(0));
327  }
328  }
329  }
330 
331  new_nodes.emplace_back(std::move(left_deep_join));
332  }
333 
334  // insert the new left join nodes to the front of the owned RelAlgNode list.
335  // This is done to ensure all created RelAlgNodes exist in this list for later
336  // visitation, such as RelAlgDag::resetQueryExecutionState.
337  nodes.insert(nodes.begin(), new_nodes.begin(), new_nodes.end());
338 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
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:235
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
Definition: RelAlgDag.cpp:527
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 264 of file RelLeftDeepInnerJoin.cpp.

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

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

265  {
266  const auto left_deep_join_filter = dynamic_cast<const RelFilter*>(node.get());
267  if (left_deep_join_filter) {
268  const auto join = dynamic_cast<const RelJoin*>(left_deep_join_filter->getInput(0));
269  if (!join) {
270  return nullptr;
271  }
272  if (join->getJoinType() == JoinType::INNER || join->getJoinType() == JoinType::SEMI ||
273  join->getJoinType() == JoinType::ANTI) {
274  return node;
275  }
276  }
277  if (!node || node->inputCount() != 1) {
278  return nullptr;
279  }
280  const auto join = dynamic_cast<const RelJoin*>(node->getInput(0));
281  if (!join) {
282  return nullptr;
283  }
284  return node->getAndOwnInput(0);
285 }
std::string join(T const &container, std::string const &delim)
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const
Definition: RelAlgDag.h:831

+ 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 287 of file RelLeftDeepInnerJoin.cpp.

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

288  {
289  RebindRexInputsFromLeftDeepJoin rebind_rex_inputs_from_left_deep_join(left_deep_join);
290  rebind_rex_inputs_from_left_deep_join.visit(rex);
291 }

+ Here is the caller graph for this function: