Skip to content
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

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 this issue Jul 18, 2024 · 10 comments

Comments

@lpil
Copy link
Contributor

lpil commented Jul 18, 2024

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: lpil/pog#29

@tsloughter
Copy link
Collaborator

Ah yup, thanks. Think I can fix.

@lpil
Copy link
Contributor Author

lpil commented Jul 22, 2024

Thank you

@tsloughter
Copy link
Collaborator

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
Copy link
Collaborator

With pgo:format_error that becomes:

"Error encoding type int4. Expected, integer(). Got, {10,54,3.45}."

@tsloughter
Copy link
Collaborator

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
Copy link
Contributor Author

lpil commented Jul 29, 2024

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

@ghivert
Copy link

ghivert commented Nov 20, 2024

I'm upping that error, because I encounter the same error with pog (in Gleam) and pgo, on Postgres 14 (Postgres containerized with Docker), with latest pgo (0.13.0). I'm on macOS too.

With a table created like CREATE TABLE min_repro_table (id uuid primary key default uuid_generate_v4(), content text) with uuid_ossp activated, a query like pgo:query("INSERT INTO min_repo_table (content) VALUES ($1)", [12]), returns {error, badarg}.
In the same spirit, if I try pgo:query("INSERT INTO min_repo_table (id) VALUES ($1)", [<<"a long imaginary UUID that doesn't exist">>]), I get {error, badarg} too.

@tsloughter
Copy link
Collaborator

Thanks @ghivert I'll try those.

@tsloughter
Copy link
Collaborator

Ok, that one I could replicate, I'll keep digging.

@tsloughter
Copy link
Collaborator

This had a couple fixes possible. I included both in my PR to pg_types: tsloughter/pg_types#11

It opens up a potential change to pgo where it returns {error, #{...}, Stacktrace} instead of just {error, #{...}} -- though that would be a breaking change.

But, I'm not sure I want to keep the matching on error:badarg in pg_types. I'll cover more about that in the comments on the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants