New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(Minor) Inconsistency in delete ... returning #86
Comments
Probably epgsql returns exactly what postgresql server returns to it. Should ensure... |
email-> delete from email_lnk returning *;
id | created | email | tries
------+------------+----------------------+-------
bkAH | 1450305670 | aherranz@......... | 0
1Poy | 1450305673 | aherranz@......... | 0
YmjV | 1450305675 | angel.herranz@...... | 0
(3 rows)
DELETE 3
email=> delete from email_lnk returning *;
id | created | email | tries
----+---------+-------+-------
(0 rows)
DELETE 0
email=> delete from email_lnk returning *;
id | created | email | tries
----+---------+-------+-------
(0 rows)
DELETE 0
email=> delete from email_lnk;
DELETE 0 |
Ok, I've just realized that your problem may be related to pgapp, not epgsql driver. I checked at current
And the same for |
On my view, the problem is still there: > epgsql:squery(C, "DELETE FROM t RETURNING c").
{ok,3,
[#column{name = <<"c">>,type = int4,size = 4,modifier = -1,
format = 0}],
[{<<"1">>},{<<"2">>},{<<"3">>}]}
> epgsql:squery(C, "DELETE FROM t RETURNING c").
{ok,0} I think this is not consistent with the documentation (returning vs no returning), but the main problem is that you have no information about columns and likely you expect them. Regards :) |
Ok, so, I traced epgsql's internal function calls and messages: 6> {ok, C} = epgsql:connect(#{host=>"localhost", username=>"postgres", password=>"postgres", database=>"postgres"}).
{ok,<0.191.0>}
7> epgsql:squery(C, "CREATE TEMPORARY TABLE t(c integer)").
{ok,[],[]}
8> epgsql:squery(C, "INSERT INTO t(c) VALUES (1), (2), (3) RETURNING c").
{ok,3,
[{column,<<"c">>,int4,4,-1,0}],
[{<<"1">>},{<<"2">>},{<<"3">>}]}
9> dbg:start().
{ok,<0.196.0>}
10> dbg:tracer().
{ok,<0.196.0>}
11> dbg:tpl(epgsql_sock, on_message, 2, []).
{ok,[{matched,nonode@nohost,1}]}
12> dbg:p(C, [c, m]).
{ok,[{matched,nonode@nohost,1}]}
% ================== Rows returned ============================
13> epgsql:squery(C, "DELETE FROM t RETURNING c").
(<0.191.0>) << {'$gen_call',{<0.188.0>,#Ref<0.0.1.1445>},
{squery,"DELETE FROM t RETURNING c"}}
(<0.191.0>) << {inet_reply,#Port<0.37136>,ok}
(<0.191.0>) << {tcp,#Port<0.37136>,
<<84,0,0,0,26,0,1,99,0,0,1,77,145,0,1,0,0,0,23,0,4,255,
255,255,255,0,0,68,0,0,0,11,0,1,0,0,0,1,49,68,0,0,0,11,
0,1,0,0,0,1,50,68,0,0,0,11,0,1,0,0,0,1,51,67,0,0,0,13,
68,69,76,69,84,69,32,51,0,90,0,0,0,5,73>>}
% 84 ("T") is "row description" packet. It contains this #column{} infos
(<0.191.0>) call epgsql_sock:on_message({84,<<0,1,99,0,0,1,77,145,0,1,0,0,0,23,0,4,255,255,255,255,0,0>>},{state,gen_tcp,#Port<0.37136>,
<<68,0,0,0,11,0,1,0,0,0,1,49,68,0,0,0,11,0,1,0,0,0,1,50,68,0,0,0,11,0,1,
0,0,0,1,51,67,0,0,0,13,68,69,76,69,84,69,32,51,0,90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.1.1445>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
{ok,3,
[{column,<<"c">>,int4,4,-1,0}],
[{<<"1">>},{<<"2">>},{<<"3">>}]}
% 68 ("D") is data row packet
(<0.191.0>) call epgsql_sock:on_message({68,<<0,1,0,0,0,1,49>>},{state,gen_tcp,#Port<0.37136>,
<<68,0,0,0,11,0,1,0,0,0,1,50,68,0,0,0,11,0,1,0,0,0,1,51,67,0,0,0,13,68,
69,76,69,84,69,32,51,0,90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.1.1445>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],
[{column,<<"c">>,int4,4,-1,0}],
[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
14> (<0.191.0>) call epgsql_sock:on_message({68,<<0,1,0,0,0,1,50>>},{state,gen_tcp,#Port<0.37136>,
<<68,0,0,0,11,0,1,0,0,0,1,51,67,0,0,0,13,68,69,76,69,84,69,32,51,0,90,0,
0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.1.1445>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],
[{column,<<"c">>,int4,4,-1,0}],
[{<<"1">>}],
[],[],undefined,73,undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined})
(<0.191.0>) call epgsql_sock:on_message({68,<<0,1,0,0,0,1,51>>},{state,gen_tcp,#Port<0.37136>,
<<67,0,0,0,13,68,69,76,69,84,69,32,51,0,90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.1.1445>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],
[{column,<<"c">>,int4,4,-1,0}],
[{<<"2">>},{<<"1">>}],
[],[],undefined,73,undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined})
% 67 ("C") is CommandComplete packet
(<0.191.0>) call epgsql_sock:on_message({67,<<68,69,76,69,84,69,32,51,0>>},{state,gen_tcp,#Port<0.37136>,
<<90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.1.1445>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],
[{column,<<"c">>,int4,4,-1,0}],
[{<<"3">>},{<<"2">>},{<<"1">>}],
[],[],undefined,73,undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined})
% 90 ("Z") - ready for next query
(<0.191.0>) call epgsql_sock:on_message({90,<<"I">>},{state,gen_tcp,#Port<0.37136>,<<>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.1.1445>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],
[{ok,3,[{column,<<"c">>,int4,4,-1,0}],[{<<"1">>},{<<"2">>},{<<"3">>}]}],
[],undefined,73,
{delete,3},
undefined,undefined,undefined,undefined,undefined,undefined,undefined})
% and epgsql sends reply back
(<0.191.0>) <0.188.0> ! {#Ref<0.0.1.1445>,
{ok,3,
[{column,<<"c">>,int4,4,-1,0}],
[{<<"1">>},{<<"2">>},{<<"3">>}]}}
14>
14> %=================== No rows returned ==========================
14> epgsql:squery(C, "DELETE FROM t RETURNING c").
(<0.191.0>) << {'$gen_call',{<0.188.0>,#Ref<0.0.2.1271>},
{squery,"DELETE FROM t RETURNING c"}}
(<0.191.0>) << {inet_reply,#Port<0.37136>,ok}
(<0.191.0>) << {tcp,#Port<0.37136>,
<<84,0,0,0,26,0,1,99,0,0,1,77,145,0,1,0,0,0,23,0,4,255,
255,255,255,0,0,67,0,0,0,13,68,69,76,69,84,69,32,48,0,
90,0,0,0,5,73>>}
{ok,0}
% 84 ("T") - row descriptions. YES! postgresql sends row descriptions even when there are no rows in response
15> (<0.191.0>) call epgsql_sock:on_message({84,<<0,1,99,0,0,1,77,145,0,1,0,0,0,23,0,4,255,255,255,255,0,0>>},{state,gen_tcp,#Port<0.37136>,
<<67,0,0,0,13,68,69,76,69,84,69,32,48,0,90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1271>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
% 67 ("C") - and right after rows descriptions there is CommandComplete
(<0.191.0>) call epgsql_sock:on_message({67,<<68,69,76,69,84,69,32,48,0>>},{state,gen_tcp,#Port<0.37136>,
<<90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1271>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],
[{column,<<"c">>,int4,4,-1,0}],
[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
(<0.191.0>) call epgsql_sock:on_message({90,<<"I">>},{state,gen_tcp,#Port<0.37136>,<<>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1271>}},
{squery,"DELETE FROM t RETURNING c"}}],
[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],
[{ok,0}],
[],undefined,73,
{delete,0},
undefined,undefined,undefined,undefined,undefined,undefined,undefined})
(<0.191.0>) <0.188.0> ! {#Ref<0.0.2.1271>,{ok,0}}
% ================ Sample SELECT, returning 0 rows =====================
21> epgsql:squery(C, "SELECT * FROM t").
(<0.191.0>) << {'$gen_call',{<0.188.0>,#Ref<0.0.2.1291>},
{squery,"SELECT * FROM t"}}
(<0.191.0>) << {inet_reply,#Port<0.37136>,ok}
(<0.191.0>) << {tcp,#Port<0.37136>,
<<84,0,0,0,26,0,1,99,0,0,1,77,145,0,1,0,0,0,23,0,4,255,
255,255,255,0,0,67,0,0,0,13,83,69,76,69,67,84,32,48,0,
90,0,0,0,5,73>>}
{ok,[{column,<<"c">>,int4,4,-1,0}],[]}
% RowDescription
22> (<0.191.0>) call epgsql_sock:on_message({84,<<0,1,99,0,0,1,77,145,0,1,0,0,0,23,0,4,255,255,255,255,0,0>>},{state,gen_tcp,#Port<0.37136>,
<<67,0,0,0,13,83,69,76,69,67,84,32,48,0,90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1291>}},{squery,"SELECT * FROM t"}}],[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
% CommandComplete
(<0.191.0>) call epgsql_sock:on_message({67,<<83,69,76,69,67,84,32,48,0>>},{state,gen_tcp,#Port<0.37136>,
<<90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1291>}},{squery,"SELECT * FROM t"}}],[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],
[{column,<<"c">>,int4,4,-1,0}],
[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
% ReadyForQuery
(<0.191.0>) call epgsql_sock:on_message({90,<<"I">>},{state,gen_tcp,#Port<0.37136>,<<>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1291>}},{squery,"SELECT * FROM t"}}],[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],
[{ok,[{column,<<"c">>,int4,4,-1,0}],[]}],
[],undefined,73,select,undefined,undefined,undefined,undefined,
undefined,undefined,undefined})
(<0.191.0>) <0.188.0> ! {#Ref<0.0.2.1291>,
{ok,[{column,<<"c">>,int4,4,-1,0}],[]}} So, yep, from the point of view of postgres protocol |
Ah, and 22> epgsql:squery(C, "DELETE FROM t").
(<0.191.0>) << {'$gen_call',{<0.188.0>,#Ref<0.0.2.1296>},
{squery,"DELETE FROM t"}}
(<0.191.0>) << {inet_reply,#Port<0.37136>,ok}
(<0.191.0>) << {tcp,#Port<0.37136>,
<<67,0,0,0,13,68,69,76,69,84,69,32,48,0,90,0,0,0,5,73>>}
{ok,0}
% CommandComplete
23> (<0.191.0>) call epgsql_sock:on_message({67,<<68,69,76,69,84,69,32,48,0>>},{state,gen_tcp,#Port<0.37136>,
<<90,0,0,0,5,73>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1296>}},{squery,"DELETE FROM t"}}],[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],[],[],undefined,73,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined})
% ReadyForQuery
(<0.191.0>) call epgsql_sock:on_message({90,<<"I">>},{state,gen_tcp,#Port<0.37136>,<<>>,
{25093,2074650982},
on_message,
{codec,[],[]},
{[{{call,{<0.188.0>,#Ref<0.0.2.1296>}},{squery,"DELETE FROM t"}}],[]},
undefined,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"on">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.1.13">>},
{<<"session_authorization">>,<<"postgres">>},
{<<"standard_conforming_strings">>,<<"on">>},
{<<"TimeZone">>,<<"W-SU">>}],
[],[],[],
[{ok,0}],
[],undefined,73,
{delete,0},
undefined,undefined,undefined,undefined,undefined,undefined,undefined})
(<0.191.0>) <0.188.0> ! {#Ref<0.0.2.1296>,{ok,0}} In this case there is no |
So, the problem is here:
|
Nice! Thank you very much. |
* Make such a response to be always a 4-tuple {ok, Count, Columns, Rows}
Fixed in #115 |
* Make such a response to be always a 4-tuple {ok, Count, Columns, Rows}
I think there is an inconsistent behaviour in delete...returning statement when no rows are deleted:
Since I am using returning I would expect the second expression to return
Am I wrong?
The text was updated successfully, but these errors were encountered: