Add E2E test for optimizing merge on supernodes
This commit is contained in:
@@ -750,7 +750,7 @@ class IndexLookupRewriter final : public HierarchicalLogicalOperatorVisitor {
|
||||
auto maybe_label = FindBestLabelIndex(labels);
|
||||
if (!maybe_label) return nullptr;
|
||||
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
|
||||
// than the allowed count.
|
||||
return nullptr;
|
||||
|
||||
@@ -13,6 +13,7 @@ import sys
|
||||
|
||||
import pytest
|
||||
from common import connect, execute_and_fetch_all
|
||||
from gqlalchemy import Memgraph
|
||||
|
||||
# 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);")
|
||||
|
||||
|
||||
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__":
|
||||
sys.exit(pytest.main([__file__, "-rA"]))
|
||||
|
||||
@@ -175,8 +175,8 @@ startup_config_dict = {
|
||||
"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_vertex_count_to_expand_existing": (
|
||||
"10",
|
||||
"10",
|
||||
"-1",
|
||||
"-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."),
|
||||
|
||||
@@ -16,6 +16,7 @@ PIP_DEPS=(
|
||||
"pyyaml==5.4.1"
|
||||
"six==1.15.0"
|
||||
"networkx==2.4"
|
||||
"gqlalchemy==1.3.3"
|
||||
)
|
||||
cd "$DIR"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user