Skip to content

Commit

Permalink
✅ Fix failing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
janetzki committed Sep 5, 2019
1 parent 91bb569 commit 1e77722
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 98 deletions.
109 changes: 19 additions & 90 deletions src/lib/optimizer/strategy/predicate_merge_rule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,73 +8,6 @@

namespace opossum {

//bool PredicateMergeRule::_mergeConjunction(const std::shared_ptr<PredicateNode>& predicate_node) const {
// const auto flat_conjunction = flatten_logical_expressions(predicate_node->predicate(), LogicalOperator::And);
// if (flat_conjunction.size() <= 1) {
// return false;
// }
//
// /**
// * Split up PredicateNode with conjunctive chain (e.g., `PredicateNode(a AND b AND c)`) as its scan expression into
// * multiple consecutive PredicateNodes (e.g. `PredicateNode(c) -> PredicateNode(b) -> PredicateNode(a)`).
// */
// for (const auto& predicate_expression : flat_conjunction) {
// const auto& new_predicate_node = PredicateNode::make(predicate_expression);
// lqp_insert_node(predicate_node, LQPInputSide::Left, new_predicate_node);
// _mergeDisjunction(new_predicate_node);
// }
// lqp_remove_node(predicate_node);

// if (const auto child_predicate = std::dynamic_pointer_cast<PredicateNode>(predicate_node->left_input())) {
// if (child_predicate->output_count() == 1) {
// and_()
// predicate_node->node_expressions[0] = and_(predicate_node->predicate(), child_predicate->predicate());
// lqp_remove_node(child_predicate);
// }
// }
//
// return true;
//}

//void PredicateMergeRule::_mergeDisjunction(const std::shared_ptr<UnionNode>& union_node) const {
// if (!_split_disjunction) {
// return;
// }
//
// const auto flat_disjunction = flatten_logical_expressions(predicate_node->predicate(), LogicalOperator::Or);
// if (flat_disjunction.size() <= 1) {
// return;
// }
//
// /**
// * Split up PredicateNode with disjunctive chain (e.g., `PredicateNode(a OR b OR c)`) as their scan expression into
// * n-1 consecutive UnionNodes and n PredicateNodes.
// */
// auto previous_union_node = UnionNode::make(UnionMode::Positions);
// const auto left_input = predicate_node->left_input();
// lqp_replace_node(predicate_node, previous_union_node);
//
// auto new_predicate_node = PredicateNode::make(flat_disjunction[0], left_input);
// previous_union_node->set_left_input(new_predicate_node);
// _mergeConjunction(new_predicate_node);
//
// new_predicate_node = PredicateNode::make(flat_disjunction[1], left_input);
// previous_union_node->set_right_input(new_predicate_node);
// _mergeConjunction(new_predicate_node);
//
// for (auto disjunction_idx = size_t{2}; disjunction_idx < flat_disjunction.size(); ++disjunction_idx) {
// const auto& predicate_expression = flat_disjunction[disjunction_idx];
// auto next_union_node = UnionNode::make(UnionMode::Positions);
// lqp_insert_node(previous_union_node, LQPInputSide::Right, next_union_node);
//
// new_predicate_node = PredicateNode::make(predicate_expression, left_input);
// next_union_node->set_right_input(new_predicate_node);
// _mergeConjunction(new_predicate_node);
//
// previous_union_node = next_union_node;
// }
//}

/**
* Function creates a boolean expression from an lqp. It traverses the passed lqp from top to bottom. However, an lqp is
* evaluated from bottom to top. This requires that the order in which the translated expressions are added to the
Expand All @@ -83,18 +16,16 @@ namespace opossum {
* child node before its parent node to the output expression.
*/
std::shared_ptr<AbstractExpression> lqp_subplan_to_boolean_expression_impl(
const std::shared_ptr<AbstractLQPNode> &begin, const std::optional<const std::shared_ptr<AbstractLQPNode>> &end,
const std::shared_ptr<AbstractLQPNode> &begin,
const std::optional<const std::shared_ptr<AbstractExpression>> &subsequent_expression) {
if (end && begin == *end) return nullptr;

switch (begin->type) {
case LQPNodeType::Predicate: {
const auto predicate_node = std::dynamic_pointer_cast<PredicateNode>(begin);
const auto predicate = predicate_node->predicate();
const auto expression = subsequent_expression ? expression_functional::and_(predicate, *subsequent_expression) : predicate;
const auto left_input_expression = lqp_subplan_to_boolean_expression_impl(begin->left_input(), end, expression);
if (left_input_expression) {
std::cout << *left_input_expression << std::endl;
const auto left_input_expression = lqp_subplan_to_boolean_expression_impl(begin->left_input(), expression);
if (begin->left_input()->output_count() == 1 && left_input_expression) { // Do not merge predicate nodes with nodes that have multiple outputs because this would unnecessarily inflate the resulting logical expression. Instead, wait until the lower node has only one output. This is the case after a diamond was resolved.
// std::cout << *left_input_expression << std::endl;
lqp_remove_node(begin->left_input());
predicate_node->node_expressions[0] = left_input_expression;
return left_input_expression;
Expand All @@ -105,25 +36,23 @@ std::shared_ptr<AbstractExpression> lqp_subplan_to_boolean_expression_impl(

case LQPNodeType::Union: {
const auto union_node = std::dynamic_pointer_cast<UnionNode>(begin);
const auto left_input_expression = lqp_subplan_to_boolean_expression_impl(begin->left_input(), end,
std::nullopt);
const auto left_input_expression = lqp_subplan_to_boolean_expression_impl(begin->left_input(), std::nullopt);
const auto right_input_expression =
lqp_subplan_to_boolean_expression_impl(begin->right_input(), end, std::nullopt);
lqp_subplan_to_boolean_expression_impl(begin->right_input(), std::nullopt);
if (left_input_expression && right_input_expression) {
std::cout << *left_input_expression << std::endl;
std::cout << *right_input_expression << std::endl;
const auto or_expression = expression_functional::or_(left_input_expression, right_input_expression);
const auto expression = subsequent_expression ? expression_functional::and_(or_expression, *subsequent_expression) : or_expression;
// std::cout << *left_input_expression << std::endl;
// std::cout << *right_input_expression << std::endl;
const auto expression = expression_functional::or_(left_input_expression, right_input_expression);

std::cout << "prepare merge" << std::endl;
// std::cout << "prepare merge" << std::endl;
lqp_remove_node(begin->left_input());
lqp_remove_node(begin->right_input());
const auto predicate_node = PredicateNode::make(expression);
lqp_replace_node(begin, predicate_node);
Assert(!predicate_node->right_input() || predicate_node->left_input() == predicate_node->right_input(), "The new predicate node must not have two different inputs");
predicate_node->set_right_input(nullptr);
std::cout << "merge" << std::endl;
return expression;
// std::cout << "merge" << std::endl;
return lqp_subplan_to_boolean_expression_impl(predicate_node, std::nullopt); // The new predicate node might be mergeable with an underlying node now
} else {
return nullptr;
}
Expand All @@ -137,8 +66,8 @@ std::shared_ptr<AbstractExpression> lqp_subplan_to_boolean_expression_impl(
// Function wraps the call to the lqp_subplan_to_boolean_expression_impl() function to hide its third parameter,
// subsequent_predicate, which is only used internally.
std::shared_ptr<AbstractExpression> PredicateMergeRule::_lqp_subplan_to_boolean_expression(
const std::shared_ptr<AbstractLQPNode>& begin, const std::optional<const std::shared_ptr<AbstractLQPNode>>& end) const {
return lqp_subplan_to_boolean_expression_impl(begin, end, std::nullopt);
const std::shared_ptr<AbstractLQPNode>& begin) const {
return lqp_subplan_to_boolean_expression_impl(begin, std::nullopt);
}

void PredicateMergeRule::apply_to(const std::shared_ptr<AbstractLQPNode>& node) const {
Expand All @@ -162,7 +91,7 @@ void PredicateMergeRule::apply_to(const std::shared_ptr<AbstractLQPNode>& node)
}
});

std::cout << "BBB: " << break_nodes.size() << std::endl;
// std::cout << "BBB: " << break_nodes.size() << std::endl;
for (const auto& next_node : break_nodes) {
apply_to(next_node->left_input());
apply_to(next_node->right_input());
Expand All @@ -171,10 +100,10 @@ void PredicateMergeRule::apply_to(const std::shared_ptr<AbstractLQPNode>& node)
// // _splitConjunction() and _splitDisjunction() split up logical expressions by calling each other recursively
// std::cout << "BBB: " << top_nodes.size() << std::endl;
// for (const auto& top_node : top_nodes) {
const auto merged_expr = _lqp_subplan_to_boolean_expression(node, std::nullopt);
if (merged_expr) {
std::cout << "AAAAA: " << *merged_expr << std::endl;
}
const auto merged_expr = _lqp_subplan_to_boolean_expression(node);
// if (merged_expr) {
//// std::cout << "AAAAA: " << *merged_expr << std::endl;
// }

// if (!_mergeConjunction(predicate_node)) {
// // If there is no conjunction at the top level, try to split disjunction first
Expand Down
11 changes: 3 additions & 8 deletions src/lib/optimizer/strategy/predicate_merge_rule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,9 @@ class PredicateMergeRule : public AbstractRule {
void apply_to(const std::shared_ptr<AbstractLQPNode>& node) const override;

private:
// /**
// * @return true if a conjunction was split up
// */
// bool _mergeConjunction(const std::shared_ptr<PredicateNode>& predicate_node) const;
// void _mergeDisjunction(const std::shared_ptr<UnionNode>& union_node) const;
std::shared_ptr<AbstractExpression> _lqp_subplan_to_boolean_expression(
const std::shared_ptr<AbstractLQPNode>& begin,
const std::optional<const std::shared_ptr<AbstractLQPNode>>& end = std::nullopt) const;
// std::shared_ptr<AbstractExpression> _mergeConjunction(const std::shared_ptr<PredicateNode>& predicate_node, const std::optional<const std::shared_ptr<AbstractExpression>> &subsequent_expression = std::nullopt) const;
// std::shared_ptr<AbstractExpression> _mergeDisjunction(const std::shared_ptr<UnionNode>& union_node) const;
std::shared_ptr<AbstractExpression> _lqp_subplan_to_boolean_expression(const std::shared_ptr<AbstractLQPNode>& begin) const;
};

} // namespace opossum

0 comments on commit 1e77722

Please sign in to comment.