diff --git a/src/graph/visitor/PropertyTrackerVisitor.cpp b/src/graph/visitor/PropertyTrackerVisitor.cpp index fe66c7983f8..fb2483a63f0 100644 --- a/src/graph/visitor/PropertyTrackerVisitor.cpp +++ b/src/graph/visitor/PropertyTrackerVisitor.cpp @@ -317,7 +317,8 @@ void PropertyTrackerVisitor::visit(AggregateExpression *expr) { std::transform(funName.begin(), funName.end(), funName.begin(), ::tolower); if (funName == "count") { auto kind = expr->arg()->kind(); - if (kind == Expression::Kind::kConstant) { + if (kind == Expression::Kind::kVarProperty || kind == Expression::Kind::kConstant || + kind == Expression::Kind::kInputProperty) { return; } } diff --git a/src/graph/visitor/PrunePropertiesVisitor.cpp b/src/graph/visitor/PrunePropertiesVisitor.cpp index 3fe1f349f5d..0b687748ebf 100644 --- a/src/graph/visitor/PrunePropertiesVisitor.cpp +++ b/src/graph/visitor/PrunePropertiesVisitor.cpp @@ -125,11 +125,6 @@ void PrunePropertiesVisitor::visitCurrent(Aggregate *node) { } } for (auto *groupItem : node->groupItems()) { - if (groupItem->kind() == Expression::Kind::kVarProperty || - groupItem->kind() == Expression::Kind::kInputProperty || - groupItem->kind() == Expression::Kind::kConstant) { - continue; - } status_ = extractPropsFromExpr(groupItem); if (!status_.ok()) { return; @@ -446,7 +441,11 @@ void PrunePropertiesVisitor::visit(Unwind *node) { void PrunePropertiesVisitor::visitCurrent(Unwind *node) { const auto &alias = node->alias(); - if (propsUsed_.hasAlias(alias)) { + auto expr = node->unwindExpr(); + auto kind = expr->kind(); + // unwind e.start_year as a + if (propsUsed_.hasAlias(alias) || + (kind != Expression::Kind::kVarProperty && kind != Expression::Kind::kInputProperty)) { status_ = extractPropsFromExpr(node->unwindExpr()); if (!status_.ok()) { return; diff --git a/tests/common/plan_differ.py b/tests/common/plan_differ.py index 19cae12dc81..061f8a2d31e 100644 --- a/tests/common/plan_differ.py +++ b/tests/common/plan_differ.py @@ -189,15 +189,22 @@ def _is_subdict_nested(self, expect, resp): def _try_convert_json(j): try: - return json.loads(j) + res = json.loads(j) + if isinstance(res, list): + for m in res: + if isinstance(m, dict): + if 'tagId' in m: + m.pop('tagId') + if 'type' in m: + m.pop('type') + return res except: return j extracted_resp_dict = {} if len(key_list) == 1: - - for k in resp: - extracted_resp_dict[k] = _try_convert_json(resp[k]) + for k in resp: + extracted_resp_dict[k] = _try_convert_json(resp[k]) else: extracted_resp_dict = self._convert_jsonStr_to_dict(resp, key_list) diff --git a/tests/tck/conftest.py b/tests/tck/conftest.py index 294aa7f7d8a..4d06bbf6c0b 100644 --- a/tests/tck/conftest.py +++ b/tests/tck/conftest.py @@ -473,7 +473,6 @@ def executing_query( exec_query(request, ngql, exec_ctx, sess) sess.release() - @when(parse("profiling query:\n{query}")) def profiling_query(query, exec_ctx, request): ngql = "PROFILE {" + combine_query(query) + "}" @@ -826,7 +825,6 @@ def drop_used_space(exec_ctx): session = exec_ctx.get('current_session') response(session, stmt) - @then(parse("the execution plan should be:\n{plan}")) def check_plan(request, plan, exec_ctx): ngql = exec_ctx["ngql"] diff --git a/tests/tck/features/optimizer/PrunePropertiesRule.feature b/tests/tck/features/optimizer/PrunePropertiesRule.feature index 734d0383c9b..f2316b6ce13 100644 --- a/tests/tck/features/optimizer/PrunePropertiesRule.feature +++ b/tests/tck/features/optimizer/PrunePropertiesRule.feature @@ -19,12 +19,12 @@ Feature: Prune Properties rule | 33 | | 41 | And the execution plan should be: - | id | name | dependencies | operator info | - | 8 | Project | 4 | | - | 4 | AppendVertices | 3 | { "props": "[{\"props\":[\"age\"],\"tagId\": 3}]" } | - | 3 | Traverse | 7 | { "vertexProps": "", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"],\"type\": 6}]" } | - | 7 | IndexScan | 2 | | - | 2 | Start | | | + | id | name | dependencies | operator info | + | 8 | Project | 4 | | + | 4 | AppendVertices | 3 | { "props": "[{\"props\":[\"age\"]}]" } | + | 3 | Traverse | 7 | { "vertexProps": "", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"]}]" } | + | 7 | IndexScan | 2 | | + | 2 | Start | | | When profiling query: """ MATCH p = (v:player{name: "Tony Parker"})-[e:like]->(v2) @@ -36,12 +36,12 @@ Feature: Prune Properties rule | "Tony Parker" | | "Tony Parker" | And the execution plan should be: - | id | name | dependencies | operator info | - | 8 | Project | 4 | | - | 4 | AppendVertices | 3 | { "props": "[{\"tagId\": 5, \"props\": [\"_tag\"]}, {\"tagId\": 3, \"props\": [\"_tag\"]}, {\"tagId\": 4, \"props\": [\"_tag\"]}]"} | - | 3 | Traverse | 7 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 3}]", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"],\"type\": 6}]" } | - | 7 | IndexScan | 2 | | - | 2 | Start | | | + | id | name | dependencies | operator info | + | 8 | Project | 4 | | + | 4 | AppendVertices | 3 | { "props": "[{ \"props\": [\"_tag\"]}, {\"props\": [\"_tag\"]}, {\"props\": [\"_tag\"]}]"} | + | 3 | Traverse | 7 | { "vertexProps": "[{\"props\":[\"name\"]}]", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"]}]" } | + | 7 | IndexScan | 2 | | + | 2 | Start | | | When profiling query: """ MATCH p = (v:player{name: "Tony Parker"})-[e:like]-(v2) @@ -58,12 +58,12 @@ Feature: Prune Properties rule | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 8 | Project | 4 | | - | 4 | AppendVertices | 3 | { "props": "[{\"tagId\": 5, \"props\": [\"_tag\"]}, {\"tagId\": 3, \"props\": [\"_tag\"]}, {\"tagId\": 4, \"props\": [\"_tag\"]}]" } | - | 3 | Traverse | 7 | { "vertexProps": "[{\"props\": [\"name\", \"age\", \"_tag\"], \"tagId\": 3}, {\"props\": [\"name\", \"speciality\", \"_tag\"], \"tagId\": 5}, {\"tagId\": 4, \"props\": [\"name\", \"_tag\"]}]", "edgeProps": "[{\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -6}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 6}]" } | - | 7 | IndexScan | 2 | | - | 2 | Start | | | + | id | name | dependencies | operator info | + | 8 | Project | 4 | | + | 4 | AppendVertices | 3 | { "props": "[{\"props\": [\"_tag\"]}, {\"props\": [\"_tag\"]}, {\"props\": [\"_tag\"]}]" } | + | 3 | Traverse | 7 | { "vertexProps": "[{\"props\": [\"name\", \"age\", \"_tag\"]}, {\"props\": [\"name\", \"speciality\", \"_tag\"]}, {\"props\": [\"name\", \"_tag\"]}]", "edgeProps": "[{\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}]" } | + | 7 | IndexScan | 2 | | + | 2 | Start | | | When profiling query: """ MATCH p = (v:player{name: "Tony Parker"})-[e:like]->(v2) @@ -75,12 +75,12 @@ Feature: Prune Properties rule | ("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"}) | | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 8 | Project | 4 | | - | 4 | AppendVertices | 3 | { "props": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"], \"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]" } | - | 3 | Traverse | 7 | { "vertexProps": "", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"],\"type\": 6}]" } | - | 7 | IndexScan | 2 | | - | 2 | Start | | | + | id | name | dependencies | operator info | + | 8 | Project | 4 | | + | 4 | AppendVertices | 3 | { "props": "[{\"props\":[\"name\", \"age\", \"_tag\"]}, {\"props\":[\"name\", \"speciality\", \"_tag\"]}, {\"props\":[\"name\", \"_tag\"]}]" } | + | 3 | Traverse | 7 | { "vertexProps": "", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"]}]" } | + | 7 | IndexScan | 2 | | + | 2 | Start | | | # The rule will not take affect in this case because it returns the whole path When executing query: """ @@ -108,12 +108,12 @@ Feature: Prune Properties rule | "like" | | "like" | And the execution plan should be: - | id | name | dependencies | operator info | - | 8 | Project | 4 | | - | 4 | AppendVertices | 3 | { "props": "[{\"props\":[\"_tag\"],\"tagId\": 5}, {\"props\":[\"_tag\"],\"tagId\": 3}, {\"props\":[\"_tag\"],\"tagId\": 4} ]" } | - | 3 | Traverse | 7 | { "vertexProps": "", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"],\"type\": 6}]" } | - | 7 | IndexScan | 2 | | - | 2 | Start | | | + | id | name | dependencies | operator info | + | 8 | Project | 4 | | + | 4 | AppendVertices | 3 | { "props": "[{\"props\":[\"_tag\"]}, {\"props\":[\"_tag\"]}, {\"props\":[\"_tag\"]} ]" } | + | 3 | Traverse | 7 | { "vertexProps": "", "edgeProps": "[{\"props\":[\"_dst\", \"_rank\", \"_type\"]}]" } | + | 7 | IndexScan | 2 | | + | 2 | Start | | | When executing query: """ MATCH (v:player{name: "Tony Parker"})-[:like]-(v2)--(v3) @@ -170,21 +170,21 @@ Feature: Prune Properties rule | "Tim Duncan" | "Boris Diaw" | "Suns" | | "Tim Duncan" | "Boris Diaw" | "Tim Duncan" | And the execution plan should be: - | id | name | dependencies | operator info | - | 16 | TopN | 12 | | - | 12 | Project | 9 | | - | 9 | HashInnerJoin | 22, 23 | | - | 22 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 23 | Project | 8 | | - | 8 | AppendVertices | 7 | { "props": "[{\"tagId\": 3,\"props\":[\"name\"]}, {\"tagId\": 4,\"props\":[\"name\"]}]" } | - | 7 | Traverse | 6 | { "vertexProps": "[{\"tagId\": 3,\"props\":[\"name\"]}]", "edgeProps": "[{\"type\": -8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"type\": -7, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -6}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 6}, {\"type\": -7, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 7}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 8}]" } | - | 6 | Argument | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 16 | TopN | 12 | | + | 12 | Project | 9 | | + | 9 | HashInnerJoin | 22, 23 | | + | 22 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"]}]" } | + | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"] }]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 23 | Project | 8 | | + | 8 | AppendVertices | 7 | { "props": "[{ \"props\":[\"name\"]}, { \"props\":[\"name\"]}]" } | + | 7 | Traverse | 6 | { "vertexProps": "[{ \"props\":[\"name\"]}]", "edgeProps": "[{ \"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}]" } | + | 6 | Argument | 0 | | + | 0 | Start | | | When profiling query: """ MATCH (m)-[]-(n), (n)-[]-(l), (l)-[]-(h) WHERE id(m)=="Tim Duncan" @@ -204,26 +204,26 @@ Feature: Prune Properties rule | "Tim Duncan" | "Aron Baynes" | "Spurs" | "Aron Baynes" | | "Tim Duncan" | "Aron Baynes" | "Spurs" | "Boris Diaw" | And the execution plan should be: - | id | name | dependencies | operator info | - | 20 | TopN | 23 | | - | 23 | Project | 13 | | - | 13 | HashInnerJoin | 9, 30 | | - | 9 | HashInnerJoin | 28, 29 | | - | 28 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 3}]", "edgeProps": "[{\"type\": -8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"type\": 8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -6}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 6}, {\"type\": -7, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 7}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 29 | Project | 8 | | - | 8 | AppendVertices | 7 | { "props": "[{\"tagId\": 4,\"props\":[\"name\"]}]" } | - | 7 | Traverse | 6 | { "vertexProps": "[{\"tagId\": 3,\"props\":[\"name\"]}]", "edgeProps": "[{\"type\": -8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"type\": 8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -6}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 6}, {\"type\": -7, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 7}]" } | - | 6 | Argument | | | - | 30 | Project | 12 | | - | 12 | AppendVertices | 11 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 11 | Traverse | 10 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 4}]", "edgeProps": "[{\"type\": -8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"type\": 8, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -6}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 6}, {\"type\": -7, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 7}]" } | - | 10 | Argument | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 20 | TopN | 23 | | + | 23 | Project | 13 | | + | 13 | HashInnerJoin | 9, 30 | | + | 9 | HashInnerJoin | 28, 29 | | + | 28 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"] }]" } | + | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"] }]", "edgeProps": "[{ \"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 29 | Project | 8 | | + | 8 | AppendVertices | 7 | { "props": "[{ \"props\":[\"name\"]}]" } | + | 7 | Traverse | 6 | { "vertexProps": "[{ \"props\":[\"name\"]}]", "edgeProps": "[{ \"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}]" } | + | 6 | Argument | | | + | 30 | Project | 12 | | + | 12 | AppendVertices | 11 | { "props": "[{\"props\":[\"name\"] }]" } | + | 11 | Traverse | 10 | { "vertexProps": "[{\"props\":[\"name\"] }]", "edgeProps": "[{ \"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"]}]" } | + | 10 | Argument | 0 | | + | 0 | Start | | | # The schema id is not fixed in standalone cluster, so we skip it @distonly @@ -250,20 +250,20 @@ Feature: Prune Properties rule | "Tim Duncan" | "Boris Diaw" | "Suns" | | "Tim Duncan" | "Boris Diaw" | "Tim Duncan" | And the execution plan should be: - | id | name | dependencies | operator info | - | 17 | TopN | 13 | | - | 13 | Project | 12 | | - | 12 | HashInnerJoin | 19, 11 | | - | 19 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 11 | Project | 10 | | - | 10 | AppendVertices | 9 | { "props": "[{\"tagId\": 3,\"props\":[\"name\"]}, {\"tagId\": 4,\"props\":[\"name\"]}]" } | - | 9 | Traverse | 8 | { "vertexProps": "[{\"tagId\": 3,\"props\":[\"name\"]}]" } | - | 8 | Argument | | | + | id | name | dependencies | operator info | + | 17 | TopN | 13 | | + | 13 | Project | 12 | | + | 12 | HashInnerJoin | 19, 11 | | + | 19 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"] }]" } | + | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"] }]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 11 | Project | 10 | | + | 10 | AppendVertices | 9 | { "props": "[{ \"props\":[\"name\"]}, { \"props\":[\"name\"]}]" } | + | 9 | Traverse | 8 | { "vertexProps": "[{ \"props\":[\"name\"]}]" } | + | 8 | Argument | | | When profiling query: """ MATCH (m)-[]-(n) WHERE id(m)=="Tim Duncan" @@ -284,25 +284,25 @@ Feature: Prune Properties rule | "Tim Duncan" | "Aron Baynes" | "Spurs" | "Aron Baynes" | | "Tim Duncan" | "Aron Baynes" | "Spurs" | "Boris Diaw" | And the execution plan should be: - | id | name | dependencies | operator info | - | 21 | TopN | 17 | | - | 17 | Project | 16 | | - | 16 | HashInnerJoin | 23, 14 | | - | 23 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 14 | HashInnerJoin | 33, 34 | | - | 33 | Project | 10 | | - | 10 | AppendVertices | 9 | { "props": "[{\"tagId\": 4,\"props\":[\"name\"]}]" } | - | 9 | Traverse | 8 | { "vertexProps": "[{\"tagId\": 3,\"props\":[\"name\"]}]" } | - | 8 | Argument | | | - | 34 | Project | 13 | | - | 13 | AppendVertices | 12 | { "props": "[{\"tagId\": 3,\"props\":[\"name\"]}]" } | - | 12 | Traverse | 11 | { "vertexProps": "[{\"tagId\": 4,\"props\":[\"name\"]}]", "edgeProps": "[{\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -8}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 8}, {\"type\": -6, \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 6}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": -7}, {\"props\": [\"_dst\", \"_rank\", \"_type\"], \"type\": 7}]" } | - | 11 | Argument | | | + | id | name | dependencies | operator info | + | 21 | TopN | 17 | | + | 17 | Project | 16 | | + | 16 | HashInnerJoin | 23, 14 | | + | 23 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"] }]" } | + | 4 | Traverse | 2 | { "vertexProps": "[{\"props\":[\"name\"] }]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 14 | HashInnerJoin | 33, 34 | | + | 33 | Project | 10 | | + | 10 | AppendVertices | 9 | { "props": "[{ \"props\":[\"name\"]}]" } | + | 9 | Traverse | 8 | { "vertexProps": "[{ \"props\":[\"name\"]}]" } | + | 8 | Argument | | | + | 34 | Project | 13 | | + | 13 | AppendVertices | 12 | { "props": "[{ \"props\":[\"name\"]}]" } | + | 12 | Traverse | 11 | { "vertexProps": "[{ \"props\":[\"name\"]}]", "edgeProps": "[{\"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"] }, { \"props\": [\"_dst\", \"_rank\", \"_type\"]}, {\"props\": [\"_dst\", \"_rank\", \"_type\"] }, {\"props\": [\"_dst\", \"_rank\", \"_type\"] }, {\"props\": [\"_dst\", \"_rank\", \"_type\"] }]" } | + | 11 | Argument | | | When profiling query: """ MATCH (v:player{name:"Tony Parker"}) @@ -315,18 +315,18 @@ Feature: Prune Properties rule | "Tim Duncan" | | "Tim Duncan" | And the execution plan should be: - | id | name | dependencies | operator info | - | 10 | Project | 11 | | - | 11 | HashInnerJoin | 14, 9 | | - | 14 | Project | 3 | | - | 3 | AppendVertices | 12 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 12 | IndexScan | 2 | | - | 2 | Start | | | - | 9 | Project | 8 | | - | 8 | AppendVertices | 7 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 7 | Traverse | 6 | { "vertexProps": "", "edgeProps": "[{\"type\": -8, \"props\": [\"_type\", \"_rank\", \"_dst\"]}, {\"props\": [\"_type\", \"_rank\", \"_dst\"], \"type\": -6}, {\"props\": [\"_type\", \"_rank\", \"_dst\"], \"type\": -7}]" } | - | 6 | Argument | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 10 | Project | 11 | | + | 11 | HashInnerJoin | 14, 9 | | + | 14 | Project | 3 | | + | 3 | AppendVertices | 12 | { "props": "[{\"props\":[\"name\"] }]" } | + | 12 | IndexScan | 2 | | + | 2 | Start | | | + | 9 | Project | 8 | | + | 8 | AppendVertices | 7 | { "props": "[{\"props\":[\"name\"] }]" } | + | 7 | Traverse | 6 | { "vertexProps": "", "edgeProps": "[{\"props\": [\"_type\", \"_rank\", \"_dst\"]}, {\"props\": [\"_type\", \"_rank\", \"_dst\"]}, {\"props\": [\"_type\", \"_rank\", \"_dst\"] }]"} | + | 6 | Argument | 0 | | + | 0 | Start | | | # The schema id is not fixed in standalone cluster, so we skip it @distonly @@ -351,20 +351,20 @@ Feature: Prune Properties rule | "Tim Duncan" | "Manu Ginobili" | NULL | | "Tim Duncan" | "Manu Ginobili" | NULL | And the execution plan should be: - | id | name | dependencies | operator info | - | 17 | TopN | 13 | | - | 13 | Project | 12 | | - | 12 | HashLeftJoin | 19, 11 | | - | 19 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 4 | Traverse | 2 | | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 11 | Project | 10 | | - | 10 | AppendVertices | 9 | { "props": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"],\"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]" } | - | 9 | Traverse | 8 | { "vertexProps": "[{\"props\":[\"name\"],\"tagId\": 3}]" } | - | 8 | Argument | | | + | id | name | dependencies | operator info | + | 17 | TopN | 13 | | + | 13 | Project | 12 | | + | 12 | HashLeftJoin | 19, 11 | | + | 19 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"name\"] }]" } | + | 4 | Traverse | 2 | | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 11 | Project | 10 | | + | 10 | AppendVertices | 9 | { "props": "[{\"props\":[\"name\", \"age\", \"_tag\"] }, {\"props\":[\"name\", \"speciality\", \"_tag\"] }, {\"props\":[\"name\", \"_tag\"] }]" } | + | 9 | Traverse | 8 | { "vertexProps": "[{\"props\":[\"name\"] }]" } | + | 8 | Argument | | | When profiling query: """ MATCH (m:player{name:"Tim Duncan"})-[:like]-(n)--() @@ -391,6 +391,24 @@ Feature: Prune Properties rule @distonly Scenario: return function Given a graph with space named "nba" + When profiling query: + """ + MATCH (v1)-[:like]->(v2) + WHERE id(v1) == "Tim Duncan" + RETURN count(v2), v1 + """ + Then the result should be, in order: + | count(v2) | v1 | + | 2 | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + And the execution plan should be: + | id | name | dependencies | operator info | + | 7 | Aggregate | 6 | | + | 6 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }]" } | + | 4 | Traverse | 2 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"] }, {\"props\":[\"name\", \"speciality\", \"_tag\"] }, {\"props\":[\"name\", \"_tag\"] }]" , "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | When profiling query: """ MATCH (v1)-[e:like*1..5]->(v2) @@ -401,14 +419,14 @@ Feature: Prune Properties rule | count(v2.player.age) | | 24 | And the execution plan should be: - | id | name | dependencies | operator info | - | 7 | Aggregate | 6 | | - | 6 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"age\"],\"tagId\": 3}]" } | - | 4 | Traverse | 2 | {"vertexProps": "", "edgeProps": "[{\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | + | id | name | dependencies | operator info | + | 7 | Aggregate | 6 | | + | 6 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"age\"] }]" } | + | 4 | Traverse | 2 | {"vertexProps": "", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | When profiling query: """ MATCH (v1)-[e:like*1..5]->(v2) @@ -419,14 +437,14 @@ Feature: Prune Properties rule | count(v2) | | 24 | And the execution plan should be: - | id | name | dependencies | operator info | - | 7 | Aggregate | 6 | | - | 6 | Project | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"_tag\", \"name\", \"speciality\"],\"tagId\": 5}, {\"props\":[\"_tag\", \"name\", \"age\"],\"tagId\": 3}, {\"props\":[\"_tag\", \"name\"],\"tagId\": 4}]" } | - | 4 | Traverse | 2 | {"vertexProps": "", "edgeProps": "[{\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | + | id | name | dependencies | operator info | + | 7 | Aggregate | 6 | | + | 6 | Project | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }]" } | + | 4 | Traverse | 2 | {"vertexProps": "" , "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | When profiling query: """ MATCH p = (v1)-[e:like*1..5]->(v2) @@ -437,14 +455,14 @@ Feature: Prune Properties rule | length(p) | | 1 | And the execution plan should be: - | id | name | dependencies | operator info | - | 13 | Project | 11 | | - | 11 | Limit | 5 | | - | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"_tag\", \"name\", \"speciality\"],\"tagId\": 5}, {\"props\":[\"_tag\", \"name\", \"age\"],\"tagId\": 3}, {\"props\":[\"_tag\", \"name\"],\"tagId\": 4}]" } | - | 4 | Traverse | 2 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"],\"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]", "edgeProps": "[{\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\", \"_src\", \"likeness\"]}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | + | id | name | dependencies | operator info | + | 13 | Project | 11 | | + | 11 | Limit | 5 | | + | 5 | AppendVertices | 4 | { "props": "[{\"props\":[\"_tag\", \"name\", \"speciality\"] }, {\"props\":[\"_tag\", \"name\", \"age\"] }, {\"props\":[\"_tag\", \"name\"] }]" } | + | 4 | Traverse | 2 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"] }, {\"props\":[\"name\", \"speciality\", \"_tag\"] }, {\"props\":[\"name\", \"_tag\"] }]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\", \"_src\", \"likeness\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | When profiling query: """ MATCH p = (a:player)-[e:like*1..3]->(b:player{age:39}) @@ -464,19 +482,19 @@ Feature: Prune Properties rule | "Tracy McGrady" | 1 | | "Tracy McGrady" | 3 | And the execution plan should be: - | id | name | dependencies | operator info | - | 14 | Project | 13 | | - | 13 | HashInnerJoin | 15,12 | | - | 15 | Project | 17 | | - | 17 | AppendVertices | 16 | { "props": "[{\"props\":[\"_tag\", \"name\", \"speciality\"],\"tagId\": 5}, {\"props\":[\"_tag\", \"name\", \"age\"],\"tagId\": 3}, {\"props\":[\"_tag\", \"name\"],\"tagId\": 4}]" } | - | 16 | Traverse | 2 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"],\"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]", "edgeProps": "[{\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\", \"_src\", \"likeness\"]}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 12 | Project | 18 | | - | 18 | AppendVertices | 10 | { "props": "[{\"props\":[\"_tag\"],\"tagId\": 4}]" } | - | 10 | Traverse | 8 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"],\"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]", "edgeProps": "[{\"type\": 7, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 8 | Argument | | | + | id | name | dependencies | operator info | + | 14 | Project | 13 | | + | 13 | HashInnerJoin | 15,12 | | + | 15 | Project | 17 | | + | 17 | AppendVertices | 16 | { "props": "[{\"props\":[\"_tag\", \"name\", \"speciality\"] }, {\"props\":[\"_tag\", \"name\", \"age\"] }, {\"props\":[\"_tag\", \"name\"] }]" } | + | 16 | Traverse | 2 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"] }, {\"props\":[\"name\", \"speciality\", \"_tag\"] }, {\"props\":[\"name\", \"_tag\"] }]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\", \"_src\", \"likeness\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 12 | Project | 18 | | + | 18 | AppendVertices | 10 | { "props": "[{\"props\":[\"_tag\"] }]" } | + | 10 | Traverse | 8 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"] }, {\"props\":[\"name\", \"speciality\", \"_tag\"] }, {\"props\":[\"name\", \"_tag\"] }]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 8 | Argument | | | @distonly Scenario: union match @@ -498,19 +516,19 @@ Feature: Prune Properties rule | "LaMarcus Aldridge" | | "Steve Nash" | And the execution plan should be: - | id | name | dependencies | operator info | - | 14 | Dedup | 13 | | - | 13 | Union | 18, 19 | | - | 18 | Project | 4 | | - | 4 | AppendVertices | 20 | { "props": "[{\"props\":[\"_tag\"],\"tagId\": 5}, {\"props\":[\"_tag\"],\"tagId\": 3}, {\"props\":[\"_tag\"],\"tagId\": 4}]" } | - | 20 | Traverse | 16 | {"vertexProps": "", "edgeProps": "[{\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 16 | IndexScan | 2 | | - | 2 | Start | | | - | 19 | Project | 10 | | - | 10 | AppendVertices | 21 | { "props": "[{\"props\":[\"_tag\"],\"tagId\": 5}, {\"props\":[\"_tag\"],\"tagId\": 3}, {\"props\":[\"_tag\"],\"tagId\": 4}]" } | - | 21 | Traverse | 17 | {"vertexProps": "", "edgeProps": "[{\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}, {\"type\": -6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 17 | IndexScan | 8 | | - | 8 | Start | | | + | id | name | dependencies | operator info | + | 14 | Dedup | 13 | | + | 13 | Union | 18, 19 | | + | 18 | Project | 4 | | + | 4 | AppendVertices | 20 | { "props": "[{\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }]" } | + | 20 | Traverse | 16 | {"vertexProps": "", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 16 | IndexScan | 2 | | + | 2 | Start | | | + | 19 | Project | 10 | | + | 10 | AppendVertices | 21 | { "props": "[{\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }, {\"props\":[\"_tag\"] }]" } | + | 21 | Traverse | 17 | {"vertexProps": "", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}, { \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 17 | IndexScan | 8 | | + | 8 | Start | | | @distonly Scenario: optional match @@ -530,27 +548,27 @@ Feature: Prune Properties rule | "Spurs" | 11 | | "Hornets" | 3 | And the execution plan should be: - | id | name | dependencies | operator info | - | 21 | Aggregate | 20 | | - | 20 | Aggregate | 19 | | - | 19 | HashLeftJoin | 10, 25 | | - | 10 | Aggregate | 23 | | - | 23 | Project | 22 | | - | 22 | Filter | 29 | | - | 29 | AppendVertices | 28 | { "props": "[{\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]" } | - | 28 | Traverse | 27 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"],\"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]", "edgeProps": "[{\"type\": 7, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 27 | Traverse | 26 | {"vertexProps": "", "edgeProps": "[{\"type\": -8, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 26 | Traverse | 2 | {"vertexProps": "", "edgeProps": "[{\"type\": -6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}, {\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 2 | Dedup | 1 | | - | 1 | PassThrough | 3 | | - | 3 | Start | | | - | 25 | Project | 24 | | - | 24 | Filter | 16 | | - | 16 | AppendVertices | 15 | { "props": "[{\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]" } | - | 15 | Traverse | 14 | {"vertexProps": "[{\"props\":[\"name\", \"age\", \"_tag\"],\"tagId\": 3}, {\"props\":[\"name\", \"speciality\", \"_tag\"],\"tagId\": 5}, {\"props\":[\"name\", \"_tag\"],\"tagId\": 4}]", "edgeProps": "[{\"type\": 7, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 14 | Traverse | 13 | {"vertexProps": "", "edgeProps": "[{\"type\": -6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 13 | Traverse | 11 | {"vertexProps": "", "edgeProps": "[{\"type\": -6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}, {\"type\": 6, \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | - | 11 | Argument | | | + | id | name | dependencies | operator info | + | 21 | Aggregate | 20 | | + | 20 | Aggregate | 19 | | + | 19 | HashLeftJoin | 10, 25 | | + | 10 | Aggregate | 23 | | + | 23 | Project | 22 | | + | 22 | Filter | 29 | | + | 29 | AppendVertices | 28 | { "props": "[{ \"props\":[\"name\",\"age\",\"_tag\"]},{\"props\":[\"name\",\"speciality\",\"_tag\"] },{ \"props\":[\"name\",\"_tag\"]}]" } | + | 28 | Traverse | 27 | {"vertexProps": "[{\"props\":[\"age\"] }]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 27 | Traverse | 26 | {"vertexProps": "", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 26 | Traverse | 2 | {"vertexProps": "[{ \"props\":[\"name\",\"age\",\"_tag\"]},{\"props\":[\"name\",\"speciality\",\"_tag\"] },{ \"props\":[\"name\",\"_tag\"]}]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}, { \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 3 | | + | 3 | Start | | | + | 25 | Project | 24 | | + | 24 | Filter | 16 | | + | 16 | AppendVertices | 15 | { "props": "[{ \"props\":[\"name\",\"age\",\"_tag\"]},{\"props\":[\"name\",\"speciality\",\"_tag\"] },{ \"props\":[\"name\",\"_tag\"]}]"} | + | 15 | Traverse | 14 | {"vertexProps": "[{\"props\":[\"age\"] }]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 14 | Traverse | 13 | {"vertexProps": "", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 13 | Traverse | 11 | {"vertexProps": "[{ \"props\":[\"name\",\"age\",\"_tag\"]},{\"props\":[\"name\",\"speciality\",\"_tag\"] },{ \"props\":[\"name\",\"_tag\"]}]", "edgeProps": "[{ \"props\": [\"_type\", \"_rank\", \"_dst\"]}, { \"props\": [\"_type\", \"_rank\", \"_dst\"]}]" } | + | 11 | Argument | | | @distonly Scenario: test properties: