{"action":"created","comment":{"url":"https://api.github.com/repos/prestodb/presto/pulls/comments/172655515","pull_request_review_id":101710860,"id":172655515,"diff_hunk":"@@ -0,0 +1,193 @@\n+/*\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+package com.facebook.presto.operator;\n+\n+import com.esri.core.geometry.ogc.OGCGeometry;\n+import com.facebook.presto.Session;\n+import com.facebook.presto.geospatial.GeometryUtils;\n+import com.facebook.presto.spi.Page;\n+import com.facebook.presto.spi.PageBuilder;\n+import com.facebook.presto.spi.block.Block;\n+import com.facebook.presto.spi.type.Type;\n+import com.facebook.presto.sql.gen.JoinFilterFunctionCompiler.JoinFilterFunctionFactory;\n+import io.airlift.slice.Slice;\n+import it.unimi.dsi.fastutil.longs.LongArrayList;\n+import org.locationtech.jts.geom.Envelope;\n+import org.locationtech.jts.index.strtree.AbstractNode;\n+import org.locationtech.jts.index.strtree.ItemBoundable;\n+import org.locationtech.jts.index.strtree.STRtree;\n+import org.openjdk.jol.info.ClassLayout;\n+\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.function.BiPredicate;\n+\n+import static com.facebook.presto.geospatial.GeometryUtils.deserialize;\n+import static com.facebook.presto.operator.SyntheticAddress.decodePosition;\n+import static com.facebook.presto.operator.SyntheticAddress.decodeSliceIndex;\n+import static io.airlift.slice.SizeOf.sizeOf;\n+import static java.lang.Math.toIntExact;\n+import static java.util.Objects.requireNonNull;\n+\n+public class PagesRTreeIndex\n+        implements PagesSpatialIndex\n+{\n+    private static final int INSTANCE_SIZE = ClassLayout.parseClass(PagesRTreeIndex.class).instanceSize();\n+    private static final int ENVELOPE_INSTANCE_SIZE = ClassLayout.parseClass(Envelope.class).instanceSize();\n+    private static final int STRTREE_INSTANCE_SIZE = ClassLayout.parseClass(STRtree.class).instanceSize();\n+    private static final int ABSTRACT_NODE_INSTANCE_SIZE = ClassLayout.parseClass(AbstractNode.class).instanceSize();\n+    private static final long[] EMPTY_ADDRESSES = new long[0];\n+\n+    private final List<Type> types;\n+    private final List<Integer> outputChannels;\n+    private final List<List<Block>> channels;\n+    private final STRtree rtree;\n+    private final BiPredicate<OGCGeometry, OGCGeometry> spatialRelationshipTest;\n+    private final JoinFilterFunction filterFunction;\n+    private final long memorySizeInBytes;\n+\n+    public static final class GeometryWithAddress\n+    {\n+        private static final int INSTANCE_SIZE = ClassLayout.parseClass(GeometryWithAddress.class).instanceSize();\n+        private final OGCGeometry ogcGeometry;\n+        private final long address;\n+\n+        public GeometryWithAddress(OGCGeometry ogcGeometry, long address)\n+        {\n+            this.ogcGeometry = ogcGeometry;\n+            this.address = address;\n+        }\n+\n+        public OGCGeometry getOgcGeometry()\n+        {\n+            return ogcGeometry;\n+        }\n+\n+        public long getAddress()\n+        {\n+            return address;\n+        }\n+\n+        public long getEstimatedMemorySizeInBytes()\n+        {\n+            return INSTANCE_SIZE + GeometryUtils.getEstimatedMemorySizeInBytes(ogcGeometry);\n+        }\n+    }\n+\n+    public PagesRTreeIndex(\n+            Session session,\n+            LongArrayList addresses,\n+            List<Type> types,\n+            List<Integer> outputChannels,\n+            List<List<Block>> channels,\n+            STRtree rtree,\n+            BiPredicate<OGCGeometry, OGCGeometry> spatialRelationshipTest,\n+            Optional<JoinFilterFunctionFactory> filterFunctionFactory)\n+    {\n+        this.types = types;\n+        this.outputChannels = outputChannels;\n+        this.channels = requireNonNull(channels, \"channels is null\");\n+        this.rtree = requireNonNull(rtree, \"rtree is null\");\n+        this.spatialRelationshipTest = requireNonNull(spatialRelationshipTest, \"spatial relationship is null\");\n+        this.filterFunction = filterFunctionFactory.map(factory -> factory.create(session.toConnectorSession(), addresses, channels)).orElse(null);\n+        this.memorySizeInBytes = computeMemorySizeInBytes(addresses);\n+    }\n+\n+    private static Envelope getEnvelope(OGCGeometry ogcGeometry)\n+    {\n+        com.esri.core.geometry.Envelope env = new com.esri.core.geometry.Envelope();\n+        ogcGeometry.getEsriGeometry().queryEnvelope(env);\n+\n+        return new Envelope(env.getXMin(), env.getXMax(), env.getYMin(), env.getYMax());\n+    }\n+\n+    private long computeMemorySizeInBytes(LongArrayList addresses)\n+    {\n+        return INSTANCE_SIZE + STRTREE_INSTANCE_SIZE + computeMemorySizeInBytes(rtree.getRoot()) +\n+                sizeOf(addresses.elements()) + channels.stream()\n+                    .flatMap(List::stream)\n+                    .mapToLong(Block::getRetainedSizeInBytes)","path":"presto-main/src/main/java/com/facebook/presto/operator/PagesRTreeIndex.java","position":null,"original_position":120,"commit_id":"41257af475bf48049c013eab33049bd19666f8c2","original_commit_id":"4b8c12465f8f85c0bd9c808e369e2214eeb564df","user":{"login":"mbasmanova","id":27965151,"avatar_url":"https://avatars3.githubusercontent.com/u/27965151?v=4","gravatar_id":"","url":"https://api.github.com/users/mbasmanova","html_url":"https://github.com/mbasmanova","followers_url":"https://api.github.com/users/mbasmanova/followers","following_url":"https://api.github.com/users/mbasmanova/following{/other_user}","gists_url":"https://api.github.com/users/mbasmanova/gists{/gist_id}","starred_url":"https://api.github.com/users/mbasmanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbasmanova/subscriptions","organizations_url":"https://api.github.com/users/mbasmanova/orgs","repos_url":"https://api.github.com/users/mbasmanova/repos","events_url":"https://api.github.com/users/mbasmanova/events{/privacy}","received_events_url":"https://api.github.com/users/mbasmanova/received_events","type":"User","site_admin":false},"body":"@findepi @dain This calculation matches `SimplePagesHashStrategy#getSizeInBytes`. Should I update both places? ","created_at":"2018-03-06T20:51:34Z","updated_at":"2018-03-06T20:51:35Z","html_url":"https://github.com/prestodb/presto/pull/9474#discussion_r172655515","pull_request_url":"https://api.github.com/repos/prestodb/presto/pulls/9474","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/prestodb/presto/pulls/comments/172655515"},"html":{"href":"https://github.com/prestodb/presto/pull/9474#discussion_r172655515"},"pull_request":{"href":"https://api.github.com/repos/prestodb/presto/pulls/9474"}},"in_reply_to_id":172398632},"pull_request":{"url":"https://api.github.com/repos/prestodb/presto/pulls/9474","id":156341016,"html_url":"https://github.com/prestodb/presto/pull/9474","diff_url":"https://github.com/prestodb/presto/pull/9474.diff","patch_url":"https://github.com/prestodb/presto/pull/9474.patch","issue_url":"https://api.github.com/repos/prestodb/presto/issues/9474","number":9474,"state":"open","locked":false,"title":"Broadcast spatial join","user":{"login":"mbasmanova","id":27965151,"avatar_url":"https://avatars3.githubusercontent.com/u/27965151?v=4","gravatar_id":"","url":"https://api.github.com/users/mbasmanova","html_url":"https://github.com/mbasmanova","followers_url":"https://api.github.com/users/mbasmanova/followers","following_url":"https://api.github.com/users/mbasmanova/following{/other_user}","gists_url":"https://api.github.com/users/mbasmanova/gists{/gist_id}","starred_url":"https://api.github.com/users/mbasmanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbasmanova/subscriptions","organizations_url":"https://api.github.com/users/mbasmanova/orgs","repos_url":"https://api.github.com/users/mbasmanova/repos","events_url":"https://api.github.com/users/mbasmanova/events{/privacy}","received_events_url":"https://api.github.com/users/mbasmanova/received_events","type":"User","site_admin":false},"body":"Implements broadcast spatial join using an R-Tree as described in #9890.\r\n\r\nSupports spatial joins defined using ST_Contains and ST_Intersects functions.\r\n\r\nThe implementation consists of an optimizer rule and two custom operators. The new rule replaces a cross join node with a spatial filter on top into a spatial join node which is executed using new operators. SpatialIndexBuilderOperator builds an R-Tree from build side geometries. SpatialLookupJoinOperator processes probe geometries one record at a time looking up matching geometries in the R-Tree.\r\n\r\nFor example, the plan for the following query\r\n\r\n```\r\nwith \r\n    points as (select * from (values ('a', 1, 2)) as t(name, lat, lng)),\r\n    polygons as (select * from (values ('p1', 'POLYGON ...')) as t(name, wkt))\r\nselect count(1)\r\nfrom points, polygons\r\nwhere ST_Contains(ST_GeometryFromText(wkt), ST_Point(lat, lng))\r\n```\r\n\r\nchanges from \r\n\r\n```\r\n- FilterProject[filterPredicate = \"st_contains\"(\"st_geometryfromtext\"(CAST(\"field_23\" AS varchar)), \"st_point\"(CAST(\"field_0\" AS double), CAST(\"field_1\" AS double)))] => []\r\n    - CrossJoin => [field_0:integer, field_1:integer, field_23:varchar(11)]\r\n```\r\n\r\nto \r\n\r\n```\r\n - SpatialJoin[\"st_contains\"(\"st_geometryfromtext\", \"st_point\")] => []                     \r\n     - Project[] => [field_0:integer, field_1:integer, st_point:Geometry]                  \r\n             st_point := \"st_point\"(CAST(\"field_0\" AS double), CAST(\"field_1\" AS double))  \r\n     - Project[] => [field_23:varchar(11), st_geometryfromtext:Geometry]               \r\n             st_geometryfromtext := \"st_geometryfromtext\"(CAST(\"field_23\" AS varchar)) \r\n```\r\n\r\n<img width=\"858\" alt=\"screen shot 2018-02-28 at 9 30 36 am\" src=\"https://user-images.githubusercontent.com/27965151/36798305-3d544802-1c78-11e8-9526-7d1c73cffff6.png\">\r\n\r\nTests for the new functionality include:\r\n\r\n- unit test for the new rule: TestTransformSpatialPredicateToJoin\r\n- test for the query planner with the new rule: TestSpatialJoinPlanning\r\n- unit test for the new SpatialJoinOperator: TestSpatialJoinOperator\r\n- end-to-end test for the spatial join queries: TestSpatialJoins\r\n\r\nKnown limitations and future work:\r\n\r\n1. The new optimizer rule and the new operators are defined in presto-main, although, logically, they belong to the presto-geospatial plugin. In the future, when plugin interface evolves to support custom rules and operators, the new rule and operators can be moved.\r\n\r\n1. The logic of computing memory size of a geometry object requires access to package private classes from the ESRI library. To gain access, presto-geospatial-toolkit includes a class in com.esri.core.geometry package. This split-package situation will block migration to Java 9 modules and needs to be addressed at some point. https://github.com/Esri/geometry-api-java/issues/156\r\n\r\n1. The R-Tree implementation in the JTS library is not GC-friendly as it creates a tree of Java objects. This implementation needs to be replaced.\r\n\r\n1. Querying an R-Tree in SpatialJoinLookupOperator is an atomic operation that doesn't support yielding.\r\n\r\n1. TODO: Consider using dictionary style blocks for probe columns (see LookupJoinPageBuilder)\r\n\r\n1. Only INNER JOIN is supported. \r\n\r\nAddressing items 2-4 will require changes to external libraries (ESRI and JTS).","created_at":"2017-12-05T00:15:48Z","updated_at":"2018-03-06T20:51:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8bf6808e22cf0a50df92e4789b2fba2108aa4f38","assignee":null,"assignees":[],"requested_reviewers":[{"login":"sopel39","id":5989165,"avatar_url":"https://avatars1.githubusercontent.com/u/5989165?v=4","gravatar_id":"","url":"https://api.github.com/users/sopel39","html_url":"https://github.com/sopel39","followers_url":"https://api.github.com/users/sopel39/followers","following_url":"https://api.github.com/users/sopel39/following{/other_user}","gists_url":"https://api.github.com/users/sopel39/gists{/gist_id}","starred_url":"https://api.github.com/users/sopel39/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sopel39/subscriptions","organizations_url":"https://api.github.com/users/sopel39/orgs","repos_url":"https://api.github.com/users/sopel39/repos","events_url":"https://api.github.com/users/sopel39/events{/privacy}","received_events_url":"https://api.github.com/users/sopel39/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":196992743,"url":"https://api.github.com/repos/prestodb/presto/labels/CLA%20Signed","name":"CLA Signed","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/prestodb/presto/pulls/9474/commits","review_comments_url":"https://api.github.com/repos/prestodb/presto/pulls/9474/comments","review_comment_url":"https://api.github.com/repos/prestodb/presto/pulls/comments{/number}","comments_url":"https://api.github.com/repos/prestodb/presto/issues/9474/comments","statuses_url":"https://api.github.com/repos/prestodb/presto/statuses/41257af475bf48049c013eab33049bd19666f8c2","head":{"label":"mbasmanova:spatial-broadcast-join","ref":"spatial-broadcast-join","sha":"41257af475bf48049c013eab33049bd19666f8c2","user":{"login":"mbasmanova","id":27965151,"avatar_url":"https://avatars3.githubusercontent.com/u/27965151?v=4","gravatar_id":"","url":"https://api.github.com/users/mbasmanova","html_url":"https://github.com/mbasmanova","followers_url":"https://api.github.com/users/mbasmanova/followers","following_url":"https://api.github.com/users/mbasmanova/following{/other_user}","gists_url":"https://api.github.com/users/mbasmanova/gists{/gist_id}","starred_url":"https://api.github.com/users/mbasmanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbasmanova/subscriptions","organizations_url":"https://api.github.com/users/mbasmanova/orgs","repos_url":"https://api.github.com/users/mbasmanova/repos","events_url":"https://api.github.com/users/mbasmanova/events{/privacy}","received_events_url":"https://api.github.com/users/mbasmanova/received_events","type":"User","site_admin":false},"repo":{"id":100315926,"name":"presto","full_name":"mbasmanova/presto","owner":{"login":"mbasmanova","id":27965151,"avatar_url":"https://avatars3.githubusercontent.com/u/27965151?v=4","gravatar_id":"","url":"https://api.github.com/users/mbasmanova","html_url":"https://github.com/mbasmanova","followers_url":"https://api.github.com/users/mbasmanova/followers","following_url":"https://api.github.com/users/mbasmanova/following{/other_user}","gists_url":"https://api.github.com/users/mbasmanova/gists{/gist_id}","starred_url":"https://api.github.com/users/mbasmanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbasmanova/subscriptions","organizations_url":"https://api.github.com/users/mbasmanova/orgs","repos_url":"https://api.github.com/users/mbasmanova/repos","events_url":"https://api.github.com/users/mbasmanova/events{/privacy}","received_events_url":"https://api.github.com/users/mbasmanova/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mbasmanova/presto","description":"Distributed SQL query engine for big data","fork":true,"url":"https://api.github.com/repos/mbasmanova/presto","forks_url":"https://api.github.com/repos/mbasmanova/presto/forks","keys_url":"https://api.github.com/repos/mbasmanova/presto/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mbasmanova/presto/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mbasmanova/presto/teams","hooks_url":"https://api.github.com/repos/mbasmanova/presto/hooks","issue_events_url":"https://api.github.com/repos/mbasmanova/presto/issues/events{/number}","events_url":"https://api.github.com/repos/mbasmanova/presto/events","assignees_url":"https://api.github.com/repos/mbasmanova/presto/assignees{/user}","branches_url":"https://api.github.com/repos/mbasmanova/presto/branches{/branch}","tags_url":"https://api.github.com/repos/mbasmanova/presto/tags","blobs_url":"https://api.github.com/repos/mbasmanova/presto/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mbasmanova/presto/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mbasmanova/presto/git/refs{/sha}","trees_url":"https://api.github.com/repos/mbasmanova/presto/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mbasmanova/presto/statuses/{sha}","languages_url":"https://api.github.com/repos/mbasmanova/presto/languages","stargazers_url":"https://api.github.com/repos/mbasmanova/presto/stargazers","contributors_url":"https://api.github.com/repos/mbasmanova/presto/contributors","subscribers_url":"https://api.github.com/repos/mbasmanova/presto/subscribers","subscription_url":"https://api.github.com/repos/mbasmanova/presto/subscription","commits_url":"https://api.github.com/repos/mbasmanova/presto/commits{/sha}","git_commits_url":"https://api.github.com/repos/mbasmanova/presto/git/commits{/sha}","comments_url":"https://api.github.com/repos/mbasmanova/presto/comments{/number}","issue_comment_url":"https://api.github.com/repos/mbasmanova/presto/issues/comments{/number}","contents_url":"https://api.github.com/repos/mbasmanova/presto/contents/{+path}","compare_url":"https://api.github.com/repos/mbasmanova/presto/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mbasmanova/presto/merges","archive_url":"https://api.github.com/repos/mbasmanova/presto/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mbasmanova/presto/downloads","issues_url":"https://api.github.com/repos/mbasmanova/presto/issues{/number}","pulls_url":"https://api.github.com/repos/mbasmanova/presto/pulls{/number}","milestones_url":"https://api.github.com/repos/mbasmanova/presto/milestones{/number}","notifications_url":"https://api.github.com/repos/mbasmanova/presto/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mbasmanova/presto/labels{/name}","releases_url":"https://api.github.com/repos/mbasmanova/presto/releases{/id}","deployments_url":"https://api.github.com/repos/mbasmanova/presto/deployments","created_at":"2017-08-14T22:58:12Z","updated_at":"2017-08-14T22:58:31Z","pushed_at":"2018-03-06T20:37:40Z","git_url":"git://github.com/mbasmanova/presto.git","ssh_url":"git@github.com:mbasmanova/presto.git","clone_url":"https://github.com/mbasmanova/presto.git","svn_url":"https://github.com/mbasmanova/presto","homepage":"https://prestodb.io","size":88086,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"prestodb:master","ref":"master","sha":"0127d8be5c16dbce9e35c2ed339dbf723a3b96c5","user":{"login":"prestodb","id":6882181,"avatar_url":"https://avatars0.githubusercontent.com/u/6882181?v=4","gravatar_id":"","url":"https://api.github.com/users/prestodb","html_url":"https://github.com/prestodb","followers_url":"https://api.github.com/users/prestodb/followers","following_url":"https://api.github.com/users/prestodb/following{/other_user}","gists_url":"https://api.github.com/users/prestodb/gists{/gist_id}","starred_url":"https://api.github.com/users/prestodb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/prestodb/subscriptions","organizations_url":"https://api.github.com/users/prestodb/orgs","repos_url":"https://api.github.com/users/prestodb/repos","events_url":"https://api.github.com/users/prestodb/events{/privacy}","received_events_url":"https://api.github.com/users/prestodb/received_events","type":"Organization","site_admin":false},"repo":{"id":5349565,"name":"presto","full_name":"prestodb/presto","owner":{"login":"prestodb","id":6882181,"avatar_url":"https://avatars0.githubusercontent.com/u/6882181?v=4","gravatar_id":"","url":"https://api.github.com/users/prestodb","html_url":"https://github.com/prestodb","followers_url":"https://api.github.com/users/prestodb/followers","following_url":"https://api.github.com/users/prestodb/following{/other_user}","gists_url":"https://api.github.com/users/prestodb/gists{/gist_id}","starred_url":"https://api.github.com/users/prestodb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/prestodb/subscriptions","organizations_url":"https://api.github.com/users/prestodb/orgs","repos_url":"https://api.github.com/users/prestodb/repos","events_url":"https://api.github.com/users/prestodb/events{/privacy}","received_events_url":"https://api.github.com/users/prestodb/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/prestodb/presto","description":"Distributed SQL query engine for big data","fork":false,"url":"https://api.github.com/repos/prestodb/presto","forks_url":"https://api.github.com/repos/prestodb/presto/forks","keys_url":"https://api.github.com/repos/prestodb/presto/keys{/key_id}","collaborators_url":"https://api.github.com/repos/prestodb/presto/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/prestodb/presto/teams","hooks_url":"https://api.github.com/repos/prestodb/presto/hooks","issue_events_url":"https://api.github.com/repos/prestodb/presto/issues/events{/number}","events_url":"https://api.github.com/repos/prestodb/presto/events","assignees_url":"https://api.github.com/repos/prestodb/presto/assignees{/user}","branches_url":"https://api.github.com/repos/prestodb/presto/branches{/branch}","tags_url":"https://api.github.com/repos/prestodb/presto/tags","blobs_url":"https://api.github.com/repos/prestodb/presto/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/prestodb/presto/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/prestodb/presto/git/refs{/sha}","trees_url":"https://api.github.com/repos/prestodb/presto/git/trees{/sha}","statuses_url":"https://api.github.com/repos/prestodb/presto/statuses/{sha}","languages_url":"https://api.github.com/repos/prestodb/presto/languages","stargazers_url":"https://api.github.com/repos/prestodb/presto/stargazers","contributors_url":"https://api.github.com/repos/prestodb/presto/contributors","subscribers_url":"https://api.github.com/repos/prestodb/presto/subscribers","subscription_url":"https://api.github.com/repos/prestodb/presto/subscription","commits_url":"https://api.github.com/repos/prestodb/presto/commits{/sha}","git_commits_url":"https://api.github.com/repos/prestodb/presto/git/commits{/sha}","comments_url":"https://api.github.com/repos/prestodb/presto/comments{/number}","issue_comment_url":"https://api.github.com/repos/prestodb/presto/issues/comments{/number}","contents_url":"https://api.github.com/repos/prestodb/presto/contents/{+path}","compare_url":"https://api.github.com/repos/prestodb/presto/compare/{base}...{head}","merges_url":"https://api.github.com/repos/prestodb/presto/merges","archive_url":"https://api.github.com/repos/prestodb/presto/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/prestodb/presto/downloads","issues_url":"https://api.github.com/repos/prestodb/presto/issues{/number}","pulls_url":"https://api.github.com/repos/prestodb/presto/pulls{/number}","milestones_url":"https://api.github.com/repos/prestodb/presto/milestones{/number}","notifications_url":"https://api.github.com/repos/prestodb/presto/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/prestodb/presto/labels{/name}","releases_url":"https://api.github.com/repos/prestodb/presto/releases{/id}","deployments_url":"https://api.github.com/repos/prestodb/presto/deployments","created_at":"2012-08-09T01:03:37Z","updated_at":"2018-03-06T15:11:09Z","pushed_at":"2018-03-06T20:37:43Z","git_url":"git://github.com/prestodb/presto.git","ssh_url":"git@github.com:prestodb/presto.git","clone_url":"https://github.com/prestodb/presto.git","svn_url":"https://github.com/prestodb/presto","homepage":"https://prestodb.io","size":88068,"stargazers_count":7180,"watchers_count":7180,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2399,"mirror_url":null,"archived":false,"open_issues_count":1213,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":2399,"open_issues":1213,"watchers":7180,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/prestodb/presto/pulls/9474"},"html":{"href":"https://github.com/prestodb/presto/pull/9474"},"issue":{"href":"https://api.github.com/repos/prestodb/presto/issues/9474"},"comments":{"href":"https://api.github.com/repos/prestodb/presto/issues/9474/comments"},"review_comments":{"href":"https://api.github.com/repos/prestodb/presto/pulls/9474/comments"},"review_comment":{"href":"https://api.github.com/repos/prestodb/presto/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/prestodb/presto/pulls/9474/commits"},"statuses":{"href":"https://api.github.com/repos/prestodb/presto/statuses/41257af475bf48049c013eab33049bd19666f8c2"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"mbasmanova"}}