erleans / pgo

Erlang Postgres client and connection pool
Apache License 2.0
79 stars 15 forks source link

Passing a datetime tuple parameter in place of some other type results in badarg instead of {pgo_protocol, {parameters, Expected, Got}} #83

Open lpil opened 1 month ago

lpil commented 1 month ago

Hello!

We've discovered a surprising behaviour where for date times specifically if they are given when a different argument type is not supplied then the usual descriptive {pgo_protocol, {parameters, Expected, Got}} error it gives just badarg.

Given this is different to the behaviour of other parameter type errors I think this is a bug.

Thanks, Louis

Related: https://github.com/lpil/pgo/issues/29

tsloughter commented 1 month ago

Ah yup, thanks. Think I can fix.

lpil commented 1 month ago

Thank you

tsloughter commented 1 month ago

Hm, I just tried to reproduce and it seemed to work as expected:

%%% pgo_datetime_SUITE ==> 
Failure/Error: ?assertMatch(# { command := insert }, pgo : query ( "insert into times (user_id, a_timestamp, a_time) VALUES ($1, $2, $3)" , [ { 10 , 54 , 3.45 } , { { 2012 , 1 , 17 } , { 10 , 54 , 3.45 } } , { 10 , 54 , 3.45 } ] ))
  expected: = # { command := insert }
       got: {error,#{error => badarg_encoding,module => pg_types,
                     value => {10,54,3.45},
                     type_info =>
                         {type_info,23,pg_int4,[],default,<<"int4">>,
                                    <<"int4send">>,<<"int4recv">>,4,
                                    <<"int4out">>,<<"int4in">>,0,undefined,0,
                                    [],undefined}}}
      line: 102

I was adding it as a test to pgo_datetime_SUITE:

insert(_Config) ->
    ?assertMatch(#{command := create},
                 pgo:query("create temporary table times (user_id integer, a_timestamp timestamp, a_time time)")),

    ?assertMatch(#{command := insert},
                 pgo:query("insert into times (a_timestamp, a_time) VALUES ($1, $2)",
                           [{{2012,1,17},{10,54,3.45}}, {10,54,3.45}])),

    ?assertMatch(#{command := select,
                   rows := [{{{2012,1,17},{10,54,3.45}}, {10,54,3.45}}]},
                 pgo:query("select a_timestamp, a_time from times")),

    ?assertMatch(#{command := insert},
                 pgo:query("insert into times (user_id, a_timestamp, a_time) VALUES ($1, $2, $3)",
                           [{10,54,3.45}, {{2012,1,17},{10,54,3.45}}, {10,54,3.45}])).
tsloughter commented 1 month ago

With pgo:format_error that becomes:

"Error encoding type int4. Expected, integer(). Got, {10,54,3.45}."
tsloughter commented 1 month ago

Just noticed they used a timestamp and I was using a datetime. But I just checked and the same thing happens:

%%% pgo_datetime_SUITE ==> 
Failure/Error: ?assertMatch(# { command := insert }, pgo : query ( "insert into times (user_id, a_timestamp, a_time) VALUES ($1, $2, $3)" , [ { { 2012 , 1 , 17 } , { 10 , 54 , 3.45 } } , { { 2012 , 1 , 17 } , { 10 , 54 , 3.45 } } , { 10 , 54 , 3.45 } ] ))
  expected: = # { command := insert }
       got: {error,#{error => badarg_encoding,module => pg_types,
                     value => {{2012,1,17},{10,54,3.45}},
                     type_info =>
                         {type_info,23,pg_int4,[],default,<<"int4">>,
                                    <<"int4send">>,<<"int4recv">>,4,
                                    <<"int4out">>,<<"int4in">>,0,undefined,0,
                                    [],undefined}}}
      line: 102
lpil commented 1 month ago

Oh strange... I'll try and reproduce it later. Thanks