You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@quickstep.apache.org by jianqiao <gi...@git.apache.org> on 2017/01/30 18:40:00 UTC

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

GitHub user jianqiao opened a pull request:

    https://github.com/apache/incubator-quickstep/pull/174

    Push down disjunctive predicates to filter small-cardinality stored relation early.

    This PR implements an optimization (physical plan transformation) that pushes down disjunctive predicate to filter stored relations early when proper conditions are met.
    
    Here we elaborate the conditions. Let
    ```
    P = p_{1,1} AND ... AND p_{1, m_1}
        OR
        ...
        OR
        p_{n,1} AND ... AND p_{n, m_n}
    ```
    be a predicate in _disjunctive normal form_.
     
    Now consider each small-cardinality relation R, if for each `i` in `1..n`, there exists at least one predicate `p_{i, k_i}` that is applicable to R. Then we can construct a new predicate
    ```
    P' = p_{1, k_1} OR ... OR p_{n, k_n}
    ```
    and push down `P'` to be applied to R.
     
    Also, if any conjunctive component in `P` contains more than one predicate that is applicable to R, then we can combine all these applicable predicates as a conjunctive component in `P'`.
     
    Finally, note that if there exists a conjunctive component that contains no predicate applicable to R. Then the condition fails and we cannot do a push down for R.
    
    This optimization improves the performance of TPC-H Q07 from ~17 seconds to ~4 seconds, with SF100 on a cloudlab machine.

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/apache/incubator-quickstep push-down-disjunctive-predicate

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/incubator-quickstep/pull/174.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #174
    
