pg icon indicating copy to clipboard operation
pg copied to clipboard

Does it support range type?

Open muei opened this issue 9 years ago • 10 comments

If support, how to use

muei avatar Aug 05 '16 05:08 muei

Sorry, I forgot to reply to this one :/ Anyway there is no any support for range types and the biggest problem for adding support for range types is that I don't know how to represent range types in Go... Do you have any ideas?

vmihailenco avatar Aug 16 '16 17:08 vmihailenco

How about using struct tags to divide the range into two parts? You could for example use ",lower" and ",upper" in this way:

type MyRanges struct{
    Id `pg:"myrangeid"`
    AgeLower `pg:"agerange,lower"`
    AgeUpper `pg:"agerange,upper"`
}

Another idea could be to use a range interface for each type (int, tzrange and so on)

type interface IntRange {
    SetRange(lower, upper int){}
    Range() (int, int) {}
}

type MyRanges struct {
    Id int `pg:"myrangeid"`
    AgeRange IntRange `pg:"agerange"`
}

viblo avatar Nov 11 '16 03:11 viblo

Forgot about inclusive/exclusive and infinity ranges. Maybe infinity could be handle by the types built in max/min values ( math.MaxInt32 and so on?). For inclusive/exclusive its trickier. Tags get a bit complicated:

type MyRanges struct{
    Id `pg:"myrangeid"`
    AgeLower `pg:"agerange,lower"`
    AgeLowerInc bool `pg:"agerange,lower_inc"`
    AgeUpper `pg:"agerange,upper"`
    AgeUpperInc bool `pg:"agerange,upper_inc"`
}

But interface is also a bit more complicated:

type interface IntRange {
    SetRange(lower, upper int, lowerInc, upperInc bool){}
    Range() (int, int, bool, bool) {} // Is this ugly? maybe better with 4 separate functions?
}

type MyRanges struct {
    Id int `pg:"myrangeid"`
    AgeRange IntRange `pg:"agerange"`
}

viblo avatar Nov 11 '16 04:11 viblo

@vmihailenco I think we can use array. Example: [2]int [0] => lower value [1] => upper value

thanhps42 avatar Oct 23 '17 09:10 thanhps42

Is the question still open?

ilyakaznacheev avatar Apr 22 '19 22:04 ilyakaznacheev

Is the question still open?

kunsonx avatar May 13 '20 09:05 kunsonx

I am currently in need of a tstzrange (no other ranges). This had me looking into how jackc/pgtype achieved ranged timestamps.

Infinity and beyond:

pg.NullTime would require support for special values, see postgresql doc section 8.5.1.4 . For a quick start, the special values for pos/neg infinity should be enough. The NullTime struct could have a member flag reflecting if it is a special value. Support could be quite easily implemented in types.ParseTimeString and types.AppendTime.

Boundaries:

Ranged type upper and lower values are bounded, mainly inclusive or exclusive, but also unbounded in case of usage of pos/neg infinity, see postgresql doc section 8.17.3 and 8.17.4. The contributors of jackc/pgtype have done it so that they keep track of the boundary types in struct members of the range types.

Range types:

@vmihailenco

... I don't know how to represent range types in Go... Do you have any ideas?

No i do not, but the guys at jackc/pgtypes had an idea. The ranged types there have upper/lower-named struct members of the underlying range type.. The interesting (cannot comment whether that is good or not) part is, that they have a base struct

type UntypedTextRange struct {
	Lower     string
	Upper     string
	lowerType BoundType
	upperType BoundType
}

(see range.go) into which they decode all range types. Then they pass the lower/upper strings to the decoding function of the underlying range type.

Future:

I am currently hacking a quick POC ripping off some of the jackc/pgtype code to see if i understand the stuff correctly. As said, this is just a tstzrange type (all i need) using scanner/valuer.

What is your plan, @vmihailenco? Are you tempted by ranged types or is this something you are indifferent about?

Since i lack your understanding of go-pg/pg i can currently only hope to produce some bastard-code that 'sort of works for me'. If you are interested in range types and if you think that something related to the jackc/pgtype approach would be ok with you, please say so. I could then try to integrate my POC with go-pg/pg instead of just having some extra package providing a (partly redundant) custom type.

burner-account avatar Dec 03 '20 22:12 burner-account

The interesting (cannot comment whether that is good or not)

I can't tell whether it is good or not too until I try it. And I won't try it until I have a use case for it. So in practice I can't offer much help except with existing go-pg code and general code review.

the jackc/pgtype

It looks like jackc/pgtype already supports database/sql interfaces. So the chances are you can already use it with go-pg.

I could then try to integrate my POC with go-pg/pg instead of just having some extra package providing a (partly redundant) custom type.

I don't have time to work on this myself, but if you need code review - just ping me. And I don't think that extra packages are bad or inefficient in any sense. On the contrary they allow to develop independent features without any communication / organization overhead. If there are specific things I can do to ease development of 3rd party plugins - let me know and I will try to help.

vmihailenco avatar Dec 04 '20 07:12 vmihailenco

It looks like jackc/pgtype already supports database/sql interfaces. So the chances are you can already use it with go-pg.

Oh thank God for a solution. I've tested, and yes jackc/pgtype works out of the box with go-pg. I'm now assigning the type pgtype.Tstzrange type to a struct field (ie. column), and using their API to read and write the lower and upper ranges as well as the inclusive/exlusive flags. At least for my use case, so far the integration is flawless. Once you figure out the Status field of both the range as a whole as well as the individual Lower.Status and Upper.Status fields, it's smooth sailing!

frickenate avatar Apr 29 '21 10:04 frickenate

It sounds nice that jackc/pgtype works with go-pg but I just wondering if it is good idea to add it with lot of unnecessary dependency. Date and timestamp ranges are quite popular and it will be nice if go-pg can support them.

alapierre avatar May 18 '21 07:05 alapierre