mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
server/nada: add unit tests for Postgres insert SQL generation
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5543 GitOrigin-RevId: 55646f653926559f1847aa692d3522627a463d25
This commit is contained in:
parent
56f2501ab9
commit
1e48af2d03
@ -1040,6 +1040,7 @@ test-suite graphql-engine-tests
|
||||
Hasura.Backends.Postgres.SQL.Select.RenameIdentifiersSpec
|
||||
Hasura.Backends.Postgres.SQL.ValueSpec
|
||||
Hasura.Backends.Postgres.Translate.DeleteSpec
|
||||
Hasura.Backends.Postgres.Translate.InsertSpec
|
||||
Hasura.Backends.Postgres.Translate.UpdateSpec
|
||||
Hasura.EventingSpec
|
||||
Hasura.Generator.Common
|
||||
@ -1073,11 +1074,13 @@ test-suite graphql-engine-tests
|
||||
Network.HTTP.Client.TransformableSpec
|
||||
Test.Aeson.Utils
|
||||
Test.Backend.Postgres.Delete
|
||||
Test.Backend.Postgres.Insert
|
||||
Test.Backend.Postgres.Misc
|
||||
Test.Backend.Postgres.Update
|
||||
Test.Parser.Delete
|
||||
Test.Parser.Expectation
|
||||
Test.Parser.Field
|
||||
Test.Parser.Insert
|
||||
Test.Parser.Internal
|
||||
Test.Parser.Monad
|
||||
Test.QuickCheck.Extended
|
||||
|
@ -0,0 +1,37 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
|
||||
module Hasura.Backends.Postgres.Translate.InsertSpec
|
||||
( spec,
|
||||
)
|
||||
where
|
||||
|
||||
import Database.PG.Query.Pool qualified as QQ
|
||||
import Hasura.RQL.IR.Returning (MutFldG (..), MutationOutputG (..))
|
||||
import Test.Backend.Postgres.Insert qualified as Test
|
||||
import Test.Backend.Postgres.Misc qualified as P
|
||||
import Test.Hspec
|
||||
import Test.Parser.Expectation as Expect
|
||||
|
||||
-- | TODO: add tests for OnConflict. Start with no longer passing 'Nothing' to
|
||||
-- /iqp1Conflict/ in 'Test.Parser.Insert.mkInsertQuery'.
|
||||
spec :: Spec
|
||||
spec =
|
||||
describe "Postgres.Translate.InsertSpec" do
|
||||
Test.runTest
|
||||
Test.TestBuilder
|
||||
{ name = "insert record",
|
||||
table = Expect.mkTable "test",
|
||||
insertColumns = [P.nameColumn],
|
||||
values = [[P.textNew], [P.textOther]],
|
||||
columns = [P.idColumn, P.nameColumn],
|
||||
mutationOutput = MOutMultirowFields [("affected_rows", MCount)],
|
||||
expectedSQL =
|
||||
[QQ.sql|
|
||||
INSERT INTO "public"."test"
|
||||
("name")
|
||||
VALUES
|
||||
(('new name')::text),
|
||||
(('other')::text)
|
||||
RETURNING *, ('true')::boolean AS "check__constraint"
|
||||
|]
|
||||
}
|
59
server/src-test/Test/Backend/Postgres/Insert.hs
Normal file
59
server/src-test/Test/Backend/Postgres/Insert.hs
Normal file
@ -0,0 +1,59 @@
|
||||
-- | Test Backend Postgres Insert
|
||||
--
|
||||
-- Helpers to build 'Hasura.RQL.IR.Insert.InsertQueryP1' and test the results
|
||||
-- of running 'Hasura.Backends.Postgres.Translate.Insert.mkInsertCTE' as raw
|
||||
-- SQL.
|
||||
--
|
||||
-- See 'Hasura.Backends.Postgres.Translate.InserSpec.spec' for usage examples.
|
||||
module Test.Backend.Postgres.Insert
|
||||
( TestBuilder (..),
|
||||
runTest,
|
||||
)
|
||||
where
|
||||
|
||||
import Hasura.Backends.Postgres.SQL.Types (QualifiedTable)
|
||||
import Hasura.Backends.Postgres.Translate.Insert qualified as Insert
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.Returning (MutationOutputG (..))
|
||||
import Hasura.RQL.IR.Value (UnpreparedValue (..))
|
||||
import Hasura.RQL.Types.Column (ColumnInfo)
|
||||
import Hasura.SQL.Backend (PostgresKind (Vanilla))
|
||||
import Hasura.SQL.Types (toSQLTxt)
|
||||
import Test.Backend.Postgres.Misc (PG)
|
||||
import Test.Hspec
|
||||
import Test.Parser.Insert qualified as Expect
|
||||
import Test.SIString qualified as SI
|
||||
|
||||
-- | Describes a /mkInsertCTE/ test.
|
||||
data TestBuilder = TestBuilder
|
||||
{ -- | test name
|
||||
name :: String,
|
||||
-- | table details
|
||||
table :: QualifiedTable,
|
||||
-- | columns used in the insert statement
|
||||
insertColumns :: [ColumnInfo PG],
|
||||
-- | rows of values to be inserted
|
||||
values :: [[UnpreparedValue PG]],
|
||||
-- | table columns
|
||||
columns :: [ColumnInfo PG],
|
||||
-- | expected output fields
|
||||
mutationOutput :: MutationOutputG PG Void (UnpreparedValue PG),
|
||||
-- | expected SQL
|
||||
expectedSQL :: Text
|
||||
}
|
||||
|
||||
-- | Runs a test for insert queries.
|
||||
runTest :: TestBuilder -> Spec
|
||||
runTest TestBuilder {..} =
|
||||
it name do
|
||||
let ins =
|
||||
Expect.mkInsertQuery
|
||||
Expect.InsertQueryBuilder
|
||||
{ iqbTable = table,
|
||||
iqbInsertColumns = insertColumns,
|
||||
iqbValues = values,
|
||||
iqbOutput = mutationOutput,
|
||||
iqbAllColumns = columns
|
||||
}
|
||||
(SI.fromText . toSQLTxt . Insert.mkInsertCTE @'Vanilla $ ins)
|
||||
`shouldBe` SI.fromText expectedSQL
|
61
server/src-test/Test/Parser/Insert.hs
Normal file
61
server/src-test/Test/Parser/Insert.hs
Normal file
@ -0,0 +1,61 @@
|
||||
module Test.Parser.Insert
|
||||
( InsertQueryBuilder (..),
|
||||
mkInsertQuery,
|
||||
)
|
||||
where
|
||||
|
||||
import Hasura.Backends.Postgres.SQL.DML qualified as S
|
||||
import Hasura.Backends.Postgres.SQL.Types (PGScalarType, QualifiedTable)
|
||||
import Hasura.Backends.Postgres.SQL.Value (txtEncoder, withScalarTypeAnn)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp (GBoolExp (..))
|
||||
import Hasura.RQL.IR.Insert (InsertQueryP1 (..))
|
||||
import Hasura.RQL.IR.Returning (MutationOutputG (..))
|
||||
import Hasura.RQL.IR.Value (UnpreparedValue (..))
|
||||
import Hasura.RQL.Types.Column (ColumnInfo (..), ColumnType (..), ColumnValue (..))
|
||||
import Hasura.RQL.Types.Instances ()
|
||||
import Hasura.SQL.Backend (BackendType (Postgres), PostgresKind (Vanilla))
|
||||
|
||||
type PG = 'Postgres 'Vanilla
|
||||
|
||||
type Output = MutationOutputG PG Void (UnpreparedValue PG)
|
||||
|
||||
-- | Internal use only. The intended use is through
|
||||
-- 'Test.Backend.Postgres.Insert.runTest'.
|
||||
--
|
||||
-- Build an 'InsertQueryP1', to be used with 'mkInsertQuery'.
|
||||
data InsertQueryBuilder = InsertQueryBuilder
|
||||
{ -- | the main table for the update
|
||||
iqbTable :: QualifiedTable,
|
||||
-- | the columns used in the insert statement
|
||||
iqbInsertColumns :: [ColumnInfo PG],
|
||||
-- | the rows of values to be inserted
|
||||
iqbValues :: [[UnpreparedValue PG]],
|
||||
-- | the 'Output' clause, e.g., selection set, affected_rows, etc.
|
||||
iqbOutput :: Output,
|
||||
-- | the table columns (all of them)
|
||||
iqbAllColumns :: [ColumnInfo PG]
|
||||
}
|
||||
|
||||
mkInsertQuery :: InsertQueryBuilder -> InsertQueryP1 PG
|
||||
mkInsertQuery InsertQueryBuilder {..} =
|
||||
InsertQueryP1
|
||||
{ iqp1Table = iqbTable,
|
||||
iqp1Cols = ciColumn <$> iqbInsertColumns,
|
||||
iqp1Tuples = fmap unpreparedValueToSQLExp <$> iqbValues,
|
||||
iqp1Conflict = Nothing,
|
||||
iqp1CheckCond = (BoolAnd [], Nothing),
|
||||
iqp1Output = unpreparedValueToSQLExp <$> iqbOutput,
|
||||
iqp1AllCols = iqbAllColumns
|
||||
}
|
||||
|
||||
unpreparedValueToSQLExp :: UnpreparedValue PG -> S.SQLExp
|
||||
unpreparedValueToSQLExp = \case
|
||||
UVLiteral sqlExp -> sqlExp
|
||||
UVParameter _varInfo cval -> withScalarTypeAnn (go $ cvType cval) (txtEncoder $ cvValue cval)
|
||||
_ -> error "unexpected value"
|
||||
where
|
||||
go :: ColumnType PG -> PGScalarType
|
||||
go = \case
|
||||
ColumnScalar t -> t
|
||||
ColumnEnumReference _ -> error "unexpected enum in translating column type"
|
Loading…
Reference in New Issue
Block a user