mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 08:02:15 +03:00
server/mssql: fix aggregations
Aggregate fields - both the table and the relationship fields haven't been enabled till now. This PR fixes enables the aggregate fields and fixes an issue with root aggregate fields. Co-authored-by: Chris Done <11019+chrisdone@users.noreply.github.com> GitOrigin-RevId: a6d7ed9b45cda6af659a57576a8623c725a7372f
This commit is contained in:
parent
bc1e131717
commit
1c668dac0e
@ -6,7 +6,7 @@
|
||||
### Bug fixes and improvements
|
||||
|
||||
(Add entries below in the order of: server, console, cli, docs, others)
|
||||
|
||||
- server: aggregation fields are now supported on mssql
|
||||
- server: accept a new server config flag `--events-fetch-batch-size` to configure the number of rows being fetched from the events log table in a single batch
|
||||
- server: fix regression: `on_conflict` was missing in the schema for inserts in tables where the current user has no columns listed in their update permissions (fix #6804)
|
||||
- server: fix one-to-one relationship bug (introduced in #459) which prevented adding one-to-one relationships which didn't have the same column name for target and source
|
||||
|
@ -46,6 +46,7 @@ import Hasura.SQL.Backend
|
||||
data Error
|
||||
= UnsupportedOpExpG (IR.OpExpG 'MSSQL Expression)
|
||||
| FunctionNotSupported
|
||||
| NodesUnsupportedForNow
|
||||
deriving (Show, Eq)
|
||||
|
||||
-- | The base monad used throughout this module for all conversion
|
||||
@ -188,7 +189,7 @@ fromSelectAggregate annSelectG = do
|
||||
, selectJoins = argsJoins <> mapMaybe fieldSourceJoin fieldSources
|
||||
, selectWhere = argsWhere <> Where [filterExpression]
|
||||
, selectFor =
|
||||
JsonFor ForJson {jsonCardinality = JsonSingleton, jsonRoot = NoRoot}
|
||||
JsonFor ForJson {jsonCardinality = JsonSingleton, jsonRoot = Root "aggregate"}
|
||||
, selectOrderBy = argsOrderBy
|
||||
, selectOffset = argsOffset
|
||||
}
|
||||
@ -502,7 +503,8 @@ fromTableAggregateFieldG (IR.FieldName name, field) =
|
||||
{ aliasedThing = TSQL.ValueExpression (ODBC.TextValue text)
|
||||
, aliasedAlias = name
|
||||
})
|
||||
IR.TAFNodes x _ -> case x of {}
|
||||
IR.TAFNodes {} ->
|
||||
refute (pure NodesUnsupportedForNow)
|
||||
|
||||
fromAggregateField :: IR.AggregateField 'MSSQL -> ReaderT EntityAlias FromIr Aggregate
|
||||
fromAggregateField aggregateField =
|
||||
|
@ -44,7 +44,7 @@ instance BackendSchema 'MSSQL where
|
||||
buildFunctionMutationFields = msBuildFunctionMutationFields
|
||||
-- backend extensions
|
||||
relayExtension = const Nothing
|
||||
nodesAggExtension = const Nothing
|
||||
nodesAggExtension = const $ Just ()
|
||||
-- indivdual components
|
||||
columnParser = msColumnParser
|
||||
jsonPathArg = msJsonPathArg
|
||||
|
@ -41,7 +41,7 @@ instance Backend 'MSSQL where
|
||||
type XComputedField 'MSSQL = XDisable
|
||||
type XRemoteField 'MSSQL = XDisable
|
||||
type XRelay 'MSSQL = XDisable
|
||||
type XNodesAgg 'MSSQL = XDisable
|
||||
type XNodesAgg 'MSSQL = XEnable
|
||||
type XDistinct 'MSSQL = XDisable
|
||||
|
||||
functionArgScalarType :: FunctionArgType 'MSSQL -> ScalarType 'MSSQL
|
||||
|
@ -55,7 +55,17 @@ planNoPlan userInfo queryDB = do
|
||||
{ selectFor =
|
||||
case selectFor select of
|
||||
NoFor -> NoFor
|
||||
JsonFor forJson -> JsonFor forJson {jsonRoot = Root "root"}
|
||||
JsonFor forJson ->
|
||||
JsonFor forJson {jsonRoot =
|
||||
case jsonRoot forJson of
|
||||
NoRoot -> Root "root"
|
||||
-- Keep whatever's there if already
|
||||
-- specified. In the case of an
|
||||
-- aggregate query, the root will
|
||||
-- be specified "aggregate", for
|
||||
-- example.
|
||||
keep -> keep
|
||||
}
|
||||
}
|
||||
|
||||
planMultiplex
|
||||
|
@ -138,9 +138,7 @@ fromDelete Delete {deleteTable, deleteWhere} =
|
||||
]
|
||||
|
||||
fromSelect :: Select -> Printer
|
||||
fromSelect Select {..} = case selectFor of
|
||||
NoFor -> result
|
||||
JsonFor _ -> SeqPrinter ["SELECT ISNULL((", result, "), '[]')"]
|
||||
fromSelect Select {..} = wrapFor selectFor result
|
||||
where
|
||||
result =
|
||||
SepByPrinter
|
||||
@ -186,18 +184,20 @@ fromJoinSource =
|
||||
JoinReselect reselect -> fromReselect reselect
|
||||
|
||||
fromReselect :: Reselect -> Printer
|
||||
fromReselect Reselect {..} =
|
||||
SepByPrinter
|
||||
NewlinePrinter
|
||||
[ "SELECT " <+>
|
||||
IndentPrinter
|
||||
7
|
||||
(SepByPrinter
|
||||
("," <+> NewlinePrinter)
|
||||
(map fromProjection (toList reselectProjections)))
|
||||
, fromFor reselectFor
|
||||
, fromWhere reselectWhere
|
||||
]
|
||||
fromReselect Reselect {..} = wrapFor reselectFor result
|
||||
where
|
||||
result =
|
||||
SepByPrinter
|
||||
NewlinePrinter
|
||||
[ "SELECT " <+>
|
||||
IndentPrinter
|
||||
7
|
||||
(SepByPrinter
|
||||
("," <+> NewlinePrinter)
|
||||
(map fromProjection (toList reselectProjections)))
|
||||
, fromFor reselectFor
|
||||
, fromWhere reselectWhere
|
||||
]
|
||||
|
||||
fromOrderBys ::
|
||||
Top -> Maybe Expression -> Maybe (NonEmpty OrderBy) -> Printer
|
||||
@ -258,15 +258,11 @@ fromFor :: For -> Printer
|
||||
fromFor =
|
||||
\case
|
||||
NoFor -> ""
|
||||
JsonFor ForJson {jsonCardinality, jsonRoot = root} ->
|
||||
JsonFor ForJson {jsonCardinality} ->
|
||||
"FOR JSON PATH" <+>
|
||||
case jsonCardinality of
|
||||
JsonArray -> ""
|
||||
JsonSingleton ->
|
||||
", WITHOUT_ARRAY_WRAPPER" <+>
|
||||
case root of
|
||||
NoRoot -> ""
|
||||
Root text -> "ROOT(" <+> QueryPrinter (toSql text) <+> ")"
|
||||
JsonArray -> ""
|
||||
JsonSingleton -> ", WITHOUT_ARRAY_WRAPPER"
|
||||
|
||||
fromProjection :: Projection -> Printer
|
||||
fromProjection =
|
||||
@ -362,6 +358,32 @@ trueExpression = ValueExpression (BoolValue True)
|
||||
falseExpression :: Expression
|
||||
falseExpression = ValueExpression (BoolValue False)
|
||||
|
||||
-- | Wrap a select with things needed when using FOR JSON.
|
||||
wrapFor :: For -> Printer -> Printer
|
||||
wrapFor for' inner = nullToArray
|
||||
where
|
||||
nullToArray =
|
||||
case for' of
|
||||
NoFor -> rooted
|
||||
JsonFor _ -> SeqPrinter ["SELECT ISNULL((", rooted, "), '[]')"]
|
||||
rooted =
|
||||
case for' of
|
||||
JsonFor ForJson {jsonRoot, jsonCardinality = JsonSingleton} ->
|
||||
case jsonRoot of
|
||||
NoRoot -> inner
|
||||
-- This is gross, but unfortunately ROOT and
|
||||
-- WITHOUT_ARRAY_WRAPPER are not allowed to be used at the
|
||||
-- same time (reason not specified). Therefore we just
|
||||
-- concatenate the necessary JSON string literals around
|
||||
-- the JSON.
|
||||
Root text ->
|
||||
SeqPrinter
|
||||
[ fromString ("SELECT CONCAT('{" <> show text <> ":', (")
|
||||
, inner
|
||||
, "), '}')"
|
||||
]
|
||||
_ -> inner
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Basic printing API
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user