refactor: delete QueryCost, instead use PlanSpec
This commit is contained in:
committed by
Laurence Isla
parent
ae3c784921
commit
519dbc75f3
@@ -13,6 +13,7 @@ import Network.HTTP.Types
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
import Text.Heredoc
|
||||
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion120,
|
||||
pgVersion130)
|
||||
@@ -298,6 +299,41 @@ spec actualPgVersion = do
|
||||
|
||||
liftIO $ planCost r `shouldSatisfy` (< 70.9)
|
||||
|
||||
|
||||
describe "function call costs" $ do
|
||||
it "should not exceed cost when calling setof composite proc" $ do
|
||||
r <- request methodGet "/rpc/get_projects_below?id=3"
|
||||
[planHdr] ""
|
||||
|
||||
liftIO $ planCost r `shouldSatisfy` (< 36.4)
|
||||
|
||||
it "should not exceed cost when calling setof composite proc with empty params" $ do
|
||||
r <- request methodGet "/rpc/getallprojects"
|
||||
[planHdr] ""
|
||||
|
||||
liftIO $ planCost r `shouldSatisfy` (< 71.0)
|
||||
|
||||
it "should not exceed cost when calling scalar proc" $ do
|
||||
r <- request methodGet "/rpc/add_them?a=3&b=4"
|
||||
[planHdr] ""
|
||||
|
||||
liftIO $ planCost r `shouldSatisfy` (< 1.18)
|
||||
|
||||
context "params=multiple-objects" $ do
|
||||
it "should not exceed cost when calling setof composite proc" $ do
|
||||
r <- request methodPost "/rpc/get_projects_below"
|
||||
[planHdr, ("Prefer", "params=multiple-objects")]
|
||||
[str| [{"id": 1}, {"id": 4}] |]
|
||||
|
||||
liftIO $ planCost r `shouldSatisfy` (< 4503.4)
|
||||
|
||||
it "should not exceed cost when calling scalar proc" $ do
|
||||
r <- request methodPost "/rpc/add_them"
|
||||
[planHdr, ("Prefer", "params=multiple-objects")]
|
||||
[str| [{"a": 3, "b": 4}, {"a": 1, "b": 2}, {"a": 8, "b": 7}] |]
|
||||
|
||||
liftIO $ planCost r `shouldSatisfy` (< 5.85)
|
||||
|
||||
disabledSpec :: SpecWith ((), Application)
|
||||
disabledSpec =
|
||||
it "doesn't work if db-plan-enabled=false(the default)" $ do
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
-- TODO Can be replaced now by obtaining the EXPLAIN plan and adding the cost tests on PlanSpec.hs
|
||||
module Main where
|
||||
|
||||
import Control.Lens ((^?))
|
||||
import qualified Data.Aeson.Lens as L
|
||||
import qualified Hasql.Decoders as HD
|
||||
import qualified Hasql.DynamicStatements.Snippet as H
|
||||
import qualified Hasql.DynamicStatements.Statement as H
|
||||
import qualified Hasql.Pool as P
|
||||
import qualified Hasql.Statement as H
|
||||
import qualified Hasql.Transaction as HT
|
||||
import qualified Hasql.Transaction.Sessions as HT
|
||||
import Text.Heredoc
|
||||
|
||||
import Protolude hiding (get, toS)
|
||||
|
||||
import PostgREST.Plan.CallPlan
|
||||
import PostgREST.Query.QueryBuilder (callPlanToQuery)
|
||||
|
||||
import PostgREST.SchemaCache.Identifiers
|
||||
import PostgREST.SchemaCache.Proc
|
||||
|
||||
import Test.Hspec
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
pool <- P.acquire 3 Nothing "postgresql://"
|
||||
|
||||
hspec $ describe "QueryCost" $
|
||||
context "call proc query" $ do
|
||||
it "should not exceed cost when calling setof composite proc" $ do
|
||||
cost <- exec pool $
|
||||
callPlanToQuery (FunctionCall (QualifiedIdentifier "test" "get_projects_below")
|
||||
(KeyParams [ProcParam "id" "int" True False])
|
||||
(Just [str| {"id": 3} |]) False False [])
|
||||
liftIO $
|
||||
cost `shouldSatisfy` (< Just 40)
|
||||
|
||||
it "should not exceed cost when calling setof composite proc with empty params" $ do
|
||||
cost <- exec pool $
|
||||
callPlanToQuery (FunctionCall (QualifiedIdentifier "test" "getallprojects") (KeyParams []) Nothing False False [])
|
||||
liftIO $
|
||||
cost `shouldSatisfy` (< Just 30)
|
||||
|
||||
it "should not exceed cost when calling scalar proc" $ do
|
||||
cost <- exec pool $
|
||||
callPlanToQuery (FunctionCall (QualifiedIdentifier "test" "add_them")
|
||||
(KeyParams [ProcParam "a" "int" True False, ProcParam "b" "int" True False])
|
||||
(Just [str| {"a": 3, "b": 4} |]) True False [])
|
||||
liftIO $
|
||||
cost `shouldSatisfy` (< Just 10)
|
||||
|
||||
context "params=multiple-objects" $ do
|
||||
it "should not exceed cost when calling setof composite proc" $ do
|
||||
cost <- exec pool $
|
||||
callPlanToQuery (FunctionCall (QualifiedIdentifier "test" "get_projects_below")
|
||||
(KeyParams [ProcParam "id" "int" True False])
|
||||
(Just [str| [{"id": 1}, {"id": 4}] |]) False True [])
|
||||
liftIO $ do
|
||||
-- lower bound needed for now to make sure that cost is not Nothing
|
||||
cost `shouldSatisfy` (> Just 2000)
|
||||
cost `shouldSatisfy` (< Just 2100)
|
||||
|
||||
it "should not exceed cost when calling scalar proc" $ do
|
||||
cost <- exec pool $
|
||||
callPlanToQuery (FunctionCall (QualifiedIdentifier "test" "add_them")
|
||||
(KeyParams [ProcParam "a" "int" True False, ProcParam "b" "int" True False])
|
||||
(Just [str| [{"a": 3, "b": 4}, {"a": 1, "b": 2}, {"a": 8, "b": 7}] |]) True False [])
|
||||
liftIO $
|
||||
cost `shouldSatisfy` (< Just 10)
|
||||
|
||||
|
||||
exec :: P.Pool -> H.Snippet -> IO (Maybe Int64)
|
||||
exec pool query =
|
||||
join . rightToMaybe <$>
|
||||
P.use pool (HT.transaction HT.ReadCommitted HT.Read $ HT.statement mempty $ explainCost query)
|
||||
|
||||
explainCost :: H.Snippet -> H.Statement () (Maybe Int64)
|
||||
explainCost query =
|
||||
H.dynamicallyParameterized snippet decodeExplain False
|
||||
where
|
||||
snippet = "EXPLAIN (FORMAT JSON) " <> query
|
||||
decodeExplain :: HD.Result (Maybe Int64)
|
||||
decodeExplain =
|
||||
let row = HD.singleRow $ HD.column $ HD.nonNullable HD.bytea in
|
||||
(^? L.nth 0 . L.key "Plan" . L.key "Total Cost" . L._Integral) <$> row
|
||||
Reference in New Issue
Block a user