@@ -63,10 +63,11 @@ data TypeInfo = TypeInfo
63
63
, typdelim :: Char
64
64
, typname :: ByteString
65
65
, typelem :: Oid
66
+ , rngsubtype :: Maybe Oid
66
67
}
67
68
68
- instance FromRow TypeInfo where
69
- fromRow = TypeInfo <$> field <*> field <*> field <*> field <*> field
69
+ instance FromRow TypeInfo where
70
+ fromRow = TypeInfo <$> field <*> field <*> field <*> field <*> field <*> field
70
71
71
72
type NameMap = Map. Map B. ByteString TypeInfo
72
73
@@ -176,6 +177,18 @@ _varbit array_varbit
176
177
_refcursor array_refcursor
177
178
_uuid array_uuid
178
179
_jsonb array_jsonb
180
+ int4range
181
+ _int4range
182
+ numrange
183
+ _numrange
184
+ tsrange
185
+ _tsrange
186
+ tstzrange
187
+ _tstzrange
188
+ daterange
189
+ _daterange
190
+ int8range
191
+ _int8range
179
192
|]
180
193
181
194
instance IsString Blaze. Builder where
@@ -187,28 +200,31 @@ withPostgreSQL = bracket (connectPostgreSQL connectionString) close
187
200
188
201
getTypeInfos :: TypeNames -> IO (OidMap , NameMap )
189
202
getTypeInfos typnames = withPostgreSQL $ \ conn -> do
190
- infos <- query conn [sql |
191
- SELECT oid, typcategory, typdelim, typname, typelem
192
- FROM pg_type
193
- WHERE typname IN ?
194
- |]
195
- (Only (In (sort (map pg typnames))))
203
+ infos <- query conn [sql |
204
+ WITH types AS
205
+ (SELECT oid, typcategory, typdelim, typname, typelem
206
+ FROM pg_type WHERE typname IN ?)
207
+ SELECT types.*, rngsubtype FROM types LEFT JOIN pg_range ON oid = rngtypid
208
+ |] (Only (In (sort (map pg typnames))))
196
209
loop conn (oidMap infos) (nameMap infos) infos
197
210
where
198
211
oidMap = Map. fromList . map (typoid &&& id )
199
212
nameMap = Map. fromList . map (typname &&& id )
200
213
loop conn oids names infos = do
201
- let unknowns = [ x | x <- map typelem infos,
214
+ let unknowns = [ x | x <- map typelem infos ++
215
+ [ x | Just x <- map rngsubtype infos ],
202
216
x /= Oid 0 ,
203
217
not (Map. member x oids) ]
204
218
case unknowns of
205
219
[] -> return (oids, names)
206
220
(_: _) -> do
207
221
infos' <- query conn [sql |
208
- SELECT oid, typcategory, typdelim, typname, typelem
209
- FROM pg_type
210
- WHERE oid IN ?
211
- |] (Only (In (sort unknowns)))
222
+ WITH types AS
223
+ (SELECT oid, typcategory, typdelim, typname, typelem
224
+ FROM pg_type WHERE oid IN ?)
225
+ SELECT types.*, rngsubtype
226
+ FROM types LEFT JOIN pg_range ON oid = rngtypid
227
+ |] (Only (In (sort unknowns)))
212
228
let oids' = oids `Map.union` oidMap infos'
213
229
names' = names `Map.union` nameMap infos'
214
230
loop conn oids' names' infos'
@@ -239,9 +255,13 @@ renderTypeInfo :: OidMap -> TypeInfo -> TypeName -> Blaze.Builder
239
255
renderTypeInfo byOid info name
240
256
| typcategory info == ' A' || typname info == " _record" =
241
257
let (Just typelem_info) = Map. lookup (typelem info) byOid
242
- typelem_hs_name = case lookup (typname typelem_info) typeNames of
243
- Nothing -> error (" type not found: " ++ B. unpack( typname typelem_info) ++ " (typelem of " ++ B. unpack (typname info) ++ " )" )
244
- Just x -> x
258
+ typelem_hs_name =
259
+ case lookup (typname typelem_info) typeNames of
260
+ Nothing -> error ( " type not found: "
261
+ ++ B. unpack( typname typelem_info)
262
+ ++ " (typelem of " ++ B. unpack (typname info)
263
+ ++ " )" )
264
+ Just x -> x
245
265
in concat
246
266
[ " \n "
247
267
, bs (hs name), " :: TypeInfo\n "
@@ -253,7 +273,27 @@ renderTypeInfo byOid info name
253
273
, " typelem = " , bs typelem_hs_name, " \n "
254
274
, " }\n "
255
275
]
256
- | typcategory info == ' R' = undefined
276
+ | typcategory info == ' R' =
277
+ let (Just rngsubtype_oid) = rngsubtype info
278
+ (Just rngsubtype_info) = Map. lookup rngsubtype_oid byOid
279
+ rngsubtype_hs_name =
280
+ case lookup (typname rngsubtype_info) typeNames of
281
+ Nothing -> error ( " type not found: "
282
+ ++ B. unpack (typname rngsubtype_info)
283
+ ++ " (rngsubtype of "
284
+ ++ B. unpack (typname info) ++ " )" )
285
+ Just x -> x
286
+ in concat
287
+ [ " \n "
288
+ , bs (hs name), " :: TypeInfo\n "
289
+ , bs (hs name), " = Range {\n "
290
+ , " typoid = " , fromString (show (typoid info)), " ,\n "
291
+ , " typcategory = '" , Blaze. fromChar (typcategory info), " ',\n "
292
+ , " typdelim = '" , Blaze. fromChar (typdelim info), " ',\n "
293
+ , " typname = \" " , bs (typname info), " \" ,\n "
294
+ , " rngsubtype = " , bs rngsubtype_hs_name, " \n "
295
+ , " }\n "
296
+ ]
257
297
| otherwise =
258
298
concat
259
299
[ " \n "
0 commit comments