Skip to content

information_schema.tables lists pgsqlite's materialized pg_* and information_schema_* relations #88

Description

@erans

Found while investigating #80 on v0.0.22. Flagged as out of scope there, since #80/#85 deliberately limited themselves to __pgsqlite_*.

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 table_name FROM information_schema.tables ORDER BY 1;"

Observed

27 internal relations listed alongside customers:

  • 4 real tables: pg_attrdef, pg_constraint, pg_depend, pg_index
  • 23 views: pg_class, pg_type, pg_attribute, pg_namespace, pg_proc, pg_roles, pg_user, pg_am, pg_enum, pg_database, pg_description, pg_foreign_data_wrapper, the pg_stat_* family, and information_schema_tables / _columns / _key_column_usage / _table_constraints / _referential_constraints / _schemata

Expected

Only user tables. In real PostgreSQL these live in the pg_catalog and information_schema schemas, which information_schema.tables reports under table_schema, not as user relations in the default schema.

Cause

The handler at src/catalog/query_interceptor.rs:2059-2061 filters sqlite_% and __pgsqlite_% but not the materialized catalog relations:

"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__pgsqlite_%'"

The sibling handler for information_schema.columns (:2335) does add AND name NOT LIKE 'pg_%', so the two are inconsistent.

Why it needs a decision, not just a filter

A blanket name NOT LIKE 'pg_%' would also hide a user's own table named e.g. pg_myreport. The robust fix is an exact-name denylist built from the migration registry (the relations pgsqlite itself creates) rather than a prefix wildcard — which is the approach #85 took for __pgsqlite_*, using substr(name, 1, 11) <> '__pgsqlite_' precisely because LIKE '__pgsqlite_%' matches unrelated names (_ is a LIKE wildcard).

Likely affects ORM introspection: Django inspectdb and SQLAlchemy automap would generate models for pg_constraint and friends.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions