Browse Source

Merge pull request #228 from enidgjoleka/handle-skipped-commands-in-batch

Handle skipped commands in execute_batch
Sergey Prokhorov 5 years ago
parent
commit
89d6140db4
3 changed files with 13 additions and 8 deletions
  1. 5 2
      README.md
  2. 3 3
      src/commands/epgsql_cmd_batch.erl
  3. 5 3
      test/epgsql_SUITE.erl

+ 5 - 2
README.md

@@ -430,8 +430,11 @@ epgsql:execute_batch(C, "INSERT INTO account (name, age) VALUES ($1, $2) RETURNI
                      [ ["Joe", 35], ["Paul", 26], ["Mary", 24] ]).
                      [ ["Joe", 35], ["Paul", 26], ["Mary", 24] ]).
 ```
 ```
 
 
-In case one of the batch items causes an error, the result returned for this particular
-item will be `{error, #error{}}` and no more results will be produced.
+In case one of the batch items causes an error, all the remaining queries of
+that batch will be ignored. So, last element of the result list will be 
+`{error, #error{}}` and the length of the result list might be shorter that 
+the length of the batch. For a better illustration of such scenario please 
+refer to `epgsql_SUITE:batch_error/1`
 
 
 `epgsqla:execute_batch/{2,3}` sends `{C, Ref, Results}`
 `epgsqla:execute_batch/{2,3}` sends `{C, Ref, Results}`
 
 

+ 3 - 3
src/commands/epgsql_cmd_batch.erl

@@ -36,7 +36,8 @@
 -type response() :: [{ok, Count :: non_neg_integer(), Rows :: [tuple()]}
 -type response() :: [{ok, Count :: non_neg_integer(), Rows :: [tuple()]}
                      | {ok, Count :: non_neg_integer()}
                      | {ok, Count :: non_neg_integer()}
                      | {ok, Rows :: [tuple()]}
                      | {ok, Rows :: [tuple()]}
-                     | {error, epgsql:query_error()}].
+                     | {error, epgsql:query_error()}
+                     ].
 -type state() :: #batch{}.
 -type state() :: #batch{}.
 
 
 -spec init(arguments()) -> state().
 -spec init(arguments()) -> state().
@@ -110,8 +111,7 @@ handle_message(?COMMAND_COMPLETE, Bin, Sock,
                      {ok, Rows}
                      {ok, Rows}
              end,
              end,
     {add_result, Result, {complete, Complete}, Sock, State#batch{batch = Batch}};
     {add_result, Result, {complete, Complete}, Sock, State#batch{batch = Batch}};
-handle_message(?READY_FOR_QUERY, _Status, Sock, #batch{batch = B} = _State) when
-      length(B) =< 1 ->
+handle_message(?READY_FOR_QUERY, _Status, Sock, _State) ->
     Results = epgsql_sock:get_results(Sock),
     Results = epgsql_sock:get_results(Sock),
     {finish, Results, done, Sock};
     {finish, Results, done, Sock};
 handle_message(?ERROR, Error, Sock, #batch{batch = [_ | Batch]} = State) ->
 handle_message(?ERROR, Error, Sock, #batch{batch = [_ | Batch]} = State) ->

+ 5 - 3
test/epgsql_SUITE.erl

@@ -543,13 +543,15 @@ batch_error(Config) ->
     Module = ?config(module, Config),
     Module = ?config(module, Config),
     epgsql_ct:with_rollback(Config, fun(C) ->
     epgsql_ct:with_rollback(Config, fun(C) ->
         {ok, S} = Module:parse(C, "insert into test_table1(id, value) values($1, $2)"),
         {ok, S} = Module:parse(C, "insert into test_table1(id, value) values($1, $2)"),
-        [{ok, 1}, {error, _}] =
+        [{ok, 1}, {error, Error}] =
             Module:execute_batch(
             Module:execute_batch(
               C,
               C,
               [{S, [3, "batch_error 3"]},
               [{S, [3, "batch_error 3"]},
                {S, [2, "batch_error 2"]}, % duplicate key error
                {S, [2, "batch_error 2"]}, % duplicate key error
-               {S, [5, "batch_error 5"]}  % won't be executed
-              ])
+               {S, [5, "batch_error 5"]},  % won't be executed
+               {S, [6, "batch_error 6"]}  % won't be executed
+              ]),
+        ?assertMatch(#error{}, Error)
     end).
     end).
 
 
 single_batch(Config) ->
 single_batch(Config) ->