squeal-postgresql-0.9.1.3: src/Squeal/PostgreSQL/Query/From.hs
{-|
Module: Squeal.PostgreSQL.Query.From
Description: from clauses
Copyright: (c) Eitan Chatav, 2019
Maintainer: eitan@morphism.tech
Stability: experimental
from clauses
-}
{-# LANGUAGE
ConstraintKinds
, DeriveGeneric
, DerivingStrategies
, FlexibleContexts
, FlexibleInstances
, GADTs
, GeneralizedNewtypeDeriving
, LambdaCase
, MultiParamTypeClasses
, OverloadedLabels
, OverloadedStrings
, QuantifiedConstraints
, ScopedTypeVariables
, StandaloneDeriving
, TypeApplications
, TypeFamilies
, DataKinds
, PolyKinds
, TypeOperators
, RankNTypes
, UndecidableInstances
#-}
module Squeal.PostgreSQL.Query.From
( -- * From Clause
FromClause (..)
, table
, subquery
, view
, common
) where
import Control.DeepSeq
import Data.ByteString (ByteString)
import qualified GHC.Generics as GHC
import Squeal.PostgreSQL.Type.Alias
import Squeal.PostgreSQL.Query
import Squeal.PostgreSQL.Render
import Squeal.PostgreSQL.Type.List
import Squeal.PostgreSQL.Type.Schema
-- $setup
-- >>> import Squeal.PostgreSQL
{-----------------------------------------
FROM clauses
-----------------------------------------}
{- |
A `FromClause` can be a table name, or a derived table such
as a subquery, a @JOIN@ construct, or complex combinations of these.
-}
newtype FromClause
(lat :: FromType)
(with :: FromType)
(db :: SchemasType)
(params :: [NullType])
(from :: FromType)
= UnsafeFromClause { renderFromClause :: ByteString }
deriving stock (GHC.Generic,Show,Eq,Ord)
deriving newtype (NFData)
instance RenderSQL (FromClause lat with db params from) where
renderSQL = renderFromClause
-- | A real `table` is a table from the database.
table
:: (Has sch db schema, Has tab schema ('Table table))
=> Aliased (QualifiedAlias sch) (alias ::: tab) -- ^ (renamable) table alias
-> FromClause lat with db params '[alias ::: TableToRow table]
table (tab `As` alias) = UnsafeFromClause $
renderSQL tab <+> "AS" <+> renderSQL alias
{- | `subquery` derives a table from a `Query`.
The subquery may not reference columns provided by preceding `FromClause` items.
Use `Squeal.PostgreSQL.Query.From.Join.JoinLateral`
if the subquery must reference columns provided by preceding `FromClause` items.
-}
subquery
:: Aliased (Query lat with db params) query
-- ^ aliased `Query`
-> FromClause lat with db params '[query]
subquery = UnsafeFromClause . renderAliased (parenthesized . renderSQL)
-- | `view` derives a table from a `View`.
view
:: (Has sch db schema, Has vw schema ('View view))
=> Aliased (QualifiedAlias sch) (alias ::: vw) -- ^ (renamable) view alias
-> FromClause lat with db params '[alias ::: view]
view (vw `As` alias) = UnsafeFromClause $
renderSQL vw <+> "AS" <+> renderSQL alias
-- | `common` derives a table from a common table expression.
common
:: Has cte with common
=> Aliased Alias (alias ::: cte) -- ^ (renamable) common table expression alias
-> FromClause lat with db params '[alias ::: common]
common (cte `As` alias) = UnsafeFromClause $
renderSQL cte <+> "AS" <+> renderSQL alias
instance Additional (FromClause lat with db params) where
also right left = UnsafeFromClause $
renderSQL left <> ", " <> renderSQL right