diff --git a/CHANGELOG.md b/CHANGELOG.md
index c31f7871c..227678e5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #2236, Support POSIX regular expression operators for row filtering - @enote-kane
- #2202, Allow returning XML from RPCs - @fjf2002
- #2269, Allow `limit=0` in the request query to return an empty array - @gautam1168, @laurenceisla
+ - #2268, Allow returning XML from single-column queries #2268 - @fjf2002
### Fixed
diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs
index b284c822f..b5d9f59bd 100644
--- a/src/PostgREST/App.hs
+++ b/src/PostgREST/App.hs
@@ -270,6 +270,7 @@ handleRead headersOnly identifier context@RequestContext{..} = do
(iAcceptContentType == CTSingularJSON)
(shouldCount iPreferCount)
(iAcceptContentType == CTTextCSV)
+ (iAcceptContentType == CTTextXML)
bField
configDbPreparedStatements
diff --git a/src/PostgREST/Query/Statements.hs b/src/PostgREST/Query/Statements.hs
index 430d7815c..d11255c8a 100644
--- a/src/PostgREST/Query/Statements.hs
+++ b/src/PostgREST/Query/Statements.hs
@@ -86,9 +86,9 @@ createWriteStatement selectQuery mutateQuery wantSingle isInsert asCsv rep pKeys
decodeStandard =
fromMaybe (Nothing, 0, [], mempty, Right [], Right Nothing) <$> HD.rowMaybe standardRow
-createReadStatement :: SQL.Snippet -> SQL.Snippet -> Bool -> Bool -> Bool -> Maybe FieldName -> Bool ->
+createReadStatement :: SQL.Snippet -> SQL.Snippet -> Bool -> Bool -> Bool -> Bool -> Maybe FieldName -> Bool ->
SQL.Statement () ResultsWithCount
-createReadStatement selectQuery countQuery isSingle countTotal asCsv binaryField =
+createReadStatement selectQuery countQuery isSingle countTotal asCsv asXml binaryField =
SQL.dynamicallyParameterized snippet decodeStandard
where
snippet =
@@ -109,6 +109,7 @@ createReadStatement selectQuery countQuery isSingle countTotal asCsv binaryField
bodyF
| asCsv = asCsvF
| isSingle = asJsonSingleF False
+ | isJust binaryField && asXml = asXmlF $ fromJust binaryField
| isJust binaryField = asBinaryF $ fromJust binaryField
| otherwise = asJsonF False
diff --git a/test/spec/Feature/Query/QuerySpec.hs b/test/spec/Feature/Query/QuerySpec.hs
index 718806a22..c3ecf3361 100644
--- a/test/spec/Feature/Query/QuerySpec.hs
+++ b/test/spec/Feature/Query/QuerySpec.hs
@@ -1010,6 +1010,14 @@ spec actualPgVersion = do
, matchHeaders = ["Content-Type" <:> "text/plain; charset=utf-8"]
}
+ it "can get raw xml output with Accept: text/xml" $
+ request methodGet "/xmltest?select=xml" (acceptHdrs "text/xml") ""
+ `shouldRespondWith`
+ "foobar"
+ { matchStatus = 200
+ , matchHeaders = ["Content-Type" <:> "text/xml; charset=utf-8"]
+ }
+
it "fails if a single column is not selected" $ do
request methodGet "/images?select=img,name&name=eq.A.png" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith`
diff --git a/test/spec/fixtures/privileges.sql b/test/spec/fixtures/privileges.sql
index e25b35dcc..7ac0f7d5c 100644
--- a/test/spec/fixtures/privileges.sql
+++ b/test/spec/fixtures/privileges.sql
@@ -178,6 +178,7 @@ GRANT ALL ON TABLE
, limited_delete_items_wnonuniq_view
, limited_delete_items_cpk_view
, limited_update_items_cpk_view
+ , xmltest
TO postgrest_test_anonymous;
GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous;
diff --git a/test/spec/fixtures/schema.sql b/test/spec/fixtures/schema.sql
index 7db770c3c..25013243a 100644
--- a/test/spec/fixtures/schema.sql
+++ b/test/spec/fixtures/schema.sql
@@ -2583,3 +2583,13 @@ select $$