diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,16 @@
 
 ### Fixed
 
+## [7.0.1] - 2020-05-18
+
+### Fixed
+
+- #1473, Fix overloaded computed columns on RPC - @wolfgangwalther
+- #1471, Fix POST, PATCH, DELETE with ?select= and return=minimal and PATCH with empty body - @wolfgangwalther
+- #1500, Fix missing `openapi-server-proxy-uri` config option - @steve-chavez
+- #1508, Fix `Content-Profile` not working for POST RPC - @steve-chavez
+- #1452, Fix PUT restriction for all columns - @steve-chavez
+
 ## [7.0.0] - 2020-04-03
 
 ### Added
diff --git a/main/Main.hs b/main/Main.hs
--- a/main/Main.hs
+++ b/main/Main.hs
@@ -17,8 +17,7 @@
                                  readIORef)
 import Data.String              (IsString (..))
 import Data.Text                (pack, replace, strip, stripPrefix)
-import Data.Text.Encoding       (decodeUtf8, encodeUtf8)
-import Data.Text.IO             (hPutStrLn, readFile)
+import Data.Text.IO             (hPutStrLn)
 import Data.Time.Clock          (getCurrentTime)
 import Network.Wai.Handler.Warp (defaultSettings, runSettings,
                                  setHost, setPort, setServerName)
@@ -34,7 +33,8 @@
 import PostgREST.Types       (ConnectionStatus (..), DbStructure,
                               PgVersion (..), Schema,
                               minimumPgVersion)
-import Protolude             hiding (hPutStrLn, head, replace)
+import Protolude             hiding (hPutStrLn, head, replace, toS)
+import Protolude.Conv        (toS)
 
 
 #ifndef mingw32_HOST_OS
diff --git a/postgrest.cabal b/postgrest.cabal
--- a/postgrest.cabal
+++ b/postgrest.cabal
@@ -1,5 +1,5 @@
 name:               postgrest
-version:            7.0.0
+version:            7.0.1
 synopsis:           REST API for any Postgres database
 description:        Reads the schema of a PostgreSQL database and creates RESTful routes
                     for the tables and views, supporting all HTTP verbs that security
@@ -19,10 +19,10 @@
   type:     git
   location: git://github.com/PostgREST/postgrest.git
 
-flag ci
+flag FailOnWarn
   default:     False
   manual:      True
-  description: No warnings allowed in continuous integration
+  description: No warnings allowed
 
 library
   exposed-modules:    PostgREST.ApiRequest
@@ -43,12 +43,12 @@
                       PostgREST.Private.Common
                       PostgREST.Private.QueryFragment
   hs-source-dirs:     src
-  build-depends:      base                      >= 4.9 && < 4.14
+  build-depends:      base                      >= 4.9 && < 4.15
                     , HTTP                      >= 4000.3.7 && < 4000.4
                     , Ranged-sets               >= 0.3 && < 0.5
-                    , aeson                     >= 0.11.3 && < 1.5
+                    , aeson                     >= 1.4.7 && < 1.5
                     , ansi-wl-pprint            >= 0.6.7 && < 0.7
-                    , base64-bytestring         >= 1 && < 1.1
+                    , base64-bytestring         >= 1 && < 1.2
                     , bytestring                >= 0.10.8 && < 0.11
                     , case-insensitive          >= 1.2 && < 1.3
                     , cassava                   >= 0.4.5 && < 0.6
@@ -67,17 +67,17 @@
                     , insert-ordered-containers >= 0.2.2 && < 0.3
                     , interpolatedstring-perl6  >= 1 && < 1.1
                     , jose                      >= 0.8.1 && < 0.9
-                    , lens                      >= 4.14 && < 4.19
+                    , lens                      >= 4.14 && < 4.20
                     , lens-aeson                >= 1.0.1 && < 1.2
-                    , network-uri               >= 2.6.1 && < 2.7
+                    , network-uri               >= 2.6.1 && < 2.8
                     , optparse-applicative      >= 0.13 && < 0.16
                     , parsec                    >= 3.1.11 && < 3.2
-                    , protolude                 >= 0.2.2 && < 0.3
+                    , protolude                 >= 0.3 && < 0.4
                     , regex-tdfa                >= 1.2.2 && < 1.4
                     , scientific                >= 0.3.4 && < 0.4
-                    , swagger2                  >= 2.4 && < 2.6
+                    , swagger2                  >= 2.4 && < 2.7
                     , text                      >= 1.2.2 && < 1.3
-                    , time                      >= 1.6 && < 1.10
+                    , time                      >= 1.6 && < 1.11
                     , unordered-containers      >= 0.2.8 && < 0.3
                     , vector                    >= 0.11 && < 0.13
                     , wai                       >= 3.2.1 && < 3.3
@@ -88,13 +88,24 @@
   default-extensions: OverloadedStrings
                       QuasiQuotes
                       NoImplicitPrelude
+  if flag(FailOnWarn)
+    ghc-options: -O2 -Werror -Wall -fwarn-identities
+                 -fno-spec-constr -optP-Wno-nonportable-include-path
+  else
+    ghc-options: -O2 -Wall -fwarn-identities
+                 -fno-spec-constr -optP-Wno-nonportable-include-path
+          -- -fno-spec-constr may help keep compile time memory use in check,
+          --   see https://gitlab.haskell.org/ghc/ghc/issues/16017#note_219304
+          -- -optP-Wno-nonportable-include-path
+          --   prevents build failures on case-insensitive filesystems (macos),
+          --   see https://github.com/commercialhaskell/stack/issues/3918
 
 executable postgrest
   main-is:            Main.hs
   hs-source-dirs:     main
-  build-depends:      base              >= 4.9 && < 4.14
+  build-depends:      base              >= 4.9 && < 4.15
                     , auto-update       >= 0.1.4 && < 0.2
-                    , base64-bytestring >= 1 && < 1.1
+                    , base64-bytestring >= 1 && < 1.2
                     , bytestring        >= 0.10.8 && < 0.11
                     , directory         >= 1.2.6 && < 1.4
                     , either            >= 4.4.1 && < 5.1
@@ -103,17 +114,24 @@
                     , hasql-transaction >= 0.7.2 && < 1.1
                     , network           < 3.2
                     , postgrest
-                    , protolude         >= 0.2.2 && < 0.3
+                    , protolude         >= 0.3 && < 0.4
                     , retry             >= 0.7.4 && < 0.9
                     , text              >= 1.2.2 && < 1.3
-                    , time              >= 1.6 && < 1.10
+                    , time              >= 1.6 && < 1.11
                     , wai               >= 3.2.1 && < 3.3
                     , warp              >= 3.2.12 && < 3.4
   default-language:   Haskell2010
   default-extensions: OverloadedStrings
                       QuasiQuotes
                       NoImplicitPrelude
-  ghc-options:        -threaded -rtsopts "-with-rtsopts=-N -I2"
+  if flag(FailOnWarn)
+    ghc-options:      -threaded -rtsopts "-with-rtsopts=-N -I2"
+                      -O2 -Werror -Wall -fwarn-identities
+                      -fno-spec-constr -optP-Wno-nonportable-include-path
+  else
+    ghc-options:      -threaded -rtsopts "-with-rtsopts=-N -I2"
+                      -O2 -Wall -fwarn-identities
+                      -fno-spec-constr -optP-Wno-nonportable-include-path
 
   if !os(windows)
     build-depends: unix
@@ -154,12 +172,12 @@
                       SpecHelper
                       TestTypes
   hs-source-dirs:     test
-  build-depends:      base              >= 4.9 && < 4.14
-                    , aeson             >= 0.11.3 && < 1.5
+  build-depends:      base              >= 4.9 && < 4.15
+                    , aeson             >= 1.4.7 && < 1.5
                     , aeson-qq          >= 0.8.1 && < 0.9
                     , async             >= 2.1.1 && < 2.3
                     , auto-update       >= 0.1.4 && < 0.2
-                    , base64-bytestring >= 1 && < 1.1
+                    , base64-bytestring >= 1 && < 1.2
                     , bytestring        >= 0.10.8 && < 0.11
                     , case-insensitive  >= 1.2 && < 1.3
                     , cassava           >= 0.4.5 && < 0.6
@@ -173,15 +191,15 @@
                     , hspec-wai         >= 0.10 && < 0.11
                     , hspec-wai-json    >= 0.10 && < 0.11
                     , http-types        >= 0.12.3 && < 0.13
-                    , lens              >= 4.14 && < 4.19
+                    , lens              >= 4.14 && < 4.20
                     , lens-aeson        >= 1.0.1 && < 1.2
                     , monad-control     >= 1.0.1 && < 1.1
                     , postgrest
                     , process           >= 1.4.2 && < 1.7
-                    , protolude         >= 0.2.2 && < 0.3
+                    , protolude         >= 0.3 && < 0.4
                     , regex-tdfa        >= 1.2.2 && < 1.4
                     , text              >= 1.2.2 && < 1.3
-                    , time              >= 1.6 && < 1.10
+                    , time              >= 1.6 && < 1.11
                     , transformers-base >= 0.4.4 && < 0.5
                     , wai               >= 3.2.1 && < 3.3
                     , wai-extra         >= 3.0.19 && < 3.1
@@ -198,12 +216,12 @@
   Hs-Source-Dirs:      test
   Main-Is:             QueryCost.hs
   Other-Modules:       SpecHelper
-  Build-Depends:       base              >= 4.9 && < 4.14
-                     , aeson             >= 0.11.3 && < 1.5
+  Build-Depends:       base              >= 4.9 && < 4.15
+                     , aeson             >= 1.4.7 && < 1.5
                      , aeson-qq          >= 0.8.1 && < 0.9
                      , async             >= 2.1.1 && < 2.3
                      , auto-update       >= 0.1.4 && < 0.2
-                     , base64-bytestring >= 1 && < 1.1
+                     , base64-bytestring >= 1 && < 1.2
                      , bytestring        >= 0.10.8 && < 0.11
                      , case-insensitive  >= 1.2 && < 1.3
                      , cassava           >= 0.4.5 && < 0.6
@@ -217,15 +235,15 @@
                      , hspec-wai         >= 0.10 && < 0.11
                      , hspec-wai-json    >= 0.10 && < 0.11
                      , http-types        >= 0.12.3 && < 0.13
-                     , lens              >= 4.14 && < 4.19
+                     , lens              >= 4.14 && < 4.20
                      , lens-aeson        >= 1.0.1 && < 1.2
                      , monad-control     >= 1.0.1 && < 1.1
                      , postgrest
                      , process           >= 1.4.2 && < 1.7
-                     , protolude         >= 0.2.2 && < 0.3
+                     , protolude         >= 0.3 && < 0.4
                      , regex-tdfa        >= 1.2.2 && < 1.4
                      , text              >= 1.2.2 && < 1.3
-                     , time              >= 1.6 && < 1.10
+                     , time              >= 1.6 && < 1.11
                      , transformers-base >= 0.4.4 && < 0.5
                      , wai               >= 3.2.1 && < 3.3
                      , wai-extra         >= 3.0.19 && < 3.1
diff --git a/src/PostgREST/ApiRequest.hs b/src/PostgREST/ApiRequest.hs
--- a/src/PostgREST/ApiRequest.hs
+++ b/src/PostgREST/ApiRequest.hs
@@ -28,8 +28,8 @@
 
 import Control.Arrow             ((***))
 import Data.Aeson.Types          (emptyArray, emptyObject)
-import Data.List                 (elem, last, lookup, partition)
-import Data.List.NonEmpty        (NonEmpty, head)
+import Data.List                 (last, lookup, partition)
+import Data.List.NonEmpty        (head)
 import Data.Maybe                (fromJust)
 import Data.Ranged.Ranges        (Range (..), emptyRange,
                                   rangeIntersection)
@@ -49,7 +49,8 @@
                              rangeLimit, rangeOffset, rangeRequested,
                              restrictRange)
 import PostgREST.Types
-import Protolude            hiding (head)
+import Protolude            hiding (head, toS)
+import Protolude.Conv       (toS)
 
 type RequestBody = BL.ByteString
 
@@ -190,11 +191,10 @@
       (CTOther "application/x-www-form-urlencoded", _) ->
         let json = M.fromList . map (toS *** JSON.String . toS) . parseSimpleQuery $ toS reqBody
             keys = S.fromList $ M.keys json in
-        Right $ ProcessedJSON (JSON.encode json) PJObject keys
+        Right $ ProcessedJSON (JSON.encode json) keys
       (ct, _) ->
         Left $ toS $ "Content-Type not acceptable: " <> toMime ct
-  rpcPrmsToJson = ProcessedJSON (JSON.encode $ M.fromList $ second JSON.toJSON <$> rpcQParams)
-                  PJObject (S.fromList $ fst <$> rpcQParams)
+  rpcPrmsToJson = ProcessedJSON (JSON.encode $ M.fromList $ second JSON.toJSON <$> rpcQParams) (S.fromList $ fst <$> rpcQParams)
   topLevelRange = fromMaybe allRange $ M.lookup "limit" ranges -- if no limit is specified, get all the request rows
   action =
     case method of
@@ -219,9 +219,9 @@
   profile
     | length confSchemas <= 1 -- only enable content negotiation by profile when there are multiple schemas specified in the config
       = Nothing
-    | action `elem` [ActionCreate, ActionUpdate, ActionSingleUpsert, ActionDelete] -- POST/PATCH/PUT/DELETE don't use the same header as per the spec
+    | action `elem` [ActionCreate, ActionUpdate, ActionSingleUpsert, ActionDelete, ActionInvoke InvPost] -- POST/PATCH/PUT/DELETE don't use the same header as per the spec
       = Just $ maybe defaultSchema toS $ lookupHeader "Content-Profile"
-    | action `elem` [ActionRead True, ActionRead False, ActionInvoke InvGet, ActionInvoke InvHead, ActionInvoke InvPost,
+    | action `elem` [ActionRead True, ActionRead False, ActionInvoke InvGet, ActionInvoke InvHead,
                      ActionInspect False, ActionInspect True, ActionInfo]
       = Just $ maybe defaultSchema toS $ lookupHeader "Accept-Profile"
     | otherwise = Nothing
@@ -333,14 +333,14 @@
                 JSON.Object x -> S.fromList (M.keys x) == canonicalKeys
                 _ -> False) arr in
           if areKeysUniform
-            then Just $ ProcessedJSON raw (PJArray $ V.length arr) canonicalKeys
+            then Just $ ProcessedJSON raw canonicalKeys
             else Nothing
         Just _ -> Nothing
         Nothing -> Just emptyPJArray
 
-    JSON.Object o -> Just $ ProcessedJSON raw PJObject (S.fromList $ M.keys o)
+    JSON.Object o -> Just $ ProcessedJSON raw (S.fromList $ M.keys o)
 
     -- truncate everything else to an empty array.
     _ -> Just emptyPJArray
   where
-    emptyPJArray = ProcessedJSON (JSON.encode emptyArray) (PJArray 0) S.empty
+    emptyPJArray = ProcessedJSON (JSON.encode emptyArray) S.empty
diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs
--- a/src/PostgREST/App.hs
+++ b/src/PostgREST/App.hs
@@ -40,13 +40,13 @@
 import Network.Wai
 
 import PostgREST.ApiRequest       (Action (..), ApiRequest (..),
-                                   ContentType (..),
                                    InvokeMethod (..), Target (..),
                                    mutuallyAgreeable, userApiRequest)
 import PostgREST.Auth             (containsRole, jwtClaims,
                                    parseSecret)
 import PostgREST.Config           (AppConfig (..))
-import PostgREST.DbRequestBuilder (mutateRequest, readRequest)
+import PostgREST.DbRequestBuilder (mutateRequest, readRequest,
+                                   returningCols)
 import PostgREST.DbStructure
 import PostgREST.Error            (PgError (..), SimpleError (..),
                                    errorResponseFor, singularityError)
@@ -64,7 +64,8 @@
                                    createReadStatement,
                                    createWriteStatement)
 import PostgREST.Types
-import Protolude                  hiding (Proxy, intercalate)
+import Protolude                  hiding (Proxy, intercalate, toS)
+import Protolude.Conv             (toS)
 
 postgrest :: AppConfig -> IORef (Maybe DbStructure) -> P.Pool -> IO UTCTime -> IO () -> Application
 postgrest conf refDbStructure pool getTime worker =
@@ -127,7 +128,7 @@
         (ActionRead headersOnly, TargetIdent (QualifiedIdentifier tSchema tName), Nothing) ->
           case readSqlParts tSchema tName of
             Left errorResponse -> return errorResponse
-            Right (q, cq, bField) -> do
+            Right (q, cq, bField, _) -> do
               let cQuery = if estimatedCount
                              then limitedQuery cq ((+ 1) <$> maxRows) -- LIMIT maxRows + 1 so we can determine below that maxRows was surpassed
                              else cq
@@ -180,7 +181,7 @@
                         , Just $ contentRangeH 1 0 $ if shouldCount then Just queryTotal else Nothing
                         , if null pkCols && isNothing (iOnConflict apiRequest)
                             then Nothing
-                            else (\x -> ("Preference-Applied", show x)) <$> iPreferResolution apiRequest
+                            else (\x -> ("Preference-Applied", encodeUtf8 (show x))) <$> iPreferResolution apiRequest
                         ] ++ ctHeaders)) (unwrapGucHeader <$> ghdrs)
                   if contentType == CTSingularJSON && queryTotal /= 1
                     then do
@@ -218,22 +219,14 @@
                     else
                       return $ responseLBS status headers rBody
 
-        (ActionSingleUpsert, TargetIdent (QualifiedIdentifier tSchema tName), Just ProcessedJSON{pjRaw, pjType, pjKeys}) ->
+        (ActionSingleUpsert, TargetIdent (QualifiedIdentifier tSchema tName), Just pJson) ->
           case mutateSqlParts tSchema tName of
             Left errorResponse -> return errorResponse
-            Right (sq, mq) -> do
-              let isSingle = case pjType of
-                               PJArray len -> len == 1
-                               PJObject    -> True
-                  colNames = colName <$> tableCols dbStructure tSchema tName
+            Right (sq, mq) ->
               if topLevelRange /= allRange
                 then return . errorResponseFor $ PutRangeNotAllowedError
-              else if not isSingle
-                then return . errorResponseFor $ PutSingletonError
-              else if S.fromList colNames /= pjKeys
-                then return . errorResponseFor $ PutPayloadIncompleteError
               else do
-                row <- H.statement (toS pjRaw) $
+                row <- H.statement (toS $ pjRaw pJson) $
                        createWriteStatement sq mq (contentType == CTSingularJSON) False
                                             (contentType == CTTextCSV) (iPreferRepresentation apiRequest) [] pgVer
                 let (_, queryTotal, _, body, gucHeaders) = row
@@ -293,10 +286,10 @@
           let tName = fromMaybe pName $ procTableName =<< proc in
           case readSqlParts tSchema tName of
             Left errorResponse -> return errorResponse
-            Right (q, cq, bField) -> do
+            Right (q, cq, bField, returning) -> do
               let
                 preferParams = iPreferParameters apiRequest
-                pq = requestToCallProcQuery qi (specifiedProcArgs cols proc) returnsScalar preferParams
+                pq = requestToCallProcQuery qi (specifiedProcArgs cols proc) returnsScalar preferParams returning
                 stm = callProcStatement returnsScalar pq q cq shouldCount (contentType == CTSingularJSON)
                         (contentType == CTTextCSV) (contentType `elem` rawContentTypes) (preferParams == Just MultipleObjects)
                         bField pgVer
@@ -351,11 +344,14 @@
         readSqlParts s t =
           let
             readReq = readRequest s t maxRows (dbRelations dbStructure) apiRequest
+            returnings :: ReadRequest -> Either Response [FieldName]
+            returnings rr = Right (returningCols rr)
           in
-          (,,) <$>
+          (,,,) <$>
           (readRequestToQuery <$> readReq) <*>
           (readRequestToCountQuery <$> readReq) <*>
-          (binaryField contentType rawContentTypes returnsScalar =<< readReq)
+          (binaryField contentType rawContentTypes returnsScalar =<< readReq) <*>
+          (returnings =<< readReq)
 
         mutateSqlParts s t =
           let
diff --git a/src/PostgREST/Auth.hs b/src/PostgREST/Auth.hs
--- a/src/PostgREST/Auth.hs
+++ b/src/PostgREST/Auth.hs
@@ -31,7 +31,8 @@
 import Crypto.JWT
 
 import PostgREST.Types
-import Protolude
+import Protolude       hiding (toS)
+import Protolude.Conv  (toS)
 
 {-|
   Possible situations encountered with client JWTs
diff --git a/src/PostgREST/Config.hs b/src/PostgREST/Config.hs
--- a/src/PostgREST/Config.hs
+++ b/src/PostgREST/Config.hs
@@ -32,17 +32,15 @@
 import qualified Data.Configurator            as C
 import qualified Text.PrettyPrint.ANSI.Leijen as L
 
-import Control.Exception           (Handler (..))
 import Control.Lens                (preview)
 import Control.Monad               (fail)
 import Crypto.JWT                  (StringOrURI, stringOrUri)
 import Data.List                   (lookup)
-import Data.List.NonEmpty          (NonEmpty, fromList)
+import Data.List.NonEmpty          (fromList)
 import Data.Scientific             (floatingOrInteger)
 import Data.Text                   (dropEnd, dropWhileEnd,
-                                    intercalate, lines, splitOn,
-                                    strip, take, unpack)
-import Data.Text.Encoding          (encodeUtf8)
+                                    intercalate, splitOn, strip, take,
+                                    unpack)
 import Data.Text.IO                (hPutStrLn)
 import Data.Version                (versionBranch)
 import Development.GitRev          (gitHash)
@@ -63,8 +61,8 @@
 import PostgREST.Parsers (pRoleClaimKey)
 import PostgREST.Types   (JSPath, JSPathExp (..))
 import Protolude         hiding (concat, hPutStrLn, intercalate, null,
-                          take, (<>))
-
+                          take, toS, (<>))
+import Protolude.Conv    (toS)
 
 
 -- | Config file settings for the server
@@ -155,7 +153,7 @@
       AppConfig
         <$> reqString "db-uri"
         <*> reqString "db-anon-role"
-        <*> optString "server-proxy-uri"
+        <*> optString "openapi-server-proxy-uri"
         <*> (fromList . splitOnCommas <$> reqValue "db-schema")
         <*> (fromMaybe "!4" <$> optString "server-host")
         <*> (fromMaybe 3000 <$> optInt "server-port")
diff --git a/src/PostgREST/DbRequestBuilder.hs b/src/PostgREST/DbRequestBuilder.hs
--- a/src/PostgREST/DbRequestBuilder.hs
+++ b/src/PostgREST/DbRequestBuilder.hs
@@ -14,6 +14,7 @@
 module PostgREST.DbRequestBuilder (
   readRequest
 , mutateRequest
+, returningCols
 ) where
 
 import qualified Data.HashMap.Strict as M
@@ -40,7 +41,7 @@
 readRequest schema rootTableName maxRows allRels apiRequest  =
   mapLeft errorResponseFor $
   treeRestrictRange maxRows =<<
-  augumentRequestWithJoin schema rootRels =<<
+  augmentRequestWithJoin schema rootRels =<<
   addFiltersOrdersRanges apiRequest <*>
   (initReadRequest rootName <$> pRequestSelect sel)
   where
@@ -89,8 +90,8 @@
     nodeRestrictRange :: Maybe Integer -> ReadNode -> ReadNode
     nodeRestrictRange m (q@Select {range_=r}, i) = (q{range_=restrictRange m r }, i)
 
-augumentRequestWithJoin :: Schema -> [Relation] -> ReadRequest -> Either ApiRequestError ReadRequest
-augumentRequestWithJoin schema allRels request =
+augmentRequestWithJoin :: Schema -> [Relation] -> ReadRequest -> Either ApiRequestError ReadRequest
+augmentRequestWithJoin schema allRels request =
   addRels schema allRels Nothing request
   >>= addJoinConditions Nothing
 
diff --git a/src/PostgREST/DbStructure.hs b/src/PostgREST/DbStructure.hs
--- a/src/PostgREST/DbStructure.hs
+++ b/src/PostgREST/DbStructure.hs
@@ -35,14 +35,13 @@
 import Data.Text                     (breakOn, dropAround, split,
                                       splitOn, strip)
 import GHC.Exts                      (groupWith)
+import Protolude                     hiding (toS)
+import Protolude.Conv                (toS)
+import Protolude.Unsafe              (unsafeHead)
 import Text.InterpolatedString.Perl6 (q, qc)
-import Unsafe                        (unsafeHead)
 
-import Control.Applicative
-
 import PostgREST.Private.Common
 import PostgREST.Types
-import Protolude
 
 getDbStructure :: [Schema] -> PgVersion -> HT.Transaction DbStructure
 getDbStructure schemas pgVer = do
@@ -190,14 +189,14 @@
 procsSqlQuery :: SqlQuery
 procsSqlQuery = [q|
   SELECT
-    pn.nspname as "proc_schema",
-    p.proname as "proc_name",
-    d.description as "proc_description",
-    pg_get_function_arguments(p.oid) as "args",
-    tn.nspname as "rettype_schema",
-    coalesce(comp.relname, t.typname) as "rettype_name",
-    p.proretset as "rettype_is_setof",
-    t.typtype as "rettype_typ",
+    pn.nspname as proc_schema,
+    p.proname as proc_name,
+    d.description as proc_description,
+    pg_get_function_arguments(p.oid) as args,
+    tn.nspname as rettype_schema,
+    coalesce(comp.relname, t.typname) as rettype_name,
+    p.proretset as rettype_is_setof,
+    t.typtype as rettype_typ,
     p.provolatile
   FROM pg_proc p
     JOIN pg_namespace pn ON pn.oid = p.pronamespace
@@ -229,11 +228,22 @@
       n.nspname as table_schema,
       relname as table_name,
       d.description as table_description,
-      c.relkind = 'r' or (c.relkind IN ('v', 'f')) and (pg_relation_is_updatable(c.oid::regclass, false) & 8) = 8
-      or (exists (
-         select 1
-         from pg_trigger
-         where pg_trigger.tgrelid = c.oid and (pg_trigger.tgtype::integer & 69) = 69)
+      (
+        c.relkind in ('r', 'v', 'f')
+        and (pg_relation_is_updatable(c.oid::regclass, false) & 8) = 8
+        -- The function `pg_relation_is_updateable` returns a bitmask where 8
+        -- corresponds to `1 << CMD_INSERT` in the PostgreSQL source code, i.e.
+        -- it's possible to insert into the relation.
+        or (exists (
+          select 1
+          from pg_trigger
+          where
+            pg_trigger.tgrelid = c.oid
+            and (pg_trigger.tgtype::integer & 69) = 69)
+            -- The trigger type `tgtype` is a bitmask where 69 corresponds to
+            -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_INSERT
+            -- in the PostgreSQL source code.
+        )
       ) as insertable
     from
       pg_class c
@@ -243,9 +253,9 @@
       c.relkind in ('v', 'r', 'm', 'f')
       and n.nspname = $1
       and (
-        pg_has_role(c.relowner, 'USAGE'::text)
-        or has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text)
-        or has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)
+        pg_has_role(c.relowner, 'USAGE')
+        or has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
+        or has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')
       )
     order by relname |]
 
@@ -374,13 +384,17 @@
       n.nspname AS table_schema,
       c.relname AS table_name,
       NULL AS table_description,
-      c.relkind = 'r' OR (c.relkind IN ('v','f'))
-      AND (pg_relation_is_updatable(c.oid::regclass, FALSE) & 8) = 8
-      OR (EXISTS
-        ( SELECT 1
+      (
+        c.relkind IN ('r', 'v','f')
+        AND (pg_relation_is_updatable(c.oid::regclass, FALSE) & 8) = 8
+        OR EXISTS (
+          SELECT 1
           FROM pg_trigger
-          WHERE pg_trigger.tgrelid = c.oid
-          AND (pg_trigger.tgtype::integer & 69) = 69) ) AS insertable
+          WHERE
+            pg_trigger.tgrelid = c.oid
+            AND (pg_trigger.tgtype::integer & 69) = 69
+        )
+      ) AS insertable
     FROM pg_class c
     JOIN pg_namespace n ON n.oid = c.relnamespace
     WHERE c.relkind IN ('v','r','m','f')
