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);
|
|
|
|
|
|
|
|
/// 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;
|
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-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
|
|
|
|
|
|
|
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-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
|
|
|
|
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,
|
|
|
|
};
|
|
|
|
|
|
|
|
std::map<std::pair<size_t, size_t>, Path> BuildDistsFromGraph(const Graph & g) const;
|
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-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
|
|
|
};
|
|
|
|
|
|
|
|
}
|