diff --git a/Database/PostgreSQL/Typed/ErrCodes.hs b/Database/PostgreSQL/Typed/ErrCodes.hs
--- a/Database/PostgreSQL/Typed/ErrCodes.hs
+++ b/Database/PostgreSQL/Typed/ErrCodes.hs
@@ -1,4 +1,4 @@
--- Automatically generated from /src/postgresql-9.5.3/src/src/backend/utils/errcodes.txt using errcodes.hs 2016-09-28 20:17:05.706135604 UTC.
+-- Automatically generated from /src/postgresql-11.3/src/src/backend/utils/errcodes.txt using errcodes 2019-05-29 19:31:19.442545643 UTC.
 {-# LANGUAGE OverloadedStrings #-}
 -- |PostgreSQL error codes.
 module Database.PostgreSQL.Typed.ErrCodes (names
@@ -72,6 +72,7 @@
   , nonstandard_use_of_escape_character
   , invalid_indicator_parameter_value
   , invalid_parameter_value
+  , invalid_preceding_or_following_size
   , invalid_regular_expression
   , invalid_row_count_in_limit_clause
   , invalid_row_count_in_result_offset_clause
@@ -83,6 +84,7 @@
   , null_value_not_allowed
   , null_value_no_indicator_parameter
   , numeric_value_out_of_range
+  , sequence_generator_limit_exceeded
   , string_data_length_mismatch
   , string_data_right_truncation
   , substring_error
@@ -121,6 +123,7 @@
   , schema_and_data_statement_mixing_not_supported
   , no_active_sql_transaction
   , in_failed_sql_transaction
+  , idle_in_transaction_session_timeout
   -- * Class 26 - Invalid SQL Statement Name
   , invalid_sql_statement_name
   -- * Class 27 - Triggered Data Change Violation
@@ -184,6 +187,7 @@
   , collation_mismatch
   , indeterminate_collation
   , wrong_object_type
+  , generated_always
   , undefined_column
   , _UNDEFINED_CURSOR
   , _UNDEFINED_DATABASE
@@ -245,6 +249,8 @@
   , io_error
   , undefined_file
   , duplicate_file
+  -- * Class 72 - Snapshot Failure
+  , snapshot_too_old
   -- * Class F0 - Configuration File Error
   , config_file_error
   , lock_file_exists
@@ -511,6 +517,10 @@
 invalid_parameter_value :: ByteString
 invalid_parameter_value = "22023"
 
+-- |@INVALID_PRECEDING_OR_FOLLOWING_SIZE@: 22013 (Error)
+invalid_preceding_or_following_size :: ByteString
+invalid_preceding_or_following_size = "22013"
+
 -- |@INVALID_REGULAR_EXPRESSION@: 2201B (Error)
 invalid_regular_expression :: ByteString
 invalid_regular_expression = "2201B"
@@ -555,6 +565,10 @@
 numeric_value_out_of_range :: ByteString
 numeric_value_out_of_range = "22003"
 
+-- |@SEQUENCE_GENERATOR_LIMIT_EXCEEDED@: 2200H (Error)
+sequence_generator_limit_exceeded :: ByteString
+sequence_generator_limit_exceeded = "2200H"
+
 -- |@STRING_DATA_LENGTH_MISMATCH@: 22026 (Error)
 string_data_length_mismatch :: ByteString
 string_data_length_mismatch = "22026"
@@ -695,6 +709,10 @@
 in_failed_sql_transaction :: ByteString
 in_failed_sql_transaction = "25P02"
 
+-- |@IDLE_IN_TRANSACTION_SESSION_TIMEOUT@: 25P03 (Error)
+idle_in_transaction_session_timeout :: ByteString
+idle_in_transaction_session_timeout = "25P03"
+
 -- |@INVALID_SQL_STATEMENT_NAME@: 26000 (Error)
 invalid_sql_statement_name :: ByteString
 invalid_sql_statement_name = "26000"
@@ -891,6 +909,10 @@
 wrong_object_type :: ByteString
 wrong_object_type = "42809"
 
+-- |@GENERATED_ALWAYS@: 428C9 (Error)
+generated_always :: ByteString
+generated_always = "428C9"
+
 -- |@UNDEFINED_COLUMN@: 42703 (Error)
 undefined_column :: ByteString
 undefined_column = "42703"
@@ -1111,6 +1133,10 @@
 duplicate_file :: ByteString
 duplicate_file = "58P02"
 
+-- |@SNAPSHOT_TOO_OLD@: 72000 (Error)
+snapshot_too_old :: ByteString
+snapshot_too_old = "72000"
+
 -- |@CONFIG_FILE_ERROR@: F0000 (Error)
 config_file_error :: ByteString
 config_file_error = "F0000"
@@ -1308,6 +1334,7 @@
   ,(invalid_escape_octet,"invalid_escape_octet")
   ,(zero_length_character_string,"zero_length_character_string")
   ,(most_specific_type_mismatch,"most_specific_type_mismatch")
+  ,(sequence_generator_limit_exceeded,"sequence_generator_limit_exceeded")
   ,(not_an_xml_document,"not_an_xml_document")
   ,(invalid_xml_document,"invalid_xml_document")
   ,(invalid_xml_content,"invalid_xml_content")
@@ -1316,6 +1343,7 @@
   ,(invalid_indicator_parameter_value,"invalid_indicator_parameter_value")
   ,(substring_error,"substring_error")
   ,(division_by_zero,"division_by_zero")
+  ,(invalid_preceding_or_following_size,"invalid_preceding_or_following_size")
   ,(invalid_argument_for_ntile_function,"invalid_argument_for_ntile_function")
   ,(interval_field_overflow,"interval_field_overflow")
   ,(invalid_argument_for_nth_value_function,"invalid_argument_for_nth_value_function")
@@ -1363,6 +1391,7 @@
   ,(held_cursor_requires_same_isolation_level,"held_cursor_requires_same_isolation_level")
   ,(no_active_sql_transaction,"no_active_sql_transaction")
   ,(in_failed_sql_transaction,"in_failed_sql_transaction")
+  ,(idle_in_transaction_session_timeout,"idle_in_transaction_session_timeout")
   ,(invalid_sql_statement_name,"invalid_sql_statement_name")
   ,(_UNDEFINED_PSTATEMENT,"UNDEFINED_PSTATEMENT")
   ,(triggered_data_change_violation,"triggered_data_change_violation")
@@ -1420,6 +1449,7 @@
   ,(invalid_foreign_key,"invalid_foreign_key")
   ,(cannot_coerce,"cannot_coerce")
   ,(undefined_function,"undefined_function")
+  ,(generated_always,"generated_always")
   ,(reserved_name,"reserved_name")
   ,(undefined_table,"undefined_table")
   ,(undefined_parameter,"undefined_parameter")
@@ -1467,6 +1497,7 @@
   ,(io_error,"io_error")
   ,(undefined_file,"undefined_file")
   ,(duplicate_file,"duplicate_file")
+  ,(snapshot_too_old,"snapshot_too_old")
   ,(config_file_error,"config_file_error")
   ,(lock_file_exists,"lock_file_exists")
   ,(fdw_error,"fdw_error")
diff --git a/Database/PostgreSQL/Typed/Inet.hs b/Database/PostgreSQL/Typed/Inet.hs
--- a/Database/PostgreSQL/Typed/Inet.hs
+++ b/Database/PostgreSQL/Typed/Inet.hs
@@ -9,20 +9,20 @@
 
 module Database.PostgreSQL.Typed.Inet where
 
-import Control.Monad (void, guard, liftM2)
+import           Control.Monad (void, guard, liftM2)
 import qualified Data.ByteString.Char8 as BSC
-import Data.Bits (shiftL, (.|.))
-import Data.Maybe (fromJust)
-import Data.Word (Word8, Word16, Word32)
-import Foreign.Marshal.Array (withArray)
-import Foreign.Ptr (castPtr)
-import Foreign.Storable (peek)
+import           Data.Bits (shiftL, (.|.))
+import           Data.Maybe (fromJust)
+import           Data.Word (Word8, Word16, Word32)
+import           Foreign.Marshal.Array (withArray)
+import           Foreign.Ptr (castPtr)
+import           Foreign.Storable (peek)
 import qualified Network.Socket as Net
-import Numeric (readDec, readHex)
-import System.IO.Unsafe (unsafeDupablePerformIO)
+import           Numeric (readDec, readHex)
+import           System.IO.Unsafe (unsafeDupablePerformIO)
 import qualified Text.ParserCombinators.ReadP as RP
 import qualified Text.ParserCombinators.ReadPrec as RP (lift)
-import Text.Read (Read(readPrec))
+import           Text.Read (Read(readPrec))
 
 import Database.PostgreSQL.Typed.Types
 
@@ -50,7 +50,8 @@
 
 instance Show PGInet where
   -- This is how Network.Socket's Show SockAddr does it:
-  show (PGInet a 32) = unsafeDupablePerformIO $ Net.inet_ntoa a
+  show (PGInet a 32) = fromJust $ fst $ unsafeDupablePerformIO $
+    Net.getNameInfo [Net.NI_NUMERICHOST] True False (Net.SockAddrInet 0 a)
   show (PGInet a m) = show (PGInet a 32) ++ '/' : show m
   show (PGInet6 a 128) = fromJust $ fst $ unsafeDupablePerformIO $
     Net.getNameInfo [Net.NI_NUMERICHOST] True False (Net.SockAddrInet6 0 0 a 0)
diff --git a/Database/PostgreSQL/Typed/Protocol.hs b/Database/PostgreSQL/Typed/Protocol.hs
--- a/Database/PostgreSQL/Typed/Protocol.hs
+++ b/Database/PostgreSQL/Typed/Protocol.hs
@@ -2,8 +2,9 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections #-}
 {-# LANGUAGE ViewPatterns #-}
 -- Copyright 2010, 2011, 2012, 2013 Chris Forno
@@ -18,6 +19,10 @@
   , defaultPGDatabase
   , PGConnection
   , PGError(..)
+#ifdef VERSION_tls
+  , PGTlsMode(..)
+  , PGTlsValidateMode (..)
+#endif
   , pgErrorCode
   , pgConnectionDatabase
   , pgTypeEnv
@@ -50,15 +55,23 @@
   , pgFetch
   -- * Notifications
   , PGNotification(..)
-  , pgGetNotifications
   , pgGetNotification
+  , pgGetNotifications
+#ifdef VERSION_tls
+  -- * TLS Helpers
+  , pgTlsValidate
+#endif
+  , pgSupportsTls
   ) where
 
 #if !MIN_VERSION_base(4,8,0)
 import           Control.Applicative ((<$>), (<$))
 #endif
 import           Control.Arrow ((&&&), first, second)
-import           Control.Exception (Exception, throwIO, onException, finally)
+import           Control.Exception (Exception, onException, finally, throwIO)
+#ifdef VERSION_tls
+import           Control.Exception (catch)
+#endif
 import           Control.Monad (void, liftM2, replicateM, when, unless)
 #ifdef VERSION_cryptonite
 import qualified Crypto.Hash as Hash
@@ -68,10 +81,13 @@
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Builder as B
 import qualified Data.ByteString.Char8 as BSC
-import           Data.ByteString.Internal (w2c)
+import           Data.ByteString.Internal (w2c, createAndTrim)
 import qualified Data.ByteString.Lazy as BSL
 import qualified Data.ByteString.Lazy.Char8 as BSLC
 import           Data.ByteString.Lazy.Internal (smallChunkSize)
+#ifdef VERSION_tls
+import           Data.Default (def)
+#endif
 import qualified Data.Foldable as Fold
 import           Data.IORef (IORef, newIORef, writeIORef, readIORef, atomicModifyIORef, atomicModifyIORef', modifyIORef')
 import           Data.Int (Int32, Int16)
@@ -81,15 +97,34 @@
 #if !MIN_VERSION_base(4,8,0)
 import           Data.Monoid (mempty)
 #endif
+import           Data.Time.Clock (getCurrentTime)
 import           Data.Tuple (swap)
 import           Data.Typeable (Typeable)
 #if !MIN_VERSION_base(4,8,0)
 import           Data.Word (Word)
 #endif
-import           Data.Word (Word32)
-import           Network (HostName, PortID(..), connectTo)
-import           System.IO (Handle, hFlush, hClose, stderr, hPutStrLn, hSetBuffering, BufferMode(BlockBuffering))
-import           System.IO.Error (mkIOError, eofErrorType, ioError)
+import           Data.Word (Word32, Word8)
+#ifdef VERSION_tls
+import           Data.X509 (SignedCertificate, HashALG(HashSHA256))
+import           Data.X509.Memory (readSignedObjectFromMemory)
+import           Data.X509.CertificateStore (makeCertificateStore)
+import qualified Data.X509.Validation
+#endif
+#ifndef mingw32_HOST_OS
+import           Foreign.C.Error (eWOULDBLOCK, getErrno, errnoToIOError)
+import           Foreign.C.Types (CChar(..), CInt(..), CSize(..))
+import           Foreign.Ptr (Ptr, castPtr)
+import           GHC.IO.Exception (IOErrorType(InvalidArgument))
+#endif
+import qualified Network.Socket as Net
+import qualified Network.Socket.ByteString as NetBS
+import qualified Network.Socket.ByteString.Lazy as NetBSL
+#ifdef VERSION_tls
+import qualified Network.TLS as TLS
+import qualified Network.TLS.Extra.Cipher as TLS
+#endif
+import           System.IO (stderr, hPutStrLn)
+import           System.IO.Error (IOError, mkIOError, eofErrorType, ioError, ioeSetErrorString)
 import           System.IO.Unsafe (unsafeInterleaveIO)
 import           Text.Read (readMaybe)
 
@@ -107,20 +142,60 @@
   | StateClosed
   deriving (Show, Eq)
 
+#ifdef VERSION_tls
+data PGTlsValidateMode
+  = TlsValidateFull
+  -- ^ Equivalent to sslmode=verify-full. Ie: Check the FQHN against the
+  -- certicate's CN
+  | TlsValidateCA
+  -- ^ Equivalent to sslmode=verify-ca. Ie: Only check that the certificate has
+  -- been signed by the root certificate we provide
+  deriving (Show, Eq)
+
+data PGTlsMode
+  = TlsDisabled
+  -- ^ TLS is disabled
+  | TlsNoValidate
+  | TlsValidate PGTlsValidateMode SignedCertificate
+  deriving (Eq, Show)
+
+-- | Constructs a 'PGTlsMode' to validate the server certificate with given root
+-- certificate (in PEM format)
+pgTlsValidate :: PGTlsValidateMode -> BSC.ByteString -> Either String PGTlsMode
+pgTlsValidate mode certPem =
+  case readSignedObjectFromMemory certPem of
+    []  -> Left "Could not parse any certificate in PEM"
+    (x:_) -> Right (TlsValidate mode x)
+
+pgSupportsTls :: PGConnection -> Bool
+pgSupportsTls PGConnection{connHandle=PGTlsContext _} = True
+pgSupportsTls _ = False
+#else
+pgSupportsTls :: PGConnection -> Bool
+pgSupportsTls _ = False
+#endif
+
 -- |Information for how to connect to a database, to be passed to 'pgConnect'.
 data PGDatabase = PGDatabase
-  { pgDBHost :: HostName -- ^ The hostname (ignored if 'pgDBPort' is 'UnixSocket')
-  , pgDBPort :: PortID -- ^ The port, likely either @PortNumber 5432@ or @UnixSocket \"\/tmp\/.s.PGSQL.5432\"@
+  { pgDBAddr :: Either (Net.HostName, Net.ServiceName) Net.SockAddr -- ^ The address to connect to the server
   , pgDBName :: BS.ByteString -- ^ The name of the database
   , pgDBUser, pgDBPass :: BS.ByteString
   , pgDBParams :: [(BS.ByteString, BS.ByteString)] -- ^ Extra parameters to set for the connection (e.g., ("TimeZone", "UTC"))
   , pgDBDebug :: Bool -- ^ Log all low-level server messages
   , pgDBLogMessage :: MessageFields -> IO () -- ^ How to log server notice messages (e.g., @print . PGError@)
+#ifdef VERSION_tls
+  , pgDBTLS :: PGTlsMode -- ^ TLS mode
+#endif
   }
 
 instance Eq PGDatabase where
-  PGDatabase h1 s1 n1 u1 p1 l1 _ _ == PGDatabase h2 s2 n2 u2 p2 l2 _ _ =
-    h1 == h2 && s1 == s2 && n1 == n2 && u1 == u2 && p1 == p2 && l1 == l2
+#ifdef VERSION_tls
+  PGDatabase a1 n1 u1 p1 l1 _ _ s1 == PGDatabase a2 n2 u2 p2 l2 _ _ s2 =
+    a1 == a2 && n1 == n2 && u1 == u2 && p1 == p2 && l1 == l2 && s1 == s2
+#else
+  PGDatabase a1 n1 u1 p1 l1 _ _ == PGDatabase a2 n2 u2 p2 l2 _ _ =
+    a1 == a2 && n1 == n2 && u1 == u2 && p1 == p2 && l1 == l2
+#endif
 
 newtype PGPreparedStatement = PGPreparedStatement Integer
   deriving (Eq, Show)
@@ -128,10 +203,48 @@
 preparedStatementName :: PGPreparedStatement -> BS.ByteString
 preparedStatementName (PGPreparedStatement n) = BSC.pack $ show n
 
+data PGHandle
+  = PGSocket Net.Socket
+#ifdef VERSION_tls
+  | PGTlsContext TLS.Context
+#endif
+
+pgPutBuilder :: PGHandle -> B.Builder -> IO ()
+pgPutBuilder (PGSocket s) b = NetBSL.sendAll s (B.toLazyByteString b)
+#ifdef VERSION_tls
+pgPutBuilder (PGTlsContext c) b = TLS.sendData c (B.toLazyByteString b)
+#endif
+
+pgPut:: PGHandle -> BS.ByteString -> IO ()
+pgPut (PGSocket s) bs = NetBS.sendAll s bs
+#ifdef VERSION_tls
+pgPut (PGTlsContext c) bs = TLS.sendData c (BSL.fromChunks [bs])
+#endif
+
+pgGetSome :: PGHandle -> Int -> IO BSC.ByteString
+pgGetSome (PGSocket s) count = NetBS.recv s count
+#ifdef VERSION_tls
+pgGetSome (PGTlsContext c) _ = TLS.recvData c
+#endif
+
+pgCloseHandle :: PGHandle -> IO ()
+pgCloseHandle (PGSocket s) = Net.close s
+#ifdef VERSION_tls
+pgCloseHandle (PGTlsContext c) = do
+  TLS.bye c `catch` \(_ :: IOError) -> pure ()
+  TLS.contextClose c
+#endif
+
+pgFlush :: PGConnection -> IO ()
+pgFlush PGConnection{connHandle=PGSocket _} = pure ()
+#ifdef VERSION_tls
+pgFlush PGConnection{connHandle=PGTlsContext c} = TLS.contextFlush c
+#endif
+
 -- |An established connection to the PostgreSQL server.
 -- These objects are not thread-safe and must only be used for a single request at a time.
 data PGConnection = PGConnection
-  { connHandle :: Handle
+  { connHandle :: PGHandle
   , connDatabase :: !PGDatabase
   , connPid :: !Word32 -- unused
   , connKey :: !Word32 -- unused
@@ -178,9 +291,6 @@
 deQueue (Queue (reverse -> x:d) []) = (Queue [] d, Just x)
 deQueue q = (q, Nothing)
 
-queueToList :: Queue a -> [a]
-queueToList (Queue e d) = d ++ reverse e
-
 -- |PGFrontendMessage represents a PostgreSQL protocol message that we'll send.
 -- See <http://www.postgresql.org/docs/current/interactive/protocol-message-formats.html>.
 data PGFrontendMessage
@@ -274,18 +384,22 @@
 -- localhost:5432:postgres
 defaultPGDatabase :: PGDatabase
 defaultPGDatabase = PGDatabase
-  { pgDBHost = "localhost"
-  , pgDBPort = PortNumber 5432
+  { pgDBAddr = Right $ Net.SockAddrInet 5432 (Net.tupleToHostAddress (127,0,0,1))
   , pgDBName = "postgres"
   , pgDBUser = "postgres"
   , pgDBPass = BS.empty
   , pgDBParams = []
   , pgDBDebug = False
   , pgDBLogMessage = defaultLogMessage
+#ifdef VERSION_tls
+  , pgDBTLS = TlsDisabled
+#endif
   }
 
-connDebug :: PGConnection -> Bool
-connDebug = pgDBDebug . connDatabase
+connDebugMsg :: PGConnection -> String -> IO ()
+connDebugMsg c msg = when (pgDBDebug $ connDatabase c) $ do
+  t <- getCurrentTime
+  hPutStrLn stderr $ show t ++ msg
 
 connLogMessage :: PGConnection -> MessageFields -> IO ()
 connLogMessage = pgDBLogMessage . connDatabase
@@ -360,9 +474,9 @@
 pgSend :: PGConnection -> PGFrontendMessage -> IO ()
 pgSend c@PGConnection{ connHandle = h, connState = sr } msg = do
   modifyIORef' sr $ state msg
-  when (connDebug c) $ putStrLn $ "> " ++ show msg
-  B.hPutBuilder h $ Fold.foldMap B.char7 t <> B.word32BE (fromIntegral $ 4 + BS.length b)
-  BS.hPut h b -- or B.hPutBuilder? But we've already had to convert to BS to get length
+  connDebugMsg c $ "> " ++ show msg
+  pgPutBuilder h $ Fold.foldMap B.char7 t <> B.word32BE (fromIntegral $ 4 + BS.length b)
+  pgPut h b -- or B.hPutBuilder? But we've already had to convert to BS to get length
   where
   (t, b) = second (BSL.toStrict . B.toLazyByteString) $ messageBody msg
   state _ StateClosed = StateClosed
@@ -371,10 +485,7 @@
   state Terminate _ = StateClosed
   state _ _ = StateUnsync
 
-pgFlush :: PGConnection -> IO ()
-pgFlush = hFlush . connHandle
 
-
 getByteStringNul :: G.Get BS.ByteString
 getByteStringNul = fmap BSL.toStrict G.getLazyByteStringNul
 
@@ -452,13 +563,13 @@
   -- |Read from connection, returning immediate value or non-empty data
   recvMsgData :: PGConnection -> IO (Either m BS.ByteString)
   recvMsgData c = do
-    r <- BS.hGetSome (connHandle c) smallChunkSize
+    r <- pgGetSome (connHandle c) smallChunkSize
     if BS.null r
       then do
         writeIORef (connState c) StateClosed
-        hClose (connHandle c)
+        pgCloseHandle (connHandle c)
         -- Should this instead be a special PGError?
-        ioError $ mkIOError eofErrorType "PGConnection" (Just (connHandle c)) Nothing
+        ioError $ mkIOError eofErrorType "PGConnection" Nothing Nothing
       else
         return (Right r)
   -- |Expected ReadyForQuery message
@@ -480,11 +591,20 @@
 -- |Process all pending messages
 data RecvNonBlock = RecvNonBlock deriving (Show)
 instance RecvMsg RecvNonBlock where
-  recvMsgData c = do
-    r <- BS.hGetNonBlocking (connHandle c) smallChunkSize
+#ifndef mingw32_HOST_OS
+  recvMsgData PGConnection{connHandle=PGSocket s} = do
+    r <- recvNonBlock s smallChunkSize
     if BS.null r
       then return (Left RecvNonBlock)
       else return (Right r)
+#else
+  recvMsgData PGConnection{connHandle=PGSocket _} =
+    throwIO (userError "Non-blocking recvMsgData is not supported on mingw32 ATM")
+#endif
+#ifdef VERSION_tls
+  recvMsgData PGConnection{connHandle=PGTlsContext _} =
+    throwIO (userError "Non-blocking recvMsgData is not supported on TLS connections")
+#endif
 
 -- |Wait for ReadyForQuery
 data RecvSync = RecvSync deriving (Show)
@@ -515,7 +635,7 @@
 
   -- read and parse
   rcv (G.Done b _ m) = do
-    when (connDebug c) $ putStrLn $ "< " ++ show m
+    connDebugMsg c $ "< " ++ show m
     got (new b) m
   rcv (G.Fail _ _ r) = next (new BS.empty) >> fail r -- not clear how can recover
   rcv d@(G.Partial r) = recvMsgData c `onException` next d >>=
@@ -552,10 +672,20 @@
   input <- newIORef getMessage
   tr <- newIORef 0
   notif <- newIORef emptyQueue
-  h <- connectTo (pgDBHost db) (pgDBPort db)
-  hSetBuffering h (BlockBuffering Nothing)
+  addr <- either
+    (\(h,p) -> head <$> Net.getAddrInfo (Just defai) (Just h) (Just p))
+    (\a -> return defai{ Net.addrAddress = a, Net.addrFamily = case a of
+      Net.SockAddrInet{}  -> Net.AF_INET
+      Net.SockAddrInet6{} -> Net.AF_INET6
+      Net.SockAddrUnix{}  -> Net.AF_UNIX
+      _ -> Net.AF_UNSPEC })
+    $ pgDBAddr db
+  sock <- Net.socket (Net.addrFamily addr) (Net.addrSocketType addr) (Net.addrProtocol addr)
+  unless (Net.addrFamily addr == Net.AF_UNIX) $ Net.setSocketOption sock Net.NoDelay 1
+  Net.connect sock $ Net.addrAddress addr
+  pgHandle <- mkPGHandle db sock
   let c = PGConnection
-        { connHandle = h
+        { connHandle = pgHandle
         , connDatabase = db
         , connPid = 0
         , connKey = 0
@@ -580,6 +710,7 @@
   pgFlush c
   conn c
   where
+  defai = Net.defaultHints{ Net.addrSocketType = Net.Stream }
   conn c = pgRecv c >>= msg c
   msg c (Right RecvSync) = do
     cp <- readIORef (connParameters c)
@@ -603,11 +734,61 @@
 #endif
   msg _ (Left m) = fail $ "pgConnect: unexpected response: " ++ show m
 
+mkPGHandle :: PGDatabase -> Net.Socket -> IO PGHandle
+#ifdef VERSION_tls
+mkPGHandle db sock =
+  case pgDBTLS db of
+    TlsDisabled     -> pure (PGSocket sock)
+    TlsNoValidate   -> mkTlsContext
+    TlsValidate _ _ -> mkTlsContext
+  where
+    mkTlsContext = do
+      NetBSL.sendAll sock sslRequest
+      resp <- NetBS.recv sock 1
+      case resp of
+        "S" -> do
+          ctx <- TLS.contextNew sock params
+          void $ TLS.handshake ctx
+          pure $ PGTlsContext ctx
+        "N" -> throwIO (userError "Server does not support TLS")
+        _ -> throwIO (userError "Unexpected response from server when issuing SSLRequest")
+    params = (TLS.defaultParamsClient tlsHost tlsPort)
+      { TLS.clientSupported =
+          def { TLS.supportedCiphers = TLS.ciphersuite_strong }
+      , TLS.clientShared = clientShared
+      , TLS.clientHooks = clientHooks
+      }
+    tlsHost = case pgDBAddr db of
+      Left (h,_) -> h
+      Right (Net.SockAddrUnix s) -> s
+      Right _ -> "some-socket"
+    tlsPort = case pgDBAddr db of
+      Left (_,p) -> BSC.pack p
+      Right _    -> "socket"
+    clientShared =
+      case pgDBTLS db of
+        TlsDisabled -> def { TLS.sharedValidationCache = noValidate }
+        TlsNoValidate -> def { TLS.sharedValidationCache = noValidate }
+        TlsValidate _ sc -> def { TLS.sharedCAStore = makeCertificateStore [sc] }
+    clientHooks =
+      case pgDBTLS db of
+        TlsValidate TlsValidateCA _ -> def { TLS.onServerCertificate = validateNoCheckFQHN }
+        _                           -> def
+    validateNoCheckFQHN = Data.X509.Validation.validate HashSHA256 def (def { TLS.checkFQHN = False })
+
+    noValidate = TLS.ValidationCache
+      (\_ _ _ -> return TLS.ValidationCachePass)
+      (\_ _ _ -> return ())
+    sslRequest = B.toLazyByteString (B.word32BE 8 <> B.word32BE 80877103)
+#else
+mkPGHandle _ sock = pure (PGSocket sock)
+#endif
+
 -- |Disconnect cleanly from the PostgreSQL server.
 pgDisconnect :: PGConnection -- ^ a handle from 'pgConnect'
              -> IO ()
 pgDisconnect c@PGConnection{ connHandle = h } =
-  pgSend c Terminate `finally` hClose h
+  pgSend c Terminate `finally` pgCloseHandle h
 
 -- |Disconnect cleanly from the PostgreSQL server, but only if it's still connected.
 pgDisconnectOnce :: PGConnection -- ^ a handle from 'pgConnect'
@@ -928,14 +1109,52 @@
   res EmptyQueryResponse = return ([], Just 0)
   res m = fail $ "pgFetch: unexpected response: " ++ show m
 
+-- |Retrieve a notifications, blocking if necessary.
+pgGetNotification :: PGConnection -> IO PGNotification
+pgGetNotification c =
+  maybe (pgRecv c) return
+   =<< atomicModifyIORef' (connNotifications c) deQueue
+
 -- |Retrieve any pending notifications.  Non-blocking.
 pgGetNotifications :: PGConnection -> IO [PGNotification]
 pgGetNotifications c = do
   RecvNonBlock <- pgRecv c
   queueToList <$> atomicModifyIORef' (connNotifications c) (emptyQueue, )
+  where
+  queueToList :: Queue a -> [a]
+  queueToList (Queue e d) = d ++ reverse e
 
--- |Retrieve a notifications, blocking if necessary.
-pgGetNotification :: PGConnection -> IO PGNotification
-pgGetNotification c =
-  maybe (pgRecv c) return
-   =<< atomicModifyIORef' (connNotifications c) deQueue
+
+--TODO: Implement non-blocking recv on mingw32
+#ifndef mingw32_HOST_OS
+recvNonBlock
+  :: Net.Socket        -- ^ Connected socket
+  -> Int               -- ^ Maximum number of bytes to receive
+  -> IO BS.ByteString  -- ^ Data received
+recvNonBlock s nbytes
+  | nbytes < 0 = ioError (mkInvalidRecvArgError "Database.PostgreSQL.Typed.Protocol.recvNonBlock")
+  | otherwise  = createAndTrim nbytes $ \ptr -> recvBufNonBlock s ptr nbytes
+
+recvBufNonBlock :: Net.Socket -> Ptr Word8 -> Int -> IO Int
+recvBufNonBlock s ptr nbytes
+ | nbytes <= 0 = ioError (mkInvalidRecvArgError "Database.PostgreSQL.Typed.recvBufNonBlock")
+ | otherwise   = do
+    len <- c_recv (Net.fdSocket s) (castPtr ptr) (fromIntegral nbytes) 0
+    if len == -1
+      then do
+        errno <- getErrno
+        if errno == eWOULDBLOCK
+          then return 0
+          else throwIO (errnoToIOError "recvBufNonBlock" errno Nothing (Just "Database.PostgreSQL.Typed"))
+      else
+        return $ fromIntegral len
+
+mkInvalidRecvArgError :: String -> IOError
+mkInvalidRecvArgError loc = ioeSetErrorString (mkIOError
+                                    InvalidArgument
+                                    loc Nothing Nothing) "non-positive length"
+
+
+foreign import ccall unsafe "recv"
+  c_recv :: CInt -> Ptr CChar -> CSize -> CInt -> IO CInt
+#endif
diff --git a/Database/PostgreSQL/Typed/Query.hs b/Database/PostgreSQL/Typed/Query.hs
--- a/Database/PostgreSQL/Typed/Query.hs
+++ b/Database/PostgreSQL/Typed/Query.hs
@@ -184,6 +184,7 @@
   when (length pt < length exprs) $ fail "Not all expression placeholders were recognized by PostgreSQL"
 
   e <- TH.newName "_tenv"
+  l <- TH.newName "l"
   (vars, vals) <- mapAndUnzipM (\t -> do
     v <- newName 'p' $ tpgValueName t
     return 
@@ -213,7 +214,10 @@
 #endif
       )
       prep)
-    `TH.AppE` TH.LamE [TH.VarP e, TH.ListP pats] (TH.TupE conv))
+    `TH.AppE` TH.LamE [TH.VarP e, TH.VarP l] (TH.CaseE (TH.VarE l)
+      [ TH.Match (TH.ListP pats) (TH.NormalB $ TH.TupE conv) []
+      , TH.Match TH.WildP (TH.NormalB $ TH.VarE 'error `TH.AppE` TH.LitE (TH.StringL "pgSQL: result arity mismatch")) []
+      ]))
     <$> mapM parse exprs
   where
   (sqlp, exprs) = sqlPlaceholders sqle
diff --git a/Database/PostgreSQL/Typed/TH.hs b/Database/PostgreSQL/Typed/TH.hs
--- a/Database/PostgreSQL/Typed/TH.hs
+++ b/Database/PostgreSQL/Typed/TH.hs
@@ -20,27 +20,29 @@
   ) where
 
 #if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>), (<$))
+import           Control.Applicative ((<$>), (<$))
 #endif
-import Control.Applicative ((<|>))
-import Control.Concurrent.MVar (MVar, newMVar, takeMVar, putMVar, withMVar)
-import Control.Exception (onException, finally)
-import Control.Monad (liftM2)
+import           Control.Applicative ((<|>))
+import           Control.Concurrent.MVar (MVar, newMVar, takeMVar, putMVar, withMVar)
+import           Control.Exception (onException, finally)
+#ifdef VERSION_tls
+import           Control.Exception (throwIO)
+#endif
+import           Control.Monad (liftM2)
 import qualified Data.ByteString as BS
+#ifdef VERSION_tls
+import qualified Data.ByteString.Char8 as BSC
+#endif
 import qualified Data.ByteString.Lazy as BSL
 import qualified Data.ByteString.UTF8 as BSU
 import qualified Data.Foldable as Fold
-import Data.Maybe (isJust, fromMaybe)
-import Data.String (fromString)
+import           Data.Maybe (isJust, fromMaybe)
+import           Data.String (fromString)
 import qualified Data.Traversable as Tv
 import qualified Language.Haskell.TH as TH
-import Network (PortID(PortNumber
-#ifndef mingw32_HOST_OS
-  , UnixSocket
-#endif
-  ), PortNumber)
-import System.Environment (lookupEnv)
-import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO)
+import qualified Network.Socket as Net
+import           System.Environment (lookupEnv)
+import           System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO)
 
 import Database.PostgreSQL.Typed.Types
 import Database.PostgreSQL.Typed.Protocol
@@ -53,21 +55,40 @@
   user <- fromMaybe "postgres" <$> liftM2 (<|>) (lookupEnv "TPG_USER") (lookupEnv "USER")
   db   <- fromMaybe user <$> lookupEnv "TPG_DB"
   host <- fromMaybe "localhost" <$> lookupEnv "TPG_HOST"
-  pnum <- maybe (5432 :: PortNumber) ((fromIntegral :: Int -> PortNumber) . read) <$> lookupEnv "TPG_PORT"
+  pnum <- fromMaybe "5432" <$> lookupEnv "TPG_PORT"
 #ifdef mingw32_HOST_OS
-  let port = PortNumber pnum
+  let port = Right pnum
 #else
-  port <- maybe (PortNumber pnum) UnixSocket <$> lookupEnv "TPG_SOCK"
+  port <- maybe (Right pnum) Left <$> lookupEnv "TPG_SOCK"
 #endif
   pass <- fromMaybe "" <$> lookupEnv "TPG_PASS"
   debug <- isJust <$> lookupEnv "TPG_DEBUG"
+#ifdef VERSION_tls
+  tlsEnabled <- isJust <$> lookupEnv "TPG_TLS"
+  tlsVerifyMode <- lookupEnv "TPG_TLS_MODE" >>= \modeStr ->
+    case modeStr of
+      Just "full" -> pure TlsValidateFull
+      Just "ca"   -> pure TlsValidateCA
+      Just other  -> throwIO (userError ("Unknown verify mode: " ++ other))
+      Nothing     -> pure TlsValidateCA
+  mTlsCertPem <- lookupEnv "TPG_TLS_ROOT_CERT"
+  dbTls <- case mTlsCertPem of
+    Just certPem ->
+      case pgTlsValidate tlsVerifyMode (BSC.pack certPem) of
+        Right x  -> pure x
+        Left err -> throwIO (userError err)
+    Nothing | tlsEnabled -> pure TlsNoValidate
+    Nothing -> pure TlsDisabled
+#endif
   return $ defaultPGDatabase
-    { pgDBHost = host
-    , pgDBPort = port
+    { pgDBAddr = either (Right . Net.SockAddrUnix) (Left . (,) host) port
     , pgDBName = BSU.fromString db
     , pgDBUser = BSU.fromString user
     , pgDBPass = BSU.fromString pass
     , pgDBDebug = debug
+#ifdef VERSION_tls
+    , pgDBTLS = dbTls
+#endif
     }
 
 {-# NOINLINE tpgState #-}
diff --git a/Database/PostgreSQL/Typed/TemplatePG.hs b/Database/PostgreSQL/Typed/TemplatePG.hs
--- a/Database/PostgreSQL/Typed/TemplatePG.hs
+++ b/Database/PostgreSQL/Typed/TemplatePG.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE TemplateHaskell #-}
+{-# OPTIONS_GHC -Wno-deprecations #-}
 -- Copyright 2010, 2011, 2012, 2013 Chris Forno
 
 -- |This module exposes the high-level Template Haskell interface for querying
@@ -22,15 +23,16 @@
   , PG.pgDisconnect
   ) where
 
-import Control.Exception (catchJust)
-import Control.Monad (liftM, void, guard)
-import Data.ByteString (ByteString)
+import           Control.Exception (catchJust)
+import           Control.Monad (liftM, void, guard)
+import           Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as BSC
 import qualified Data.ByteString.Lazy.Char8 as BSLC
-import Data.Maybe (listToMaybe, isJust)
+import           Data.Maybe (listToMaybe, isJust)
 import qualified Language.Haskell.TH as TH
-import Network (HostName, PortID(..))
-import System.Environment (lookupEnv)
+import           Network (HostName, PortID(..))
+import qualified Network.Socket as Net
+import           System.Environment (lookupEnv)
 
 import qualified Database.PostgreSQL.Typed.Protocol as PG
 import Database.PostgreSQL.Typed.Query
@@ -98,8 +100,10 @@
 pgConnect h n d u p = do
   debug <- isJust `liftM` lookupEnv "TPG_DEBUG"
   PG.pgConnect $ PG.defaultPGDatabase
-    { PG.pgDBHost = h
-    , PG.pgDBPort = n
+    { PG.pgDBAddr = case n of
+        PortNumber s -> Left (h, show s)
+        Service    s -> Left (h, s)
+        UnixSocket s -> Right (Net.SockAddrUnix s)
     , PG.pgDBName = d
     , PG.pgDBUser = u
     , PG.pgDBPass = p
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# Haskell PostgreSQL-typed
+
+A Haskell PostgreSQL interface that provides type-safety through compile-time (template Haskell) database access.
+See the [Haddock](http://hackage.haskell.org/package/postgresql-typed) documentation in [Database.PostgreSQL.Typed](http://hackage.haskell.org/package/postgresql-typed/docs/Database-PostgreSQL-Typed.html) or the [test cases](test/Main.hs) for simple examples.
+
+[![Build Status](https://travis-ci.org/dylex/postgresql-typed.svg?branch=master)](https://travis-ci.org/dylex/postgresql-typed)
diff --git a/postgresql-typed.cabal b/postgresql-typed.cabal
--- a/postgresql-typed.cabal
+++ b/postgresql-typed.cabal
@@ -1,9 +1,9 @@
 Name:          postgresql-typed
-Version:       0.5.3.0
+Version:       0.6
 Cabal-Version: >= 1.8
 License:       BSD3
 License-File:  COPYING
-Copyright:     2010-2013 Chris Forno, 2014-2017 Dylan Simon
+Copyright:     2010-2013 Chris Forno, 2014-2019 Dylan Simon
 Author:        Dylan Simon
 Maintainer:    Dylan Simon <dylan-pgtyped@dylex.net>
 Stability:     provisional
@@ -21,6 +21,7 @@
                Originally based on Chris Forno's templatepg library.
 Tested-With:   GHC == 7.10.3, GHC == 8.0.1
 Build-Type:    Simple
+extra-source-files: README.md
 
 source-repository head
   type:     git
@@ -53,6 +54,10 @@
 Flag HDBC
   Description: Provide an HDBC driver backend using the raw PostgreSQL protocol.
 
+Flag tls
+  Description: Enable TLS (SSL) support in PostgreSQL server connections.
+  Default: True
+
 Library
   Build-Depends:
     base >= 4.8 && < 5,
@@ -103,6 +108,8 @@
     Build-Depends: HDBC >= 2.2
     Exposed-Modules:
       Database.PostgreSQL.Typed.HDBC
+  if flag(tls)
+    Build-Depends: data-default, tls, x509, x509-store, x509-validation
 
 test-suite test
   type: exitcode-stdio-1.0
@@ -112,6 +119,8 @@
   Extensions: TemplateHaskell, QuasiQuotes
   build-depends: base, network, time, bytestring, postgresql-typed, QuickCheck
   GHC-Options: -Wall
+  if flag(tls)
+    Build-Depends: tls
 
 test-suite hdbc
   type: exitcode-stdio-1.0
@@ -127,6 +136,23 @@
     Testbasics
     Tests
   if flag(HDBC)
-    build-depends: base, network, time, containers, convertible, postgresql-typed, HDBC, HUnit
+    build-depends: base, bytestring, network, time, containers, convertible, postgresql-typed, HDBC, HUnit
   else
     buildable: False
+  if flag(tls)
+    Build-Depends: tls
+
+benchmark bench
+  type: exitcode-stdio-1.0
+  hs-source-dirs: test
+  main-is: Bench.hs
+  other-modules: Connect
+  build-depends:
+    base,
+    bytestring,
+    time,
+    network,
+    criterion,
+    postgresql-typed
+  if flag(tls)
+    Build-Depends: tls
diff --git a/test/Bench.hs b/test/Bench.hs
new file mode 100644
--- /dev/null
+++ b/test/Bench.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE TemplateHaskell, QuasiQuotes, DataKinds #-}
+module Main (main) where
+
+import qualified Data.ByteString as BS
+import           Data.Int (Int16, Int32, Int64)
+import qualified Data.Time as Time
+import qualified Criterion.Main as C
+import           System.Exit (exitSuccess, exitFailure)
+
+import Database.PostgreSQL.Typed
+import Database.PostgreSQL.Typed.Types
+import Database.PostgreSQL.Typed.Query
+
+import Connect
+
+useTPGDatabase db
+
+selectTypes :: PGConnection -> IO [(String, OID, Int16, Bool, Maybe BS.ByteString)]
+selectTypes c = pgQuery c [pgSQL|SELECT typname, typnamespace, typlen, typbyval, typdefault FROM pg_catalog.pg_type|]
+
+selectTypesLazy :: PGConnection -> IO [(String, OID, Int16, Bool, Maybe BS.ByteString)]
+selectTypesLazy c = pgLazyQuery c [pgSQL|$SELECT typname, typnamespace, typlen, typbyval, typdefault FROM pg_catalog.pg_type|] 1
+
+selectParams :: PGConnection -> IO [(Maybe String, Maybe Int64, Maybe Double, Maybe BS.ByteString, Maybe Bool)]
+selectParams c = pgQuery c [pgSQL|$SELECT ${"hello"}::text, ${123::Int64}::bigint, ${123.4::Double}::float, ${BS.pack [120..220]}::bytea, ${Nothing::Maybe Bool}::boolean|]
+
+selectValues :: PGConnection -> IO [(Int32, Time.UTCTime)]
+selectValues c = pgQuery c [pgSQL|!SELECT generate_series, now() FROM generate_series(8,256)|]
+
+selectValuesLazy :: PGConnection -> IO [(Int32, Time.UTCTime)]
+selectValuesLazy c = pgLazyQuery c [pgSQL|$!SELECT generate_series, now() FROM generate_series(8,256)|] 5
+
+main :: IO ()
+main = do
+  c <- pgConnect db
+  C.defaultMain
+    [ C.bench "types" $ C.nfIO $ selectTypes c
+    , C.bench "types lazy" $ C.nfIO $ selectTypesLazy c
+    , C.bench "params" $ C.nfIO $ selectParams c
+    , C.bench "values" $ C.nfIO $ selectValues c
+    , C.bench "values lazy" $ C.nfIO $ selectValuesLazy c
+    ]
diff --git a/test/Connect.hs b/test/Connect.hs
--- a/test/Connect.hs
+++ b/test/Connect.hs
@@ -1,17 +1,58 @@
-{-# LANGUAGE CPP, OverloadedStrings #-}
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE NamedFieldPuns    #-}
+{-# LANGUAGE OverloadedStrings #-}
 module Connect where
 
-import Database.PostgreSQL.Typed (PGDatabase(..), defaultPGDatabase)
-import Network (PortID(UnixSocket))
+#ifdef VERSION_tls
+import           Control.Exception                  (throwIO)
+#endif
+import qualified Data.ByteString.Char8              as BSC
+import           Data.Maybe                         (fromMaybe, isJust)
+import           Database.PostgreSQL.Typed          (PGDatabase (..),
+                                                     defaultPGDatabase)
+#ifdef VERSION_tls
+import           Database.PostgreSQL.Typed.Protocol (PGTlsMode (..),
+                                                     PGTlsValidateMode (..),
+                                                     pgTlsValidate)
+#endif
+import           Network.Socket                     (SockAddr (SockAddrUnix))
+import           System.Environment                 (lookupEnv)
+import           System.IO.Unsafe                   (unsafePerformIO)
 
 db :: PGDatabase
-db = defaultPGDatabase
-  { pgDBName = "templatepg"
+db = unsafePerformIO $ do
+  mPort <- lookupEnv "PGPORT"
+  pgDBAddr <- case mPort of
+    Nothing ->
 #ifndef mingw32_HOST_OS
-  , pgDBPort = UnixSocket "/tmp/.s.PGSQL.5432"
+      Right . SockAddrUnix . fromMaybe "/tmp/.s.PGSQL.5432" <$> lookupEnv "PGSOCK"
+#else
+      pure $ pgDBAddr defaultPGDatabase
 #endif
-  , pgDBUser = "templatepg"
-  -- , pgDBDebug = True
-  , pgDBParams = [("TimeZone", "UTC")]
-  }
-
+    Just port -> pure $ Left ("localhost", port)
+#ifdef VERSION_tls
+  pgDBTLS <- do
+    enabled <- isJust <$> lookupEnv "PGTLS"
+    validateFull <- isJust <$> lookupEnv "PGTLS_VALIDATEFULL"
+    rootcert <- fmap BSC.pack <$> lookupEnv "PGTLS_ROOTCERT"
+    case (enabled,validateFull,rootcert) of
+      (False,_,_) -> pure TlsDisabled
+      (True,False,Nothing) -> pure TlsNoValidate
+      (True,True,Just cert) -> either (throwIO . userError) pure $ pgTlsValidate TlsValidateFull cert
+      (True,True,Nothing) -> throwIO $ userError "Need to pass the root certificate on the PGTLS_ROOTCERT environment variable to validate FQHN"
+      (True,False,Just cert) -> either (throwIO . userError) pure $ pgTlsValidate TlsValidateCA cert
+#endif
+  pgDBPass <- maybe BSC.empty BSC.pack <$> lookupEnv "PG_PASS"
+  pgDBDebug <- isJust <$> lookupEnv "PG_DEBUG"
+  pure $ defaultPGDatabase
+    { pgDBName = "templatepg"
+    , pgDBUser = "templatepg"
+    , pgDBParams = [("TimeZone", "UTC")]
+    , pgDBDebug
+#ifdef VERSION_tls
+    , pgDBTLS
+#endif
+    , pgDBAddr
+    , pgDBPass
+    }
+{-# NOINLINE db #-}
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,9 +1,10 @@
 {-# LANGUAGE OverloadedStrings, FlexibleInstances, MultiParamTypeClasses, DataKinds, DeriveDataTypeable, TypeFamilies, PatternGuards, StandaloneDeriving #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -fno-warn-orphans -Wincomplete-uni-patterns #-}
 --{-# OPTIONS_GHC -ddump-splices #-}
 module Main (main) where
 
 import Control.Exception (try)
+import Control.Monad (unless)
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Char8 as BSC
 import Data.Char (isDigit, toUpper)
@@ -171,8 +172,10 @@
     Left e2 <- try $ pgSimpleQuery c "SELECT 1"
     assert $ pgErrorCode e2 == PGErr.in_failed_sql_transaction
 
-  [PGNotification _ "channame" "there", PGNotification _ "channame" ""] <- pgGetNotifications c
-  [] <- pgGetNotifications c
+  unless (pgSupportsTls c) $ do
+    [PGNotification _ "channame" "there", PGNotification _ "channame" ""] <- pgGetNotifications c
+    [] <- pgGetNotifications c
+    pure ()
 
   pgDisconnect c
   exitSuccess
