2016-08-03 2 views
1

Эта ошибочная функция ниже является частью программы, называемой подразделением, работающей с геопространственными пересечениями Postgis на стороне сервера и обработкой возвращаемого массива Int64 на стороне клиента.haskell postgresql-simple несовместимый тип _int8 и Int64 (и целочисленный)

Он построен и работает под стеком, разрешая Nightly 2016-08-02 и явно указывая архитектуру x86_64.

Я получаю следующее сообщение об ошибке во время выполнения выполнения запроса Postgres определяется как «intersectionsSql» (см комментарий RUNTIME ОШИБКИ ЗДЕСЬ):

"Created table: server : [Only {fromOnly = \"PostgreSQL 9.6beta2 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit\"}] quadrant: BOX3D(-180.0 90.0, -90.0 45.0)" 
subdivide: Incompatible {errSQLType = "_int8", errSQLTableOid = Nothing, errSQLField = "object_ids", errHaskellType = "Int64", errMessage = "types incompatible"} 

Я пытался Integer, Int64 и Int, все с тем же результатом, который является нелогичным, как те типы Haskell все должны быть совместимы с _int8 в соответствии с PostgreSQL-простой экземпляра документации:

https://hackage.haskell.org/package/postgresql-simple-0.5.0.0/candidate/docs/Database-PostgreSQL-Simple-FromField.html

запрос SQL должен возвращать одну строку POSTGRES BIGINT [] , который я подтвердил через PGAdmin.

Любые идеи?

Также любые комментарии по поводу того, как я написал код - его более десяти лет с тех пор, как я работал с GHC, и времена изменились.

Благодарим за внимание.

Майк Томас

accumulateIntersections :: Identifier -> Identifier -> ConnectInfo -> ((Double,Double),(Double,Double)) -> IO() 
accumulateIntersections sourceTable accumulationTable connectionInfo q = 
let 
    theBox = makeBox3D (fst (fst q)) (snd (fst q)) (fst (snd q)) (snd (snd q)) 
    theValue = (Only theBox) 
    dropTable = [sql| DROP TABLE IF EXISTS ? CASCADE |] 
    createTable = [sql| CREATE TABLE ? (quadrant_id BIGSERIAL, area_metres_squared FLOAT8, shape GEOMETRY, object_ids BIGINT[]) |] 
    aggregateSql = [sql| DROP AGGREGATE IF EXISTS _array_agg (anyarray); 
         CREATE AGGREGATE _array_agg(anyarray) (SFUNC = array_cat, STYPE = anyarray); 
         |] 
    intersectionsSql = [sql| SELECT _array_agg (object_ids) object_ids 
          FROM ? 
          WHERE ST_Intersects(ST_SetSRID (?::box3d, 4326), shape) 
          |] 
    insertIntersections = [sql| INSERT INTO ? (shape, object_ids) 
           VALUES (ST_SetSRID (?::box3d, 4326) 
             , ?) |] 
in 
do 
    connection <- connect connectionInfo 
    execute_ connection aggregateSql 
    postgresVersion <- (query_ connection "SELECT version()" :: IO [Only String]) 
    i0 <- execute connection dropTable (Only accumulationTable) 
    i1 <- execute connection createTable (Only accumulationTable) 
    print ("Created table: server : " ++ (show postgresVersion) ++ " quadrant: " ++ theBox) 
    is :: [Only Int64] <- query connection intersectionsSql (sourceTable, theBox) -- RUNTIME ERROR HERE 
    print ("Intersections done.") 
    ids::[Int64] <- forM is (\(Only id) -> return id) 
    print ("Ids done.") 
    close connection 
    return() 
+0

От автора PostgreSQL-простой библиотеки - LP Smith: «Конечно, подчеркивание в _int8 означает, что это массив из 8-байтовых целых чисел. Поэтому вам нужно изменить тип возврата на [Only (Vector Int64)]" Это изменение типа возвращаемого запроса разрешило проблему. Спасибо, Леон. –

ответ

0

Смотрите выше комментарий ретрансляционного от LP Смита, который я связался, когда нет ответов не были предстоящими здесь. Он решает мою проблему.

Ключ должен был признать, что _int8 представляет массив из 8 байтовых целых чисел, а не мышления, как я и сделал, что это внутреннее представление для одного 8-байтового целого. Предполагаемое изменение Леона заключалось в том, чтобы заменить «[Only (Vector Int64)]» ​​для «[Только Int64]» в строке, отмеченной выше, в качестве точки ошибки времени выполнения.

Спасибо Leon.

Смежные вопросы