Skip to content

Commit

Permalink
Add configuration to skip querying of comp_oids (#663)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeregrine authored Nov 2, 2023
1 parent c8edce4 commit ab4265e
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 18 deletions.
3 changes: 3 additions & 0 deletions lib/postgrex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ defmodule Postgrex do
See the [PostgreSQL docs](https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH)
for more details.
* `:disable_composite_types` - Set to `true` to disable composite types support.
This is useful when using Postgrex against systems that do not support composite types
(default: `false`).
`Postgrex` uses the `DBConnection` library and supports all `DBConnection`
options like `:idle`, `:after_connect` etc. See `DBConnection.start_link/2`
Expand Down
15 changes: 9 additions & 6 deletions lib/postgrex/protocol.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ defmodule Postgrex.Protocol do
transactions: :strict,
buffer: nil,
disconnect_on_error_codes: [],
scram: nil
scram: nil,
disable_composite_types: false

@type state :: %__MODULE__{
sock: {module, any},
Expand Down Expand Up @@ -80,6 +81,7 @@ defmodule Postgrex.Protocol do
types_mod = Keyword.fetch!(opts, :types)
disconnect_on_error_codes = opts[:disconnect_on_error_codes] || []
target_server_type = opts[:target_server_type] || :any
disable_composite_types = opts[:disable_composite_types] || false

transactions =
case opts[:transactions] || :naive do
Expand All @@ -98,7 +100,8 @@ defmodule Postgrex.Protocol do
ping_timeout: ping_timeout,
postgres: :idle,
transactions: transactions,
disconnect_on_error_codes: disconnect_on_error_codes
disconnect_on_error_codes: disconnect_on_error_codes,
disable_composite_types: disable_composite_types
}

connect_timeout = Keyword.get(opts, :connect_timeout, timeout)
Expand Down Expand Up @@ -1029,10 +1032,10 @@ defmodule Postgrex.Protocol do
end
end

defp bootstrap_send(%{types: types} = s, status, buffer) do
defp bootstrap_send(s, status, buffer) do
%{parameters: parameters} = s
version = Postgrex.Utils.parse_version(parameters["server_version"])
statement = Types.bootstrap_query(version, types)
statement = Types.bootstrap_query(version, s)

if statement do
bootstrap_send(s, status, statement, buffer)
Expand Down Expand Up @@ -1867,12 +1870,12 @@ defmodule Postgrex.Protocol do
end
end

defp reload(%{types: types} = s, status, oids, acc, buffer) do
defp reload(s, status, oids, acc, buffer) do
%{parameters: parameters} = s

with {:ok, parameters} <- Postgrex.Parameters.fetch(parameters) do
version = Postgrex.Utils.parse_version(parameters["server_version"])
statement = Types.reload_query(version, Enum.to_list(oids), types)
statement = Types.reload_query(version, Enum.to_list(oids), s)

if statement do
reload_send(s, status, statement, acc, buffer)
Expand Down
31 changes: 20 additions & 11 deletions lib/postgrex/types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ defmodule Postgrex.Types do

@doc false
@spec bootstrap_query({pos_integer, non_neg_integer, non_neg_integer}, state) :: binary | nil
def bootstrap_query(version, {_, table}) do
def bootstrap_query(version, %{types: {_, table}} = s) do
case :ets.info(table, :size) do
0 ->
# avoid loading information about table-types
Expand All @@ -56,14 +56,14 @@ defmodule Postgrex.Types do
AND (t.typelem = 0 OR NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type s WHERE s.typrelid != 0 AND s.oid = t.typelem))
"""

build_bootstrap_query(version, filter_oids)
build_bootstrap_query(version, filter_oids, s)

_ ->
nil
end
end

defp build_bootstrap_query(version, filter_oids) do
defp build_bootstrap_query(version, filter_oids, s) do
{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"}
Expand All @@ -85,14 +85,23 @@ defmodule Postgrex.Types do
{"0", ""}
end

comp_oids =
if s.disable_composite_types do
"null"
else
"""
ARRAY (
SELECT a.atttypid
FROM pg_attribute AS a
WHERE a.attrelid = t.typrelid AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
)
"""
end

"""
SELECT t.oid, t.typname, t.typsend, t.typreceive, t.typoutput, t.typinput,
#{typelem}, #{rngsubtype}, ARRAY (
SELECT a.atttypid
FROM pg_attribute AS a
WHERE a.attrelid = t.typrelid AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
)
#{typelem}, #{rngsubtype}, #{comp_oids}
FROM pg_type AS t
#{join_domain}
#{join_range}
Expand All @@ -103,13 +112,13 @@ defmodule Postgrex.Types do
@doc false
@spec reload_query({pos_integer, non_neg_integer, non_neg_integer}, [oid, ...], state) ::
binary | nil
def reload_query(version, oids, {_, table}) do
def reload_query(version, oids, %{types: {_, table}} = s) do
case Enum.reject(oids, &:ets.member(table, &1)) do
[] ->
nil

oids ->
build_bootstrap_query(version, "WHERE t.oid IN (#{Enum.join(oids, ", ")})")
build_bootstrap_query(version, "WHERE t.oid IN (#{Enum.join(oids, ", ")})", s)
end
end

Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"table": {:hex, :table, "0.1.0", "f16104d717f960a623afb134a91339d40d8e11e0c96cfce54fee086b333e43f0", [:mix], [], "hexpm", "bf533d3606823ad8a7ee16f41941e5e6e0e42a20c4504cdf4cfabaaed1c8acb9"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
}

0 comments on commit ab4265e

Please sign in to comment.