OmniSciDB  a5dc49c757
 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 286 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().

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

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

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

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

281  {
282  RebindRexInputsFromLeftDeepJoin rebind_rex_inputs_from_left_deep_join(left_deep_join);
283  rebind_rex_inputs_from_left_deep_join.visit(rex);
284 }

+ Here is the caller graph for this function: