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