diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,18 @@
 # Revision history for hiedb
 
+## 0.4.0.0 -- 2021-06-29
+
+* Index module exports
+* New queries `getAllIndexedExports`, `getExportsForModule`, and `findExporters`
+* Support for ghc-9.0
+* An new `addRefsFromLoaded_unsafe` to index a module with cleanup or transactional behaviour
+* Include test data in source tarball
+* Use terminal-size for printing in some cases, making verbose indexing faster in some cases
+
 ## 0.3.0.1 -- 2021-01-27
 
 * Add additional sqlite indexes to prevent accidently quadratic behaviour while indexing
-  
+
 ## 0.3.0.0 -- 2021-01-20
 
 * Introduce `SourceFile` type
diff --git a/hiedb.cabal b/hiedb.cabal
--- a/hiedb.cabal
+++ b/hiedb.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                hiedb
-version:             0.3.0.1
+version:             0.4.0.0
 synopsis:            Generates a references DB from .hie files
 description:         Tool and library to index and query a collection of `.hie` files
 bug-reports:         https://github.com/wz1000/HieDb/issues
@@ -13,6 +13,11 @@
 extra-source-files:
   CHANGELOG.md
   README.md
+  test/data/*.hs
+  test/data/Sub/*.hs
+tested-with:         GHC ==8.8.1 || ==8.8.2  || ==8.8.3  || ==8.8.4
+                     || ==8.10.1 || ==8.10.2 || ==8.10.3 || ==8.10.4
+                     || ==9.0.1
 
 
 source-repository head
@@ -21,7 +26,7 @@
 
 common common-options
   default-language:    Haskell2010
-  build-depends:       base >= 4.12 && < 4.15
+  build-depends:       base >= 4.12 && < 4.16
   ghc-options:         -Wall
                        -Wincomplete-uni-patterns
                        -Wincomplete-record-updates
@@ -45,6 +50,7 @@
                        HieDb.Utils,
                        HieDb.Create,
                        HieDb.Query,
+                       HieDb.Compat,
                        HieDb.Types,
                        HieDb.Dump,
                        HieDb.Html,
@@ -64,6 +70,9 @@
                      , optparse-applicative
                      , extra
                      , ansi-terminal
+                     , terminal-size
+  if impl(ghc >= 9.0)
+    build-depends: ghc-api-compat
 
 test-suite hiedb-tests
   import:             common-options
@@ -80,3 +89,5 @@
                     , hspec
                     , process
                     , temporary
+  if impl(ghc >= 9.0)
+    build-depends: ghc-api-compat
diff --git a/src/HieDb/Compat.hs b/src/HieDb/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/HieDb/Compat.hs
@@ -0,0 +1,58 @@
+
+{-# LANGUAGE CPP #-}
+module HieDb.Compat (
+    nodeInfo'
+    , Unit
+    , unitString
+    , stringToUnit
+    , moduleUnit
+    , unhelpfulSpanFS
+
+) where
+
+import Compat.HieTypes
+
+import Module
+
+#if __GLASGOW_HASKELL__ >= 900
+import GHC.Types.SrcLoc
+import Compat.HieUtils
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+
+-- nodeInfo' :: Ord a => HieAST a -> NodeInfo a
+nodeInfo' :: HieAST TypeIndex -> NodeInfo TypeIndex
+nodeInfo' = M.foldl' combineNodeInfo' emptyNodeInfo . getSourcedNodeInfo . sourcedNodeInfo
+
+combineNodeInfo' :: Ord a => NodeInfo a -> NodeInfo a -> NodeInfo a
+(NodeInfo as ai ad) `combineNodeInfo'` (NodeInfo bs bi bd) =
+  NodeInfo (S.union as bs) (mergeSorted ai bi) (M.unionWith (<>) ad bd)
+  where
+    mergeSorted :: Ord a => [a] -> [a] -> [a]
+    mergeSorted la@(a:as) lb@(b:bs) = case compare a b of
+                                        LT -> a : mergeSorted as lb
+                                        EQ -> a : mergeSorted as bs
+                                        GT -> b : mergeSorted la bs
+    mergeSorted as [] = as
+    mergeSorted [] bs = bs
+#else
+import qualified FastString as FS
+
+nodeInfo' :: HieAST TypeIndex -> NodeInfo TypeIndex
+nodeInfo' = nodeInfo
+type Unit = UnitId
+unitString :: Unit -> String
+unitString = unitIdString
+stringToUnit :: String -> Unit
+stringToUnit = stringToUnitId
+moduleUnit :: Module -> Unit
+moduleUnit = moduleUnitId
+unhelpfulSpanFS :: FS.FastString -> FS.FastString
+unhelpfulSpanFS = id
+#endif
+
+#if __GLASGOW_HASKELL__ >= 900
+#else
+#endif
diff --git a/src/HieDb/Create.hs b/src/HieDb/Create.hs
--- a/src/HieDb/Create.hs
+++ b/src/HieDb/Create.hs
@@ -32,11 +32,13 @@
 
 import Database.SQLite.Simple
 
+import HieDb.Compat
 import HieDb.Types
 import HieDb.Utils
+import FastString  as FS      ( FastString )
 
 sCHEMA_VERSION :: Integer
-sCHEMA_VERSION = 5
+sCHEMA_VERSION = 6
 
 dB_VERSION :: Integer
 dB_VERSION = read (show sCHEMA_VERSION ++ "999" ++ show hieVersion)
@@ -60,7 +62,7 @@
 withHieDb :: FilePath -> (HieDb -> IO a) -> IO a
 withHieDb fp f = withConnection fp (checkVersion f . HieDb)
 
-{-| Given GHC LibDir and path to @.hiedb@ file, 
+{-| Given GHC LibDir and path to @.hiedb@ file,
 constructs DynFlags (required for printing info from @.hie@ files)
 and 'HieDb' and passes them to given function.
 -}
@@ -90,6 +92,19 @@
                 \)"
   execute_ conn "CREATE INDEX IF NOT EXISTS mod_hash ON mods(hieFile,hash)"
 
+  execute_ conn "CREATE TABLE IF NOT EXISTS exports \
+                \( hieFile TEXT NOT NULL \
+                \, occ     TEXT NOT NULL \
+                \, mod     TEXT NOT NULL \
+                \, unit    TEXT NOT NULL \
+                \, parent  TEXT \
+                \, parentMod TEXT \
+                \, parentUnit TEXT \
+                \, is_datacon BOOL NOT NULL \
+                \, FOREIGN KEY(hieFile) REFERENCES mods(hieFile) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED \
+                \)"
+  execute_ conn "CREATE INDEX IF NOT EXISTS exports_mod ON exports(hieFile)"
+
   execute_ conn "CREATE TABLE IF NOT EXISTS refs \
                 \( hieFile TEXT NOT NULL \
                 \, occ     TEXT NOT NULL \
@@ -150,7 +165,7 @@
   execute_ conn "CREATE INDEX IF NOT EXISTS typerefs_mod ON typerefs(hieFile)"
 
 {-| Add names of types from @.hie@ file to 'HieDb'.
-Returns an Array mapping 'TypeIndex' to database ID assigned to the 
+Returns an Array mapping 'TypeIndex' to database ID assigned to the
 corresponding record in DB.
 -}
 addArr :: HieDb -> A.Array TypeIndex HieTypeFlat -> IO (A.Array TypeIndex (Maybe Int64))
@@ -166,7 +181,7 @@
       Just m -> do
         let occ = nameOccName n
             mod = moduleName m
-            uid = moduleUnitId m
+            uid = moduleUnit m
         execute conn "INSERT INTO typenames(name,mod,unit) VALUES (?,?,?)" (occ,mod,uid)
         Just . fromOnly . head <$> query conn "SELECT id FROM typenames WHERE name = ? AND mod = ? AND unit = ?" (occ,mod,uid)
 
@@ -179,7 +194,9 @@
   -> IO ()
 addTypeRefs db path hf ixs = mapM_ addTypesFromAst asts
   where
+    arr :: A.Array TypeIndex HieTypeFlat
     arr = hie_types hf
+    asts :: M.Map FS.FastString (HieAST TypeIndex)
     asts = getAsts $ hie_asts hf
     addTypesFromAst :: HieAST TypeIndex -> IO ()
     addTypesFromAst ast = do
@@ -187,7 +204,7 @@
         $ mapMaybe (\x -> guard (any (not . isOccurrence) (identInfo x)) *> identType x)
         $ M.elems
         $ nodeIdentifiers
-        $ nodeInfo ast
+        $ nodeInfo' ast
       mapM_ addTypesFromAst $ nodeChildren ast
 
 {-| Adds all references from given @.hie@ file to 'HieDb'.
@@ -214,12 +231,33 @@
   -> Fingerprint -- ^ The hash of the @.hie@ file
   -> HieFile -- ^ Data loaded from the @.hie@ file
   -> m ()
-addRefsFromLoaded db@(getConn -> conn) path sourceFile hash hf = liftIO $ withTransaction conn $ do
-  deleteInternalTables conn path
+addRefsFromLoaded
+  db@(getConn -> conn) path sourceFile hash hf =
+    liftIO $ withTransaction conn $ do
+      deleteInternalTables conn path
+      addRefsFromLoaded_unsafe db path sourceFile hash hf
 
+-- | Like 'addRefsFromLoaded' but without:
+--   1) using a transaction
+--   2) cleaning up previous versions of the file
+--
+--   Mostly useful to index a new database from scratch as fast as possible
+addRefsFromLoaded_unsafe
+  :: MonadIO m
+  => HieDb -- ^ HieDb into which we're adding the file
+  -> FilePath -- ^ Path to @.hie@ file
+  -> SourceFile -- ^ Path to .hs file from which @.hie@ file was created
+                -- Also tells us if this is a real source file?
+                -- i.e. does it come from user's project (as opposed to from project's dependency)?
+  -> Fingerprint -- ^ The hash of the @.hie@ file
+  -> HieFile -- ^ Data loaded from the @.hie@ file
+  -> m ()
+addRefsFromLoaded_unsafe
+ db@(getConn -> conn) path sourceFile hash hf = liftIO $ do
+
   let isBoot = "boot" `isSuffixOf` path
       mod    = moduleName smod
-      uid    = moduleUnitId smod
+      uid    = moduleUnit smod
       smod   = hie_module hf
       refmap = generateReferencesMap $ getAsts $ hie_asts hf
       (srcFile, isReal) = case sourceFile of
@@ -236,6 +274,9 @@
   let defs = genDefRow path smod refmap
   executeMany conn "INSERT INTO defs VALUES (?,?,?,?,?,?)" defs
 
+  let exports = generateExports path $ hie_exports hf
+  executeMany conn "INSERT INTO exports VALUES (?,?,?,?,?,?,?,?)" exports
+
   ixs <- addArr db (hie_types hf)
   addTypeRefs db path hf ixs
 
@@ -243,7 +284,7 @@
 No action is taken if the corresponding @.hie@ file has not been indexed yet.
 -}
 addSrcFile
-  :: HieDb 
+  :: HieDb
   -> FilePath -- ^ Path to @.hie@ file
   -> FilePath -- ^ Path to .hs file to be added to DB
   -> Bool -- ^ Is this a real source file? I.e. does it come from user's project (as opposed to from project's dependency)?
@@ -284,3 +325,4 @@
   execute conn "DELETE FROM defs  WHERE hieFile = ?" (Only path)
   execute conn "DELETE FROM typerefs WHERE hieFile = ?" (Only path)
   execute conn "DELETE FROM mods  WHERE hieFile = ?" (Only path)
+  execute conn "DELETE FROM exports WHERE hieFile = ?" (Only path)
diff --git a/src/HieDb/Query.hs b/src/HieDb/Query.hs
--- a/src/HieDb/Query.hs
+++ b/src/HieDb/Query.hs
@@ -12,7 +12,7 @@
 
 import           GHC
 import           Compat.HieTypes
-import           Module
+-- import           Module
 import           Name
 
 import           System.Directory
@@ -33,6 +33,7 @@
 import Database.SQLite.Simple
 
 import           HieDb.Dump (sourceCode)
+import           HieDb.Compat
 import           HieDb.Types
 import           HieDb.Utils
 import qualified HieDb.Html as Html
@@ -41,11 +42,25 @@
 getAllIndexedMods :: HieDb -> IO [HieModuleRow]
 getAllIndexedMods (getConn -> conn) = query_ conn "SELECT * FROM mods"
 
-{-| Lookup UnitId associated with given ModuleName.
+{-| List all module exports -}
+getAllIndexedExports :: HieDb -> IO [(ExportRow)]
+getAllIndexedExports (getConn -> conn) = query_ conn "SELECT * FROM exports"
+
+{-| List all exports of the given module -}
+getExportsForModule :: HieDb -> ModuleName -> IO [ExportRow]
+getExportsForModule (getConn -> conn) mn =
+  query conn "SELECT exports.* FROM exports JOIN mods USING (hieFile) WHERE mods.mod = ?" (Only mn)
+
+{-| Find all the modules that export an identifier |-}
+findExporters :: HieDb -> OccName -> ModuleName -> Unit -> IO [ModuleName]
+findExporters (getConn -> conn) occ mn unit =
+  query conn "SELECT mods.mod FROM exports JOIN mods USING (hieFile) WHERE occ = ? AND mod = ? AND unit = ?" (occ, mn, unit)
+
+{-| Lookup Unit associated with given ModuleName.
 HieDbErr is returned if no module with given name has been indexed
 or if ModuleName is ambiguous (i.e. there are multiple packages containing module with given name)
 -}
-resolveUnitId :: HieDb -> ModuleName -> IO (Either HieDbErr UnitId)
+resolveUnitId :: HieDb -> ModuleName -> IO (Either HieDbErr Unit)
 resolveUnitId (getConn -> conn) mn = do
   luid <- query conn "SELECT mod, unit, is_boot, hs_src, is_real, hash FROM mods WHERE mod = ? and is_boot = 0" (Only mn)
   return $ case luid of
@@ -53,7 +68,7 @@
     [x] -> Right $ modInfoUnit x
     (x:xs) -> Left $ AmbiguousUnitId $ x :| xs
 
-findReferences :: HieDb -> Bool -> OccName -> Maybe ModuleName -> Maybe UnitId -> [FilePath] -> IO [Res RefRow]
+findReferences :: HieDb -> Bool -> OccName -> Maybe ModuleName -> Maybe Unit -> [FilePath] -> IO [Res RefRow]
 findReferences (getConn -> conn) isReal occ mn uid exclude =
   queryNamed conn thisQuery ([":occ" := occ, ":mod" := mn, ":unit" := uid, ":real" := isReal] ++ excludedFields)
   where
@@ -65,8 +80,8 @@
             \((NOT :real) OR (mods.is_real AND mods.hs_src IS NOT NULL))"
       <> " AND mods.hs_src NOT IN (" <> Query (T.intercalate "," (map (\(l := _) -> l) excludedFields)) <> ")"
 
-{-| Lookup 'HieModule' row from 'HieDb' given its 'ModuleName' and 'UnitId' -}
-lookupHieFile :: HieDb -> ModuleName -> UnitId -> IO (Maybe HieModuleRow)
+{-| Lookup 'HieModule' row from 'HieDb' given its 'ModuleName' and 'Unit' -}
+lookupHieFile :: HieDb -> ModuleName -> Unit -> IO (Maybe HieModuleRow)
 lookupHieFile (getConn -> conn) mn uid = do
   files <- query conn "SELECT * FROM mods WHERE mod = ? AND unit = ? AND is_boot = 0" (mn, uid)
   case files of
@@ -89,7 +104,7 @@
             ++ show fp ++ ". Entries: "
             ++ intercalate ", " (map (show . toRow) xs)
 
-findTypeRefs :: HieDb -> Bool -> OccName -> Maybe ModuleName -> Maybe UnitId -> [FilePath] -> IO [Res TypeRef]
+findTypeRefs :: HieDb -> Bool -> OccName -> Maybe ModuleName -> Maybe Unit -> [FilePath] -> IO [Res TypeRef]
 findTypeRefs (getConn -> conn) isReal occ mn uid exclude
   = queryNamed conn thisQuery ([":occ" := occ, ":mod" := mn, ":unit" := uid, ":real" := isReal] ++ excludedFields)
   where
@@ -103,14 +118,14 @@
       <> " AND mods.hs_src NOT IN (" <> Query (T.intercalate "," (map (\(l := _) -> l) excludedFields)) <> ")"
       <> " ORDER BY typerefs.depth ASC"
 
-findDef :: HieDb -> OccName -> Maybe ModuleName -> Maybe UnitId -> IO [Res DefRow]
+findDef :: HieDb -> OccName -> Maybe ModuleName -> Maybe Unit -> IO [Res DefRow]
 findDef conn occ mn uid
   = queryNamed (getConn conn) "SELECT defs.*, mods.mod,mods.unit,mods.is_boot,mods.hs_src,mods.is_real,mods.hash \
                               \FROM defs JOIN mods USING (hieFile) \
                               \WHERE occ = :occ AND (:mod IS NULL OR mod = :mod) AND (:unit IS NULL OR unit = :unit)"
                               [":occ" := occ,":mod" := mn, ":unit" := uid]
 
-findOneDef :: HieDb -> OccName -> Maybe ModuleName -> Maybe UnitId -> IO (Either HieDbErr (Res DefRow))
+findOneDef :: HieDb -> OccName -> Maybe ModuleName -> Maybe Unit -> IO (Either HieDbErr (Res DefRow))
 findOneDef conn occ mn muid = wrap <$> findDef conn occ mn muid
   where
     wrap [x]    = Right x
@@ -126,7 +141,7 @@
                          \LIMIT 200" (Only $ '_':cs++"%")
 
 {-| @withTarget db t f@ runs function @f@ with HieFile specified by HieTarget @t@.
-In case the target is given by ModuleName (and optionally UnitId) it is first resolved
+In case the target is given by ModuleName (and optionally Unit) it is first resolved
 from HieDb, which can lead to error if given file is not indexed/Module name is ambiguous.
 -}
 withTarget
@@ -151,8 +166,8 @@
       nc <- newIORef =<< makeNc
       runDbM nc $ do
         Right <$> withHieFile fp' (return . f)
-  
 
+
 type Vertex = (String, String, String, Int, Int, Int, Int)
 
 declRefs :: HieDb -> IO ()
@@ -197,7 +212,7 @@
     one s = do
       let n = toNsChar (occNameSpace $ symName s) : occNameString (symName s)
           m = moduleNameString $ moduleName $ symModule s
-          u = unitIdString (moduleUnitId $ symModule s)
+          u = unitString (moduleUnit $ symModule s)
       query conn "SELECT mods.mod, decls.hieFile, decls.occ, decls.sl, decls.sc, decls.el, decls.ec \
                  \FROM decls JOIN mods USING (hieFile) \
                  \WHERE ( decls.occ = ? AND mods.mod = ? AND mods.unit = ? ) " (n, m, u)
@@ -224,9 +239,9 @@
         m2 = foldl' (f Html.Unreachable) m1        us
     return m2
   where
-    f :: Html.Color 
-      -> Map FilePath (ModuleName, Set Html.Span) 
-      -> Vertex 
+    f :: Html.Color
+      -> Map FilePath (ModuleName, Set Html.Span)
+      -> Vertex
       -> Map FilePath (ModuleName, Set Html.Span)
     f c m v =
         let (fp, mod', sp) = g c v
diff --git a/src/HieDb/Run.hs b/src/HieDb/Run.hs
--- a/src/HieDb/Run.hs
+++ b/src/HieDb/Run.hs
@@ -1,8 +1,10 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE ViewPatterns #-}
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE RecordWildCards #-}
 module HieDb.Run where
 
 import Prelude hiding (mod)
@@ -11,7 +13,6 @@
 import Compat.HieTypes
 import Compat.HieUtils
 import Name
-import Module
 import Outputable ((<+>),hang,showSDoc,ppr,text)
 import IfaceType (IfaceType)
 
@@ -30,6 +31,7 @@
 import System.Time.Extra
 
 import System.Console.ANSI
+import System.Console.Terminal.Size
 
 import Control.Monad
 import Control.Monad.IO.Class
@@ -47,7 +49,9 @@
 import Options.Applicative
 
 import HieDb
+import HieDb.Compat
 import HieDb.Dump
+import Text.Printf (printf)
 
 hiedbMain :: LibDir -> IO ()
 hiedbMain libdir = do
@@ -85,15 +89,16 @@
 data Command
   = Init
   | Index [FilePath]
-  | NameRefs String (Maybe ModuleName) (Maybe UnitId)
-  | TypeRefs String (Maybe ModuleName) (Maybe UnitId)
-  | NameDef  String (Maybe ModuleName) (Maybe UnitId)
-  | TypeDef  String (Maybe ModuleName) (Maybe UnitId)
+  | NameRefs String (Maybe ModuleName) (Maybe Unit)
+  | TypeRefs String (Maybe ModuleName) (Maybe Unit)
+  | NameDef  String (Maybe ModuleName) (Maybe Unit)
+  | TypeDef  String (Maybe ModuleName) (Maybe Unit)
   | Cat HieTarget
   | Ls
+  | LsExports (Maybe ModuleName)
   | Rm [HieTarget]
   | ModuleUIDs ModuleName
-  | LookupHieFile ModuleName (Maybe UnitId)
+  | LookupHieFile ModuleName (Maybe Unit)
   | RefsAtPoint  HieTarget (Int,Int) (Maybe (Int,Int))
   | TypesAtPoint HieTarget (Int,Int) (Maybe (Int,Int))
   | DefsAtPoint  HieTarget (Int,Int) (Maybe (Int,Int))
@@ -155,6 +160,8 @@
                          $ progDesc "Dump contents of MODULE as stored in the hiefile")
   <> command "ls" (info (pure Ls)
                          $ progDesc "List all indexed files/modules")
+  <> command "ls-exports" (info (LsExports <$> optional moduleNameParser)
+                         $ progDesc "List all exports")
   <> command "rm" (info (Rm <$> many hieTarget)
                          $ progDesc "Remove targets from index")
   <> command "module-uids" (info (ModuleUIDs <$> moduleNameParser)
@@ -194,9 +201,9 @@
 posParser :: Char -> Parser (Int,Int)
 posParser c = (,) <$> argument auto (metavar $ c:"LINE") <*> argument auto (metavar $ c:"COL")
 
-maybeUnitId :: Parser (Maybe UnitId)
+maybeUnitId :: Parser (Maybe Unit)
 maybeUnitId =
-  optional (stringToUnitId <$> strOption (short 'u' <> long "unit-id" <> metavar "UNITID"))
+  optional (stringToUnit <$> strOption (short 'u' <> long "unit-id" <> metavar "UNITID"))
 
 symbolParser :: Parser Symbol
 symbolParser = argument auto $ metavar "SYMBOL"
@@ -211,7 +218,7 @@
 
 progress :: Handle -> Int -> Int -> (FilePath -> DbMonad Bool) -> FilePath -> DbMonad Bool
 progress hndl total cur act f = do
-  mw <- fmap snd <$> liftIO getTerminalSize
+  mw <- liftIO $ fmap width <$> size
   let msg' = unwords ["Processing file", show (cur + 1) ++ "/" ++ show total ++ ":", f] ++ "..."
   msg <- liftIO $ case mw of
     Nothing -> hPutStrLn hndl "" >> pure msg'
@@ -298,7 +305,15 @@
         putStr "\t"
         putStr $ moduleNameString $ modInfoName $ hieModInfo mod
         putStr "\t"
-        putStrLn $ unitIdString $ modInfoUnit $ hieModInfo mod
+        putStrLn $ unitString $ modInfoUnit $ hieModInfo mod
+    LsExports mn -> do
+      exports <- maybe (getAllIndexedExports conn) (getExportsForModule conn) mn
+      forM_ exports $ \ExportRow{..} -> do
+        putStr exportHieFile
+        putStr "\t"
+        case exportParent of
+          Nothing -> putStrLn $ occNameString exportName
+          Just p -> printf "%s(%s)\n" (occNameString p) (occNameString exportName)
     Rm targets -> do
         forM_ targets $ \target -> do
           case target of
@@ -329,7 +344,7 @@
             Nothing -> return $ Left (NotIndexed mn $ Just uid)
             Just x -> Right <$> putStrLn (hieModuleHieFile x)
     RefsAtPoint target sp mep -> hieFileCommand conn opts target $ \hf -> do
-      let names = concat $ pointCommand hf sp mep $ rights . M.keys . nodeIdentifiers . nodeInfo
+      let names = concat $ pointCommand hf sp mep $ rights . M.keys . nodeIdentifiers . nodeInfo'
       when (null names) $
         reportAmbiguousErr opts (Left $ NoNameAtPoint target sp)
       forM_ names $ \name -> do
@@ -338,7 +353,7 @@
           hPutStrLn stderr ""
         case nameModule_maybe name of
           Just mod -> do
-            reportRefs opts =<< findReferences conn False (nameOccName name) (Just $ moduleName mod) (Just $ moduleUnitId mod) []
+            reportRefs opts =<< findReferences conn False (nameOccName name) (Just $ moduleName mod) (Just $ moduleUnit mod) []
           Nothing -> do
             let refmap = generateReferencesMap (getAsts $ hie_asts hf)
                 refs = map (toRef . fst) $ M.findWithDefault [] (Right name) refmap
@@ -348,19 +363,23 @@
                             ,Just $ Right (hie_hs_src hf))
             reportRefSpans opts refs
     TypesAtPoint target sp mep -> hieFileCommand conn opts target $ \hf -> do
-      let types' = concat $ pointCommand hf sp mep $ nodeType . nodeInfo
+      let types' = concat $ pointCommand hf sp mep $ nodeType . nodeInfo'
           types = map (flip recoverFullType $ hie_types hf) types'
       when (null types) $
         reportAmbiguousErr opts (Left $ NoNameAtPoint target sp)
       forM_ types $ \typ -> do
         putStrLn $ renderHieType dynFlags typ
     DefsAtPoint target sp mep -> hieFileCommand conn opts target $ \hf -> do
-      let names = concat $ pointCommand hf sp mep $ rights . M.keys . nodeIdentifiers . nodeInfo
+      let names = concat $ pointCommand hf sp mep $ rights . M.keys . nodeIdentifiers . nodeInfo'
       when (null names) $
         reportAmbiguousErr opts (Left $ NoNameAtPoint target sp)
       forM_ names $ \name -> do
         case nameSrcSpan name of
+#if __GLASGOW_HASKELL__ >= 900
+          RealSrcSpan dsp _ -> do
+#else
           RealSrcSpan dsp -> do
+#endif
             unless (quiet opts) $
               hPutStrLn stderr $ unwords ["Name", ppName opts (nameOccName name),"at",ppSpan opts sp,"is defined at:"]
             contents <- case nameModule_maybe name of
@@ -368,7 +387,7 @@
               Just mod
                 | mod == hie_module hf -> pure $ Just $ Right $ hie_hs_src hf
                 | otherwise -> unsafeInterleaveIO $ do
-                    loc <- findOneDef conn (nameOccName name) (Just $ moduleName mod) (Just $ moduleUnitId mod)
+                    loc <- findOneDef conn (nameOccName name) (Just $ moduleName mod) (Just $ moduleUnit mod)
                     pure $ case loc of
                       Left _ -> Nothing
                       Right (row:._) -> Just $ Left $ defSrc row
@@ -383,7 +402,7 @@
             case nameModule_maybe name of
               Just mod -> do
                 (row:.inf) <- reportAmbiguousErr opts
-                    =<< findOneDef conn (nameOccName name) (Just $ moduleName mod) (Just $ moduleUnitId mod)
+                    =<< findOneDef conn (nameOccName name) (Just $ moduleName mod) (Just $ moduleUnit mod)
                 unless (quiet opts) $
                   hPutStrLn stderr $ unwords ["Name", ppName opts (nameOccName name),"at",ppSpan opts sp,"is defined at:"]
                 reportRefSpans opts
@@ -393,10 +412,10 @@
                    ,Just $ Left $ defSrc row
                    )]
               Nothing -> do
-                reportAmbiguousErr opts $ Left $ NameUnhelpfulSpan name (FS.unpackFS msg)
+                reportAmbiguousErr opts $ Left $ NameUnhelpfulSpan name (FS.unpackFS $ unhelpfulSpanFS msg)
     InfoAtPoint target sp mep -> hieFileCommand conn opts target $ \hf -> do
       mapM_ (uncurry $ printInfo dynFlags) $ pointCommand hf sp mep $ \ast ->
-        (hieTypeToIface . flip recoverFullType (hie_types hf) <$> nodeInfo ast, nodeSpan ast)
+        (hieTypeToIface . flip recoverFullType (hie_types hf) <$> nodeInfo' ast, nodeSpan ast)
     RefGraph -> declRefs conn
     Dump path -> do
       nc <- newIORef =<< makeNc
@@ -449,13 +468,13 @@
 showHieDbErr opts e = case e of
   NoNameAtPoint t spn -> unwords ["No symbols found at",ppSpan opts spn,"in",either id (\(mn,muid) -> ppMod opts mn ++ maybe "" (\uid -> "("++ppUnit opts uid++")") muid) t]
   NotIndexed mn muid -> unwords ["Module", ppMod opts mn ++ maybe "" (\uid -> "("++ppUnit opts uid++")") muid, "not indexed."]
-  AmbiguousUnitId xs -> unlines $ "UnitId could be any of:" : map ((" - "<>) . unitIdString . modInfoUnit) (toList xs)
+  AmbiguousUnitId xs -> unlines $ "Unit could be any of:" : map ((" - "<>) . unitString . modInfoUnit) (toList xs)
     <> ["Use --unit-id to disambiguate"]
   NameNotFound occ mn muid -> unwords
     ["Couldn't find name:", ppName opts occ, maybe "" (("from module " ++) . moduleNameString) mn ++ maybe "" (\uid ->"("++ppUnit opts uid++")") muid]
   NameUnhelpfulSpan nm msg -> unwords
     ["Got no helpful spans for:", occNameString (nameOccName nm), "\nMsg:", msg]
- 
+
 reportRefSpans :: Options -> [(Module,(Int,Int),(Int,Int),Maybe (Either FilePath BS.ByteString))] -> IO ()
 reportRefSpans opts xs = do
   nc <- newIORef =<< makeNc
@@ -529,7 +548,7 @@
 ppMod :: Options -> ModuleName -> String
 ppMod = colouredPP Green moduleNameString
 
-ppUnit :: Options -> UnitId -> String
+ppUnit :: Options -> Unit -> String
 ppUnit = colouredPP Yellow show
 
 ppSpan :: Options -> (Int,Int) -> String
diff --git a/src/HieDb/Types.hs b/src/HieDb/Types.hs
--- a/src/HieDb/Types.hs
+++ b/src/HieDb/Types.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE FlexibleInstances #-}
 {-# OPTIONS_GHC -Wno-orphans #-}
 module HieDb.Types where
 
@@ -34,6 +35,8 @@
 
 import qualified Text.ParserCombinators.ReadP as R
 
+import HieDb.Compat
+
 newtype HieDb = HieDb { getConn :: Connection }
 
 data HieDbException
@@ -55,7 +58,7 @@
 data ModuleInfo
   = ModuleInfo
   { modInfoName :: ModuleName
-  , modInfoUnit :: UnitId -- ^ Identifies the package this module is part of
+  , modInfoUnit :: Unit -- ^ Identifies the package this module is part of
   , modInfoIsBoot :: Bool -- ^ True, when this ModuleInfo was created by indexing @.hie-boot@  file;
                           -- False when it was created from @.hie@ file
   , modInfoSrcFile :: Maybe FilePath -- ^ The path to the haskell source file, from which the @.hie@ file was created
@@ -79,11 +82,14 @@
 instance FromField ModuleName where
   fromField fld = mkModuleName . T.unpack <$> fromField fld
 
-instance ToField UnitId where
-  toField uid = SQLText $ T.pack $ unitIdString uid
-instance FromField UnitId where
-  fromField fld = stringToUnitId . T.unpack <$> fromField fld
+instance FromRow ModuleName where
+  fromRow = field
 
+instance ToField Unit where
+  toField uid = SQLText $ T.pack $ unitString uid
+instance FromField Unit where
+  fromField fld = stringToUnit . T.unpack <$> fromField fld
+
 instance ToField Fingerprint where
   toField hash = SQLText $ T.pack $ show hash
 instance FromField Fingerprint where
@@ -139,7 +145,7 @@
   { refSrc :: FilePath
   , refNameOcc :: OccName
   , refNameMod :: ModuleName
-  , refNameUnit :: UnitId
+  , refNameUnit :: Unit
   , refSLine :: Int
   , refSCol :: Int
   , refELine :: Int
@@ -175,7 +181,7 @@
 data TypeName = TypeName
   { typeName :: OccName
   , typeMod :: ModuleName
-  , typeUnit :: UnitId
+  , typeUnit :: Unit
   }
 
 data TypeRef = TypeRef
@@ -212,7 +218,22 @@
   fromRow = DefRow <$> field <*> field <*> field <*> field
                    <*> field <*> field
 
+data ExportRow = ExportRow
+  { exportHieFile :: FilePath -- ^ Exporting module
+  , exportName :: OccName
+  , exportMod :: ModuleName -- ^ Definition module
+  , exportUnit :: Unit
+  , exportParent :: Maybe OccName
+  , exportParentMod :: Maybe ModuleName
+  , exportParentUnit :: Maybe Unit
+  , exportIsDatacon :: Bool
+  }
+instance ToRow ExportRow where
+  toRow (ExportRow a b c d e f g h) = toRow (a,b,c,d,e,f,g,h)
 
+instance FromRow ExportRow where
+  fromRow = ExportRow <$> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field
+
 {-| Monad with access to 'NameCacheUpdater', which is needed to deserialize @.hie@ files -}
 class Monad m => NameCacheMonad m where
   getNcUpdater :: m NameCacheUpdater
@@ -233,9 +254,9 @@
 
 
 data HieDbErr
-  = NotIndexed ModuleName (Maybe UnitId)
+  = NotIndexed ModuleName (Maybe Unit)
   | AmbiguousUnitId (NonEmpty ModuleInfo)
-  | NameNotFound OccName (Maybe ModuleName) (Maybe UnitId)
+  | NameNotFound OccName (Maybe ModuleName) (Maybe Unit)
   | NoNameAtPoint HieTarget (Int,Int)
   | NameUnhelpfulSpan Name String
 
@@ -251,7 +272,8 @@
            <> ":"
            <> moduleNameString (moduleName $ symModule s)
            <> ":"
-           <> unitIdString (moduleUnitId $ symModule s)
+        --    <> unitIdString (moduleUnit $ symModule s)
+           <> unitString (moduleUnit $ symModule s)
 
 instance Read Symbol where
   readsPrec = const $ R.readP_to_S readSymbol
@@ -275,7 +297,7 @@
   u <- R.many1 R.get
   R.eof
   let mn  = mkModuleName m
-      uid = stringToUnitId u
+      uid = stringToUnit u
       sym = Symbol
               { symName   = mkOccName ns n
               , symModule = mkModule uid mn
@@ -288,5 +310,5 @@
 
 -- | A way to specify which HieFile to operate on.
 -- Either the path to @.hie@ file is given in the Left
--- Or ModuleName (with optional UnitId) is given in the Right
-type HieTarget = Either FilePath (ModuleName, Maybe UnitId)
+-- Or ModuleName (with optional Unit) is given in the Right
+type HieTarget = Either FilePath (ModuleName, Maybe Unit)
diff --git a/src/HieDb/Utils.hs b/src/HieDb/Utils.hs
--- a/src/HieDb/Utils.hs
+++ b/src/HieDb/Utils.hs
@@ -45,7 +45,10 @@
 import Data.IORef
 
 import HieDb.Types
+import HieDb.Compat
 import Database.SQLite.Simple
+import Avail
+import DataCon (flLabel)
 
 addTypeRef :: HieDb -> FilePath -> A.Array TypeIndex HieTypeFlat -> A.Array TypeIndex (Maybe Int64) -> RealSrcSpan -> TypeIndex -> IO ()
 addTypeRef (getConn -> conn) hf arr ixs sp = go 0
@@ -71,7 +74,11 @@
 #endif
         HTyConApp _ (HieArgs xs) -> mapM_ (next . snd) xs
         HForAllTy ((_ , a),_) b -> mapM_ next [a,b]
+#if __GLASGOW_HASKELL__ >= 900
+        HFunTy a b c -> mapM_ next [a,b,c]
+#else
         HFunTy a b -> mapM_ next [a,b]
+#endif
         HQualTy a b -> mapM_ next [a,b]
         HLitTy _ -> pure ()
         HCastTy a -> go d a
@@ -115,9 +122,13 @@
   nc <- readIORef ncr
   return $ case lookupOrigNameCache (nsNames nc) mdl occ of
     Just name -> case nameSrcSpan name of
+#if __GLASGOW_HASKELL__ >= 900
+      RealSrcSpan sp _ -> Right (sp, mdl)
+#else
       RealSrcSpan sp -> Right (sp, mdl)
-      UnhelpfulSpan msg -> Left $ NameUnhelpfulSpan name (FS.unpackFS msg)
-    Nothing -> Left $ NameNotFound occ (Just $ moduleName mdl) (Just $ moduleUnitId mdl)
+#endif
+      UnhelpfulSpan msg -> Left $ NameUnhelpfulSpan name (FS.unpackFS $ unhelpfulSpanFS msg)
+    Nothing -> Left $ NameNotFound occ (Just $ moduleName mdl) (Just $ moduleUnit mdl)
 
 pointCommand :: HieFile -> (Int, Int) -> Maybe (Int, Int) -> (HieAST TypeIndex -> a) -> [a]
 pointCommand hf (sl,sc) mep k =
@@ -158,7 +169,7 @@
 
     goRef (Right name, (sp,_))
       | Just mod <- nameModule_maybe name = Just $
-          RefRow path occ (moduleName mod) (moduleUnitId mod) sl sc el ec
+          RefRow path occ (moduleName mod) (moduleUnit mod) sl sc el ec
           where
             occ = nameOccName name
             sl = srcSpanStartLine sp
@@ -198,7 +209,11 @@
   where
     genRows = mapMaybe go
     getSpan name dets
+#if __GLASGOW_HASKELL__ >= 900
+      | RealSrcSpan sp _ <- nameSrcSpan name = Just sp
+#else
       | RealSrcSpan sp <- nameSrcSpan name = Just sp
+#endif
       | otherwise = do
           (sp, _dets) <- find defSpan dets
           pure sp
@@ -222,8 +237,56 @@
     go _ = Nothing
 
 identifierTree :: HieTypes.HieAST a -> Data.Tree.Tree ( HieTypes.HieAST a )
-identifierTree HieTypes.Node{ nodeInfo, nodeSpan, nodeChildren } =
+identifierTree nd@HieTypes.Node{ nodeChildren } =
   Data.Tree.Node
-    { rootLabel = HieTypes.Node{ nodeInfo, nodeSpan, nodeChildren = mempty }
+    { rootLabel = nd { nodeChildren = mempty }
     , subForest = map identifierTree nodeChildren
     }
+
+generateExports :: FilePath -> [AvailInfo] -> [ExportRow]
+generateExports fp = concatMap generateExport where
+  generateExport :: AvailInfo -> [ExportRow]
+  generateExport (Avail n)
+    = [ExportRow
+        { exportHieFile = fp
+        , exportName = nameOccName n
+        , exportMod = moduleName $ nameModule n
+        , exportUnit = moduleUnit $ nameModule n
+        , exportParent = Nothing
+        , exportParentMod = Nothing
+        , exportParentUnit = Nothing
+        , exportIsDatacon = False
+        }]
+  generateExport (AvailTC name pieces fields)
+    = ExportRow
+        { exportHieFile = fp
+        , exportName = nameOccName name
+        , exportMod = moduleName $ nameModule name
+        , exportUnit = moduleUnit $ nameModule name
+        , exportParent = Nothing
+        , exportParentMod = Nothing
+        , exportParentUnit = Nothing
+        , exportIsDatacon = False}
+    : [ExportRow
+        { exportHieFile = fp
+        , exportName = n
+        , exportMod = m
+        , exportUnit = u
+        , exportParent = Just (nameOccName name)
+        , exportParentMod = Just (moduleName $ nameModule name)
+        , exportParentUnit = Just (moduleUnit $ nameModule name)
+        , exportIsDatacon = False}
+      | (n,m,u) <- map (\n ->
+                        (nameOccName n
+                        ,moduleName $ nameModule n
+                        ,moduleUnit $ nameModule n
+                        ))
+                      (drop 1 pieces)
+               <> map (\s ->
+                        (mkVarOccFS $ flLabel s
+                        -- For fields, the module details come from the parent
+                        ,moduleName $ nameModule name
+                        ,moduleUnit $ nameModule name
+                        ))
+                      fields
+      ]
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,16 +1,19 @@
+{-# LANGUAGE CPP #-}
 module Main where
 
-import GHC.Paths (libdir)
+import GHC.Paths (libdir, ghc)
 import HieDb (HieDb, HieModuleRow (..), LibDir (..), ModuleInfo (..), withHieDb, withHieFile, addRefsFromLoaded, deleteMissingRealFiles)
 import HieDb.Query (getAllIndexedMods, lookupHieFile, resolveUnitId, lookupHieFileFromSource)
 import HieDb.Run (Command (..), Options (..), runCommand)
 import HieDb.Types (HieDbErr (..), SourceFile(..), runDbM)
 import HieDb.Utils (makeNc)
-import Module (mkModuleName, moduleNameString, stringToUnitId)
+import HieDb.Compat (stringToUnit)
+import Module (mkModuleName, moduleNameString)
 import System.Directory (findExecutable, getCurrentDirectory, removeDirectoryRecursive)
 import System.Exit (ExitCode (..), die)
 import System.FilePath ((</>))
 import System.Process (callProcess, proc, readCreateProcessWithExitCode)
+import System.Environment (lookupEnv)
 import System.IO.Temp
 import System.IO
 import Test.Hspec (Expectation, Spec, afterAll_, around, beforeAll_, describe, hspec, it, runIO,
@@ -18,6 +21,8 @@
 import Test.Orphans ()
 import GHC.Fingerprint
 import Data.IORef
+import Data.List (sort)
+import Data.Maybe (fromMaybe)
 
 main :: IO ()
 main = hspec spec
@@ -50,7 +55,7 @@
             res <- resolveUnitId conn (mkModuleName "Module1")
             case res of
               Left e       -> fail $ "Unexpected error: " <> show e
-              Right unitId -> unitId `shouldBe` stringToUnitId "main"
+              Right unit   -> unit `shouldBe` stringToUnit "main"
 
           it "returns NotIndexed error on not-indexed module" $ \conn -> do
             let notIndexedModule = mkModuleName "NotIndexed"
@@ -58,12 +63,12 @@
             case res of
               Left (NotIndexed modName Nothing) -> modName `shouldBe` notIndexedModule
               Left e                            -> fail $ "Unexpected error: " <> show e
-              Right unitId                      -> fail $ "Unexpected success: " <> show unitId
+              Right unit                        -> fail $ "Unexpected success: " <> show unit
 
         describe "lookupHieFile" $ do
           it "Should lookup indexed Module" $ \conn -> do
             let modName = mkModuleName "Module1"
-            res <- lookupHieFile conn modName (stringToUnitId "main")
+            res <- lookupHieFile conn modName (stringToUnit "main")
             case res of
               Just modRow -> do
                 hieModuleHieFile modRow `shouldEndWith` "Module1.hie"
@@ -72,7 +77,7 @@
                 modInfoName modInfo `shouldBe` modName
               Nothing -> fail "Should have looked up indexed file"
           it "Should return Nothing for not indexed Module" $ \conn -> do
-            res <- lookupHieFile conn (mkModuleName "NotIndexed") (stringToUnitId "main")
+            res <- lookupHieFile conn (mkModuleName "NotIndexed") (stringToUnit "main")
             case res of
               Nothing -> pure ()
               Just _  -> fail "Lookup suceeded unexpectedly"
@@ -91,7 +96,7 @@
             fp <- withSystemTempFile "Test.hs" $ \fp h -> do
               hPutStr h contents
               hClose h
-              callProcess "ghc" $
+              runGhc $
                 "-fno-code" : -- don't produce unnecessary .o and .hi files
                 "-fwrite-ide-info" :
                 "-hiedir=" <> testTmp :
@@ -129,21 +134,23 @@
     describe "index" $
       it "indexes testing project .hie files" $ do
         runHieDbCli ["index", testTmp, "--quiet"]
-          `suceedsWithStdin` ""
+          `succeedsWithStdin` ""
 
     describe "ls" $
       it "lists the indexed modules" $ do
         cwd <- getCurrentDirectory
-        let expectedOutput = unlines (fmap (\x -> cwd </> testTmp </> x)
+        let expectedOutput = fmap (\x -> cwd </> testTmp </> x)
               [ "Sub/Module2.hie\tSub.Module2\tmain"
               , "Module1.hie\tModule1\tmain"
-              ])
-        runHieDbCli ["ls"] `suceedsWithStdin` expectedOutput
+              ]
+        (exitCode, actualStdin, _actualStdErr) <- runHieDbCli ["ls"]
+        exitCode `shouldBe` ExitSuccess
+        (sort $ lines actualStdin) `shouldBe` (sort expectedOutput)
 
     describe "name-refs" $
       it "lists all references of given function" $ do
         runHieDbCli ["name-refs", "function2"]
-          `suceedsWithStdin` unlines
+          `succeedsWithStdin` unlines
             [ "Module1:3:7-3:16"
             , "Module1:12:1-12:10"
             , "Module1:13:1-13:10"
@@ -152,7 +159,7 @@
     describe "point-refs" $
       it "list references at given point" $
         runHieDbCli ["point-refs", "Module1", "13", "2"]
-          `suceedsWithStdin` unlines
+          `succeedsWithStdin` unlines
             [ "Module1:3:7-3:16"
             , "Module1:12:1-12:10"
             , "Module1:13:1-13:10"
@@ -161,7 +168,7 @@
     describe "point-types" $ do
       it "Prints types of symbol under cursor" $
         runHieDbCli ["point-types", "Module1", "10", "10" ]
-          `suceedsWithStdin` unlines
+          `succeedsWithStdin` unlines
             [ "Int -> Bool" {- types of `even` function under cursor -}
             , "forall a. Integral a => a -> Bool"
             ]
@@ -170,11 +177,11 @@
         actualStdout `shouldBe` ""
         exitCode `shouldBe` ExitFailure 1
         actualStderr `shouldBe` "No symbols found at (8,21) in Module1\n"
-        
+
     describe "point-defs" $ do
       it "outputs the location of symbol when definition site can be found is indexed" $
         runHieDbCli ["point-defs", "Module1", "13", "29"]
-          `suceedsWithStdin` unlines
+          `succeedsWithStdin` unlines
             [ "Sub.Module2:7:1-7:8"
             ]
       it "Fails with informative error message when there's no symbol at given point" $ do
@@ -192,24 +199,38 @@
     describe "point-info" $ do
       it "gives information about symbol at specified location" $
         runHieDbCli ["point-info", "Sub.Module2", "10", "10"]
-          `suceedsWithStdin` unlines
+          `succeedsWithStdin` unlines
             [ "Span: test/data/Sub/Module2.hs:10:7-23"
             , "Constructors: {(ConDeclH98, ConDecl)}"
             , "Identifiers:"
             , "Symbol:c:Data1Constructor1:Sub.Module2:main"
             , "Data1Constructor1 defined at test/data/Sub/Module2.hs:10:7-23"
+#if __GLASGOW_HASKELL__ >= 900
+            , "    Details:  Nothing {declaration of constructor bound at: test/data/Sub/Module2.hs:10:7-23}"
+#else
             , "    IdentifierDetails Nothing {Decl ConDec (Just SrcSpanOneLine \"test/data/Sub/Module2.hs\" 10 7 24)}"
+#endif
             , "Types:\n"
             ]
       it "correctly prints type signatures" $
         runHieDbCli ["point-info", "Module1", "10", "10"]
-          `suceedsWithStdin` unlines
+          `succeedsWithStdin` unlines
             [ "Span: test/data/Module1.hs:10:8-11"
+#if __GLASGOW_HASKELL__ >= 900
+            , "Constructors: {(HsVar, HsExpr), (XExpr, HsExpr)}"
+#else
             , "Constructors: {(HsVar, HsExpr), (HsWrap, HsExpr)}"
+#endif
             , "Identifiers:"
             , "Symbol:v:even:GHC.Real:base"
             , "even defined at <no location info>"
+#if __GLASGOW_HASKELL__ >= 900
+            , "    Details:  Just forall a. Integral a => a -> Bool {usage}"
+            , "$dIntegral defined at <no location info>"
+            , "    Details:  Just Integral Int {usage of evidence variable}"
+#else
             , "    IdentifierDetails Just forall a. Integral a => a -> Bool {Use}"
+#endif
             , "Types:"
             , "Int -> Bool"
             , "forall a. Integral a => a -> Bool"
@@ -219,12 +240,12 @@
     describe "name-def" $
       it "lookup definition of name" $
         runHieDbCli ["name-def", "showInt"]
-          `suceedsWithStdin` "Sub.Module2:7:1-7:8\n"
+          `succeedsWithStdin` "Sub.Module2:7:1-7:8\n"
 
     describe "type-def" $
       it "lookup definition of type" $
         runHieDbCli ["type-def", "Data1"]
-          `suceedsWithStdin` "Sub.Module2:9:1-11:28\n"
+          `succeedsWithStdin` "Sub.Module2:9:1-11:28\n"
 
     describe "cat" $
       describe "dumps module source stored in .hie file" $ do
@@ -232,39 +253,65 @@
         it "when given --hiefile" $ do
           cwd <- getCurrentDirectory
           runHieDbCli ["cat", "--hiefile" , cwd </> testTmp </> "Module1.hie"]
-            `suceedsWithStdin` (module1Src <> "\n")
+            `succeedsWithStdin` (module1Src <> "\n")
         it "when given module name" $
           runHieDbCli ["cat", "Module1"]
-            `suceedsWithStdin` (module1Src <> "\n")
+            `succeedsWithStdin` (module1Src <> "\n")
 
     describe "lookup-hie" $
       it "looks up location of .hie file" $ do
         cwd <- getCurrentDirectory
         runHieDbCli ["lookup-hie", "Module1"]
-          `suceedsWithStdin` (cwd </> testTmp </> "Module1.hie\n")
+          `succeedsWithStdin` (cwd </> testTmp </> "Module1.hie\n")
 
     describe "module-uids" $
       it "lists uids for given module" $
         runHieDbCli ["module-uids", "Module1"]
-          `suceedsWithStdin` "main\n"
-    
+          `succeedsWithStdin` "main\n"
+
+    describe "ls-exports" $ do
+      it "shows exports for Module1" $ do
+        cwd <- getCurrentDirectory
+        runHieDbCli ["ls-exports", "Module1"] `succeedsWithStdin` unlines
+          (fmap (\x -> cwd </> testTmp </> x)
+          [ "Module1.hie\tfunction1"
+          , "Module1.hie\tfunction2"
+          ])
+
+      it "shows all the exports" $ do
+        cwd <- getCurrentDirectory
+        runHieDbCli ["ls-exports"] `succeedsWithStdinSorted` unlines
+          (fmap (\x -> cwd </> testTmp </> x)
+          [ "Module1.hie\tfunction1"
+          , "Module1.hie\tfunction2"
+          , "Sub/Module2.hie\tshowInt"
+          , "Sub/Module2.hie\tData1"
+          , "Sub/Module2.hie\tData1(Data1Constructor1)"
+          , "Sub/Module2.hie\tData1(Data1Constructor2)"
+          ])
+
     describe "rm" $
       it "removes given module from DB" $ do
         runHieDbCli ["rm", "Module1"]
-          `suceedsWithStdin` ""
+          `succeedsWithStdin` ""
         -- Check with 'ls' comand that there's just one module left
         cwd <- getCurrentDirectory
-        runHieDbCli ["ls"] `suceedsWithStdin` (cwd </> testTmp </> "Sub/Module2.hie\tSub.Module2\tmain\n")
-    
+        runHieDbCli ["ls"] `succeedsWithStdin` (cwd </> testTmp </> "Sub/Module2.hie\tSub.Module2\tmain\n")
 
 
-suceedsWithStdin :: IO (ExitCode, String, String) -> String -> Expectation
-suceedsWithStdin action expectedStdin = do
+succeedsWithStdin :: IO (ExitCode, String, String) -> String -> Expectation
+succeedsWithStdin action expectedStdin = do
   (exitCode, actualStdin, _actualStdErr) <- action
   exitCode `shouldBe` ExitSuccess
   actualStdin `shouldBe` expectedStdin
 
 
+succeedsWithStdinSorted :: IO (ExitCode, String, String) -> String -> Expectation
+succeedsWithStdinSorted action expectedStdin = do
+  (exitCode, actualStdin, _actualStdErr) <- action
+  exitCode `shouldBe` ExitSuccess
+  sort (lines actualStdin) `shouldBe` sort (lines expectedStdin)
+
 runHieDbCli :: [String] -> IO (ExitCode, String, String)
 runHieDbCli args = do
   hiedb <- findHieDbExecutable
@@ -282,9 +329,14 @@
 cleanTestData :: IO ()
 cleanTestData = removeDirectoryRecursive testTmp
 
+runGhc :: [String] -> IO ()
+runGhc args = do
+  hc <- fromMaybe ghc <$> lookupEnv "HC"
+  callProcess hc args
+
 compileTestModules :: IO ()
-compileTestModules =
-  callProcess "ghc" $
+compileTestModules = do
+  runGhc $
     "-fno-code" : -- don't produce unnecessary .o and .hi files
     "-fwrite-ide-info" :
     "-hiedir=" <> testTmp :
diff --git a/test/Test/Orphans.hs b/test/Test/Orphans.hs
--- a/test/Test/Orphans.hs
+++ b/test/Test/Orphans.hs
@@ -2,8 +2,9 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Test.Orphans where
 
+import HieDb.Compat
 import HieDb.Types
-import Module (ModuleName, moduleName, moduleNameString, moduleUnitId)
+import Module (ModuleName, moduleName, moduleNameString)
 import Name (Name, nameModule, nameOccName)
 import OccName (OccName, occNameString)
 
@@ -14,7 +15,7 @@
     let occ = nameOccName n
         mod' = nameModule n
         mn = moduleName mod'
-        uid = moduleUnitId mod'
+        uid = moduleUnit mod'
     in show uid <> ":" <> show mn <> ":" <> show occ
 
 deriving instance Show HieDbErr
diff --git a/test/data/Module1.hs b/test/data/Module1.hs
new file mode 100644
--- /dev/null
+++ b/test/data/Module1.hs
@@ -0,0 +1,13 @@
+module Module1
+    ( function1
+    , function2
+    ) where
+
+import Sub.Module2 (showInt)
+
+function1 :: Int -> String
+function1 i =
+    if even i then "It's even" else "It's odd"
+
+function2 :: Int -> IO ()
+function2 i = putStrLn $ showInt i
diff --git a/test/data/Sub/Module2.hs b/test/data/Sub/Module2.hs
new file mode 100644
--- /dev/null
+++ b/test/data/Sub/Module2.hs
@@ -0,0 +1,11 @@
+module Sub.Module2
+    ( showInt
+    , Data1(..)
+    ) where
+
+showInt :: Int -> String
+showInt = show
+
+data Data1
+    = Data1Constructor1
+    | Data1Constructor2 Int
