diff --git a/Database/SQLite3.hs b/Database/SQLite3.hs
--- a/Database/SQLite3.hs
+++ b/Database/SQLite3.hs
@@ -25,6 +25,7 @@
     bindParameterCount,
     bindParameterName,
     columnCount,
+    columnName,
 
     -- * Binding values to a prepared statement
     -- | <http://www.sqlite.org/c3ref/bind_blob.html>
@@ -381,6 +382,30 @@
         Just name -> Just <$> fromUtf8 desc name
   where
     desc = "Database.SQLite3.bindParameterName: Invalid UTF-8"
+
+-- | <http://www.sqlite.org/c3ref/column_name.html>
+--
+-- Return the name of a result column.  If the column index is out of range,
+-- return 'Nothing'.
+columnName :: Statement -> ColumnIndex -> IO (Maybe Text)
+columnName stmt idx = do
+    m <- Direct.columnName stmt idx
+    case m of
+        Just name -> Just <$> fromUtf8 desc name
+        Nothing -> do
+            -- sqlite3_column_name only returns NULL if memory allocation fails
+            -- or if the column index is out of range.
+            count <- Direct.columnCount stmt
+            if idx >= 0 && idx < count
+                then throwIO outOfMemory
+                else return Nothing
+  where
+    desc = "Database.SQLite3.columnName: Invalid UTF-8"
+    outOfMemory = SQLError
+        { sqlError        = ErrorNoMemory
+        , sqlErrorDetails = "out of memory (sqlite3_column_name returned NULL)"
+        , sqlErrorContext = "column name"
+        }
 
 bindBlob :: Statement -> ParamIndex -> ByteString -> IO ()
 bindBlob statement parameterIndex byteString =
diff --git a/Database/SQLite3/Bindings.hs b/Database/SQLite3/Bindings.hs
--- a/Database/SQLite3/Bindings.hs
+++ b/Database/SQLite3/Bindings.hs
@@ -30,6 +30,7 @@
     c_sqlite3_bind_parameter_count,
     c_sqlite3_bind_parameter_name,
     c_sqlite3_column_count,
+    c_sqlite3_column_name,
 
     -- * Binding Values To Prepared Statements
     -- | <http://www.sqlite.org/c3ref/bind_blob.html>
@@ -195,6 +196,10 @@
 -- | <http://www.sqlite.org/c3ref/column_count.html>
 foreign import ccall unsafe "sqlite3_column_count"
     c_sqlite3_column_count :: Ptr CStatement -> IO CColumnCount
+
+-- | <http://www.sqlite.org/c3ref/column_name.html>
+foreign import ccall unsafe "sqlite3_column_name"
+    c_sqlite3_column_name :: Ptr CStatement -> CColumnIndex -> IO CString
 
 
 foreign import ccall unsafe "sqlite3_bind_blob"
diff --git a/Database/SQLite3/Direct.hs b/Database/SQLite3/Direct.hs
--- a/Database/SQLite3/Direct.hs
+++ b/Database/SQLite3/Direct.hs
@@ -33,6 +33,7 @@
     bindParameterCount,
     bindParameterName,
     columnCount,
+    columnName,
 
     -- * Binding values to a prepared statement
     -- | <http://www.sqlite.org/c3ref/bind_blob.html>
@@ -390,6 +391,12 @@
 columnCount :: Statement -> IO ColumnCount
 columnCount (Statement stmt) =
     fromFFI <$> c_sqlite3_column_count stmt
+
+-- | <http://www.sqlite.org/c3ref/column_name.html>
+columnName :: Statement -> ColumnIndex -> IO (Maybe Utf8)
+columnName (Statement stmt) idx =
+    c_sqlite3_column_name stmt (toFFI idx) >>=
+        packUtf8 Nothing Just
 
 bindInt64 :: Statement -> ParamIndex -> Int64 -> IO (Either Error ())
 bindInt64 (Statement stmt) idx value =
diff --git a/direct-sqlite.cabal b/direct-sqlite.cabal
--- a/direct-sqlite.cabal
+++ b/direct-sqlite.cabal
@@ -1,5 +1,5 @@
 name: direct-sqlite
-version: 2.3.3.1
+version: 2.3.4
 build-type: Simple
 license: BSD3
 license-file: LICENSE
@@ -21,6 +21,9 @@
   .
   Release history:
   .
+  [Version 2.3.4] Work around a linker error on some systems; add
+  column-name reporting.
+  .
   [Version 2.3.3.1] Upgrade bundled SQLite3 to 3.7.15.2.
   .
   [Version 2.3.3] Add trace support, as a feature for debugging.
@@ -76,6 +79,9 @@
     cpp-options: -Ddirect_sqlite_systemlib
     extra-libraries: sqlite3
   } else {
+    if !os(windows) {
+      extra-libraries: pthread
+    }
     c-sources: cbits/sqlite3.c
   }
 
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -45,6 +45,7 @@
     , TestLabel "Params"        . testBindParamName
     , TestLabel "Params"        . testBindErrorValidation
     , TestLabel "Columns"       . testColumns
+    , TestLabel "ColumnName"    . testColumnName
     , TestLabel "Errors"        . testErrors
     , TestLabel "Integrity"     . testIntegrity
     , TestLabel "DecodeError"   . testDecodeError
@@ -353,6 +354,46 @@
       0 <- columnCount stmt
       Done <- step stmt
       0 <- columnCount stmt
+      return ()
+
+testColumnName :: TestEnv -> Test
+testColumnName TestEnv{..} = TestCase $ do
+  withConn $ \conn -> do
+    exec conn "CREATE TABLE foo (id INTEGER PRIMARY KEY, abc TEXT, \"123\" REAL, über INT)"
+    exec conn "INSERT INTO foo (abc, \"123\", über) VALUES ('hello', 3.14, 456)"
+
+    withStmt conn "SELECT id AS id, abc AS x, \"123\" AS y, über AS ü FROM foo"
+      $ \stmt -> do
+      let checkNames = do
+              4 <- columnCount stmt
+              Nothing   <- columnName stmt (-1)
+              Just "id" <- columnName stmt 0
+              Just "x"  <- columnName stmt 1
+              Just "y"  <- columnName stmt 2
+              Just "ü"  <- columnName stmt 3
+              Nothing   <- columnName stmt 4
+              Nothing   <- columnName stmt (ColumnIndex minBound)
+              Nothing   <- columnName stmt (ColumnIndex maxBound)
+              return ()
+      checkNames
+      Row <- step stmt
+      checkNames
+      [SQLInteger 1, SQLText "hello", SQLFloat 3.14, SQLInteger 456] <- columns stmt
+      Done <- step stmt
+      checkNames
+
+    -- Column names without AS clauses may change in future versions of SQLite.
+    -- This test will fail if they do.
+    withStmt conn "SELECT * FROM foo" $ \stmt -> do
+      4 <- columnCount stmt
+      Nothing     <- columnName stmt (-1)
+      Just "id"   <- columnName stmt 0
+      Just "abc"  <- columnName stmt 1
+      Just "123"  <- columnName stmt 2
+      Just "über" <- columnName stmt 3
+      Nothing     <- columnName stmt 4
+      Nothing     <- columnName stmt (ColumnIndex minBound)
+      Nothing     <- columnName stmt (ColumnIndex maxBound)
       return ()
 
 -- Testing for specific error codes:
