2022-02-08 12:24:34 +03:00
|
|
|
-- | Postgres Translate Mutation
|
|
|
|
--
|
|
|
|
-- Provide a combinator for generating a Postgres SQL SELECT statement for the
|
|
|
|
-- selected columns in mutation queries.
|
|
|
|
--
|
|
|
|
-- See 'Hasura.Backends.Postgres.Execute.Mutation' and note
|
|
|
|
-- [Prepared statements in Mutations]
|
2020-10-29 19:58:13 +03:00
|
|
|
module Hasura.Backends.Postgres.Translate.Mutation
|
2020-11-12 12:25:48 +03:00
|
|
|
( mkSelectExpFromColumnValues,
|
2021-05-21 05:46:58 +03:00
|
|
|
)
|
|
|
|
where
|
2021-09-24 01:56:37 +03:00
|
|
|
|
2023-04-26 18:42:13 +03:00
|
|
|
import Data.HashMap.Strict qualified as HashMap
|
2020-10-29 19:58:13 +03:00
|
|
|
import Data.Text.Extended
|
2021-03-25 20:50:08 +03:00
|
|
|
import Hasura.Backends.Postgres.SQL.DML qualified as S
|
2020-10-29 19:58:13 +03:00
|
|
|
import Hasura.Backends.Postgres.SQL.Types
|
|
|
|
import Hasura.Backends.Postgres.SQL.Value
|
2021-03-25 20:50:08 +03:00
|
|
|
import Hasura.Backends.Postgres.Types.Column
|
2021-05-11 18:18:31 +03:00
|
|
|
import Hasura.Base.Error
|
2020-10-29 19:58:13 +03:00
|
|
|
import Hasura.Prelude
|
2023-04-24 21:35:48 +03:00
|
|
|
import Hasura.RQL.Types.BackendType
|
2022-04-27 16:57:28 +03:00
|
|
|
import Hasura.RQL.Types.Column
|
2020-10-29 19:58:13 +03:00
|
|
|
import Hasura.SQL.Types
|
2023-05-17 11:53:31 +03:00
|
|
|
import Hasura.Table.Cache
|
2020-10-29 19:58:13 +03:00
|
|
|
|
|
|
|
-- | Note:- Using sorted columns is necessary to enable casting the rows returned by VALUES expression to table type.
|
|
|
|
-- For example, let's consider the table, `CREATE TABLE test (id serial primary key, name text not null, age int)`.
|
|
|
|
-- The generated values expression should be in order of columns;
|
|
|
|
-- `SELECT ("row"::table).* VALUES (1, 'Robert', 23) AS "row"`.
|
2020-11-12 12:25:48 +03:00
|
|
|
mkSelectExpFromColumnValues ::
|
2021-04-22 00:44:37 +03:00
|
|
|
forall pgKind m.
|
2023-05-17 11:53:31 +03:00
|
|
|
(MonadError QErr m) =>
|
2021-04-22 00:44:37 +03:00
|
|
|
QualifiedTable ->
|
|
|
|
[ColumnInfo ('Postgres pgKind)] ->
|
|
|
|
[ColumnValues ('Postgres pgKind) TxtEncodedVal] ->
|
|
|
|
m S.Select
|
2020-11-12 12:25:48 +03:00
|
|
|
mkSelectExpFromColumnValues qt allCols = \case
|
|
|
|
[] -> return selNoRows
|
|
|
|
colVals -> do
|
|
|
|
tuples <- mapM mkTupsFromColVal colVals
|
2022-10-11 13:42:15 +03:00
|
|
|
let fromItem = S.FIValues (S.ValuesExp tuples) rowAlias Nothing
|
2020-11-12 12:25:48 +03:00
|
|
|
return
|
|
|
|
S.mkSelect
|
|
|
|
{ S.selExtr = [extractor],
|
|
|
|
S.selFrom = Just $ S.FromExp [fromItem]
|
|
|
|
}
|
2020-10-29 19:58:13 +03:00
|
|
|
where
|
2022-10-11 13:42:15 +03:00
|
|
|
rowAlias = S.mkTableAlias "row"
|
|
|
|
rowIdentifier = S.tableAliasToIdentifier rowAlias
|
|
|
|
extractor = S.selectStar' $ S.QualifiedIdentifier rowIdentifier $ Just $ S.TypeAnn $ toSQLTxt qt
|
2020-10-29 19:58:13 +03:00
|
|
|
sortedCols = sortCols allCols
|
|
|
|
mkTupsFromColVal colVal =
|
2023-05-24 16:51:56 +03:00
|
|
|
fmap S.TupleExp
|
|
|
|
$ forM sortedCols
|
|
|
|
$ \ci -> do
|
2022-01-19 11:37:50 +03:00
|
|
|
let pgCol = ciColumn ci
|
2020-10-29 19:58:13 +03:00
|
|
|
val <-
|
2023-05-24 16:51:56 +03:00
|
|
|
onNothing (HashMap.lookup pgCol colVal)
|
|
|
|
$ throw500
|
|
|
|
$ "column "
|
|
|
|
<> pgCol
|
|
|
|
<<> " not found in returning values"
|
2022-01-19 11:37:50 +03:00
|
|
|
pure $ txtEncodedToSQLExp (ciType ci) val
|
2020-10-29 19:58:13 +03:00
|
|
|
|
|
|
|
selNoRows =
|
|
|
|
S.mkSelect
|
|
|
|
{ S.selExtr = [S.selectStar],
|
|
|
|
S.selFrom = Just $ S.mkSimpleFromExp qt,
|
|
|
|
S.selWhere = Just $ S.WhereFrag $ S.BELit False
|
|
|
|
}
|
|
|
|
|
|
|
|
txtEncodedToSQLExp colTy = \case
|
|
|
|
TENull -> S.SENull
|
|
|
|
TELit textValue ->
|
2022-04-27 18:36:02 +03:00
|
|
|
withScalarTypeAnn (unsafePGColumnToBackend colTy) $ S.SELit textValue
|