feat: Raise minimum supported version to 12.1

There is no reason to support the 12.0 version, which is outdated for
many years already. We still support all other minors for v12.
This commit is contained in:
Wolfgang Walther
2024-06-15 17:23:34 +02:00
committed by Wolfgang Walther
parent 7d2d363575
commit b38ea4dcd0
4 changed files with 85 additions and 101 deletions
+1 -5
View File
@@ -3,7 +3,6 @@
module PostgREST.Config.PgVersion module PostgREST.Config.PgVersion
( PgVersion(..) ( PgVersion(..)
, minimumPgVersion , minimumPgVersion
, pgVersion121
, pgVersion130 , pgVersion130
, pgVersion140 , pgVersion140
, pgVersion150 , pgVersion150
@@ -26,10 +25,7 @@ instance Ord PgVersion where
-- | Tells the minimum PostgreSQL version required by this version of PostgREST -- | Tells the minimum PostgreSQL version required by this version of PostgREST
minimumPgVersion :: PgVersion minimumPgVersion :: PgVersion
minimumPgVersion = pgVersion120 minimumPgVersion = pgVersion121
pgVersion120 :: PgVersion
pgVersion120 = PgVersion 120000 "12.0" "12.0"
pgVersion121 :: PgVersion pgVersion121 :: PgVersion
pgVersion121 = PgVersion 120001 "12.1" "12.1" pgVersion121 = PgVersion 120001 "12.1" "12.1"
+3 -9
View File
@@ -7,13 +7,11 @@ import Test.Hspec
import Test.Hspec.Wai import Test.Hspec.Wai
import Test.Hspec.Wai.JSON import Test.Hspec.Wai.JSON
import PostgREST.Config.PgVersion (PgVersion, pgVersion121)
import Protolude hiding (get) import Protolude hiding (get)
import SpecHelper import SpecHelper
spec :: PgVersion -> SpecWith ((), Application) spec :: SpecWith ((), Application)
spec actualPgVersion = describe "json and jsonb operators" $ do spec = describe "json and jsonb operators" $ do
context "Shaping response with select parameter" $ do context "Shaping response with select parameter" $ do
it "obtains a json subfield one level with casting" $ it "obtains a json subfield one level with casting" $
get "/complex_items?id=eq.1&select=settings->>foo::json" `shouldRespondWith` get "/complex_items?id=eq.1&select=settings->>foo::json" `shouldRespondWith`
@@ -27,12 +25,8 @@ spec actualPgVersion = describe "json and jsonb operators" $ do
it "fails on bad casting (data of the wrong format)" $ it "fails on bad casting (data of the wrong format)" $
get "/complex_items?select=settings->foo->>bar::integer" get "/complex_items?select=settings->foo->>bar::integer"
`shouldRespondWith` ( `shouldRespondWith`
if actualPgVersion >= pgVersion121 then
[json| {"hint":null,"details":null,"code":"22P02","message":"invalid input syntax for type integer: \"baz\""} |] [json| {"hint":null,"details":null,"code":"22P02","message":"invalid input syntax for type integer: \"baz\""} |]
else
[json| {"hint":null,"details":null,"code":"22P02","message":"invalid input syntax for integer: \"baz\""} |]
)
{ matchStatus = 400 , matchHeaders = [] } { matchStatus = 400 , matchHeaders = [] }
it "obtains a json subfield two levels (string)" $ it "obtains a json subfield two levels (string)" $
+79 -85
View File
@@ -8,12 +8,11 @@ import Test.Hspec hiding (pendingWith)
import Test.Hspec.Wai import Test.Hspec.Wai
import Test.Hspec.Wai.JSON import Test.Hspec.Wai.JSON
import PostgREST.Config.PgVersion (PgVersion, pgVersion121) import Protolude hiding (get)
import Protolude hiding (get)
import SpecHelper import SpecHelper
spec :: PgVersion -> SpecWith ((), Application) spec :: SpecWith ((), Application)
spec actualPgVersion = do spec = do
describe "Querying a table with a column called count" $ describe "Querying a table with a column called count" $
it "should not confuse count column with pg_catalog.count aggregate" $ it "should not confuse count column with pg_catalog.count aggregate" $
@@ -551,90 +550,89 @@ spec actualPgVersion = do
{"name":"Lamborghini","car_models":[{"name":"Murcielago","year":2001},{"name":"Veneno","year":2013}]}] |] {"name":"Lamborghini","car_models":[{"name":"Murcielago","year":2001},{"name":"Veneno","year":2013}]}] |]
{ matchHeaders = [matchContentTypeJson] } { matchHeaders = [matchContentTypeJson] }
when (actualPgVersion >= pgVersion121) $ do it "can request tables as children from a partitioned table" $
it "can request tables as children from a partitioned table" $ get "/car_models?name=in.(DeLorean,F310-B)&select=name,year,car_racers(name)&order=name.asc" `shouldRespondWith`
get "/car_models?name=in.(DeLorean,F310-B)&select=name,year,car_racers(name)&order=name.asc" `shouldRespondWith` [json|
[json| [{"name":"DeLorean","year":1981,"car_racers":[]},
[{"name":"DeLorean","year":1981,"car_racers":[]}, {"name":"F310-B","year":1997,"car_racers":[{"name":"Michael Schumacher"}]}] |]
{"name":"F310-B","year":1997,"car_racers":[{"name":"Michael Schumacher"}]}] |] { matchHeaders = [matchContentTypeJson] }
{ matchHeaders = [matchContentTypeJson] }
it "can request a partitioned table as parent from a table" $ it "can request a partitioned table as parent from a table" $
get "/car_racers?select=name,car_models(name,year)&order=name.asc" `shouldRespondWith` get "/car_racers?select=name,car_models(name,year)&order=name.asc" `shouldRespondWith`
[json| [json|
[{"name":"Alain Prost","car_models":null}, [{"name":"Alain Prost","car_models":null},
{"name":"Michael Schumacher","car_models":{"name":"F310-B","year":1997}}] |] {"name":"Michael Schumacher","car_models":{"name":"F310-B","year":1997}}] |]
{ matchHeaders = [matchContentTypeJson] } { matchHeaders = [matchContentTypeJson] }
it "can request partitioned tables as children from a partitioned table" $ it "can request partitioned tables as children from a partitioned table" $
get "/car_models?name=in.(DeLorean,Murcielago,Veneno)&select=name,year,car_model_sales(date,quantity)&order=name.asc" `shouldRespondWith` get "/car_models?name=in.(DeLorean,Murcielago,Veneno)&select=name,year,car_model_sales(date,quantity)&order=name.asc" `shouldRespondWith`
[json| [json|
[{"name":"DeLorean","year":1981,"car_model_sales":[{"date":"2021-01-14","quantity":7},{"date":"2021-01-15","quantity":9}]}, [{"name":"DeLorean","year":1981,"car_model_sales":[{"date":"2021-01-14","quantity":7},{"date":"2021-01-15","quantity":9}]},
{"name":"Murcielago","year":2001,"car_model_sales":[{"date":"2021-02-11","quantity":1},{"date":"2021-02-12","quantity":3}]}, {"name":"Murcielago","year":2001,"car_model_sales":[{"date":"2021-02-11","quantity":1},{"date":"2021-02-12","quantity":3}]},
{"name":"Veneno","year":2013,"car_model_sales":[]}] |] {"name":"Veneno","year":2013,"car_model_sales":[]}] |]
{ matchHeaders = [matchContentTypeJson] } { matchHeaders = [matchContentTypeJson] }
it "can request a partitioned table as parent from a partitioned table" $ do it "can request a partitioned table as parent from a partitioned table" $ do
get "/car_model_sales?date=in.(2021-01-15,2021-02-11)&select=date,quantity,car_models(name,year)&order=date.asc" `shouldRespondWith` get "/car_model_sales?date=in.(2021-01-15,2021-02-11)&select=date,quantity,car_models(name,year)&order=date.asc" `shouldRespondWith`
[json| [json|
[{"date":"2021-01-15","quantity":9,"car_models":{"name":"DeLorean","year":1981}}, [{"date":"2021-01-15","quantity":9,"car_models":{"name":"DeLorean","year":1981}},
{"date":"2021-02-11","quantity":1,"car_models":{"name":"Murcielago","year":2001}}] |] {"date":"2021-02-11","quantity":1,"car_models":{"name":"Murcielago","year":2001}}] |]
{ matchHeaders = [matchContentTypeJson] } { matchHeaders = [matchContentTypeJson] }
it "can request many to many relationships between partitioned tables ignoring the intermediate table partitions" $ it "can request many to many relationships between partitioned tables ignoring the intermediate table partitions" $
get "/car_models?select=name,year,car_dealers(name,city)&order=name.asc&limit=4" `shouldRespondWith` get "/car_models?select=name,year,car_dealers(name,city)&order=name.asc&limit=4" `shouldRespondWith`
[json| [json|
[{"name":"DeLorean","year":1981,"car_dealers":[{"name":"Springfield Cars S.A.","city":"Springfield"}]}, [{"name":"DeLorean","year":1981,"car_dealers":[{"name":"Springfield Cars S.A.","city":"Springfield"}]},
{"name":"F310-B","year":1997,"car_dealers":[]}, {"name":"F310-B","year":1997,"car_dealers":[]},
{"name":"Murcielago","year":2001,"car_dealers":[{"name":"The Best Deals S.A.","city":"Franklin"}]}, {"name":"Murcielago","year":2001,"car_dealers":[{"name":"The Best Deals S.A.","city":"Franklin"}]},
{"name":"Veneno","year":2013,"car_dealers":[]}] |] {"name":"Veneno","year":2013,"car_dealers":[]}] |]
{ matchStatus = 200 { matchStatus = 200
, matchHeaders = [matchContentTypeJson] , matchHeaders = [matchContentTypeJson]
} }
it "cannot request partitions as children from a partitioned table" $ it "cannot request partitions as children from a partitioned table" $
get "/car_models?id=in.(1,2,4)&select=id,name,car_model_sales_202101(id)&order=id.asc" `shouldRespondWith` get "/car_models?id=in.(1,2,4)&select=id,name,car_model_sales_202101(id)&order=id.asc" `shouldRespondWith`
[json| [json|
{"hint":"Perhaps you meant 'car_model_sales' instead of 'car_model_sales_202101'.", {"hint":"Perhaps you meant 'car_model_sales' instead of 'car_model_sales_202101'.",
"details":"Searched for a foreign key relationship between 'car_models' and 'car_model_sales_202101' in the schema 'test', but no matches were found.", "details":"Searched for a foreign key relationship between 'car_models' and 'car_model_sales_202101' in the schema 'test', but no matches were found.",
"code":"PGRST200", "code":"PGRST200",
"message":"Could not find a relationship between 'car_models' and 'car_model_sales_202101' in the schema cache"} |] "message":"Could not find a relationship between 'car_models' and 'car_model_sales_202101' in the schema cache"} |]
{ matchStatus = 400 { matchStatus = 400
, matchHeaders = [matchContentTypeJson] , matchHeaders = [matchContentTypeJson]
} }
it "cannot request a partitioned table as parent from a partition" $ it "cannot request a partitioned table as parent from a partition" $
get "/car_model_sales_202101?select=id,name,car_models(id,name)&order=id.asc" `shouldRespondWith` get "/car_model_sales_202101?select=id,name,car_models(id,name)&order=id.asc" `shouldRespondWith`
[json| [json|
{"hint":"Perhaps you meant 'car_model_sales' instead of 'car_model_sales_202101'.", {"hint":"Perhaps you meant 'car_model_sales' instead of 'car_model_sales_202101'.",
"details":"Searched for a foreign key relationship between 'car_model_sales_202101' and 'car_models' in the schema 'test', but no matches were found.", "details":"Searched for a foreign key relationship between 'car_model_sales_202101' and 'car_models' in the schema 'test', but no matches were found.",
"code":"PGRST200", "code":"PGRST200",
"message":"Could not find a relationship between 'car_model_sales_202101' and 'car_models' in the schema cache"} |] "message":"Could not find a relationship between 'car_model_sales_202101' and 'car_models' in the schema cache"} |]
{ matchStatus = 400 { matchStatus = 400
, matchHeaders = [matchContentTypeJson] , matchHeaders = [matchContentTypeJson]
} }
it "cannot request a partition as parent from a partitioned table" $ it "cannot request a partition as parent from a partitioned table" $
get "/car_model_sales?id=in.(1,3,4)&select=id,name,car_models_default(id,name)&order=id.asc" `shouldRespondWith` get "/car_model_sales?id=in.(1,3,4)&select=id,name,car_models_default(id,name)&order=id.asc" `shouldRespondWith`
[json| [json|
{"hint":"Perhaps you meant 'car_models' instead of 'car_models_default'.", {"hint":"Perhaps you meant 'car_models' instead of 'car_models_default'.",
"details":"Searched for a foreign key relationship between 'car_model_sales' and 'car_models_default' in the schema 'test', but no matches were found.", "details":"Searched for a foreign key relationship between 'car_model_sales' and 'car_models_default' in the schema 'test', but no matches were found.",
"code":"PGRST200", "code":"PGRST200",
"message":"Could not find a relationship between 'car_model_sales' and 'car_models_default' in the schema cache"} |] "message":"Could not find a relationship between 'car_model_sales' and 'car_models_default' in the schema cache"} |]
{ matchStatus = 400 { matchStatus = 400
, matchHeaders = [matchContentTypeJson] , matchHeaders = [matchContentTypeJson]
} }
it "cannot request partitioned tables as children from a partition" $ it "cannot request partitioned tables as children from a partition" $
get "/car_models_default?select=id,name,car_model_sales(id,name)&order=id.asc" `shouldRespondWith` get "/car_models_default?select=id,name,car_model_sales(id,name)&order=id.asc" `shouldRespondWith`
[json| [json|
{"hint":"Perhaps you meant 'car_model_sales' instead of 'car_models_default'.", {"hint":"Perhaps you meant 'car_model_sales' instead of 'car_models_default'.",
"details":"Searched for a foreign key relationship between 'car_models_default' and 'car_model_sales' in the schema 'test', but no matches were found.", "details":"Searched for a foreign key relationship between 'car_models_default' and 'car_model_sales' in the schema 'test', but no matches were found.",
"code":"PGRST200", "code":"PGRST200",
"message":"Could not find a relationship between 'car_models_default' and 'car_model_sales' in the schema cache"} |] "message":"Could not find a relationship between 'car_models_default' and 'car_model_sales' in the schema cache"} |]
{ matchStatus = 400 { matchStatus = 400
, matchHeaders = [matchContentTypeJson] , matchHeaders = [matchContentTypeJson]
} }
describe "view embedding" $ do describe "view embedding" $ do
it "can detect fk relations through views to tables in the public schema" $ it "can detect fk relations through views to tables in the public schema" $
@@ -1133,12 +1131,8 @@ spec actualPgVersion = do
it "only returns an empty result set if the in value is empty" $ it "only returns an empty result set if the in value is empty" $
get "/items_with_different_col_types?int_data=in.( ,3,4)" get "/items_with_different_col_types?int_data=in.( ,3,4)"
`shouldRespondWith` ( `shouldRespondWith`
if actualPgVersion >= pgVersion121 then
[json| {"hint":null,"details":null,"code":"22P02","message":"invalid input syntax for type integer: \"\""} |] [json| {"hint":null,"details":null,"code":"22P02","message":"invalid input syntax for type integer: \"\""} |]
else
[json| {"hint":null,"details":null,"code":"22P02","message":"invalid input syntax for integer: \"\""} |]
)
{ matchStatus = 400 { matchStatus = 400
, matchHeaders = [matchContentTypeJson] , matchHeaders = [matchContentTypeJson]
} }
+2 -2
View File
@@ -150,13 +150,13 @@ main = do
, ("Feature.Query.EmbedDisambiguationSpec" , Feature.Query.EmbedDisambiguationSpec.spec) , ("Feature.Query.EmbedDisambiguationSpec" , Feature.Query.EmbedDisambiguationSpec.spec)
, ("Feature.Query.EmbedInnerJoinSpec" , Feature.Query.EmbedInnerJoinSpec.spec) , ("Feature.Query.EmbedInnerJoinSpec" , Feature.Query.EmbedInnerJoinSpec.spec)
, ("Feature.Query.InsertSpec" , Feature.Query.InsertSpec.spec actualPgVersion) , ("Feature.Query.InsertSpec" , Feature.Query.InsertSpec.spec actualPgVersion)
, ("Feature.Query.JsonOperatorSpec" , Feature.Query.JsonOperatorSpec.spec actualPgVersion) , ("Feature.Query.JsonOperatorSpec" , Feature.Query.JsonOperatorSpec.spec)
, ("Feature.Query.NullsStripSpec" , Feature.Query.NullsStripSpec.spec) , ("Feature.Query.NullsStripSpec" , Feature.Query.NullsStripSpec.spec)
, ("Feature.Query.PgErrorCodeMappingSpec" , Feature.Query.ErrorSpec.pgErrorCodeMapping) , ("Feature.Query.PgErrorCodeMappingSpec" , Feature.Query.ErrorSpec.pgErrorCodeMapping)
, ("Feature.Query.PgSafeUpdateSpec.disabledSpec" , Feature.Query.PgSafeUpdateSpec.disabledSpec) , ("Feature.Query.PgSafeUpdateSpec.disabledSpec" , Feature.Query.PgSafeUpdateSpec.disabledSpec)
, ("Feature.Query.PlanSpec.disabledSpec" , Feature.Query.PlanSpec.disabledSpec) , ("Feature.Query.PlanSpec.disabledSpec" , Feature.Query.PlanSpec.disabledSpec)
, ("Feature.Query.PreferencesSpec" , Feature.Query.PreferencesSpec.spec) , ("Feature.Query.PreferencesSpec" , Feature.Query.PreferencesSpec.spec)
, ("Feature.Query.QuerySpec" , Feature.Query.QuerySpec.spec actualPgVersion) , ("Feature.Query.QuerySpec" , Feature.Query.QuerySpec.spec)
, ("Feature.Query.RawOutputTypesSpec" , Feature.Query.RawOutputTypesSpec.spec) , ("Feature.Query.RawOutputTypesSpec" , Feature.Query.RawOutputTypesSpec.spec)
, ("Feature.Query.RelatedQueriesSpec" , Feature.Query.RelatedQueriesSpec.spec) , ("Feature.Query.RelatedQueriesSpec" , Feature.Query.RelatedQueriesSpec.spec)
, ("Feature.Query.RpcSpec" , Feature.Query.RpcSpec.spec) , ("Feature.Query.RpcSpec" , Feature.Query.RpcSpec.spec)