Current section
18 Versions
Jump to
Current section
18 Versions
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 |