vapor / fluent-postgres-driver

🐘 PostgreSQL driver for Fluent.
MIT License
149 stars 53 forks source link

refresh table names after migration #114

Closed tanner0101 closed 4 years ago

tanner0101 commented 5 years ago

This fixes the failing test case added in https://github.com/vapor/fluent-postgresql/pull/111 by refreshing the Postgres connection's table name cache before querying.

Postgres returns column values with two pieces of identifying information:

To convert between table name (String) and table OID, a query to the DB must be made:

SELECT oid, relname FROM pg_class

Fluent PostgreSQL does this for each new connection when it is first created. The table names are then cached so that they can be accessed synchronously. Synchronous access is required since Codable encoder/decoders must be synchronous.

Because table names are cached when the connection is created, it's possible that a connection's cache may become outdated. Especially if db schema is modified after that connection was created.

If a table name cache is outdated, Fluent will fallback to picking columns based on first match. This means that ambiguous columns will be picked at random. To fix this, call tableNames(refresh: true) on the connection after modifying the schema, so that all table names can be looked up correctly.

This shouldn't be a problem for most Vapor applications since a separate connection pool is used during the migration process, and that process happens before the application boots.

Additionally, this will no longer be a problem in the next major version. Fluent 4 uses column aliases instead of relying on table OID for disambiguation, so there is no need for a table name cache there. Unfortunately that's a breaking change, and can't be backported.