{-|
Module: Squeal.PostgreSQL.Type.Alias
Description: aliases
Copyright: (c) Eitan Chatav, 2019
Maintainer: eitan@morphism.tech
Stability: experimental

This module embeds Postgres's alias system in Haskell in
a typesafe fashion. Thanks to GHC's @OverloadedLabels@ extension,
Squeal can reference aliases by prepending with a @#@.
-}

{-# LANGUAGE
    AllowAmbiguousTypes
  , ConstraintKinds
  , DeriveAnyClass
  , DeriveGeneric
  , FlexibleContexts
  , FlexibleInstances
  , FunctionalDependencies
  , GADTs
  , LambdaCase
  , OverloadedStrings
  , QuantifiedConstraints
  , RankNTypes
  , ScopedTypeVariables
  , StandaloneDeriving
  , TypeApplications
  , TypeFamilyDependencies
  , TypeInType
  , TypeOperators
  , UndecidableInstances
  , UndecidableSuperClasses
#-}

module Squeal.PostgreSQL.Type.Alias
  ( -- * Aliases
    (:::)
  , Alias (..)
  , IsLabel (..)
  , Aliased (As)
  , Aliasable (as)
  , renderAliased
  , mapAliased
  , Has
  , HasUnique
  , HasErr
  , HasAll
  , HasIn
    -- * Qualified Aliases
  , QualifiedAlias (..)
  , IsQualified (..)
    -- * Grouping
  , Grouping (..)
  , GroupedBy
  ) where

import Control.DeepSeq
import Data.ByteString (ByteString)
import Data.String (fromString)
import GHC.OverloadedLabels
import GHC.TypeLits

import qualified Generics.SOP as SOP
import qualified GHC.Generics as GHC

import Squeal.PostgreSQL.Type.List
import Squeal.PostgreSQL.Render

-- $setup
-- >>> import Squeal.PostgreSQL

-- | The alias operator `:::` is like a promoted version of `As`,
-- a type level pair between an alias and some type.
type (:::) (alias :: Symbol) ty = '(alias,ty)
infixr 6 :::


-- | `Grouping` is an auxiliary namespace, created by
-- @GROUP BY@ clauses (`Squeal.PostgreSQL.Query.groupBy`), and used
-- for typesafe aggregation
data Grouping
  = Ungrouped -- ^ no aggregation permitted
  | Grouped [(Symbol,Symbol)] -- ^ aggregation required for any column which is not grouped

{- | A `GroupedBy` constraint indicates that a table qualified column is
a member of the auxiliary namespace created by @GROUP BY@ clauses and thus,
may be called in an output `Squeal.PostgreSQL.Expression.Expression` without aggregating.
-}
class (KnownSymbol table, KnownSymbol column)
  => GroupedBy table column bys where
instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
  => GroupedBy table column ('(table,column) ': bys)
instance {-# OVERLAPPABLE #-}
  ( KnownSymbol table
  , KnownSymbol column
  , GroupedBy table column bys
  ) => GroupedBy table column (tabcol ': bys)

-- | `Alias`es are proxies for a type level string or `Symbol`
-- and have an `IsLabel` instance so that with @-XOverloadedLabels@
--
-- >>> :set -XOverloadedLabels
-- >>> #foobar :: Alias "foobar"
-- Alias
data Alias (alias :: Symbol) = Alias
  deriving (Alias alias -> Alias alias -> Bool
(Alias alias -> Alias alias -> Bool)
-> (Alias alias -> Alias alias -> Bool) -> Eq (Alias alias)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
/= :: Alias alias -> Alias alias -> Bool
$c/= :: forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
== :: Alias alias -> Alias alias -> Bool
$c== :: forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
Eq,(forall x. Alias alias -> Rep (Alias alias) x)
-> (forall x. Rep (Alias alias) x -> Alias alias)
-> Generic (Alias alias)
forall x. Rep (Alias alias) x -> Alias alias
forall x. Alias alias -> Rep (Alias alias) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (alias :: Symbol) x. Rep (Alias alias) x -> Alias alias
forall (alias :: Symbol) x. Alias alias -> Rep (Alias alias) x
$cto :: forall (alias :: Symbol) x. Rep (Alias alias) x -> Alias alias
$cfrom :: forall (alias :: Symbol) x. Alias alias -> Rep (Alias alias) x
GHC.Generic,Eq (Alias alias)
Eq (Alias alias)
-> (Alias alias -> Alias alias -> Ordering)
-> (Alias alias -> Alias alias -> Bool)
-> (Alias alias -> Alias alias -> Bool)
-> (Alias alias -> Alias alias -> Bool)
-> (Alias alias -> Alias alias -> Bool)
-> (Alias alias -> Alias alias -> Alias alias)
-> (Alias alias -> Alias alias -> Alias alias)
-> Ord (Alias alias)
Alias alias -> Alias alias -> Bool
Alias alias -> Alias alias -> Ordering
Alias alias -> Alias alias -> Alias alias
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (alias :: Symbol). Eq (Alias alias)
forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
forall (alias :: Symbol). Alias alias -> Alias alias -> Ordering
forall (alias :: Symbol). Alias alias -> Alias alias -> Alias alias
min :: Alias alias -> Alias alias -> Alias alias
$cmin :: forall (alias :: Symbol). Alias alias -> Alias alias -> Alias alias
max :: Alias alias -> Alias alias -> Alias alias
$cmax :: forall (alias :: Symbol). Alias alias -> Alias alias -> Alias alias
>= :: Alias alias -> Alias alias -> Bool
$c>= :: forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
> :: Alias alias -> Alias alias -> Bool
$c> :: forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
<= :: Alias alias -> Alias alias -> Bool
$c<= :: forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
< :: Alias alias -> Alias alias -> Bool
$c< :: forall (alias :: Symbol). Alias alias -> Alias alias -> Bool
compare :: Alias alias -> Alias alias -> Ordering
$ccompare :: forall (alias :: Symbol). Alias alias -> Alias alias -> Ordering
$cp1Ord :: forall (alias :: Symbol). Eq (Alias alias)
Ord,Int -> Alias alias -> ShowS
[Alias alias] -> ShowS
Alias alias -> String
(Int -> Alias alias -> ShowS)
-> (Alias alias -> String)
-> ([Alias alias] -> ShowS)
-> Show (Alias alias)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (alias :: Symbol). Int -> Alias alias -> ShowS
forall (alias :: Symbol). [Alias alias] -> ShowS
forall (alias :: Symbol). Alias alias -> String
showList :: [Alias alias] -> ShowS
$cshowList :: forall (alias :: Symbol). [Alias alias] -> ShowS
show :: Alias alias -> String
$cshow :: forall (alias :: Symbol). Alias alias -> String
showsPrec :: Int -> Alias alias -> ShowS
$cshowsPrec :: forall (alias :: Symbol). Int -> Alias alias -> ShowS
Show,Alias alias -> ()
(Alias alias -> ()) -> NFData (Alias alias)
forall a. (a -> ()) -> NFData a
forall (alias :: Symbol). Alias alias -> ()
rnf :: Alias alias -> ()
$crnf :: forall (alias :: Symbol). Alias alias -> ()
NFData)
instance alias1 ~ alias2 => IsLabel alias1 (Alias alias2) where
  fromLabel :: Alias alias2
fromLabel = Alias alias2
forall (alias :: Symbol). Alias alias
Alias
instance aliases ~ '[alias] => IsLabel alias (NP Alias aliases) where
  fromLabel :: NP Alias aliases
fromLabel = Alias alias
forall (x :: Symbol) a. IsLabel x a => a
fromLabel Alias alias -> NP Alias '[] -> NP Alias '[alias]
forall k (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
SOP.:* NP Alias '[]
forall k (a :: k -> *). NP a '[]
Nil
-- | >>> printSQL (#jimbob :: Alias "jimbob")
-- "jimbob"
instance KnownSymbol alias => RenderSQL (Alias alias) where
  renderSQL :: Alias alias -> ByteString
renderSQL = ByteString -> ByteString
doubleQuoted (ByteString -> ByteString)
-> (Alias alias -> ByteString) -> Alias alias -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
forall a. IsString a => String -> a
fromString (String -> ByteString)
-> (Alias alias -> String) -> Alias alias -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alias alias -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal

-- >>> printSQL (#jimbob :* #kandi :: NP Alias '["jimbob", "kandi"])
-- "jimbob", "kandi"
instance SOP.All KnownSymbol aliases => RenderSQL (NP Alias aliases) where
  renderSQL :: NP Alias aliases -> ByteString
renderSQL
    = [ByteString] -> ByteString
commaSeparated
    ([ByteString] -> ByteString)
-> (NP Alias aliases -> [ByteString])
-> NP Alias aliases
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NP (K ByteString) aliases -> [ByteString]
forall k l (h :: (k -> *) -> l -> *) (xs :: l) a.
(HCollapse h, SListIN h xs) =>
h (K a) xs -> CollapseTo h a
SOP.hcollapse
    (NP (K ByteString) aliases -> [ByteString])
-> (NP Alias aliases -> NP (K ByteString) aliases)
-> NP Alias aliases
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy KnownSymbol
-> (forall (a :: Symbol).
    KnownSymbol a =>
    Alias a -> K ByteString a)
-> NP Alias aliases
-> NP (K ByteString) aliases
forall k l (h :: (k -> *) -> l -> *) (c :: k -> Constraint)
       (xs :: l) (proxy :: (k -> Constraint) -> *) (f :: k -> *)
       (f' :: k -> *).
(AllN (Prod h) c xs, HAp h) =>
proxy c
-> (forall (a :: k). c a => f a -> f' a) -> h f xs -> h f' xs
SOP.hcmap (Proxy KnownSymbol
forall k (t :: k). Proxy t
SOP.Proxy @KnownSymbol) (ByteString -> K ByteString a
forall k a (b :: k). a -> K a b
SOP.K (ByteString -> K ByteString a)
-> (Alias a -> ByteString) -> Alias a -> K ByteString a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alias a -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL)

-- | The `As` operator is used to name an expression. `As` is like a demoted
-- version of `:::`.
--
-- >>> Just "hello" `As` #hi :: Aliased Maybe ("hi" ::: String)
-- As (Just "hello") Alias
data Aliased expression aliased where
  As
    :: KnownSymbol alias
    => expression ty
    -> Alias alias
    -> Aliased expression (alias ::: ty)
deriving instance Show (expression ty)
  => Show (Aliased expression (alias ::: ty))
deriving instance Eq (expression ty)
  => Eq (Aliased expression (alias ::: ty))
deriving instance Ord (expression ty)
  => Ord (Aliased expression (alias ::: ty))
instance (alias0 ~ alias1, alias0 ~ alias2, KnownSymbol alias2)
  => IsLabel alias0 (Aliased Alias (alias1 ::: alias2)) where
    fromLabel :: Aliased Alias (alias1 ::: alias2)
fromLabel = forall a. IsLabel alias2 a => a
forall (x :: Symbol) a. IsLabel x a => a
fromLabel @alias2 Alias alias2 -> Alias alias1 -> Aliased Alias (alias1 ::: alias2)
forall k (alias :: Symbol) (expression :: k -> *) (ty :: k).
KnownSymbol alias =>
expression ty -> Alias alias -> Aliased expression (alias ::: ty)
`As` forall a. IsLabel alias1 a => a
forall (x :: Symbol) a. IsLabel x a => a
fromLabel @alias1

-- | The `Aliasable` class provides a way to scrap your `Nil`s
-- in an `NP` list of `Aliased` expressions.
class KnownSymbol alias => Aliasable alias expression aliased
  | aliased -> expression
  , aliased -> alias
  where as :: expression -> Alias alias -> aliased
instance (KnownSymbol alias, aliased ~ (alias ::: ty)) => Aliasable alias
  (expression ty)
  (Aliased expression aliased)
    where
      as :: expression ty -> Alias alias -> Aliased expression aliased
as = expression ty -> Alias alias -> Aliased expression aliased
forall k (alias :: Symbol) (expression :: k -> *) (ty :: k).
KnownSymbol alias =>
expression ty -> Alias alias -> Aliased expression (alias ::: ty)
As
instance (KnownSymbol alias, tys ~ '[alias ::: ty]) => Aliasable alias
  (expression ty)
  (NP (Aliased expression) tys)
    where
      expression ty
expression `as` Alias alias
alias = expression ty
expression expression ty -> Alias alias -> Aliased expression (alias ::: ty)
forall k (alias :: Symbol) (expression :: k -> *) (ty :: k).
KnownSymbol alias =>
expression ty -> Alias alias -> Aliased expression (alias ::: ty)
`As` Alias alias
alias Aliased expression (alias ::: ty)
-> NP (Aliased expression) '[]
-> NP (Aliased expression) '[alias ::: ty]
forall k (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
SOP.:* NP (Aliased expression) '[]
forall k (a :: k -> *). NP a '[]
Nil

-- | >>> let renderMaybe = fromString . maybe "Nothing" (const "Just")
-- >>> renderAliased renderMaybe (Just (3::Int) `As` #an_int)
-- "Just AS \"an_int\""
renderAliased
  :: (forall ty. expression ty -> ByteString)
  -> Aliased expression aliased
  -> ByteString
renderAliased :: (forall (ty :: k). expression ty -> ByteString)
-> Aliased expression aliased -> ByteString
renderAliased forall (ty :: k). expression ty -> ByteString
render (expression ty
expression `As` Alias alias
alias) =
  expression ty -> ByteString
forall (ty :: k). expression ty -> ByteString
render expression ty
expression ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
" AS " ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Alias alias -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL Alias alias
alias

-- | Map a function over an `Aliased` expression.
mapAliased
  :: (expr x -> expr y)
  -> Aliased expr (alias ::: x)
  -> Aliased expr (alias ::: y)
mapAliased :: (expr x -> expr y)
-> Aliased expr (alias ::: x) -> Aliased expr (alias ::: y)
mapAliased expr x -> expr y
f (expr ty
x `As` Alias alias
alias) = expr x -> expr y
f expr x
expr ty
x expr y -> Alias alias -> Aliased expr (alias ::: y)
forall k (alias :: Symbol) (expression :: k -> *) (ty :: k).
KnownSymbol alias =>
expression ty -> Alias alias -> Aliased expression (alias ::: ty)
`As` Alias alias
alias

-- | @HasUnique alias fields field@ is a constraint that proves that
-- @fields@ is a singleton of @alias ::: field@.
type HasUnique alias fields field = fields ~ '[alias ::: field]

-- | @Has alias fields field@ is a constraint that proves that
-- @fields@ has a field of @alias ::: field@, inferring @field@
-- from @alias@ and @fields@.
type Has (alias :: Symbol) (fields :: [(Symbol,kind)]) (field :: kind)
  = HasErr fields alias fields field

{- | `HasErr` is like `Has` except it also retains the original
list of fields being searched, so that error messages are more
useful.
-}
class KnownSymbol alias =>
  HasErr err (alias :: Symbol) (fields :: [(Symbol,kind)]) (field :: kind)
  | alias fields -> field where
instance {-# OVERLAPPING #-} (KnownSymbol alias, field0 ~ field1)
  => HasErr err alias (alias ::: field0 ': fields) field1
instance {-# OVERLAPPABLE #-} (KnownSymbol alias, HasErr err alias fields field)
  => HasErr err alias (field' ': fields) field

{-| @HasIn fields (alias ::: field)@ is a constraint that proves that
@fields@ has a field of @alias ::: field@. It is used in @UPDATE@s to
choose which subfields to update.
-}
class HasIn fields field where
instance (Has alias fields field) => HasIn fields (alias ::: field) where

-- | `HasAll` extends `Has` to take lists of @aliases@ and @fields@ and infer
-- a list of @subfields@.
class
  ( SOP.All KnownSymbol aliases
  ) => HasAll
    (aliases :: [Symbol])
    (fields :: [(Symbol,kind)])
    (subfields :: [(Symbol,kind)])
    | aliases fields -> subfields where
instance {-# OVERLAPPING #-} HasAll '[] fields '[]
instance {-# OVERLAPPABLE #-}
  (Has alias fields field, HasAll aliases fields subfields)
  => HasAll (alias ': aliases) fields (alias ::: field ': subfields)

-- | Analagous to `IsLabel`, the constraint
-- `IsQualified` defines `!` for a column alias qualified
-- by a table alias.
class IsQualified qualifier alias expression where
  (!) :: Alias qualifier -> Alias alias -> expression
  infixl 9 !
instance IsQualified qualifier alias (Alias qualifier, Alias alias) where
  (!) = (,)

{-| `QualifiedAlias`es enables multi-schema support by allowing a reference
to a `Squeal.PostgreSQL.Type.Schema.Table`, `Squeal.PostgreSQL.Type.Schema.Typedef`
or `Squeal.PostgreSQL.Type.Schema.View` to be qualified by their schemas. By default,
a qualifier of @public@ is provided.

>>> :{
let
  alias1 :: QualifiedAlias "sch" "tab"
  alias1 = #sch ! #tab
  alias2 :: QualifiedAlias "public" "vw"
  alias2 = #vw
in printSQL alias1 >> printSQL alias2
:}
"sch"."tab"
"vw"
-}
data QualifiedAlias (qualifier :: Symbol) (alias :: Symbol) = QualifiedAlias
  deriving (QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
(QualifiedAlias qualifier alias
 -> QualifiedAlias qualifier alias -> Bool)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias -> Bool)
-> Eq (QualifiedAlias qualifier alias)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
/= :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
$c/= :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
== :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
$c== :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
Eq,(forall x.
 QualifiedAlias qualifier alias
 -> Rep (QualifiedAlias qualifier alias) x)
-> (forall x.
    Rep (QualifiedAlias qualifier alias) x
    -> QualifiedAlias qualifier alias)
-> Generic (QualifiedAlias qualifier alias)
forall x.
Rep (QualifiedAlias qualifier alias) x
-> QualifiedAlias qualifier alias
forall x.
QualifiedAlias qualifier alias
-> Rep (QualifiedAlias qualifier alias) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (qualifier :: Symbol) (alias :: Symbol) x.
Rep (QualifiedAlias qualifier alias) x
-> QualifiedAlias qualifier alias
forall (qualifier :: Symbol) (alias :: Symbol) x.
QualifiedAlias qualifier alias
-> Rep (QualifiedAlias qualifier alias) x
$cto :: forall (qualifier :: Symbol) (alias :: Symbol) x.
Rep (QualifiedAlias qualifier alias) x
-> QualifiedAlias qualifier alias
$cfrom :: forall (qualifier :: Symbol) (alias :: Symbol) x.
QualifiedAlias qualifier alias
-> Rep (QualifiedAlias qualifier alias) x
GHC.Generic,Eq (QualifiedAlias qualifier alias)
Eq (QualifiedAlias qualifier alias)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias -> Ordering)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias -> Bool)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias -> Bool)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias -> Bool)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias -> Bool)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias)
-> (QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias
    -> QualifiedAlias qualifier alias)
-> Ord (QualifiedAlias qualifier alias)
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Ordering
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> QualifiedAlias qualifier alias
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (qualifier :: Symbol) (alias :: Symbol).
Eq (QualifiedAlias qualifier alias)
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Ordering
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> QualifiedAlias qualifier alias
min :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> QualifiedAlias qualifier alias
$cmin :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> QualifiedAlias qualifier alias
max :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> QualifiedAlias qualifier alias
$cmax :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> QualifiedAlias qualifier alias
>= :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
$c>= :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
> :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
$c> :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
<= :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
$c<= :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
< :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
$c< :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Bool
compare :: QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Ordering
$ccompare :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
-> QualifiedAlias qualifier alias -> Ordering
$cp1Ord :: forall (qualifier :: Symbol) (alias :: Symbol).
Eq (QualifiedAlias qualifier alias)
Ord,Int -> QualifiedAlias qualifier alias -> ShowS
[QualifiedAlias qualifier alias] -> ShowS
QualifiedAlias qualifier alias -> String
(Int -> QualifiedAlias qualifier alias -> ShowS)
-> (QualifiedAlias qualifier alias -> String)
-> ([QualifiedAlias qualifier alias] -> ShowS)
-> Show (QualifiedAlias qualifier alias)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (qualifier :: Symbol) (alias :: Symbol).
Int -> QualifiedAlias qualifier alias -> ShowS
forall (qualifier :: Symbol) (alias :: Symbol).
[QualifiedAlias qualifier alias] -> ShowS
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias -> String
showList :: [QualifiedAlias qualifier alias] -> ShowS
$cshowList :: forall (qualifier :: Symbol) (alias :: Symbol).
[QualifiedAlias qualifier alias] -> ShowS
show :: QualifiedAlias qualifier alias -> String
$cshow :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias -> String
showsPrec :: Int -> QualifiedAlias qualifier alias -> ShowS
$cshowsPrec :: forall (qualifier :: Symbol) (alias :: Symbol).
Int -> QualifiedAlias qualifier alias -> ShowS
Show,QualifiedAlias qualifier alias -> ()
(QualifiedAlias qualifier alias -> ())
-> NFData (QualifiedAlias qualifier alias)
forall a. (a -> ()) -> NFData a
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias -> ()
rnf :: QualifiedAlias qualifier alias -> ()
$crnf :: forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias -> ()
NFData)
instance (q ~ q', a ~ a') => IsQualified q a (QualifiedAlias q' a') where
  Alias q
_ ! :: Alias q -> Alias a -> QualifiedAlias q' a'
! Alias a
_ = QualifiedAlias q' a'
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
QualifiedAlias
instance (q' ~ "public", a ~ a') => IsLabel a (QualifiedAlias q' a') where
  fromLabel :: QualifiedAlias q' a'
fromLabel = QualifiedAlias q' a'
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
QualifiedAlias
instance (q0 ~ q1, a0 ~ a1, a1 ~ a2, KnownSymbol a2) =>
  IsQualified q0 a0 (Aliased (QualifiedAlias q1) (a1 ::: a2)) where
    Alias q0
_ ! :: Alias q0 -> Alias a0 -> Aliased (QualifiedAlias q1) (a1 ::: a2)
! Alias a0
_ = QualifiedAlias q1 a2
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
QualifiedAlias QualifiedAlias q1 a2
-> Alias a1 -> Aliased (QualifiedAlias q1) (a1 ::: a2)
forall k (alias :: Symbol) (expression :: k -> *) (ty :: k).
KnownSymbol alias =>
expression ty -> Alias alias -> Aliased expression (alias ::: ty)
`As` Alias a1
forall (alias :: Symbol). Alias alias
Alias
instance (q ~ "public", a0 ~ a1, a1 ~ a2, KnownSymbol a2) =>
  IsLabel a0 (Aliased (QualifiedAlias q) (a1 ::: a2)) where
    fromLabel :: Aliased (QualifiedAlias q) (a1 ::: a2)
fromLabel = QualifiedAlias q a2
forall (qualifier :: Symbol) (alias :: Symbol).
QualifiedAlias qualifier alias
QualifiedAlias QualifiedAlias q a2
-> Alias a1 -> Aliased (QualifiedAlias q) (a1 ::: a2)
forall k (alias :: Symbol) (expression :: k -> *) (ty :: k).
KnownSymbol alias =>
expression ty -> Alias alias -> Aliased expression (alias ::: ty)
`As` Alias a1
forall (alias :: Symbol). Alias alias
Alias

instance (KnownSymbol q, KnownSymbol a)
  => RenderSQL (QualifiedAlias q a) where
    renderSQL :: QualifiedAlias q a -> ByteString
renderSQL QualifiedAlias q a
_ =
      let
        qualifier :: ByteString
qualifier = Alias q -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL (Alias q
forall (alias :: Symbol). Alias alias
Alias @q)
        alias :: ByteString
alias = Alias a -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL (Alias a
forall (alias :: Symbol). Alias alias
Alias @a)
      in
        if ByteString
qualifier ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
"\"public\"" then ByteString
alias else ByteString
qualifier ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"." ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
alias