{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-898063815", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 898063815, "node_id": "IC_kwDOBm6k_c41h13H", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-13T00:33:17Z", "updated_at": "2021-08-13T00:33:17Z", "author_association": "OWNER", "body": "Improved version of that function:\r\n```python\r\ndef columns_for_query(conn, sql):\r\n \"\"\"\r\n Given a SQLite connection ``conn`` and a SQL query ``sql``,\r\n returns a list of ``(table_name, column_name)`` pairs, one\r\n per returned column. ``(None, None)`` if no table and column\r\n could be derived.\r\n \"\"\"\r\n rows = conn.execute('explain ' + sql).fetchall()\r\n table_rootpage_by_register = {r['p1']: r['p2'] for r in rows if r['opcode'] == 'OpenRead'}\r\n names_by_rootpage = dict(\r\n conn.execute(\r\n 'select rootpage, name from sqlite_master where rootpage in ({})'.format(\r\n ', '.join(map(str, table_rootpage_by_register.values()))\r\n )\r\n )\r\n )\r\n columns_by_column_register = {}\r\n for row in rows:\r\n if row['opcode'] in ('Rowid', 'Column'):\r\n addr, opcode, table_id, cid, column_register, p4, p5, comment = row\r\n table = names_by_rootpage[table_rootpage_by_register[table_id]]\r\n columns_by_column_register[column_register] = (table, cid)\r\n result_row = [dict(r) for r in rows if r['opcode'] == 'ResultRow'][0]\r\n registers = list(range(result_row[\"p1\"], result_row[\"p1\"] + result_row[\"p2\"]))\r\n all_column_names = {}\r\n for table in names_by_rootpage.values():\r\n table_xinfo = conn.execute('pragma table_xinfo({})'.format(table)).fetchall()\r\n for row in table_xinfo:\r\n all_column_names[(table, row[\"cid\"])] = row[\"name\"]\r\n final_output = []\r\n for r in registers:\r\n try:\r\n table, cid = columns_by_column_register[r]\r\n final_output.append((table, all_column_names[table, cid]))\r\n except KeyError:\r\n final_output.append((None, None))\r\n return final_output\r\n```\r\nIt works!\r\n\r\n\r\n\r\n```diff\r\ndiff --git a/datasette/templates/query.html b/datasette/templates/query.html\r\nindex 75f7f1b..9fe1d4f 100644\r\n--- a/datasette/templates/query.html\r\n+++ b/datasette/templates/query.html\r\n@@ -67,6 +67,8 @@\r\n
\r\n \r\n \r\n+extra_column_info: {{ extra_column_info }}\r\n+\r\n {% if display_rows %}\r\nThis data as {% for name, url in renderers.items() %}{{ name }}{{ \", \" if not loop.last }}{% endfor %}, CSV
\r\n