remove: drop support for PostgreSQL 12
This has been EOL since November and has been dropped from nixpkgs.
This commit is contained in:
@@ -67,7 +67,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pgVersion: [12, 13, 14, 15, 16, 17]
|
||||
pgVersion: [13, 14, 15, 16, 17]
|
||||
name: PG ${{ matrix.pgVersion }}
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
|
||||
@@ -59,7 +59,6 @@ let
|
||||
{ name = "postgresql-15"; postgresql = pkgs.postgresql_15.withPackages (p: [ p.postgis p.pg_safeupdate ]); }
|
||||
{ name = "postgresql-14"; postgresql = pkgs.postgresql_14.withPackages (p: [ p.postgis p.pg_safeupdate ]); }
|
||||
{ name = "postgresql-13"; postgresql = pkgs.postgresql_13.withPackages (p: [ p.postgis p.pg_safeupdate ]); }
|
||||
{ name = "postgresql-12"; postgresql = pkgs.postgresql_12.withPackages (p: [ p.postgis p.pg_safeupdate ]); }
|
||||
];
|
||||
|
||||
haskellPackages = pkgs.haskell.packages."${compiler}";
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ postgrest-dump-schema postgrest-watch
|
||||
postgrest-gen-ctags postgrest-with-all
|
||||
postgrest-gen-jwt postgrest-with-git
|
||||
postgrest-gen-secret postgrest-with-pgrst
|
||||
postgrest-git-hooks postgrest-with-postgresql-12
|
||||
postgrest-git-hooks
|
||||
postgrest-hsie-graph-modules postgrest-with-postgresql-13
|
||||
postgrest-hsie-graph-symbols postgrest-with-postgresql-14
|
||||
postgrest-hsie-minimal-imports postgrest-with-postgresql-15
|
||||
|
||||
@@ -45,7 +45,6 @@ import PostgREST.AppState (AppState)
|
||||
import PostgREST.Auth.Types (AuthResult (..))
|
||||
import PostgREST.Config (AppConfig (..), LogLevel (..),
|
||||
LogQuery (..))
|
||||
import PostgREST.Config.PgVersion (PgVersion (..))
|
||||
import PostgREST.Error (Error)
|
||||
import PostgREST.Network (resolveHost)
|
||||
import PostgREST.Observation (Observation (..))
|
||||
@@ -108,12 +107,11 @@ postgrest logLevel appState connWorker =
|
||||
Right authResult -> do
|
||||
appConf <- AppState.getConfig appState -- the config must be read again because it can reload
|
||||
maybeSchemaCache <- AppState.getSchemaCache appState
|
||||
pgVer <- AppState.getPgVersion appState
|
||||
|
||||
let
|
||||
eitherResponse :: IO (Either Error Wai.Response)
|
||||
eitherResponse =
|
||||
runExceptT $ postgrestResponse appState appConf maybeSchemaCache pgVer authResult req
|
||||
runExceptT $ postgrestResponse appState appConf maybeSchemaCache authResult req
|
||||
|
||||
response <- either Error.errorResponseFor identity <$> eitherResponse
|
||||
-- Launch the connWorker when the connection is down. The postgrest
|
||||
@@ -129,11 +127,10 @@ postgrestResponse
|
||||
:: AppState.AppState
|
||||
-> AppConfig
|
||||
-> Maybe SchemaCache
|
||||
-> PgVersion
|
||||
-> AuthResult
|
||||
-> Wai.Request
|
||||
-> Handler IO Wai.Response
|
||||
postgrestResponse appState conf@AppConfig{..} maybeSchemaCache pgVer authResult@AuthResult{..} req = do
|
||||
postgrestResponse appState conf@AppConfig{..} maybeSchemaCache authResult@AuthResult{..} req = do
|
||||
sCache <-
|
||||
case maybeSchemaCache of
|
||||
Just sCache ->
|
||||
@@ -150,7 +147,7 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache pgVer authResult@
|
||||
(parseTime, apiReq@ApiRequest{..}) <- withTiming $ liftEither . mapLeft Error.ApiRequestError $ ApiRequest.userApiRequest conf prefs req body
|
||||
(planTime, plan) <- withTiming $ liftEither $ Plan.actionPlan iAction conf apiReq sCache
|
||||
|
||||
let query = Query.query conf authResult apiReq plan sCache pgVer
|
||||
let query = Query.query conf authResult apiReq plan sCache
|
||||
logSQL = lift . AppState.getObserver appState . DBQuery (Query.getSQLQuery query)
|
||||
|
||||
(queryTime, queryResult) <- withTiming $ do
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
module PostgREST.Config.PgVersion
|
||||
( PgVersion(..)
|
||||
, minimumPgVersion
|
||||
, pgVersion130
|
||||
, pgVersion140
|
||||
, pgVersion150
|
||||
, pgVersion170
|
||||
@@ -26,10 +25,7 @@ instance Ord PgVersion where
|
||||
|
||||
-- | Tells the minimum PostgreSQL version required by this version of PostgREST
|
||||
minimumPgVersion :: PgVersion
|
||||
minimumPgVersion = pgVersion121
|
||||
|
||||
pgVersion121 :: PgVersion
|
||||
pgVersion121 = PgVersion 120001 "12.1" "12.1"
|
||||
minimumPgVersion = pgVersion130
|
||||
|
||||
pgVersion130 :: PgVersion
|
||||
pgVersion130 = PgVersion 130000 "13.0" "13.0"
|
||||
|
||||
@@ -70,7 +70,6 @@ import PostgREST.SchemaCache.Routine (MediaHandler (..),
|
||||
Routine (..),
|
||||
RoutineMap,
|
||||
RoutineParam (..),
|
||||
funcReturnsCompositeAlias,
|
||||
funcReturnsScalar,
|
||||
funcReturnsSetOfScalar,
|
||||
funcReturnsSingle)
|
||||
@@ -1024,7 +1023,6 @@ callPlan proc ApiRequest{} paramKeys args readReq = FunctionCall {
|
||||
, funCArgs = args
|
||||
, funCScalar = funcReturnsScalar proc
|
||||
, funCSetOfScalar = funcReturnsSetOfScalar proc
|
||||
, funCRetCompositeAlias = funcReturnsCompositeAlias proc
|
||||
, funCFilterFields = getFilterFieldNames readReq
|
||||
, funCReturning = inferColsEmbedNeeds readReq []
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ import PostgREST.SchemaCache.Routine (Routine (..),
|
||||
import Protolude
|
||||
|
||||
data CallPlan = FunctionCall
|
||||
{ funCQi :: QualifiedIdentifier
|
||||
, funCParams :: CallParams
|
||||
, funCArgs :: CallArgs
|
||||
, funCScalar :: Bool
|
||||
, funCSetOfScalar :: Bool
|
||||
, funCRetCompositeAlias :: Bool
|
||||
, funCFilterFields :: Set FieldName
|
||||
, funCReturning :: Set FieldName
|
||||
{ funCQi :: QualifiedIdentifier
|
||||
, funCParams :: CallParams
|
||||
, funCArgs :: CallArgs
|
||||
, funCScalar :: Bool
|
||||
, funCSetOfScalar :: Bool
|
||||
, funCFilterFields :: Set FieldName
|
||||
, funCReturning :: Set FieldName
|
||||
}
|
||||
|
||||
data CallParams
|
||||
|
||||
+10
-11
@@ -39,7 +39,6 @@ import PostgREST.ApiRequest.Preferences (PreferCount (..),
|
||||
import PostgREST.Auth.Types (AuthResult (..))
|
||||
import PostgREST.Config (AppConfig (..),
|
||||
OpenAPIMode (..))
|
||||
import PostgREST.Config.PgVersion (PgVersion (..))
|
||||
import PostgREST.Error (Error)
|
||||
import PostgREST.MediaType (MediaType (..))
|
||||
import PostgREST.Plan (ActionPlan (..),
|
||||
@@ -80,16 +79,16 @@ data QueryResult
|
||||
| MaybeDbResult InspectPlan (Maybe (TablesMap, RoutineMap, Maybe Text))
|
||||
| NoDbResult InfoPlan
|
||||
|
||||
query :: AppConfig -> AuthResult -> ApiRequest -> ActionPlan -> SchemaCache -> PgVersion -> Query
|
||||
query _ _ _ (NoDb x) _ _ = NoDbQuery $ NoDbResult x
|
||||
query config AuthResult{..} apiReq (Db plan) sCache pgVer =
|
||||
query :: AppConfig -> AuthResult -> ApiRequest -> ActionPlan -> SchemaCache -> Query
|
||||
query _ _ _ (NoDb x) _ = NoDbQuery $ NoDbResult x
|
||||
query config AuthResult{..} apiReq (Db plan) sCache =
|
||||
DbQuery isoLvl txMode dbHandler transaction mainSQLQuery
|
||||
where
|
||||
transaction = if prepared then SQL.transaction else SQL.unpreparedTransaction
|
||||
prepared = configDbPreparedStatements config
|
||||
isoLvl = planIsoLvl config authRole plan
|
||||
txMode = planTxMode plan
|
||||
(mainActionQuery, mainSQLQuery) = actionQuery plan config apiReq pgVer sCache
|
||||
(mainActionQuery, mainSQLQuery) = actionQuery plan config apiReq sCache
|
||||
dbHandler = do
|
||||
setPgLocals plan config authClaims authRole apiReq
|
||||
runPreReq config
|
||||
@@ -108,8 +107,8 @@ planIsoLvl AppConfig{configRoleIsoLvl} role actPlan = case actPlan of
|
||||
roleIsoLvl = HM.findWithDefault SQL.ReadCommitted role configRoleIsoLvl
|
||||
|
||||
-- TODO: Generate the Hasql Statement in a diferent module after the OpenAPI functionality is removed
|
||||
actionQuery :: DbActionPlan -> AppConfig -> ApiRequest -> PgVersion -> SchemaCache -> (DbHandler QueryResult, ByteString)
|
||||
actionQuery (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ _ =
|
||||
actionQuery :: DbActionPlan -> AppConfig -> ApiRequest -> SchemaCache -> (DbHandler QueryResult, ByteString)
|
||||
actionQuery (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
||||
(mainActionQuery, mainSQLQuery)
|
||||
where
|
||||
countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan
|
||||
@@ -131,7 +130,7 @@ actionQuery (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq@ApiReque
|
||||
optionalRollback conf apiReq
|
||||
DbCrudResult plan <$> resultSetWTotal conf apiReq resultSet countQuery
|
||||
|
||||
actionQuery (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ _ =
|
||||
actionQuery (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
||||
(mainActionQuery, mainSQLQuery)
|
||||
where
|
||||
(isPut, isInsert, pkCols) = case mrMutatePlan of {Insert{where_,insPkCols} -> ((not . null) where_, True, insPkCols); _ -> (False,False, mempty);}
|
||||
@@ -163,12 +162,12 @@ actionQuery (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiReques
|
||||
optionalRollback conf apiReq
|
||||
pure $ DbCrudResult plan resultSet
|
||||
|
||||
actionQuery (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} pgVer _ =
|
||||
actionQuery (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
||||
(mainActionQuery, mainSQLQuery)
|
||||
where
|
||||
(result, mainSQLQuery) = Statements.prepareCall
|
||||
crProc
|
||||
(QueryBuilder.callPlanToQuery crCallPlan pgVer)
|
||||
(QueryBuilder.callPlanToQuery crCallPlan)
|
||||
(QueryBuilder.readPlanToQuery crReadPlan)
|
||||
(QueryBuilder.readPlanToCountQuery crReadPlan)
|
||||
(shouldCount preferCount)
|
||||
@@ -182,7 +181,7 @@ actionQuery (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{
|
||||
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
|
||||
pure $ DbCallResult plan resultSet
|
||||
|
||||
actionQuery (MaybeDb plan@InspectPlan{ipSchema=tSchema}) AppConfig{..} _ _ sCache =
|
||||
actionQuery (MaybeDb plan@InspectPlan{ipSchema=tSchema}) AppConfig{..} _ sCache =
|
||||
(mainActionQuery, mempty)
|
||||
where
|
||||
mainActionQuery = lift $
|
||||
|
||||
@@ -28,7 +28,6 @@ import Data.Maybe (fromJust)
|
||||
import Data.Tree (Tree (..))
|
||||
|
||||
import PostgREST.ApiRequest.Preferences (PreferResolution (..))
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion130)
|
||||
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
||||
import PostgREST.SchemaCache.Relationship (Cardinality (..),
|
||||
Junction (..),
|
||||
@@ -169,8 +168,8 @@ mutatePlanToQuery (Delete mainQi logicForest returnings) =
|
||||
where
|
||||
whereLogic = if null logicForest then mempty else " WHERE " <> intercalateSnippet " AND " (pgFmtLogicTree mainQi <$> logicForest)
|
||||
|
||||
callPlanToQuery :: CallPlan -> PgVersion -> SQL.Snippet
|
||||
callPlanToQuery (FunctionCall qi params arguments returnsScalar returnsSetOfScalar returnsCompositeAlias filterFields returnings) pgVer =
|
||||
callPlanToQuery :: CallPlan -> SQL.Snippet
|
||||
callPlanToQuery (FunctionCall qi params arguments returnsScalar returnsSetOfScalar filterFields returnings) =
|
||||
"SELECT " <> (if returnsScalar || returnsSetOfScalar then "pgrst_call.pgrst_scalar" else returnedColumns) <> " " <>
|
||||
fromCall
|
||||
where
|
||||
@@ -186,9 +185,8 @@ callPlanToQuery (FunctionCall qi params arguments returnsScalar returnsSetOfScal
|
||||
"LATERAL " <> callIt (fmtParams prms)
|
||||
|
||||
callIt :: SQL.Snippet -> SQL.Snippet
|
||||
callIt argument | pgVer < pgVersion130 && returnsCompositeAlias = "(SELECT (" <> fromQi qi <> "(" <> argument <> ")).*) pgrst_call"
|
||||
| returnsScalar || returnsSetOfScalar = "(SELECT " <> fromQi qi <> "(" <> argument <> ") pgrst_scalar) pgrst_call"
|
||||
| otherwise = fromQi qi <> "(" <> argument <> ") pgrst_call"
|
||||
callIt argument | returnsScalar || returnsSetOfScalar = "(SELECT " <> fromQi qi <> "(" <> argument <> ") pgrst_scalar) pgrst_call"
|
||||
| otherwise = fromQi qi <> "(" <> argument <> ") pgrst_call"
|
||||
|
||||
fmtParams :: [RoutineParam] -> SQL.Snippet
|
||||
fmtParams prms = intercalateSnippet ", "
|
||||
|
||||
@@ -14,7 +14,6 @@ module PostgREST.SchemaCache.Routine
|
||||
, funcReturnsSingleComposite
|
||||
, funcReturnsVoid
|
||||
, funcTableName
|
||||
, funcReturnsCompositeAlias
|
||||
, funcReturnsSingle
|
||||
, MediaHandlerMap
|
||||
, ResolvedHandler
|
||||
@@ -127,12 +126,6 @@ funcReturnsSetOfScalar proc = case proc of
|
||||
Function{pdReturnType = SetOf (Scalar{})} -> True
|
||||
_ -> False
|
||||
|
||||
funcReturnsCompositeAlias :: Routine -> Bool
|
||||
funcReturnsCompositeAlias proc = case proc of
|
||||
Function{pdReturnType = Single (Composite _ True)} -> True
|
||||
Function{pdReturnType = SetOf (Composite _ True)} -> True
|
||||
_ -> False
|
||||
|
||||
funcReturnsSingleComposite :: Routine -> Bool
|
||||
funcReturnsSingleComposite proc = case proc of
|
||||
Function{pdReturnType = Single (Composite _ _)} -> True
|
||||
|
||||
@@ -11,8 +11,7 @@ import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
import Text.Heredoc
|
||||
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion130,
|
||||
pgVersion140)
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion140)
|
||||
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
@@ -208,11 +207,7 @@ spec actualPgVersion = do
|
||||
it "fails with 400 and error" $
|
||||
post "/simple_pk" [json| { "extra":"foo"} |]
|
||||
`shouldRespondWith`
|
||||
(if actualPgVersion >= pgVersion130 then
|
||||
[json|{"hint":null,"details":"Failing row contains (null, foo).","code":"23502","message":"null value in column \"k\" of relation \"simple_pk\" violates not-null constraint"}|]
|
||||
else
|
||||
[json|{"hint":null,"details":"Failing row contains (null, foo).","code":"23502","message":"null value in column \"k\" violates not-null constraint"}|]
|
||||
)
|
||||
[json|{"hint":null,"details":"Failing row contains (null, foo).","code":"23502","message":"null value in column \"k\" of relation \"simple_pk\" violates not-null constraint"}|]
|
||||
{ matchStatus = 400
|
||||
, matchHeaders = [ matchContentTypeJson]
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion130,
|
||||
pgVersion170)
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion170)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
@@ -50,27 +49,15 @@ spec actualPgVersion = do
|
||||
resStatus `shouldBe` Status { statusCode = 200, statusMessage="OK" }
|
||||
totalCost `shouldBe` 24.28
|
||||
|
||||
it "outputs blocks info when using the buffers option" $
|
||||
if actualPgVersion >= pgVersion130
|
||||
then do
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=buffers") ""
|
||||
it "outputs blocks info when using the buffers option" $ do
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=buffers") ""
|
||||
|
||||
let resBody = simpleBody r
|
||||
resHeaders = simpleHeaders r
|
||||
let resBody = simpleBody r
|
||||
resHeaders = simpleHeaders r
|
||||
|
||||
liftIO $ do
|
||||
resHeaders `shouldSatisfy` elem ("Content-Type", "application/vnd.pgrst.plan+json; for=\"application/json\"; options=buffers; charset=utf-8")
|
||||
resBody `shouldSatisfy` (\t -> T.isInfixOf "Shared Hit Blocks" (decodeUtf8 $ LBS.toStrict t))
|
||||
else do
|
||||
-- analyze is required for buffers on pg < 13
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=analyze|buffers") ""
|
||||
|
||||
let blocks = simpleBody r ^? nth 0 . key "Plan" . key "Shared Hit Blocks"
|
||||
resHeaders = simpleHeaders r
|
||||
|
||||
liftIO $ do
|
||||
resHeaders `shouldSatisfy` elem ("Content-Type", "application/vnd.pgrst.plan+json; for=\"application/json\"; options=analyze|buffers; charset=utf-8")
|
||||
blocks `shouldBe` Just [aesonQQ| 1.0 |]
|
||||
liftIO $ do
|
||||
resHeaders `shouldSatisfy` elem ("Content-Type", "application/vnd.pgrst.plan+json; for=\"application/json\"; options=buffers; charset=utf-8")
|
||||
resBody `shouldSatisfy` (\t -> T.isInfixOf "Shared Hit Blocks" (decodeUtf8 $ LBS.toStrict t))
|
||||
|
||||
it "outputs the search path when using the settings option" $ do
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=settings") ""
|
||||
@@ -87,16 +74,15 @@ spec actualPgVersion = do
|
||||
}
|
||||
|]
|
||||
|
||||
when (actualPgVersion >= pgVersion130) $
|
||||
it "outputs WAL info when using the wal option" $ do
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=analyze|wal") ""
|
||||
it "outputs WAL info when using the wal option" $ do
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=analyze|wal") ""
|
||||
|
||||
let walRecords = simpleBody r ^? nth 0 . key "Plan" . key "WAL Records"
|
||||
resHeaders = simpleHeaders r
|
||||
let walRecords = simpleBody r ^? nth 0 . key "Plan" . key "WAL Records"
|
||||
resHeaders = simpleHeaders r
|
||||
|
||||
liftIO $ do
|
||||
resHeaders `shouldSatisfy` elem ("Content-Type", "application/vnd.pgrst.plan+json; for=\"application/json\"; options=analyze|wal; charset=utf-8")
|
||||
walRecords `shouldBe` Just [aesonQQ|0|]
|
||||
liftIO $ do
|
||||
resHeaders `shouldSatisfy` elem ("Content-Type", "application/vnd.pgrst.plan+json; for=\"application/json\"; options=analyze|wal; charset=utf-8")
|
||||
walRecords `shouldBe` Just [aesonQQ|0|]
|
||||
|
||||
it "outputs columns info when using the verbose option" $ do
|
||||
r <- request methodGet "/projects" (acceptHdrs "application/vnd.pgrst.plan+json; options=verbose") ""
|
||||
|
||||
Reference in New Issue
Block a user