livehelpnow / tds_ecto

TDS Adapter for Ecto
57 stars 34 forks source link

Support for Stored procedures in Ecto 2 #51

Closed RaoKrishna closed 6 years ago

RaoKrishna commented 7 years ago

I am trying to invoke stored procedure and I get the following error "[error] GenServer #PID<0.271.0> terminating (DBConnection.ConnectionError) client #PID<0.254.0> stopped: (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2 (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 17, 0, 193, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, ...>>, [done: %{cmd: <<192, 0>>, rows: 0, status: 256}])"

Please let me know if the current Tds adapter supports invoking stored procedures. I have mentioned the different ways of invoking the stored procedure and the error stack.

Cases tried:

1.

{:ok, pid} = Tds.start_link([hostname: "host", username: "user", password: "pwd", database: "mydb", instance: "myinstance", port: 4000]) Tds.query(pid, "exec schema.procName @param1, @param2, @param3", [%Tds.Parameter{name: "@param1", value: 1}, %Tds.Parameter{name: "@param2", value: 7},
%Tds.Parameter{name: "@param3", value: 1}])

  1. Mention the config details in the config file and the code:

Ecto.Adapters.SQL.query(Repo, "exec schema.procName $1, $2, $3", [1,7,1])

Detailed error stack:

[error] GenServer #PID<0.271.0> terminating (DBConnection.ConnectionError) client #PID<0.254.0> stopped: (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2 (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 17, 0, 193, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, ...>>, [done: %{cmd: <<192, 0>>, rows: 0, status: 256}]) (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2 (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4 (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2 (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3 (db_connection) lib/db_connection.ex:958: DBConnection.handle/4 (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5 (db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5 (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3 (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4 (tds_ecto) lib/tds_ecto/connection.ex:46: Tds.Ecto.Connection.execute/4 (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6 (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6 (elixir) src/elixir.erl:239: :elixir.eval_forms/4 (iex) lib/iex/evaluator.ex:219: IEx.Evaluator.handle_eval/5 (iex) lib/iex/evaluator.ex:200: IEx.Evaluator.do_eval/3 (iex) lib/iex/evaluator.ex:178: IEx.Evaluator.eval/3 (iex) lib/iex/evaluator.ex:77: IEx.Evaluator.loop/1 (iex) lib/iex/evaluator.ex:21: IEx.Evaluator.init/4 (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

(db_connection) lib/db_connection/connection.ex:243: DBConnection.Connection.handle_cast/2
(connection) lib/connection.ex:488: Connection.handle_call/3
(stdlib) gen_server.erl:636: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:665: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

