ClickHouse/src/Interpreters/ComparisonGraph.h

89 lines
2.3 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>
#include <vector>
namespace DB
{
class ComparisonGraph
{
public:
ComparisonGraph(const std::vector<ASTPtr> & atomic_formulas);
/// Works for string and num.
/// For other -- only eq.
enum class CompareResult
{
LESS,
LESS_OR_EQUAL,
EQUAL,
GREATER_OR_EQUAL,
GREATER,
UNKNOWN,
};
2021-03-05 09:54:13 +00:00
CompareResult compare(const ASTPtr & left, const ASTPtr & right) const;
CompareResult getExpectedCompare(const ASTPtr & ast) const;
2021-03-04 12:11:43 +00:00
std::vector<ASTPtr> getEqual(const ASTPtr & ast) const;
/// Find constants less and greater.
/// For int and double linear programming can be applied here.
// TODO: implement
2021-03-05 09:54:13 +00:00
//ASTPtr getMax(const ASTPtr &) const { return nullptr; } // sup
//ASTPtr getMin(const ASTPtr &) const { return nullptr; } // inf
//ASTPtr getEqualConst(const ASTPtr &) const { return nullptr; } // inf
2021-03-04 12:11:43 +00:00
private:
/// strongly connected component
struct EqualComponent
{
std::vector<ASTPtr> asts;
};
/// 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-03-05 09:54:13 +00:00
struct ASTHash {
size_t operator() (const IAST::Hash & hash) const {
return hash.first;
}
};
std::unordered_map<IAST::Hash, size_t, ASTHash> ast_hash_to_component;
2021-03-04 12:11:43 +00:00
std::vector<EqualComponent> vertexes;
std::vector<std::vector<Edge>> edges;
};
2021-03-05 09:54:13 +00:00
ASTPtr normalizeAtom(const ASTPtr & atom) const;
Graph BuildGraphFromAstsGraph(const Graph & asts_graph) const;
Graph reverseGraph(const Graph & asts_graph) const;
void dfsOrder(const Graph & asts_graph, size_t v, std::vector<bool> & visited, std::vector<size_t> & order) const;
void dfsComponents(
const Graph & reversed_graph, size_t v, std::vector<size_t> & components, const size_t not_visited, const size_t component) const;
2021-03-04 12:11:43 +00:00
Graph graph;
};
}