Current section

18 Versions

Jump to

Compare versions

5 files changed
+24 additions
-10 deletions
  @@ -47,4 +47,4 @@
47 47 {<<"links">>,[{<<"Github">>,<<"https://github.com/epgsql/epgsql">>}]}.
48 48 {<<"name">>,<<"epgsql">>}.
49 49 {<<"requirements">>,[]}.
50 - {<<"version">>,<<"4.7.0">>}.
50 + {<<"version">>,<<"4.7.1">>}.
  @@ -32,7 +32,7 @@
32 32 -record(squery,
33 33 {query :: iodata(),
34 34 columns = [],
35 - decoder}).
35 + decoder = undefined :: epgsql_wire:row_decoder() | undefined}).
36 36
37 37 init(Sql) ->
38 38 #squery{query = Sql}.
  @@ -63,7 +63,8 @@ handle_message(?COMMAND_COMPLETE, Bin, Sock, #squery{columns = Cols} = St) ->
63 63 _ ->
64 64 {ok, Cols, Rows}
65 65 end,
66 - {add_result, Result, {complete, Complete}, Sock, St};
66 + {add_result, Result, {complete, Complete}, Sock, St#squery{columns = [],
67 + decoder = undefined}};
67 68 handle_message(?EMPTY_QUERY, _, Sock, St) ->
68 69 {add_result, {ok, [], []}, {complete, empty}, Sock, St};
69 70 handle_message(?READY_FOR_QUERY, _Status, Sock, _State) ->
  @@ -12,7 +12,6 @@
12 12
13 13 -type response() :: ok | {error, epgsql:query_error()}.
14 14
15 - -include("epgsql.hrl").
16 15 -include("protocol.hrl").
17 16 -include("../epgsql_replication.hrl").
18 17
  @@ -65,8 +64,13 @@ execute(Sock, #start_repl{slot = ReplicationSlot, callback = Callback,
65 64 %% CopyBothResponse
66 65 handle_message(?COPY_BOTH_RESPONSE, _Data, Sock, _State) ->
67 66 {finish, ok, ok, epgsql_sock:set_packet_handler(on_replication, Sock)};
68 - handle_message(?ERROR, Error, _Sock, _State) ->
67 + handle_message(?ERROR, Error, Sock, State) ->
68 + %% In the case of error, Postgresql replication protocol sends a ReadyForQuery message.
69 + %% Adds an error to results to handle it later in the ?READY_FOR_QUERY branch.
69 70 Result = {error, Error},
70 - {sync_required, Result};
71 + {add_result, Result, Result, Sock, State};
72 + handle_message(?READY_FOR_QUERY, _Data, Sock, _State) ->
73 + [Error = {error, _}] = epgsql_sock:get_results(Sock), % assert a single error response
74 + {finish, Error, done, Sock};
71 75 handle_message(_, _, _, _) ->
72 76 unknown.
  @@ -1,6 +1,6 @@
1 1 {application,epgsql,
2 2 [{description,"PostgreSQL Client"},
3 - {vsn,"4.7.0"},
3 + {vsn,"4.7.1"},
4 4 {modules,[]},
5 5 {registered,[]},
6 6 {applications,[kernel,stdlib,ssl]},
  @@ -488,6 +488,15 @@ send_multi(#state{mod = Mod, sock = Sock}, List) ->
488 488 end, List)).
489 489
490 490 do_send(gen_tcp, Sock, Bin) ->
491 + gen_tcp_send(Sock, Bin);
492 + do_send(ssl, Sock, Bin) ->
493 + ssl:send(Sock, Bin).
494 +
495 + -if(?OTP_RELEASE >= 26).
496 + gen_tcp_send(Sock, Bin) ->
497 + gen_tcp:send(Sock, Bin).
498 + -else.
499 + gen_tcp_send(Sock, Bin) ->
491 500 %% Why not gen_tcp:send/2?
492 501 %% See https://github.com/rabbitmq/rabbitmq-common/blob/v3.7.4/src/rabbit_writer.erl#L367-L384
493 502 %% Since `epgsql' uses `{active, true}' socket option by-default, it may potentially quickly
  @@ -496,15 +505,15 @@ do_send(gen_tcp, Sock, Bin) ->
496 505 %% `{active, true}' is still the default.
497 506 %%
498 507 %% Because we use `inet' driver directly, we also have `handle_info({inet_reply, ...`
508 + %% This `gen_tcp:send/2' problem have been solved in OTP-26, so this hack is no longer needed.
499 509 try erlang:port_command(Sock, Bin) of
500 510 true ->
501 511 ok
502 512 catch
503 513 error:_Error ->
504 514 {error, einval}
505 - end;
506 - do_send(ssl, Sock, Bin) ->
507 - ssl:send(Sock, Bin).
515 + end.
516 + -endif.
508 517
509 518 loop(#state{data = Data, handler = Handler, subproto_state = Repl} = State) ->
510 519 case epgsql_wire:decode_message(Data) of