Skip to content

Fix domain over composite arrays#772

Open
greg-rychlewski wants to merge 2 commits into
elixir-ecto:masterfrom
greg-rychlewski:fix_domain
Open

Fix domain over composite arrays#772
greg-rychlewski wants to merge 2 commits into
elixir-ecto:masterfrom
greg-rychlewski:fix_domain

Conversation

@greg-rychlewski

@greg-rychlewski greg-rychlewski commented Jun 20, 2026

Copy link
Copy Markdown
Member

There was another gap in the way we were handling domains. This one is kind of weird but I'll do my best to paint a clear picture. This fix is for when the domain has a base type that is an array of a composite type. For example this

CREATE TYPE composite_test AS (a text, b integer);
CREATE DOMAIN composite_array_domain AS composite_test[] CHECK (array_length(VALUE, 1) > 0);

When you try to encode a parameter for this you get the error "Postgrex has no clue how to encode this because we don't know the right extension" (see here). So why does this happen:

  1. In the first bootstrap query we filter composites and arrays of composites out for efficiency (see here)
  2. Our domain type does get bootstrapped as an array type (send = array_send) and its element type is the composite type that was not bootstrapped.
  3. When we encode the parameter we go to fetch the type info and we see it's an array and then we say ok so what type is in the array and find a composite that has not been bootstrapped. So it errors and says Postgrex doesn't know what to do with this.

Then you might ask how are composites/arrays of composites working. And basically they get reloaded the first time they are found missing. So the fix here is to basically do the same thing: take domains with a base composite array type out of the original bootstrap so they can be reloaded.

The reason this isn't working right now is because it's only if the "top" type is missing that we reload. If a sub type is missing it just raises. And in our case we bootstrapped the top type (domain) but not the subtype (composite array)

@greg-rychlewski

greg-rychlewski commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

I think if we want to do this 100% properly we need to reload sub-types. But that is a pretty big change. We're only handling one level of domain nesting...i.e. you can define a new domain over an old domain. But that is consistent with how we were dealing with domain over arrays here for a long time:

{typelem, join_domain} =
      if version >= {9, 0, 0} do
        {"coalesce(d.typelem, t.typelem)", "LEFT JOIN pg_type AS d ON t.typbasetype = d.oid"}

@greg-rychlewski

Copy link
Copy Markdown
Member Author

I think if we want to do this 100% properly we need to reload sub-types.

Or instead of this if we had some kind of way to know if we are looking at a domain defined over a domain and trace the pointers to the end of the road.

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