Ошибка совместимости типа count(*) с Database.PostgreSQL.Simple?

Ошибка

*** Exception: Incompatible {errSQLType = "int8", errHaskellType = "Int", errMessage = "types incompatible"}

Похоже, любое значение, возвращаемое count(*) в запросе должны быть преобразованы в Integer скорее, чем Int, Если я изменю эти конкретные переменные на тип Integer, запросы будут работать.

Но эта ошибка не возникала на другой машине с таким же точным кодом. Первая машина была 32-битной, а другая - 64-битной. Это единственное отличие, которое я мог различить.

У кого-нибудь есть понимание того, что происходит?

2 ответа

Решение

Функции count () в PostgreSQL возвращают тип Bigint, см.

http://www.postgresql.org/docs/9.2/static/functions-aggregate.html

Bigint составляет 8 байт, см. http://www.postgresql.org/docs/9.2/static/datatype-numeric.html

Haskell int равен ~ 2**29, что подразумевает 4-байтовое целое число.

http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Int.html

Тогда это нормально, что PostgreSQL или его API не будут выполнять неявное преобразование с понижением точности.

Так что используйте тип Haskell int64 или число приведения (*) к целому числу.

Как описано в модуле FromField, postgresql-simple будет выполнять преобразование на стороне клиента между числовыми типами, только когда нет никакой возможности переполнения или потери точности. Обратите особое внимание на список типов в пикшах для instance FromField Int: "int2, int4, и если скомпилировано как 64-битный код, так и int8. Эта библиотека была скомпилирована как 32-битный код." Последняя часть этого комментария, конечно, специфична для сборки, которую выполняет сам хакер.

На 32-битных платформах, Int является 32-разрядным целым числом, и на 64-разрядных платформах, Int является 64-битным целым числом Если вы используете Int32 вы получите то же исключение. Ты можешь использовать Int64 или произвольная точность Integer типа, чтобы избежать этой проблемы на обоих видах платформ.

Другие вопросы по тегам