{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module      : Database.Relational.Relation
-- Copyright   : 2013-2017 Kei Hibino
-- License     : BSD3
--
-- Maintainer  : ex8k.hibino@gmail.com
-- Stability   : experimental
-- Portability : unknown
--
-- This module integrate monadic operations to compose complex queries
-- with re-usable Relation type.
module Database.Relational.Relation (
  -- * Relation type
  table, derivedRelation, tableOf,
  relation, relation',
  aggregateRelation, aggregateRelation',

  UniqueRelation,
  unsafeUnique, unUnique,

  uniqueRelation', aggregatedUnique,

  -- * Query using relation
  query, queryMaybe, queryList, queryList', queryScalar, queryScalar',
  uniqueQuery', uniqueQueryMaybe',
  ) where

import Control.Applicative ((<$>))

import Database.Relational.Internal.ContextType (Flat, Aggregated)
import Database.Relational.SqlSyntax (NodeAttr(Just', Maybe), Record, )

import Database.Relational.Monad.BaseType
  (ConfigureQuery, qualifyQuery,
   Relation, unsafeTypeRelation, untypeRelation, relationWidth)
import Database.Relational.Monad.Class
  (MonadQualify (liftQualify), MonadQuery (query', queryMaybe'), )
import Database.Relational.Monad.Simple (QuerySimple, SimpleQuery)
import qualified Database.Relational.Monad.Simple as Simple
import Database.Relational.Monad.Aggregate (QueryAggregate, AggregatedQuery)
import qualified Database.Relational.Monad.Aggregate as Aggregate
import Database.Relational.Monad.Unique (QueryUnique, unsafeUniqueSubQuery)
import qualified Database.Relational.Monad.Unique as Unique
import Database.Relational.Table (Table, TableDerivable, derivedTable)
import qualified Database.Relational.Table as Table
import Database.Relational.Scalar (ScalarDegree)
import Database.Relational.Pi (Pi)
import Database.Relational.Record (RecordList)
import qualified Database.Relational.Record as Record
import Database.Relational.Projectable
  (PlaceHolders, unitPlaceHolder, unsafeAddPlaceHolders, unsafePlaceHolders, )


-- | Simple 'Relation' from 'Table'.
table :: Table r -> Relation () r
table :: Table r -> Relation () r
table = ConfigureQuery SubQuery -> Relation () r
forall p r. ConfigureQuery SubQuery -> Relation p r
unsafeTypeRelation (ConfigureQuery SubQuery -> Relation () r)
-> (Table r -> ConfigureQuery SubQuery) -> Table r -> Relation () r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SubQuery -> ConfigureQuery SubQuery
forall (m :: * -> *) a. Monad m => a -> m a
return (SubQuery -> ConfigureQuery SubQuery)
-> (Table r -> SubQuery) -> Table r -> ConfigureQuery SubQuery
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Table r -> SubQuery
forall r. Table r -> SubQuery
Table.toSubQuery

-- | Inferred 'Relation'.
derivedRelation :: TableDerivable r => Relation () r
derivedRelation :: Relation () r
derivedRelation =  Table r -> Relation () r
forall r. Table r -> Relation () r
table Table r
forall r. TableDerivable r => Table r
derivedTable

-- | Interface to derive 'Table' type object.
tableOf :: TableDerivable r => Relation () r -> Table r
tableOf :: Relation () r -> Table r
tableOf =  Table r -> Relation () r -> Table r
forall a b. a -> b -> a
const Table r
forall r. TableDerivable r => Table r
derivedTable

placeHoldersFromRelation :: Relation p r -> PlaceHolders p
placeHoldersFromRelation :: Relation p r -> PlaceHolders p
placeHoldersFromRelation =  PlaceHolders p -> Relation p r -> PlaceHolders p
forall a b. a -> b -> a
const PlaceHolders p
forall p. PlaceHolders p
unsafePlaceHolders

-- | Join sub-query. Query result is not 'Maybe'.
query :: (MonadQualify ConfigureQuery m, MonadQuery m)
      => Relation () r
      -> m (Record Flat r)
query :: Relation () r -> m (Record Flat r)
query =  ((PlaceHolders (), Record Flat r) -> Record Flat r)
-> m (PlaceHolders (), Record Flat r) -> m (Record Flat r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PlaceHolders (), Record Flat r) -> Record Flat r
forall a b. (a, b) -> b
snd (m (PlaceHolders (), Record Flat r) -> m (Record Flat r))
-> (Relation () r -> m (PlaceHolders (), Record Flat r))
-> Relation () r
-> m (Record Flat r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Relation () r -> m (PlaceHolders (), Record Flat r)
forall (m :: * -> *) p r.
MonadQuery m =>
Relation p r -> m (PlaceHolders p, Record Flat r)
query'

-- | Join sub-query. Query result is 'Maybe'.
--   The combinations of 'query' and 'queryMaybe' express
--   inner joins, left outer joins, right outer joins, and full outer joins.
--   Here is an example of a right outer join:
--
-- @
--   outerJoin = relation $ do
--     e <- queryMaybe employee
--     d <- query department
--     on $ e ?! E.deptId' .=. just (d ! D.deptId')
--     return $ (,) |$| e |*| d
-- @
queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m)
           => Relation () r
           -> m (Record Flat (Maybe r))
queryMaybe :: Relation () r -> m (Record Flat (Maybe r))
queryMaybe =  ((PlaceHolders (), Record Flat (Maybe r)) -> Record Flat (Maybe r))
-> m (PlaceHolders (), Record Flat (Maybe r))
-> m (Record Flat (Maybe r))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PlaceHolders (), Record Flat (Maybe r)) -> Record Flat (Maybe r)
forall a b. (a, b) -> b
snd (m (PlaceHolders (), Record Flat (Maybe r))
 -> m (Record Flat (Maybe r)))
-> (Relation () r -> m (PlaceHolders (), Record Flat (Maybe r)))
-> Relation () r
-> m (Record Flat (Maybe r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Relation () r -> m (PlaceHolders (), Record Flat (Maybe r))
forall (m :: * -> *) p r.
MonadQuery m =>
Relation p r -> m (PlaceHolders p, Record Flat (Maybe r))
queryMaybe'

queryList0 :: MonadQualify ConfigureQuery m => Relation p r -> m (RecordList (Record c) r)
queryList0 :: Relation p r -> m (RecordList (Record c) r)
queryList0 =  Qualify (QueryConfig Identity) (RecordList (Record c) r)
-> m (RecordList (Record c) r)
forall (q :: * -> *) (m :: * -> *) a.
MonadQualify q m =>
q a -> m a
liftQualify
              (Qualify (QueryConfig Identity) (RecordList (Record c) r)
 -> m (RecordList (Record c) r))
-> (Relation p r
    -> Qualify (QueryConfig Identity) (RecordList (Record c) r))
-> Relation p r
-> m (RecordList (Record c) r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SubQuery -> RecordList (Record c) r)
-> ConfigureQuery SubQuery
-> Qualify (QueryConfig Identity) (RecordList (Record c) r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SubQuery -> RecordList (Record c) r
forall (p :: * -> *) t. SubQuery -> RecordList p t
Record.unsafeListFromSubQuery
              (ConfigureQuery SubQuery
 -> Qualify (QueryConfig Identity) (RecordList (Record c) r))
-> (Relation p r -> ConfigureQuery SubQuery)
-> Relation p r
-> Qualify (QueryConfig Identity) (RecordList (Record c) r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Relation p r -> ConfigureQuery SubQuery
forall p r. Relation p r -> ConfigureQuery SubQuery
untypeRelation

-- | List sub-query, for /IN/ and /EXIST/ with place-holder parameter 'p'.
queryList' :: MonadQualify ConfigureQuery m
           => Relation p r
           -> m (PlaceHolders p, RecordList (Record c) r)
queryList' :: Relation p r -> m (PlaceHolders p, RecordList (Record c) r)
queryList' Relation p r
rel = do
  RecordList (Record c) r
ql <- Relation p r -> m (RecordList (Record c) r)
forall (m :: * -> *) p r c.
MonadQualify ConfigureQuery m =>
Relation p r -> m (RecordList (Record c) r)
queryList0 Relation p r
rel
  (PlaceHolders p, RecordList (Record c) r)
-> m (PlaceHolders p, RecordList (Record c) r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Relation p r -> PlaceHolders p
forall p r. Relation p r -> PlaceHolders p
placeHoldersFromRelation Relation p r
rel, RecordList (Record c) r
ql)

-- | List sub-query, for /IN/ and /EXIST/.
queryList :: MonadQualify ConfigureQuery m
          => Relation () r
          -> m (RecordList (Record c) r)
queryList :: Relation () r -> m (RecordList (Record c) r)
queryList =  Relation () r -> m (RecordList (Record c) r)
forall (m :: * -> *) p r c.
MonadQualify ConfigureQuery m =>
Relation p r -> m (RecordList (Record c) r)
queryList0

addUnitPH :: Functor f => f t -> f (PlaceHolders (), t)
addUnitPH :: f t -> f (PlaceHolders (), t)
addUnitPH =  ((,) PlaceHolders ()
unitPlaceHolder (t -> (PlaceHolders (), t)) -> f t -> f (PlaceHolders (), t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)

-- | Finalize 'QuerySimple' monad and generate 'Relation' with place-holder parameter 'p'.
relation' :: SimpleQuery p r -> Relation p r
relation' :: SimpleQuery p r -> Relation p r
relation' =  ConfigureQuery SubQuery -> Relation p r
forall p r. ConfigureQuery SubQuery -> Relation p r
unsafeTypeRelation (ConfigureQuery SubQuery -> Relation p r)
-> (SimpleQuery p r -> ConfigureQuery SubQuery)
-> SimpleQuery p r
-> Relation p r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery p r -> ConfigureQuery SubQuery
forall p r. SimpleQuery p r -> ConfigureQuery SubQuery
Simple.toSubQuery

-- | Finalize 'QuerySimple' monad and generate 'Relation'.
relation :: QuerySimple (Record Flat r) -> Relation () r
relation :: QuerySimple (Record Flat r) -> Relation () r
relation =  SimpleQuery () r -> Relation () r
forall p r. SimpleQuery p r -> Relation p r
relation' (SimpleQuery () r -> Relation () r)
-> (QuerySimple (Record Flat r) -> SimpleQuery () r)
-> QuerySimple (Record Flat r)
-> Relation () r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QuerySimple (Record Flat r) -> SimpleQuery () r
forall (f :: * -> *) t. Functor f => f t -> f (PlaceHolders (), t)
addUnitPH

-- | Finalize 'QueryAggregate' monad and geneate 'Relation' with place-holder parameter 'p'.
aggregateRelation' :: AggregatedQuery p r -> Relation p r
aggregateRelation' :: AggregatedQuery p r -> Relation p r
aggregateRelation' =  ConfigureQuery SubQuery -> Relation p r
forall p r. ConfigureQuery SubQuery -> Relation p r
unsafeTypeRelation (ConfigureQuery SubQuery -> Relation p r)
-> (AggregatedQuery p r -> ConfigureQuery SubQuery)
-> AggregatedQuery p r
-> Relation p r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AggregatedQuery p r -> ConfigureQuery SubQuery
forall p r. AggregatedQuery p r -> ConfigureQuery SubQuery
Aggregate.toSubQuery

-- | Finalize 'QueryAggregate' monad and geneate 'Relation'.
aggregateRelation :: QueryAggregate (Record Aggregated r) -> Relation () r
aggregateRelation :: QueryAggregate (Record Aggregated r) -> Relation () r
aggregateRelation =  AggregatedQuery () r -> Relation () r
forall p r. AggregatedQuery p r -> Relation p r
aggregateRelation' (AggregatedQuery () r -> Relation () r)
-> (QueryAggregate (Record Aggregated r) -> AggregatedQuery () r)
-> QueryAggregate (Record Aggregated r)
-> Relation () r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QueryAggregate (Record Aggregated r) -> AggregatedQuery () r
forall (f :: * -> *) t. Functor f => f t -> f (PlaceHolders (), t)
addUnitPH


-- | Unique relation type to compose scalar queries.
newtype UniqueRelation p c r =  Unique (Relation p r)

-- | Unsafely specify unique relation.
unsafeUnique :: Relation p r -> UniqueRelation p c r
unsafeUnique :: Relation p r -> UniqueRelation p c r
unsafeUnique =  Relation p r -> UniqueRelation p c r
forall p c r. Relation p r -> UniqueRelation p c r
Unique

-- | Discard unique attribute.
unUnique :: UniqueRelation p c r -> Relation p r
unUnique :: UniqueRelation p c r -> Relation p r
unUnique (Unique Relation p r
r) = Relation p r
r

-- | Basic monadic join operation using 'MonadQuery'.
uniqueQueryWithAttr :: NodeAttr
                    -> UniqueRelation p c r
                    -> QueryUnique (PlaceHolders p, Record c r)
uniqueQueryWithAttr :: NodeAttr
-> UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
uniqueQueryWithAttr NodeAttr
attr = QueryUnique (Record c r)
-> QueryUnique (PlaceHolders p, Record c r)
forall (f :: * -> *) a p. Functor f => f a -> f (PlaceHolders p, a)
unsafeAddPlaceHolders (QueryUnique (Record c r)
 -> QueryUnique (PlaceHolders p, Record c r))
-> (UniqueRelation p c r -> QueryUnique (Record c r))
-> UniqueRelation p c r
-> QueryUnique (PlaceHolders p, Record c r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UniqueRelation p c r -> QueryUnique (Record c r)
forall p c r c' r.
UniqueRelation p c r -> QueryUnique (Record c' r)
run where
  run :: UniqueRelation p c r -> QueryUnique (Record c' r)
run UniqueRelation p c r
rel = do
    Qualified SubQuery
q <- Qualify (QueryConfig Identity) (Qualified SubQuery)
-> QueryUnique (Qualified SubQuery)
forall (q :: * -> *) (m :: * -> *) a.
MonadQualify q m =>
q a -> m a
liftQualify (Qualify (QueryConfig Identity) (Qualified SubQuery)
 -> QueryUnique (Qualified SubQuery))
-> Qualify (QueryConfig Identity) (Qualified SubQuery)
-> QueryUnique (Qualified SubQuery)
forall a b. (a -> b) -> a -> b
$ do
      SubQuery
sq <- Relation p r -> ConfigureQuery SubQuery
forall p r. Relation p r -> ConfigureQuery SubQuery
untypeRelation (UniqueRelation p c r -> Relation p r
forall p c r. UniqueRelation p c r -> Relation p r
unUnique UniqueRelation p c r
rel)
      SubQuery -> Qualify (QueryConfig Identity) (Qualified SubQuery)
forall a. a -> ConfigureQuery (Qualified a)
qualifyQuery SubQuery
sq
    Record Any r -> Record c' r
forall c r c'. Record c r -> Record c' r
Record.unsafeChangeContext (Record Any r -> Record c' r)
-> QueryUnique (Record Any r) -> QueryUnique (Record c' r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NodeAttr -> Qualified SubQuery -> QueryUnique (Record Any r)
forall c r.
NodeAttr -> Qualified SubQuery -> QueryUnique (Record c r)
unsafeUniqueSubQuery NodeAttr
attr Qualified SubQuery
q

-- | Join unique sub-query with place-holder parameter 'p'.
uniqueQuery' :: UniqueRelation p c r
             -> QueryUnique (PlaceHolders p, Record c r)
uniqueQuery' :: UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
uniqueQuery' = NodeAttr
-> UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
forall p c r.
NodeAttr
-> UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
uniqueQueryWithAttr NodeAttr
Just'

-- | Join unique sub-query with place-holder parameter 'p'. Query result is 'Maybe'.
uniqueQueryMaybe' :: UniqueRelation p c r
                  -> QueryUnique (PlaceHolders p, Record c (Maybe r))
uniqueQueryMaybe' :: UniqueRelation p c r
-> QueryUnique (PlaceHolders p, Record c (Maybe r))
uniqueQueryMaybe' UniqueRelation p c r
pr =  do
  (PlaceHolders p
ph, Record c r
pj) <- NodeAttr
-> UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
forall p c r.
NodeAttr
-> UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
uniqueQueryWithAttr NodeAttr
Maybe UniqueRelation p c r
pr
  (PlaceHolders p, Record c (Maybe r))
-> QueryUnique (PlaceHolders p, Record c (Maybe r))
forall (m :: * -> *) a. Monad m => a -> m a
return (PlaceHolders p
ph, Record c r -> Record c (Maybe r)
forall c r. Record c r -> Record c (Maybe r)
Record.just Record c r
pj)

-- | Finalize 'QueryUnique' monad and generate 'UniqueRelation'.
uniqueRelation' :: QueryUnique (PlaceHolders p, Record c r) -> UniqueRelation p c r
uniqueRelation' :: QueryUnique (PlaceHolders p, Record c r) -> UniqueRelation p c r
uniqueRelation' =  Relation p r -> UniqueRelation p c r
forall p r c. Relation p r -> UniqueRelation p c r
unsafeUnique (Relation p r -> UniqueRelation p c r)
-> (QueryUnique (PlaceHolders p, Record c r) -> Relation p r)
-> QueryUnique (PlaceHolders p, Record c r)
-> UniqueRelation p c r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfigureQuery SubQuery -> Relation p r
forall p r. ConfigureQuery SubQuery -> Relation p r
unsafeTypeRelation (ConfigureQuery SubQuery -> Relation p r)
-> (QueryUnique (PlaceHolders p, Record c r)
    -> ConfigureQuery SubQuery)
-> QueryUnique (PlaceHolders p, Record c r)
-> Relation p r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QueryUnique (PlaceHolders p, Record c r) -> ConfigureQuery SubQuery
forall p c r.
QueryUnique (PlaceHolders p, Record c r) -> ConfigureQuery SubQuery
Unique.toSubQuery

-- | Aggregated 'UniqueRelation'.
aggregatedUnique :: Relation ph r
                 -> Pi r a
                 -> (Record Flat a -> Record Aggregated b)
                 -> UniqueRelation ph Flat b
aggregatedUnique :: Relation ph r
-> Pi r a
-> (Record Flat a -> Record Aggregated b)
-> UniqueRelation ph Flat b
aggregatedUnique Relation ph r
rel Pi r a
k Record Flat a -> Record Aggregated b
ag = Relation ph b -> UniqueRelation ph Flat b
forall p r c. Relation p r -> UniqueRelation p c r
unsafeUnique (Relation ph b -> UniqueRelation ph Flat b)
-> (AggregatedQuery ph b -> Relation ph b)
-> AggregatedQuery ph b
-> UniqueRelation ph Flat b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AggregatedQuery ph b -> Relation ph b
forall p r. AggregatedQuery p r -> Relation p r
aggregateRelation' (AggregatedQuery ph b -> UniqueRelation ph Flat b)
-> AggregatedQuery ph b -> UniqueRelation ph Flat b
forall a b. (a -> b) -> a -> b
$ do
  (PlaceHolders ph
ph, Record Flat r
a) <- Relation ph r
-> Orderings
     Aggregated
     (Restrictings Aggregated (AggregatingSetT QueryCore))
     (PlaceHolders ph, Record Flat r)
forall (m :: * -> *) p r.
MonadQuery m =>
Relation p r -> m (PlaceHolders p, Record Flat r)
query' Relation ph r
rel
  (PlaceHolders ph, Record Aggregated b) -> AggregatedQuery ph b
forall (m :: * -> *) a. Monad m => a -> m a
return (PlaceHolders ph
ph, Record Flat a -> Record Aggregated b
ag (Record Flat a -> Record Aggregated b)
-> Record Flat a -> Record Aggregated b
forall a b. (a -> b) -> a -> b
$ PersistableRecordWidth r
-> Record Flat r -> Pi r a -> Record Flat a
forall a c b.
PersistableRecordWidth a -> Record c a -> Pi a b -> Record c b
Record.wpi (Relation ph r -> PersistableRecordWidth r
forall p r. Relation p r -> PersistableRecordWidth r
relationWidth Relation ph r
rel) Record Flat r
a Pi r a
k)

-- | Scalar sub-query with place-holder parameter 'p'.
queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)
             => UniqueRelation p c r
             -> m (PlaceHolders p, Record c (Maybe r))
queryScalar' :: UniqueRelation p c r -> m (PlaceHolders p, Record c (Maybe r))
queryScalar' UniqueRelation p c r
ur =
  m (Record c (Maybe r)) -> m (PlaceHolders p, Record c (Maybe r))
forall (f :: * -> *) a p. Functor f => f a -> f (PlaceHolders p, a)
unsafeAddPlaceHolders (m (Record c (Maybe r)) -> m (PlaceHolders p, Record c (Maybe r)))
-> (Qualify (QueryConfig Identity) (Record c (Maybe r))
    -> m (Record c (Maybe r)))
-> Qualify (QueryConfig Identity) (Record c (Maybe r))
-> m (PlaceHolders p, Record c (Maybe r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Qualify (QueryConfig Identity) (Record c (Maybe r))
-> m (Record c (Maybe r))
forall (q :: * -> *) (m :: * -> *) a.
MonadQualify q m =>
q a -> m a
liftQualify (Qualify (QueryConfig Identity) (Record c (Maybe r))
 -> m (PlaceHolders p, Record c (Maybe r)))
-> Qualify (QueryConfig Identity) (Record c (Maybe r))
-> m (PlaceHolders p, Record c (Maybe r))
forall a b. (a -> b) -> a -> b
$
  SubQuery -> Record c (Maybe r)
forall c t. SubQuery -> Record c t
Record.unsafeFromScalarSubQuery (SubQuery -> Record c (Maybe r))
-> ConfigureQuery SubQuery
-> Qualify (QueryConfig Identity) (Record c (Maybe r))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Relation p r -> ConfigureQuery SubQuery
forall p r. Relation p r -> ConfigureQuery SubQuery
untypeRelation (UniqueRelation p c r -> Relation p r
forall p c r. UniqueRelation p c r -> Relation p r
unUnique UniqueRelation p c r
ur)

-- | Scalar sub-query.
queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)
            => UniqueRelation () c r
            -> m (Record c (Maybe r))
queryScalar :: UniqueRelation () c r -> m (Record c (Maybe r))
queryScalar =  ((PlaceHolders (), Record c (Maybe r)) -> Record c (Maybe r))
-> m (PlaceHolders (), Record c (Maybe r))
-> m (Record c (Maybe r))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PlaceHolders (), Record c (Maybe r)) -> Record c (Maybe r)
forall a b. (a, b) -> b
snd (m (PlaceHolders (), Record c (Maybe r)) -> m (Record c (Maybe r)))
-> (UniqueRelation () c r
    -> m (PlaceHolders (), Record c (Maybe r)))
-> UniqueRelation () c r
-> m (Record c (Maybe r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UniqueRelation () c r -> m (PlaceHolders (), Record c (Maybe r))
forall (m :: * -> *) r p c.
(MonadQualify ConfigureQuery m, ScalarDegree r) =>
UniqueRelation p c r -> m (PlaceHolders p, Record c (Maybe r))
queryScalar'