From a5e5e15b5373b62d319e94de4d388ecea1d68ffc Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Sun, 2 Feb 2025 07:27:53 -0500 Subject: [PATCH 1/2] we could already support search path --- lib/postgrex/protocol.ex | 84 +++++++++------------------------------- 1 file changed, 18 insertions(+), 66 deletions(-) diff --git a/lib/postgrex/protocol.ex b/lib/postgrex/protocol.ex index 7ff12f02..97ba3e3c 100644 --- a/lib/postgrex/protocol.ex +++ b/lib/postgrex/protocol.ex @@ -85,6 +85,7 @@ defmodule Postgrex.Protocol do 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 + parameters = opts[:parameters] || [] {ssl_opts, opts} = case Keyword.pop(opts, :ssl, false) do @@ -116,6 +117,20 @@ defmodule Postgrex.Protocol do :unnamed -> :unnamed end + parameters = + case opts[:search_path] do + path when is_list(path) -> + path = Enum.intersperse(path, ", ") + Keyword.put(parameters, :search_path, path) + + nil -> + parameters + + other -> + raise ArgumentError, + "expected :search_path to be a list of strings, got: #{inspect(other)}" + end + s = %__MODULE__{ timeout: timeout, ping_timeout: ping_timeout, @@ -128,15 +143,14 @@ defmodule Postgrex.Protocol do connect_timeout = Keyword.get(opts, :connect_timeout, timeout) status = %{ - opts: opts, + opts: Keyword.put(opts, :parameters, parameters), types_mod: types_mod, types_key: nil, types_lock: nil, prepare: prepare, messages: [], ssl: ssl_opts, - target_server_type: target_server_type, - search_path: opts[:search_path] + target_server_type: target_server_type } connect_endpoints(endpoints, sock_opts ++ @sock_opts, connect_timeout, s, status, []) @@ -916,7 +930,7 @@ defmodule Postgrex.Protocol do init_recv(%{s | connection_id: pid, connection_key: key}, status, buffer) {:ok, msg_ready(), buffer} -> - set_search_path(s, status, buffer) + check_target_server_type(s, status, buffer) {:ok, msg_error(fields: fields), buffer} -> disconnect(s, Postgrex.Error.exception(postgres: fields), buffer) @@ -930,68 +944,6 @@ defmodule Postgrex.Protocol do end end - ## set search path on connection startup - - defp set_search_path(s, %{search_path: nil} = status, buffer), - do: set_search_path_done(s, status, buffer) - - defp set_search_path(s, %{search_path: search_path} = status, buffer) - when is_list(search_path), - do: set_search_path_send(s, status, buffer) - - defp set_search_path(_, %{search_path: search_path}, _) do - raise ArgumentError, - "expected :search_path to be a list of strings, got: #{inspect(search_path)}" - end - - defp set_search_path_send(s, status, buffer) do - search_path = Enum.intersperse(status.search_path, ",") - msg = msg_query(statement: ["set search_path to " | search_path]) - - case msg_send(s, msg, buffer) do - :ok -> - set_search_path_recv(s, status, buffer) - - {:disconnect, _, _} = dis -> - dis - end - end - - defp set_search_path_recv(s, status, buffer) do - case msg_recv(s, :infinity, buffer) do - {:ok, msg_row_desc(fields: fields), buffer} -> - {[@text_type_oid], ["search_path"], _} = columns(fields) - set_search_path_recv(s, status, buffer) - - {:ok, msg_data_row(), buffer} -> - set_search_path_recv(s, status, buffer) - - {:ok, msg_command_complete(), buffer} -> - set_search_path_recv(s, status, buffer) - - {:ok, msg_ready(status: :idle), buffer} -> - set_search_path_done(s, status, buffer) - - {:ok, msg_ready(status: postgres), _buffer} -> - err = %Postgrex.Error{message: "unexpected postgres status: #{postgres}"} - {:disconnect, err, s} - - {:ok, msg_error(fields: fields), buffer} -> - err = Postgrex.Error.exception(postgres: fields) - {:disconnect, err, %{s | buffer: buffer}} - - {:ok, msg, buffer} -> - s = handle_msg(s, status, msg) - set_search_path_recv(s, status, buffer) - - {:disconnect, _, _} = dis -> - dis - end - end - - defp set_search_path_done(s, status, buffer), - do: check_target_server_type(s, status, buffer) - ## check_target_server_type defp check_target_server_type(s, %{target_server_type: :any} = status, buffer), From 3199aac7def231882a691285f51e74c29d45fb11 Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Sun, 2 Feb 2025 08:16:12 -0500 Subject: [PATCH 2/2] deprecate --- lib/postgrex.ex | 9 --------- lib/postgrex/protocol.ex | 5 +++++ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/postgrex.ex b/lib/postgrex.ex index 2da0c960..cd1400ee 100644 --- a/lib/postgrex.ex +++ b/lib/postgrex.ex @@ -52,7 +52,6 @@ defmodule Postgrex do | {:prepare, :named | :unnamed} | {:transactions, :strict | :naive} | {:types, module} - | {:search_path, [String.t()]} | {:disconnect_on_error_codes, [atom]} | DBConnection.start_option() @@ -161,14 +160,6 @@ defmodule Postgrex do option is only required when using custom encoding or decoding (default: `Postgrex.DefaultTypes`); - * `:search_path` - A list of strings used to set the search path for the connection. - This is useful when, for instance, an extension like `citext` is installed in a - separate schema. If that schema is not in the connection's search path, Postgrex - might not be able to recognize the extension's data type. When this option is `nil`, - the search path is not modified. (default: `nil`). - 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`). diff --git a/lib/postgrex/protocol.ex b/lib/postgrex/protocol.ex index 97ba3e3c..586f0131 100644 --- a/lib/postgrex/protocol.ex +++ b/lib/postgrex/protocol.ex @@ -120,6 +120,11 @@ defmodule Postgrex.Protocol do parameters = case opts[:search_path] do path when is_list(path) -> + Logger.warning( + "the `:search_path` option is deprecated. Please use the `:parameters` option by " <> + "passing `:search_path` as a key and a comma delimited string as the value." + ) + path = Enum.intersperse(path, ", ") Keyword.put(parameters, :search_path, path)