这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions server/src-lib/Hasura/GraphQL/Resolve/Insert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ parseOnConflict inpCols val = withPathK "on_conflict" $
flip withObject val $ \_ obj -> do
actionM <- forM (OMap.lookup "action" obj) parseAction
constraint <- parseConstraint obj
updColsM <- forM (OMap.lookup "update_columns" obj) parseUpdCols
updColsM <- forM (OMap.lookup "update_columns" obj) parseColumns
-- consider "action" if "update_columns" is not mentioned
return $ mkConflictClause $ case (updColsM, actionM) of
(Just [], _) -> RI.CCDoNothing $ Just constraint
Expand All @@ -177,11 +177,6 @@ parseOnConflict inpCols val = withPathK "on_conflict" $
(_, enumVal) <- asEnumVal v
return $ ConstraintName $ G.unName $ G.unEnumValue enumVal

parseUpdCols v = flip withArray v $ \_ enumVals ->
forM enumVals $ \eVal -> do
(_, ev) <- asEnumVal eVal
return $ PGCol $ G.unName $ G.unEnumValue ev

mkConflictClause (RI.CCDoNothing constrM) =
RI.CP1DoNothing $ fmap RI.Constraint constrM
mkConflictClause (RI.CCUpdate constr updCols) =
Expand Down
39 changes: 33 additions & 6 deletions server/src-lib/Hasura/GraphQL/Resolve/Select.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Hasura.GraphQL.Resolve.Select
( convertSelect
, convertSelectByPKey
, convertAggSelect
, parseColumns
, withSelSet
, fromSelSet
, fieldAsPath
Expand All @@ -32,6 +33,7 @@ import qualified Hasura.SQL.DML as S
import Hasura.GraphQL.Resolve.BoolExp
import Hasura.GraphQL.Resolve.Context
import Hasura.GraphQL.Resolve.InputValue
import Hasura.GraphQL.Schema (isAggFld)
import Hasura.GraphQL.Validate.Field
import Hasura.GraphQL.Validate.Types
import Hasura.RQL.DML.Internal (onlyPositiveInt)
Expand Down Expand Up @@ -199,6 +201,29 @@ convertSelectByPKey qt permFilter fld = do
return $ RS.selectP2 True (selData, prepArgs)

-- agg select related
parseColumns :: MonadError QErr m => AnnGValue -> m [PGCol]
parseColumns val =
flip withArray val $ \_ vals ->
forM vals $ \v -> do
(_, enumVal) <- asEnumVal v
return $ PGCol $ G.unName $ G.unEnumValue enumVal

convertCount :: MonadError QErr m => ArgsMap -> m S.CountType
convertCount args = do
columnsM <- withArgM args "columns" parseColumns
isDistinct <- or <$> withArgM args "distinct" parseDistinct
maybe (return S.CTStar) (mkCType isDistinct) columnsM
where
parseDistinct v = do
(_, val) <- asPGColVal v
case val of
PGValBoolean b -> return b
_ ->
throw500 "expecting Boolean for \"distinct\""

mkCType isDistinct cols = return $
bool (S.CTSimple cols) (S.CTDistinct cols) isDistinct

convertColFlds
:: Monad m => G.NamedType -> SelSet -> m RS.ColFlds
convertColFlds ty selSet =
Expand All @@ -216,12 +241,14 @@ convertAggFld ty selSet =
fSelSet = _fSelSet fld
case _fName fld of
"__typename" -> return $ RS.AFExp $ G.unName $ G.unNamedType ty
"count" -> return RS.AFCount
"sum" -> RS.AFSum <$> convertColFlds fType fSelSet
"avg" -> RS.AFAvg <$> convertColFlds fType fSelSet
"max" -> RS.AFMax <$> convertColFlds fType fSelSet
"min" -> RS.AFMin <$> convertColFlds fType fSelSet
G.Name t -> throw500 $ "unexpected field in _agg node: " <> t
"count" -> RS.AFCount <$> convertCount (_fArguments fld)
n -> do
colFlds <- convertColFlds fType fSelSet
unless (isAggFld n) $ throwInvalidFld n
return $ RS.AFOp $ RS.AggOp (G.unName n) colFlds
where
throwInvalidFld (G.Name t) =
throw500 $ "unexpected field in _aggregate node: " <> t

fromAggField
:: (MonadError QErr m, MonadReader r m, Has FieldMap r, Has OrdByCtx r)
Expand Down
96 changes: 69 additions & 27 deletions server/src-lib/Hasura/GraphQL/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Hasura.GraphQL.Schema
, InsCtx(..)
, InsCtxMap
, RelationInfoMap
, isAggFld
) where

