2016-08-03 7 views
1

以下の誤った関数は、サーバー側でPostgis地理空間交点を処理し、クライアント側でInt64の返された配列を処理するsubdivideというプログラムの一部です。haskell postgresql-simple互換性のない型_int8およびInt64(およびInteger)

スタックの下でビルドされ、実行され、Nightly 2016-08-02に解決され、アーキテクチャx86_64が明示的に指定されます。

私は(HEREコメントランタイムエラーを参照してください)「intersectionsSql」として定義されPostgresのクエリを実行し、次のランタイムエラーを取得:

"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"} 

私はすべて同じ結果で、整数、Int64型とのIntを試してみました、ものHaskellの型として反直感的である全てのPostgreSQL、単純インスタンスドキュメントに従って_int8と適合性でなければならない:

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

SQLクエリーは[PostgresのBIGINTの単一の行を返すべきです]これは私がPGAdminで確認したものです。

アイデア?

また、コードをどのように記述したかについてのコメントは、最後にGHCで作業してから10年以上経ちましたが、変更されました。

ありがとうございました。

マイク・トーマス

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-simpleライブラリの著者であるLP Smith: "確かに_int8のアンダースコアは8バイト整数の配列なので、戻り値の型を[Only(Vector Int64)]に変更する必要がありますクエリの戻り値の型にこの変更が問題を解決しました。レオンに感謝します。 –

答えて

0

は何の答えはここに来るなかったとき、私は連絡LPスミス、から中継された上記のコメントを参照してください。それは私の問題を解決します。

私が行ったように、8バイト整数の内部表現ではなく、_int8が8バイト整数の配列を表していることが鍵となりました。 Leonの提案された変更は、上記の行の[[Int64のみ] "の[Only(Vector Int64)]をランタイムエラーのポイントに置き換えることでした。

ありがとうございました。

関連する問題