OmniSciDB  d2f719934e
 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 "RelAlgDagBuilder.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 282 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().

282  {
283  std::list<std::shared_ptr<RelAlgNode>> new_nodes;
284  for (auto& left_deep_join_candidate : nodes) {
285  std::shared_ptr<RelLeftDeepInnerJoin> left_deep_join;
286  std::shared_ptr<const RelAlgNode> old_root;
287  std::tie(left_deep_join, old_root) = create_left_deep_join(left_deep_join_candidate);
288  if (!left_deep_join) {
289  continue;
290  }
291  CHECK_GE(left_deep_join->inputCount(), size_t(2));
292  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
293  ++nesting_level) {
294  const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
295  if (outer_condition) {
296  rebind_inputs_from_left_deep_join(outer_condition, left_deep_join.get());
297  }
298  }
299  rebind_inputs_from_left_deep_join(left_deep_join->getInnerCondition(),
300  left_deep_join.get());
301  for (auto& node : nodes) {
302  if (node && node->hasInput(old_root.get())) {
303  node->replaceInput(left_deep_join_candidate, left_deep_join);
304  std::shared_ptr<const RelJoin> old_join;
305  if (std::dynamic_pointer_cast<const RelJoin>(left_deep_join_candidate)) {
306  old_join = std::static_pointer_cast<const RelJoin>(left_deep_join_candidate);
307  } else {
308  CHECK_EQ(size_t(1), left_deep_join_candidate->inputCount());
309  old_join = std::dynamic_pointer_cast<const RelJoin>(
310  left_deep_join_candidate->getAndOwnInput(0));
311  }
312  while (old_join) {
313  node->replaceInput(old_join, left_deep_join);
314  old_join =
315  std::dynamic_pointer_cast<const RelJoin>(old_join->getAndOwnInput(0));
316  }
317  }
318  }
319 
320  new_nodes.emplace_back(std::move(left_deep_join));
321  }
322 
323  // insert the new left join nodes to the front of the owned RelAlgNode list.
324  // This is done to ensure all created RelAlgNodes exist in this list for later
325  // visitation, such as RelAlgDagBuilder::resetQueryExecutionState.
326  nodes.insert(nodes.begin(), new_nodes.begin(), new_nodes.end());
327 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
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:224
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 253 of file RelLeftDeepInnerJoin.cpp.

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

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

254  {
255  const auto left_deep_join_filter = dynamic_cast<const RelFilter*>(node.get());
256  if (left_deep_join_filter) {
257  const auto join = dynamic_cast<const RelJoin*>(left_deep_join_filter->getInput(0));
258  if (!join) {
259  return nullptr;
260  }
261  if (join->getJoinType() == JoinType::INNER || join->getJoinType() == JoinType::SEMI ||
262  join->getJoinType() == JoinType::ANTI) {
263  return node;
264  }
265  }
266  if (!node || node->inputCount() != 1) {
267  return nullptr;
268  }
269  const auto join = dynamic_cast<const RelJoin*>(node->getInput(0));
270  if (!join) {
271  return nullptr;
272  }
273  return node->getAndOwnInput(0);
274 }
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 276 of file RelLeftDeepInnerJoin.cpp.

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

277  {
278  RebindRexInputsFromLeftDeepJoin rebind_rex_inputs_from_left_deep_join(left_deep_join);
279  rebind_rex_inputs_from_left_deep_join.visit(rex);
280 }

+ Here is the caller graph for this function: