-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Postgres OID resolution query does not take into account current search_path
#2133
Postgres OID resolution query does not take into account current search_path
#2133
Conversation
@95ulisse current development is on the |
7d2b3e7
to
4d9d138
Compare
@abonander I've just rebased my PR on top of |
4d9d138
to
758b3b0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize it was this simple to get a type's OID, this is probably the way we should have been doing it from the start.
We do have a method already to clear the prepared statement cache, I suppose maybe that should also clear the type mapping cache because it's likely going to be called when major changes are being made anyway.
I've modified |
…rch_path` (#2133) * Fix oid resolution query * Address review comments
…rch_path` (#2133) * Fix oid resolution query * Address review comments
…rch_path` (launchbadge#2133) * Fix oid resolution query * Address review comments
Problem
The current strategy employed to resolve a user-defined type name to an OID does not take into account the current
search_path
. This might cause some issues if we have different types with the same name in different schemas.I noticed this behaviour because I'm working on a project that uses Postgres schemas to isolate integration tests by creating a new schema for each one, which means that I have a lot of types with the same name in different schemas.
As an example, if we open a new connection and set the
search_path
totest123
,INSERT
s referencing the enumstatus
start failing:The root of the error lies in the resolution of the type name
status
to OID thatsqlx
does when encoding the parameters for theINSERT
, because thestatus
name has been unexpectedly resolved to thepublic.status
enum, and not to thetest123.status
enum.The query used to resolve the name involves a
SELECT
from the tablepg_catalog.pg_type
, which is not namespaced, and thus, if we have multiple types with the same name, it will select one of them at random (even if in my tests, thepublic
schema always was first, but I have no idea whether this is granted or not).Proposed solution
Postgres has a native syntax to resolve type names to OIDs, which is
'some_type':regtype::oid
, which correctly takes into account the currentsearch_path
. This PR proposes changing the current query with:In order to respect the
search_path
of the current connection.Drawbacks
The first drawback I can think of is caching. Connections cache the
type name => oid
mappings for obvious performance reasons, and this change would make the cached mappings invalid if thesearch_path
changes after a type has been resolved.We could decide to expose methods on the connections to manually clear the type cache (like we have right now for statements), but I'm not exactly sure it is worth it.
Also, please note that I have no idea whether this is a breaking change or not. I ran all the Postgres tests locally and they were green.