bun icon indicating copy to clipboard operation
bun copied to clipboard

uint64 field create column with the bigint type

Open qRoC opened this issue 4 years ago • 9 comments

NewCreateTable generates a bigint column type from the uint64 model fields, but bigint is the signed 8-byte integer.

qRoC avatar Dec 15 '21 10:12 qRoC

Yes, What do you suggest?

vmihailenco avatar Dec 15 '21 11:12 vmihailenco

Must be numeric, because bigint is unsafe.

qRoC avatar Dec 15 '21 11:12 qRoC

because bigint is unsafe

Oh wow, this is interesting. What does this mean? Can you explain it to newbies like me, please?

frederikhors avatar Dec 15 '21 11:12 frederikhors

bigint is like int64 (-9223372036854775808 .. 9223372036854775807) but uint64 in range 0 .. 18446744073709551615.

So for safe usage you must:

  1. use bitcast (but select queries will be broken)
  2. use offset value-9223372036854775807 with typecast (but select queries will be broken)
  3. use bigint (possible "out of range" error on insert/update)
  4. use numeric (slow, but can contains full range)

qRoC avatar Dec 15 '21 12:12 qRoC

And why it's unsafe if you only use part of that range in go code with uint64?

frederikhors avatar Dec 15 '21 13:12 frederikhors

Why are you using uint64 when you want int64?

If I set uint64 then I need this range. The client should mirror the model in the database, and not distort it.

qRoC avatar Dec 15 '21 14:12 qRoC

It's a mirroring. And for @vmihailenco the best solution on DB is to map uint64 to bigint even if bigint is "bigger".

I don't understand why this is a problem. But I'm not angry, I'm really curious to understand even from the amazing master @vmihailenco.

frederikhors avatar Dec 15 '21 14:12 frederikhors

@frederikhors bigint is "lower", "numeric" is "bigger". (see https://github.com/uptrace/bun/issues/359#issuecomment-994751260)

And my proposal - use numeric instead bigint for uint64.

qRoC avatar Dec 15 '21 15:12 qRoC

Bun casts uint64 to int64 when appending the data - see https://github.com/uptrace/bun/blob/master/dialect/pgdialect/dialect.go#L83-L89 . So it works but the order by can be broken for large values.

I actually use uint64 with PostgreSQL and bigint, because some models are shared between different databases (ClickHouse) and in those databases uint64 is fully supported. And I don't use those fields for sorting.

That said, we should allow users to specify type:numeric and change Bun to append unsigned numbers without casting. But the default will remain as is.

vmihailenco avatar Dec 16 '21 07:12 vmihailenco