Last message (from #PID<0.279.0>): {:stop, #Reference<0.171843970.1740374017.204371>, %DBConnection.ConnectionError{message: "client #PID<0.254.0> stopped: ** (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2\n (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 17, 0, 193, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, ...>>, [done: %{cmd: <<192, 0>>, rows: 0, status: 256}])\n (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2\n (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4\n (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2\n (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3\n (db_connection) lib/db_connection.ex:958: DBConnection.handle/4\n (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5\n (db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5\n (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3\n (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4\n (tds_ecto) lib/tds_ecto/connection.ex:46: Tds.Ecto.Connection.execute/4\n (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6\n (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6\n (elixir) src/elixir.erl:239: :elixir.eval_forms/4\n (iex) lib/iex/evaluator.ex:219: IEx.Evaluator.handle_eval/5\n (iex) lib/iex/evaluator.ex:200: IEx.Evaluator.do_eval/3\n (iex) lib/iex/evaluator.ex:178: IEx.Evaluator.eval/3\n (iex) lib/iex/evaluator.ex:77: IEx.Evaluator.loop/1\n (iex) lib/iex/evaluator.ex:21: IEx.Evaluator.init/4\n (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3\n"}, %Tds.Protocol{env: %{trans: <<0>>}, itcp: 49815, opts: [password: :REDACTED, idle_timeout: 5000, name: Sqlapp.Repo.Pool, otp_app: :sqlapp, repo: Sqlapp.Repo, timeout: 15000, pool_timeout: 5000, database: "mydb", username: "user", hostname: "host", instance: "myinst", odbc_driver: "{SQL Server Native Client 11.0}", pool_size: 15, pool: DBConnection.Poolboy], pak_data: "", pak_header: "", query: %Tds.Query{handle: 1, statement: nil}, result: %Tds.Result{columns: [], command: nil, num_rows: 0, rows: []}, sock: {:gen_tcp, #Port<0.8444>}, state: :ready, tail: "", transaction: nil, usock: #Port<0.8432>}} State: {Tds.Protocol, %Tds.Protocol{env: %{trans: <<0>>}, itcp: 49815, opts: [password: :REDACTED, idle_timeout: 5000, name: Sqlapp.Repo.Pool, otp_app: :sqlapp, repo: Sqlapp.Repo, timeout: 15000, pool_timeout: 5000, database: "mydb", username: "user", hostname: "host", instance: "myinst", odbc_driver: "{SQL Server Native Client 11.0}", pool_size: 15, pool: DBConnection.Poolboy], pak_data: "", pak_header: "", query: %Tds.Query{handle: 1, statement: nil}, result: %Tds.Result{columns: [], command: nil, num_rows: 0, rows: []}, sock: {:gen_tcp, #Port<0.8444>}, state: :ready, tail: "", transaction: nil, usock: #Port<0.8432>}} Client #PID<0.279.0> is alive (stdlib) gen.erl:169: :gen.do_call/4 (stdlib) gen_server.erl:210: :gen_server.call/3 (db_connection) lib/db_connection/connection.ex:428: DBConnection.Connection.sync_stop/5

** (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2

The following arguments were given to Tds.Tokens.decode_token/2:

    # 1
    <<0, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 17, 0,
  193, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  121, 0, 0, ...>>

    # 2
    [done: %{cmd: <<192, 0>>, rows: 0, status: 256}]

Attempted function clauses (showing 10 out of 12):

    defp decode_token(-<<172::integer(), tail::binary()>>-, tokens)
    defp decode_token(-<<121::integer(), _value::integer()-little()-size(32), tail::binary()>>-, tokens)
    defp decode_token(-<<129::integer(), column_count::integer()-little()-unit(8)-size(2), tail::binary()>>-, tokens)
    defp decode_token(-<<169::integer(), length::integer()-little()-unsigned()-size(16), tail::binary()>>-, tokens)
    defp decode_token(-<<170::integer(), length::integer()-little()-size(16), number::integer()-little()-size(32), state::integer(), class::integer(), msg_len::integer()-little()-size(16), msg::binary()-unit(16)-size(msg_len), sn_len::integer(), server_name::binary()-unit(16)-size(sn_len), pn_len::integer(), proc_name::binary()-unit(16)-size(pn_len), line_number::integer()-little()-size(32), _data::binary()>>-, _tokens)
    defp decode_token(-<<171::integer(), length::integer()-little()-size(16), number::integer()-little()-size(32), state::integer(), class::integer(), msg_len::integer()-little()-size(16), msg::binary()-unit(16)-size(msg_len), sn_len::integer(), server_name::binary()-unit(16)-size(sn_len), pn_len::integer(), proc_name::binary()-unit(16)-size(pn_len), line_number::integer()-little()-size(32), tail::binary()>>-, tokens)
    defp decode_token(-<<209::integer(), tail::binary()>>-, tokens)
    defp decode_token(-<<210::integer(), tail::binary()>>-, tokens)
    defp decode_token(-<<227::integer(), _length::integer()-little()-unsigned()-size(16), env_type::integer()-unsigned()-size(8), tail::binary()>>-, tokens)
    defp decode_token(-<<253::integer(), status::integer()-signed()-size(16), cur_cmd::binary()-size(2), row_count::integer()-little()-unit(8)-size(8), _tail::binary()>>-, tokens)

(tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token/2
(tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2
(tds) lib/tds/messages.ex:99: Tds.Messages.parse/4
(tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2
(tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3
(db_connection) lib/db_connection.ex:958: DBConnection.handle/4
(db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5
(db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5
(db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4
(tds_ecto) lib/tds_ecto/connection.ex:46: Tds.Ecto.Connection.execute/4
(ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
mjaric commented 7 years ago

Did you set nocount on in stores procedure?

Also does your stored procedure print anything ?

RaoKrishna commented 7 years ago

Yes, I have set nocount on in stored procedure.

No, The stored proc does not print anything. It just returns couple of rows.

I noticed now that the SQL proc does return the necessary rows. But it still throws the same error. The error is seen as follows:

[error] GenServer #PID<0.243.0> terminating (DBConnection.ConnectionError) client #PID<0.362.0> stopped: (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2 (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 254, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0>>, [done: %{cmd: <<193, 0>>, rows: 7, status: 256}, order: [0], columns: [%{collation: <<9, 4, 208, 0, 52>>, data_reader: :shortlen, data_type: :variable, data_type_code: 231, length: 402, name: ""}, %{data_type: :fixed, data_type_code: 50, length: 1, name: "IsPrimaryId"}, %{data_type: :fixed, data_type_code: 56, length: 4, name: "dataObjectDefId"}], rows: [["Person:Ethnicity", false, 14], ["Course:DisplayCode", false, 2], ["Course:CourseId", true, 2], ["Student:email", false, 1], ["Student:Last", false, 1], ["Student:First", false, 1], ["Student:StudentId", true, 1]]]) (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2 (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4 (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2 (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3 (db_connection) lib/db_connection.ex:958: DBConnection.handle/4 (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5 (db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5 (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3 (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4 (tds_ecto) lib/tds_ecto/connection.ex:46: Tds.Ecto.Connection.execute/4 (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6 (sqlapp) web/controllers/page_controller.ex:14: Sqlapp.PageController.index/2 (sqlapp) web/controllers/page_controller.ex:1: Sqlapp.PageController.action/2 (sqlapp) web/controllers/page_controller.ex:1: Sqlapp.PageController.phoenix_controller_pipeline/2 (sqlapp) lib/sqlapp/endpoint.ex:1: Sqlapp.Endpoint.instrument/4 (sqlapp) lib/phoenix/router.ex:261: Sqlapp.Router.dispatch/2 (sqlapp) web/router.ex:1: Sqlapp.Router.do_call/2 (sqlapp) lib/sqlapp/endpoint.ex:1: Sqlapp.Endpoint.phoenix_pipeline/1 (sqlapp) lib/plug/debugger.ex:123: Sqlapp.Endpoint."call (overridable 3)"/2

(db_connection) lib/db_connection/connection.ex:243: DBConnection.Connection.handle_cast/2
(connection) lib/connection.ex:488: Connection.handle_call/3
(stdlib) gen_server.erl:636: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:665: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

Last message (from #PID<0.365.0>): {:stop, #Reference<0.449797592.141819905.225720>, %DBConnection.ConnectionError{message: "client #PID<0.362.0> stopped: ** (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2\n (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 254, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0>>, [done: %{cmd: <<193, 0>>, rows: 7, status: 256}, order: [0], columns: [%{collation: <<9, 4, 208, 0, 52>>, data_reader: :shortlen, data_type: :variable, data_type_code: 231, length: 402, name: \"\"}, %{data_type: :fixed, data_type_code: 50, length: 1, name: \"IsPrimaryId\"}, %{data_type: :fixed, data_type_code: 56, length: 4, name: \"dataObjectDefId\"}], rows: [[\"Person:Ethnicity\", false, 14], [\"Course:DisplayCode\", false, 2], [\"Course:CourseId\", true, 2], [\"Student:email\", false, 1], [\"Student:Last\", false, 1], [\"Student:First\", false, 1], [\"Student:StudentId\", true, 1]]])\n (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2\n (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4\n (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2\n (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3\n (db_connection) lib/db_connection.ex:958: DBConnection.handle/4\n (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5\n (db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5\n (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3\n (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4\n (tds_ecto) lib/tds_ecto/connection.ex:46: Tds.Ecto.Connection.execute/4\n (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6\n (sqlapp) web/controllers/page_controller.ex:14: Sqlapp.PageController.index/2\n (sqlapp) web/controllers/page_controller.ex:1: Sqlapp.PageController.action/2\n (sqlapp) web/controllers/page_controller.ex:1: Sqlapp.PageController.phoenix_controller_pipeline/2\n (sqlapp) lib/sqlapp/endpoint.ex:1: Sqlapp.Endpoint.instrument/4\n (sqlapp) lib/phoenix/router.ex:261: Sqlapp.Router.dispatch/2\n (sqlapp) web/router.ex:1: Sqlapp.Router.do_call/2\n (sqlapp) lib/sqlapp/endpoint.ex:1: Sqlapp.Endpoint.phoenix_pipeline/1\n (sqlapp) lib/plug/debugger.ex:123: Sqlapp.Endpoint.\"call (overridable 3)\"/2\n"}, %Tds.Protocol{env: %{trans: <<0>>}, itcp: 49815, opts: [password: :REDACTED, idle_timeout: 5000, name: Sqlapp.Repo.Pool, otp_app: :sqlapp, repo: Sqlapp.Repo, timeout: 15000, pool_timeout: 5000, database: "mydb", username: "user", hostname: "host", instance: "myinst", odbc_driver: "{SQL Server Native Client 11.0}", pool_size: 15, pool: DBConnection.Poolboy], pak_data: "", pak_header: "", query: %Tds.Query{handle: 1, statement: nil}, result: %Tds.Result{columns: [], command: nil, num_rows: 0, rows: []}, sock: {:gen_tcp, #Port<0.7720>}, state: :ready, tail: "", transaction: nil, usock: #Port<0.7403>}} State: {Tds.Protocol, %Tds.Protocol{env: %{trans: <<0>>}, itcp: 49815, opts: [password: :REDACTED, idle_timeout: 5000, name: Sqlapp.Repo.Pool, otp_app: :sqlapp, repo: Sqlapp.Repo, timeout: 15000, pool_timeout: 5000, database: "mydb", username: "user", hostname: "host", instance: "myinst", odbc_driver: "{SQL Server Native Client 11.0}", pool_size: 15, pool: DBConnection.Poolboy], pak_data: "", pak_header: "", query: %Tds.Query{handle: 1, statement: nil}, result: %Tds.Result{columns: [], command: nil, num_rows: 0, rows: []}, sock: {:gen_tcp, #Port<0.7720>}, state: :ready, tail: "", transaction: nil, usock: #Port<0.7403>}}

mjaric commented 7 years ago

is first column (nvarchar) in your select statement product of string concatenation?

I have some code which calls stored procedures but I haven't had issue. if this stored procedure is not confidential, could you provide me select statement? or if you can't, could you try reproduce issue on some dummy example?

RaoKrishna commented 7 years ago

I tried the above case with the dummy data and got the same error.

Dummy Table:

CREATE TABLE [dbo].[dummy_tbl](
    [id] [int] NOT NULL,
    [name] [nvarchar] (50) NOT NULL
) 
id (primary key) name
1 Elixir
2 Elm
3 SQL

SQL Procedure:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE RetrieveDummyValues 
    -- Add the parameters for the stored procedure here
    @filterId INT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    select * from dummy_tbl
END
GO

Elixir code:

defmodule SampleQuery do
  import Ecto.Query
  alias Sqlapp.Repo

  def invoke_proc do
    {:ok, pid} = Tds.start_link([hostname: "host", username: "user",
     password: "pwd", database: "mydb", instance: "myinst", port: 4000])
    Tds.query(pid, "exec RetrieveDummyValues @filterId", 
        [%Tds.Parameter{name: "@filterId", value: 1}])

    ## Ecto.Adapters.SQL.query(Repo, "exec RetrieveDummyValues $1", [2]) 
  end
end

Error:

iex(2)>  SampleQuery.invoke_proc
** (EXIT from #PID<0.265.0>) evaluator process exited with reason: an exception was raised:
    ** (DBConnection.ConnectionError) client #PID<0.265.0> stopped: ** (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2
    (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 254, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0>>, [done: %{cmd: <<193, 0>>, rows: 3, status: 256}, columns: [%{data_type: :fixed, data_type_code: 56, length: 4, name: "id"}, %{collation: <<9, 4, 208, 0, 52>>, data_reader: :shortlen, data_type: :variable, data_type_code: 231, length: 100, name: "name"}], rows: [[3, "SQL"], [2, "Elm"], [1, "Elixir"]]])
    (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2
    (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4
    (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2
    (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3
    (db_connection) lib/db_connection.ex:958: DBConnection.handle/4
    (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5
    (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3
    (db_connection) lib/db_connection.ex:1133: DBConnection.run_meter/3
    (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4
    (tds) lib/tds.ex:15: Tds.query/4
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (elixir) src/elixir.erl:239: :elixir.eval_forms/4
    (iex) lib/iex/evaluator.ex:219: IEx.Evaluator.handle_eval/5
    (iex) lib/iex/evaluator.ex:200: IEx.Evaluator.do_eval/3
    (iex) lib/iex/evaluator.ex:178: IEx.Evaluator.eval/3
    (iex) lib/iex/evaluator.ex:77: IEx.Evaluator.loop/1
    (iex) lib/iex/evaluator.ex:21: IEx.Evaluator.init/4
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
    (db_connection) lib/db_connection/connection.ex:243: DBConnection.Connection.handle_cast/2
    (connection) lib/connection.ex:810: Connection.handle_async/3
    (stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:686: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
[error] GenServer #PID<0.284.0> terminating
** (DBConnection.ConnectionError) client #PID<0.265.0> stopped: ** (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2
    (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 254, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0>>, [done: %{cmd: <<193, 0>>, rows: 3, status: 256}, columns: [%{data_type: :fixed, data_type_code: 56, length: 4, name: "id"}, %{collation: <<9, 4, 208, 0, 52>>, data_reader: :shortlen, data_type: :variable, data_type_code: 231, length: 100, name: "name"}], rows: [[3, "SQL"], [2, "Elm"], [1, "Elixir"]]])
    (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2
    (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4
    (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2
    (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3
    (db_connection) lib/db_connection.ex:958: DBConnection.handle/4
    (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5
    (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3
    (db_connection) lib/db_connection.ex:1133: DBConnection.run_meter/3
    (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4
    (tds) lib/tds.ex:15: Tds.query/4
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (elixir) src/elixir.erl:239: :elixir.eval_forms/4
    (iex) lib/iex/evaluator.ex:219: IEx.Evaluator.handle_eval/5
    (iex) lib/iex/evaluator.ex:200: IEx.Evaluator.do_eval/3
    (iex) lib/iex/evaluator.ex:178: IEx.Evaluator.eval/3
    (iex) lib/iex/evaluator.ex:77: IEx.Evaluator.loop/1
    (iex) lib/iex/evaluator.ex:21: IEx.Evaluator.init/4
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
    (db_connection) lib/db_connection/connection.ex:243: DBConnection.Connection.handle_cast/2
    (connection) lib/connection.ex:810: Connection.handle_async/3
    (stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:686: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:stop, #Reference<0.3349945222.155189249.122573>, %DBConnection.ConnectionError{message: "client #PID<0.265.0> stopped: ** (FunctionClauseError) no function clause matching in Tds.Tokens.decode_token/2\n    (tds) lib/tds/tokens.ex:51: Tds.Tokens.decode_token(<<0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 254, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0>>, [done: %{cmd: <<193, 0>>, rows: 3, status: 256}, columns: [%{data_type: :fixed, data_type_code: 56, length: 4, name: \"id\"}, %{collation: <<9, 4, 208, 0, 52>>, data_reader: :shortlen, data_type: :variable, data_type_code: 231, length: 100, name: \"name\"}], rows: [[3, \"SQL\"], [2, \"Elm\"], [1, \"Elixir\"]]])\n    (tds) lib/tds/tokens.ex:38: Tds.Tokens.decode_tokens/2\n    (tds) lib/tds/messages.ex:99: Tds.Messages.parse/4\n    (tds) lib/tds/protocol.ex:265: Tds.Protocol.new_data/2\n    (tds) lib/tds/protocol.ex:408: Tds.Protocol.send_param_query/3\n    (db_connection) lib/db_connection.ex:958: DBConnection.handle/4\n    (db_connection) lib/db_connection.ex:1078: DBConnection.describe_run/5\n    (db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3\n    (db_connection) lib/db_connection.ex:1133: DBConnection.run_meter/3\n    (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4\n    (tds) lib/tds.ex:15: Tds.query/4\n    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6\n    (elixir) src/elixir.erl:239: :elixir.eval_forms/4\n    (iex) lib/iex/evaluator.ex:219: IEx.Evaluator.handle_eval/5\n    (iex) lib/iex/evaluator.ex:200: IEx.Evaluator.do_eval/3\n    (iex) lib/iex/evaluator.ex:178: IEx.Evaluator.eval/3\n    (iex) lib/iex/evaluator.ex:77: IEx.Evaluator.loop/1\n    (iex) lib/iex/evaluator.ex:21: IEx.Evaluator.init/4\n    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3\n"}, %Tds.Protocol{env: %{trans: <<0>>}, itcp: 49815, opts: [password: :REDACTED, idle_timeout: 5000, hostname: "host", username: "user", database: "mydb", instance: "myinst", port: 4000], pak_data: "", pak_header: "", query: %Tds.Query{handle: 1, statement: nil}, result: %Tds.Result{columns: [], command: nil, num_rows: 0, rows: []}, sock: {:gen_tcp, #Port<0.8721>}, state: :ready, tail: "", transaction: nil, usock: #Port<0.8718>}}}
State: {Tds.Protocol, %Tds.Protocol{env: %{trans: <<0>>}, itcp: 49815, opts: [password: :REDACTED, idle_timeout: 5000, hostname: "host", username: "user", database: "mydb", instance: "myinst", port: 4000], pak_data: "", pak_header: "", query: %Tds.Query{handle: 1, statement: nil}, result: %Tds.Result{columns: [], command: nil, num_rows: 0, rows: []}, sock: {:gen_tcp, #Port<0.8721>}, state: :ready, tail: "", transaction: nil, usock: #Port<0.8718>}}
mjaric commented 6 years ago

fixed in tds repo commit dce844

pull from hex updated version of tds lib v1.0.11