----
commit 6a184c8ad981343dd50f04c76d3937bcdce34ddc
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Date:   2017-01-30T07:02:19Z

    Push down low cost disjunctive predicates to filter the stored relations early

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98710964
  
    --- Diff: query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp ---
    @@ -0,0 +1,118 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *   http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + **/
    +
    +#ifndef QUICKSTEP_QUERY_OPTIMIZER_RULES_PUSH_DOWN_LOW_COST_DISJUNCTIVE_PREDICATE_HPP_
    +#define QUICKSTEP_QUERY_OPTIMIZER_RULES_PUSH_DOWN_LOW_COST_DISJUNCTIVE_PREDICATE_HPP_
    +
    +#include <cstddef>
    +#include <map>
    +#include <memory>
    +#include <string>
    +#include <utility>
    +#include <vector>
    +
    +#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
    +#include "query_optimizer/expressions/AttributeReference.hpp"
    +#include "query_optimizer/expressions/Predicate.hpp"
    +#include "query_optimizer/physical/Physical.hpp"
    +#include "query_optimizer/rules/Rule.hpp"
    +#include "utility/Macros.hpp"
    +
    +namespace quickstep {
    +namespace optimizer {
    +
    +/** \addtogroup OptimizerRules
    + *  @{
    + */
    +
    +/**
    + * @brief Rule that applies to a physical plan to push down low-cost disjunctive
    + *        predicate when proper conditions are met.
    + *
    + * Here we elaborate the conditions.
    + *
    + * Let
    + *   P = p_{1,1} AND ... AND p_{1, m_1} OR ... OR p_{n,1} AND ... AND p_{n, m_n}
    + * be a predicate in disjunctive normal form.
    + *
    + * Now consider each small-cardinality relation R, if for each i in 1..n, there
    + * exists at least one predicate p_{i, k_i} that is applicable to R. Then we can
    + * construct a new predicate
    + *   P' = p_{1, k_1} OR ... OR p_{n, k_n}
    + * and push down P' to be applied to R.
    + *
    + * Also, if any conjunctive component in P contains more than one predicate that
    + * is applicable to R, then we can combine all these applicable predicates as a
    + * conjunctive component in P'.
    + *
    + * Finally, note that if there exists a conjunctive component that contains no
    + * predicate applicable to R. Then the condition fails and we cannot do a push
    + * down for R.
    + */
    +class PushDownLowCostDisjunctivePredicate : public Rule<physical::Physical> {
    + public:
    +  /**
    +   * @brief Constructor.
    +   */
    +  PushDownLowCostDisjunctivePredicate() {}
    +
    +  ~PushDownLowCostDisjunctivePredicate() override {}
    +
    +  std::string getName() const override {
    +    return "PushDownLowCostDisjunctivePredicate";
    +  }
    +
    +  physical::PhysicalPtr apply(const physical::PhysicalPtr &input) override;
    +
    + private:
    +  struct PredicateInfo {
    +    PredicateInfo() {}
    +    inline void add(expressions::PredicatePtr predicate) {
    +      predicates.emplace_back(predicate);
    +    }
    +    std::vector<expressions::PredicatePtr> predicates;
    +  };
    +
    +  void collectApplicablePredicates(const physical::PhysicalPtr &input);
    +  physical::PhysicalPtr attachPredicates(const physical::PhysicalPtr &input) const;
    --- End diff --
    
    Updated.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98692800
  
    --- Diff: query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp ---
    @@ -0,0 +1,218 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *   http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + **/
    +
    +#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
    +
    +#include <cstddef>
    +#include <vector>
    +
    +#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
    +#include "query_optimizer/expressions/AttributeReference.hpp"
    +#include "query_optimizer/expressions/ExpressionUtil.hpp"
    +#include "query_optimizer/expressions/LogicalAnd.hpp"
    +#include "query_optimizer/expressions/LogicalOr.hpp"
    +#include "query_optimizer/expressions/PatternMatcher.hpp"
    +#include "query_optimizer/expressions/Predicate.hpp"
    +#include "query_optimizer/physical/Aggregate.hpp"
    +#include "query_optimizer/physical/HashJoin.hpp"
    +#include "query_optimizer/physical/NestedLoopsJoin.hpp"
    +#include "query_optimizer/physical/PatternMatcher.hpp"
    +#include "query_optimizer/physical/Physical.hpp"
    +#include "query_optimizer/physical/PhysicalType.hpp"
    +#include "query_optimizer/physical/Selection.hpp"
    +#include "query_optimizer/physical/TableReference.hpp"
    +#include "query_optimizer/physical/TopLevelPlan.hpp"
    +
    +#include "glog/logging.h"
    +
    +namespace quickstep {
    +namespace optimizer {
    +
    +namespace E = ::quickstep::optimizer::expressions;
    +namespace P = ::quickstep::optimizer::physical;
    +
    +P::PhysicalPtr PushDownLowCostDisjunctivePredicate::apply(const P::PhysicalPtr &input) {
    +  DCHECK(input->getPhysicalType() == P::PhysicalType::kTopLevelPlan);
    +
    +  const P::TopLevelPlanPtr top_level_plan =
    +     std::static_pointer_cast<const P::TopLevelPlan>(input);
    +  cost_model_.reset(
    +      new cost::StarSchemaSimpleCostModel(
    +          top_level_plan->shared_subplans()));
    +
    +  collectApplicablePredicates(input);
    +
    +  if (!applicable_predicates_.empty()) {
    +    // Apply the selected predicates to stored relations.
    +    return attachPredicates(input);
    +  } else {
    +    return input;
    +  }
    +}
    +
    +void PushDownLowCostDisjunctivePredicate::collectApplicablePredicates(
    +    const physical::PhysicalPtr &input) {
    +  P::TableReferencePtr table_reference;
    +  if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
    +    // Consider only stored relations with small cardinality as targets.
    +    if (cost_model_->estimateCardinality(input) <= 100u) {
    +      applicable_nodes_.emplace_back(input, &table_reference->attribute_list());
    +    }
    +    return;
    +  }
    +
    +  for (const auto &child : input->children()) {
    +    collectApplicablePredicates(child);
    +  }
    +
    +  E::PredicatePtr filter_predicate = nullptr;
    +  switch (input->getPhysicalType()) {
    +    case P::PhysicalType::kAggregate: {
    +      filter_predicate =
    +          std::static_pointer_cast<const P::Aggregate>(input)->filter_predicate();
    +      break;
    +    }
    +    case P::PhysicalType::kHashJoin: {
    +      const P::HashJoinPtr hash_join =
    +          std::static_pointer_cast<const P::HashJoin>(input);
    +      if (hash_join->join_type() == P::HashJoin::JoinType::kInnerJoin) {
    +        filter_predicate = hash_join->residual_predicate();
    +      }
    +      break;
    +    }
    +    case P::PhysicalType::kNestedLoopsJoin: {
    +      filter_predicate =
    +          std::static_pointer_cast<const P::NestedLoopsJoin>(input)->join_predicate();
    +      break;
    +    }
    +    case P::PhysicalType::kSelection: {
    +      filter_predicate =
    +          std::static_pointer_cast<const P::Selection>(input)->filter_predicate();
    +      break;
    +    }
    +    default:
    +      break;
    +  }
    +
    +  E::LogicalOrPtr disjunctive_predicate;
    +  if (filter_predicate == nullptr ||
    +      !E::SomeLogicalOr::MatchesWithConditionalCast(filter_predicate, &disjunctive_predicate)) {
    +    return;
    +  }
    +
    +  // Consider only disjunctive normal form, i.e. disjunction of conjunctions.
    +  // Divide the disjunctive components into groups.
    +  std::vector<std::vector<E::PredicatePtr>> candidate_predicates;
    +  std::vector<std::vector<std::vector<E::AttributeReferencePtr>>> candidate_attributes;
    +  for (const auto &conjunctive_predicate : disjunctive_predicate->operands()) {
    +    candidate_predicates.emplace_back();
    +    candidate_attributes.emplace_back();
    +    E::LogicalAndPtr logical_and;
    +    if (E::SomeLogicalAnd::MatchesWithConditionalCast(conjunctive_predicate, &logical_and)) {
    +      for (const auto &predicate : logical_and->operands()) {
    +        candidate_predicates.back().emplace_back(predicate);
    +        candidate_attributes.back().emplace_back(
    +            predicate->getReferencedAttributes());
    +      }
    +    } else {
    +      candidate_predicates.back().emplace_back(conjunctive_predicate);
    +      candidate_attributes.back().emplace_back(
    +          conjunctive_predicate->getReferencedAttributes());
    +    }
    +  }
    +
    +  // Check whether the conditions are met for pushing down part of the predicates
    +  // to each small-cardinality stored relation.
    +  for (const auto &node_pair : applicable_nodes_) {
    +    const std::vector<E::AttributeReferencePtr> &target_attributes = *node_pair.second;
    +    std::vector<E::PredicatePtr> selected_disj_preds;
    +    for (std::size_t i = 0; i < candidate_predicates.size(); ++i) {
    +      const auto &cand_preds = candidate_predicates[i];
    +      const auto &cand_attrs = candidate_attributes[i];
    +
    +      std::vector<E::PredicatePtr> selected_conj_preds;
    +      for (std::size_t j = 0; j < cand_preds.size(); ++j) {
    +        if (E::SubsetOfExpressions(cand_attrs[j], target_attributes)) {
    +          selected_conj_preds.emplace_back(cand_preds[j]);
    +        }
    +      }
    +      if (selected_conj_preds.empty()) {
    +        // Not every disjunctive component contains a predicate that can be applied
    +        // to the table reference node -- condition failed, exit.
    +        selected_disj_preds.clear();
    +        break;
    +      } else {
    +        selected_disj_preds.emplace_back(
    +            CreateConjunctive(selected_conj_preds));
    +      }
    +    }
    +    if (!selected_disj_preds.empty()) {
    +      applicable_predicates_[node_pair.first].add(
    +          CreateDisjunctive(selected_disj_preds));
    +    }
    +  }
    +}
    +
    +P::PhysicalPtr PushDownLowCostDisjunctivePredicate::attachPredicates(
    +    const P::PhysicalPtr &input) const {
    +  std::vector<P::PhysicalPtr> new_children;
    +  for (const P::PhysicalPtr &child : input->children()) {
    +    const P::PhysicalPtr new_child = attachPredicates(child);
    +    new_children.push_back(new_child);
    +  }
    +
    +  const P::PhysicalPtr output =
    +      new_children == input->children() ? input
    +                                        : input->copyWithNewChildren(new_children);
    +
    +  const auto &node_it = applicable_predicates_.find(input);
    +  if (node_it != applicable_predicates_.end()) {
    +    const E::PredicatePtr filter_predicate =
    +        CreateConjunctive(node_it->second.predicates);
    +    return P::Selection::Create(output,
    +                                E::ToNamedExpressions(output->getOutputAttributes()),
    +                                filter_predicate);
    +  }
    +
    +  return output;
    +}
    +
    +E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateConjunctive(
    +    const std::vector<E::PredicatePtr> predicates) {
    +  DCHECK_GE(predicates.size(), 1u);
    +  if (predicates.size() == 1) {
    +    return predicates.front();
    +  } else {
    +    return E::LogicalAnd::Create(predicates);
    +  }
    +}
    +
    +E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateDisjunctive(
    +    const std::vector<E::PredicatePtr> predicates) {
    +  DCHECK_GE(predicates.size(), 1u);
    +  if (predicates.size() == 1) {
    +    return predicates.front();
    +  } else {
    +    return E::LogicalOr::Create(predicates);
    +  }
    +}
    +
    +
    --- End diff --
    
    Remove this extra empty line.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98714653
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    Please add a `NOTE` comment regarding two `Selection`s after applying this rule.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98693328
  
    --- Diff: query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp ---
    @@ -0,0 +1,118 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *   http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + **/
    +
    +#ifndef QUICKSTEP_QUERY_OPTIMIZER_RULES_PUSH_DOWN_LOW_COST_DISJUNCTIVE_PREDICATE_HPP_
    +#define QUICKSTEP_QUERY_OPTIMIZER_RULES_PUSH_DOWN_LOW_COST_DISJUNCTIVE_PREDICATE_HPP_
    +
    +#include <cstddef>
    +#include <map>
    +#include <memory>
    +#include <string>
    +#include <utility>
    +#include <vector>
    +
    +#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
    +#include "query_optimizer/expressions/AttributeReference.hpp"
    +#include "query_optimizer/expressions/Predicate.hpp"
    +#include "query_optimizer/physical/Physical.hpp"
    +#include "query_optimizer/rules/Rule.hpp"
    +#include "utility/Macros.hpp"
    +
    +namespace quickstep {
    +namespace optimizer {
    +
    +/** \addtogroup OptimizerRules
    + *  @{
    + */
    +
    +/**
    + * @brief Rule that applies to a physical plan to push down low-cost disjunctive
    + *        predicate when proper conditions are met.
    + *
    + * Here we elaborate the conditions.
    + *
    + * Let
    + *   P = p_{1,1} AND ... AND p_{1, m_1} OR ... OR p_{n,1} AND ... AND p_{n, m_n}
    + * be a predicate in disjunctive normal form.
    + *
    + * Now consider each small-cardinality relation R, if for each i in 1..n, there
    + * exists at least one predicate p_{i, k_i} that is applicable to R. Then we can
    + * construct a new predicate
    + *   P' = p_{1, k_1} OR ... OR p_{n, k_n}
    + * and push down P' to be applied to R.
    + *
    + * Also, if any conjunctive component in P contains more than one predicate that
    + * is applicable to R, then we can combine all these applicable predicates as a
    + * conjunctive component in P'.
    + *
    + * Finally, note that if there exists a conjunctive component that contains no
    + * predicate applicable to R. Then the condition fails and we cannot do a push
    + * down for R.
    + */
    +class PushDownLowCostDisjunctivePredicate : public Rule<physical::Physical> {
    + public:
    +  /**
    +   * @brief Constructor.
    +   */
    +  PushDownLowCostDisjunctivePredicate() {}
    +
    +  ~PushDownLowCostDisjunctivePredicate() override {}
    +
    +  std::string getName() const override {
    +    return "PushDownLowCostDisjunctivePredicate";
    +  }
    +
    +  physical::PhysicalPtr apply(const physical::PhysicalPtr &input) override;
    +
    + private:
    +  struct PredicateInfo {
    +    PredicateInfo() {}
    +    inline void add(expressions::PredicatePtr predicate) {
    +      predicates.emplace_back(predicate);
    +    }
    +    std::vector<expressions::PredicatePtr> predicates;
    +  };
    +
    +  void collectApplicablePredicates(const physical::PhysicalPtr &input);
    +  physical::PhysicalPtr attachPredicates(const physical::PhysicalPtr &input) const;
    --- End diff --
    
    Please add an empty line between two above methods.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98711958
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    Yes it will only create necessary `Selection`s. I.e. there won't be two selections in a chain that can be fused into one.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98710865
  
    --- Diff: query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp ---
    @@ -0,0 +1,218 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *   http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + **/
    +
    +#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
    +
    +#include <cstddef>
    +#include <vector>
    +
    +#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
    +#include "query_optimizer/expressions/AttributeReference.hpp"
    +#include "query_optimizer/expressions/ExpressionUtil.hpp"
    +#include "query_optimizer/expressions/LogicalAnd.hpp"
    +#include "query_optimizer/expressions/LogicalOr.hpp"
    +#include "query_optimizer/expressions/PatternMatcher.hpp"
    +#include "query_optimizer/expressions/Predicate.hpp"
    +#include "query_optimizer/physical/Aggregate.hpp"
    +#include "query_optimizer/physical/HashJoin.hpp"
    +#include "query_optimizer/physical/NestedLoopsJoin.hpp"
    +#include "query_optimizer/physical/PatternMatcher.hpp"
    +#include "query_optimizer/physical/Physical.hpp"
    +#include "query_optimizer/physical/PhysicalType.hpp"
    +#include "query_optimizer/physical/Selection.hpp"
    +#include "query_optimizer/physical/TableReference.hpp"
    +#include "query_optimizer/physical/TopLevelPlan.hpp"
    +
    +#include "glog/logging.h"
    +
    +namespace quickstep {
    +namespace optimizer {
    +
    +namespace E = ::quickstep::optimizer::expressions;
    +namespace P = ::quickstep::optimizer::physical;
    +
    +P::PhysicalPtr PushDownLowCostDisjunctivePredicate::apply(const P::PhysicalPtr &input) {
    +  DCHECK(input->getPhysicalType() == P::PhysicalType::kTopLevelPlan);
    +
    +  const P::TopLevelPlanPtr top_level_plan =
    +     std::static_pointer_cast<const P::TopLevelPlan>(input);
    +  cost_model_.reset(
    +      new cost::StarSchemaSimpleCostModel(
    +          top_level_plan->shared_subplans()));
    +
    +  collectApplicablePredicates(input);
    +
    +  if (!applicable_predicates_.empty()) {
    +    // Apply the selected predicates to stored relations.
    +    return attachPredicates(input);
    +  } else {
    +    return input;
    +  }
    +}
    +
    +void PushDownLowCostDisjunctivePredicate::collectApplicablePredicates(
    +    const physical::PhysicalPtr &input) {
    +  P::TableReferencePtr table_reference;
    +  if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
    +    // Consider only stored relations with small cardinality as targets.
    +    if (cost_model_->estimateCardinality(input) <= 100u) {
    --- End diff --
    
    It is okay to be conservative and the stat is more accurate if the `\analyze` command gets executed.
    
    Added a gflag.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98711534
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    I think [here](https://github.com/apache/incubator-quickstep/pull/174/files#diff-ca3b59cc48fbc383291bdfefaf5de128R188) we add a new `Physical::Select`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98710981
  
    --- Diff: query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp ---
    @@ -0,0 +1,218 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *   http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + **/
    +
    +#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
    +
    +#include <cstddef>
    +#include <vector>
    +
    +#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
    +#include "query_optimizer/expressions/AttributeReference.hpp"
    +#include "query_optimizer/expressions/ExpressionUtil.hpp"
    +#include "query_optimizer/expressions/LogicalAnd.hpp"
    +#include "query_optimizer/expressions/LogicalOr.hpp"
    +#include "query_optimizer/expressions/PatternMatcher.hpp"
    +#include "query_optimizer/expressions/Predicate.hpp"
    +#include "query_optimizer/physical/Aggregate.hpp"
    +#include "query_optimizer/physical/HashJoin.hpp"
    +#include "query_optimizer/physical/NestedLoopsJoin.hpp"
    +#include "query_optimizer/physical/PatternMatcher.hpp"
    +#include "query_optimizer/physical/Physical.hpp"
    +#include "query_optimizer/physical/PhysicalType.hpp"
    +#include "query_optimizer/physical/Selection.hpp"
    +#include "query_optimizer/physical/TableReference.hpp"
    +#include "query_optimizer/physical/TopLevelPlan.hpp"
    +
    +#include "glog/logging.h"
    +
    +namespace quickstep {
    +namespace optimizer {
    +
    +namespace E = ::quickstep::optimizer::expressions;
    +namespace P = ::quickstep::optimizer::physical;
    +
    +P::PhysicalPtr PushDownLowCostDisjunctivePredicate::apply(const P::PhysicalPtr &input) {
    +  DCHECK(input->getPhysicalType() == P::PhysicalType::kTopLevelPlan);
    +
    +  const P::TopLevelPlanPtr top_level_plan =
    +     std::static_pointer_cast<const P::TopLevelPlan>(input);
    +  cost_model_.reset(
    +      new cost::StarSchemaSimpleCostModel(
    +          top_level_plan->shared_subplans()));
    +
    +  collectApplicablePredicates(input);
    +
    +  if (!applicable_predicates_.empty()) {
    +    // Apply the selected predicates to stored relations.
    +    return attachPredicates(input);
    +  } else {
    +    return input;
    +  }
    +}
    +
    +void PushDownLowCostDisjunctivePredicate::collectApplicablePredicates(
    +    const physical::PhysicalPtr &input) {
    +  P::TableReferencePtr table_reference;
    +  if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
    +    // Consider only stored relations with small cardinality as targets.
    +    if (cost_model_->estimateCardinality(input) <= 100u) {
    +      applicable_nodes_.emplace_back(input, &table_reference->attribute_list());
    +    }
    +    return;
    +  }
    +
    +  for (const auto &child : input->children()) {
    +    collectApplicablePredicates(child);
    +  }
    +
    +  E::PredicatePtr filter_predicate = nullptr;
    +  switch (input->getPhysicalType()) {
    +    case P::PhysicalType::kAggregate: {
    +      filter_predicate =
    +          std::static_pointer_cast<const P::Aggregate>(input)->filter_predicate();
    +      break;
    +    }
    +    case P::PhysicalType::kHashJoin: {
    +      const P::HashJoinPtr hash_join =
    +          std::static_pointer_cast<const P::HashJoin>(input);
    +      if (hash_join->join_type() == P::HashJoin::JoinType::kInnerJoin) {
    +        filter_predicate = hash_join->residual_predicate();
    +      }
    +      break;
    +    }
    +    case P::PhysicalType::kNestedLoopsJoin: {
    +      filter_predicate =
    +          std::static_pointer_cast<const P::NestedLoopsJoin>(input)->join_predicate();
    +      break;
    +    }
    +    case P::PhysicalType::kSelection: {
    +      filter_predicate =
    +          std::static_pointer_cast<const P::Selection>(input)->filter_predicate();
    +      break;
    +    }
    +    default:
    +      break;
    +  }
    +
    +  E::LogicalOrPtr disjunctive_predicate;
    +  if (filter_predicate == nullptr ||
    +      !E::SomeLogicalOr::MatchesWithConditionalCast(filter_predicate, &disjunctive_predicate)) {
    +    return;
    +  }
    +
    +  // Consider only disjunctive normal form, i.e. disjunction of conjunctions.
    +  // Divide the disjunctive components into groups.
    +  std::vector<std::vector<E::PredicatePtr>> candidate_predicates;
    +  std::vector<std::vector<std::vector<E::AttributeReferencePtr>>> candidate_attributes;
    +  for (const auto &conjunctive_predicate : disjunctive_predicate->operands()) {
    +    candidate_predicates.emplace_back();
    +    candidate_attributes.emplace_back();
    +    E::LogicalAndPtr logical_and;
    +    if (E::SomeLogicalAnd::MatchesWithConditionalCast(conjunctive_predicate, &logical_and)) {
    +      for (const auto &predicate : logical_and->operands()) {
    +        candidate_predicates.back().emplace_back(predicate);
    +        candidate_attributes.back().emplace_back(
    +            predicate->getReferencedAttributes());
    +      }
    +    } else {
    +      candidate_predicates.back().emplace_back(conjunctive_predicate);
    +      candidate_attributes.back().emplace_back(
    +          conjunctive_predicate->getReferencedAttributes());
    +    }
    +  }
    +
    +  // Check whether the conditions are met for pushing down part of the predicates
    +  // to each small-cardinality stored relation.
    +  for (const auto &node_pair : applicable_nodes_) {
    +    const std::vector<E::AttributeReferencePtr> &target_attributes = *node_pair.second;
    +    std::vector<E::PredicatePtr> selected_disj_preds;
    +    for (std::size_t i = 0; i < candidate_predicates.size(); ++i) {
    +      const auto &cand_preds = candidate_predicates[i];
    +      const auto &cand_attrs = candidate_attributes[i];
    +
    +      std::vector<E::PredicatePtr> selected_conj_preds;
    +      for (std::size_t j = 0; j < cand_preds.size(); ++j) {
    +        if (E::SubsetOfExpressions(cand_attrs[j], target_attributes)) {
    +          selected_conj_preds.emplace_back(cand_preds[j]);
    +        }
    +      }
    +      if (selected_conj_preds.empty()) {
    +        // Not every disjunctive component contains a predicate that can be applied
    +        // to the table reference node -- condition failed, exit.
    +        selected_disj_preds.clear();
    +        break;
    +      } else {
    +        selected_disj_preds.emplace_back(
    +            CreateConjunctive(selected_conj_preds));
    +      }
    +    }
    +    if (!selected_disj_preds.empty()) {
    +      applicable_predicates_[node_pair.first].add(
    +          CreateDisjunctive(selected_disj_preds));
    +    }
    +  }
    +}
    +
    +P::PhysicalPtr PushDownLowCostDisjunctivePredicate::attachPredicates(
    +    const P::PhysicalPtr &input) const {
    +  std::vector<P::PhysicalPtr> new_children;
    +  for (const P::PhysicalPtr &child : input->children()) {
    +    const P::PhysicalPtr new_child = attachPredicates(child);
    +    new_children.push_back(new_child);
    +  }
    +
    +  const P::PhysicalPtr output =
    +      new_children == input->children() ? input
    +                                        : input->copyWithNewChildren(new_children);
    +
    +  const auto &node_it = applicable_predicates_.find(input);
    +  if (node_it != applicable_predicates_.end()) {
    +    const E::PredicatePtr filter_predicate =
    +        CreateConjunctive(node_it->second.predicates);
    +    return P::Selection::Create(output,
    +                                E::ToNamedExpressions(output->getOutputAttributes()),
    +                                filter_predicate);
    +  }
    +
    +  return output;
    +}
    +
    +E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateConjunctive(
    +    const std::vector<E::PredicatePtr> predicates) {
    +  DCHECK_GE(predicates.size(), 1u);
    +  if (predicates.size() == 1) {
    +    return predicates.front();
    +  } else {
    +    return E::LogicalAnd::Create(predicates);
    +  }
    +}
    +
    +E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateDisjunctive(
    +    const std::vector<E::PredicatePtr> predicates) {
    +  DCHECK_GE(predicates.size(), 1u);
    +  if (predicates.size() == 1) {
    +    return predicates.front();
    +  } else {
    +    return E::LogicalOr::Create(predicates);
    +  }
    +}
    +
    +
    --- End diff --
    
    Updated.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98689643
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    Could we have some comments regarding the order of `rules`, i.e., why put `PushDownLowCostDisjunctivePredicate` here?
    
    If I understand correctly, `PushDownLowCostDisjunctivePredicate` may generate new `Physical Select`s. Would the rest of `rules` eliminate multiple `Physical Select`s into one?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98691158
  
    --- Diff: query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp ---
    @@ -0,0 +1,218 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *   http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + **/
    +
    +#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
    +
    +#include <cstddef>
    +#include <vector>
    +
    +#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
    +#include "query_optimizer/expressions/AttributeReference.hpp"
    +#include "query_optimizer/expressions/ExpressionUtil.hpp"
    +#include "query_optimizer/expressions/LogicalAnd.hpp"
    +#include "query_optimizer/expressions/LogicalOr.hpp"
    +#include "query_optimizer/expressions/PatternMatcher.hpp"
    +#include "query_optimizer/expressions/Predicate.hpp"
    +#include "query_optimizer/physical/Aggregate.hpp"
    +#include "query_optimizer/physical/HashJoin.hpp"
    +#include "query_optimizer/physical/NestedLoopsJoin.hpp"
    +#include "query_optimizer/physical/PatternMatcher.hpp"
    +#include "query_optimizer/physical/Physical.hpp"
    +#include "query_optimizer/physical/PhysicalType.hpp"
    +#include "query_optimizer/physical/Selection.hpp"
    +#include "query_optimizer/physical/TableReference.hpp"
    +#include "query_optimizer/physical/TopLevelPlan.hpp"
    +
    +#include "glog/logging.h"
    +
    +namespace quickstep {
    +namespace optimizer {
    +
    +namespace E = ::quickstep::optimizer::expressions;
    +namespace P = ::quickstep::optimizer::physical;
    +
    +P::PhysicalPtr PushDownLowCostDisjunctivePredicate::apply(const P::PhysicalPtr &input) {
    +  DCHECK(input->getPhysicalType() == P::PhysicalType::kTopLevelPlan);
    +
    +  const P::TopLevelPlanPtr top_level_plan =
    +     std::static_pointer_cast<const P::TopLevelPlan>(input);
    +  cost_model_.reset(
    +      new cost::StarSchemaSimpleCostModel(
    +          top_level_plan->shared_subplans()));
    +
    +  collectApplicablePredicates(input);
    +
    +  if (!applicable_predicates_.empty()) {
    +    // Apply the selected predicates to stored relations.
    +    return attachPredicates(input);
    +  } else {
    +    return input;
    +  }
    +}
    +
    +void PushDownLowCostDisjunctivePredicate::collectApplicablePredicates(
    +    const physical::PhysicalPtr &input) {
    +  P::TableReferencePtr table_reference;
    +  if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
    +    // Consider only stored relations with small cardinality as targets.
    +    if (cost_model_->estimateCardinality(input) <= 100u) {
    --- End diff --
    
    Just curious about `100u` here. My concern is that the result of `estimateCardinality` for a small relation is two orders bigger than the fact; I have seen it in the `query_optimizer execution_generator` unit test.
    
    Also, I'd suggest to use a `gflags` for `100u` to replace `kCardinalityThreshold` defined in the header file.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98708919
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -27,6 +27,7 @@
     #include "query_optimizer/logical/Logical.hpp"
     #include "query_optimizer/physical/Physical.hpp"
     #include "query_optimizer/rules/AttachLIPFilters.hpp"
    +#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
    --- End diff --
    
    Updated.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98708887
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    The three rules blocks from `PushDownLowCostDisjunctivePredicate` to `ReorderColumns` can be arranged in any order.
    
    `PushDownLowCostDisjunctivePredicate` will not generate unnecessary `Selection`s. And currently in the physical generate there's no rule that fuses `Selection`s.
    
    I add a comment to indicate that currently new rules should better be added before `AttachLIPFilters` because rules after that needs extra handling of `LIPFilterConfiguration` for transformed nodes.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98714161
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    Oh I made a mistake that actually the `InjectFilterJoin` optimization will not generate unnecessary `Selection`s, but `PushDownLowCostDisjunctivePredicate` may generate two `Selection`s in a chain. Currently this is a not an issue since the `Selection`s for tables with cardinality around 100 are very light-weight. We may add a `FuseSelection` optimization later.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by jianqiao <gi...@git.apache.org>.
Github user jianqiao commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98716718
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -108,6 +109,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
     P::PhysicalPtr PhysicalGenerator::optimizePlan() {
       std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
       rules.emplace_back(new PruneColumns());
    +  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
    --- End diff --
    
    Updated.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by zuyu <gi...@git.apache.org>.
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/174#discussion_r98688681
  
    --- Diff: query_optimizer/PhysicalGenerator.cpp ---
    @@ -27,6 +27,7 @@
     #include "query_optimizer/logical/Logical.hpp"
     #include "query_optimizer/physical/Physical.hpp"
     #include "query_optimizer/rules/AttachLIPFilters.hpp"
    +#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
    --- End diff --
    
    Code style: sort in alphabetic order, so move this line after the next.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] incubator-quickstep pull request #174: Push down disjunctive predicates to f...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/incubator-quickstep/pull/174


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---