From dabf972f74735d285d9a21c006e9ced24fa3bf70 Mon Sep 17 00:00:00 2001 From: Anton Lebedevich Date: Tue, 19 Jun 2012 12:44:55 +0400 Subject: [PATCH] allow concurrent pgsql:equery on same connection --- README | 11 ++++++++--- TODO | 2 +- src/pgsql.erl | 3 ++- src/pgsql_sock.erl | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README b/README index 34586ba..3474ed7 100644 --- a/README +++ b/README @@ -33,6 +33,8 @@ Asynchronous fork of https://github.com/wg/epgsql the 3 failing timeout tests. SSL performance can degrade if the driver process has a large inbox (thousands of messages). + Usage of unnamed prepared statement and portals leads to unpredicted results + in case of concurrent access to same connection. * Connect @@ -145,14 +147,17 @@ Asynchronous fork of https://github.com/wg/epgsql bools as true/false, etc. For details see pgsql_binary.erl and the Data Representation section below. - Ref = apgsql:equery(C, Sql, [Parameters]), + Asynchronous api equery requires you to parse statement beforehand + + Ref = apgsql:equery(C, Statement, [Parameters]), receive {C, Ref, Res} -> Res end. + Statement - parsed statement (see parse below) Res has same format as return value of pgsql:equery. - ipgsql:equery(C, Sql, [Parameters]) sends same set of messages as squery - including final {C, Ref, done}. + ipgsql:equery(C, Statement, [Parameters]) sends same set of messages as + squery including final {C, Ref, done}. * Parse/Bind/Execute diff --git a/TODO b/TODO index 9c0dea6..2d48290 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,7 @@ notify_async sends useful warnings, don't hide them if no async listeners call with timeouts (query cancellation?) describe portal test connect on start? -text format support +text column format support remove parse before equery (needs text column format) selectable date return format like erlang:now() diff --git a/src/pgsql.erl b/src/pgsql.erl index 2bd70f9..a9b9864 100644 --- a/src/pgsql.erl +++ b/src/pgsql.erl @@ -58,7 +58,8 @@ equery(C, Sql) -> %% TODO add fast_equery command that doesn't need parsed statement equery(C, Sql, Parameters) -> - case parse(C, Sql) of + Name = ["equery-", atom_to_list(node()), pid_to_list(self())], + case parse(C, Name, Sql, []) of {ok, #statement{types = Types} = S} -> Typed_Parameters = lists:zip(Types, Parameters), gen_server:call(C, {equery, S, Typed_Parameters}, infinity); diff --git a/src/pgsql_sock.erl b/src/pgsql_sock.erl index 49b4dba..9fd1c0c 100644 --- a/src/pgsql_sock.erl +++ b/src/pgsql_sock.erl @@ -158,7 +158,7 @@ command({equery, Statement, Parameters}, State) -> Bin2 = pgsql_wire:encode_formats(Columns), send(State, $B, ["", 0, StatementName, 0, Bin1, Bin2]), send(State, $E, ["", 0, <<0:?int32>>]), - send(State, $C, [$S, "", 0]), + send(State, $C, [$S, StatementName, 0]), send(State, $S, []), {noreply, State};