crystal-pg icon indicating copy to clipboard operation
crystal-pg copied to clipboard

Support range types

Open vladfaust opened this issue 5 years ago • 7 comments

Currently:

require "pg"

db = DB.open("postgres://postgres:postgres@localhost:5432/postgres")
pp db.scalar("SELECT int4range(10, 20)") # => Bytes

vladfaust avatar Apr 13 '19 14:04 vladfaust

I've been taking a stab at this, and can't seem to figure out where the "rules" for decoding a given message from Postgres wire format come from - @will any advice here?

miketheman avatar Oct 09 '19 19:10 miketheman

@miketheman It's in https://github.com/will/crystal-pg/blob/master/src/pg/decoder.cr

Every postgres type has an ID, called oid. A decoder can handle a series of oids. So my guess is that you'll need to define a new Int4Range decoder and register it, but then you'll also want to define a Postgres::Range type, which is different than Crystal's Range.

(this is just from me fiddling with the library, I might be wrong)

asterite avatar Oct 09 '19 19:10 asterite

@asterite Thanks - I got that far. I'm more interested in how to interpret the bytes returned from PG.

miketheman avatar Oct 09 '19 19:10 miketheman

The functions in postgres are usually ending in _send

Here is the range one I think: https://github.com/postgres/postgres/blob/b538c90b1bded5464787e2b8e4431302d24eb601/src/backend/utils/adt/rangetypes.c#L246

will avatar Oct 09 '19 19:10 will

You can also call them as functions in postgres if that helps playing around with things faster:

will=# select range_send('[1,3]'::int4range);
              range_send
--------------------------------------
 \x0200000004000000010000000400000004
(1 row)

will avatar Oct 09 '19 19:10 will

I started a Draft PR for discussion.

miketheman avatar Oct 09 '19 22:10 miketheman

I can work on this, if it is stalled. Got a prototype working, need some guidance though.

pascalbetz avatar Oct 02 '20 17:10 pascalbetz