mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-09-17 13:37:26 +03:00
server: transform enum with upper
for graphql-default
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5032 GitOrigin-RevId: 206a673f4bd59700436f6160feeb7df415f637ad
This commit is contained in:
parent
9e9dff763b
commit
d66abcefab
@ -204,7 +204,7 @@ Please submit any feedback you may have for this feature at https://github.com/h
|
||||
- server: fix prefix/suffix behaviour for `graphql-default` naming convention (fixes #8544)
|
||||
- server: fix namespace visibility during introspection (fix #8434)
|
||||
- server: Create missing SQL triggers, if any, while reloading metadata and startup.
|
||||
- server: fix name transformation bug in `graphql-default` naming convention (fixes #8640 partially)
|
||||
- server: fix name/enum transformation bugs in `graphql-default` naming convention (fixes #8640)
|
||||
- server: changes to the Rest Endpoints OpenAPI specification:
|
||||
- the nullability of items in the output is now always correctly reported
|
||||
- scalars other than UUID are more consistently inlined
|
||||
|
@ -224,7 +224,8 @@ fromSelectRows parentSelectFromEntity annSelectG = do
|
||||
{ _asnFields = fields,
|
||||
_asnFrom = from,
|
||||
_asnPerm = perm,
|
||||
_asnArgs = args
|
||||
_asnArgs = args,
|
||||
_asnNamingConvention = _tCase
|
||||
} = annSelectG
|
||||
Ir.TablePerm {_tpLimit = mPermLimit, _tpFilter = permFilter} = perm
|
||||
permissionBasedTop =
|
||||
@ -518,7 +519,8 @@ fromSelectAggregate minnerJoinFields annSelectG = do
|
||||
{ _asnFields = fields,
|
||||
_asnFrom = from,
|
||||
_asnPerm = perm,
|
||||
_asnArgs = args
|
||||
_asnArgs = args,
|
||||
_asnNamingConvention = _tCase
|
||||
} = annSelectG
|
||||
Ir.TablePerm {_tpLimit = mPermLimit, _tpFilter = permFilter} = perm
|
||||
permissionBasedTop =
|
||||
|
@ -439,7 +439,8 @@ bqComputedField sourceName ComputedFieldInfo {..} tableName tableInfo = runMaybe
|
||||
IR._asnFrom = IR.FromFunction (_cffName _cfiFunction) functionArgs' Nothing,
|
||||
IR._asnPerm = tablePermissionsInfo returnTablePermissions,
|
||||
IR._asnArgs = args,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Nothing
|
||||
}
|
||||
BigQuery.ReturnTableSchema returnFields -> do
|
||||
-- Check if the computed field is available in the select permission
|
||||
@ -465,7 +466,8 @@ bqComputedField sourceName ComputedFieldInfo {..} tableName tableInfo = runMaybe
|
||||
IR._asnFrom = IR.FromFunction (_cffName _cfiFunction) functionArgs' Nothing,
|
||||
IR._asnPerm = IR.noTablePermissions,
|
||||
IR._asnArgs = IR.noSelectArgs,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Nothing
|
||||
}
|
||||
where
|
||||
fieldDescription :: Maybe G.Description
|
||||
|
@ -12,7 +12,7 @@ import Hasura.RQL.Types.Column qualified as IR
|
||||
import Hasura.SQL.Backend
|
||||
|
||||
fromDelete :: IR.AnnDel 'MSSQL -> FromIr Delete
|
||||
fromDelete (IR.AnnDel table (permFilter, whereClause) _ allColumns) = do
|
||||
fromDelete (IR.AnnDel table (permFilter, whereClause) _ allColumns _) = do
|
||||
tableAlias <- generateAlias (TableTemplate (tableName table))
|
||||
runReaderT
|
||||
( do
|
||||
|
@ -50,7 +50,7 @@ mkMutationOutputSelect stringifyNum withAlias = \case
|
||||
IR.Fields (IR.AnnFieldG 'MSSQL Void Expression) ->
|
||||
FromIr Select
|
||||
mkSelect jsonAggSelect annFields = do
|
||||
let annSelect = IR.AnnSelectG annFields (IR.FromIdentifier $ IR.FIIdentifier withAlias) IR.noTablePermissions IR.noSelectArgs stringifyNum
|
||||
let annSelect = IR.AnnSelectG annFields (IR.FromIdentifier $ IR.FIIdentifier withAlias) IR.noTablePermissions IR.noSelectArgs stringifyNum Nothing
|
||||
fromSelect jsonAggSelect annSelect
|
||||
|
||||
-- SELECT COUNT(*) AS "count" FROM [with_alias]
|
||||
|
@ -234,7 +234,8 @@ fromSelectRows annSelectG = do
|
||||
{ _asnFields = fields,
|
||||
_asnFrom = from,
|
||||
_asnPerm = perm,
|
||||
_asnArgs = args
|
||||
_asnArgs = args,
|
||||
_asnNamingConvention = _tCase
|
||||
} = annSelectG
|
||||
IR.TablePerm {_tpLimit = mPermLimit, _tpFilter = permFilter} = perm
|
||||
permissionBasedTop =
|
||||
@ -329,7 +330,8 @@ fromSelectAggregate
|
||||
{ _asnFields = (zip [0 ..] -> fields),
|
||||
_asnFrom = from,
|
||||
_asnPerm = IR.TablePerm {_tpLimit = (maybe NoTop Top -> permissionBasedTop), _tpFilter = permFilter},
|
||||
_asnArgs = args
|
||||
_asnArgs = args,
|
||||
_asnNamingConvention = _tCase
|
||||
} =
|
||||
do
|
||||
selectFrom <- case from of
|
||||
|
@ -20,7 +20,7 @@ import Hasura.RQL.Types.Column qualified as IR
|
||||
import Hasura.SQL.Backend
|
||||
|
||||
fromUpdate :: IR.AnnotatedUpdate 'MSSQL -> FromIr Update
|
||||
fromUpdate (IR.AnnotatedUpdateG table (permFilter, whereClause) _ backendUpdate _ allColumns) = do
|
||||
fromUpdate (IR.AnnotatedUpdateG table (permFilter, whereClause) _ backendUpdate _ allColumns _tCase) = do
|
||||
tableAlias <- generateAlias (TableTemplate (tableName table))
|
||||
runReaderT
|
||||
( do
|
||||
|
@ -545,7 +545,8 @@ fromSelectAggregate mparentRelationship annSelectG = do
|
||||
_asnFrom = from,
|
||||
_asnPerm = perm,
|
||||
_asnArgs = args,
|
||||
_asnStrfyNum = _num
|
||||
_asnStrfyNum = _num,
|
||||
_asnNamingConvention = _tCase
|
||||
} = annSelectG
|
||||
IR.TablePerm {_tpLimit = mPermLimit, _tpFilter = permFilter} = perm
|
||||
|
||||
@ -731,7 +732,8 @@ fromSelectRows annSelectG = do
|
||||
{ _asnFields = fields,
|
||||
_asnFrom = from,
|
||||
_asnPerm = perm,
|
||||
_asnArgs = args
|
||||
_asnArgs = args,
|
||||
_asnNamingConvention = _tCase
|
||||
} = annSelectG
|
||||
IR.TablePerm {_tpLimit = mPermLimit, _tpFilter = permFilter} = perm
|
||||
|
||||
|
@ -688,7 +688,7 @@ mkTriggerFunctionQ triggerName (QualifiedObject schema table) allCols op (Subscr
|
||||
mkRowExp $ map (\col -> toExtractor (mkQId opVar strfyNum col) col) columns
|
||||
|
||||
mkQId opVar strfyNum colInfo =
|
||||
toJSONableExp strfyNum (ciType colInfo) False $
|
||||
toJSONableExp strfyNum (ciType colInfo) False Nothing $
|
||||
SEQIdentifier $ QIdentifier (opToQual opVar) $ toIdentifier $ ciColumn colInfo
|
||||
|
||||
-- Generate the SQL expression
|
||||
|
@ -29,6 +29,7 @@ import Hasura.Backends.Postgres.Translate.Select (PostgresAnnotatedFieldJSON)
|
||||
import Hasura.Backends.Postgres.Types.Insert
|
||||
import Hasura.Base.Error
|
||||
import Hasura.EncJSON
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.Prelude
|
||||
import Hasura.QueryTags
|
||||
@ -56,13 +57,14 @@ convertToSQLTransaction ::
|
||||
UserInfo ->
|
||||
Seq.Seq Q.PrepArg ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
m EncJSON
|
||||
convertToSQLTransaction (IR.AnnotatedInsert fieldName isSingle annIns mutationOutput) userInfo planVars stringifyNum =
|
||||
convertToSQLTransaction (IR.AnnotatedInsert fieldName isSingle annIns mutationOutput _tCase) userInfo planVars stringifyNum tCase =
|
||||
if null $ IR._aiInsertObject annIns
|
||||
then pure $ IR.buildEmptyMutResp mutationOutput
|
||||
else
|
||||
withPaths ["selectionSet", fieldName, "args", suffix] $
|
||||
insertMultipleObjects annIns mempty userInfo mutationOutput planVars stringifyNum
|
||||
insertMultipleObjects annIns mempty userInfo mutationOutput planVars stringifyNum tCase
|
||||
where
|
||||
withPaths p x = foldr ($) x $ withPathK <$> p
|
||||
suffix = bool "objects" "object" isSingle
|
||||
@ -82,8 +84,9 @@ insertMultipleObjects ::
|
||||
IR.MutationOutput ('Postgres pgKind) ->
|
||||
Seq.Seq Q.PrepArg ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
m EncJSON
|
||||
insertMultipleObjects multiObjIns additionalColumns userInfo mutationOutput planVars stringifyNum =
|
||||
insertMultipleObjects multiObjIns additionalColumns userInfo mutationOutput planVars stringifyNum tCase =
|
||||
bool withoutRelsInsert withRelsInsert anyRelsToInsert
|
||||
where
|
||||
IR.AnnotatedInsertData insObjs table checkCondition columnInfos presetRow (BackendInsert conflictClause) = multiObjIns
|
||||
@ -108,12 +111,12 @@ insertMultipleObjects multiObjIns additionalColumns userInfo mutationOutput plan
|
||||
rowCount = tshow . length $ IR._aiInsertObject multiObjIns
|
||||
Tracing.trace ("Insert (" <> rowCount <> ") " <> qualifiedObjectToText table) do
|
||||
Tracing.attachMetadata [("count", rowCount)]
|
||||
PGE.execInsertQuery stringifyNum userInfo (insertQuery, planVars)
|
||||
PGE.execInsertQuery stringifyNum tCase userInfo (insertQuery, planVars)
|
||||
|
||||
withRelsInsert = do
|
||||
insertRequests <- indexedForM insObjs \obj -> do
|
||||
let singleObj = IR.AnnotatedInsertData (IR.Single obj) table checkCondition columnInfos presetRow (BackendInsert conflictClause)
|
||||
insertObject singleObj additionalColumns userInfo planVars stringifyNum
|
||||
insertObject singleObj additionalColumns userInfo planVars stringifyNum tCase
|
||||
let affectedRows = sum $ map fst insertRequests
|
||||
columnValues = mapMaybe snd insertRequests
|
||||
selectExpr <- PGT.mkSelectExpFromColumnValues table columnInfos columnValues
|
||||
@ -124,6 +127,7 @@ insertMultipleObjects multiObjIns additionalColumns userInfo mutationOutput plan
|
||||
(PGT.MCSelectValues selectExpr)
|
||||
mutationOutput
|
||||
stringifyNum
|
||||
tCase
|
||||
[]
|
||||
|
||||
insertObject ::
|
||||
@ -140,12 +144,13 @@ insertObject ::
|
||||
UserInfo ->
|
||||
Seq.Seq Q.PrepArg ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
m (Int, Maybe (ColumnValues ('Postgres pgKind) TxtEncodedVal))
|
||||
insertObject singleObjIns additionalColumns userInfo planVars stringifyNum = Tracing.trace ("Insert " <> qualifiedObjectToText table) do
|
||||
insertObject singleObjIns additionalColumns userInfo planVars stringifyNum tCase = Tracing.trace ("Insert " <> qualifiedObjectToText table) do
|
||||
validateInsert (Map.keys columns) (map IR._riRelationInfo objectRels) (Map.keys additionalColumns)
|
||||
|
||||
-- insert all object relations and fetch this insert dependent column values
|
||||
objInsRes <- forM beforeInsert $ insertObjRel planVars userInfo stringifyNum
|
||||
objInsRes <- forM beforeInsert $ insertObjRel planVars userInfo stringifyNum tCase
|
||||
|
||||
-- prepare final insert columns
|
||||
let objRelAffRows = sum $ map fst objInsRes
|
||||
@ -156,7 +161,7 @@ insertObject singleObjIns additionalColumns userInfo planVars stringifyNum = Tra
|
||||
|
||||
PGE.MutateResp affRows colVals <-
|
||||
liftTx $
|
||||
PGE.mutateAndFetchCols @pgKind table allColumns (PGT.MCCheckConstraint cte, planVars) stringifyNum
|
||||
PGE.mutateAndFetchCols @pgKind table allColumns (PGT.MCCheckConstraint cte, planVars) stringifyNum tCase
|
||||
colValM <- asSingleObject colVals
|
||||
|
||||
arrRelAffRows <- bool (withArrRels colValM) (return 0) $ null allAfterInsertRels
|
||||
@ -195,7 +200,7 @@ insertObject singleObjIns additionalColumns userInfo planVars stringifyNum = Tra
|
||||
afterInsertDepColsWithVal <- fetchFromColVals colVal afterInsertDepCols
|
||||
arrInsARows <-
|
||||
forM allAfterInsertRels $
|
||||
insertArrRel afterInsertDepColsWithVal userInfo planVars stringifyNum
|
||||
insertArrRel afterInsertDepColsWithVal userInfo planVars stringifyNum tCase
|
||||
return $ sum arrInsARows
|
||||
|
||||
asSingleObject ::
|
||||
@ -223,11 +228,12 @@ insertObjRel ::
|
||||
Seq.Seq Q.PrepArg ->
|
||||
UserInfo ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
IR.ObjectRelationInsert ('Postgres pgKind) PG.SQLExp ->
|
||||
m (Int, [(PGCol, PG.SQLExp)])
|
||||
insertObjRel planVars userInfo stringifyNum objRelIns =
|
||||
insertObjRel planVars userInfo stringifyNum tCase objRelIns =
|
||||
withPathK (relNameToTxt relName) $ do
|
||||
(affRows, colValM) <- withPathK "data" $ insertObject singleObjIns mempty userInfo planVars stringifyNum
|
||||
(affRows, colValM) <- withPathK "data" $ insertObject singleObjIns mempty userInfo planVars stringifyNum tCase
|
||||
colVal <- onNothing colValM $ throw400 NotSupported errMsg
|
||||
retColsWithVals <- fetchFromColVals colVal rColInfos
|
||||
let columns = flip mapMaybe (Map.toList mapCols) \(column, target) -> do
|
||||
@ -259,9 +265,10 @@ insertArrRel ::
|
||||
UserInfo ->
|
||||
Seq.Seq Q.PrepArg ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
IR.ArrayRelationInsert ('Postgres pgKind) PG.SQLExp ->
|
||||
m Int
|
||||
insertArrRel resCols userInfo planVars stringifyNum arrRelIns =
|
||||
insertArrRel resCols userInfo planVars stringifyNum tCase arrRelIns =
|
||||
withPathK (relNameToTxt $ riName relInfo) $ do
|
||||
let additionalColumns = Map.fromList $
|
||||
flip mapMaybe resCols \(column, value) -> do
|
||||
@ -269,7 +276,7 @@ insertArrRel resCols userInfo planVars stringifyNum arrRelIns =
|
||||
Just (target, value)
|
||||
resBS <-
|
||||
withPathK "data" $
|
||||
insertMultipleObjects multiObjIns additionalColumns userInfo mutOutput planVars stringifyNum
|
||||
insertMultipleObjects multiObjIns additionalColumns userInfo mutOutput planVars stringifyNum tCase
|
||||
resObj <- decodeEncJSON resBS
|
||||
onNothing (Map.lookup ("affected_rows" :: Text) resObj) $
|
||||
throw500 "affected_rows not returned in array rel insert"
|
||||
|
@ -31,6 +31,7 @@ import Hasura.Backends.Postgres.Translate.Select
|
||||
import Hasura.Backends.Postgres.Translate.Update
|
||||
import Hasura.Base.Error
|
||||
import Hasura.EncJSON
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.Prelude
|
||||
import Hasura.QueryTags
|
||||
@ -68,7 +69,8 @@ data Mutation (b :: BackendType) = Mutation
|
||||
_mQuery :: !(MutationCTE, DS.Seq Q.PrepArg),
|
||||
_mOutput :: !(MutationOutput b),
|
||||
_mCols :: ![ColumnInfo b],
|
||||
_mStrfyNum :: !Options.StringifyNumbers
|
||||
_mStrfyNum :: !Options.StringifyNumbers,
|
||||
_mNamingConvention :: !(Maybe NamingCase)
|
||||
}
|
||||
|
||||
mkMutation ::
|
||||
@ -78,9 +80,10 @@ mkMutation ::
|
||||
MutationOutput ('Postgres pgKind) ->
|
||||
[ColumnInfo ('Postgres pgKind)] ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
Mutation ('Postgres pgKind)
|
||||
mkMutation _userInfo table query output allCols strfyNum =
|
||||
Mutation table query output allCols strfyNum
|
||||
mkMutation _userInfo table query output allCols strfyNum tCase =
|
||||
Mutation table query output allCols strfyNum tCase
|
||||
|
||||
runMutation ::
|
||||
( MonadTx m,
|
||||
@ -102,8 +105,8 @@ mutateAndReturn ::
|
||||
) =>
|
||||
Mutation ('Postgres pgKind) ->
|
||||
m EncJSON
|
||||
mutateAndReturn (Mutation qt (cte, p) mutationOutput allCols strfyNum) =
|
||||
executeMutationOutputQuery qt allCols Nothing cte mutationOutput strfyNum (toList p)
|
||||
mutateAndReturn (Mutation qt (cte, p) mutationOutput allCols strfyNum tCase) =
|
||||
executeMutationOutputQuery qt allCols Nothing cte mutationOutput strfyNum tCase (toList p)
|
||||
|
||||
execUpdateQuery ::
|
||||
forall pgKind m.
|
||||
@ -113,10 +116,11 @@ execUpdateQuery ::
|
||||
MonadReader QueryTagsComment m
|
||||
) =>
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
UserInfo ->
|
||||
(AnnotatedUpdate ('Postgres pgKind), DS.Seq Q.PrepArg) ->
|
||||
m EncJSON
|
||||
execUpdateQuery strfyNum userInfo (u, p) =
|
||||
execUpdateQuery strfyNum tCase userInfo (u, p) =
|
||||
case updateCTE of
|
||||
Update singleUpdate -> runCTE singleUpdate
|
||||
MultiUpdate ctes -> encJFromList <$> traverse runCTE ctes
|
||||
@ -127,7 +131,7 @@ execUpdateQuery strfyNum userInfo (u, p) =
|
||||
runCTE :: S.TopLevelCTE -> m EncJSON
|
||||
runCTE cte =
|
||||
runMutation
|
||||
(mkMutation userInfo (_auTable u) (MCCheckConstraint cte, p) (_auOutput u) (_auAllCols u) strfyNum)
|
||||
(mkMutation userInfo (_auTable u) (MCCheckConstraint cte, p) (_auOutput u) (_auAllCols u) strfyNum tCase)
|
||||
|
||||
execDeleteQuery ::
|
||||
forall pgKind m.
|
||||
@ -137,12 +141,13 @@ execDeleteQuery ::
|
||||
MonadReader QueryTagsComment m
|
||||
) =>
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
UserInfo ->
|
||||
(AnnDel ('Postgres pgKind), DS.Seq Q.PrepArg) ->
|
||||
m EncJSON
|
||||
execDeleteQuery strfyNum userInfo (u, p) =
|
||||
execDeleteQuery strfyNum tCase userInfo (u, p) =
|
||||
runMutation
|
||||
(mkMutation userInfo (_adTable u) (MCDelete delete, p) (_adOutput u) (_adAllCols u) strfyNum)
|
||||
(mkMutation userInfo (_adTable u) (MCDelete delete, p) (_adOutput u) (_adAllCols u) strfyNum tCase)
|
||||
where
|
||||
delete = mkDelete u
|
||||
|
||||
@ -153,12 +158,13 @@ execInsertQuery ::
|
||||
MonadReader QueryTagsComment m
|
||||
) =>
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
UserInfo ->
|
||||
(InsertQueryP1 ('Postgres pgKind), DS.Seq Q.PrepArg) ->
|
||||
m EncJSON
|
||||
execInsertQuery strfyNum userInfo (u, p) =
|
||||
execInsertQuery strfyNum tCase userInfo (u, p) =
|
||||
runMutation
|
||||
(mkMutation userInfo (iqp1Table u) (MCCheckConstraint insertCTE, p) (iqp1Output u) (iqp1AllCols u) strfyNum)
|
||||
(mkMutation userInfo (iqp1Table u) (MCCheckConstraint insertCTE, p) (iqp1Output u) (iqp1AllCols u) strfyNum tCase)
|
||||
where
|
||||
insertCTE = mkInsertCTE u
|
||||
|
||||
@ -185,9 +191,9 @@ mutateAndSel ::
|
||||
) =>
|
||||
Mutation ('Postgres pgKind) ->
|
||||
m EncJSON
|
||||
mutateAndSel (Mutation qt q mutationOutput allCols strfyNum) = do
|
||||
mutateAndSel (Mutation qt q mutationOutput allCols strfyNum tCase) = do
|
||||
-- Perform mutation and fetch unique columns
|
||||
MutateResp _ columnVals <- liftTx $ mutateAndFetchCols qt allCols q strfyNum
|
||||
MutateResp _ columnVals <- liftTx $ mutateAndFetchCols qt allCols q strfyNum tCase
|
||||
select <- mkSelectExpFromColumnValues qt allCols columnVals
|
||||
-- Perform select query and fetch returning fields
|
||||
executeMutationOutputQuery
|
||||
@ -197,6 +203,7 @@ mutateAndSel (Mutation qt q mutationOutput allCols strfyNum) = do
|
||||
(MCSelectValues select)
|
||||
mutationOutput
|
||||
strfyNum
|
||||
tCase
|
||||
[]
|
||||
|
||||
withCheckPermission :: (MonadError QErr m) => m (a, Bool) -> m a
|
||||
@ -220,14 +227,15 @@ executeMutationOutputQuery ::
|
||||
MutationCTE ->
|
||||
MutationOutput ('Postgres pgKind) ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
-- | Prepared params
|
||||
[Q.PrepArg] ->
|
||||
m EncJSON
|
||||
executeMutationOutputQuery qt allCols preCalAffRows cte mutOutput strfyNum prepArgs = do
|
||||
executeMutationOutputQuery qt allCols preCalAffRows cte mutOutput strfyNum tCase prepArgs = do
|
||||
queryTags <- ask
|
||||
let queryTx :: Q.FromRes a => m a
|
||||
queryTx = do
|
||||
let selectWith = mkMutationOutputExp qt allCols preCalAffRows cte mutOutput strfyNum
|
||||
let selectWith = mkMutationOutputExp qt allCols preCalAffRows cte mutOutput strfyNum tCase
|
||||
query = Q.fromBuilder $ toSQL selectWith
|
||||
queryWithQueryTags = query {Q.getQueryText = (Q.getQueryText query) <> (_unQueryTagsComment queryTags)}
|
||||
-- See Note [Prepared statements in Mutations]
|
||||
@ -244,8 +252,9 @@ mutateAndFetchCols ::
|
||||
[ColumnInfo ('Postgres pgKind)] ->
|
||||
(MutationCTE, DS.Seq Q.PrepArg) ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
Q.TxE QErr (MutateResp ('Postgres pgKind) TxtEncodedVal)
|
||||
mutateAndFetchCols qt cols (cte, p) strfyNum = do
|
||||
mutateAndFetchCols qt cols (cte, p) strfyNum tCase = do
|
||||
let mutationTx :: Q.FromRes a => Q.TxE QErr a
|
||||
mutationTx =
|
||||
-- See Note [Prepared statements in Mutations]
|
||||
@ -288,4 +297,4 @@ mutateAndFetchCols qt cols (cte, p) strfyNum = do
|
||||
colSel =
|
||||
S.SESelect $
|
||||
mkSQLSelect JASMultipleRows $
|
||||
AnnSelectG selFlds tabFrom tabPerm noSelectArgs strfyNum
|
||||
AnnSelectG selFlds tabFrom tabPerm noSelectArgs strfyNum tCase
|
||||
|
@ -202,7 +202,7 @@ convertDelete ::
|
||||
convertDelete userInfo deleteOperation stringifyNum = do
|
||||
queryTags <- ask
|
||||
preparedDelete <- traverse (prepareWithoutPlan userInfo) deleteOperation
|
||||
pure $ flip runReaderT queryTags $ PGE.execDeleteQuery stringifyNum userInfo (preparedDelete, Seq.empty)
|
||||
pure $ flip runReaderT queryTags $ PGE.execDeleteQuery stringifyNum (_adNamingConvention deleteOperation) userInfo (preparedDelete, Seq.empty)
|
||||
|
||||
convertUpdate ::
|
||||
forall pgKind m.
|
||||
@ -223,7 +223,7 @@ convertUpdate userInfo updateOperation stringifyNum = do
|
||||
else
|
||||
pure $
|
||||
flip runReaderT queryTags $
|
||||
PGE.execUpdateQuery stringifyNum userInfo (preparedUpdate, Seq.empty)
|
||||
PGE.execUpdateQuery stringifyNum (_auNamingConvention updateOperation) userInfo (preparedUpdate, Seq.empty)
|
||||
|
||||
convertInsert ::
|
||||
forall pgKind m.
|
||||
@ -239,7 +239,7 @@ convertInsert ::
|
||||
convertInsert userInfo insertOperation stringifyNum = do
|
||||
queryTags <- ask
|
||||
preparedInsert <- traverse (prepareWithoutPlan userInfo) insertOperation
|
||||
pure $ flip runReaderT queryTags $ convertToSQLTransaction preparedInsert userInfo Seq.empty stringifyNum
|
||||
pure $ flip runReaderT queryTags $ convertToSQLTransaction preparedInsert userInfo Seq.empty stringifyNum (_aiNamingConvention insertOperation)
|
||||
|
||||
-- | A pared-down version of 'Query.convertQuerySelSet', for use in execution of
|
||||
-- special case of SQL function mutations (see 'MDBFunction').
|
||||
|
@ -290,7 +290,7 @@ updateTableMany scenario sourceInfo tableInfo gqlName = runMaybeT do
|
||||
let argsParser = liftA2 (,) updates (pure annBoolExpTrue)
|
||||
pure $
|
||||
P.subselection updateName updateDesc argsParser selection
|
||||
<&> SU.mkUpdateObject tableName columns updatePerms . fmap MOutMultirowFields
|
||||
<&> SU.mkUpdateObject tableName columns updatePerms (Just tCase) . fmap MOutMultirowFields
|
||||
where
|
||||
tableName = tableInfoName tableInfo
|
||||
defaultUpdateDesc = "update multiples rows of table: " <>> tableName
|
||||
|
@ -51,6 +51,7 @@ module Hasura.Backends.Postgres.SQL.DML
|
||||
applyJsonBuildArray,
|
||||
applyJsonBuildObj,
|
||||
applyRowToJson,
|
||||
applyUppercase,
|
||||
boolTypeAnn,
|
||||
buildUpsertSetExp,
|
||||
columnDefaultValue,
|
||||
@ -618,6 +619,10 @@ applyRowToJson :: [Extractor] -> SQLExp
|
||||
applyRowToJson extrs =
|
||||
SEFnApp "row_to_json" [mkRowExp extrs] Nothing
|
||||
|
||||
applyUppercase :: SQLExp -> SQLExp
|
||||
applyUppercase arg =
|
||||
SEFnApp "upper" [arg] Nothing
|
||||
|
||||
mkExtr :: (IsIdentifier a) => a -> Extractor
|
||||
mkExtr t = Extractor (mkSIdenExp t) Nothing
|
||||
|
||||
|
@ -12,6 +12,7 @@ module Hasura.Backends.Postgres.Schema.Select
|
||||
where
|
||||
|
||||
import Control.Lens hiding (index)
|
||||
import Data.Has (getter)
|
||||
import Data.HashMap.Strict.Extended qualified as Map
|
||||
import Data.Sequence qualified as Seq
|
||||
import Data.Text.Extended
|
||||
@ -61,6 +62,7 @@ selectFunction ::
|
||||
Maybe G.Description ->
|
||||
m (Maybe (FieldParser n (SelectExp ('Postgres pgKind))))
|
||||
selectFunction sourceInfo fi@FunctionInfo {..} description = runMaybeT do
|
||||
tCase <- asks getter
|
||||
tableInfo <- lift $ askTableInfo sourceInfo _fiReturnType
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions tableInfo
|
||||
selectionSetParser <- MaybeT $ returnFunctionParser sourceInfo tableInfo
|
||||
@ -78,7 +80,8 @@ selectFunction sourceInfo fi@FunctionInfo {..} description = runMaybeT do
|
||||
IR._asnFrom = IR.FromFunction _fiSQLName funcArgs Nothing,
|
||||
IR._asnPerm = tablePermissionsInfo selectPermissions,
|
||||
IR._asnArgs = tableArgs',
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
where
|
||||
returnFunctionParser =
|
||||
@ -98,6 +101,7 @@ selectFunctionAggregate ::
|
||||
Maybe G.Description ->
|
||||
m (Maybe (FieldParser n (AggSelectExp ('Postgres pgKind))))
|
||||
selectFunctionAggregate sourceInfo fi@FunctionInfo {..} description = runMaybeT do
|
||||
tCase <- asks getter
|
||||
targetTableInfo <- askTableInfo sourceInfo _fiReturnType
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions targetTableInfo
|
||||
guard $ spiAllowAgg selectPermissions
|
||||
@ -130,7 +134,8 @@ selectFunctionAggregate sourceInfo fi@FunctionInfo {..} description = runMaybeT
|
||||
IR._asnFrom = IR.FromFunction _fiSQLName funcArgs Nothing,
|
||||
IR._asnPerm = tablePermissionsInfo selectPermissions,
|
||||
IR._asnArgs = tableArgs',
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
|
||||
selectFunctionConnection ::
|
||||
@ -148,6 +153,7 @@ selectFunctionConnection ::
|
||||
PrimaryKeyColumns ('Postgres pgKind) ->
|
||||
m (Maybe (FieldParser n (ConnectionSelectExp ('Postgres pgKind))))
|
||||
selectFunctionConnection sourceInfo fi@FunctionInfo {..} description pkeyColumns = runMaybeT do
|
||||
tCase <- asks getter
|
||||
returnTableInfo <- lift $ askTableInfo sourceInfo _fiReturnType
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions returnTableInfo
|
||||
xRelayInfo <- hoistMaybe $ relayExtension @('Postgres pgKind)
|
||||
@ -173,7 +179,8 @@ selectFunctionConnection sourceInfo fi@FunctionInfo {..} description pkeyColumns
|
||||
IR._asnFrom = IR.FromFunction _fiSQLName funcArgs Nothing,
|
||||
IR._asnPerm = tablePermissionsInfo selectPermissions,
|
||||
IR._asnArgs = args,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,6 +195,7 @@ computedFieldPG ::
|
||||
TableInfo ('Postgres pgKind) ->
|
||||
m (Maybe (FieldParser n (AnnotatedField ('Postgres pgKind))))
|
||||
computedFieldPG sourceInfo ComputedFieldInfo {..} parentTable tableInfo = runMaybeT do
|
||||
tCase <- asks getter
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions tableInfo
|
||||
stringifyNumbers <- retrieve Options.soStringifyNumbers
|
||||
fieldName <- lift $ textToName $ computedFieldNameToText _cfiName
|
||||
@ -233,7 +241,8 @@ computedFieldPG sourceInfo ComputedFieldInfo {..} parentTable tableInfo = runMay
|
||||
IR._asnFrom = IR.FromFunction (_cffName _cfiFunction) functionArgs' Nothing,
|
||||
IR._asnPerm = tablePermissionsInfo remotePerms,
|
||||
IR._asnArgs = args,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
where
|
||||
fieldDescription :: Maybe G.Description
|
||||
|
@ -11,6 +11,7 @@ import Hasura.Backends.Postgres.SQL.DML
|
||||
import Hasura.Backends.Postgres.SQL.Types
|
||||
import Hasura.Backends.Postgres.SQL.Value
|
||||
import Hasura.Backends.Postgres.Types.Column
|
||||
import Hasura.GraphQL.Schema.NamingCase
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Column
|
||||
@ -23,8 +24,8 @@ toTxtValue ColumnValue {..} =
|
||||
ty = unsafePGColumnToBackend cvType
|
||||
|
||||
-- | Formats each columns to appropriate SQL expression
|
||||
toJSONableExp :: Options.StringifyNumbers -> ColumnType ('Postgres pgKind) -> Bool -> SQLExp -> SQLExp
|
||||
toJSONableExp stringifyNum colType asText expression
|
||||
toJSONableExp :: Options.StringifyNumbers -> ColumnType ('Postgres pgKind) -> Bool -> Maybe NamingCase -> SQLExp -> SQLExp
|
||||
toJSONableExp stringifyNum colType asText tCase expression
|
||||
-- If it's a numeric column greater than a 32-bit integer, we have to stringify it as JSON spec doesn't support >32-bit integers
|
||||
| asText || (isScalarColumnWhere isBigNum colType && (case stringifyNum of Options.StringifyNumbers -> True; Options.Don'tStringifyNumbers -> False)) =
|
||||
expression `SETyAnn` textTypeAnn
|
||||
@ -38,4 +39,5 @@ toJSONableExp stringifyNum colType asText expression
|
||||
]
|
||||
Nothing
|
||||
`SETyAnn` jsonTypeAnn
|
||||
| isEnumColumn colType && any isGraphqlCase tCase = applyUppercase expression
|
||||
| otherwise = expression
|
||||
|
@ -20,7 +20,7 @@ mkDelete ::
|
||||
Backend ('Postgres pgKind) =>
|
||||
AnnDel ('Postgres pgKind) ->
|
||||
S.SQLDelete
|
||||
mkDelete (AnnDel tn (fltr, wc) _ _) =
|
||||
mkDelete (AnnDel tn (fltr, wc) _ _ _) =
|
||||
S.SQLDelete tn Nothing tableFltr $ Just S.returningStar
|
||||
where
|
||||
tableFltr =
|
||||
|
@ -18,6 +18,7 @@ import Data.Coerce
|
||||
import Hasura.Backends.Postgres.SQL.DML qualified as S
|
||||
import Hasura.Backends.Postgres.SQL.Types
|
||||
import Hasura.Backends.Postgres.Translate.Select
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
@ -85,9 +86,10 @@ mkMutFldExp ::
|
||||
Identifier ->
|
||||
Maybe Int ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
MutFld ('Postgres pgKind) ->
|
||||
S.SQLExp
|
||||
mkMutFldExp cteAlias preCalAffRows strfyNum = \case
|
||||
mkMutFldExp cteAlias preCalAffRows strfyNum tCase = \case
|
||||
MCount ->
|
||||
let countExp =
|
||||
S.SESelect $
|
||||
@ -102,7 +104,7 @@ mkMutFldExp cteAlias preCalAffRows strfyNum = \case
|
||||
tabPerm = TablePerm annBoolExpTrue Nothing
|
||||
in S.SESelect $
|
||||
mkSQLSelect JASMultipleRows $
|
||||
AnnSelectG selFlds tabFrom tabPerm noSelectArgs strfyNum
|
||||
AnnSelectG selFlds tabFrom tabPerm noSelectArgs strfyNum tCase
|
||||
|
||||
toFIIdentifier :: Identifier -> FIIdentifier
|
||||
toFIIdentifier = coerce . getIdenTxt
|
||||
@ -143,8 +145,9 @@ mkMutationOutputExp ::
|
||||
MutationCTE ->
|
||||
MutationOutput ('Postgres pgKind) ->
|
||||
Options.StringifyNumbers ->
|
||||
Maybe NamingCase ->
|
||||
S.SelectWith
|
||||
mkMutationOutputExp qt allCols preCalAffRows cte mutOutput strfyNum =
|
||||
mkMutationOutputExp qt allCols preCalAffRows cte mutOutput strfyNum tCase =
|
||||
S.SelectWith
|
||||
[ (S.toTableAlias mutationResultAlias, getMutationCTE cte),
|
||||
(S.toTableAlias allColumnsAlias, allColumnsSelect)
|
||||
@ -173,7 +176,7 @@ mkMutationOutputExp qt allCols preCalAffRows cte mutOutput strfyNum =
|
||||
let jsonBuildObjArgs = flip concatMap mutFlds $
|
||||
\(FieldName k, mutFld) ->
|
||||
[ S.SELit k,
|
||||
mkMutFldExp allColumnsAlias preCalAffRows strfyNum mutFld
|
||||
mkMutFldExp allColumnsAlias preCalAffRows strfyNum tCase mutFld
|
||||
]
|
||||
in S.SEFnApp "json_build_object" jsonBuildObjArgs Nothing
|
||||
MOutSinglerowObject annFlds ->
|
||||
@ -181,7 +184,7 @@ mkMutationOutputExp qt allCols preCalAffRows cte mutOutput strfyNum =
|
||||
tabPerm = TablePerm annBoolExpTrue Nothing
|
||||
in S.SESelect $
|
||||
mkSQLSelect JASSingleObject $
|
||||
AnnSelectG annFlds tabFrom tabPerm noSelectArgs strfyNum
|
||||
AnnSelectG annFlds tabFrom tabPerm noSelectArgs strfyNum tCase
|
||||
|
||||
mkCheckErrorExp :: IsIdentifier a => a -> S.SQLExp
|
||||
mkCheckErrorExp alias =
|
||||
|
@ -75,6 +75,7 @@ import Hasura.Backends.Postgres.Translate.Select.Internal.JoinTree
|
||||
)
|
||||
import Hasura.Backends.Postgres.Translate.Select.Internal.OrderBy (processOrderByItems)
|
||||
import Hasura.Backends.Postgres.Translate.Types
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Node (currentNodeIdVersion, nodeIdVersionInt)
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.Prelude
|
||||
@ -198,7 +199,7 @@ processAnnAggregateSelect sourcePrefixes fieldAlias annAggSel = do
|
||||
aggregateFieldToExp aggFields strfyNum
|
||||
)
|
||||
TAFNodes _ annFields -> do
|
||||
annFieldExtr <- processAnnFields thisSourcePrefix fieldName similarArrayFields annFields
|
||||
annFieldExtr <- processAnnFields thisSourcePrefix fieldName similarArrayFields annFields tCase
|
||||
pure
|
||||
( [annFieldExtr],
|
||||
withJsonAggExtr permLimitSubQuery (orderByForJsonAgg selectSource) $
|
||||
@ -221,7 +222,7 @@ processAnnAggregateSelect sourcePrefixes fieldAlias annAggSel = do
|
||||
|
||||
pure (selectSource, nodeExtractors, topLevelExtractor)
|
||||
where
|
||||
AnnSelectG aggSelFields tableFrom tablePermissions tableArgs strfyNum = annAggSel
|
||||
AnnSelectG aggSelFields tableFrom tablePermissions tableArgs strfyNum tCase = annAggSel
|
||||
permLimit = _tpLimit tablePermissions
|
||||
orderBy = _saOrderBy tableArgs
|
||||
permLimitSubQuery = mkPermissionLimitSubQuery permLimit aggSelFields orderBy
|
||||
@ -268,8 +269,9 @@ processAnnFields ::
|
||||
FieldName ->
|
||||
SimilarArrayFields ->
|
||||
AnnFields ('Postgres pgKind) ->
|
||||
Maybe NamingCase ->
|
||||
m (S.ColumnAlias, S.SQLExp)
|
||||
processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
|
||||
processAnnFields sourcePrefix fieldAlias similarArrFields annFields tCase = do
|
||||
fieldExps <- forM annFields $ \(fieldName, field) ->
|
||||
(fieldName,)
|
||||
<$> case field of
|
||||
@ -281,7 +283,7 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
|
||||
AnnObjectSelectG objAnnFields tableFrom tableFilter = annObjSel
|
||||
objRelSourcePrefix = mkObjectRelationTableAlias sourcePrefix relName
|
||||
sourcePrefixes = mkSourcePrefixes objRelSourcePrefix
|
||||
annFieldsExtr <- processAnnFields (_pfThis sourcePrefixes) fieldName HM.empty objAnnFields
|
||||
annFieldsExtr <- processAnnFields (_pfThis sourcePrefixes) fieldName HM.empty objAnnFields tCase
|
||||
let selectSource =
|
||||
ObjectSelectSource
|
||||
(_pfThis sourcePrefixes)
|
||||
@ -296,7 +298,7 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
|
||||
AFArrayRelation arrSel -> do
|
||||
let arrRelSourcePrefix = mkArrayRelationSourcePrefix sourcePrefix fieldAlias similarArrFields fieldName
|
||||
arrRelAlias = mkArrayRelationAlias fieldAlias similarArrFields fieldName
|
||||
processArrayRelation (mkSourcePrefixes arrRelSourcePrefix) fieldName arrRelAlias arrSel
|
||||
processArrayRelation (mkSourcePrefixes arrRelSourcePrefix) fieldName arrRelAlias arrSel tCase
|
||||
pure $ S.mkQIdenExp arrRelSourcePrefix fieldName
|
||||
AFComputedField _ _ (CFSScalar scalar caseBoolExpMaybe) -> do
|
||||
computedFieldSQLExp <- fromScalarComputedField scalar
|
||||
@ -355,13 +357,13 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
|
||||
toSQLBoolExp (S.QualifiedIdentifier baseTableIdentifier Nothing) $
|
||||
_accColCaseBoolExpField <$> caseBoolExp
|
||||
in S.SECond boolExp sqlExpression S.SENull
|
||||
pure $ toJSONableExp strfyNum typ asText finalSQLExpression
|
||||
pure $ toJSONableExp strfyNum typ asText tCase finalSQLExpression
|
||||
|
||||
fromScalarComputedField :: ComputedFieldScalarSelect ('Postgres pgKind) S.SQLExp -> m S.SQLExp
|
||||
fromScalarComputedField computedFieldScalar = do
|
||||
strfyNum <- ask
|
||||
pure $
|
||||
toJSONableExp strfyNum (ColumnScalar ty) False $
|
||||
toJSONableExp strfyNum (ColumnScalar ty) False Nothing $
|
||||
withColumnOp colOpM $
|
||||
S.SEFunction $ S.FunctionExp fn (fromTableRowArgs sourcePrefix args) Nothing
|
||||
where
|
||||
@ -375,7 +377,7 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
|
||||
mkNodeId :: SourceName -> QualifiedTable -> PrimaryKeyColumns ('Postgres pgKind) -> S.SQLExp
|
||||
mkNodeId _sourceName (QualifiedObject tableSchema tableName) pkeyColumns =
|
||||
let columnInfoToSQLExp pgColumnInfo =
|
||||
toJSONableExp Options.Don'tStringifyNumbers (ciType pgColumnInfo) False $
|
||||
toJSONableExp Options.Don'tStringifyNumbers (ciType pgColumnInfo) False Nothing $
|
||||
S.mkQIdenExp (mkBaseTableAlias sourcePrefix) $ ciColumn pgColumnInfo
|
||||
in -- See Note [Relay Node id].
|
||||
encodeBase64 $
|
||||
@ -447,8 +449,9 @@ processArrayRelation ::
|
||||
FieldName ->
|
||||
S.TableAlias ->
|
||||
ArraySelect ('Postgres pgKind) ->
|
||||
Maybe NamingCase ->
|
||||
m ()
|
||||
processArrayRelation sourcePrefixes fieldAlias relAlias arrSel =
|
||||
processArrayRelation sourcePrefixes fieldAlias relAlias arrSel _tCase =
|
||||
case arrSel of
|
||||
ASSimple annArrRel -> withWriteArrayRelation $ do
|
||||
let AnnRelationSelectG _ colMapping sel = annArrRel
|
||||
@ -504,7 +507,7 @@ aggregateFieldToExp aggFlds strfyNum = jsonRow
|
||||
|
||||
colFldsToExtr opText (FieldName t, CFCol col ty) =
|
||||
[ S.SELit t,
|
||||
toJSONableExp strfyNum ty False $
|
||||
toJSONableExp strfyNum ty False Nothing $
|
||||
S.SEFnApp opText [S.SEIdentifier $ toIdentifier col] Nothing
|
||||
]
|
||||
colFldsToExtr _ (FieldName t, CFExp e) =
|
||||
@ -535,11 +538,11 @@ processAnnSimpleSelect sourcePrefixes fieldAlias permLimitSubQuery annSimpleSel
|
||||
permLimitSubQuery
|
||||
tablePermissions
|
||||
tableArgs
|
||||
annFieldsExtr <- processAnnFields (_pfThis sourcePrefixes) fieldAlias similarArrayFields annSelFields
|
||||
annFieldsExtr <- processAnnFields (_pfThis sourcePrefixes) fieldAlias similarArrayFields annSelFields tCase
|
||||
let allExtractors = HM.fromList $ annFieldsExtr : orderByAndDistinctExtrs
|
||||
pure (selectSource, allExtractors)
|
||||
where
|
||||
AnnSelectG annSelFields tableFrom tablePermissions tableArgs _ = annSimpleSel
|
||||
AnnSelectG annSelFields tableFrom tablePermissions tableArgs _ tCase = annSimpleSel
|
||||
similarArrayFields =
|
||||
mkSimilarArrayFields annSelFields $ _saOrderBy tableArgs
|
||||
|
||||
@ -595,7 +598,7 @@ processConnectionSelect sourcePrefixes fieldAlias relAlias colMapping connection
|
||||
)
|
||||
where
|
||||
ConnectionSelect _ primaryKeyColumns maybeSplit maybeSlice select = connectionSelect
|
||||
AnnSelectG fields selectFrom tablePermissions tableArgs _ = select
|
||||
AnnSelectG fields selectFrom tablePermissions tableArgs _ tCase = select
|
||||
fieldIdentifier = toIdentifier fieldAlias
|
||||
thisPrefix = _pfThis sourcePrefixes
|
||||
permLimitSubQuery = PLSQNotRequired
|
||||
@ -605,7 +608,7 @@ processConnectionSelect sourcePrefixes fieldAlias relAlias colMapping connection
|
||||
flip concatMap (toList primaryKeyColumns) $
|
||||
\pgColumnInfo ->
|
||||
[ S.SELit $ getPGColTxt $ ciColumn pgColumnInfo,
|
||||
toJSONableExp Options.Don'tStringifyNumbers (ciType pgColumnInfo) False $
|
||||
toJSONableExp Options.Don'tStringifyNumbers (ciType pgColumnInfo) False tCase $
|
||||
S.mkQIdenExp (mkBaseTableAlias thisPrefix) $ ciColumn pgColumnInfo
|
||||
]
|
||||
|
||||
@ -685,7 +688,7 @@ processConnectionSelect sourcePrefixes fieldAlias relAlias colMapping connection
|
||||
FieldName $
|
||||
getFieldNameTxt fieldAlias <> "." <> fieldText <> "." <> edgeText
|
||||
edgeFieldIdentifier = toIdentifier edgeFieldName
|
||||
annFieldsExtrExp <- processAnnFields thisPrefix edgeFieldName similarArrayFields annFields
|
||||
annFieldsExtrExp <- processAnnFields thisPrefix edgeFieldName similarArrayFields annFields tCase
|
||||
modify' (<> [annFieldsExtrExp])
|
||||
pure $ S.SEIdentifier edgeFieldIdentifier
|
||||
|
||||
|
@ -96,7 +96,7 @@ mkStreamSQLSelect (AnnSelectStreamG () fields from perm args strfyNum) =
|
||||
_saOrderBy = orderByItems,
|
||||
_saLimit = Just $ _ssaBatchSize args
|
||||
}
|
||||
sqlSelect = AnnSelectG fields from perm selectArgs strfyNum
|
||||
sqlSelect = AnnSelectG fields from perm selectArgs strfyNum Nothing
|
||||
permLimitSubQuery = PLSQNotRequired
|
||||
((selectSource, nodeExtractors), joinTree) =
|
||||
runWriter $
|
||||
|
@ -34,7 +34,7 @@ mkUpdateCTE ::
|
||||
Backend ('Postgres pgKind) =>
|
||||
AnnotatedUpdate ('Postgres pgKind) ->
|
||||
UpdateCTE
|
||||
mkUpdateCTE (AnnotatedUpdateG tn (permFltr, wc) chk backendUpdate _ columnsInfo) =
|
||||
mkUpdateCTE (AnnotatedUpdateG tn (permFltr, wc) chk backendUpdate _ columnsInfo _tCase) =
|
||||
case backendUpdate of
|
||||
BackendUpdate opExps ->
|
||||
Update $ S.CTEUpdate update
|
||||
|
@ -321,7 +321,7 @@ resolveAsyncActionQuery userInfo annAction =
|
||||
{ RS._saWhere = Just tableBoolExpression
|
||||
}
|
||||
tablePermissions = RS.TablePerm annBoolExpTrue Nothing
|
||||
in RS.AnnSelectG annotatedFields tableFromExp tablePermissions tableArguments stringifyNumerics
|
||||
in RS.AnnSelectG annotatedFields tableFromExp tablePermissions tableArguments stringifyNumerics Nothing
|
||||
where
|
||||
IR.AnnActionAsyncQuery _ actionId outputType asyncFields definitionList stringifyNumerics _ actionSource = annAction
|
||||
|
||||
@ -658,8 +658,8 @@ processOutputSelectionSet ::
|
||||
IR.ActionFields ->
|
||||
Options.StringifyNumbers ->
|
||||
RS.AnnSimpleSelectG ('Postgres 'Vanilla) Void v
|
||||
processOutputSelectionSet tableRowInput actionOutputType definitionList actionFields =
|
||||
RS.AnnSelectG annotatedFields selectFrom RS.noTablePermissions RS.noSelectArgs
|
||||
processOutputSelectionSet tableRowInput actionOutputType definitionList actionFields strfyNum =
|
||||
RS.AnnSelectG annotatedFields selectFrom RS.noTablePermissions RS.noSelectArgs strfyNum Nothing
|
||||
where
|
||||
annotatedFields = fmap actionFieldToAnnField <$> actionFields
|
||||
jsonbToPostgresRecordFunction =
|
||||
|
@ -211,7 +211,8 @@ convertRemoteSourceRelationship
|
||||
_asnFrom = selectFrom,
|
||||
_asnPerm = TablePerm annBoolExpTrue Nothing,
|
||||
_asnArgs = noSelectArgs,
|
||||
_asnStrfyNum = Options.Don'tStringifyNumbers
|
||||
_asnStrfyNum = Options.Don'tStringifyNumbers,
|
||||
_asnNamingConvention = Nothing
|
||||
}
|
||||
|
||||
data DBStepInfo b = DBStepInfo
|
||||
|
@ -12,6 +12,7 @@ module Hasura.GraphQL.Schema.Mutation
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Has (getter)
|
||||
import Data.HashMap.Strict qualified as Map
|
||||
import Data.HashSet qualified as Set
|
||||
import Data.Text.Extended
|
||||
@ -19,6 +20,7 @@ import Hasura.GraphQL.Parser.Class
|
||||
import Hasura.GraphQL.Schema.Backend
|
||||
import Hasura.GraphQL.Schema.BoolExp
|
||||
import Hasura.GraphQL.Schema.Common
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Parser
|
||||
( FieldParser,
|
||||
InputFieldsParser,
|
||||
@ -75,6 +77,7 @@ insertIntoTable backendInsertAction scenario sourceInfo tableInfo fieldName desc
|
||||
-- If we're in a frontend scenario, we should not include backend_only inserts
|
||||
-- For more info see Note [Backend only permissions]
|
||||
guard $ not $ scenario == Frontend && ipiBackendOnly insertPerms
|
||||
tCase <- asks getter
|
||||
lift do
|
||||
updatePerms <- _permUpd <$> tablePermissions tableInfo
|
||||
-- objects [{ ... }]
|
||||
@ -88,7 +91,7 @@ insertIntoTable backendInsertAction scenario sourceInfo tableInfo fieldName desc
|
||||
pure $ mkInsertObject objects tableInfo backendInsert insertPerms updatePerms
|
||||
pure $
|
||||
P.subselection fieldName description argsParser selectionParser
|
||||
<&> \(insertObject, output) -> IR.AnnotatedInsert (G.unName fieldName) False insertObject (IR.MOutMultirowFields output)
|
||||
<&> \(insertObject, output) -> IR.AnnotatedInsert (G.unName fieldName) False insertObject (IR.MOutMultirowFields output) (Just tCase)
|
||||
where
|
||||
mkObjectsArg objectParser =
|
||||
P.field
|
||||
@ -124,6 +127,7 @@ insertOneIntoTable backendInsertAction scenario sourceInfo tableInfo fieldName d
|
||||
-- For more info see Note [Backend only permissions]
|
||||
guard $ not $ scenario == Frontend && ipiBackendOnly insertPerms
|
||||
selectionParser <- MaybeT $ tableSelectionSet sourceInfo tableInfo
|
||||
tCase <- asks getter
|
||||
lift do
|
||||
updatePerms <- _permUpd <$> tablePermissions tableInfo
|
||||
objectParser <- tableFieldsInput sourceInfo tableInfo
|
||||
@ -134,7 +138,7 @@ insertOneIntoTable backendInsertAction scenario sourceInfo tableInfo fieldName d
|
||||
pure $ mkInsertObject [object] tableInfo backendInsert insertPerms updatePerms
|
||||
pure $
|
||||
P.subselection fieldName description argsParser selectionParser
|
||||
<&> \(insertObject, output) -> IR.AnnotatedInsert (G.unName fieldName) True insertObject (IR.MOutSinglerowObject output)
|
||||
<&> \(insertObject, output) -> IR.AnnotatedInsert (G.unName fieldName) True insertObject (IR.MOutSinglerowObject output) (Just tCase)
|
||||
where
|
||||
mkObjectArg objectParser =
|
||||
P.field
|
||||
@ -358,6 +362,7 @@ deleteFromTable scenario sourceInfo tableInfo fieldName description = runMaybeT
|
||||
-- If we're in a frontend scenario, we should not include backend_only deletes
|
||||
-- For more info see Note [Backend only permissions]
|
||||
guard $ not $ scenario == Frontend && dpiBackendOnly deletePerms
|
||||
tCase <- asks getter
|
||||
lift do
|
||||
let whereName = Name._where
|
||||
whereDesc = "filter the rows which have to be deleted"
|
||||
@ -366,7 +371,7 @@ deleteFromTable scenario sourceInfo tableInfo fieldName description = runMaybeT
|
||||
let columns = tableColumns tableInfo
|
||||
pure $
|
||||
P.subselection fieldName description whereArg selection
|
||||
<&> mkDeleteObject (tableInfoName tableInfo) columns deletePerms . fmap IR.MOutMultirowFields
|
||||
<&> mkDeleteObject (tableInfoName tableInfo) columns deletePerms (Just tCase) . fmap IR.MOutMultirowFields
|
||||
|
||||
-- | Construct a root field, normally called delete_tablename_by_pk, that can be used to delete an
|
||||
-- individual rows from a DB table, specified by primary key. Select permissions are required, as
|
||||
@ -394,24 +399,27 @@ deleteFromTableByPk scenario sourceInfo tableInfo fieldName description = runMay
|
||||
-- For more info see Note [Backend only permissions]
|
||||
guard $ not $ scenario == Frontend && dpiBackendOnly deletePerms
|
||||
selection <- MaybeT $ tableSelectionSet sourceInfo tableInfo
|
||||
tCase <- asks getter
|
||||
let columns = tableColumns tableInfo
|
||||
pure $
|
||||
P.subselection fieldName description pkArgs selection
|
||||
<&> mkDeleteObject (tableInfoName tableInfo) columns deletePerms . fmap IR.MOutSinglerowObject
|
||||
<&> mkDeleteObject (tableInfoName tableInfo) columns deletePerms (Just tCase) . fmap IR.MOutSinglerowObject
|
||||
|
||||
mkDeleteObject ::
|
||||
Backend b =>
|
||||
TableName b ->
|
||||
[ColumnInfo b] ->
|
||||
DelPermInfo b ->
|
||||
Maybe NamingCase ->
|
||||
(AnnBoolExp b (IR.UnpreparedValue b), IR.MutationOutputG b (IR.RemoteRelationshipField IR.UnpreparedValue) (IR.UnpreparedValue b)) ->
|
||||
IR.AnnDelG b (IR.RemoteRelationshipField IR.UnpreparedValue) (IR.UnpreparedValue b)
|
||||
mkDeleteObject table columns deletePerms (whereExp, mutationOutput) =
|
||||
mkDeleteObject table columns deletePerms tCase (whereExp, mutationOutput) =
|
||||
IR.AnnDel
|
||||
{ IR._adTable = table,
|
||||
IR._adWhere = (permissionFilter, whereExp),
|
||||
IR._adOutput = mutationOutput,
|
||||
IR._adAllCols = columns
|
||||
IR._adAllCols = columns,
|
||||
IR._adNamingConvention = tCase
|
||||
}
|
||||
where
|
||||
permissionFilter = fmap partialSQLExpToUnpreparedValue <$> dpiFilter deletePerms
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Hasura.GraphQL.Schema.NamingCase
|
||||
( NamingCase (..),
|
||||
isGraphqlCase,
|
||||
parseNamingConventionFromText,
|
||||
)
|
||||
where
|
||||
@ -29,3 +30,7 @@ parseNamingConventionFromText :: Text -> Either String NamingCase
|
||||
parseNamingConventionFromText "hasura-default" = Right HasuraCase
|
||||
parseNamingConventionFromText "graphql-default" = Right GraphqlCase
|
||||
parseNamingConventionFromText _ = Left "naming_convention can either be \"hasura-default\" or \"graphql-default\""
|
||||
|
||||
isGraphqlCase :: NamingCase -> Bool
|
||||
isGraphqlCase GraphqlCase = True
|
||||
isGraphqlCase _ = False
|
||||
|
@ -23,6 +23,7 @@ import Hasura.Base.ToErrorValue
|
||||
import Hasura.GraphQL.Schema.Backend
|
||||
import Hasura.GraphQL.Schema.Common
|
||||
import Hasura.GraphQL.Schema.Instances ()
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Node
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.GraphQL.Schema.Parser (Kind (..), Parser, memoizeOn)
|
||||
@ -110,6 +111,7 @@ nodeField sourceCache = do
|
||||
let idDescription = G.Description "A globally unique id"
|
||||
idArgument = P.field Name._id (Just idDescription) P.identifier
|
||||
stringifyNumbers <- retrieve Options.soStringifyNumbers
|
||||
tCase <- asks getter
|
||||
nodeObject <-
|
||||
retrieve scSchemaKind >>= \case
|
||||
HasuraSchema -> throw500 "internal error: the node field should only be built for the Relay schema"
|
||||
@ -130,7 +132,7 @@ nodeField sourceCache = do
|
||||
let matchingTables = flip mapMaybe (Map.keys sourceCache) \sourceName ->
|
||||
(sourceName,) <$> findNode @('Postgres 'Vanilla) sourceName tableName parseds
|
||||
case matchingTables of
|
||||
[(sourceName, nodeValue)] -> createRootField stringifyNumbers sourceName tableName nodeValue pKeys
|
||||
[(sourceName, nodeValue)] -> createRootField stringifyNumbers sourceName tableName nodeValue pKeys (Just tCase)
|
||||
[] -> throwInvalidNodeId $ "no such table found: " <> toErrorValue tableName
|
||||
l ->
|
||||
throwInvalidNodeId $
|
||||
@ -146,7 +148,7 @@ nodeField sourceCache = do
|
||||
nodeValue <-
|
||||
findNode @b sourceName tableName parseds
|
||||
`onNothing` throwInvalidNodeId ("no table " <> toErrorValue tableName <> " found in source " <> toErrorValue sourceName)
|
||||
createRootField stringifyNumbers sourceName tableName nodeValue pKeys
|
||||
createRootField stringifyNumbers sourceName tableName nodeValue pKeys (Just tCase)
|
||||
where
|
||||
throwInvalidNodeId :: ErrorMessage -> n a
|
||||
throwInvalidNodeId t = P.withKey (J.Key "args") $ P.withKey (J.Key "id") $ P.parseError $ "invalid node id: " <> t
|
||||
@ -165,8 +167,9 @@ nodeField sourceCache = do
|
||||
TableName b ->
|
||||
NodeInfo b ->
|
||||
NESeq.NESeq J.Value ->
|
||||
Maybe NamingCase ->
|
||||
n (IR.QueryRootField IR.UnpreparedValue)
|
||||
createRootField stringifyNumbers sourceName tableName (NodeInfo sourceConfig perms pKeys fields) columnValues = do
|
||||
createRootField stringifyNumbers sourceName tableName (NodeInfo sourceConfig perms pKeys fields) columnValues tCase = do
|
||||
whereExp <- buildNodeIdBoolExp columnValues pKeys
|
||||
pure $
|
||||
IR.RFDB sourceName $
|
||||
@ -186,7 +189,8 @@ nodeField sourceCache = do
|
||||
IR._saOffset = Nothing,
|
||||
IR._saDistinct = Nothing
|
||||
},
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = tCase
|
||||
}
|
||||
|
||||
-- Craft the 'where' condition of the query by making an `AEQ` entry for
|
||||
|
@ -103,6 +103,7 @@ defaultSelectTable ::
|
||||
Maybe G.Description ->
|
||||
m (Maybe (FieldParser n (SelectExp b)))
|
||||
defaultSelectTable sourceInfo tableInfo fieldName description = runMaybeT do
|
||||
tCase <- asks getter
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions tableInfo
|
||||
selectionSetParser <- MaybeT $ tableSelectionList sourceInfo tableInfo
|
||||
lift $ memoizeOn 'defaultSelectTable (_siName sourceInfo, tableName, fieldName) do
|
||||
@ -117,7 +118,8 @@ defaultSelectTable sourceInfo tableInfo fieldName description = runMaybeT do
|
||||
IR._asnFrom = IR.FromTable tableName,
|
||||
IR._asnPerm = tablePermissionsInfo selectPermissions,
|
||||
IR._asnArgs = args,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
where
|
||||
tableName = tableInfoName tableInfo
|
||||
@ -157,6 +159,7 @@ selectTableConnection ::
|
||||
PrimaryKeyColumns b ->
|
||||
m (Maybe (FieldParser n (ConnectionSelectExp b)))
|
||||
selectTableConnection sourceInfo tableInfo fieldName description pkeyColumns = runMaybeT do
|
||||
tCase <- asks getter
|
||||
xRelayInfo <- hoistMaybe $ relayExtension @b
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions tableInfo
|
||||
selectionSetParser <- fmap P.nonNullableParser <$> MaybeT $ tableConnectionSelectionSet sourceInfo tableInfo
|
||||
@ -177,7 +180,8 @@ selectTableConnection sourceInfo tableInfo fieldName description pkeyColumns = r
|
||||
IR._asnFrom = IR.FromTable tableName,
|
||||
IR._asnPerm = tablePermissionsInfo selectPermissions,
|
||||
IR._asnArgs = args,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
}
|
||||
where
|
||||
@ -205,6 +209,7 @@ selectTableByPk ::
|
||||
Maybe G.Description ->
|
||||
m (Maybe (FieldParser n (SelectExp b)))
|
||||
selectTableByPk sourceInfo tableInfo fieldName description = runMaybeT do
|
||||
tCase <- asks getter
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions tableInfo
|
||||
primaryKeys <- hoistMaybe $ fmap _pkColumns . _tciPrimaryKey . _tiCoreInfo $ tableInfo
|
||||
selectionSetParser <- MaybeT $ tableSelectionSet sourceInfo tableInfo
|
||||
@ -230,7 +235,8 @@ selectTableByPk sourceInfo tableInfo fieldName description = runMaybeT do
|
||||
IR._asnFrom = IR.FromTable tableName,
|
||||
IR._asnPerm = permissions,
|
||||
IR._asnArgs = IR.noSelectArgs {IR._saWhere = whereExpr},
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
where
|
||||
tableName = tableInfoName tableInfo
|
||||
@ -257,6 +263,7 @@ defaultSelectTableAggregate ::
|
||||
Maybe G.Description ->
|
||||
m (Maybe (FieldParser n (AggSelectExp b)))
|
||||
defaultSelectTableAggregate sourceInfo tableInfo fieldName description = runMaybeT $ do
|
||||
tCase <- asks getter
|
||||
selectPermissions <- MaybeT $ tableSelectPermissions tableInfo
|
||||
guard $ spiAllowAgg selectPermissions
|
||||
xNodesAgg <- hoistMaybe $ nodesAggExtension @b
|
||||
@ -285,7 +292,8 @@ defaultSelectTableAggregate sourceInfo tableInfo fieldName description = runMayb
|
||||
IR._asnFrom = IR.FromTable tableName,
|
||||
IR._asnPerm = tablePermissionsInfo selectPermissions,
|
||||
IR._asnArgs = args,
|
||||
IR._asnStrfyNum = stringifyNumbers
|
||||
IR._asnStrfyNum = stringifyNumbers,
|
||||
IR._asnNamingConvention = Just tCase
|
||||
}
|
||||
where
|
||||
tableName = tableInfoName tableInfo
|
||||
|
@ -16,7 +16,7 @@ module Hasura.GraphQL.Schema.Update
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Has (Has)
|
||||
import Data.Has (Has (getter))
|
||||
import Data.HashMap.Strict qualified as M
|
||||
import Data.HashMap.Strict.Extended qualified as M
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
@ -277,10 +277,11 @@ updateTable backendUpdate scenario sourceInfo tableInfo fieldName description =
|
||||
guard $ not $ scenario == Frontend && upiBackendOnly updatePerms
|
||||
whereArg <- lift $ P.field whereName (Just whereDesc) <$> boolExp sourceInfo tableInfo
|
||||
selection <- lift $ mutationSelectionSet sourceInfo tableInfo
|
||||
tCase <- asks getter
|
||||
let argsParser = liftA2 (,) backendUpdate whereArg
|
||||
pure $
|
||||
P.subselection fieldName description argsParser selection
|
||||
<&> mkUpdateObject tableName columns updatePerms . fmap MOutMultirowFields
|
||||
<&> mkUpdateObject tableName columns updatePerms (Just tCase) . fmap MOutMultirowFields
|
||||
|
||||
-- | Construct a root field, normally called 'update_tablename_by_pk', that can be used
|
||||
-- to update a single in a DB table, specified by primary key. Only returns a
|
||||
@ -313,6 +314,7 @@ updateTableByPk backendUpdate scenario sourceInfo tableInfo fieldName descriptio
|
||||
guard $ not $ scenario == Frontend && upiBackendOnly updatePerms
|
||||
pkArgs <- MaybeT $ primaryKeysArguments tableInfo
|
||||
selection <- MaybeT $ tableSelectionSet sourceInfo tableInfo
|
||||
tCase <- asks getter
|
||||
lift $ do
|
||||
tableGQLName <- getTableGQLName tableInfo
|
||||
pkObjectName <- mkTypename $ tableGQLName <> $$(litName "_pk_columns_input")
|
||||
@ -322,20 +324,21 @@ updateTableByPk backendUpdate scenario sourceInfo tableInfo fieldName descriptio
|
||||
argsParser = (,) <$> backendUpdate <*> P.field pkFieldName Nothing pkParser
|
||||
pure $
|
||||
P.subselection fieldName description argsParser selection
|
||||
<&> mkUpdateObject tableName columns updatePerms . fmap MOutSinglerowObject
|
||||
<&> mkUpdateObject tableName columns updatePerms (Just tCase) . fmap MOutSinglerowObject
|
||||
|
||||
mkUpdateObject ::
|
||||
Backend b =>
|
||||
TableName b ->
|
||||
[ColumnInfo b] ->
|
||||
UpdPermInfo b ->
|
||||
(Maybe NamingCase) ->
|
||||
( ( BackendUpdate b (UnpreparedValue b),
|
||||
AnnBoolExp b (UnpreparedValue b)
|
||||
),
|
||||
MutationOutputG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
|
||||
) ->
|
||||
AnnotatedUpdateG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
|
||||
mkUpdateObject _auTable _auAllCols updatePerms ((_auBackend, whereExp), _auOutput) =
|
||||
mkUpdateObject _auTable _auAllCols updatePerms _auNamingConvention ((_auBackend, whereExp), _auOutput) =
|
||||
AnnotatedUpdateG {..}
|
||||
where
|
||||
permissionFilter = fmap partialSQLExpToUnpreparedValue <$> upiFilter updatePerms
|
||||
|
@ -86,6 +86,7 @@ validateDeleteQWith
|
||||
(resolvedDelFltr, annSQLBoolExp)
|
||||
(mkDefaultMutFlds mAnnRetCols)
|
||||
allCols
|
||||
Nothing
|
||||
where
|
||||
selNecessaryMsg =
|
||||
"; \"delete\" is only allowed if the role "
|
||||
@ -123,4 +124,4 @@ runDelete q = do
|
||||
validateDeleteQ q
|
||||
>>= runTxWithCtx (_pscExecCtx sourceConfig) Q.ReadWrite
|
||||
. flip runReaderT emptyQueryTagsComment
|
||||
. execDeleteQuery strfyNum userInfo
|
||||
. execDeleteQuery strfyNum Nothing userInfo
|
||||
|
@ -253,7 +253,7 @@ runInsert q = do
|
||||
res <- convInsQ q
|
||||
strfyNum <- stringifyNum . _sccSQLGenCtx <$> askServerConfigCtx
|
||||
runTxWithCtx (_pscExecCtx sourceConfig) Q.ReadWrite $
|
||||
flip runReaderT emptyQueryTagsComment $ execInsertQuery strfyNum userInfo res
|
||||
flip runReaderT emptyQueryTagsComment $ execInsertQuery strfyNum Nothing userInfo res
|
||||
|
||||
decodeInsObjs :: (UserInfoM m, QErrM m) => Value -> m [InsObj ('Postgres 'Vanilla)]
|
||||
decodeInsObjs v = do
|
||||
|
@ -232,7 +232,7 @@ convSelectQ table fieldInfoMap selPermInfo selQ sessVarBldr prepValBldr = do
|
||||
tabArgs = SelectArgs wClause annOrdByM mQueryLimit (fromIntegral <$> mQueryOffset) Nothing
|
||||
|
||||
strfyNum <- stringifyNum . _sccSQLGenCtx <$> askServerConfigCtx
|
||||
pure $ AnnSelectG annFlds tabFrom tabPerm tabArgs strfyNum
|
||||
pure $ AnnSelectG annFlds tabFrom tabPerm tabArgs strfyNum Nothing
|
||||
where
|
||||
mQueryOffset = sqOffset selQ
|
||||
mQueryLimit = sqLimit selQ
|
||||
|
@ -191,6 +191,7 @@ validateUpdateQueryWith sessVarBldr prepValBldr uq = do
|
||||
(BackendUpdate $ Map.fromList $ fmap UpdateSet <$> setExpItems)
|
||||
(mkDefaultMutFlds mAnnRetCols)
|
||||
allCols
|
||||
Nothing
|
||||
where
|
||||
mRetCols = uqReturning uq
|
||||
selNecessaryMsg =
|
||||
@ -229,4 +230,4 @@ runUpdate q = do
|
||||
validateUpdateQuery q
|
||||
>>= runTxWithCtx (_pscExecCtx sourceConfig) Q.ReadWrite
|
||||
. flip runReaderT emptyQueryTagsComment
|
||||
. execUpdateQuery strfyNum userInfo
|
||||
. execUpdateQuery strfyNum Nothing userInfo
|
||||
|
@ -8,11 +8,13 @@ module Hasura.RQL.IR.Delete
|
||||
adWhere,
|
||||
adOutput,
|
||||
adAllCols,
|
||||
adNamingConvention,
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Lens.TH (makeLenses)
|
||||
import Data.Kind (Type)
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
import Hasura.RQL.IR.Returning
|
||||
@ -24,7 +26,8 @@ data AnnDelG (b :: BackendType) (r :: Type) v = AnnDel
|
||||
{ _adTable :: TableName b,
|
||||
_adWhere :: (AnnBoolExp b v, AnnBoolExp b v),
|
||||
_adOutput :: MutationOutputG b r v,
|
||||
_adAllCols :: [ColumnInfo b]
|
||||
_adAllCols :: [ColumnInfo b],
|
||||
_adNamingConvention :: Maybe NamingCase
|
||||
}
|
||||
deriving (Functor, Foldable, Traversable)
|
||||
|
||||
|
@ -18,6 +18,7 @@ module Hasura.RQL.IR.Insert
|
||||
aiIsSingle,
|
||||
aiData,
|
||||
aiOutput,
|
||||
aiNamingConvention,
|
||||
AnnotatedInsertField (..),
|
||||
AnnotatedInsertRow,
|
||||
ArrayRelationInsert,
|
||||
@ -42,6 +43,7 @@ where
|
||||
import Control.Lens ((^?))
|
||||
import Control.Lens.TH (makeLenses, makePrisms)
|
||||
import Data.Kind (Type)
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
import Hasura.RQL.IR.Conflict
|
||||
@ -60,7 +62,8 @@ data AnnotatedInsert (b :: BackendType) (r :: Type) v = AnnotatedInsert
|
||||
{ _aiFieldName :: Text,
|
||||
_aiIsSingle :: Bool,
|
||||
_aiData :: MultiObjectInsert b v,
|
||||
_aiOutput :: MutationOutputG b r v
|
||||
_aiOutput :: MutationOutputG b r v,
|
||||
_aiNamingConvention :: Maybe NamingCase
|
||||
}
|
||||
deriving (Functor, Foldable, Traversable)
|
||||
|
||||
|
@ -104,6 +104,7 @@ module Hasura.RQL.IR.Select
|
||||
asnFrom,
|
||||
asnPerm,
|
||||
asnStrfyNum,
|
||||
asnNamingConvention,
|
||||
bifoldMapAnnSelectG,
|
||||
csXRelay,
|
||||
csPrimaryKeyColumns,
|
||||
@ -152,6 +153,7 @@ import Data.Kind (Type)
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Data.Sequence qualified as Seq
|
||||
import Hasura.Backends.Postgres.SQL.Types qualified as PG
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.GraphQL.Schema.Options (StringifyNumbers)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
@ -192,7 +194,8 @@ data AnnSelectG (b :: BackendType) (f :: Type -> Type) (v :: Type) = AnnSelectG
|
||||
_asnFrom :: SelectFromG b v,
|
||||
_asnPerm :: TablePermG b v,
|
||||
_asnArgs :: SelectArgsG b v,
|
||||
_asnStrfyNum :: StringifyNumbers
|
||||
_asnStrfyNum :: StringifyNumbers,
|
||||
_asnNamingConvention :: Maybe NamingCase
|
||||
}
|
||||
deriving stock (Functor, Foldable, Traversable)
|
||||
|
||||
|
@ -10,11 +10,13 @@ module Hasura.RQL.IR.Update
|
||||
auBackend,
|
||||
auOutput,
|
||||
auAllCols,
|
||||
auNamingConvention,
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Lens.TH (makeLenses)
|
||||
import Data.Kind (Type)
|
||||
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
import Hasura.RQL.IR.Returning
|
||||
@ -38,7 +40,8 @@ data AnnotatedUpdateG (b :: BackendType) (r :: Type) v = AnnotatedUpdateG
|
||||
|
||||
-- | Selection set
|
||||
_auOutput :: !(MutationOutputG b r v),
|
||||
_auAllCols :: ![ColumnInfo b]
|
||||
_auAllCols :: ![ColumnInfo b],
|
||||
_auNamingConvention :: !(Maybe NamingCase)
|
||||
}
|
||||
deriving stock (Functor, Foldable, Traversable)
|
||||
|
||||
|
@ -5,6 +5,7 @@ module Hasura.RQL.Types.Column
|
||||
( ColumnType (..),
|
||||
_ColumnScalar,
|
||||
_ColumnEnumReference,
|
||||
isEnumColumn,
|
||||
isScalarColumnWhere,
|
||||
ValueParser,
|
||||
onlyNumCols,
|
||||
@ -133,6 +134,10 @@ isScalarColumnWhere f = \case
|
||||
ColumnScalar scalar -> f scalar
|
||||
ColumnEnumReference _ -> False
|
||||
|
||||
isEnumColumn :: ColumnType b -> Bool
|
||||
isEnumColumn (ColumnEnumReference _) = True
|
||||
isEnumColumn _ = False
|
||||
|
||||
-- | Note: Unconditionally accepts null values and returns 'PGNull'.
|
||||
parseScalarValueColumnType ::
|
||||
forall m b.
|
||||
|
@ -8,7 +8,7 @@ import Hasura.Backends.DataConnector.RQLGenerator.GenSelectFromG (genSelectFromG
|
||||
import Hasura.Backends.DataConnector.RQLGenerator.GenTablePermG (genTablePermG)
|
||||
import Hasura.Generator.Common (defaultRange)
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
import Hasura.Prelude (Applicative ((<*>)), Bool (..), (<$>), (<&>))
|
||||
import Hasura.Prelude hiding (bool)
|
||||
import Hasura.RQL.IR (AnnSelectG (..))
|
||||
import Hasura.RQL.IR.Generator (genFields)
|
||||
import Hasura.SQL.Backend (BackendType (..))
|
||||
@ -25,6 +25,7 @@ genAnnSelectG genA genFA =
|
||||
<*> genTablePermG genA
|
||||
<*> genArgs
|
||||
<*> genStringifyNumbers
|
||||
<*> (pure Nothing)
|
||||
where
|
||||
genStringifyNumbers =
|
||||
bool <&> \case
|
||||
|
@ -25,6 +25,7 @@ genAnnSelectG genA genFA =
|
||||
<*> genTablePermG genA
|
||||
<*> genArgs
|
||||
<*> genStringifyNumbers
|
||||
<*> (pure Nothing)
|
||||
where
|
||||
genStringifyNumbers =
|
||||
Gen.bool <&> \case
|
||||
|
@ -19,6 +19,7 @@ import Hasura.Backends.Postgres.Types.Update (BackendUpdate (..), MultiRowUpdate
|
||||
import Hasura.GraphQL.Parser.Internal.Parser (FieldParser (..))
|
||||
import Hasura.GraphQL.Parser.Schema (Definition (..))
|
||||
import Hasura.GraphQL.Parser.Variable (Variable (..))
|
||||
import Hasura.GraphQL.Schema.NamingCase
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp (AnnBoolExpFld (..), GBoolExp (..), OpExpG (..))
|
||||
import Hasura.RQL.IR.Returning (MutationOutputG (..))
|
||||
@ -197,3 +198,6 @@ mkAnnotatedUpdate AnnotatedUpdateBuilder {..} = AnnotatedUpdateG {..}
|
||||
BoolAnd
|
||||
. fmap (\c -> BoolField . AVColumn c $ stuff)
|
||||
$ aubColumns
|
||||
|
||||
_auNamingConvention :: Maybe NamingCase
|
||||
_auNamingConvention = Just HasuraCase
|
||||
|
@ -34,7 +34,7 @@
|
||||
);
|
||||
INSERT INTO days_of_the_week (day_name)
|
||||
VALUES ('Monday'), ('Tuesday'), ('Wednesday'), ('Thursday'), ('Friday'), ('Saturday'), ('Sunday');
|
||||
|
||||
|
||||
CREATE TABLE users(
|
||||
id serial PRIMARY KEY,
|
||||
favourite_day text NOT NULL REFERENCES days_of_the_week
|
||||
@ -86,6 +86,135 @@
|
||||
}
|
||||
}
|
||||
|
||||
- description: Insert users returning enum values (should be uppercased)
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
insertUsers:
|
||||
returning:
|
||||
- id: 2
|
||||
favouriteDay: SUNDAY
|
||||
- id: 3
|
||||
favouriteDay: FRIDAY
|
||||
- id: 4
|
||||
favouriteDay: MONDAY
|
||||
- id: 5
|
||||
favouriteDay: SATURDAY
|
||||
|
||||
query:
|
||||
query: |
|
||||
mutation {
|
||||
insertUsers(objects: [{favouriteDay: SUNDAY},{favouriteDay: FRIDAY},{favouriteDay: MONDAY},{favouriteDay: SATURDAY}]) {
|
||||
returning {
|
||||
id
|
||||
favouriteDay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- description: Update users returning enum values (should be uppercased)
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
updateUsers:
|
||||
returning:
|
||||
- id: 1
|
||||
favouriteDay: MONDAY
|
||||
- id: 2
|
||||
favouriteDay: MONDAY
|
||||
|
||||
query:
|
||||
query: |
|
||||
mutation {
|
||||
updateUsers(where: {favouriteDay: {_eq: SUNDAY}}, _set: {favouriteDay: MONDAY}) {
|
||||
returning {
|
||||
id
|
||||
favouriteDay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- description: Delete users returning enum values (should be uppercased)
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
deleteUsers:
|
||||
returning:
|
||||
- id: 4
|
||||
favouriteDay: MONDAY
|
||||
- id: 1
|
||||
favouriteDay: MONDAY
|
||||
- id: 2
|
||||
favouriteDay: MONDAY
|
||||
|
||||
query:
|
||||
query: |
|
||||
mutation MyMutation {
|
||||
deleteUsers(where: {favouriteDay: {_eq: MONDAY}}) {
|
||||
returning {
|
||||
id
|
||||
favouriteDay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- description: Insert user by pk returning enum value (should be uppercased)
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
insertUsersOne:
|
||||
id: 6
|
||||
favouriteDay: SUNDAY
|
||||
|
||||
query:
|
||||
query: |
|
||||
mutation {
|
||||
insertUsersOne(object: {favouriteDay: SUNDAY}) {
|
||||
id
|
||||
favouriteDay
|
||||
}
|
||||
}
|
||||
|
||||
- description: Update user by pk returning enum value (should be uppercased)
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
updateUsersByPk:
|
||||
id: 3
|
||||
favouriteDay: WEDNESDAY
|
||||
|
||||
query:
|
||||
query: |
|
||||
mutation {
|
||||
updateUsersByPk(pk_columns: {id: 3}, _set: {favouriteDay: WEDNESDAY}) {
|
||||
id
|
||||
favouriteDay
|
||||
}
|
||||
}
|
||||
|
||||
- description: Delete user by pk returning enum value (should be uppercased)
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
deleteUsersByPk:
|
||||
id: 5
|
||||
favouriteDay: SATURDAY
|
||||
|
||||
query:
|
||||
query: |
|
||||
mutation MyMutation {
|
||||
deleteUsersByPk(id: 5) {
|
||||
id
|
||||
favouriteDay
|
||||
}
|
||||
}
|
||||
|
||||
- description: Untrack tables
|
||||
url: /v1/metadata
|
||||
status: 200
|
||||
|
@ -39,6 +39,7 @@ class TestNamingConventionsFailure:
|
||||
check_query_f(hge_ctx, self.dir() + '/mssql_naming_convention.yaml')
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not env_var_contains('HASURA_GRAPHQL_EXPERIMENTAL_FEATURES', 'naming_convention') or
|
||||
not env_var_contains('HASURA_GRAPHQL_DEFAULT_NAMING_CONVENTION', 'graphql-default'),
|
||||
reason="This test expects the HASURA_GRAPHQL_DEFAULT_NAMING_CONVENTION environment variable set to graphql-default")
|
||||
class TestDefaultNamingConvention:
|
||||
|
Loading…
Reference in New Issue
Block a user