elixir-ecto / myxql

MySQL 5.5+ driver for Elixir
Apache License 2.0
273 stars 67 forks source link

No match for `:ok_packet` when executing query_many in MyXql #151

Closed savtrip closed 1 year ago

savtrip commented 2 years ago

Hello to the amazing Elixir team,

I ran into a strange issue whilst using MyXql.query_many/4 within an IEX session for a new feature I was testing. I raised the issue here as it seems like there is a match issue within the DBConnection module. The query actually executes successfully (verified by looking at my database) but the GenServer for the connection crashes due to the mismatch. I read the source code but I saw no obvious spot of failure, there are quite a few private functions being utilised.

Versions db_connection -> 2.4.2 MyXql -> 0.6.1 MySql -> 8.0.28 Elixir -> 1.13.3

Example Query MyXQL.query_many(:myxql, "DROP TABLE IF EXISTS `exampleTable`;", [], query_type: :text)

Line of Interest db_connection 2.4.2) lib/db_connection.ex:652: DBConnection.execute/4

Below I added the Stack Trace from my IEX session. I only received the error when I ran a DROP command, the SELECT command ran fine.

iex(2)> MyXQL.query_many(:myxql, "DROP TABLE IF EXISTS `exampleTable`;", [], query_type: :text)
** (MatchError) no match of right hand side value: {:ok_packet, 0, 0, 2, 0, ""}
    (myxql 0.6.1) lib/myxql/connection.ex:330: anonymous fn/3 in MyXQL.Connection.result/3
    (elixir 1.13.3) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
    (myxql 0.6.1) lib/myxql/connection.ex:323: MyXQL.Connection.result/3
    (db_connection 2.4.2) lib/db_connection/holder.ex:354: DBConnection.Holder.holder_apply/4
    (db_connection 2.4.2) lib/db_connection.ex:1364: DBConnection.run_execute/5
    (db_connection 2.4.2) lib/db_connection.ex:1459: DBConnection.run/6
    (db_connection 2.4.2) lib/db_connection.ex:652: DBConnection.execute/4
    (myxql 0.6.1) lib/myxql.ex:355: MyXQL.do_query/4
[error] GenServer #PID<0.606.0> terminating
** (DBConnection.ConnectionError) client #PID<0.619.0> stopped: ** (MatchError) no match of right hand side value: {:ok_packet, 0, 0, 2, 0, ""}
    (myxql 0.6.1) lib/myxql/connection.ex:330: anonymous fn/3 in MyXQL.Connection.result/3
    (elixir 1.13.3) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
    (myxql 0.6.1) lib/myxql/connection.ex:323: MyXQL.Connection.result/3
    (db_connection 2.4.2) lib/db_connection/holder.ex:354: DBConnection.Holder.holder_apply/4
    (db_connection 2.4.2) lib/db_connection.ex:1364: DBConnection.run_execute/5
    (db_connection 2.4.2) lib/db_connection.ex:1459: DBConnection.run/6
    (db_connection 2.4.2) lib/db_connection.ex:652: DBConnection.execute/4
    (myxql 0.6.1) lib/myxql.ex:355: MyXQL.do_query/4
    (stdlib 3.17) erl_eval.erl:685: :erl_eval.do_apply/6
    (elixir 1.13.3) src/elixir.erl:296: :elixir.recur_eval/3
    (elixir 1.13.3) src/elixir.erl:274: :elixir.eval_forms/3
    (iex 1.13.3) lib/iex/evaluator.ex:310: IEx.Evaluator.handle_eval/3
    (iex 1.13.3) lib/iex/evaluator.ex:285: IEx.Evaluator.do_eval/3
    (iex 1.13.3) lib/iex/evaluator.ex:274: IEx.Evaluator.eval/3
    (iex 1.13.3) lib/iex/evaluator.ex:169: IEx.Evaluator.loop/1
    (iex 1.13.3) lib/iex/evaluator.ex:32: IEx.Evaluator.init/4
    (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

    (db_connection 2.4.2) lib/db_connection/connection.ex:198: DBConnection.Connection.handle_cast/2
    (connection 1.1.0) lib/connection.ex:810: Connection.handle_async/3
    (stdlib 3.17) gen_server.erl:695: :gen_server.try_dispatch/4
    (stdlib 3.17) gen_server.erl:771: :gen_server.handle_msg/6
    (stdlib 3.17) proc_lib.erl:236: :proc_lib.wake_up/3
Last message: {:"$gen_cast", {:stop, #Reference<0.2150810417.2459566084.228242>, %DBConnection.ConnectionError{message: "client #PID<0.619.0> stopped: ** (MatchError) no match of right hand side value: {:ok_packet, 0, 0, 2, 0, \"\"}\n    (myxql 0.6.1) lib/myxql/connection.ex:330: anonymous fn/3 in MyXQL.Connection.result/3\n    (elixir 1.13.3) lib/enum.ex:2396: Enum.\"-reduce/3-lists^foldl/2-0-\"/3\n    (myxql 0.6.1) lib/myxql/connection.ex:323: MyXQL.Connection.result/3\n    (db_connection 2.4.2) lib/db_connection/holder.ex:354: DBConnection.Holder.holder_apply/4\n    (db_connection 2.4.2) lib/db_connection.ex:1364: DBConnection.run_execute/5\n    (db_connection 2.4.2) lib/db_connection.ex:1459: DBConnection.run/6\n    (db_connection 2.4.2) lib/db_connection.ex:652: DBConnection.execute/4\n    (myxql 0.6.1) lib/myxql.ex:355: MyXQL.do_query/4\n    (stdlib 3.17) erl_eval.erl:685: :erl_eval.do_apply/6\n    (elixir 1.13.3) src/elixir.erl:296: :elixir.recur_eval/3\n    (elixir 1.13.3) src/elixir.erl:274: :elixir.eval_forms/3\n    (iex 1.13.3) lib/iex/evaluator.ex:310: IEx.Evaluator.handle_eval/3\n    (iex 1.13.3) lib/iex/evaluator.ex:285: IEx.Evaluator.do_eval/3\n    (iex 1.13.3) lib/iex/evaluator.ex:274: IEx.Evaluator.eval/3\n    (iex 1.13.3) lib/iex/evaluator.ex:169: IEx.Evaluator.loop/1\n    (iex 1.13.3) lib/iex/evaluator.ex:32: IEx.Evaluator.init/4\n    (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3\n", reason: :error, severity: :error}, %MyXQL.Connection{client: %MyXQL.Client{connection_id: 874, sock: {:gen_tcp, #Port<0.11>}}, cursors: %{}, disconnect_on_error_codes: [1461], last_ref: nil, ping_timeout: 15000, prepare: :named, queries: #Reference<0.2150810417.2459566083.228195>, transaction_status: :idle}}}
State: {MyXQL.Connection, %MyXQL.Connection{client: %MyXQL.Client{connection_id: 874, sock: {:gen_tcp, #Port<0.11>}}, cursors: %{}, disconnect_on_error_codes: [1461], last_ref: nil, ping_timeout: 15000, prepare: :named, queries: #Reference<0.2150810417.2459566083.228195>, transaction_status: :idle}}

Thanks guys!

wojtekmach commented 2 years ago

Thank you for the report!

cc @greg-rychlewski

greg-rychlewski commented 2 years ago

Thanks for the report. I see the issue...an individual result can be either an ok_packet record or a resultset record and query_many is only handling resultset. I'm out right now but will have a fix later tonight :).

savtrip commented 2 years ago

Awesome, thanks @wojtekmach and @greg-rychlewski