@@ -407,9 +421,7 @@
         info.column_default AS default_value,
         array_to_string(enum_info.vals, ',') AS enum
     FROM (
-        /*
         -- CTE based on pg_catalog to get PRIMARY/FOREIGN key and UNIQUE columns outside api schema
-        */
         WITH key_columns AS (
              SELECT
                r.oid AS r_oid,
@@ -437,19 +449,16 @@
         -- limit columns to the ones in the api schema or PK/FK columns
         */
         columns AS (
-            SELECT current_database()::information_schema.sql_identifier AS table_catalog,
-                nc.nspname::information_schema.sql_identifier AS table_schema,
-                c.relname::information_schema.sql_identifier AS table_name,
-                a.attname::information_schema.sql_identifier AS column_name,
+            SELECT
+                nc.nspname::name AS table_schema,
+                c.relname::name AS table_name,
+                a.attname::name AS column_name,
                 d.description AS description,
-                a.attnum::information_schema.cardinal_number AS ordinal_position,
-                pg_get_expr(ad.adbin, ad.adrelid)::information_schema.character_data AS column_default,
-                    CASE
-                        WHEN a.attnotnull OR t.typtype = 'd'::"char" AND t.typnotnull THEN 'NO'::text
-                        ELSE 'YES'::text
-                    END::information_schema.yes_or_no AS is_nullable,
+                a.attnum::integer AS ordinal_position,
+                pg_get_expr(ad.adbin, ad.adrelid)::text AS column_default,
+                not (a.attnotnull OR t.typtype = 'd' AND t.typnotnull) AS is_nullable,
                     CASE
-                        WHEN t.typtype = 'd'::"char" THEN
+                        WHEN t.typtype = 'd' THEN
                         CASE
                             WHEN bt.typelem <> 0::oid AND bt.typlen = (-1) THEN 'ARRAY'::text
                             WHEN nbt.nspname = 'pg_catalog'::name THEN format_type(t.typbasetype, NULL::integer)
@@ -461,77 +470,42 @@
                             WHEN nt.nspname = 'pg_catalog'::name THEN format_type(a.atttypid, NULL::integer)
                             ELSE format_type(a.atttypid, a.atttypmod)
                         END
-                    END::information_schema.character_data AS data_type,
-                information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_maximum_length,
-                information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_octet_length,
-                information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision,
-                information_schema._pg_numeric_precision_radix(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision_radix,
-                information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_scale,
-                information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS datetime_precision,
-                information_schema._pg_interval_type(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.character_data AS interval_type,
-                NULL::integer::information_schema.cardinal_number AS interval_precision,
-                NULL::character varying::information_schema.sql_identifier AS character_set_catalog,
-                NULL::character varying::information_schema.sql_identifier AS character_set_schema,
-                NULL::character varying::information_schema.sql_identifier AS character_set_name,
-                    CASE
-                        WHEN nco.nspname IS NOT NULL THEN current_database()
-                        ELSE NULL::name
-                    END::information_schema.sql_identifier AS collation_catalog,
-                nco.nspname::information_schema.sql_identifier AS collation_schema,
-                co.collname::information_schema.sql_identifier AS collation_name,
-                    CASE
-                        WHEN t.typtype = 'd'::"char" THEN current_database()
-                        ELSE NULL::name
-                    END::information_schema.sql_identifier AS domain_catalog,
-                    CASE
-                        WHEN t.typtype = 'd'::"char" THEN nt.nspname
-                        ELSE NULL::name
-                    END::information_schema.sql_identifier AS domain_schema,
-                    CASE
-                        WHEN t.typtype = 'd'::"char" THEN t.typname
-                        ELSE NULL::name
-                    END::information_schema.sql_identifier AS domain_name,
-                current_database()::information_schema.sql_identifier AS udt_catalog,
-                COALESCE(nbt.nspname, nt.nspname)::information_schema.sql_identifier AS udt_schema,
-                COALESCE(bt.typname, t.typname)::information_schema.sql_identifier AS udt_name,
-                NULL::character varying::information_schema.sql_identifier AS scope_catalog,
-                NULL::character varying::information_schema.sql_identifier AS scope_schema,
-                NULL::character varying::information_schema.sql_identifier AS scope_name,
-                NULL::integer::information_schema.cardinal_number AS maximum_cardinality,
-                a.attnum::information_schema.sql_identifier AS dtd_identifier,
-                'NO'::character varying::information_schema.yes_or_no AS is_self_referencing,
-                'NO'::character varying::information_schema.yes_or_no AS is_identity,
-                NULL::character varying::information_schema.character_data AS identity_generation,
-                NULL::character varying::information_schema.character_data AS identity_start,
-                NULL::character varying::information_schema.character_data AS identity_increment,
-                NULL::character varying::information_schema.character_data AS identity_maximum,
-                NULL::character varying::information_schema.character_data AS identity_minimum,
-                NULL::character varying::information_schema.yes_or_no AS identity_cycle,
-                'NEVER'::character varying::information_schema.character_data AS is_generated,
-                NULL::character varying::information_schema.character_data AS generation_expression,
-                CASE
-                    WHEN c.relkind = 'r'::"char" OR (c.relkind = ANY (ARRAY['v'::"char", 'f'::"char"])) AND pg_column_is_updatable(c.oid::regclass, a.attnum, false) THEN 'YES'::text
-                    ELSE 'NO'::text
-                END::information_schema.yes_or_no AS is_updatable
+                    END::text AS data_type,
+                information_schema._pg_char_max_length(
+                    information_schema._pg_truetypid(a.*, t.*),
+                    information_schema._pg_truetypmod(a.*, t.*)
+                )::integer AS character_maximum_length,
+                information_schema._pg_numeric_precision(
+                    information_schema._pg_truetypid(a.*, t.*),
+                    information_schema._pg_truetypmod(a.*, t.*)
+                )::integer AS numeric_precision,
+                COALESCE(bt.typname, t.typname)::name AS udt_name,
+                (
+                    c.relkind in ('r', 'v', 'f')
+                    AND pg_column_is_updatable(c.oid::regclass, a.attnum, false)
+                )::bool is_updatable
             FROM pg_attribute a
-               LEFT JOIN key_columns kc ON kc.conkey = a.attnum AND kc.c_oid = a.attrelid
-               LEFT JOIN pg_catalog.pg_description AS d ON d.objoid = a.attrelid and d.objsubid = a.attnum
-               LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
-               JOIN (pg_class c
-               JOIN pg_namespace nc ON c.relnamespace = nc.oid) ON a.attrelid = c.oid
-               JOIN (pg_type t
-               JOIN pg_namespace nt ON t.typnamespace = nt.oid) ON a.atttypid = t.oid
-               LEFT JOIN (pg_type bt
-               JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd'::"char" AND t.typbasetype = bt.oid
-               LEFT JOIN (pg_collation co
-               JOIN pg_namespace nco ON co.collnamespace = nco.oid) ON a.attcollation = co.oid AND (nco.nspname <> 'pg_catalog'::name OR co.collname <> 'default'::name)
+                LEFT JOIN key_columns kc
+                    ON kc.conkey = a.attnum AND kc.c_oid = a.attrelid
+                LEFT JOIN pg_catalog.pg_description AS d
+                    ON d.objoid = a.attrelid and d.objsubid = a.attnum
+                LEFT JOIN pg_attrdef ad
+                    ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
+                JOIN (pg_class c JOIN pg_namespace nc ON c.relnamespace = nc.oid)
+                    ON a.attrelid = c.oid
+                JOIN (pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid)
+                    ON a.atttypid = t.oid
+                LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid)
+                    ON t.typtype = 'd' AND t.typbasetype = bt.oid
+                LEFT JOIN (pg_collation co JOIN pg_namespace nco ON co.collnamespace = nco.oid)
+                    ON a.attcollation = co.oid AND (nco.nspname <> 'pg_catalog'::name OR co.collname <> 'default'::name)
             WHERE
                 NOT pg_is_other_temp_schema(nc.oid)
                 AND a.attnum > 0
                 AND NOT a.attisdropped
-                AND (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'f'::"char", 'm'::"char"]))
-                AND (nc.nspname = ANY ($1) OR kc.r_oid IS NOT NULL) /*--filter only columns that are FK/PK or in the api schema */
-              /*--AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_column_privilege(c.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'::text))*/
+                AND c.relkind in ('r', 'v', 'f', 'm')
+                -- Filter only columns that are FK/PK or in the api schema:
+                AND (nc.nspname = ANY ($1) OR kc.r_oid IS NOT NULL)
         )
         SELECT
             table_schema,
@@ -546,7 +520,6 @@
             numeric_precision,
             column_default,
             udt_name
-        /*-- FROM information_schema.columns*/
         FROM columns
         WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
     ) AS info
@@ -618,69 +591,36 @@
   H.Statement sql HE.noParams (decodePks tabs) True
  where
   sql = [q|
-    /*
     -- CTE to replace information_schema.table_constraints to remove owner limit
-    */
     WITH tc AS (
-        SELECT current_database()::information_schema.sql_identifier AS constraint_catalog,
-            nc.nspname::information_schema.sql_identifier AS constraint_schema,
-            c.conname::information_schema.sql_identifier AS constraint_name,
-            current_database()::information_schema.sql_identifier AS table_catalog,
-            nr.nspname::information_schema.sql_identifier AS table_schema,
-            r.relname::information_schema.sql_identifier AS table_name,
-                CASE c.contype
-                    WHEN 'c'::"char" THEN 'CHECK'::text
-                    WHEN 'f'::"char" THEN 'FOREIGN KEY'::text
-                    WHEN 'p'::"char" THEN 'PRIMARY KEY'::text
-                    WHEN 'u'::"char" THEN 'UNIQUE'::text
-                    ELSE NULL::text
-                END::information_schema.character_data AS constraint_type,
-                CASE
-                    WHEN c.condeferrable THEN 'YES'::text
-                    ELSE 'NO'::text
-                END::information_schema.yes_or_no AS is_deferrable,
-                CASE
-                    WHEN c.condeferred THEN 'YES'::text
-                    ELSE 'NO'::text
-                END::information_schema.yes_or_no AS initially_deferred
+        SELECT
+            c.conname::name AS constraint_name,
+            nr.nspname::name AS table_schema,
+            r.relname::name AS table_name
         FROM pg_namespace nc,
             pg_namespace nr,
             pg_constraint c,
             pg_class r
-        WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND (c.contype <> ALL (ARRAY['t'::"char", 'x'::"char"])) AND r.relkind = 'r'::"char" AND NOT pg_is_other_temp_schema(nr.oid)
-        /*--AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES'::text))*/
-        UNION ALL
-        SELECT current_database()::information_schema.sql_identifier AS constraint_catalog,
-            nr.nspname::information_schema.sql_identifier AS constraint_schema,
-            (((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text)::information_schema.sql_identifier AS constraint_name,
-            current_database()::information_schema.sql_identifier AS table_catalog,
-            nr.nspname::information_schema.sql_identifier AS table_schema,
-            r.relname::information_schema.sql_identifier AS table_name,
-            'CHECK'::character varying::information_schema.character_data AS constraint_type,
-            'NO'::character varying::information_schema.yes_or_no AS is_deferrable,
-            'NO'::character varying::information_schema.yes_or_no AS initially_deferred
-        FROM pg_namespace nr,
-            pg_class r,
-            pg_attribute a
-        WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r'::"char" AND NOT pg_is_other_temp_schema(nr.oid)
-        /*--AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES'::text))*/
+        WHERE
+            nc.oid = c.connamespace
+            AND nr.oid = r.relnamespace
+            AND c.conrelid = r.oid
+            AND r.relkind = 'r'
+            AND NOT pg_is_other_temp_schema(nr.oid)
+            AND c.contype = 'p'
     ),
-    /*
     -- CTE to replace information_schema.key_column_usage to remove owner limit
-    */
     kc AS (
-        SELECT current_database()::information_schema.sql_identifier AS constraint_catalog,
-            ss.nc_nspname::information_schema.sql_identifier AS constraint_schema,
-            ss.conname::information_schema.sql_identifier AS constraint_name,
-            current_database()::information_schema.sql_identifier AS table_catalog,
-            ss.nr_nspname::information_schema.sql_identifier AS table_schema,
-            ss.relname::information_schema.sql_identifier AS table_name,
-            a.attname::information_schema.sql_identifier AS column_name,
-            (ss.x).n::information_schema.cardinal_number AS ordinal_position,
-                CASE
-                    WHEN ss.contype = 'f'::"char" THEN information_schema._pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
-                    ELSE NULL::integer
-                END::information_schema.cardinal_number AS position_in_unique_constraint
+        SELECT
+            ss.conname::name AS constraint_name,
+            ss.nr_nspname::name AS table_schema,
+            ss.relname::name AS table_name,
+            a.attname::name AS column_name,
+            (ss.x).n::integer AS ordinal_position,
+            CASE
+                WHEN ss.contype = 'f' THEN information_schema._pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
+                ELSE NULL::integer
+            END::integer AS position_in_unique_constraint
         FROM pg_attribute a,
             ( SELECT r.oid AS roid,
                 r.relname,
@@ -692,28 +632,31 @@
                 c.contype,
                 c.conindid,
                 c.confkey,
-                c.confrelid,
                 information_schema._pg_expandarray(c.conkey) AS x
                FROM pg_namespace nr,
                 pg_class r,
                 pg_namespace nc,
                 pg_constraint c
-              WHERE nr.oid = r.relnamespace AND r.oid = c.conrelid AND nc.oid = c.connamespace AND (c.contype = ANY (ARRAY['p'::"char", 'u'::"char", 'f'::"char"])) AND r.relkind = 'r'::"char" AND NOT pg_is_other_temp_schema(nr.oid)) ss
-        WHERE ss.roid = a.attrelid AND a.attnum = (ss.x).x AND NOT a.attisdropped
-        /*--AND (pg_has_role(ss.relowner, 'USAGE'::text) OR has_column_privilege(ss.roid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'::text))*/
+              WHERE
+                nr.oid = r.relnamespace
+                AND r.oid = c.conrelid
+                AND nc.oid = c.connamespace
+                AND c.contype in ('p', 'u', 'f')
+                AND r.relkind = 'r'
+                AND NOT pg_is_other_temp_schema(nr.oid)
+            ) ss
+        WHERE
+          ss.roid = a.attrelid
+          AND a.attnum = (ss.x).x
+          AND NOT a.attisdropped
     )
     SELECT
         kc.table_schema,
         kc.table_name,
         kc.column_name
     FROM
-        /*
-        --information_schema.table_constraints tc,
-        --information_schema.key_column_usage kc
-        */
         tc, kc
     WHERE
-        tc.constraint_type = 'PRIMARY KEY' AND
         kc.table_name = tc.table_name AND
         kc.table_schema = tc.table_schema AND
         kc.constraint_name = tc.constraint_name AND
@@ -744,7 +687,7 @@
         from pg_class c
         join pg_namespace n on n.oid = c.relnamespace
         join pg_rewrite r on r.ev_class = c.oid
-        where (c.relkind in ('v', 'm')) and n.nspname = ANY ($1)
+        where c.relkind in ('v', 'm') and n.nspname = ANY ($1)
       ),
       removed_subselects as(
         select
diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs
--- a/src/PostgREST/Error.hs
+++ b/src/PostgREST/Error.hs
@@ -23,12 +23,12 @@
 
 import Data.Aeson  ((.=))
 import Network.Wai (Response, responseLBS)
-import Text.Read   (readMaybe)
 
 import Network.HTTP.Types.Header
 
 import PostgREST.Types
-import Protolude
+import Protolude       hiding (toS)
+import Protolude.Conv  (toS)
 
 
 class (JSON.ToJSON a) => PgrstError a where
@@ -223,10 +223,8 @@
   = GucHeadersError
   | BinaryFieldError ContentType
   | ConnectionLostError
-  | PutSingletonError
   | PutMatchingPkError
   | PutRangeNotAllowedError
-  | PutPayloadIncompleteError
   | JwtTokenMissing
   | JwtTokenInvalid Text
   | SingularityError Integer
@@ -234,17 +232,15 @@
   deriving (Show, Eq)
 
 instance PgrstError SimpleError where
-  status GucHeadersError           = HT.status500
-  status (BinaryFieldError _)      = HT.status406
-  status ConnectionLostError       = HT.status503
-  status PutSingletonError         = HT.status400
-  status PutMatchingPkError        = HT.status400
-  status PutRangeNotAllowedError   = HT.status400
-  status PutPayloadIncompleteError = HT.status400
-  status JwtTokenMissing           = HT.status500
-  status (JwtTokenInvalid _)       = HT.unauthorized401
-  status (SingularityError _)      = HT.status406
-  status (ContentTypeError _)      = HT.status415
+  status GucHeadersError         = HT.status500
+  status (BinaryFieldError _)    = HT.status406
+  status ConnectionLostError     = HT.status503
+  status PutMatchingPkError      = HT.status400
+  status PutRangeNotAllowedError = HT.status400
+  status JwtTokenMissing         = HT.status500
+  status (JwtTokenInvalid _)     = HT.unauthorized401
+  status (SingularityError _)    = HT.status406
+  status (ContentTypeError _)    = HT.status415
 
   headers (SingularityError _)     = [toHeader CTSingularJSON]
   headers (JwtTokenInvalid m)      = [toHeader CTApplicationJSON, invalidTokenHeader m]
@@ -258,12 +254,8 @@
   toJSON ConnectionLostError       = JSON.object [
     "message" .= ("Database connection lost, retrying the connection." :: Text)]
 
-  toJSON PutSingletonError         = JSON.object [
-    "message" .= ("PUT payload must contain a single row" :: Text)]
   toJSON PutRangeNotAllowedError   = JSON.object [
     "message" .= ("Range header and limit/offset querystring parameters are not allowed for PUT" :: Text)]
-  toJSON PutPayloadIncompleteError = JSON.object [
-    "message" .= ("You must specify all columns in the payload when using PUT" :: Text)]
   toJSON PutMatchingPkError        = JSON.object [
     "message" .= ("Payload values do not match URL in primary key column(s)" :: Text)]
 
@@ -280,7 +272,7 @@
 
 invalidTokenHeader :: Text -> Header
 invalidTokenHeader m =
-  ("WWW-Authenticate", "Bearer error=\"invalid_token\", " <> "error_description=" <> show m)
+  ("WWW-Authenticate", "Bearer error=\"invalid_token\", " <> "error_description=" <> encodeUtf8 (show m))
 
 singularityError :: (Integral a) => a -> SimpleError
 singularityError = SingularityError . toInteger
diff --git a/src/PostgREST/Middleware.hs b/src/PostgREST/Middleware.hs
--- a/src/PostgREST/Middleware.hs
+++ b/src/PostgREST/Middleware.hs
@@ -27,7 +27,8 @@
 import PostgREST.Error        (SimpleError (JwtTokenInvalid, JwtTokenMissing),
                                errorResponseFor)
 import PostgREST.QueryBuilder (setLocalQuery, setLocalSearchPathQuery)
-import Protolude              hiding (head)
+import Protolude              hiding (head, toS)
+import Protolude.Conv         (toS)
 
 runWithClaims :: AppConfig -> JWTAttempt ->
                  (ApiRequest -> H.Transaction Response) ->
diff --git a/src/PostgREST/OpenAPI.hs b/src/PostgREST/OpenAPI.hs
--- a/src/PostgREST/OpenAPI.hs
+++ b/src/PostgREST/OpenAPI.hs
@@ -32,7 +32,8 @@
                              PrimaryKey (..), ProcDescription (..),
                              Proxy (..), Table (..), toMime)
 import Protolude            hiding (Proxy, dropWhile, get,
-                             intercalate, (&))
+                             intercalate, toLower, toS, (&))
+import Protolude.Conv       (toS)
 
 makeMimeList :: [ContentType] -> MimeList
 makeMimeList cs = MimeList $ map (fromString . toS . toMime) cs
@@ -117,7 +118,7 @@
   [ Inline $ (mempty :: Param)
     & name     .~ "args"
     & required ?~ True
-    & schema   .~ (ParamBody $ Inline $ makeProcSchema pd)
+    & schema   .~ ParamBody (Inline $ makeProcSchema pd)
   , Ref $ Reference "preferParams"
   ]
 
@@ -221,7 +222,7 @@
         & description .~ "OK"
         & schema ?~ Inline (mempty
           & type_ ?~ SwaggerArray
-          & items ?~ (SwaggerItemsObject $ Ref $ Reference $ tableName t)
+          & items ?~ SwaggerItemsObject (Ref $ Reference $ tableName t)
         )
       )
     postOp = tOp
diff --git a/src/PostgREST/Parsers.hs b/src/PostgREST/Parsers.hs
--- a/src/PostgREST/Parsers.hs
+++ b/src/PostgREST/Parsers.hs
@@ -9,10 +9,8 @@
 import qualified Data.HashMap.Strict as M
 import qualified Data.Set            as S
 
-import Control.Monad           ((>>))
 import Data.Either.Combinators (mapLeft)
 import Data.Foldable           (foldl1)
-import Data.Functor            (($>))
 import Data.List               (init, last)
 import Data.Text               (intercalate, replace, strip)
 import Text.Read               (read)
@@ -24,7 +22,9 @@
 import PostgREST.Error      (ApiRequestError (ParseRequestError))
 import PostgREST.RangeQuery (NonnegRange)
 import PostgREST.Types
-import Protolude            hiding (intercalate, option, replace, try)
+import Protolude            hiding (intercalate, option, replace, toS,
+                             try)
+import Protolude.Conv       (toS)
 
 pRequestSelect :: Text -> Either ApiRequestError [Tree SelectItem]
 pRequestSelect selStr =
diff --git a/src/PostgREST/Private/QueryFragment.hs b/src/PostgREST/Private/QueryFragment.hs
--- a/src/PostgREST/Private/QueryFragment.hs
+++ b/src/PostgREST/Private/QueryFragment.hs
@@ -11,12 +11,13 @@
 import           Data.Maybe
 import           Data.Text                     (intercalate,
                                                 isInfixOf, replace,
-                                                toLower, unwords)
+                                                toLower)
 import qualified Data.Text                     as T (map, null,
                                                      takeWhile)
 import           PostgREST.Types
 import           Protolude                     hiding (cast,
-                                                intercalate, replace)
+                                                intercalate, replace,
+                                                toLower)
 import           Text.InterpolatedString.Perl6 (qc)
 
 noLocationF :: SqlFragment
@@ -186,8 +187,8 @@
 countF countQuery shouldCount =
   if shouldCount
     then (
-        ", pg_source_count AS (" <> countQuery <> ")"
-      , "(SELECT pg_catalog.count(*) FROM pg_source_count)" )
+        ", pgrst_source_count AS (" <> countQuery <> ")"
+      , "(SELECT pg_catalog.count(*) FROM pgrst_source_count)" )
     else (
         mempty
       , "null::bigint")
diff --git a/src/PostgREST/QueryBuilder.hs b/src/PostgREST/QueryBuilder.hs
--- a/src/PostgREST/QueryBuilder.hs
+++ b/src/PostgREST/QueryBuilder.hs
@@ -22,7 +22,7 @@
 
 import qualified Data.Set as S
 
-import Data.Text (intercalate, unwords)
+import Data.Text (intercalate)
 import Data.Tree (Tree (..))
 
 import Data.Maybe
@@ -94,7 +94,10 @@
     cols = intercalate ", " $ pgFmtIdent <$> S.toList iCols
 mutateRequestToQuery (Update mainQi uCols logicForest returnings) =
   if S.null uCols
-    then "WITH " <> ignoredBody <> "SELECT null WHERE false" -- if there are no columns we cannot do UPDATE table SET {empty}, it'd be invalid syntax
+    -- if there are no columns we cannot do UPDATE table SET {empty}, it'd be invalid syntax
+    -- selecting an empty resultset from mainQi gives us the column names to prevent errors when using &select=
+    -- the select has to be based on "returnings" to make computed overloaded functions not throw
+    then "WITH " <> ignoredBody <> "SELECT " <> empty_body_returned_columns <> " FROM " <> fromQi mainQi <> " WHERE false"
     else
       unwords [
         "WITH " <> normalizedBody,
@@ -105,6 +108,10 @@
         ]
   where
     cols = intercalate ", " (pgFmtIdent <> const " = _." <> pgFmtIdent <$> S.toList uCols)
+    empty_body_returned_columns :: SqlFragment
+    empty_body_returned_columns
+      | null returnings = "NULL"
+      | otherwise       = intercalate ", " (pgFmtColumn (QualifiedIdentifier mempty $ qiName mainQi) <$> returnings)
 mutateRequestToQuery (Delete mainQi logicForest returnings) =
   unwords [
     "WITH " <> ignoredBody,
@@ -113,15 +120,15 @@
     returningF mainQi returnings
     ]
 
-requestToCallProcQuery :: QualifiedIdentifier -> [PgArg] -> Bool -> Maybe PreferParameters -> SqlQuery
-requestToCallProcQuery qi pgArgs returnsScalar preferParams =
+requestToCallProcQuery :: QualifiedIdentifier -> [PgArg] -> Bool -> Maybe PreferParameters -> [FieldName] -> SqlQuery
+requestToCallProcQuery qi pgArgs returnsScalar preferParams returnings =
   unwords [
     "WITH",
     argsCTE,
     sourceBody ]
   where
     paramsAsSingleObject    = preferParams == Just SingleObject
-    paramsAsMulitpleObjects = preferParams == Just MultipleObjects
+    paramsAsMultipleObjects = preferParams == Just MultipleObjects
 
     (argsCTE, args)
       | null pgArgs = (ignoredBody, "")
@@ -132,7 +139,7 @@
             "pgrst_args AS (",
               "SELECT * FROM json_to_recordset(" <> selectBody <> ") AS _(" <> fmtArgs (\a -> " " <> pgaType a) <> ")",
             ")"]
-         , if paramsAsMulitpleObjects
+         , if paramsAsMultipleObjects
              then fmtArgs (\a -> " := pgrst_args." <> pgFmtIdent (pgaName a))
              else fmtArgs (\a -> " := (SELECT " <> pgFmtIdent (pgaName a) <> " FROM pgrst_args LIMIT 1)")
         )
@@ -142,19 +149,24 @@
 
     sourceBody :: SqlFragment
     sourceBody
-      | paramsAsMulitpleObjects =
+      | paramsAsMultipleObjects =
           if returnsScalar
             then "SELECT " <> callIt <> " AS pgrst_scalar FROM pgrst_args"
             else unwords [ "SELECT pgrst_lat_args.*"
                          , "FROM pgrst_args,"
-                         , "LATERAL ( SELECT * FROM " <> callIt <> " ) pgrst_lat_args" ]
+                         , "LATERAL ( SELECT " <> returned_columns <> " FROM " <> callIt <> " ) pgrst_lat_args" ]
       | otherwise =
           if returnsScalar
             then "SELECT " <> callIt <> " AS pgrst_scalar"
-            else "SELECT * FROM " <> callIt
+            else "SELECT " <> returned_columns <> " FROM " <> callIt
 
     callIt :: SqlFragment
     callIt = fromQi qi <> "(" <> args <> ")"
+
+    returned_columns :: SqlFragment
+    returned_columns
+      | null returnings = "*"
+      | otherwise       = intercalate ", " (pgFmtColumn (QualifiedIdentifier mempty $ qiName qi) <$> returnings)
 
 
 -- | SQL query meant for COUNTing the root node of the Tree.
diff --git a/src/PostgREST/RangeQuery.hs b/src/PostgREST/RangeQuery.hs
--- a/src/PostgREST/RangeQuery.hs
+++ b/src/PostgREST/RangeQuery.hs
@@ -26,7 +26,8 @@
 import Network.HTTP.Types.Header
 import Network.HTTP.Types.Status
 
-import Protolude
+import Protolude      hiding (toS)
+import Protolude.Conv (toS)
 
 type NonnegRange = Range Integer
 
@@ -91,9 +92,9 @@
 
 contentRangeH :: (Integral a, Show a) => a -> a -> Maybe a -> Header
 contentRangeH lower upper total =
-    ("Content-Range", headerValue)
+    ("Content-Range", toUtf8 headerValue)
     where
-      headerValue   = rangeString <> "/" <> totalString
+      headerValue   = rangeString <> "/" <> totalString :: Text
       rangeString
         | totalNotZero && fromInRange = show lower <> "-" <> show upper
         | otherwise = "*"
diff --git a/src/PostgREST/Statements.hs b/src/PostgREST/Statements.hs
--- a/src/PostgREST/Statements.hs
+++ b/src/PostgREST/Statements.hs
@@ -22,8 +22,6 @@
 import qualified Data.Aeson.Lens                 as L
 import qualified Data.ByteString.Char8           as BS
 import           Data.Maybe
-import           Data.Text                       (unwords)
-import           Data.Text.Encoding              (encodeUtf8)
 import qualified Hasql.Decoders                  as HD
 import qualified Hasql.Encoders                  as HE
 import qualified Hasql.Statement                 as H
@@ -31,7 +29,8 @@
 import           PostgREST.Private.QueryFragment
 import           PostgREST.Types
 import           Protolude                       hiding (cast,
-                                                  replace)
+                                                  replace, toS)
+import           Protolude.Conv                  (toS)
 import           Text.InterpolatedString.Perl6   (qc)
 
 {-| The generic query result format used by API responses. The location header
@@ -55,7 +54,7 @@
         {locF} AS header,
         {bodyF} AS body,
         {responseHeadersF pgVer} AS response_headers
-      FROM ({selectQuery}) _postgrest_t |]
+      FROM ({selectF}) _postgrest_t |]
 
   locF =
     if isInsert && rep `elem` [Full, HeadersOnly]
@@ -71,6 +70,11 @@
     | asCsv = asCsvF
     | wantSingle = asJsonSingleF
     | otherwise = asJsonF
+
+  selectF
+    -- prevent using any of the column names in ?select= when no response is returned from the CTE
+    | rep `elem` [None, HeadersOnly] = "SELECT * FROM " <> sourceCTEName
+    | otherwise                      = selectQuery
 
   decodeStandard :: HD.Result ResultsWithCount
   decodeStandard =
diff --git a/src/PostgREST/Types.hs b/src/PostgREST/Types.hs
--- a/src/PostgREST/Types.hs
+++ b/src/PostgREST/Types.hs
@@ -24,7 +24,8 @@
 import Data.Tree
 
 import PostgREST.RangeQuery (NonnegRange)
-import Protolude
+import Protolude            hiding (toS)
+import Protolude.Conv       (toS)
 
 -- | Enumeration of currently supported response content types
 data ContentType = CTApplicationJSON | CTSingularJSON
@@ -308,9 +309,8 @@
   ProcessedJSON {
     -- | This is the raw ByteString that comes from the request body.
     -- We cache this instead of an Aeson Value because it was detected that for large payloads the encoding
-    -- had high memory usage, see #1005 for more details
+    -- had high memory usage, see https://github.com/PostgREST/postgrest/pull/1005 for more details
     pjRaw  :: BL.ByteString
-  , pjType :: PJType
     -- | Keys of the object or if it's an array these keys are guaranteed to be the same across all its objects
   , pjKeys :: S.Set Text
   }|
@@ -522,7 +522,7 @@
 pgVersion121 = PgVersion 120001 "12.1"
 
 sourceCTEName :: SqlFragment
-sourceCTEName = "pg_source"
+sourceCTEName = "pgrst_source"
 
 -- | full jspath, e.g. .property[0].attr.detail
 type JSPath = [JSPathExp]
diff --git a/test/Feature/ConcurrentSpec.hs b/test/Feature/ConcurrentSpec.hs
--- a/test/Feature/ConcurrentSpec.hs
+++ b/test/Feature/ConcurrentSpec.hs
@@ -5,7 +5,6 @@
 module Feature.ConcurrentSpec where
 
 import Control.Concurrent.Async (mapConcurrently)
-import Control.Monad            (void)
 import Network.Wai              (Application)
 
 import Control.Monad.Base
diff --git a/test/Feature/DeleteSpec.hs b/test/Feature/DeleteSpec.hs
--- a/test/Feature/DeleteSpec.hs
+++ b/test/Feature/DeleteSpec.hs
@@ -27,15 +27,30 @@
           { matchStatus  = 200
           , matchHeaders = ["Content-Range" <:> "*/1"]
           }
+
+      it "ignores ?select= when return not set or return=minimal" $ do
+        request methodDelete "/items?id=eq.3&select=id" [] ""
+          `shouldRespondWith` ""
+          { matchStatus  = 204
+          , matchHeaders = ["Content-Range" <:> "*/*"]
+          }
+        request methodDelete "/items?id=eq.3&select=id" [("Prefer", "return=minimal")] ""
+          `shouldRespondWith` ""
+          { matchStatus  = 204
+          , matchHeaders = ["Content-Range" <:> "*/*"]
+          }
+
       it "returns the deleted item and shapes the response" $
         request methodDelete "/complex_items?id=eq.2&select=id,name" [("Prefer", "return=representation")] ""
           `shouldRespondWith` [str|[{"id":2,"name":"Two"}]|]
           { matchStatus  = 200
           , matchHeaders = ["Content-Range" <:> "*/*"]
           }
+
       it "can rename and cast the selected columns" $
         request methodDelete "/complex_items?id=eq.3&select=ciId:id::text,ciName:name" [("Prefer", "return=representation")] ""
           `shouldRespondWith` [str|[{"ciId":"3","ciName":"Three"}]|]
+
       it "can embed (parent) entities" $
         request methodDelete "/tasks?id=eq.8&select=id,name,project:projects(id)" [("Prefer", "return=representation")] ""
           `shouldRespondWith` [str|[{"id":8,"name":"Code OSX","project":{"id":4}}]|]
diff --git a/test/Feature/EmbedDisambiguationSpec.hs b/test/Feature/EmbedDisambiguationSpec.hs
--- a/test/Feature/EmbedDisambiguationSpec.hs
+++ b/test/Feature/EmbedDisambiguationSpec.hs
@@ -324,20 +324,20 @@
             ]|]
             { matchHeaders = [matchContentTypeJson] }
 
-        it "embeds childs recursively" $
-          get "/family_tree?id=eq.1&select=id,name, childs:family_tree!parent(id,name,childs:family_tree!parent(id,name))" `shouldRespondWith`
+        it "embeds children recursively" $
+          get "/family_tree?id=eq.1&select=id,name, children:family_tree!parent(id,name,children:family_tree!parent(id,name))" `shouldRespondWith`
             [json|[{
-              "id": "1", "name": "Parental Unit", "childs": [
-                { "id": "2", "name": "Kid One", "childs": [ { "id": "4", "name": "Grandkid One" } ] },
-                { "id": "3", "name": "Kid Two", "childs": [ { "id": "5", "name": "Grandkid Two" } ] }
+              "id": "1", "name": "Parental Unit", "children": [
+                { "id": "2", "name": "Kid One", "children": [ { "id": "4", "name": "Grandkid One" } ] },
+                { "id": "3", "name": "Kid Two", "children": [ { "id": "5", "name": "Grandkid Two" } ] }
               ]
             }]|] { matchHeaders = [matchContentTypeJson] }
 
-        it "embeds parent and then embeds childs" $
-          get "/family_tree?id=eq.2&select=id,name,parent(id,name,childs:family_tree!parent(id,name))" `shouldRespondWith`
+        it "embeds parent and then embeds children" $
+          get "/family_tree?id=eq.2&select=id,name,parent(id,name,children:family_tree!parent(id,name))" `shouldRespondWith`
             [json|[{
               "id": "2", "name": "Kid One", "parent": {
-                "id": "1", "name": "Parental Unit", "childs": [ { "id": "2", "name": "Kid One" }, { "id": "3", "name": "Kid Two"} ]
+                "id": "1", "name": "Parental Unit", "children": [ { "id": "2", "name": "Kid One" }, { "id": "3", "name": "Kid Two"} ]
               }
             }]|] { matchHeaders = [matchContentTypeJson] }
 
@@ -356,7 +356,7 @@
               }
             }]|] { matchHeaders = [matchContentTypeJson] }
 
-        it "embeds childs" $ do
+        it "embeds children" $ do
           get "/organizations?select=id,name,refereeds:organizations!referee(id,name)&id=eq.1" `shouldRespondWith`
             [json|[{
               "id": 1, "name": "Referee Org",
diff --git a/test/Feature/InsertSpec.hs b/test/Feature/InsertSpec.hs
--- a/test/Feature/InsertSpec.hs
+++ b/test/Feature/InsertSpec.hs
@@ -2,7 +2,6 @@
 
 import qualified Data.Aeson as JSON
 
-import Control.Monad          (replicateM_, void)
 import Data.List              (lookup)
 import Data.Maybe             (fromJust)
 import Network.Wai            (Application)
@@ -48,6 +47,22 @@
           , matchHeaders = [matchContentTypeJson]
           }
 
+      it "ignores &select when return not set or using return=minimal" $ do
+        request methodPost "/menagerie?select=integer,varchar" []
+          [json| [{
+            "integer": 15, "double": 3.14159, "varchar": "testing!"
+          , "boolean": false, "date": "1900-01-01", "money": "$3.99"
+          , "enum": "foo"
+          }] |] `shouldRespondWith` ""
+          { matchStatus  = 201 }
+        request methodPost "/menagerie?select=integer,varchar" [("Prefer", "return=minimal")]
+          [json| [{
+            "integer": 16, "double": 3.14159, "varchar": "testing!"
+          , "boolean": false, "date": "1900-01-01", "money": "$3.99"
+          , "enum": "foo"
+          }] |] `shouldRespondWith` ""
+          { matchStatus  = 201 }
+
     context "non uniform json array" $ do
       it "rejects json array that isn't exclusivily composed of objects" $
         post "/articles"
@@ -189,11 +204,20 @@
       it "fails with 400 and error" $
         post "/simple_pk" "}{ x = 2"
         `shouldRespondWith`
-        [json|{"message":"Error in $: Failed reading: not a valid json value"}|]
+        [json|{"message":"Error in $: Failed reading: not a valid json value at '}{x=2'"}|]
         { matchStatus  = 400
         , matchHeaders = [matchContentTypeJson]
         }
 
+    context "with no payload" $
+      it "fails with 400 and error" $
+        post "/simple_pk" ""
+        `shouldRespondWith`
+        [json|{"message":"Error in $: not enough input"}|]
+        { matchStatus  = 400
+        , matchHeaders = [matchContentTypeJson]
+        }
+
     context "with valid json payload" $
       it "succeeds and returns 201 created" $
         post "/simple_pk" [json| { "k":"k1", "extra":"e1" } |] `shouldRespondWith` 201
@@ -251,6 +275,20 @@
           , matchHeaders = []
           }
 
+      it "successfully inserts a row with all-default columns with prefer=rep" $
+        request methodPost "/items" [("Prefer", "return=representation")] "{}"
+          `shouldRespondWith` [json|[{ id: 20 }]|]
+          { matchStatus  = 201,
+            matchHeaders = []
+          }
+
+      it "successfully inserts a row with all-default columns with prefer=rep and &select=" $
+        request methodPost "/items?select=id" [("Prefer", "return=representation")] "{}"
+          `shouldRespondWith` [json|[{ id: 21 }]|]
+          { matchStatus  = 201,
+            matchHeaders = []
+          }
+
     context "POST with ?columns parameter" $ do
       it "ignores json keys not included in ?columns" $ do
         request methodPost "/articles?columns=id,body" [("Prefer", "return=representation")]
@@ -383,6 +421,24 @@
             matchHeaders = []
           }
 
+    context "with invalid json payload" $
+      it "fails with 400 and error" $
+        request methodPatch "/simple_pk" [] "}{ x = 2"
+          `shouldRespondWith`
+          [json|{"message":"Error in $: Failed reading: not a valid json value at '}{x=2'"}|]
+          { matchStatus  = 400,
+            matchHeaders = [matchContentTypeJson]
+          }
+
+    context "with no payload" $
+      it "fails with 400 and error" $
+        request methodPatch "/items" [] ""
+          `shouldRespondWith`
+          [json|{"message":"Error in $: not enough input"}|]
+          { matchStatus  = 400,
+            matchHeaders = [matchContentTypeJson]
+          }
+
     context "in a nonempty table" $ do
       it "can update a single item" $ do
         g <- get "/items?id=eq.42"
@@ -464,48 +520,124 @@
               matchHeaders = []
             }
 
-      it "can provide a representation" $ do
-        _ <- post "/items"
-          [json| { id: 1 } |]
-        request methodPatch
-          "/items?id=eq.1"
-          [("Prefer", "return=representation")]
-          [json| { id: 99 } |]
-          `shouldRespondWith` [json| [{id:99}] |]
-          { matchHeaders = [matchContentTypeJson] }
-        -- put value back for other tests
-        void $ request methodPatch "/items?id=eq.99" [] [json| { "id":1 } |]
+      context "with representation requested" $ do
+        it "can provide a representation" $ do
+          _ <- post "/items"
+            [json| { id: 1 } |]
+          request methodPatch
+            "/items?id=eq.1"
+            [("Prefer", "return=representation")]
+            [json| { id: 99 } |]
+            `shouldRespondWith` [json| [{id:99}] |]
+            { matchHeaders = [matchContentTypeJson] }
+          -- put value back for other tests
+          void $ request methodPatch "/items?id=eq.99" [] [json| { "id":1 } |]
 
-      it "makes no updates and returns 204, when patching with an empty json object/array" $ do
-        request methodPatch "/items" [] [json| {} |]
-          `shouldRespondWith` ""
-          {
-            matchStatus  = 204,
-            matchHeaders = ["Content-Range" <:> "*/*"]
-          }
+        it "can return computed columns" $
+          request methodPatch
+            "/items?id=eq.1&select=id,always_true"
+            [("Prefer", "return=representation")]
+            [json| { id: 1 } |]
+            `shouldRespondWith` [json| [{ id: 1, always_true: true }] |]
+            { matchHeaders = [matchContentTypeJson] }
 
