P::PhysicalPtr InjectJoinFilters::transformHashJoinToFilters( const P::PhysicalPtr &input) const { std::vector<P::PhysicalPtr> new_children; for (const P::PhysicalPtr &child : input->children()) { new_children.emplace_back(transformHashJoinToFilters(child)); } P::HashJoinPtr hash_join; if (P::SomeHashJoin::MatchesWithConditionalCast(input, &hash_join) && isTransformable(hash_join)) { const bool is_anti_join = hash_join->join_type() == P::HashJoin::JoinType::kLeftAntiJoin; DCHECK_EQ(2u, new_children.size()); P::PhysicalPtr build_child = new_children[1]; E::PredicatePtr build_side_filter_predicate = nullptr; P::SelectionPtr selection; if (hash_join->build_predicate() == nullptr) { if (P::SomeSelection::MatchesWithConditionalCast(build_child, &selection) && E::SubsetOfExpressions(hash_join->right_join_attributes(), selection->input()->getOutputAttributes())) { build_child = selection->input(); build_side_filter_predicate = selection->filter_predicate(); } } else { build_child = hash_join->right(); build_side_filter_predicate = hash_join->build_predicate(); } return P::FilterJoin::Create(new_children[0], build_child, hash_join->left_join_attributes(), hash_join->right_join_attributes(), hash_join->project_expressions(), build_side_filter_predicate, is_anti_join, hash_join->hasRepartition(), hash_join->cloneOutputPartitionSchemeHeader()); } if (input->children() != new_children) { return input->copyWithNewChildren(new_children); } else { return input; } }
P::PhysicalPtr FuseHashSelect::applyToNode( const P::PhysicalPtr &node) { P::HashJoinPtr hash_join; // Check to see if the join is a hash join, if the hash join is an inner // join.. We also check that there are no partitions. // TODO(dbacon): Add support for other join types. if ((!P::SomeHashJoin::MatchesWithConditionalCast(node, &hash_join)) || hash_join->getOutputPartitionSchemeHeader() != nullptr) { return node; } // Get the join attributes from the build side. P::PhysicalPtr right_child = hash_join->right(); const std::vector<E::AttributeReferencePtr> &right_join_attributes = hash_join->right_join_attributes(); E::PredicatePtr build_predicate = nullptr; // Check that the build side is a Selection and that the join attributes match up. // If so, set the new hash join build side to the Selection input and the build predicate // to the selection's filter. P::SelectionPtr selection; if (P::SomeSelection::MatchesWithConditionalCast(right_child, &selection)) { if (E::SubsetOfExpressions(right_join_attributes, selection->input()->getOutputAttributes())) { right_child = selection->input(); build_predicate = selection->filter_predicate(); } } return P::HashJoin::Create(hash_join->left(), right_child, hash_join->left_join_attributes(), right_join_attributes, hash_join->residual_predicate(), build_predicate, hash_join->project_expressions(), hash_join->join_type(), hash_join->hasRepartition(), hash_join->cloneOutputPartitionSchemeHeader()); }