{"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-376981291", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 376981291, "node_id": "MDEyOklzc3VlQ29tbWVudDM3Njk4MTI5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T18:06:08Z", "updated_at": "2018-03-28T18:06:08Z", "author_association": "OWNER", "body": "Given how unlikely it is that this will pose a real problem I think I like option 1: enable sort-by-column by default for all tables, then allow power users to instead switch to explicit enabling of the functionality in their `metadata.json` if they know their data is too big.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-376983741", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 376983741, "node_id": "MDEyOklzc3VlQ29tbWVudDM3Njk4Mzc0MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T18:12:35Z", "updated_at": "2018-03-28T18:12:35Z", "author_association": "OWNER", "body": "I think this can work with a `?_sort=xxx` parameter - and `?_sort=-xxx` to sort in the opposite direction.\r\n\r\nI'd like to support \"sort by X descending, then by Y ascending if there are dupes for X\" as well. Two ways that could work:\r\n\r\n`?_sort=-xxx,yyy`\r\n\r\nOr...\r\n\r\n`?_sort=-xxx&_sort=yyy`\r\n\r\nThe second option is probably better in that it makes it easier for columns to have a comma in their name.\r\n\r\nIs it possible for a SQLite column to start with a `-` character?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-376986668", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 376986668, "node_id": "MDEyOklzc3VlQ29tbWVudDM3Njk4NjY2OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T18:21:53Z", "updated_at": "2018-03-28T18:21:53Z", "author_association": "OWNER", "body": "Might have to do something special to get sort-by-nulls-last: https://stackoverflow.com/questions/12503120/how-to-do-nulls-last-in-sqlite\r\n\r\n order by ifnull(column_name, -999999)\r\n\r\nWould need to figure out a smart way to get the default value - maybe by running a min() or max() against the column first?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-377049625", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 377049625, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA0OTYyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T21:52:05Z", "updated_at": "2018-03-28T21:52:05Z", "author_association": "OWNER", "body": "This is a better pattern as you don't have to pick a minimum value:\r\n\r\n ORDER BY CASE WHEN SOMECOL IS NULL THEN 1 ELSE 0 END, SOMECOL", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-377050461", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 377050461, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA1MDQ2MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T21:55:14Z", "updated_at": "2018-03-28T22:06:30Z", "author_association": "OWNER", "body": "I think there are actually four kinds of sort order we need to support;\r\n\r\n* ascending\r\n* descending\r\n* ascending, nulls last\r\n* descending, nulls last\r\n\r\nIt looks like [-blah] is a valid SQLite table name, so mark I descending with a hyphen prefix isn't good.\r\n\r\nInstead, maybe this:\r\n\r\n ?_sort_asc=col1&_sort_desc_nulls_last=col2\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-377051018", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 377051018, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA1MTAxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T21:57:20Z", "updated_at": "2018-03-28T22:00:17Z", "author_association": "OWNER", "body": "I'd like to continue to support _next=token pagination even for custom sort orders.\r\n\r\nTo do that I should include rowid (or general primary key) as the tie breaker on all sorts so I can incorporate that it into the _next= token.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-377052634", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 377052634, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA1MjYzNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T22:03:16Z", "updated_at": "2018-03-28T22:03:16Z", "author_association": "OWNER", "body": "In terms of user interface: the obvious place to put this is as a drop down menu on the column headers.\r\n\r\nThis also means the UI can support combined sort orders. Assuming you are already sorted by county descending and you select the candidate column header, the options could be:\r\n\r\n* sort all by candidate\r\n* sort all by candidate, descending\r\n* sort by county descending, then by candidate\r\n* sort by county descending, then by candidate descending", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-377054358", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 377054358, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA1NDM1OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T22:09:25Z", "updated_at": "2018-03-28T22:09:25Z", "author_association": "OWNER", "body": "I'm tempted to put these verbose sorting options inline in the page HTML but have them in the table footer so they don't clog up the top half of the page with uninteresting links - then use JavaScript to hoik them out into a dropdown menu attached to each column header.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/189#issuecomment-377055663", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/189", "id": 377055663, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA1NTY2Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T22:14:53Z", "updated_at": "2018-03-28T22:14:53Z", "author_association": "OWNER", "body": "There is one other interesting option for auto-enabling/disabling sort: the inspect command could include data about column index presence and whether or not a column has any null values in it.\r\n\r\nThis would allow us to dynamically include a \"nulls last\" option but only for columns that contain at least one null.\r\n\r\nIt's quite a lot of additional engineering for a very minor feature though, so I think I'll punt on that for the moment.\r\n\r\nWe may find that the _group_count feature can benefit from column value statistics later on though.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309471814, "label": "Ability to sort (and paginate) by column"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/190#issuecomment-377065541", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/190", "id": 377065541, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA2NTU0MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T22:58:52Z", "updated_at": "2018-03-28T22:58:52Z", "author_association": "OWNER", "body": "This is because the SQL we are using here is:\r\n\r\n select * from compound_primary_key where \"pk1\" > \"d\" and \"pk2\" > \"v\" order by pk1, pk2 limit 101\r\n\r\nThis is incorrect. The correct SQL syntax (according to the example on https://www.sqlite.org/rowvalue.html#scrolling_window_queries ) is:\r\n\r\n select * from compound_primary_key where (\"pk1\", \"pk2\") > (\"d\", \"v\") order by pk1, pk2 limit 101\r\n\r\nBUT... this uses \"row values\" syntax which was only added to SQLite in version 3.15.0 in October 2016: https://sqlite.org/changes.html#version_3_15_0\r\n\r\nThe version on https://datasette-issue-190-compound-pks.now.sh/compound-pks-9aafe8f?sql=select+sqlite_version%28%29%3B is 3.8.7.1 from October 2014.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309558826, "label": "Keyset pagination doesn't work correctly for compound primary keys"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/190#issuecomment-377066466", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/190", "id": 377066466, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA2NjQ2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T23:03:45Z", "updated_at": "2018-03-28T23:03:57Z", "author_association": "OWNER", "body": "Without row values syntax, the necessary SQL to retrieve the next page after `d, v` gets a bit gnarly:\r\n\r\n select * from compound_primary_key\r\n where pk1 >= \"d\" and not (pk1 = \"d\" and pk2 <= \"v\")\r\n order by pk1, pk2\r\n\r\nSee https://datasette-issue-190-compound-pks.now.sh/compound-pks-9aafe8f?sql=select+*+from+compound_primary_key+where+pk1+%3E%3D+%22d%22+and+not+%28pk1+%3D+%22d%22+and+pk2+%3C%3D+%22v%22%29+order+by+pk1%2C+pk2\r\n\r\nThis article was useful for figuring this out: https://use-the-index-luke.com/sql/partial-results/fetch-next-page", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309558826, "label": "Keyset pagination doesn't work correctly for compound primary keys"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/190#issuecomment-377067541", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/190", "id": 377067541, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA2NzU0MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T23:09:18Z", "updated_at": "2018-03-28T23:09:51Z", "author_association": "OWNER", "body": "Here's how I generated the table for testing this with 3 compound primary keys:\r\n\r\n CREATE_SQL = '''\r\n CREATE TABLE compound_three_primary_keys (\r\n pk1 varchar(30),\r\n pk2 varchar(30),\r\n pk3 varchar(30),\r\n content text,\r\n PRIMARY KEY (pk1, pk2, pk3)\r\n );'''\r\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\r\n for a in alphabet:\r\n for b in alphabet:\r\n for c in alphabet:\r\n print('''\r\n INSERT INTO compound_three_primary_keys VALUES ('{}', '{}', '{}', '{}');\r\n '''.strip().format(a, b, c, '{}-{}-{}-{}-{}-{}'.format(a,b,c,a,b,c)))\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309558826, "label": "Keyset pagination doesn't work correctly for compound primary keys"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/190#issuecomment-377072022", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/190", "id": 377072022, "node_id": "MDEyOklzc3VlQ29tbWVudDM3NzA3MjAyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-03-28T23:32:24Z", "updated_at": "2018-03-28T23:32:24Z", "author_association": "OWNER", "body": "Here's the SQL for a next page with three compound primary keys:\r\n\r\nhttps://datasette-issue-190-compound-pks.now.sh/compound-pks-8e99805?sql=select+*+from+compound_three_primary_keys%0D%0Awhere%0D%0A++%28pk1+%3E+%3Apk1%29%0D%0A++++or%0D%0A++%28pk1+%3D+%3Apk1+and+pk2+%3E+%3Apk2%29%0D%0A++++or%0D%0A++%28pk1+%3D+%3Apk1+and+pk2+%3D+%3Apk2+and+pk3+%3E+%3Apk3%29%0D%0Aorder+by+pk1%2C+pk2%2C+pk3%3B%0D%0A%0D%0A%0D%0A&pk1=a&pk2=d&pk3=v\r\n\r\n```\r\nselect * from compound_three_primary_keys\r\nwhere\r\n (pk1 > :pk1)\r\n or\r\n (pk1 = :pk1 and pk2 > :pk2)\r\n or\r\n (pk1 = :pk1 and pk2 = :pk2 and pk3 > :pk3)\r\norder by pk1, pk2, pk3;\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 309558826, "label": "Keyset pagination doesn't work correctly for compound primary keys"}, "performed_via_github_app": null}