import Data.Has
Expand Down Expand Up @@ -153,6 +154,17 @@ isRelNullable fim ri = isNullable
lColInfos = getColInfos lCols allCols
isNullable = any pgiIsNullable lColInfos

numAggOps :: [G.Name]
numAggOps = [ "sum", "avg", "stddev", "stddev_samp", "stddev_pop"
, "variance", "var_samp", "var_pop"
]

compAggOps :: [G.Name]
compAggOps = ["max", "min"]

isAggFld :: G.Name -> Bool
isAggFld = flip elem (numAggOps <> compAggOps)

mkColName :: PGCol -> G.Name
mkColName (PGCol n) = G.Name n

Expand Down Expand Up @@ -378,7 +390,14 @@ mkTableAggObj tn =
{-
type table_aggregate_fields{
count: Int
sum: table_num_fields
sum: table_sum_fields
avg: table_avg_fields
stddev: table_stddev_fields
stddev_pop: table_stddev_pop_fields
variance: table_variance_fields
var_pop: table_var_pop_fields
max: table_max_fields
min: table_min_fields
}
-}
mkTableAggFldsObj
Expand All @@ -390,22 +409,24 @@ mkTableAggFldsObj tn numCols compCols =
desc = G.Description $
"aggregate fields of " <>> tn

countFld = ObjFldInfo Nothing "count" Map.empty $ G.toGT $
countFld = ObjFldInfo Nothing "count" countParams $ G.toGT $
mkScalarTy PGInteger

numFlds = bool [sumFld, avgFld] [] $ null numCols
compFlds = bool [maxFld, minFld] [] $ null compCols
countParams = fromInpValL [countColInpVal, distinctInpVal]

sumFld = mkColOpFld "sum"
avgFld = mkColOpFld "avg"
maxFld = mkColOpFld "max"
minFld = mkColOpFld "min"
countColInpVal = InpValInfo Nothing "columns" $ G.toGT $
G.toLT $ G.toNT $ mkSelColumnInpTy tn
distinctInpVal = InpValInfo Nothing "distinct" $ G.toGT $
mkScalarTy PGBoolean

numFlds = bool (map mkColOpFld numAggOps) [] $ null numCols
compFlds = bool (map mkColOpFld compAggOps) [] $ null compCols

mkColOpFld op = ObjFldInfo Nothing op Map.empty $ G.toGT $
mkTableColAggFldsTy op tn

