Add E2E test for optimizing merge on supernodes

This commit is contained in:
Josip Mrden
2023-06-20 17:20:09 +02:00
parent 114f00d64c
commit c66cc56d5f
4 changed files with 58 additions and 3 deletions

View File

@@ -750,7 +750,7 @@ class IndexLookupRewriter final : public HierarchicalLogicalOperatorVisitor {
auto maybe_label = FindBestLabelIndex(labels); auto maybe_label = FindBestLabelIndex(labels);
if (!maybe_label) return nullptr; if (!maybe_label) return nullptr;
const auto &label = *maybe_label; const auto &label = *maybe_label;
if (max_vertex_count && db_->VerticesCount(GetLabel(label)) > *max_vertex_count) { if (max_vertex_count && *max_vertex_count >= 1 && db_->VerticesCount(GetLabel(label)) > *max_vertex_count) {
// Don't create an indexed lookup, since we have more labeled vertices // Don't create an indexed lookup, since we have more labeled vertices
// than the allowed count. // than the allowed count.
return nullptr; return nullptr;

View File

@@ -13,6 +13,7 @@ import sys
import pytest import pytest
from common import connect, execute_and_fetch_all from common import connect, execute_and_fetch_all
from gqlalchemy import Memgraph
# E2E tests for checking query semantic # E2E tests for checking query semantic
# ------------------------------------ # ------------------------------------
@@ -278,5 +279,58 @@ def test_same_avg_group_size_diff_distribution(connect):
execute_and_fetch_all(cursor, "DROP INDEX ON :Label(id2);") execute_and_fetch_all(cursor, "DROP INDEX ON :Label(id2);")
def test_given_supernode_when_expanding_then_expand_other_way_around():
memgraph = Memgraph()
memgraph.execute("FOREACH (i in range(1, 20000) | CREATE (:Node {id: i}));")
memgraph.execute("CREATE (:SuperNode {id: 1});")
memgraph.execute("CREATE INDEX ON :SuperNode(id);")
memgraph.execute("CREATE INDEX ON :SuperNode;")
memgraph.execute("CREATE INDEX ON :Node(id);")
memgraph.execute("CREATE INDEX ON :Node;")
memgraph.execute("match (n:Node) match (s:SuperNode {id: 1}) merge (n)<-[:HAS_REL_TO]-(s);")
result_without_analysis = list(
memgraph.execute_and_fetch("explain match (n:Node) match (s:SuperNode {id: 1}) merge (n)<-[:HAS_REL_TO]-(s);")
)
result_without_analysis = [x["QUERY PLAN"] for x in result_without_analysis]
expected_explain_before_analysis = [
f" * EmptyResult",
f" * Merge",
f" |\\ On Match",
f" | * Expand (s)-[anon3:HAS_REL_TO]->(n)",
f" | * Once",
f" |\\ On Create",
f" | * CreateExpand (n)<-[anon3:HAS_REL_TO]-(s)",
f" | * Once",
f" * ScanAllByLabel (n :Node)",
f" * ScanAllByLabelPropertyValue (s :SuperNode {{id}})",
f" * Once",
]
memgraph.execute("analyze graph;")
result_with_analysis = list(
memgraph.execute_and_fetch("explain match (n:Node) match (s:SuperNode {id: 1}) merge (n)<-[:HAS_REL_TO]-(s);")
)
result_with_analysis = [x["QUERY PLAN"] for x in result_with_analysis]
expected_explain_after_analysis = [
f" * EmptyResult",
f" * Merge",
f" |\\ On Match",
f" | * Expand (n)<-[anon3:HAS_REL_TO]-(s)",
f" | * Once",
f" |\\ On Create",
f" | * CreateExpand (n)<-[anon3:HAS_REL_TO]-(s)",
f" | * Once",
f" * ScanAllByLabel (n :Node)",
f" * ScanAllByLabelPropertyValue (s :SuperNode {{id}})",
f" * Once",
]
assert expected_explain_before_analysis == result_without_analysis
assert expected_explain_after_analysis == result_with_analysis
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(pytest.main([__file__, "-rA"])) sys.exit(pytest.main([__file__, "-rA"]))

View File

@@ -175,8 +175,8 @@ startup_config_dict = {
"query_cost_planner": ("true", "true", "Use the cost-estimating query planner."), "query_cost_planner": ("true", "true", "Use the cost-estimating query planner."),
"query_plan_cache_ttl": ("60", "60", "Time to live for cached query plans, in seconds."), "query_plan_cache_ttl": ("60", "60", "Time to live for cached query plans, in seconds."),
"query_vertex_count_to_expand_existing": ( "query_vertex_count_to_expand_existing": (
"10", "-1",
"10", "-1",
"Maximum count of indexed vertices which provoke indexed lookup and then expand to existing, instead of a regular expand. Default is 10, to turn off use -1.", "Maximum count of indexed vertices which provoke indexed lookup and then expand to existing, instead of a regular expand. Default is 10, to turn off use -1.",
), ),
"query_max_plans": ("1000", "1000", "Maximum number of generated plans for a query."), "query_max_plans": ("1000", "1000", "Maximum number of generated plans for a query."),

View File

@@ -16,6 +16,7 @@ PIP_DEPS=(
"pyyaml==5.4.1" "pyyaml==5.4.1"
"six==1.15.0" "six==1.15.0"
"networkx==2.4" "networkx==2.4"
"gqlalchemy==1.3.3"
) )
cd "$DIR" cd "$DIR"