{"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-625003013", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 625003013, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNTAwMzAxMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-07T03:07:55Z", "updated_at": "2020-05-07T03:09:05Z", "author_association": "OWNER", "body": "Here's another demo I built using this feature: https://observablehq.com/@simonw/datasette-table-diagram\r\n\r\n\"Datasette_foreign_key_diagram___Simon_Willison___Observable\"\r\n\r\nRunning on this query:\r\n\r\n```sql\r\nselect\r\n sqlite_master.name as table_from,\r\n fk_info.[from] as column_from,\r\n fk_info.[table] as table_to,\r\n fk_info.[to] as column_to\r\nfrom\r\n sqlite_master\r\n join pragma_foreign_key_list(sqlite_master.name) as fk_info\r\norder by\r\n sqlite_master.name\r\n```\r\nSee https://github-to-sqlite.dogsheep.net/github?sql=select%0D%0A++sqlite_master.name+as+table_from%2C%0D%0A++fk_info.%5Bfrom%5D+as+column_from%2C%0D%0A++fk_info.%5Btable%5D+as+table_to%2C%0D%0A++fk_info.%5Bto%5D+as+column_to%0D%0Afrom%0D%0A++sqlite_master%0D%0A++join+pragma_foreign_key_list%28sqlite_master.name%29+as+fk_info%0D%0Aorder+by%0D%0A++sqlite_master.name", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624790887", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624790887, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc5MDg4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T17:41:21Z", "updated_at": "2020-05-06T17:41:21Z", "author_association": "OWNER", "body": "More demos here: https://github.com/simonw/til/blob/master/sqlite/list-all-columns-in-a-database.md", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624783996", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624783996, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc4Mzk5Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T17:28:20Z", "updated_at": "2020-05-06T17:28:20Z", "author_association": "OWNER", "body": "Interestingly https://latest.datasette.io/fixtures?sql=select+*+from+pragma_function_list() doesn't work, when it DOES work on my laptop. \r\n\r\n`latest.datasette.io` currently runs SQLite `3.27.2` while my laptop runs `3.31.1`\r\n\r\nhttps://www.sqlite.org/changes.html#version_3_30_0 says that as-of 3.30.0:\r\n> The PRAGMA function_list, PRAGMA module_list, and PRAGMA pragma_list commands are now enabled in all builds by default. Disable them using -DSQLITE_OMIT_INTROSPECTION_PRAGMAS. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624782775", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624782775, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc4Mjc3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T17:26:05Z", "updated_at": "2020-05-06T17:26:05Z", "author_association": "OWNER", "body": "Some demos:\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_database_list%28%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_foreign_key_list%28%27complex_foreign_keys%27%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_function_list%28%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_index_info%28%27idx_compound_three_primary_keys_content%27%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_index_list%28%27compound_three_primary_keys%27%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_index_xinfo%28%27idx_compound_three_primary_keys_content%27%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_page_count%28%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_max_page_count%28%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_page_size%28%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_schema_version%28%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_table_info%28%27complex_foreign_keys%27%29\r\n* https://latest.datasette.io/fixtures?sql=select+*+from+pragma_table_xinfo%28%27complex_foreign_keys%27%29", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624774928", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624774928, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc3NDkyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T17:11:15Z", "updated_at": "2020-05-06T17:11:15Z", "author_association": "OWNER", "body": "For the moment I'll allow-list the following:\r\n* `pragma_database_list`\r\n* `pragma_foreign_key_list`\r\n* `pragma_function_list`\r\n* `pragma_index_info`\r\n* `pragma_index_list`\r\n* `pragma_index_xinfo`\r\n* `pragma_page_count`\r\n* `pragma_max_page_count`\r\n* `pragma_page_size`\r\n* `pragma_schema_version`\r\n* `pragma_table_info`\r\n* `pragma_table_xinfo`\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624766424", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624766424, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc2NjQyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T16:54:38Z", "updated_at": "2020-05-06T17:01:02Z", "author_association": "OWNER", "body": "I could allow-list some other useful `pragma_x` tables too.\r\n\r\nSQLite calls these \"pragma functions\" - documented here: https://www.sqlite.org/pragma.html#pragfunc\r\n\r\nThey sound safe:\r\n\r\n> Table-valued functions exist only for PRAGMAs that return results and that have no side-effects. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624768744", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624768744, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc2ODc0NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T16:59:01Z", "updated_at": "2020-05-06T16:59:01Z", "author_association": "OWNER", "body": "Maybe use a negative lookahead assertion? https://docs.python.org/3/library/re.html#index-20\r\n\r\n> `(?!...)`\r\n> \r\n> Matches if `...` doesn\u2019t match next. This is a negative lookahead assertion. For example, `Isaac (?!Asimov)` will match 'Isaac ' only if it\u2019s not followed by 'Asimov'.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/761#issuecomment-624767466", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/761", "id": 624767466, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNDc2NzQ2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-06T16:56:40Z", "updated_at": "2020-05-06T16:57:03Z", "author_association": "OWNER", "body": "The rationale for blocking `pragma` entirely from statements is that it can be used to change the state of the SQLite database, e.g. from https://www.sqlite.org/pragma.html :\r\n\r\n```\r\nPRAGMA schema.application_id;\r\nPRAGMA schema.application_id = integer ;\r\n```\r\nThat second line is unsafe. I don't think it's possible to use the `pragma_table_x` variants to make writes in this way.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 613467382, "label": "Allow-list pragma_table_info(tablename) and similar"}, "performed_via_github_app": null}