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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support xid8 type #558

Closed
maltoe opened this issue Jul 11, 2021 · 1 comment 路 Fixed by #559
Closed

Support xid8 type #558

maltoe opened this issue Jul 11, 2021 · 1 comment 路 Fixed by #559

Comments

@maltoe
Copy link
Contributor

maltoe commented Jul 11, 2021

Hello postgrex devs 馃憢

PostgreSQL 13 introduced a new xid8 type and for its new 64-bit long transaction IDs (basically to ensure uniqueness over the lifespan of the DB). We'd like to be able to query these using Postgrex.

Actual Behaviour

iex(4)> Ecto.Adapters.SQL.query!(MyApp.Repo, "SELECT '1'::xid8;")
** (Postgrex.QueryError) type `xid8` can not be handled by the types module Postgrex.DefaultTypes
    (ecto_sql 3.6.1) lib/ecto/adapters/sql.ex:749: Ecto.Adapters.SQL.raise_sql_call_error/1
[debug] QUERY ERROR db=0.0ms queue=3.8ms idle=262.4ms
SELECT '1'::xid8; []
iex(4)> [error] Postgrex.Protocol (#PID<0.672.0>) disconnected: ** (Postgrex.QueryError) type `xid8` can not be handled by the types module Postgrex.DefaultTypes

Side-note: Postgres doesn't have a int8->xid8 cast function, hence the quotes above.

Desired behaviour

Like xid:

iex(4)> Ecto.Adapters.SQL.query!(MyApp.Repo, "SELECT '1'::xid;")
[debug] QUERY OK db=0.2ms queue=0.3ms idle=982.4ms
SELECT '1'::xid; []
%Postgrex.Result{
  columns: ["xid"],
  command: :select,
  connection_id: 87864,
  messages: [],
  num_rows: 1,
  rows: [[1]]
}

Solution

We currently run a custom extension:

defmodule Postgrex.Extensions.Xid8 do
  @moduledoc false
  import Postgrex.BinaryUtils, warn: false
  use Postgrex.BinaryExtension, send: "xid8send"

  @xid8_range 0..18_446_744_073_709_551_615

  def encode(_) do
    range = Macro.escape(@xid8_range)

    quote location: :keep do
      # BinaryUtils doesn't have uint64 yet
      int when is_integer(int) and int in unquote(range) ->
        <<8::int32, int::unsigned-64>>

      other ->
        raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, unquote(range))
    end
  end

  def decode(_) do
    quote location: :keep do
      <<8::int32, int::unsigned-64>> -> int
    end
  end
end

I'm happy to come up with a PR if this is something you're interested in and if you could point me in the right direction with regards to:

  • testing without hard dependency on PostgreSQL 13
  • I noticed that xid is in fact cast by Postgrex.Extensions.OID - should this also play a role for xid8?

Thanks for considering! And thanks for all the work on the library!

Best,
malte

@josevalim
Copy link
Member

A PR is welcome, if we can handle it in OID that鈥檚 fine by me, but it may require a new type indeed or reusing another one if 64 bits.

For the PG 13 tests, you can see the existing test helpers for examples!

maltoe added a commit to maltoe/postgrex that referenced this issue Jul 11, 2021
Fixes [[elixir-ecto#558]](elixir-ecto#558)

This patch adds support for the `xid8` type introduced in PostgreSQL 13.
maltoe added a commit to maltoe/postgrex that referenced this issue Jul 11, 2021
Fixes [[elixir-ecto#558]](elixir-ecto#558)

This patch adds support for the `xid8` type introduced in PostgreSQL 13.
maltoe added a commit to maltoe/postgrex that referenced this issue Jul 11, 2021
Fixes [elixir-ecto#558](elixir-ecto#558)

This patch adds support for the `xid8` type introduced in PostgreSQL 13.
maltoe added a commit to maltoe/postgrex that referenced this issue Jul 11, 2021
Fixes [elixir-ecto#558](elixir-ecto#558)

This patch adds support for the `xid8` type introduced in PostgreSQL 13.
josevalim pushed a commit that referenced this issue Jul 11, 2021
Fixes [#558](#558)

This patch adds support for the `xid8` type introduced in PostgreSQL 13.
josevalim pushed a commit that referenced this issue Sep 26, 2021
Fixes [#558](#558)

This patch adds support for the `xid8` type introduced in PostgreSQL 13.
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

Successfully merging a pull request may close this issue.

2 participants