{-
type table_sum_fields{
type table_<agg-op>_fields{
num_col: Int
. .
. .
Expand Down Expand Up @@ -840,10 +861,15 @@ mkConstraintInpTy :: QualifiedTable -> G.NamedType
mkConstraintInpTy tn =
G.NamedType $ qualTableToName tn <> "_constraint"

-- table_column
mkColumnInpTy :: QualifiedTable -> G.NamedType
mkColumnInpTy tn =
G.NamedType $ qualTableToName tn <> "_column"
-- table_update_column
mkUpdColumnInpTy :: QualifiedTable -> G.NamedType
mkUpdColumnInpTy tn =
G.NamedType $ qualTableToName tn <> "_update_column"

--table_select_column
mkSelColumnInpTy :: QualifiedTable -> G.NamedType
mkSelColumnInpTy tn =
G.NamedType $ qualTableToName tn <> "_select_column"
{-
input table_obj_rel_insert_input {
data: table_insert_input!
Expand Down Expand Up @@ -946,7 +972,7 @@ mkOnConflictInp tn =
G.toGT $ G.toNT $ mkConstraintInpTy tn

updateColumnsInpVal = InpValInfo Nothing (G.Name "update_columns") $
G.toGT $ G.toLT $ G.toNT $ mkColumnInpTy tn
G.toGT $ G.toLT $ G.toNT $ mkUpdColumnInpTy tn
{-

insert_table(
Expand Down Expand Up @@ -991,17 +1017,27 @@ mkConstriantTy tn cons = enumTyInfo
EnumValInfo (Just "unique or primary key constraint")
(G.EnumValue $ G.Name n) False

mkColumnTy :: QualifiedTable -> [PGCol] -> EnumTyInfo
mkColumnTy tn cols = enumTyInfo
mkColumnEnumVal :: PGCol -> EnumValInfo
mkColumnEnumVal (PGCol col) =
EnumValInfo (Just "column name") (G.EnumValue $ G.Name col) False

mkUpdColumnTy :: QualifiedTable -> [PGCol] -> EnumTyInfo
mkUpdColumnTy tn cols = enumTyInfo
where
enumTyInfo = EnumTyInfo (Just desc) (mkColumnInpTy tn) $
enumTyInfo = EnumTyInfo (Just desc) (mkUpdColumnInpTy tn) $
mapFromL _eviVal $ map mkColumnEnumVal cols

desc = G.Description $
"columns of table " <>> tn
"update columns of table " <>> tn

mkColumnEnumVal (PGCol col) =
EnumValInfo (Just "column name") (G.EnumValue $ G.Name col) False
mkSelColumnTy :: QualifiedTable -> [PGCol] -> EnumTyInfo
mkSelColumnTy tn cols = enumTyInfo
where
enumTyInfo = EnumTyInfo (Just desc) (mkSelColumnInpTy tn) $
mapFromL _eviVal $ map mkColumnEnumVal cols

desc = G.Description $
"select columns of table " <>> tn

mkConflictActionTy :: EnumTyInfo
mkConflictActionTy = EnumTyInfo (Just desc) ty $ mapFromL _eviVal
Expand Down Expand Up @@ -1108,7 +1144,7 @@ mkOnConflictTypes tn c cols =
where
tyInfos = [ TIEnum mkConflictActionTy
, TIEnum $ mkConstriantTy tn constraints
, TIEnum $ mkColumnTy tn cols
, TIEnum $ mkUpdColumnTy tn cols
, TIInpObj $ mkOnConflictInp tn
]
constraints = filter isUniqueOrPrimary c
Expand Down Expand Up @@ -1159,6 +1195,7 @@ mkGCtxRole' tn insPermM selPermM updColsM delPermM pkeyCols constraints viM allC
, TIInpObj <$> mutHelper viIsUpdatable updSetInpObjM
, TIInpObj <$> mutHelper viIsUpdatable updIncInpObjM
, TIObj <$> mutRespObjM
, TIEnum <$> selColInpTyM
]
mutHelper f objM = bool Nothing objM $ isMutable f viM

Expand Down Expand Up @@ -1190,6 +1227,8 @@ mkGCtxRole' tn insPermM selPermM updColsM delPermM pkeyCols constraints viM allC
updSetInpObjFldsM = mkColFldMap (mkUpdSetTy tn) <$> updColsM

selFldsM = snd <$> selPermM
selColsM = (map pgiName . lefts) <$> selFldsM
selColInpTyM = mkSelColumnTy tn <$> selColsM
-- boolexp input type
boolExpInpObjM = case selFldsM of
Just selFlds -> Just $ mkBoolExpInp tn selFlds
Expand Down Expand Up @@ -1240,15 +1279,18 @@ mkGCtxRole' tn insPermM selPermM updColsM delPermM pkeyCols constraints viM allC
_ -> []
getNumCols = onlyNumCols . lefts
getCompCols = onlyComparableCols . lefts
onlyFloat = const $ mkScalarTy PGFloat

mkTypeMaker "sum" = mkScalarTy
mkTypeMaker _ = onlyFloat

mkColAggFldsObjs flds =
let numCols = getNumCols flds
compCols = getCompCols flds
sumFldsObj = mkTableColAggFldsObj tn "sum" mkScalarTy numCols
avgFldsObj = mkTableColAggFldsObj tn "avg" (const $ mkScalarTy PGFloat) numCols
maxFldsObj = mkTableColAggFldsObj tn "max" mkScalarTy compCols
minFldsObj = mkTableColAggFldsObj tn "min" mkScalarTy compCols
numFldsObjs = bool [sumFldsObj, avgFldsObj] [] $ null numCols
compFldsObjs = bool [maxFldsObj, minFldsObj] [] $ null compCols
mkNumObjFld n = mkTableColAggFldsObj tn n (mkTypeMaker n) numCols
mkCompObjFld n = mkTableColAggFldsObj tn n mkScalarTy compCols
numFldsObjs = bool (map mkNumObjFld numAggOps) [] $ null numCols
compFldsObjs = bool (map mkCompObjFld compAggOps) [] $ null compCols
in numFldsObjs <> compFldsObjs
-- the fields used in table object
selObjFldsM = mkFldMap (mkTableTy tn) <$> selFldsM
Expand Down
2 changes: 1 addition & 1 deletion server/src-lib/Hasura/RQL/DML/Count.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ mkSQLCount
:: CountQueryP1 -> S.Select
mkSQLCount (CountQueryP1 tn (permFltr, mWc) mDistCols) =
S.mkSelect
{ S.selExtr = [S.Extractor (S.SEFnApp "count" [S.SEStar] Nothing) Nothing]
{ S.selExtr = [S.Extractor S.countStar Nothing]
, S.selFrom = Just $ S.FromExp
[S.mkSelFromExp False innerSel $ TableName "r"]
}
Expand Down
2 changes: 1 addition & 1 deletion server/src-lib/Hasura/RQL/DML/Returning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ mkMutFldExp :: QualifiedTable -> Bool -> MutFld -> S.SQLExp
mkMutFldExp qt singleObj = \case
MCount -> S.SESelect $
S.mkSelect
{ S.selExtr = [S.Extractor (S.SEUnsafe "count(*)") Nothing]
{ S.selExtr = [S.Extractor S.countStar Nothing]
, S.selFrom = Just $ S.FromExp $ pure frmItem
}
MExp t -> S.SELit t
Expand Down
43 changes: 23 additions & 20 deletions server/src-lib/Hasura/RQL/DML/Select/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,15 @@ data PGColFld

type ColFlds = [(T.Text, PGColFld)]

data AggOp
= AggOp
{ _aoOp :: !T.Text
, _aoFlds :: !ColFlds
} deriving (Show, Eq)

data AggFld
= AFCount
| AFSum !ColFlds
| AFAvg !ColFlds
| AFMax !ColFlds
| AFMin !ColFlds
= AFCount !S.CountType
| AFOp !AggOp
| AFExp !T.Text
deriving (Show, Eq)

Expand Down Expand Up @@ -165,14 +168,11 @@ aggFldToExp aggFlds = jsonRow
jsonRow = S.applyJsonBuildObj (concatMap aggToFlds aggFlds)
withAls fldName sqlExp = [S.SELit fldName, sqlExp]
aggToFlds (t, fld) = withAls t $ case fld of
AFCount -> S.SEUnsafe "count(*)"
AFSum sumFlds -> colFldsToObj "sum" sumFlds
AFAvg avgFlds -> colFldsToObj "avg" avgFlds
AFMax maxFlds -> colFldsToObj "max" maxFlds
AFMin minFlds -> colFldsToObj "min" minFlds
AFExp e -> S.SELit e

colFldsToObj op flds =
AFCount cty -> S.SECount cty
AFOp aggOp -> aggOpToObj aggOp
AFExp e -> S.SELit e

aggOpToObj (AggOp op flds) =
S.applyJsonBuildObj $ concatMap (colFldsToExtr op) flds

colFldsToExtr op (t, PCFCol col) =
Expand Down Expand Up @@ -442,14 +442,17 @@ mkBaseNode pfx fldAls annSelFlds tableFrom tablePerm tableArgs =
)
TAFExp _ -> (HM.fromList obExtrs, HM.empty, HM.empty, HM.empty)

fetchExtrFromAggFld AFCount = []
fetchExtrFromAggFld (AFSum sumFlds) = colFldsToExps sumFlds
fetchExtrFromAggFld (AFAvg avgFlds) = colFldsToExps avgFlds
fetchExtrFromAggFld (AFMax maxFlds) = colFldsToExps maxFlds
fetchExtrFromAggFld (AFMin minFlds) = colFldsToExps minFlds
fetchExtrFromAggFld (AFExp _) = []
fetchExtrFromAggFld (AFCount cty) = countTyToExps cty
fetchExtrFromAggFld (AFOp aggOp) = aggOpToExps aggOp
fetchExtrFromAggFld (AFExp _) = []

countTyToExps S.CTStar = []
countTyToExps (S.CTSimple cols) = colsToExps cols
countTyToExps (S.CTDistinct cols) = colsToExps cols

colsToExps = mapMaybe (mkColExp . PCFCol)

colFldsToExps = mapMaybe (mkColExp . snd)
aggOpToExps = mapMaybe (mkColExp . snd) . _aoFlds

mkColExp (PCFCol c) =
let qualCol = S.mkQIdenExp (mkBaseTableAls pfx) (toIden c)
Expand Down
Loading