-        request methodPatch "/items" [] [json| [] |]
+        it "can select overloaded computed columns" $ do
+          request methodPatch
+            "/items?id=eq.1&select=id,computed_overload"
+            [("Prefer", "return=representation")]
+            [json| { id: 1 } |]
+            `shouldRespondWith` [json| [{ id: 1, computed_overload: true }] |]
+            { matchHeaders = [matchContentTypeJson] }
+          request methodPatch
+            "/items2?id=eq.1&select=id,computed_overload"
+            [("Prefer", "return=representation")]
+            [json| { id: 1 } |]
+            `shouldRespondWith` [json| [{ id: 1, computed_overload: true }] |]
+            { matchHeaders = [matchContentTypeJson] }
+
+      it "ignores ?select= when return not set or return=minimal" $ do
+        request methodPatch "/items?id=eq.1&select=id" [] [json| { id:1 } |]
           `shouldRespondWith` ""
           {
             matchStatus  = 204,
-            matchHeaders = ["Content-Range" <:> "*/*"]
+            matchHeaders = ["Content-Range" <:> "0-0/*"]
           }
-
-        request methodPatch "/items" [] [json| [{}] |]
+        request methodPatch "/items?id=eq.1&select=id" [("Prefer", "return=minimal")] [json| { id:1 } |]
           `shouldRespondWith` ""
           {
             matchStatus  = 204,
-            matchHeaders = ["Content-Range" <:> "*/*"]
+            matchHeaders = ["Content-Range" <:> "0-0/*"]
           }
 
-      it "makes no updates and returns 200, when patching with an empty json object and return=rep" $
-        request methodPatch "/items" [("Prefer", "return=representation")] [json| {} |]
-          `shouldRespondWith` "[]"
-          {
-            matchStatus  = 200,
-            matchHeaders = ["Content-Range" <:> "*/*"]
-          }
+      context "when patching with an empty body" $ do
+        it "makes no updates and returns 204 without return= and without ?select=" $ do
+          request methodPatch "/items" [] [json| {} |]
+            `shouldRespondWith` ""
+            {
+              matchStatus  = 204,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
 
+          request methodPatch "/items" [] [json| [] |]
+            `shouldRespondWith` ""
+            {
+              matchStatus  = 204,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+          request methodPatch "/items" [] [json| [{}] |]
+            `shouldRespondWith` ""
+            {
+              matchStatus  = 204,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+        it "makes no updates and returns 204 without return= and with ?select=" $ do
+          request methodPatch "/items?select=id" [] [json| {} |]
+            `shouldRespondWith` ""
+            {
+              matchStatus  = 204,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+          request methodPatch "/items?select=id" [] [json| [] |]
+            `shouldRespondWith` ""
+            {
+              matchStatus  = 204,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+          request methodPatch "/items?select=id" [] [json| [{}] |]
+            `shouldRespondWith` ""
+            {
+              matchStatus  = 204,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+        it "makes no updates and returns 200 with return=rep and without ?select=" $
+          request methodPatch "/items" [("Prefer", "return=representation")] [json| {} |]
+            `shouldRespondWith` "[]"
+            {
+              matchStatus  = 200,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+        it "makes no updates and returns 200 with return=rep and with ?select=" $
+          request methodPatch "/items?select=id" [("Prefer", "return=representation")] [json| {} |]
+            `shouldRespondWith` "[]"
+            {
+              matchStatus  = 200,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
+        it "makes no updates and returns 200 with return=rep and with ?select= for overloaded computed columns" $
+          request methodPatch "/items?select=id,computed_overload" [("Prefer", "return=representation")] [json| {} |]
+            `shouldRespondWith` "[]"
+            {
+              matchStatus  = 200,
+              matchHeaders = ["Content-Range" <:> "*/*"]
+            }
+
     context "with unicode values" $
       it "succeeds and returns values intact" $ do
         void $ request methodPost "/no_pk" []
@@ -561,7 +693,7 @@
         , matchHeaders = [ matchContentTypeJson , "Location" <:> "/web_content?id=eq.6" ]
         }
 
-    it "embeds childs after update" $
+    it "embeds children after update" $
       request methodPatch "/web_content?id=eq.0&select=id,name,web_content(name)"
               [("Prefer", "return=representation")]
         [json|{"name": "tardis-patched"}|]
@@ -573,7 +705,7 @@
           matchHeaders = [matchContentTypeJson]
         }
 
-    it "embeds parent, childs and grandchilds after update" $
+    it "embeds parent, children and grandchildren after update" $
       request methodPatch "/web_content?id=eq.0&select=id,name,web_content(name,web_content(name)),parent_content:p_web_id(name)"
               [("Prefer", "return=representation")]
         [json|{"name": "tardis-patched-2"}|]
@@ -594,7 +726,7 @@
           matchHeaders = [matchContentTypeJson]
         }
 
-    it "embeds childs after update without explicitly including the id in the ?select" $
+    it "embeds children after update without explicitly including the id in the ?select" $
       request methodPatch "/web_content?id=eq.0&select=name,web_content(name)"
               [("Prefer", "return=representation")]
         [json|{"name": "tardis-patched"}|]
diff --git a/test/Feature/MultipleSchemaSpec.hs b/test/Feature/MultipleSchemaSpec.hs
--- a/test/Feature/MultipleSchemaSpec.hs
+++ b/test/Feature/MultipleSchemaSpec.hs
@@ -77,7 +77,7 @@
 
     context "Inserting tables on different schemas" $ do
       it "succeeds inserting on default schema and returning it" $
-        request methodPost "/childs" [("Prefer", "return=representation")] [json|{"name": "child v1-1", "parent_id": 1}|]
+        request methodPost "/children" [("Prefer", "return=representation")] [json|{"name": "child v1-1", "parent_id": 1}|]
          `shouldRespondWith`
          [json|[{"id":1, "name": "child v1-1", "parent_id": 1}]|]
          {
@@ -86,7 +86,7 @@
          }
 
       it "succeeds inserting on the v1 schema and returning its parent" $
-        request methodPost "/childs?select=id,parent(*)" [("Prefer", "return=representation"), ("Content-Profile", "v1")]
+        request methodPost "/children?select=id,parent(*)" [("Prefer", "return=representation"), ("Content-Profile", "v1")]
           [json|{"name": "child v1-2", "parent_id": 2}|]
           `shouldRespondWith`
           [json|[{"id":2, "parent": {"id": 2, "name": "parent v1-2"}}]|]
@@ -96,7 +96,7 @@
           }
 
       it "succeeds inserting on the v2 schema and returning its parent" $
-        request methodPost "/childs?select=id,parent(*)" [("Prefer", "return=representation"), ("Content-Profile", "v2")]
+        request methodPost "/children?select=id,parent(*)" [("Prefer", "return=representation"), ("Content-Profile", "v2")]
           [json|{"name": "child v2-3", "parent_id": 3}|]
           `shouldRespondWith`
           [json|[{"id":1, "parent": {"id": 3, "name": "parent v2-3"}}]|]
@@ -106,7 +106,7 @@
           }
 
       it "fails when inserting on an unknown schema" $
-        request methodPost "/childs" [("Content-Profile", "unknown")]
+        request methodPost "/children" [("Content-Profile", "unknown")]
           [json|{"name": "child 4", "parent_id": 4}|]
           `shouldRespondWith`
           [json|{"message":"The schema must be one of the following: v1, v2"}|]
@@ -125,30 +125,42 @@
           }
 
       it "succeeds in calling the v1 schema proc and embedding" $
-        request methodGet "/rpc/get_parents_below?id=6&select=id,name,childs(id,name)" [("Accept-Profile", "v1")] ""
+        request methodGet "/rpc/get_parents_below?id=6&select=id,name,children(id,name)" [("Accept-Profile", "v1")] ""
           `shouldRespondWith`
           [json| [
-            {"id":1,"name":"parent v1-1","childs":[{"id":1,"name":"child v1-1"}]},
-            {"id":2,"name":"parent v1-2","childs":[{"id":2,"name":"child v1-2"}]}] |]
+            {"id":1,"name":"parent v1-1","children":[{"id":1,"name":"child v1-1"}]},
+            {"id":2,"name":"parent v1-2","children":[{"id":2,"name":"child v1-2"}]}] |]
           {
             matchStatus = 200
           , matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "v1"]
           }
 
       it "succeeds in calling the v2 schema proc and embedding" $
-        request methodGet "/rpc/get_parents_below?id=6&select=id,name,childs(id,name)" [("Accept-Profile", "v2")] ""
+        request methodGet "/rpc/get_parents_below?id=6&select=id,name,children(id,name)" [("Accept-Profile", "v2")] ""
           `shouldRespondWith`
           [json| [
-            {"id":3,"name":"parent v2-3","childs":[{"id":1,"name":"child v2-3"}]},
-            {"id":4,"name":"parent v2-4","childs":[]}] |]
+            {"id":3,"name":"parent v2-3","children":[{"id":1,"name":"child v2-3"}]},
+            {"id":4,"name":"parent v2-4","children":[]}] |]
           {
             matchStatus = 200
           , matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "v2"]
           }
 
+      it "succeeds in calling the v2 schema proc with POST by using Content-Profile" $
+        request methodPost "/rpc/get_parents_below?select=id,name" [("Content-Profile", "v2")]
+          [json|{"id": "6"}|]
+          `shouldRespondWith`
+          [json| [
+            {"id":3,"name":"parent v2-3"},
+            {"id":4,"name":"parent v2-4"}]|]
+          {
+            matchStatus = 200
+          , matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "v2"]
+          }
+
     context "Modifying tables on different schemas" $ do
       it "succeeds in patching on the v1 schema and returning its parent" $
-        request methodPatch "/childs?select=name,parent(name)&id=eq.1" [("Content-Profile", "v1"), ("Prefer", "return=representation")]
+        request methodPatch "/children?select=name,parent(name)&id=eq.1" [("Content-Profile", "v1"), ("Prefer", "return=representation")]
           [json|{"name": "child v1-1 updated"}|]
           `shouldRespondWith`
           [json|[{"name":"child v1-1 updated", "parent": {"name": "parent v1-1"}}]|]
@@ -158,7 +170,7 @@
           }
 
       it "succeeds in patching on the v2 schema and returning its parent" $
-        request methodPatch "/childs?select=name,parent(name)&id=eq.1" [("Content-Profile", "v2"), ("Prefer", "return=representation")]
+        request methodPatch "/children?select=name,parent(name)&id=eq.1" [("Content-Profile", "v2"), ("Prefer", "return=representation")]
           [json|{"name": "child v2-1 updated"}|]
           `shouldRespondWith`
           [json|[{"name":"child v2-1 updated", "parent": {"name": "parent v2-3"}}]|]
@@ -168,13 +180,13 @@
           }
 
       it "succeeds on deleting on the v2 schema" $ do
-        request methodDelete "/childs?id=eq.1" [("Content-Profile", "v2"), ("Prefer", "return=representation")] ""
+        request methodDelete "/children?id=eq.1" [("Content-Profile", "v2"), ("Prefer", "return=representation")] ""
           `shouldRespondWith` [json|[{"id": 1, "name": "child v2-1 updated", "parent_id": 3}]|]
           {
             matchStatus = 200
           , matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "v2"]
           }
