ClickHouse/src/Interpreters/ComparisonGraph.h

129 lines
3.7 KiB
C++
Raw Normal View History

2021-03-04 12:11:43 +00:00
#pragma once
#include <Parsers/IAST_fwd.h>
#include <Parsers/ASTLiteral.h>
#include <unordered_map>
2021-04-03 16:30:49 +00:00
#include <map>
2021-03-04 12:11:43 +00:00
#include <vector>
namespace DB
{
2021-03-05 12:46:42 +00:00
/*
* Graph of relations between terms in constraints.
* Allows to compare terms and get equal terms.
*/
2021-03-04 12:11:43 +00:00
class ComparisonGraph
{
public:
ComparisonGraph(const std::vector<ASTPtr> & atomic_formulas);
enum class CompareResult
{
LESS,
LESS_OR_EQUAL,
EQUAL,
GREATER_OR_EQUAL,
GREATER,
2021-05-04 10:47:23 +00:00
NOT_EQUAL,
2021-03-04 12:11:43 +00:00
UNKNOWN,
};
2021-05-04 10:47:23 +00:00
static CompareResult getCompareResult(const std::string & name);
static CompareResult inverseCompareResult(const CompareResult result);
2021-03-05 09:54:13 +00:00
CompareResult compare(const ASTPtr & left, const ASTPtr & right) const;
2021-03-04 12:11:43 +00:00
2021-05-02 19:16:40 +00:00
/// It's possible that left <expected> right
bool isPossibleCompare(const CompareResult expected, const ASTPtr & left, const ASTPtr & right) const;
/// It's always true that left <expected> right
bool isAlwaysCompare(const CompareResult expected, const ASTPtr & left, const ASTPtr & right) const;
2021-03-04 12:11:43 +00:00
std::vector<ASTPtr> getEqual(const ASTPtr & ast) const;
2021-03-05 12:46:42 +00:00
std::optional<ASTPtr> getEqualConst(const ASTPtr & ast) const;
2021-03-04 12:11:43 +00:00
2021-04-26 11:26:54 +00:00
std::optional<std::size_t> getComponentId(const ASTPtr & ast) const;
std::vector<ASTPtr> getComponent(const std::size_t id) const;
2021-05-03 19:08:26 +00:00
bool hasPath(const size_t left, const size_t right) const;
2021-04-26 11:26:54 +00:00
2021-04-03 12:12:45 +00:00
/// Find constants lessOrEqual and greaterOrEqual.
2021-03-04 12:11:43 +00:00
/// For int and double linear programming can be applied here.
2021-04-10 20:46:53 +00:00
/// Returns: {constant, is strict less/greater}
std::optional<std::pair<Field, bool>> getConstUpperBound(const ASTPtr & ast) const;
std::optional<std::pair<Field, bool>> getConstLowerBound(const ASTPtr & ast) const;
2021-03-04 12:11:43 +00:00
2021-05-04 18:43:58 +00:00
std::vector<ASTs> getVertices() const;
2021-04-28 17:35:51 +00:00
2021-03-04 12:11:43 +00:00
private:
/// strongly connected component
struct EqualComponent
{
std::vector<ASTPtr> asts;
2021-04-10 15:47:50 +00:00
ssize_t constant_index = -1;
bool hasConstant() const;
ASTPtr getConstant() const;
void buildConstants();
2021-03-04 12:11:43 +00:00
};
/// TODO: move to diff for int and double:
/// LESS and LESS_OR_EQUAL with +const or 0 --- ok
/// with -const --- not ok
/// EQUAL is ok only for 0
struct Edge
{
enum Type
{
LESS,
LESS_OR_EQUAL,
EQUAL,
};
Type type;
2021-03-05 09:54:13 +00:00
size_t to;
2021-03-04 12:11:43 +00:00
};
struct Graph
{
2021-05-04 18:43:58 +00:00
struct ASTHash
{
size_t operator() (const IAST::Hash & hash) const
{
2021-03-05 09:54:13 +00:00
return hash.first;
}
};
std::unordered_map<IAST::Hash, size_t, ASTHash> ast_hash_to_component;
2021-05-04 18:43:58 +00:00
std::vector<EqualComponent> vertices;
2021-03-04 12:11:43 +00:00
std::vector<std::vector<Edge>> edges;
};
2021-05-06 08:29:24 +00:00
static ASTPtr normalizeAtom(const ASTPtr & atom);
static Graph BuildGraphFromAstsGraph(const Graph & asts_graph);
2021-03-05 09:54:13 +00:00
2021-05-06 08:29:24 +00:00
static Graph reverseGraph(const Graph & asts_graph);
static void dfsOrder(const Graph & asts_graph, size_t v, std::vector<bool> & visited, std::vector<size_t> & order);
static void dfsComponents(
const Graph & reversed_graph, size_t v, std::vector<size_t> & components, const size_t not_visited, const size_t component);
2021-03-04 12:11:43 +00:00
2021-03-05 12:13:00 +00:00
std::pair<bool, bool> findPath(const size_t start, const size_t finish) const;
2021-04-03 16:30:49 +00:00
enum class Path
{
LESS,
LESS_OR_EQUAL,
};
2021-05-06 08:29:24 +00:00
static std::map<std::pair<size_t, size_t>, Path> BuildDistsFromGraph(const Graph & g);
2021-04-10 20:46:53 +00:00
std::pair<std::vector<ssize_t>, std::vector<ssize_t>> buildConstBounds() const;
2021-04-03 16:30:49 +00:00
2021-03-04 12:11:43 +00:00
Graph graph;
2021-04-03 16:30:49 +00:00
std::map<std::pair<size_t, size_t>, Path> dists;
2021-05-04 10:47:23 +00:00
std::set<std::pair<size_t, size_t>> not_equal;
2021-04-10 20:46:53 +00:00
std::vector<ssize_t> ast_const_lower_bound;
std::vector<ssize_t> ast_const_upper_bound;
2021-03-04 12:11:43 +00:00
};
}