{"action":"created","comment":{"url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/comments/152013386","pull_request_review_id":77809954,"id":152013386,"diff_hunk":"@@ -29,173 +29,406 @@ import org.opencypher.caps.impl.logical\n import org.opencypher.caps.impl.util.toVar\n import org.opencypher.caps.ir.api._\n import org.opencypher.caps.ir.api.block._\n-import org.opencypher.caps.ir.api.pattern.{DirectedRelationship, Pattern}\n+import org.opencypher.caps.ir.api.pattern.{AllGiven, DirectedRelationship, Pattern}\n import org.opencypher.caps.ir.impl.IrTestSuite\n import org.opencypher.caps.toField\n-import org.scalatest.matchers.{MatchResult, Matcher}\n+import org.scalatest.matchers._\n \n import scala.language.implicitConversions\n \n class LogicalPlannerTest extends IrTestSuite {\n \n-  val nodeA = IRField(\"a\")(CTNode)\n-  val nodeB = IRField(\"b\")(CTNode)\n-  val nodeG = IRField(\"g\")(CTNode)\n-  val relR = IRField(\"r\")(CTRelationship)\n+  val nodeA = IRField(\"a\", CTNode)\n+  val nodeB = IRField(\"b\", CTNode)\n+  val nodeG = IRField(\"g\", CTNode)\n+  val relR = IRField(\"r\", CTRelationship)\n+  val uri = URI.create(\"test\")\n+\n+  val emptySqm = SolvedQueryModel.empty[Expr]\n+\n+  // Helper to create nicer expected results with `asCode`\n+//  implicit val specialMappings = Map[Any, String](\n+//    Schema.empty -> \"Schema.empty\",\n+//    CTNode -> \"CTNode\",\n+//    CTRelationship -> \"CTRelationship\",\n+//    emptySqm -> \"emptySqm\",\n+//    nodeA -> \"nodeA\",\n+//    relR -> \"relR\",\n+//    nodeB -> \"nodeB\",\n+//    (nodeA: IRField) -> \"nodeA\",\n+//    (relR: IRField) -> \"relR\",\n+//    (nodeB: IRField) -> \"nodeB\"\n+//  )\n \n   test(\"convert load graph block\") {\n-    plan(irFor(leafBlock)) should equal(Select(IndexedSeq.empty, Set.empty, leafPlan)(emptySqm))\n+    val result = plan(irFor(leafBlock))\n+    val expected = Select(IndexedSeq.empty, Set.empty, leafPlan, emptySqm)\n+    result should structurallyEqual(expected)\n   }\n \n   test(\"convert match block\") {\n-    val pattern = Pattern.empty[Expr]\n+    val pattern = Pattern\n+      .empty[Expr]\n       .withEntity(nodeA)\n       .withEntity(nodeB)\n       .withEntity(relR)\n       .withConnection(relR, DirectedRelationship(nodeA, nodeB))\n \n     val block = matchBlock(pattern)\n \n-    val scan1 = NodeScan(nodeA, SetSourceGraph(leafPlan.sourceGraph, leafPlan)(emptySqm.withField(nodeA)))(emptySqm.withField(nodeA))\n-    val scan2 = NodeScan(nodeB, leafPlan)(emptySqm.withField(nodeB))\n-    plan(irWithLeaf(block)) should equalWithoutResult(\n-      ExpandSource(nodeA, relR, nodeB, scan1, scan2)(emptySqm.withFields(nodeA, nodeB, relR))\n-    )\n-  }\n+    val scan1 = NodeScan(nodeA, SetSourceGraph(leafPlan.sourceGraph, leafPlan, emptySqm), emptySqm.withField(nodeA))\n+    val scan2 = NodeScan(nodeB, leafPlan, emptySqm.withField(nodeB))\n+    val ir = irWithLeaf(block)\n+    val result = plan(ir)\n \n-  val emptySqm = SolvedQueryModel.empty[Expr]\n+    val expected = ExpandSource(nodeA, relR, nodeB, scan1, scan2, SolvedQueryModel(Set(nodeA, nodeB, relR)))\n+\n+    result should equalWithoutResult(expected)\n+  }\n \n   test(\"convert project block\") {\n-    val fields = FieldsAndGraphs[Expr](Map(toField('a) -> Property('n, PropertyKey(\"prop\"))(CTFloat)))\n+    val fields = FieldsAndGraphs[Expr](Map(toField('a) -> Property('n, PropertyKey(\"prop\"), CTFloat)))\n     val block = project(fields)\n \n-    plan(irWithLeaf(block)) should equalWithoutResult(\n-      Project(ProjectedField('a, Property('n, PropertyKey(\"prop\"))(CTFloat)),   // n is a dangling reference here\n-        leafPlan)(emptySqm.withFields('a))\n-    )\n+    val result = plan(irWithLeaf(block))\n+\n+    val expected = Project(\n+      ProjectedField('a, Property('n, PropertyKey(\"prop\"), CTFloat)), // n is a dangling reference here\n+      leafPlan,\n+      emptySqm.withFields('a))\n+    result should equalWithoutResult(expected)\n   }\n \n   test(\"plan query\") {\n-    val ir = \"MATCH (a:Administrator)-[r]->(g:Group) WHERE g.name = $foo RETURN a.name\".irWithParams(\"foo\" -> CypherString(\"test\"))\n-\n-    plan(ir) should equal(\n-      Select(IndexedSeq(Var(\"a.name\")(CTNull)), Set.empty,\n-        Project(ProjectedField(Var(\"a.name\")(CTNull), Property(Var(\"a\")(CTNode(\"Administrator\")), PropertyKey(\"name\"))(CTNull)),\n-          Filter(Equals(Property(Var(\"g\")(CTNode(\"Group\")), PropertyKey(\"name\"))(CTNull), Param(\"foo\")(CTString))(CTBoolean),\n-            Project(ProjectedExpr(Property(Var(\"g\")(CTNode(\"Group\")), PropertyKey(\"name\"))(CTNull)),\n-              Filter(HasLabel(Var(\"g\")(CTNode), Label(\"Group\"))(CTBoolean),\n-                Filter(HasLabel(Var(\"a\")(CTNode), Label(\"Administrator\"))(CTBoolean),\n-                  ExpandSource(Var(\"a\")(CTNode), Var(\"r\")(CTRelationship), Var(\"g\")(CTNode),\n-                    NodeScan(Var(\"a\")(CTNode),\n-                      SetSourceGraph(LogicalExternalGraph(testGraph.name, testGraph.uri, Schema.empty),\n-                        Start(LogicalExternalGraph(testGraph.name, testGraph.uri, Schema.empty), Set.empty)(emptySqm)\n-                      )(emptySqm)\n-                    )(emptySqm),\n-                    NodeScan(Var(\"g\")(CTNode),\n-                      Start(LogicalExternalGraph(testGraph.name, testGraph.uri, Schema.empty), Set.empty)(emptySqm)\n-                    )(emptySqm)\n-                  )(emptySqm)\n-                )(emptySqm)\n-              )(emptySqm)\n-            )(emptySqm)\n-          )(emptySqm)\n-        )(emptySqm)\n-      )(emptySqm)\n+    val ir = \"MATCH (a:Administrator)-[r]->(g:Group) WHERE g.name = $foo RETURN a.name\".irWithParams(\n+      \"foo\" -> CypherString(\"test\"))\n+    val result = plan(ir)\n+\n+    val expected = Project(\n+      ProjectedField(\n+        Var(\"a.name\", CTNull),\n+        Property(Var(\"a\", CTNode(Set(\"Administrator\"))), PropertyKey(\"name\"), CTNull)),\n+      Filter(\n+        Equals(\n+          Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTNull),\n+          Param(\"foo\", CTString),\n+          CTBoolean),\n+        Project(\n+          ProjectedExpr(Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTNull)),\n+          Filter(\n+            HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean),\n+            Filter(\n+              HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+              ExpandSource(\n+                Var(\"a\", CTNode),\n+                Var(\"r\", CTRelationship),\n+                Var(\"g\", CTNode),\n+                NodeScan(\n+                  Var(\"a\", CTNode),\n+                  SetSourceGraph(\n+                    LogicalExternalGraph(\"test\", uri, Schema.empty),\n+                    Start(LogicalExternalGraph(\"test\", uri, Schema.empty), Set(), emptySqm),\n+                    emptySqm),\n+                  SolvedQueryModel(Set(nodeA), Set(), Set())\n+                ),\n+                NodeScan(\n+                  Var(\"g\", CTNode),\n+                  Start(LogicalExternalGraph(\"test\", uri, Schema.empty), Set(), emptySqm),\n+                  SolvedQueryModel(Set(IRField(\"g\", CTNode)), Set(), Set())),\n+                SolvedQueryModel(Set(nodeA, IRField(\"g\", CTNode), relR))\n+              ),\n+              SolvedQueryModel(\n+                Set(nodeA, IRField(\"g\", CTNode), relR),\n+                Set(HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean)))\n+            ),\n+            SolvedQueryModel(\n+              Set(nodeA, IRField(\"g\", CTNode), relR),\n+              Set(\n+                HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+                HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean))\n+            )\n+          ),\n+          SolvedQueryModel(\n+            Set(nodeA, IRField(\"g\", CTNode), relR),\n+            Set(\n+              HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+              HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean))\n+          )\n+        ),\n+        SolvedQueryModel(\n+          Set(nodeA, IRField(\"g\", CTNode), relR),\n+          Set(\n+            HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+            HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean),\n+            Equals(\n+              Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTNull),\n+              Param(\"foo\", CTString),\n+              CTBoolean)\n+          )\n+        )\n+      ),\n+      SolvedQueryModel(\n+        Set(nodeA, IRField(\"g\", CTNode), relR, IRField(\"a.name\", CTNull)),\n+        Set(\n+          HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+          HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean),\n+          Equals(\n+            Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTNull),\n+            Param(\"foo\", CTString),\n+            CTBoolean)\n+        )\n+      )\n     )\n+    result should equalWithoutResult(expected)\n   }\n \n   test(\"plan query with type information\") {\n     implicit val schema: Schema = Schema.empty\n       .withNodePropertyKeys(\"Group\")(\"name\" -> CTString)\n       .withNodePropertyKeys(\"Administrator\")(\"name\" -> CTFloat)\n \n-    val ir = \"MATCH (a:Administrator)-[r]->(g:Group) WHERE g.name = $foo RETURN a.name\".irWithParams(\"foo\" -> CypherString(\"test\"))\n-\n-    plan(ir, schema) should equal(\n-      Select(IndexedSeq(Var(\"a.name\")(CTFloat)), Set.empty,\n-        Project(ProjectedField(Var(\"a.name\")(CTFloat), Property(Var(\"a\")(CTNode(\"Administrator\")), PropertyKey(\"name\"))(CTFloat)),\n-          Filter(Equals(Property(Var(\"g\")(CTNode(\"Group\")), PropertyKey(\"name\"))(CTString), Param(\"foo\")(CTString))(CTBoolean),\n-            Project(ProjectedExpr(Property(Var(\"g\")(CTNode(\"Group\")), PropertyKey(\"name\"))(CTString)),\n-              Filter(HasLabel(Var(\"g\")(CTNode), Label(\"Group\"))(CTBoolean),\n-                Filter(HasLabel(Var(\"a\")(CTNode), Label(\"Administrator\"))(CTBoolean),\n-                  ExpandSource(Var(\"a\")(CTNode), Var(\"r\")(CTRelationship), Var(\"g\")(CTNode),\n-                    NodeScan(Var(\"a\")(CTNode),\n-                      SetSourceGraph(LogicalExternalGraph(testGraph.name, testGraph.uri, schema),\n-                        Start(LogicalExternalGraph(testGraph.name, testGraph.uri, schema), Set.empty)(emptySqm)\n-                      )(emptySqm)\n-                    )(emptySqm),\n-                    NodeScan(Var(\"g\")(CTNode),\n-                      Start(LogicalExternalGraph(testGraph.name, testGraph.uri, schema), Set.empty)(emptySqm)\n-                    )(emptySqm)\n-                  )(emptySqm)\n-                )(emptySqm)\n-              )(emptySqm)\n-            )(emptySqm)\n-          )(emptySqm)\n-        )(emptySqm)\n-      )(emptySqm)\n+    val ir = \"MATCH (a:Administrator)-[r]->(g:Group) WHERE g.name = $foo RETURN a.name\".irWithParams(\n+      \"foo\" -> CypherString(\"test\"))\n+\n+    val result = plan(ir, schema)\n+\n+    val expected = Project(\n+      ProjectedField(\n+        Var(\"a.name\", CTFloat),\n+        Property(Var(\"a\", CTNode(Set(\"Administrator\"))), PropertyKey(\"name\"), CTFloat)),\n+      Filter(\n+        Equals(\n+          Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTString),\n+          Param(\"foo\", CTString),\n+          CTBoolean),\n+        Project(\n+          ProjectedExpr(Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTString)),\n+          Filter(\n+            HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean),\n+            Filter(\n+              HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+              ExpandSource(\n+                Var(\"a\", CTNode),\n+                Var(\"r\", CTRelationship),\n+                Var(\"g\", CTNode),\n+                NodeScan(\n+                  Var(\"a\", CTNode),\n+                  SetSourceGraph(\n+                    LogicalExternalGraph(\n+                      \"test\",\n+                      uri,\n+                      Schema(\n+                        Set(\"Group\", \"Administrator\"),\n+                        Set(),\n+                        PropertyKeyMap(\n+                          Map(\n+                            Tuple2(\"Group\", Map(Tuple2(\"name\", CTString))),\n+                            Tuple2(\"Administrator\", Map(Tuple2(\"name\", CTFloat)))),\n+                          Set()),\n+                        PropertyKeyMap(Map(), Set()),\n+                        ImpliedLabels(Map()),\n+                        LabelCombinations(Set())\n+                      )\n+                    ),\n+                    Start(\n+                      LogicalExternalGraph(\n+                        \"test\",\n+                        uri,\n+                        Schema(\n+                          Set(\"Group\", \"Administrator\"),\n+                          Set(),\n+                          PropertyKeyMap(\n+                            Map(\n+                              Tuple2(\"Group\", Map(Tuple2(\"name\", CTString))),\n+                              Tuple2(\"Administrator\", Map(Tuple2(\"name\", CTFloat)))),\n+                            Set()),\n+                          PropertyKeyMap(Map(), Set()),\n+                          ImpliedLabels(Map()),\n+                          LabelCombinations(Set())\n+                        )\n+                      ),\n+                      Set(),\n+                      emptySqm\n+                    ),\n+                    emptySqm\n+                  ),\n+                  SolvedQueryModel(Set(nodeA), Set(), Set())\n+                ),\n+                NodeScan(\n+                  Var(\"g\", CTNode),\n+                  Start(\n+                    LogicalExternalGraph(\n+                      \"test\",\n+                      uri,\n+                      Schema(\n+                        Set(\"Group\", \"Administrator\"),\n+                        Set(),\n+                        PropertyKeyMap(\n+                          Map(\n+                            Tuple2(\"Group\", Map(Tuple2(\"name\", CTString))),\n+                            Tuple2(\"Administrator\", Map(Tuple2(\"name\", CTFloat)))),\n+                          Set()),\n+                        PropertyKeyMap(Map(), Set()),\n+                        ImpliedLabels(Map()),\n+                        LabelCombinations(Set())\n+                      )\n+                    ),\n+                    Set(),\n+                    emptySqm\n+                  ),\n+                  SolvedQueryModel(Set(IRField(\"g\", CTNode)), Set(), Set())\n+                ),\n+                SolvedQueryModel(Set(nodeA, IRField(\"g\", CTNode), relR), Set(), Set())\n+              ),\n+              SolvedQueryModel(\n+                Set(nodeA, IRField(\"g\", CTNode), relR),\n+                Set(HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean)))\n+            ),\n+            SolvedQueryModel(\n+              Set(nodeA, IRField(\"g\", CTNode), relR),\n+              Set(\n+                HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+                HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean))\n+            )\n+          ),\n+          SolvedQueryModel(\n+            Set(nodeA, IRField(\"g\", CTNode), relR),\n+            Set(\n+              HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+              HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean))\n+          )\n+        ),\n+        SolvedQueryModel(\n+          Set(nodeA, IRField(\"g\", CTNode), relR),\n+          Set(\n+            HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+            HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean),\n+            Equals(\n+              Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTString),\n+              Param(\"foo\", CTString),\n+              CTBoolean)\n+          )\n+        )\n+      ),\n+      SolvedQueryModel(\n+        Set(nodeA, IRField(\"g\", CTNode), relR, IRField(\"a.name\", CTFloat)),\n+        Set(\n+          HasLabel(Var(\"a\", CTNode), Label(\"Administrator\"), CTBoolean),\n+          HasLabel(Var(\"g\", CTNode), Label(\"Group\"), CTBoolean),\n+          Equals(\n+            Property(Var(\"g\", CTNode(Set(\"Group\"))), PropertyKey(\"name\"), CTString),\n+            Param(\"foo\", CTString),\n+            CTBoolean)\n+        )\n+      )\n     )\n+\n+    result should equalWithoutResult(expected)\n   }\n \n   test(\"plan query with negation\") {\n-    val ir = \"MATCH (a) WHERE NOT $p1 = $p2 RETURN a.prop\".irWithParams(\"p1\" -> CypherInteger(1L), \"p2\" -> CypherBoolean(true))\n-\n-    plan(ir) should equal(\n-      Select(IndexedSeq(Var(\"a.prop\")(CTNull)), Set.empty,\n-        Project(ProjectedField(Var(\"a.prop\")(CTNull), Property(nodeA, PropertyKey(\"prop\"))(CTNull)),\n-          Filter(Not(Equals(Param(\"p1\")(CTInteger), Param(\"p2\")(CTBoolean))(CTBoolean))(CTBoolean),\n-            NodeScan(nodeA,\n-              SetSourceGraph(LogicalExternalGraph(testGraph.name, testGraph.uri, Schema.empty),\n-                Start(LogicalExternalGraph(testGraph.name, testGraph.uri, Schema.empty), Set.empty)(emptySqm)\n-              )(emptySqm)\n-            )(emptySqm)\n-          )(emptySqm)\n-        )(emptySqm)\n-      )(emptySqm)\n+    val ir =\n+      \"MATCH (a) WHERE NOT $p1 = $p2 RETURN a.prop\".irWithParams(\"p1\" -> CypherInteger(1L), \"p2\" -> CypherBoolean(true))\n+\n+    val result = plan(ir)\n+\n+    val expected = Project(\n+      ProjectedField(Var(\"a.prop\", CTNull), Property(Var(\"a\", CTNode), PropertyKey(\"prop\"), CTNull)),\n+      Filter(\n+        Not(Equals(Param(\"p1\", CTInteger), Param(\"p2\", CTBoolean), CTBoolean), CTBoolean),\n+        NodeScan(\n+          Var(\"a\", CTNode),\n+          SetSourceGraph(\n+            LogicalExternalGraph(\"test\", uri, Schema.empty),\n+            Start(LogicalExternalGraph(\"test\", uri, Schema.empty), Set(), emptySqm),\n+            emptySqm),\n+          SolvedQueryModel(Set(nodeA), Set(), Set())\n+        ),\n+        SolvedQueryModel(","path":"caps-core/src/test/scala/org/opencypher/caps/impl/logical/LogicalPlannerTest.scala","position":379,"original_position":412,"commit_id":"63cec3e457640a3102539c36f1632b7e56d63d6d","original_commit_id":"e0f5c594052effe3cd868e03bfbaf2e5ac9fd780","user":{"login":"Mats-SX","id":2419675,"avatar_url":"https://avatars2.githubusercontent.com/u/2419675?v=4","gravatar_id":"","url":"https://api.github.com/users/Mats-SX","html_url":"https://github.com/Mats-SX","followers_url":"https://api.github.com/users/Mats-SX/followers","following_url":"https://api.github.com/users/Mats-SX/following{/other_user}","gists_url":"https://api.github.com/users/Mats-SX/gists{/gist_id}","starred_url":"https://api.github.com/users/Mats-SX/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Mats-SX/subscriptions","organizations_url":"https://api.github.com/users/Mats-SX/orgs","repos_url":"https://api.github.com/users/Mats-SX/repos","events_url":"https://api.github.com/users/Mats-SX/events{/privacy}","received_events_url":"https://api.github.com/users/Mats-SX/received_events","type":"User","site_admin":false},"body":"I suppose we could simplify that by moving it to a `Map[LogicalOperator, SolvedQueryModel]` on `LogicalPlanningContext`.","created_at":"2017-11-20T15:00:45Z","updated_at":"2017-11-20T15:00:45Z","html_url":"https://github.com/opencypher/cypher-for-apache-spark/pull/215#discussion_r152013386","pull_request_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/comments/152013386"},"html":{"href":"https://github.com/opencypher/cypher-for-apache-spark/pull/215#discussion_r152013386"},"pull_request":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215"}},"in_reply_to_id":151939038},"pull_request":{"url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215","id":153322332,"html_url":"https://github.com/opencypher/cypher-for-apache-spark/pull/215","diff_url":"https://github.com/opencypher/cypher-for-apache-spark/pull/215.diff","patch_url":"https://github.com/opencypher/cypher-for-apache-spark/pull/215.patch","issue_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/215","number":215,"state":"open","locked":false,"title":"Migrate to new tree representation","user":{"login":"pstutz","id":254096,"avatar_url":"https://avatars3.githubusercontent.com/u/254096?v=4","gravatar_id":"","url":"https://api.github.com/users/pstutz","html_url":"https://github.com/pstutz","followers_url":"https://api.github.com/users/pstutz/followers","following_url":"https://api.github.com/users/pstutz/following{/other_user}","gists_url":"https://api.github.com/users/pstutz/gists{/gist_id}","starred_url":"https://api.github.com/users/pstutz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pstutz/subscriptions","organizations_url":"https://api.github.com/users/pstutz/orgs","repos_url":"https://api.github.com/users/pstutz/repos","events_url":"https://api.github.com/users/pstutz/events{/privacy}","received_events_url":"https://api.github.com/users/pstutz/received_events","type":"User","site_admin":false},"body":"Sorry, this is quite huge change. We didn't want to merge the new node representation before a review and most other changes build on top of that or would interfere with it.\r\n\r\nMigrates the flat/physical planners to the new tree representation. Builds on https://github.com/opencypher/cypher-for-apache-spark/pull/212\r\n\r\nSummary of changes (including https://github.com/opencypher/cypher-for-apache-spark/pull/212):\r\n- Add Catalyst-style tree node representation\r\n- Migrate physical planner to new node representation\r\n- Implement physical optimiser that places caching operators using the new node representation\r\n- Migrate flat and logical planners to new tree node representation\r\n- Change `Expr` and `IRField` to include their `CypherType` in the first parameter list but still exclude it from `equals`/`hashCode`\r\n- Add `asCode` for convenient test case creation: It turns most of the representations we use into strings that can be used to create an instance of the value. In order to make this work without much extra magic `Expr/IRField.cypherType` was moved to the first argument list.\r\n- Add `equalWithTracing` as a replacement for the ScalaTest matcher, because the normal matcher seems to sometimes crash when matching our trees\r\n- Add Scalafmt config that is used by the Scalafmt IntelliJ plugin and incorporates the feedback from https://github.com/opencypher/cypher-for-apache-spark/pull/204. The formatting rules are not applied to the whole codebase.","created_at":"2017-11-17T15:20:01Z","updated_at":"2017-11-20T15:00:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"873bfdbca8eb7f69fbf53323a2397e781130b399","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215/commits","review_comments_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215/comments","review_comment_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/comments{/number}","comments_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/215/comments","statuses_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/statuses/63cec3e457640a3102539c36f1632b7e56d63d6d","head":{"label":"opencypher:migrate-to-new-tree-representation","ref":"migrate-to-new-tree-representation","sha":"63cec3e457640a3102539c36f1632b7e56d63d6d","user":{"login":"opencypher","id":14857376,"avatar_url":"https://avatars2.githubusercontent.com/u/14857376?v=4","gravatar_id":"","url":"https://api.github.com/users/opencypher","html_url":"https://github.com/opencypher","followers_url":"https://api.github.com/users/opencypher/followers","following_url":"https://api.github.com/users/opencypher/following{/other_user}","gists_url":"https://api.github.com/users/opencypher/gists{/gist_id}","starred_url":"https://api.github.com/users/opencypher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencypher/subscriptions","organizations_url":"https://api.github.com/users/opencypher/orgs","repos_url":"https://api.github.com/users/opencypher/repos","events_url":"https://api.github.com/users/opencypher/events{/privacy}","received_events_url":"https://api.github.com/users/opencypher/received_events","type":"Organization","site_admin":false},"repo":{"id":64759356,"name":"cypher-for-apache-spark","full_name":"opencypher/cypher-for-apache-spark","owner":{"login":"opencypher","id":14857376,"avatar_url":"https://avatars2.githubusercontent.com/u/14857376?v=4","gravatar_id":"","url":"https://api.github.com/users/opencypher","html_url":"https://github.com/opencypher","followers_url":"https://api.github.com/users/opencypher/followers","following_url":"https://api.github.com/users/opencypher/following{/other_user}","gists_url":"https://api.github.com/users/opencypher/gists{/gist_id}","starred_url":"https://api.github.com/users/opencypher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencypher/subscriptions","organizations_url":"https://api.github.com/users/opencypher/orgs","repos_url":"https://api.github.com/users/opencypher/repos","events_url":"https://api.github.com/users/opencypher/events{/privacy}","received_events_url":"https://api.github.com/users/opencypher/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opencypher/cypher-for-apache-spark","description":"Cypher for Apache Spark brings the leading graph query language, Cypher, onto the leading distributed processing platform, Spark.","fork":false,"url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark","forks_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/forks","keys_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/teams","hooks_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/hooks","issue_events_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/events{/number}","events_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/events","assignees_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/assignees{/user}","branches_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/branches{/branch}","tags_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/tags","blobs_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/refs{/sha}","trees_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/statuses/{sha}","languages_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/languages","stargazers_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/stargazers","contributors_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/contributors","subscribers_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/subscribers","subscription_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/subscription","commits_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/commits{/sha}","git_commits_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/commits{/sha}","comments_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/comments{/number}","issue_comment_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/comments{/number}","contents_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/contents/{+path}","compare_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/merges","archive_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/downloads","issues_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues{/number}","pulls_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls{/number}","milestones_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/milestones{/number}","notifications_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/labels{/name}","releases_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/releases{/id}","deployments_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/deployments","created_at":"2016-08-02T13:31:04Z","updated_at":"2017-11-19T03:03:09Z","pushed_at":"2017-11-20T12:55:03Z","git_url":"git://github.com/opencypher/cypher-for-apache-spark.git","ssh_url":"git@github.com:opencypher/cypher-for-apache-spark.git","clone_url":"https://github.com/opencypher/cypher-for-apache-spark.git","svn_url":"https://github.com/opencypher/cypher-for-apache-spark","homepage":"","size":19184,"stargazers_count":36,"watchers_count":36,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":67,"forks":6,"open_issues":67,"watchers":36,"default_branch":"master"}},"base":{"label":"opencypher:master","ref":"master","sha":"edd0b29f088aa90a747c7932328a92aec6065efb","user":{"login":"opencypher","id":14857376,"avatar_url":"https://avatars2.githubusercontent.com/u/14857376?v=4","gravatar_id":"","url":"https://api.github.com/users/opencypher","html_url":"https://github.com/opencypher","followers_url":"https://api.github.com/users/opencypher/followers","following_url":"https://api.github.com/users/opencypher/following{/other_user}","gists_url":"https://api.github.com/users/opencypher/gists{/gist_id}","starred_url":"https://api.github.com/users/opencypher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencypher/subscriptions","organizations_url":"https://api.github.com/users/opencypher/orgs","repos_url":"https://api.github.com/users/opencypher/repos","events_url":"https://api.github.com/users/opencypher/events{/privacy}","received_events_url":"https://api.github.com/users/opencypher/received_events","type":"Organization","site_admin":false},"repo":{"id":64759356,"name":"cypher-for-apache-spark","full_name":"opencypher/cypher-for-apache-spark","owner":{"login":"opencypher","id":14857376,"avatar_url":"https://avatars2.githubusercontent.com/u/14857376?v=4","gravatar_id":"","url":"https://api.github.com/users/opencypher","html_url":"https://github.com/opencypher","followers_url":"https://api.github.com/users/opencypher/followers","following_url":"https://api.github.com/users/opencypher/following{/other_user}","gists_url":"https://api.github.com/users/opencypher/gists{/gist_id}","starred_url":"https://api.github.com/users/opencypher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencypher/subscriptions","organizations_url":"https://api.github.com/users/opencypher/orgs","repos_url":"https://api.github.com/users/opencypher/repos","events_url":"https://api.github.com/users/opencypher/events{/privacy}","received_events_url":"https://api.github.com/users/opencypher/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opencypher/cypher-for-apache-spark","description":"Cypher for Apache Spark brings the leading graph query language, Cypher, onto the leading distributed processing platform, Spark.","fork":false,"url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark","forks_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/forks","keys_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/teams","hooks_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/hooks","issue_events_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/events{/number}","events_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/events","assignees_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/assignees{/user}","branches_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/branches{/branch}","tags_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/tags","blobs_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/refs{/sha}","trees_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/statuses/{sha}","languages_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/languages","stargazers_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/stargazers","contributors_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/contributors","subscribers_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/subscribers","subscription_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/subscription","commits_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/commits{/sha}","git_commits_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/git/commits{/sha}","comments_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/comments{/number}","issue_comment_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/comments{/number}","contents_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/contents/{+path}","compare_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/merges","archive_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/downloads","issues_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues{/number}","pulls_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls{/number}","milestones_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/milestones{/number}","notifications_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/labels{/name}","releases_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/releases{/id}","deployments_url":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/deployments","created_at":"2016-08-02T13:31:04Z","updated_at":"2017-11-19T03:03:09Z","pushed_at":"2017-11-20T12:55:03Z","git_url":"git://github.com/opencypher/cypher-for-apache-spark.git","ssh_url":"git@github.com:opencypher/cypher-for-apache-spark.git","clone_url":"https://github.com/opencypher/cypher-for-apache-spark.git","svn_url":"https://github.com/opencypher/cypher-for-apache-spark","homepage":"","size":19184,"stargazers_count":36,"watchers_count":36,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":67,"forks":6,"open_issues":67,"watchers":36,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215"},"html":{"href":"https://github.com/opencypher/cypher-for-apache-spark/pull/215"},"issue":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/215"},"comments":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/issues/215/comments"},"review_comments":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215/comments"},"review_comment":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/pulls/215/commits"},"statuses":{"href":"https://api.github.com/repos/opencypher/cypher-for-apache-spark/statuses/63cec3e457640a3102539c36f1632b7e56d63d6d"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"Mats-SX"}}