Internal __pgsqlite_* bookkeeping tables leak into client sqlite_master queries
Version: 0.0.22 (reproduced on 0.0.19 as well)
Summary
pgsqlite stores its own bookkeeping in tables named __pgsqlite_*
(__pgsqlite_schema, __pgsqlite_migrations, __pgsqlite_enum_types,
__pgsqlite_string_constraints, __pgsqlite_numeric_constraints,
__pgsqlite_datetime_cache, etc.). The catalog queries pgsqlite synthesizes
itself already hide these, e.g. src/catalog/pg_class.rs:
db.query("SELECT name FROM sqlite_master WHERE type='table' \
AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__pgsqlite_%'")
But a sqlite_master (or its sqlite_schema alias) query written directly by
a client is passed through verbatim, so any tool that lists the native SQLite
catalog sees pgsqlite's internal tables mixed in with the user's own.
Reproduce
pgsqlite --database /tmp/t.sqlite --port 5599 &
psql "host=127.0.0.1 port=5599 user=postgres dbname=main gssencmode=disable" \
-c "CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT);"
psql "host=127.0.0.1 port=5599 user=postgres dbname=main gssencmode=disable" \
-tA -c "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"
Observed output includes pgsqlite's internal tables:
__pgsqlite_array_types
__pgsqlite_datetime_cache
__pgsqlite_enum_types
__pgsqlite_migrations
__pgsqlite_schema
__pgsqlite_string_constraints
...
customers
Expected
A client sqlite_master / sqlite_schema query should not expose pgsqlite's
internal __pgsqlite_* bookkeeping tables, consistent with the filtering that
pgsqlite's own synthesized catalog queries already apply.
Proposed fix
Intercept client sqlite_master / sqlite_schema SELECTs and AND
name NOT LIKE '__pgsqlite_%' into the WHERE clause before execution, failing
open (running the query unchanged) whenever it cannot be parsed as a single
SELECT over a real sqlite_master relation. A PR implementing this is attached.
Related observation (out of scope for the attached PR)
Separately from the __pgsqlite_* tables, pgsqlite materializes its
pg_catalog / information_schema emulation as real SQLite tables named
pg_class, pg_type, pg_attribute, information_schema_tables,
information_schema_columns, ... (plus supporting idx_* /
sqlite_autoindex_* entries). These also appear in a client sqlite_master
listing and are the same relations that surface through
information_schema.tables. Filtering those is a broader policy decision (a
user could in principle name a table pg_*), so the attached PR deliberately
scopes itself to the unambiguous __pgsqlite_* prefix only. Flagging it here
for visibility.
Internal
__pgsqlite_*bookkeeping tables leak into clientsqlite_masterqueriesVersion: 0.0.22 (reproduced on 0.0.19 as well)
Summary
pgsqlite stores its own bookkeeping in tables named
__pgsqlite_*(
__pgsqlite_schema,__pgsqlite_migrations,__pgsqlite_enum_types,__pgsqlite_string_constraints,__pgsqlite_numeric_constraints,__pgsqlite_datetime_cache, etc.). The catalog queries pgsqlite synthesizesitself already hide these, e.g.
src/catalog/pg_class.rs:But a
sqlite_master(or itssqlite_schemaalias) query written directly bya client is passed through verbatim, so any tool that lists the native SQLite
catalog sees pgsqlite's internal tables mixed in with the user's own.
Reproduce
Observed output includes pgsqlite's internal tables:
Expected
A client
sqlite_master/sqlite_schemaquery should not expose pgsqlite'sinternal
__pgsqlite_*bookkeeping tables, consistent with the filtering thatpgsqlite's own synthesized catalog queries already apply.
Proposed fix
Intercept client
sqlite_master/sqlite_schemaSELECTs and ANDname NOT LIKE '__pgsqlite_%'into the WHERE clause before execution, failingopen (running the query unchanged) whenever it cannot be parsed as a single
SELECT over a real
sqlite_masterrelation. A PR implementing this is attached.Related observation (out of scope for the attached PR)
Separately from the
__pgsqlite_*tables, pgsqlite materializes itspg_catalog/information_schemaemulation as real SQLite tables namedpg_class,pg_type,pg_attribute,information_schema_tables,information_schema_columns, ... (plus supportingidx_*/sqlite_autoindex_*entries). These also appear in a clientsqlite_masterlisting and are the same relations that surface through
information_schema.tables. Filtering those is a broader policy decision (auser could in principle name a table
pg_*), so the attached PR deliberatelyscopes itself to the unambiguous
__pgsqlite_*prefix only. Flagging it herefor visibility.