-        request methodGet "/childs?id=eq.1" [("Accept-Profile", "v2")] ""
+        request methodGet "/children?id=eq.1" [("Accept-Profile", "v2")] ""
           `shouldRespondWith` "[]"
           {
             matchStatus = 200
@@ -183,7 +195,7 @@
 
       when (actualPgVersion >= pgVersion96) $
         it "succeeds on PUT on the v2 schema" $
-          request methodPut "/childs?id=eq.111" [("Content-Profile", "v2"), ("Prefer", "return=representation")]
+          request methodPut "/children?id=eq.111" [("Content-Profile", "v2"), ("Prefer", "return=representation")]
             [json| [ { "id": 111, "name": "child v2-111", "parent_id": null } ]|]
             `shouldRespondWith`
             [json|[{ "id": 111, "name": "child v2-111", "parent_id": null }]|]
diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs
--- a/test/Feature/QuerySpec.hs
+++ b/test/Feature/QuerySpec.hs
@@ -237,7 +237,6 @@
         [json| [{"myId":1}] |]
         { matchHeaders = [matchContentTypeJson] }
 
-
     it "one simple column with casting (text)" $
       get "/complex_items?select=id::text" `shouldRespondWith`
         [json| [{"id":"1"},{"id":"2"},{"id":"3"}] |]
@@ -327,6 +326,30 @@
         [json|[{"user_id":2,"task_id":6,"comments":[{"content":"Needs to be delivered ASAP"}]}]|]
         { matchHeaders = [matchContentTypeJson] }
 
+    describe "computed columns" $ do
+      it "computed column on table" $
+        get "/items?id=eq.1&select=id,always_true" `shouldRespondWith`
+          [json|[{"id":1,"always_true":true}]|]
+          { matchHeaders = [matchContentTypeJson] }
+
+      it "computed column on rpc" $
+        get "/rpc/search?id=1&select=id,always_true" `shouldRespondWith`
+          [json|[{"id":1,"always_true":true}]|]
+          { matchHeaders = [matchContentTypeJson] }
+
+      it "overloaded computed columns on both tables" $ do
+        get "/items?id=eq.1&select=id,computed_overload" `shouldRespondWith`
+          [json|[{"id":1,"computed_overload":true}]|]
+          { matchHeaders = [matchContentTypeJson] }
+        get "/items2?id=eq.1&select=id,computed_overload" `shouldRespondWith`
+          [json|[{"id":1,"computed_overload":true}]|]
+          { matchHeaders = [matchContentTypeJson] }
+
+      it "overloaded computed column on rpc" $
+        get "/rpc/search?id=1&select=id,computed_overload" `shouldRespondWith`
+          [json|[{"id":1,"computed_overload":true}]|]
+          { matchHeaders = [matchContentTypeJson] }
+
     describe "view embedding" $ do
       it "can detect fk relations through views to tables in the public schema" $
         get "/consumers_view?select=*,orders_view(*)" `shouldRespondWith` 200
@@ -482,18 +505,18 @@
               "designTasks":[ ] }
           ]|] { matchHeaders = [matchContentTypeJson] }
 
-      it "works with two aliased childs embeds plus and/or" $
-        get "/entities?select=id,childs:child_entities(id,gChilds:grandchild_entities(id))&childs.and=(id.in.(1,2,3))&childs.gChilds.or=(id.eq.1,id.eq.2)" `shouldRespondWith`
+      it "works with two aliased children embeds plus and/or" $
+        get "/entities?select=id,children:child_entities(id,gChildren:grandchild_entities(id))&children.and=(id.in.(1,2,3))&children.gChildren.or=(id.eq.1,id.eq.2)" `shouldRespondWith`
           [json|[
             { "id":1,
-              "childs":[
-                {"id":1,"gChilds":[{"id":1}, {"id":2}]},
-                {"id":2,"gChilds":[]}]},
+              "children":[
+                {"id":1,"gChildren":[{"id":1}, {"id":2}]},
+                {"id":2,"gChildren":[]}]},
             { "id":2,
-              "childs":[
-                {"id":3,"gChilds":[]}]},
-            { "id":3,"childs":[]},
-            { "id":4,"childs":[]}
+              "children":[
+                {"id":3,"gChildren":[]}]},
+            { "id":3,"children":[]},
+            { "id":4,"children":[]}
           ]|] { matchHeaders = [matchContentTypeJson] }
 
   describe "ordering response" $ do
diff --git a/test/Feature/UnicodeSpec.hs b/test/Feature/UnicodeSpec.hs
--- a/test/Feature/UnicodeSpec.hs
+++ b/test/Feature/UnicodeSpec.hs
@@ -1,7 +1,6 @@
 module Feature.UnicodeSpec where
 
-import Control.Monad (void)
-import Network.Wai   (Application)
+import Network.Wai (Application)
 
 import Test.Hspec
 import Test.Hspec.Wai
diff --git a/test/Feature/UpsertSpec.hs b/test/Feature/UpsertSpec.hs
--- a/test/Feature/UpsertSpec.hs
+++ b/test/Feature/UpsertSpec.hs
@@ -180,26 +180,6 @@
             [json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT"}|]
             { matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
 
-        it "fails if the payload has more than one row" $
-          put "/tiobe_pls?name=eq.Go"
-            [str| [ { "name": "Go", "rank": 19 }, { "name": "Swift", "rank": 12 } ]|]
-            `shouldRespondWith`
-            [json|{"message":"PUT payload must contain a single row"}|]
-            { matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
-
-        it "fails if not all columns are specified" $ do
-          put "/tiobe_pls?name=eq.Go"
-            [str| [ { "name": "Go" } ]|]
-            `shouldRespondWith`
-            [json|{"message":"You must specify all columns in the payload when using PUT"}|]
-            { matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
-
-          put "/employees?first_name=eq.Susan&last_name=eq.Heidt"
-            [str| [ { "first_name": "Susan", "last_name": "Heidt", "salary": "48000" } ]|]
-            `shouldRespondWith`
-            [json|{"message":"You must specify all columns in the payload when using PUT"}|]
-            { matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
-
         it "rejects every other filter than pk cols eq's" $ do
           put "/tiobe_pls?rank=eq.19"
             [str| [ { "name": "Go", "rank": 19 } ]|]
@@ -279,6 +259,14 @@
           get "/tiobe_pls?name=eq.Go" `shouldRespondWith` [json|[ { "name": "Go", "rank": 19 } ]|] { matchHeaders = [matchContentTypeJson] }
           put "/tiobe_pls?name=eq.Go" [str| [ { "name": "Go", "rank": 13 } ]|] `shouldRespondWith` 204
           get "/tiobe_pls?name=eq.Go" `shouldRespondWith` [json| [ { "name": "Go", "rank": 13 } ]|] { matchHeaders = [matchContentTypeJson] }
+
+        it "succeeds if the payload has more than one row, but it only puts the first element" $
+          request methodPut "/tiobe_pls?name=eq.Go"
+            [("Prefer", "return=representation"), ("Accept", "application/vnd.pgrst.object+json")]
+            [str| [ { "name": "Go", "rank": 19 }, { "name": "Swift", "rank": 12 } ] |]
+            `shouldRespondWith`
+            [json|{ "name": "Go", "rank": 19 }|]
+            { matchStatus = 200 , matchHeaders = [matchContentTypeSingular] }
 
         it "succeeds on table with composite pk" $ do
           get "/employees?first_name=eq.Susan&last_name=eq.Heidt"
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -16,7 +16,8 @@
 import PostgREST.Config      (AppConfig (..))
 import PostgREST.DbStructure (getDbStructure, getPgVersion)
 import PostgREST.Types       (pgVersion95, pgVersion96)
-import Protolude             hiding (toList)
+import Protolude             hiding (toList, toS)
+import Protolude.Conv        (toS)
 import SpecHelper
 
 import qualified Feature.AndOrParamsSpec
@@ -55,7 +56,6 @@
   getTime <- mkAutoUpdate defaultUpdateSettings { updateAction = getCurrentTime }
 
   testDbConn <- getEnvVarWithDefault "POSTGREST_TEST_CONNECTION" "postgres://postgrest_test@localhost/postgrest_test"
-  setupDb testDbConn
 
   pool <- P.acquire (3, 10, toS testDbConn)
 
diff --git a/test/QueryCost.hs b/test/QueryCost.hs
--- a/test/QueryCost.hs
+++ b/test/QueryCost.hs
@@ -10,7 +10,8 @@
 import qualified Hasql.Transaction.Sessions as HT
 import           Text.Heredoc
 
-import Protolude hiding (get)
+import Protolude      hiding (get, toS)
+import Protolude.Conv (toS)
 
 import PostgREST.QueryBuilder (requestToCallProcQuery)
 import PostgREST.Types
@@ -22,40 +23,39 @@
 main :: IO ()
 main = do
   testDbConn <- getEnvVarWithDefault "POSTGREST_TEST_CONNECTION" "postgres://postgrest_test@localhost/postgrest_test"
-  -- To speed things up, assume setupDb has ben ran in the previous spec.
   pool <- P.acquire (3, 10, toS testDbConn)
 
   hspec $ describe "QueryCost" $
     context "call proc query" $ do
       it "should not exceed cost when calling setof composite proc" $ do
         cost <- exec pool [str| {"id": 3} |] $
-          requestToCallProcQuery (QualifiedIdentifier "test" "get_projects_below") [PgArg "id" "int" True] False Nothing
+          requestToCallProcQuery (QualifiedIdentifier "test" "get_projects_below") [PgArg "id" "int" True] False Nothing []
         liftIO $
           cost `shouldSatisfy` (< Just 40)
 
       it "should not exceed cost when calling setof composite proc with empty params" $ do
         cost <- exec pool mempty $
-          requestToCallProcQuery (QualifiedIdentifier "test" "getallprojects") [] False Nothing
+          requestToCallProcQuery (QualifiedIdentifier "test" "getallprojects") [] False Nothing []
         liftIO $
           cost `shouldSatisfy` (< Just 30)
 
       it "should not exceed cost when calling scalar proc" $ do
         cost <- exec pool [str| {"a": 3, "b": 4} |] $
-          requestToCallProcQuery (QualifiedIdentifier "test" "add_them") [PgArg "a" "int" True, PgArg "b" "int" True] True Nothing
+          requestToCallProcQuery (QualifiedIdentifier "test" "add_them") [PgArg "a" "int" True, PgArg "b" "int" True] True Nothing []
         liftIO $
           cost `shouldSatisfy` (< Just 10)
 
       context "params=multiple-objects" $ do
         it "should not exceed cost when calling setof composite proc" $ do
           cost <- exec pool [str| [{"id": 1}, {"id": 4}] |] $
-            requestToCallProcQuery (QualifiedIdentifier "test" "get_projects_below") [PgArg "id" "int" True] False (Just MultipleObjects)
+            requestToCallProcQuery (QualifiedIdentifier "test" "get_projects_below") [PgArg "id" "int" True] False (Just MultipleObjects) []
           liftIO $ do
             cost `shouldSatisfy` (> Just 2000)
             cost `shouldSatisfy` (< Just 2100)
 
         it "should not exceed cost when calling scalar proc" $ do
           cost <- exec pool [str| [{"a": 3, "b": 4}, {"a": 1, "b": 2}, {"a": 8, "b": 7}] |] $
-            requestToCallProcQuery (QualifiedIdentifier "test" "add_them") [PgArg "a" "int" True, PgArg "b" "int" True] True Nothing
+            requestToCallProcQuery (QualifiedIdentifier "test" "add_them") [PgArg "a" "int" True, PgArg "b" "int" True] True Nothing []
           liftIO $
             cost `shouldSatisfy` (< Just 10)
 
diff --git a/test/SpecHelper.hs b/test/SpecHelper.hs
--- a/test/SpecHelper.hs
+++ b/test/SpecHelper.hs
@@ -7,7 +7,6 @@
 import qualified Data.Set               as S
 import qualified System.IO.Error        as E
 
-import Control.Monad        (void)
 import Data.Aeson           (Value (..), decode, encode)
 import Data.CaseInsensitive (CI (..))
 import Data.List            (lookup)
@@ -25,7 +24,8 @@
 
 import PostgREST.Config (AppConfig (..))
 import PostgREST.Types  (JSPathExp (..))
-import Protolude
+import Protolude        hiding (toS)
+import Protolude.Conv   (toS)
 
 matchContentTypeJson :: MatchHeader
 matchContentTypeJson = "Content-Type" <:> "application/json; charset=utf-8"
@@ -144,16 +144,6 @@
 
 testMultipleSchemaCfg :: Text -> AppConfig
 testMultipleSchemaCfg testDbConn = (testCfg testDbConn) { configSchemas = fromList ["v1", "v2"] }
-
-setupDb :: Text -> IO ()
-setupDb dbConn = do
-  loadFixture dbConn "database"
-  loadFixture dbConn "roles"
-  loadFixture dbConn "schema"
-  loadFixture dbConn "jwt"
-  loadFixture dbConn "jsonschema"
-  loadFixture dbConn "privileges"
-  resetDb dbConn
 
 resetDb :: Text -> IO ()
 resetDb dbConn = loadFixture dbConn "data"
