Skip to content

Fix existsTable() ignoring databaseSchema on DBI Postgres connections - #342

Open
DG47 wants to merge 1 commit into
OHDSI:developfrom
DG47:fix/existsTable-dbi-schema
Open

DG47 wants to merge 1 commit into
OHDSI:developfrom
DG47:fix/existsTable-dbi-schema

Conversation

@DG47

@DG47 DG47 commented Oct 8, 2026

Copy link
Copy Markdown

Fixes #327.

Problem

For connections made with createDbiConnectionDetails(), dbListTables(conn, databaseSchema = ...) falls through to DBI::dbListTables(conn@dbiConnection, schema = databaseSchema). RPostgres::dbListTables() does not have a schema argument and silently drops it, so it returns the tables on the search path (usually public) instead of the tables in the requested schema. Because getTableNames() and existsTable() build on this, they give wrong answers:

connectionDetails <- createDbiConnectionDetails(dbms = "postgresql", drv = RPostgres::Postgres(), ...)
connection <- connect(connectionDetails)
existsTable(connection, "results", "achilles_results")
#> [1] FALSE   (TRUE when called on connection@dbiConnection)

It can also return a false positive when a table with the same name exists in public: existsTable(connection, "non_existing_schema", "person") returns TRUE.

Change

dbListTables() for DBI connections already has a branch that queries information_schema.tables for DuckDB. This PR uses that same branch for postgresql and redshift, which is also what getTableNames() already does for a plain PqConnection / RedshiftConnection. Nothing changes for other platforms or for JDBC connections.

Tests

I added a test to tests/testthat/test-getTableNames.R that connects through createDbiConnectionDetails() with RPostgres::Postgres(), using the existing CDM5_POSTGRESQL_* environment variables. It checks that person is listed in the CDM schema, that existsTable() finds it, and that existsTable() returns FALSE for a schema that doesn't exist. The test is skipped when no Postgres test server is configured or RPostgres is not installed.

  • I ran it against a local PostgreSQL 16 container (with the CDM5_POSTGRESQL_* variables pointing at it). Without the fix it fails in both setups: when person is only in the CDM schema, the positive checks fail, and when there is also a public.person, the negative check fails. With the fix it passes in both.
  • testthat::test_local() with only the local SQLite/DuckDB servers: 112 expectations passed, 0 failures. There were 4 errors, and I got the same 4 on unmodified develop. They come from my local setup (no JDBC driver folder, bigrquery not installed).
  • R CMD check --no-manual --ignore-vignettes: 0 errors, 0 warnings, 0 notes.

I did not touch NEWS.md.

RPostgres' dbListTables() silently ignores the schema argument, so
dbListTables(), getTableNames() and existsTable() on a connection made
with createDbiConnectionDetails() listed the tables on the search path
instead of the requested schema. Use the information schema query that
is already used for DuckDB for PostgreSQL and Redshift as well.

Fixes OHDSI#327
@DG47

DG47 commented Oct 13, 2026

Copy link
Copy Markdown
Author

@schuemie requesting review

@DG47

DG47 commented Oct 19, 2026

Copy link
Copy Markdown
Author

Hi, would someone have time to look at this? It fixes #327: on connections from createDbiConnectionDetails() with RPostgres, existsTable() ignores databaseSchema. So it returns FALSE for tables that exist in the schema, and TRUE when a table with the same name is in public. The change reuses the information_schema branch the DuckDB path already has.

This branch has not been deployed

No deployments
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