Postgrex seemingly incorrect row data returned in transaction upsert with returning

I am doing a Postgrex transaction. Inside the transaction I am doing a series of inserts. The inserts have an on conflict (whatever) do update returning id clause in them. The first insert seems to work and returns the correct id, subsequent inserts appear to work but are returning stuff I don’t understand.

Here is the insert:

insert into tokens (contract, token_id) values ($1, $2) on conflict (contract, token_id) do update set updated_at = now() returning id

I am just returning a list of the Postgrex.Result structs. Here is an example of what I am getting:

{:ok, [%Postgrex.Result{command: :insert, columns: ["id"], rows: [[6]], num_rows: 1, connection_id: 602780, messages: []}, %Postgrex.Result{command: :insert, columns: ["id"], rows: [~c"\a"], num_rows: 1, connection_id: 602780, messages: []}, %Postgrex.Result{command: :insert, columns: ["id"], rows: [~c"\b"], num_rows: 1, connection_id: 602780, messages: []}, %Postgrex.Result{command: :insert, columns: ["id"], rows: [~c"\t"], num_rows: 1, connection_id: 602780, messages: []}, %Postgrex.Result{command: :insert, columns: ["id"], rows: [~c"\n"], num_rows: 1, connection_id: 602780, messages: []}]}

The first insert returned [[6]] as expected but subsequent inserts returned things I don’t recognize like [~c"\a"]. I noticed there was a pattern, like a, b, c, t, '\n'.

I am beginning learning Elixir so I don’t recognize what ~c"\a" is or why I am getting this. I am skipping Ecto for the time being because I want to understand internals.

Can anyone help?

Hey @bananaphone welcome! Good news! It’s returning the right thing, it’s just presented in a confusing way. Binaries, strings, and charlists - The Elixir programming language

Basically, to maintain compatibility with Erlang, when a list contains only integers and those integers are printable, it is displayed as text with the ~c"text here" syntax. That is just a display thing, it is still a list:

iex(4)> [7] == ~c"\a"
true

I believe there is an option you can set to always display charlists as lists, let me see if I can find that.

3 Likes