Skip to content

Fix composite type loading when record_send is duplicated.#770

Merged
josevalim merged 1 commit into
elixir-ecto:masterfrom
leandrocp:lp-fix-ambiguous-type-loading
Jun 17, 2026
Merged

Fix composite type loading when record_send is duplicated.#770
josevalim merged 1 commit into
elixir-ecto:masterfrom
leandrocp:lp-fix-ambiguous-type-loading

Conversation

@leandrocp

Copy link
Copy Markdown
Contributor

The type-loading query does return qualified names when they are duplicated, for example when a user-defined record_send is present:

CREATE TYPE my_composite AS (a int, b text);
CREATE FUNCTION public.record_send(integer) RETURNS bytea LANGUAGE sql AS $$ SELECT ''::bytea $$;
Postgrex.query(conn, "SELECT $1::my_composite[]", [[]])
{:error, %Postgrex.QueryError{message: "type `_my_composite` can not be handled by the types module Postgrex.DefaultTypes"}}

This naive fix strips out the pg_catalog. prefix to keep only the bare name as expected by Postgrex.

--

For context, this was reported by a customer of Supabase Realtime and I tried the smallest fix possible to not cause too many changes and not cause any performance impact.

The type-loading query does return qualified names when they are duplicated,
for example when a user-defined `record_send` is present:

    CREATE TYPE my_composite AS (a int, b text);
    CREATE FUNCTION public.record_send(integer) RETURNS bytea LANGUAGE sql AS $$ SELECT ''::bytea $$;
    Postgrex.query(conn, "SELECT $1::my_composite[]", [[]])
    {:error, %Postgrex.QueryError{message: "type `_my_composite` can not be handled by the types module Postgrex.DefaultTypes"}}

This naive fix strips out the `pg_catalog.` prefix to keep only the bare name as expected by Postgrex.
@josevalim josevalim merged commit f79090d into elixir-ecto:master Jun 17, 2026
13 checks passed
@josevalim

Copy link
Copy Markdown
Member

💚 💙 💜 💛 ❤️

@leandrocp leandrocp deleted the lp-fix-ambiguous-type-loading branch June 17, 2026 20:52
@greg-rychlewski

Copy link
Copy Markdown
Member

This is a pretty cool issue. I’m going to show it to my team as an example of “whatever can happen will happen”

@leandrocp

Copy link
Copy Markdown
Contributor Author

This is a pretty cool issue. I’m going to show it to my team as an example of “whatever can happen will happen”

I mean... it kinda makes sense, but duplicating a record_send function might not be very usual 😃

postgres> select t.oid, t.typsend from pg_type as t where t.typname = 'record';
+------+-------------+
| oid  | typsend     |
|------+-------------|
| 2249 | record_send |
+------+-------------+
SELECT 1

postgres> CREATE FUNCTION public.record_send(integer) RETURNS bytea LANGUAGE sql AS $$ SELECT ''::bytea $$;
CREATE FUNCTION

postgres> select t.oid, t.typsend from pg_type as t where t.typname = 'record';
+------+------------------------+
| oid  | typsend                |
|------+------------------------|
| 2249 | pg_catalog.record_send |
+------+------------------------+
SELECT 1

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.

3 participants