| /** |
| * 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 ORC_SRC_SEARCHARGUMENT_HH |
| #define ORC_SRC_SEARCHARGUMENT_HH |
| |
| #include "ExpressionTree.hh" |
| #include "orc/sargs/SearchArgument.hh" |
| #include "sargs/PredicateLeaf.hh" |
| #include "wrap/orc-proto-wrapper.hh" |
| |
| #include <deque> |
| #include <stdexcept> |
| #include <unordered_map> |
| |
| namespace orc { |
| |
| /** |
| * Primary interface for a search argument, which are the subset of predicates |
| * that can be pushed down to the RowReader. Each SearchArgument consists |
| * of a series of search clauses that must each be true for the row to be |
| * accepted by the filter. |
| * |
| * This requires that the filter be normalized into conjunctive normal form |
| * (<a href="http://en.wikipedia.org/wiki/Conjunctive_normal_form">CNF</a>). |
| */ |
| class SearchArgumentImpl : public SearchArgument { |
| public: |
| SearchArgumentImpl(TreeNode root, const std::vector<PredicateLeaf>& leaves); |
| |
| /** |
| * Get the leaf predicates that are required to evaluate the predicate. The |
| * list will have the duplicates removed. |
| * @return the list of leaf predicates |
| */ |
| const std::vector<PredicateLeaf>& getLeaves() const; |
| |
| /** |
| * Get the expression tree. This should only needed for file formats that |
| * need to translate the expression to an internal form. |
| */ |
| const ExpressionTree* getExpression() const; |
| |
| /** |
| * Evaluate the entire predicate based on the values for the leaf predicates. |
| * @param leaves the value of each leaf predicate |
| * @return the value of the entire predicate |
| */ |
| TruthValue evaluate(const std::vector<TruthValue>& leaves) const override; |
| |
| std::string toString() const override; |
| |
| private: |
| std::shared_ptr<ExpressionTree> expressionTree_; |
| std::vector<PredicateLeaf> leaves_; |
| }; |
| |
| /** |
| * A builder object to create a SearchArgument from expressions. The user |
| * must call startOr, startAnd, or startNot before adding any leaves. |
| */ |
| class SearchArgumentBuilderImpl : public SearchArgumentBuilder { |
| public: |
| SearchArgumentBuilderImpl(); |
| |
| /** |
| * Start building an or operation and push it on the stack. |
| * @return this |
| */ |
| SearchArgumentBuilder& startOr() override; |
| |
| /** |
| * Start building an and operation and push it on the stack. |
| * @return this |
| */ |
| SearchArgumentBuilder& startAnd() override; |
| |
| /** |
| * Start building a not operation and push it on the stack. |
| * @return this |
| */ |
| SearchArgumentBuilder& startNot() override; |
| |
| /** |
| * Finish the current operation and pop it off of the stack. Each start |
| * call must have a matching end. |
| * @return this |
| */ |
| SearchArgumentBuilder& end() override; |
| |
| /** |
| * Add a less than leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& lessThan(const std::string& column, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add a less than leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& lessThan(uint64_t columnId, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add a less than equals leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& lessThanEquals(const std::string& column, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add a less than equals leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& lessThanEquals(uint64_t columnId, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add an equals leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& equals(const std::string& column, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add an equals leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& equals(uint64_t columnId, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add a null safe equals leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& nullSafeEquals(const std::string& column, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add a null safe equals leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param literal the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& nullSafeEquals(uint64_t columnId, PredicateDataType type, |
| Literal literal) override; |
| |
| /** |
| * Add an in leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param literals the literals |
| * @return this |
| */ |
| SearchArgumentBuilder& in(const std::string& column, PredicateDataType type, |
| const std::initializer_list<Literal>& literals) override; |
| |
| /** |
| * Add an in leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param literals the literals |
| * @return this |
| */ |
| SearchArgumentBuilder& in(uint64_t columnId, PredicateDataType type, |
| const std::initializer_list<Literal>& literals) override; |
| |
| /** |
| * Add an in leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param literals the literals |
| * @return this |
| */ |
| SearchArgumentBuilder& in(const std::string& column, PredicateDataType type, |
| const std::vector<Literal>& literals) override; |
| |
| /** |
| * Add an in leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param literals the literals |
| * @return this |
| */ |
| SearchArgumentBuilder& in(uint64_t columnId, PredicateDataType type, |
| const std::vector<Literal>& literals) override; |
| |
| /** |
| * Add an is null leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @return this |
| */ |
| SearchArgumentBuilder& isNull(const std::string& column, PredicateDataType type) override; |
| |
| /** |
| * Add an is null leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @return this |
| */ |
| SearchArgumentBuilder& isNull(uint64_t columnId, PredicateDataType type) override; |
| |
| /** |
| * Add a between leaf to the current item on the stack. |
| * @param column the field name of the column |
| * @param type the type of the expression |
| * @param lower the literal |
| * @param upper the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& between(const std::string& column, PredicateDataType type, Literal lower, |
| Literal upper) override; |
| |
| /** |
| * Add a between leaf to the current item on the stack. |
| * @param columnId the column id of the column |
| * @param type the type of the expression |
| * @param lower the literal |
| * @param upper the literal |
| * @return this |
| */ |
| SearchArgumentBuilder& between(uint64_t columnId, PredicateDataType type, Literal lower, |
| Literal upper) override; |
| |
| /** |
| * Add a truth value to the expression. |
| * @param truth truth value |
| * @return this |
| */ |
| SearchArgumentBuilder& literal(TruthValue truth) override; |
| |
| /** |
| * Build and return the SearchArgument that has been defined. All of the |
| * starts must have been ended before this call. |
| * @return the new SearchArgument |
| */ |
| std::unique_ptr<SearchArgument> build() override; |
| |
| private: |
| SearchArgumentBuilder& start(ExpressionTree::Operator op); |
| size_t addLeaf(PredicateLeaf leaf); |
| |
| static bool isInvalidColumn(const std::string& column); |
| static bool isInvalidColumn(uint64_t columnId); |
| |
| template <typename T> |
| SearchArgumentBuilder& compareOperator(PredicateLeaf::Operator op, T column, |
| PredicateDataType type, Literal literal); |
| |
| template <typename T, typename CONTAINER> |
| SearchArgumentBuilder& addChildForIn(T column, PredicateDataType type, |
| const CONTAINER& literals); |
| |
| template <typename T> |
| SearchArgumentBuilder& addChildForIsNull(T column, PredicateDataType type); |
| |
| template <typename T> |
| SearchArgumentBuilder& addChildForBetween(T column, PredicateDataType type, Literal lower, |
| Literal upper); |
| |
| public: |
| static TreeNode pushDownNot(TreeNode root); |
| static TreeNode foldMaybe(TreeNode expr); |
| static TreeNode flatten(TreeNode root); |
| static TreeNode convertToCNF(TreeNode root); |
| |
| private: |
| std::deque<TreeNode> currTree_; |
| std::unordered_map<PredicateLeaf, size_t, PredicateLeafHash, PredicateLeafComparator> leaves_; |
| std::shared_ptr<ExpressionTree> root_; |
| }; |
| |
| } // namespace orc |
| |
| #endif // ORC_SRC_SEARCHARGUMENT_HH |