blob: 1963c993d62825da23aa67106d285dec74a88181 [file] [log] [blame]
/**
* 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