diff --git a/CHANGELOG.md b/CHANGELOG.md index 88b258b79..6c0dfdbad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- #1113, Fix UPSERT failing when having a camel case PK column - @steve-chavez + ### Changed ## [0.5.0.0] - 2018-05-14 diff --git a/src/PostgREST/QueryBuilder.hs b/src/PostgREST/QueryBuilder.hs index 5a8522a49..4d1491df0 100644 --- a/src/PostgREST/QueryBuilder.hs +++ b/src/PostgREST/QueryBuilder.hs @@ -288,7 +288,7 @@ requestToQuery schema _ (DbMutate (Insert mainTbl pkCols p@(PayloadJSON _ pType -- Only used for PUT ("WHERE " <> intercalate " AND " (pgFmtLogicTree (QualifiedIdentifier "" "_") <$> logicForest)) `emptyOnFalse` null logicForest], maybe "" (\x -> ( - "ON CONFLICT(" <> intercalate ", " pkCols <> ") " <> case x of + "ON CONFLICT(" <> intercalate ", " (pgFmtIdent <$> pkCols) <> ") " <> case x of IgnoreDuplicates -> "DO NOTHING" MergeDuplicates -> diff --git a/test/Feature/UpsertSpec.hs b/test/Feature/UpsertSpec.hs index 3c52b9696..e7cbcb177 100644 --- a/test/Feature/UpsertSpec.hs +++ b/test/Feature/UpsertSpec.hs @@ -198,3 +198,30 @@ spec = [("Prefer", "return=representation"), ("Accept", "application/vnd.pgrst.object+json")] [str| [ { "name": "Ruby", "rank": 11 } ]|] `shouldRespondWith` [json|{ "name": "Ruby", "rank": 11 }|] { matchHeaders = [matchContentTypeSingular] } + + context "with a camel case pk column" $ do + it "works with POST and merge-duplicates/ignore-duplicates headers" $ do + request methodPost "/UnitTest" [("Prefer", "return=representation"), ("Prefer", "resolution=merge-duplicates")] + [json| [ + { "idUnitTest": 1, "nameUnitTest": "name of unittest 1" }, + { "idUnitTest": 2, "nameUnitTest": "name of unittest 2" } + ]|] `shouldRespondWith` [json|[ + { "idUnitTest": 1, "nameUnitTest": "name of unittest 1" }, + { "idUnitTest": 2, "nameUnitTest": "name of unittest 2" } + ]|] + { matchStatus = 201 + , matchHeaders = ["Preference-Applied" <:> "resolution=merge-duplicates", matchContentTypeJson] + } + request methodPost "/UnitTest" [("Prefer", "return=representation"), ("Prefer", "resolution=ignore-duplicates")] + [json| [ + { "idUnitTest": 1, "nameUnitTest": "name of unittest 1" }, + { "idUnitTest": 2, "nameUnitTest": "name of unittest 2" } + ]|] `shouldRespondWith` [json|[]|] + { matchStatus = 201 + , matchHeaders = ["Preference-Applied" <:> "resolution=ignore-duplicates", matchContentTypeJson] + } + + it "works with PUT" $ do + put "/UnitTest?idUnitTest=eq.1" [str| [ { "idUnitTest": 1, "nameUnitTest": "unit test 1" } ]|] `shouldRespondWith` 204 + get "/UnitTest?idUnitTest=eq.1" `shouldRespondWith` + [json| [ { "idUnitTest": 1, "nameUnitTest": "unit test 1" } ]|] { matchHeaders = [matchContentTypeJson] } diff --git a/test/fixtures/data.sql b/test/fixtures/data.sql index d421b4d0a..b8d9e6436 100644 --- a/test/fixtures/data.sql +++ b/test/fixtures/data.sql @@ -411,3 +411,6 @@ INSERT INTO zone VALUES (4, 'store 4', 3, 1); -- for foreign table projects_dump copy (select id, name, client_id from projects) to '/tmp/projects_dump.csv' with csv; + +TRUNCATE TABLE "UnitTest" CASCADE; +INSERT INTO "UnitTest" VALUES (1, 'unit test 1'); diff --git a/test/fixtures/privileges.sql b/test/fixtures/privileges.sql index b94dbb746..beced9875 100644 --- a/test/fixtures/privileges.sql +++ b/test/fixtures/privileges.sql @@ -79,6 +79,7 @@ GRANT ALL ON TABLE , space , zone , projects_dump + , "UnitTest" TO postgrest_test_anonymous; GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous; diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index 8ef333926..05df3f9d4 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -1451,3 +1451,8 @@ comment on foreign table projects_dump is $$A temporary projects dump Just a test for foreign tables$$; + +create table "UnitTest"( + "idUnitTest" integer primary key, + "nameUnitTest" text +);