Skip to content

fix(plugin-postgresql): gate version-dependent system catalogs (#1240)#1241

Merged
datlechin merged 1 commit into
mainfrom
fix/postgres-old-version-pg-matviews
May 13, 2026
Merged

fix(plugin-postgresql): gate version-dependent system catalogs (#1240)#1241
datlechin merged 1 commit into
mainfrom
fix/postgres-old-version-pg-matviews

Conversation

@datlechin
Copy link
Copy Markdown
Member

Summary

Issue #1240: TablePro 0.40.2 fails to connect to old PostgreSQL servers with ERROR: relation "pg_matviews" does not exist. This PR introduces a PostgreSQLCapabilities model derived from PQserverVersion and routes every version-dependent SQL site through it.

Audit (the immediate bug was the tip of the iceberg)

# Hot/Cold Feature Min PG Site
1 HOT (connect) pg_matviews 9.3 fetchTables
2 HOT (connect) pg_foreign_table 9.1 fetchTables
3 HOT (open table) attidentity 10 fetchColumns / fetchAllColumns / fetchTableDDL
4 HOT (open table) attgenerated 12 same
5 WARM (indexes) array_position() 9.5 fetchIndexes
6 WARM (DDL) pg_sequences 9.5 fetchDependentSequences
7 COLD (create DB) datlocprovider / daticulocale / datlocale 15 / 15 / 17 fetchTemplate1Defaults, createDatabaseFormSpec, createDatabase

Only #1 and #2 were caught by the original report — the rest were latent regressions that would have surfaced as soon as the PG < 10 user clicked on a table.

Changes

New Plugins/PostgreSQLDriverPlugin/PostgreSQLCapabilities.swift — single source of truth, each flag documents its minimum PG version inline:

struct PostgreSQLCapabilities: Sendable, Equatable {
    let serverVersion: Int32
    var hasMaterializedViewsCatalog: Bool { serverVersion >= 90_300 }
    var hasForeignTablesCatalog: Bool { serverVersion >= 90_100 }
    var hasSequencesCatalog: Bool { serverVersion >= 90_500 }
    var hasIdentityColumns: Bool { serverVersion >= 100_000 }
    var hasGeneratedColumns: Bool { serverVersion >= 120_000 }
    var hasArrayPosition: Bool { serverVersion >= 90_500 }
    var hasOrderedAggregates: Bool { serverVersion >= 90_000 }
    var hasCollationProvider: Bool { serverVersion >= 100_000 }
    var hasDatabaseICULocale: Bool { serverVersion >= 150_000 }
    var hasDatabaseLocale: Bool { serverVersion >= 170_000 }
}

LibPQPluginConnection.swift — caches the numeric value from PQserverVersion(connection) alongside the existing display string; new serverVersionNumber() -> Int32 accessor.

PostgreSQLPluginDriver.swift — adds var capabilities computed from the connection; rewrites:

  • fetchTables UNION pieces are appended only when the catalog exists.
  • fetchIndexes uses ORDER BY array_position(...) only when supported, falls back to ORDER BY a.attnum (deterministic ordering, may not match index logical order on PG <9.5).
  • fetchTableDDL builds the identity / generated CASE clauses conditionally; the atthasdef guard adapts.
  • fetchDependentSequences short-circuits when pg_sequences is unavailable (DDL still generates, just without sequence details).
  • fetchTemplate1Defaults, createDatabaseFormSpec, and the CREATE DATABASE builder now consult capabilities.hasDatabaseICULocale / hasDatabaseLocale instead of the local ad-hoc parsedServerMajorVersion() (now deleted).

PostgreSQLPluginDriver+Columns.swiftfetchColumns and fetchAllColumns substitute NULL::text for attidentity / attgenerated projections when the columns don't exist, so the row shape stays stable and mapPgColumnRow needs no change.

What stays unchanged

  • The pg_collation.collprovider (PG 10+) call in fetchCollations() is wrapped in do/catch that returns empty arrays, so PG <10 still falls back cleanly. Left as-is to keep the diff focused.
  • Redshift driver is untouched.

Test plan

  • Connect to PG ≥ 13: schema, columns, indexes, DDL, create database all work as before (no behavioral change).
  • Connect to PG 9.6: schema/columns/indexes work; tables with identity/generated columns missing those markers in DDL (correct — PG 9.6 doesn't have them).
  • Connect to PG 9.2: schema loads (no matviews / no foreign tables UNION); column / index queries succeed.
  • Connect to PG 9.0: same; pg_sequences-dependent sequence details omitted from DDL.
  • Create Database dialog: PG ≥ 15 shows libc/icu provider picker, < 15 shows only libc.

Notes

Bundled plugin — ships in the next app release. No registry republish per feedback_no_registry_for_builtins.

@datlechin datlechin merged commit 9f14077 into main May 13, 2026
2 checks passed
@datlechin datlechin deleted the fix/postgres-old-version-pg-matviews branch May 13, 2026 01:52
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 this pull request may close these issues.

1 participant