Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically hide type=shadow tables in SQLite 3.37 or higher #2296

Closed
simonw opened this issue Mar 7, 2024 · 2 comments · Fixed by #2391
Closed

Automatically hide type=shadow tables in SQLite 3.37 or higher #2296

simonw opened this issue Mar 7, 2024 · 2 comments · Fixed by #2391
Assignees

Comments

@simonw
Copy link
Owner

simonw commented Mar 7, 2024

For filtering virtual table's "shadow tables" (ex the FTS5 _content and most the spatialite tables), you can use pragma_table_list (first appeared in SQLite 3.37 (2021-11-27), which has a type column that calls out type="shadow" tables https://www.sqlite.org/pragma.html#pragma_table_list

Originally posted by @asg017 in #2104 (comment)

@simonw
Copy link
Owner Author

simonw commented Mar 7, 2024

The code for this can go here:

async def hidden_table_names(self):
# Mark tables 'hidden' if they relate to FTS virtual tables
hidden_tables = [
r[0]
for r in (
await self.execute(
"""
select name from sqlite_master
where rootpage = 0
and (
sql like '%VIRTUAL TABLE%USING FTS%'
) or name in ('sqlite_stat1', 'sqlite_stat2', 'sqlite_stat3', 'sqlite_stat4')
or name like '\\_%' escape '\\'
"""
)
).rows
]
has_spatialite = await self.execute_fn(detect_spatialite)
if has_spatialite:
# Also hide Spatialite internal tables
hidden_tables += [
"ElementaryGeometries",
"SpatialIndex",
"geometry_columns",
"spatial_ref_sys",
"spatialite_history",
"sql_statements_log",
"sqlite_sequence",
"views_geometry_columns",
"virts_geometry_columns",
"data_licenses",
"KNN",
"KNN2",
] + [
r[0]
for r in (
await self.execute(
"""
select name from sqlite_master
where name like "idx_%"
and type = "table"
"""
)
).rows
]
# Add any tables marked as hidden in config
db_config = self.ds.config.get("databases", {}).get(self.name, {})
if "tables" in db_config:
hidden_tables += [
t for t in db_config["tables"] if db_config["tables"][t].get("hidden")
]
# Also mark as hidden any tables which start with the name of a hidden table
# e.g. "searchable_fts" implies "searchable_fts_content" should be hidden
for table_name in await self.table_names():
for hidden_table in hidden_tables[:]:
if table_name.startswith(hidden_table):
hidden_tables.append(table_name)
continue
return hidden_tables

It will need to gracefully handle that missing pragma.

@asg017 asg017 self-assigned this Aug 13, 2024
@simonw
Copy link
Owner Author

simonw commented Aug 13, 2024

We're going to change something here too: we're going to NOT hide FTS virtual tables (or indeed any other virtual table) by default any more.

Reason is that FTS tables are actually OK to browse, e.g. https://datasette.io/content/repos_fts

And some SQLite FTS tables don't correspond to a content table, so should be visible anyway.

@simonw simonw closed this as completed in 6d91d08 Aug 15, 2024
@simonw simonw mentioned this issue Aug 15, 2024
3 tasks
simonw added a commit that referenced this issue Aug 16, 2024
simonw added a commit that referenced this issue Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants