mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 10:02:01 +00:00
fix
This commit is contained in:
parent
5a2fa1aba7
commit
06454bd912
@ -102,6 +102,38 @@ ComparisonGraph::ComparisonGraph(const std::vector<ASTPtr> & atomic_formulas)
|
||||
graph = BuildGraphFromAstsGraph(g);
|
||||
}
|
||||
|
||||
std::pair<bool, bool> ComparisonGraph::findPath(const size_t start, const size_t finish) const
|
||||
{
|
||||
// min path : < = -1, =< = 0
|
||||
const auto inf = std::numeric_limits<int64_t>::max();
|
||||
const size_t n = graph.vertexes.size();
|
||||
std::vector<int64_t> dist(n, inf);
|
||||
dist[start] = 0;
|
||||
for (size_t k = 0; k < n; ++k)
|
||||
{
|
||||
bool has_relaxation = false;
|
||||
for (size_t v = 0; v < n; ++v)
|
||||
{
|
||||
if (dist[v] == inf)
|
||||
continue;
|
||||
|
||||
for (const auto & edge : graph.edges[v])
|
||||
{
|
||||
const int64_t weight = edge.type == Edge::Type::LESS ? -1 : 0;
|
||||
if (dist[edge.to] > dist[v] + weight)
|
||||
{
|
||||
dist[edge.to] = dist[v] + weight;
|
||||
has_relaxation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_relaxation)
|
||||
break;
|
||||
}
|
||||
return {dist[finish] != inf, dist[finish] < 0};
|
||||
}
|
||||
|
||||
ComparisonGraph::CompareResult ComparisonGraph::compare(const ASTPtr & left, const ASTPtr & right) const
|
||||
{
|
||||
size_t start = 0;
|
||||
@ -132,8 +164,17 @@ ComparisonGraph::CompareResult ComparisonGraph::compare(const ASTPtr & left, con
|
||||
if (start == finish)
|
||||
return CompareResult::EQUAL;
|
||||
|
||||
/// TODO: precalculate in O(n^3) using Floyd–Warshall algorithm where < = -1 and =< = 0.
|
||||
/// TODO: precalculate using Floyd–Warshall O(n^3) algorithm where < = -1 and =< = 0.
|
||||
/// TODO: use it for less, greater and so on
|
||||
|
||||
auto [has_path, is_strict] = findPath(start, finish);
|
||||
if (has_path)
|
||||
return is_strict ? CompareResult::GREATER : CompareResult::GREATER_OR_EQUAL;
|
||||
|
||||
auto [has_path_r, is_strict_r] = findPath(finish, start);
|
||||
if (has_path_r)
|
||||
return is_strict_r ? CompareResult::LESS : CompareResult::LESS_OR_EQUAL;
|
||||
|
||||
return CompareResult::UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ public:
|
||||
};
|
||||
|
||||
CompareResult compare(const ASTPtr & left, const ASTPtr & right) const;
|
||||
CompareResult getExpectedCompare(const ASTPtr & ast) const;
|
||||
|
||||
std::vector<ASTPtr> getEqual(const ASTPtr & ast) const;
|
||||
|
||||
@ -82,6 +81,8 @@ private:
|
||||
void dfsComponents(
|
||||
const Graph & reversed_graph, size_t v, std::vector<size_t> & components, const size_t not_visited, const size_t component) const;
|
||||
|
||||
std::pair<bool, bool> findPath(const size_t start, const size_t finish) const;
|
||||
|
||||
Graph graph;
|
||||
};
|
||||
|
||||
|
@ -193,7 +193,7 @@ bool checkIfGroupAlwaysTrueGraph(const CNFQuery::OrGroup & group, const Comparis
|
||||
Poco::Logger::get("GRAPH REASON").information(atom.ast->dumpTree());
|
||||
Poco::Logger::get("GRAPH REASON").information(std::to_string(static_cast<int>(expected)) + " " + std::to_string(static_cast<int>(result)));
|
||||
|
||||
if (expected == ComparisonGraph::CompareResult::UNKNOWN)
|
||||
if (expected == ComparisonGraph::CompareResult::UNKNOWN || result == ComparisonGraph::CompareResult::UNKNOWN)
|
||||
return false;
|
||||
|
||||
if (expected == result)
|
||||
@ -232,6 +232,38 @@ bool checkIfAtomAlwaysFalseFullMatch(const CNFQuery::AtomicFormula & atom, const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkIfAtomAlwaysFalseGraph(const CNFQuery::AtomicFormula & atom, const ComparisonGraph & graph)
|
||||
{
|
||||
const auto * func = atom.ast->as<ASTFunction>();
|
||||
if (func && func->arguments->children.size() == 2)
|
||||
{
|
||||
/// TODO: special support for !=
|
||||
const auto expected = getExpectedCompare(atom);
|
||||
const auto result = graph.compare(func->arguments->children[0], func->arguments->children[1]);
|
||||
Poco::Logger::get("GRAPH REASON F").information("neg: " + std::to_string(atom.negative));
|
||||
Poco::Logger::get("GRAPH REASON F").information(atom.ast->dumpTree());
|
||||
Poco::Logger::get("GRAPH REASON F").information(std::to_string(static_cast<int>(expected)) + " " + std::to_string(static_cast<int>(result)));
|
||||
|
||||
if (expected == ComparisonGraph::CompareResult::UNKNOWN || result == ComparisonGraph::CompareResult::UNKNOWN)
|
||||
return false;
|
||||
|
||||
if (expected == result)
|
||||
return false;
|
||||
else if (result == ComparisonGraph::CompareResult::EQUAL &&
|
||||
(expected == ComparisonGraph::CompareResult::LESS_OR_EQUAL || expected == ComparisonGraph::CompareResult::GREATER_OR_EQUAL))
|
||||
return false;
|
||||
else if (result == ComparisonGraph::CompareResult::LESS && expected == ComparisonGraph::CompareResult::LESS_OR_EQUAL)
|
||||
return false;
|
||||
else if (result == ComparisonGraph::CompareResult::GREATER && expected == ComparisonGraph::CompareResult::GREATER_OR_EQUAL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void WhereConstraintsOptimizer::perform()
|
||||
{
|
||||
if (select_query->where() && metadata_snapshot)
|
||||
@ -245,8 +277,8 @@ void WhereConstraintsOptimizer::perform()
|
||||
.filterAlwaysTrueGroups([&constraint_data, &compare_graph](const auto & group) { /// remove always true groups from CNF
|
||||
return !checkIfGroupAlwaysTrueFullMatch(group, constraint_data) && !checkIfGroupAlwaysTrueGraph(group, compare_graph);
|
||||
})
|
||||
.filterAlwaysFalseAtoms([&constraint_data](const auto & atom) { /// remove always false atoms from CNF
|
||||
return !checkIfAtomAlwaysFalseFullMatch(atom, constraint_data);
|
||||
.filterAlwaysFalseAtoms([&constraint_data, &compare_graph](const auto & atom) { /// remove always false atoms from CNF
|
||||
return !checkIfAtomAlwaysFalseFullMatch(atom, constraint_data) && !checkIfAtomAlwaysFalseGraph(atom, compare_graph);
|
||||
})
|
||||
.pushNotInFuntions();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user