-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Squeal PostgreSQL Library
--   
--   Squeal is a type-safe embedding of PostgreSQL in Haskell
@package squeal-postgresql
@version 0.1.1.4


-- | Pretty print helper functions.
module Squeal.PostgreSQL.Prettyprint

-- | Parenthesize a <a>ByteString</a>.
parenthesized :: ByteString -> ByteString

-- | Concatenate two <a>ByteString</a>s with a space between.
(<+>) :: ByteString -> ByteString -> ByteString

-- | Comma separate a list of <a>ByteString</a>s.
commaSeparated :: [ByteString] -> ByteString

-- | Comma separate the renderings of a heterogeneous list.
renderCommaSeparated :: SListI xs => (forall x. expression x -> ByteString) -> NP expression xs -> ByteString

-- | Comma separate the <a>Maybe</a> renderings of a heterogeneous list,
--   dropping <a>Nothing</a>s.
renderCommaSeparatedMaybe :: SListI xs => (forall x. expression x -> Maybe ByteString) -> NP expression xs -> ByteString

-- | Render a promoted <a>Nat</a>.
renderNat :: KnownNat n => proxy n -> ByteString


-- | Embedding of PostgreSQL type and alias system
module Squeal.PostgreSQL.Schema

-- | <a>PGType</a> is the promoted datakind of PostgreSQL types.
data PGType

-- | logical Boolean (true/false)
PGbool :: PGType

-- | signed two-byte integer
PGint2 :: PGType

-- | signed four-byte integer
PGint4 :: PGType

-- | signed eight-byte integer
PGint8 :: PGType

-- | arbitrary precision numeric type
PGnumeric :: PGType

-- | single precision floating-point number (4 bytes)
PGfloat4 :: PGType

-- | double precision floating-point number (8 bytes)
PGfloat8 :: PGType

-- | fixed-length character string
PGchar :: Nat -> PGType

-- | variable-length character string
PGvarchar :: Nat -> PGType

-- | variable-length character string
PGtext :: PGType

-- | binary data ("byte array")
PGbytea :: PGType

-- | date and time (no time zone)
PGtimestamp :: PGType

-- | date and time, including time zone
PGtimestamptz :: PGType

-- | calendar date (year, month, day)
PGdate :: PGType

-- | time of day (no time zone)
PGtime :: PGType

-- | time of day, including time zone
PGtimetz :: PGType

-- | time span
PGinterval :: PGType

-- | universally unique identifier
PGuuid :: PGType

-- | IPv4 or IPv6 host address
PGinet :: PGType

-- | textual JSON data
PGjson :: PGType

-- | binary JSON data, decomposed
PGjsonb :: PGType

-- | an escape hatch for unsupported PostgreSQL types
UnsafePGType :: Symbol -> PGType

-- | <a>NullityType</a> encodes the potential presence or definite absence
--   of a <tt>NULL</tt> allowing operations which are sensitive to such to
--   be well typed.
data NullityType

-- | <tt>NULL</tt> may be present
Null :: PGType -> NullityType

-- | <tt>NULL</tt> is absent
NotNull :: PGType -> NullityType

-- | <a>ColumnType</a> encodes the allowance of <tt>DEFAULT</tt> and the
--   only way to generate an <a>Optional</a> <a>Expression</a> is to use
--   <a>def</a>, <a>unDef</a> or <a>param</a>.
data ColumnType

-- | <tt>DEFAULT</tt> is allowed
Optional :: NullityType -> ColumnType

-- | <tt>DEFAULT</tt> is not allowed
Required :: NullityType -> ColumnType

-- | <a>ColumnsType</a> is a kind synonym for a row of <a>ColumnType</a>s.
type ColumnsType = [(Symbol, ColumnType)]

-- | <a>TablesType</a> is a kind synonym for a row of <a>ColumnsType</a>s.
--   It is used as a kind for both a schema, a disjoint union of tables,
--   and a joined table <a>FromClause</a>, a product of tables.
type TablesType = [(Symbol, ColumnsType)]

-- | <a>Grouping</a> is an auxiliary namespace, created by <tt>GROUP
--   BY</tt> clauses (<a>group</a>), and used for typesafe aggregation
data Grouping
Ungrouped :: Grouping
Grouped :: [(Symbol, Symbol)] -> Grouping

-- | <a>PGNum</a> is a constraint on <a>PGType</a> whose <a>Expression</a>s
--   have a <a>Num</a> constraint.
type PGNum ty = In ty '[ 'PGint2, 'PGint4, 'PGint8, 'PGnumeric, 'PGfloat4, 'PGfloat8]

-- | <a>PGIntegral</a> is a constraint on <a>PGType</a> whose
--   <a>Expression</a>s have <a>div_</a> and <a>mod_</a> functions.
type PGIntegral ty = In ty '[ 'PGint2,  'PGint4,  'PGint8]

-- | <a>PGFloating</a> is a constraint on <a>PGType</a> whose
--   <a>Expression</a>s have <a>Fractional</a> and <a>Floating</a>
--   constraints.
type PGFloating ty = In ty '[ 'PGfloat4,  'PGfloat8,  'PGnumeric]

-- | <a>:::</a> is like a promoted version of <a>As</a>, a type level pair
--   between an alias and some type, usually a column alias and a
--   <a>ColumnType</a> or a table alias and a <a>ColumnsType</a>.
type (:::) (alias :: Symbol) (ty :: polykind) = '(alias, ty)

-- | <a>Alias</a>es are proxies for a type level string or <a>Symbol</a>
--   and have an <a>IsLabel</a> instance so that with
--   <tt>-XOverloadedLabels</tt>
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedLabels
--   
--   &gt;&gt;&gt; #foobar :: Alias "foobar"
--   Alias
--   </pre>
data Alias (alias :: Symbol)
Alias :: Alias

-- | <pre>
--   &gt;&gt;&gt; renderAlias #alias
--   "alias"
--   </pre>
renderAlias :: KnownSymbol alias => Alias alias -> ByteString

-- | The <a>As</a> operator is used to name an expression. <a>As</a> is
--   like a demoted version of <a>:::</a>.
--   
--   <pre>
--   &gt;&gt;&gt; Just "hello" `As` #hi :: Aliased Maybe ("hi" ::: String)
--   As (Just "hello") Alias
--   </pre>
data Aliased expression aliased
[As] :: KnownSymbol alias => expression ty -> Alias alias -> Aliased expression (alias ::: ty)

-- | <pre>
--   &gt;&gt;&gt; let renderMaybe = fromString . maybe "Nothing" (const "Just")
--   
--   &gt;&gt;&gt; renderAliased renderMaybe (Just (3::Int) `As` #an_int)
--   "Just AS an_int"
--   </pre>
renderAliased :: (forall ty. expression ty -> ByteString) -> Aliased expression aliased -> ByteString
class IsLabel (x :: Symbol) a
fromLabel :: IsLabel x a => a

-- | Analagous to <a>IsLabel</a>, the constraint <a>IsTableColumn</a>
--   defines <a>!</a> for a column alias qualified by a table alias.
class IsTableColumn table column expression
(!) :: IsTableColumn table column expression => Alias table -> Alias column -> expression

-- | <tt>In x xs</tt> is a constraint that proves that <tt>x</tt> is in
--   <tt>xs</tt>.

-- | <tt>HasUnique alias xs x</tt> is a constraint that proves that
--   <tt>xs</tt> is a singleton of <tt>alias ::: x</tt>.
type HasUnique alias xs x = xs ~ '[alias ::: x]

-- | <a>BaseType</a> forgets about <tt>NULL</tt> and <tt>DEFAULT</tt>

-- | <a>SameTypes</a> is a constraint that proves two <a>ColumnsType</a>s
--   have the same length and the same <a>ColumnType</a>s.

-- | <a>AllNotNull</a> is a constraint that proves a <a>ColumnsType</a> has
--   no <tt>NULL</tt>s.

-- | <a>NotAllNull</a> is a constraint that proves a <a>ColumnsType</a> has
--   some <tt>NOT NULL</tt>.

-- | <a>NullifyType</a> is an idempotent that nullifies a
--   <a>ColumnType</a>.

-- | <a>NullifyColumns</a> is an idempotent that nullifies a
--   <a>ColumnsType</a>.

-- | <a>NullifyTables</a> is an idempotent that nullifies a
--   <a>TablesType</a> used to nullify the left or right hand side of an
--   outer join in a <a>FromClause</a>.

-- | <a>Join</a> is simply promoted <a>++</a> and is used in <tt>JOIN</tt>s
--   in <a>FromClause</a>s.

-- | <tt>Create alias x xs</tt> adds <tt>alias ::: x</tt> to the end of
--   <tt>xs</tt> and is used in <a>createTable</a> statements and in
--   <tt>ALTER TABLE</tt> <a>addColumnDefault</a> and <a>addColumnNull</a>
--   statements.

-- | <tt>Drop alias xs</tt> removes the type associated with <tt>alias</tt>
--   in <tt>xs</tt> and is used in <a>dropTable</a> statements and in
--   <tt>ALTER TABLE</tt> <a>dropColumn</a> statements.

-- | <tt>Alter alias xs x</tt> replaces the type associated with an
--   <tt>alias</tt> in <tt>xs</tt> with the type <tt>x</tt> and is used in
--   <a>alterTable</a> and <a>alterColumn</a>.

-- | <tt>Rename alias0 alias1 xs</tt> replaces the alias <tt>alias0</tt> by
--   <tt>alias1</tt> in <tt>xs</tt> and is used in <a>alterTableRename</a>
--   and <a>renameColumn</a>.

-- | A <a>SameField</a> constraint is an equality constraint on a
--   <a>FieldInfo</a> and the column alias in a <a>:::</a> pair.
class SameField (fieldInfo :: FieldInfo) (fieldty :: (Symbol, ColumnType))

-- | A <a>SameFields</a> constraint proves that a <a>DatatypeInfo</a> of a
--   record type has the same field names as the column aliases of a
--   <a>ColumnsType</a>.
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Schema.Alias alias)
instance GHC.Show.Show (Squeal.PostgreSQL.Schema.Alias alias)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Alias alias)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Schema.Alias alias)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Alias alias)
instance forall polykind (expression :: polykind -> *) (ty :: polykind) (alias :: GHC.Types.Symbol). GHC.Show.Show (expression ty) => GHC.Show.Show (Squeal.PostgreSQL.Schema.Aliased polykind expression ((Squeal.PostgreSQL.Schema.:::) polykind alias ty))
instance forall polykind (expression :: polykind -> *) (ty :: polykind) (alias :: GHC.Types.Symbol). GHC.Classes.Eq (expression ty) => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Aliased polykind expression ((Squeal.PostgreSQL.Schema.:::) polykind alias ty))
instance forall polykind (expression :: polykind -> *) (ty :: polykind) (alias :: GHC.Types.Symbol). GHC.Classes.Ord (expression ty) => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Aliased polykind expression ((Squeal.PostgreSQL.Schema.:::) polykind alias ty))
instance field ~ column => Squeal.PostgreSQL.Schema.SameField ('Generics.SOP.Type.Metadata.FieldInfo field) ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column ty)
instance Squeal.PostgreSQL.Schema.IsTableColumn table column (Squeal.PostgreSQL.Schema.Alias table, Squeal.PostgreSQL.Schema.Alias column)
instance alias1 ~ alias2 => GHC.OverloadedLabels.IsLabel alias1 (Squeal.PostgreSQL.Schema.Alias alias2)


-- | Squeal expressions are the atoms used to build statements.
module Squeal.PostgreSQL.Expression

-- | <a>Expression</a>s are used in a variety of contexts, such as in the
--   target list of the <tt>select</tt> command, as new column values in
--   <tt>insertInto</tt> or <tt>update</tt>, or in search <a>Condition</a>s
--   in a number of commands.
--   
--   The expression syntax allows the calculation of values from primitive
--   expression using arithmetic, logical, and other operations.
newtype Expression (tables :: TablesType) (grouping :: Grouping) (params :: [ColumnType]) (ty :: ColumnType)
UnsafeExpression :: ByteString -> Expression
[renderExpression] :: Expression -> ByteString

-- | A <a>HasParameter</a> constraint is used to indicate a value that is
--   supplied externally to a SQL statement. <a>manipulateParams</a>,
--   <a>queryParams</a> and <a>traversePrepared</a> support specifying data
--   values separately from the SQL command string, in which case
--   <a>param</a>s are used to refer to the out-of-line data values.
class (PGTyped (BaseType ty), KnownNat n) => HasParameter (n :: Nat) params ty | n params -> ty
param :: HasParameter n params ty => Expression tables grouping params ty

-- | A <a>HasColumn</a> constraint indicates an unqualified column
--   reference. <a>getColumn</a> can only be unambiguous when the
--   <tt>TableExpression</tt> the column references is unique, in which
--   case the column may be referenced using <tt>-XOverloadedLabels</tt>.
--   Otherwise, combined with a <a>HasTable</a> constraint, the qualified
--   column reference operator <a>!</a> may be used.
class KnownSymbol column => HasColumn column columns ty | column columns -> ty
getColumn :: (HasColumn column columns ty, HasUnique table tables columns) => Alias column -> Expression tables  'Ungrouped params ty

-- | A <a>Column</a> is a witness to a <a>HasColumn</a> constraint. It's
--   used in <a>unique</a> and other <a>TableConstraint</a>s to witness a
--   subcolumns relationship.
data Column (columns :: ColumnsType) (columnty :: (Symbol, ColumnType))
[Column] :: HasColumn column columns ty => Alias column -> Column columns (column ::: ty)

-- | Render a <a>Column</a>.
renderColumn :: Column columns columnty -> ByteString

-- | A <a>GroupedBy</a> constraint indicates that a table qualified column
--   is a member of the auxiliary namespace created by <tt>GROUP BY</tt>
--   clauses and thus, may be called in an output <a>Expression</a> without
--   aggregating.
class (KnownSymbol table, KnownSymbol column) => GroupedBy table column bys
getGroup1 :: (GroupedBy table column bys, HasUnique table tables columns, HasColumn column columns ty) => Alias column -> Expression tables ( 'Grouped bys) params ty
getGroup2 :: (GroupedBy table column bys, HasTable table tables columns, HasColumn column columns ty) => Alias table -> Alias column -> Expression tables ( 'Grouped bys) params ty

-- | <pre>
--   &gt;&gt;&gt; renderExpression def
--   "DEFAULT"
--   </pre>
def :: Expression '[]  'Ungrouped params ( 'Optional (nullity ty))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unDef false
--   "FALSE"
--   </pre>
unDef :: Expression '[]  'Ungrouped params ( 'Required (nullity ty)) -> Expression '[]  'Ungrouped params ( 'Optional (nullity ty))

-- | analagous to <a>Nothing</a>
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ null_
--   "NULL"
--   </pre>
null_ :: Expression tables grouping params (optionality ( 'Null ty))

-- | analagous to <a>Just</a>
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true
--   "TRUE"
--   </pre>
unNull :: Expression tables grouping params (optionality ( 'NotNull ty)) -> Expression tables grouping params (optionality ( 'Null ty))

-- | return the leftmost value which is not NULL
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ coalesce [null_, unNull true] false
--   "COALESCE(NULL, TRUE, FALSE)"
--   </pre>
coalesce :: [Expression tables grouping params ( 'Required ( 'Null ty))] -> Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'NotNull ty))

-- | analagous to <tt>fromMaybe</tt> using <tt>COALESCE</tt>
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ fromNull true null_
--   "COALESCE(NULL, TRUE)"
--   </pre>
fromNull :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'Null ty)) -> Expression tables grouping params ( 'Required ( 'NotNull ty))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ null_ &amp; isNull
--   "NULL IS NULL"
--   </pre>
isNull :: Expression tables grouping params ( 'Required ( 'Null ty)) -> Condition tables grouping params

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ null_ &amp; isn'tNull
--   "NULL IS NOT NULL"
--   </pre>
isn'tNull :: Expression tables grouping params ( 'Required ( 'Null ty)) -> Condition tables grouping params

-- | analagous to <a>maybe</a> using <tt>IS NULL</tt>
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ matchNull true not_ null_
--   "CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END"
--   </pre>
matchNull :: Expression tables grouping params ( 'Required nullty) -> (Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required nullty)) -> Expression tables grouping params ( 'Required ( 'Null ty)) -> Expression tables grouping params ( 'Required nullty)

-- | right inverse to <a>fromNull</a>, if its arguments are equal then
--   <a>nullIf</a> gives <tt>NULL</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XTypeApplications -XDataKinds
--   
--   &gt;&gt;&gt; renderExpression @_ @_ @'[_] $ fromNull false (nullIf false (param @1))
--   "COALESCE(NULL IF (FALSE, ($1 :: bool)), FALSE)"
--   </pre>
nullIf :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'Null ty))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unsafeBinaryOp "OR" true false
--   "(TRUE OR FALSE)"
--   </pre>
unsafeBinaryOp :: ByteString -> Expression tables grouping params ( 'Required ty0) -> Expression tables grouping params ( 'Required ty1) -> Expression tables grouping params ( 'Required ty2)

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unsafeUnaryOp "NOT" true
--   "(NOT TRUE)"
--   </pre>
unsafeUnaryOp :: ByteString -> Expression tables grouping params ( 'Required ty0) -> Expression tables grouping params ( 'Required ty1)

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unsafeFunction "f" true
--   "f(TRUE)"
--   </pre>
unsafeFunction :: ByteString -> Expression tables grouping params ( 'Required xty) -> Expression tables grouping params ( 'Required yty)

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ atan2_ pi 2
--   "atan2(pi(), 2)"
--   </pre>
atan2_ :: PGFloating float => Expression tables grouping params ( 'Required (nullity float)) -> Expression tables grouping params ( 'Required (nullity float)) -> Expression tables grouping params ( 'Required (nullity float))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ true &amp; cast int4
--   "(TRUE :: int4)"
--   </pre>
cast :: TypeExpression ( 'Required ( 'Null ty1)) -> Expression tables grouping params ( 'Required (nullity ty0)) -> Expression tables grouping params ( 'Required (nullity ty1))

-- | integer division, truncates the result
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_(_ 'PGint2)) $ 5 `quot_` 2
--   "(5 / 2)"
--   </pre>
quot_ :: PGIntegral int => Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int))

-- | remainder upon integer division
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ 5 `rem_` 2
--   "(5 % 2)"
--   </pre>
rem_ :: PGIntegral int => Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ trunc pi
--   "trunc(pi())"
--   </pre>
trunc :: PGFloating frac => Expression tables grouping params ( 'Required (nullity frac)) -> Expression tables grouping params ( 'Required (nullity frac))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ round_ pi
--   "round(pi())"
--   </pre>
round_ :: PGFloating frac => Expression tables grouping params ( 'Required (nullity frac)) -> Expression tables grouping params ( 'Required (nullity frac))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ ceiling_ pi
--   "ceiling(pi())"
--   </pre>
ceiling_ :: PGFloating frac => Expression tables grouping params ( 'Required (nullity frac)) -> Expression tables grouping params ( 'Required (nullity frac))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @'[_] $ greatest currentTimestamp [param @1]
--   "GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))"
--   </pre>
greatest :: Expression tables grouping params ( 'Required nullty) -> [Expression tables grouping params ( 'Required nullty)] -> Expression tables grouping params ( 'Required nullty)

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ least currentTimestamp [null_]
--   "LEAST(CURRENT_TIMESTAMP, NULL)"
--   </pre>
least :: Expression tables grouping params ( 'Required nullty) -> [Expression tables grouping params ( 'Required nullty)] -> Expression tables grouping params ( 'Required nullty)

-- | A <a>Condition</a> is a boolean valued <a>Expression</a>. While SQL
--   allows conditions to have <tt>NULL</tt>, squeal instead chooses to
--   disallow <tt>NULL</tt>, forcing one to handle the case of
--   <tt>NULL</tt> explicitly to produce a <a>Condition</a>.
type Condition tables grouping params = Expression tables grouping params ( 'Required ( 'NotNull  'PGbool))

-- | <pre>
--   &gt;&gt;&gt; renderExpression true
--   "TRUE"
--   </pre>
true :: Condition tables grouping params

-- | <pre>
--   &gt;&gt;&gt; renderExpression false
--   "FALSE"
--   </pre>
false :: Condition tables grouping params

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ not_ true
--   "(NOT TRUE)"
--   </pre>
not_ :: Condition tables grouping params -> Condition tables grouping params

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ true .&amp;&amp; false
--   "(TRUE AND FALSE)"
--   </pre>
(.&&) :: Condition tables grouping params -> Condition tables grouping params -> Condition tables grouping params

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ true .|| false
--   "(TRUE OR FALSE)"
--   </pre>
(.||) :: Condition tables grouping params -> Condition tables grouping params -> Condition tables grouping params

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ caseWhenThenElse [(true, 1), (false, 2)] 3
--   "CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END"
--   </pre>
caseWhenThenElse :: [(Condition tables grouping params, Expression tables grouping params ( 'Required ty))] -> Expression tables grouping params ( 'Required ty) -> Expression tables grouping params ( 'Required ty)

-- | <pre>
--   &gt;&gt;&gt; renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ ifThenElse true 1 0
--   "CASE WHEN TRUE THEN 1 ELSE 0 END"
--   </pre>
ifThenElse :: Condition tables grouping params -> Expression tables grouping params ( 'Required ty) -> Expression tables grouping params ( 'Required ty) -> Expression tables grouping params ( 'Required ty)

-- | Comparison operations like <a>.==</a>, <a>./=</a>, <a>.&gt;</a>,
--   <a>.&gt;=</a>, <a>.&lt;</a> and <a>.&lt;=</a> will produce
--   <tt>NULL</tt>s if one of their arguments is <tt>NULL</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true .== null_
--   "(TRUE = NULL)"
--   </pre>
(.==) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))
infix 4 .==

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true ./= null_
--   "(TRUE &lt;&gt; NULL)"
--   </pre>
(./=) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))
infix 4 ./=

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true .&gt;= null_
--   "(TRUE &gt;= NULL)"
--   </pre>
(.>=) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))
infix 4 .>=

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true .&lt; null_
--   "(TRUE &lt; NULL)"
--   </pre>
(.<) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))
infix 4 .<

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true .&lt;= null_
--   "(TRUE &lt;= NULL)"
--   </pre>
(.<=) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))
infix 4 .<=

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ unNull true .&gt; null_
--   "(TRUE &gt; NULL)"
--   </pre>
(.>) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))
infix 4 .>

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ currentDate
--   "CURRENT_DATE"
--   </pre>
currentDate :: Expression tables grouping params ( 'Required (nullity  'PGdate))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ currentTime
--   "CURRENT_TIME"
--   </pre>
currentTime :: Expression tables grouping params ( 'Required (nullity  'PGtimetz))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ currentTimestamp
--   "CURRENT_TIMESTAMP"
--   </pre>
currentTimestamp :: Expression tables grouping params ( 'Required (nullity  'PGtimestamptz))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ localTime
--   "LOCALTIME"
--   </pre>
localTime :: Expression tables grouping params ( 'Required (nullity  'PGtime))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ localTimestamp
--   "LOCALTIMESTAMP"
--   </pre>
localTimestamp :: Expression tables grouping params ( 'Required (nullity  'PGtimestamp))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ lower "ARRRGGG"
--   "lower(E'ARRRGGG')"
--   </pre>
lower :: Expression tables grouping params ( 'Required (nullity  'PGtext)) -> Expression tables grouping params ( 'Required (nullity  'PGtext))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ upper "eeee"
--   "upper(E'eeee')"
--   </pre>
upper :: Expression tables grouping params ( 'Required (nullity  'PGtext)) -> Expression tables grouping params ( 'Required (nullity  'PGtext))

-- | <pre>
--   &gt;&gt;&gt; renderExpression $ charLength "four"
--   "char_length(E'four')"
--   </pre>
charLength :: Expression tables grouping params ( 'Required (nullity  'PGtext)) -> Expression tables grouping params ( 'Required (nullity  'PGint4))

-- | The <a>like</a> expression returns true if the <tt>string</tt> matches
--   the supplied <tt>pattern</tt>. If <tt>pattern</tt> does not contain
--   percent signs or underscores, then the pattern only represents the
--   string itself; in that case <a>like</a> acts like the equals operator.
--   An underscore (_) in pattern stands for (matches) any single
--   character; a percent sign (%) matches any sequence of zero or more
--   characters.
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression $ "abc" `like` "a%"
--   "(E'abc' LIKE E'a%')"
--   </pre>
like :: Expression tables grouping params ( 'Required (nullity  'PGtext)) -> Expression tables grouping params ( 'Required (nullity  'PGtext)) -> Expression tables grouping params ( 'Required (nullity  'PGbool))

-- | escape hatch to define aggregate functions
unsafeAggregate :: ByteString -> Expression tables  'Ungrouped params ( 'Required xty) -> Expression tables ( 'Grouped bys) params ( 'Required yty)

-- | escape hatch to define aggregate functions over distinct values
unsafeAggregateDistinct :: ByteString -> Expression tables  'Ungrouped params ( 'Required xty) -> Expression tables ( 'Grouped bys) params ( 'Required yty)

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGnumeric)]] $ sum_ #col
--   "sum(col)"
--   </pre>
sum_ :: PGNum ty => Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGnumeric)]] $ sumDistinct #col
--   "sum(DISTINCT col)"
--   </pre>
sumDistinct :: PGNum ty => Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty))

-- | A constraint for <a>PGType</a>s that you can take averages of and the
--   resulting <a>PGType</a>.
class PGAvg ty avg | ty -> avg
avg, avgDistinct :: PGAvg ty avg => Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity avg))
avg, avgDistinct :: PGAvg ty avg => Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity avg))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitAnd #col
--   "bit_and(col)"
--   </pre>
bitAnd :: PGIntegral int => Expression tables  'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitOr #col
--   "bit_or(col)"
--   </pre>
bitOr :: PGIntegral int => Expression tables  'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolAnd #col
--   "bool_and(col)"
--   </pre>
boolAnd :: Expression tables  'Ungrouped params ( 'Required (nullity  'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity  'PGbool))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolOr #col
--   "bool_or(col)"
--   </pre>
boolOr :: Expression tables  'Ungrouped params ( 'Required (nullity  'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity  'PGbool))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitAndDistinct #col
--   "bit_and(DISTINCT col)"
--   </pre>
bitAndDistinct :: PGIntegral int => Expression tables  'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitOrDistinct #col
--   "bit_or(DISTINCT col)"
--   </pre>
bitOrDistinct :: PGIntegral int => Expression tables  'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolAndDistinct #col
--   "bool_and(DISTINCT col)"
--   </pre>
boolAndDistinct :: Expression tables  'Ungrouped params ( 'Required (nullity  'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity  'PGbool))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolOrDistinct #col
--   "bool_or(DISTINCT col)"
--   </pre>
boolOrDistinct :: Expression tables  'Ungrouped params ( 'Required (nullity  'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity  'PGbool))

-- | A special aggregation that does not require an input
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression countStar
--   "count(*)"
--   </pre>
countStar :: Expression tables ( 'Grouped bys) params ( 'Required ( 'NotNull  'PGint8))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Optional _]] $ count #col
--   "count(col)"
--   </pre>
count :: Expression tables  'Ungrouped params ( 'Required ty) -> Expression tables ( 'Grouped bys) params ( 'Required ( 'NotNull  'PGint8))

-- | <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required _]] $ countDistinct #col
--   "count(DISTINCT col)"
--   </pre>
countDistinct :: Expression tables  'Ungrouped params ( 'Required ty) -> Expression tables ( 'Grouped bys) params ( 'Required ( 'NotNull  'PGint8))

-- | synonym for <a>boolAnd</a>
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ every #col
--   "every(col)"
--   </pre>
every :: Expression tables  'Ungrouped params ( 'Required (nullity  'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity  'PGbool))

-- | synonym for <a>boolAndDistinct</a>
--   
--   <pre>
--   &gt;&gt;&gt; renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ everyDistinct #col
--   "every(DISTINCT col)"
--   </pre>
everyDistinct :: Expression tables  'Ungrouped params ( 'Required (nullity  'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity  'PGbool))

-- | minimum and maximum aggregation
max_ :: Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty))

-- | minimum and maximum aggregation
maxDistinct :: Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty))

-- | minimum and maximum aggregation
min_ :: Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty))

-- | minimum and maximum aggregation
minDistinct :: Expression tables  'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty))

-- | A <a>Table</a> from a schema without its alias with an <a>IsLabel</a>
--   instance to call a table reference by its alias.
newtype Table (schema :: TablesType) (columns :: ColumnsType)
UnsafeTable :: ByteString -> Table
[renderTable] :: Table -> ByteString

-- | A <a>HasTable</a> constraint indicates a table reference.
class KnownSymbol table => HasTable table tables columns | table tables -> columns
getTable :: HasTable table tables columns => Alias table -> Table tables columns

-- | <a>TypeExpression</a>s are used in <a>cast</a>s and
--   <tt>createTable</tt> commands.
newtype TypeExpression (ty :: ColumnType)
UnsafeTypeExpression :: ByteString -> TypeExpression
[renderTypeExpression] :: TypeExpression -> ByteString

-- | <a>pgtype</a> is a demoted version of a <a>PGType</a>
class PGTyped (ty :: PGType)
pgtype :: PGTyped ty => TypeExpression ( 'Required ( 'Null ty))

-- | logical Boolean (true/false)
bool :: TypeExpression ( 'Required ( 'Null  'PGbool))

-- | signed two-byte integer
int2 :: TypeExpression ( 'Required ( 'Null  'PGint2))

-- | signed two-byte integer
smallint :: TypeExpression ( 'Required ( 'Null  'PGint2))

-- | signed four-byte integer
int4 :: TypeExpression ( 'Required ( 'Null  'PGint4))

-- | signed four-byte integer
int :: TypeExpression ( 'Required ( 'Null  'PGint4))

-- | signed four-byte integer
integer :: TypeExpression ( 'Required ( 'Null  'PGint4))

-- | signed eight-byte integer
int8 :: TypeExpression ( 'Required ( 'Null  'PGint8))

-- | signed eight-byte integer
bigint :: TypeExpression ( 'Required ( 'Null  'PGint8))

-- | arbitrary precision numeric type
numeric :: TypeExpression ( 'Required ( 'Null  'PGnumeric))

-- | single precision floating-point number (4 bytes)
float4 :: TypeExpression ( 'Required ( 'Null  'PGfloat4))

-- | single precision floating-point number (4 bytes)
real :: TypeExpression ( 'Required ( 'Null  'PGfloat4))

-- | double precision floating-point number (8 bytes)
float8 :: TypeExpression ( 'Required ( 'Null  'PGfloat8))

-- | double precision floating-point number (8 bytes)
doublePrecision :: TypeExpression ( 'Required ( 'Null  'PGfloat8))

-- | not a true type, but merely a notational convenience for creating
--   unique identifier columns with type `<a>PGint2</a>
serial2 :: TypeExpression ( 'Optional ( 'NotNull  'PGint2))

-- | not a true type, but merely a notational convenience for creating
--   unique identifier columns with type `<a>PGint2</a>
smallserial :: TypeExpression ( 'Optional ( 'NotNull  'PGint2))

-- | not a true type, but merely a notational convenience for creating
--   unique identifier columns with type `<a>PGint4</a>
serial4 :: TypeExpression ( 'Optional ( 'NotNull  'PGint4))

-- | not a true type, but merely a notational convenience for creating
--   unique identifier columns with type `<a>PGint4</a>
serial :: TypeExpression ( 'Optional ( 'NotNull  'PGint4))

-- | not a true type, but merely a notational convenience for creating
--   unique identifier columns with type `<a>PGint8</a>
serial8 :: TypeExpression ( 'Optional ( 'NotNull  'PGint8))

-- | not a true type, but merely a notational convenience for creating
--   unique identifier columns with type `<a>PGint8</a>
bigserial :: TypeExpression ( 'Optional ( 'NotNull  'PGint8))

-- | variable-length character string
text :: TypeExpression ( 'Required ( 'Null  'PGtext))

-- | fixed-length character string
char :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGchar n)))

-- | fixed-length character string
character :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGchar n)))

-- | variable-length character string
varchar :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGvarchar n)))

-- | variable-length character string
characterVarying :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGvarchar n)))

-- | binary data ("byte array")
bytea :: TypeExpression ( 'Required ( 'Null  'PGbytea))

-- | date and time (no time zone)
timestamp :: TypeExpression ( 'Required ( 'Null  'PGtimestamp))

-- | date and time, including time zone
timestampWithTimeZone :: TypeExpression ( 'Required ( 'Null  'PGtimestamptz))

-- | calendar date (year, month, day)
date :: TypeExpression ( 'Required ( 'Null  'PGdate))

-- | time of day (no time zone)
time :: TypeExpression ( 'Required ( 'Null  'PGtime))

-- | time of day, including time zone
timeWithTimeZone :: TypeExpression ( 'Required ( 'Null  'PGtimetz))

-- | time span
interval :: TypeExpression ( 'Required ( 'Null  'PGinterval))

-- | universally unique identifier
uuid :: TypeExpression ( 'Required ( 'Null  'PGuuid))

-- | IPv4 or IPv6 host address
inet :: TypeExpression ( 'Required ( 'Null  'PGinet))

-- | textual JSON data
json :: TypeExpression ( 'Required ( 'Null  'PGjson))

-- | binary JSON data, decomposed
jsonb :: TypeExpression ( 'Required ( 'Null  'PGjsonb))

-- | used in <tt>createTable</tt> commands as a column constraint to ensure
--   <tt>NULL</tt> is not present
notNull :: TypeExpression (optionality ( 'Null ty)) -> TypeExpression (optionality ( 'NotNull ty))

-- | used in <tt>createTable</tt> commands as a column constraint to give a
--   default
default_ :: Expression '[]  'Ungrouped '[] ( 'Required ty) -> TypeExpression ( 'Required ty) -> TypeExpression ( 'Optional ty)

-- | <a>&amp;</a> is a reverse application operator. This provides
--   notational convenience. Its precedence is one higher than that of the
--   forward application operator <a>$</a>, which allows <a>&amp;</a> to be
--   nested in <a>$</a>.
(&) :: () => a -> (a -> b) -> b
infixl 1 &

-- | An n-ary product.
--   
--   The product is parameterized by a type constructor <tt>f</tt> and
--   indexed by a type-level list <tt>xs</tt>. The length of the list
--   determines the number of elements in the product, and if the
--   <tt>i</tt>-th element of the list is of type <tt>x</tt>, then the
--   <tt>i</tt>-th element of the product is of type <tt>f x</tt>.
--   
--   The constructor names are chosen to resemble the names of the list
--   constructors.
--   
--   Two common instantiations of <tt>f</tt> are the identity functor
--   <a>I</a> and the constant functor <a>K</a>. For <a>I</a>, the product
--   becomes a heterogeneous list, where the type-level list describes the
--   types of its components. For <tt><a>K</a> a</tt>, the product becomes
--   a homogeneous list, where the contents of the type-level list are
--   ignored, but its length still specifies the number of elements.
--   
--   In the context of the SOP approach to generic programming, an n-ary
--   product describes the structure of the arguments of a single data
--   constructor.
--   
--   <i>Examples:</i>
--   
--   <pre>
--   I 'x'    :* I True  :* Nil  ::  NP I       '[ Char, Bool ]
--   K 0      :* K 1     :* Nil  ::  NP (K Int) '[ Char, Bool ]
--   Just 'x' :* Nothing :* Nil  ::  NP Maybe   '[ Char, Bool ]
--   </pre>
data NP k (a :: k -> *) (b :: [k]) :: forall k. () => (k -> *) -> [k] -> *
[Nil] :: NP k a [] k
[:*] :: NP k a (:) k x xs
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.TypeExpression ty)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.TypeExpression ty)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.TypeExpression ty)
instance GHC.Show.Show (Squeal.PostgreSQL.Expression.TypeExpression ty)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.TypeExpression ty)
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.Table schema columns)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Table schema columns)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Table schema columns)
instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Table schema columns)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.Table schema columns)
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.Expression tables grouping params ty)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Expression tables grouping params ty)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Expression tables grouping params ty)
instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Expression tables grouping params ty)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.Expression tables grouping params ty)
instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Column columns columnty)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Column columns columnty)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Column columns columnty)
instance Squeal.PostgreSQL.Expression.PGTyped (Squeal.PostgreSQL.Schema.BaseType ty1) => Squeal.PostgreSQL.Expression.HasParameter 1 ((':) Squeal.PostgreSQL.Schema.ColumnType ty1 tys) ty1
instance (GHC.TypeNats.KnownNat n, Squeal.PostgreSQL.Expression.HasParameter (n GHC.TypeNats.- 1) params ty) => Squeal.PostgreSQL.Expression.HasParameter n ((':) Squeal.PostgreSQL.Schema.ColumnType ty' params) ty
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGbool
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGint2
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGint4
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGint8
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGnumeric
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGfloat4
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGfloat8
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtext
instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Squeal.PostgreSQL.Expression.PGTyped ('Squeal.PostgreSQL.Schema.PGchar n)
instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Squeal.PostgreSQL.Expression.PGTyped ('Squeal.PostgreSQL.Schema.PGvarchar n)
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGbytea
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtimestamp
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtimestamptz
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGdate
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtime
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtimetz
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGinterval
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGuuid
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGjson
instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGjsonb
instance (GHC.TypeLits.KnownSymbol table, GHC.TypeLits.KnownSymbol column) => Squeal.PostgreSQL.Expression.GroupedBy table column ((':) (GHC.Types.Symbol, GHC.Types.Symbol) '(table, column) bys)
instance (GHC.TypeLits.KnownSymbol table, GHC.TypeLits.KnownSymbol column, Squeal.PostgreSQL.Expression.GroupedBy table column bys) => Squeal.PostgreSQL.Expression.GroupedBy table column ((':) (GHC.Types.Symbol, GHC.Types.Symbol) tabcol bys)
instance (Squeal.PostgreSQL.Schema.HasUnique Squeal.PostgreSQL.Schema.ColumnsType table tables columns, Squeal.PostgreSQL.Expression.HasColumn column columns ty, Squeal.PostgreSQL.Expression.GroupedBy table column bys) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Expression.Expression tables ('Squeal.PostgreSQL.Schema.Grouped bys) params ty)
instance (Squeal.PostgreSQL.Expression.HasTable table tables columns, Squeal.PostgreSQL.Expression.HasColumn column columns ty, Squeal.PostgreSQL.Expression.GroupedBy table column bys) => Squeal.PostgreSQL.Schema.IsTableColumn table column (Squeal.PostgreSQL.Expression.Expression tables ('Squeal.PostgreSQL.Schema.Grouped bys) params ty)
instance (Squeal.PostgreSQL.Expression.HasTable table tables columns, Squeal.PostgreSQL.Expression.HasColumn column columns ty) => Squeal.PostgreSQL.Schema.IsTableColumn table column (Squeal.PostgreSQL.Expression.Expression tables 'Squeal.PostgreSQL.Schema.Ungrouped params ty)
instance GHC.TypeLits.KnownSymbol table => Squeal.PostgreSQL.Expression.HasTable table ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnsType) ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnsType table columns) tables) columns
instance (GHC.TypeLits.KnownSymbol table, Squeal.PostgreSQL.Expression.HasTable table schema columns) => Squeal.PostgreSQL.Expression.HasTable table ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnsType) table' schema) columns
instance Squeal.PostgreSQL.Expression.HasTable table schema columns => GHC.OverloadedLabels.IsLabel table (Squeal.PostgreSQL.Expression.Table schema columns)
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGint2 'Squeal.PostgreSQL.Schema.PGnumeric
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGint4 'Squeal.PostgreSQL.Schema.PGnumeric
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGint8 'Squeal.PostgreSQL.Schema.PGnumeric
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGnumeric 'Squeal.PostgreSQL.Schema.PGnumeric
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGfloat4 'Squeal.PostgreSQL.Schema.PGfloat8
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGfloat8 'Squeal.PostgreSQL.Schema.PGfloat8
instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGinterval 'Squeal.PostgreSQL.Schema.PGinterval
instance GHC.TypeLits.KnownSymbol column => Squeal.PostgreSQL.Expression.HasColumn column ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column (optionality ty)) tys) ('Squeal.PostgreSQL.Schema.Required ty)
instance (GHC.TypeLits.KnownSymbol column, Squeal.PostgreSQL.Expression.HasColumn column table ty) => Squeal.PostgreSQL.Expression.HasColumn column ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) ty' table) ty
instance (Squeal.PostgreSQL.Expression.HasColumn column columns ty, Squeal.PostgreSQL.Schema.HasUnique Squeal.PostgreSQL.Schema.ColumnsType table tables columns) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Expression.Expression tables 'Squeal.PostgreSQL.Schema.Ungrouped params ty)
instance Squeal.PostgreSQL.Schema.PGNum ty => GHC.Num.Num (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity ty)))
instance (Squeal.PostgreSQL.Schema.PGNum ty, Squeal.PostgreSQL.Schema.PGFloating ty) => GHC.Real.Fractional (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity ty)))
instance (Squeal.PostgreSQL.Schema.PGNum ty, Squeal.PostgreSQL.Schema.PGFloating ty) => GHC.Float.Floating (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity ty)))
instance Data.String.IsString (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity 'Squeal.PostgreSQL.Schema.PGtext)))
instance GHC.Base.Monoid (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity 'Squeal.PostgreSQL.Schema.PGtext)))


-- | Squeal queries.
module Squeal.PostgreSQL.Query

-- | The process of retrieving or the command to retrieve data from a
--   database is called a <a>Query</a>. The <a>select</a>,
--   <a>selectStar</a>, <a>selectDotStar</a>, <a>selectDistinct</a>,
--   <a>selectDistinctStar</a> and <a>selectDistinctDotStar</a> commands
--   are used to specify queries.
--   
--   simple query:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectStar (from (Table (#tab `As` #t)))
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t"
--   </pre>
--   
--   restricted query:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query
--       '[ "tab" :::
--          '[ "col1" ::: 'Required ('NotNull 'PGint4)
--           , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[]
--       '[ "sum" ::: 'Required ('NotNull 'PGint4)
--        , "col1" ::: 'Required ('NotNull 'PGint4) ]
--     query = 
--       select
--         ((#col1 + #col2) `As` #sum :* #col1 `As` #col1 :* Nil)
--         ( from (Table (#tab `As` #t))
--           &amp; where_ (#col1 .&gt; #col2)
--           &amp; where_ (#col2 .&gt; 0) )
--   in renderQuery query
--   :}
--   "SELECT (col1 + col2) AS sum, col1 AS col1 FROM tab AS t WHERE ((col1 &gt; col2) AND (col2 &gt; 0))"
--   </pre>
--   
--   subquery:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query =
--       selectStar
--         (from (Subquery (selectStar (from (Table (#tab `As` #t))) `As` #sub)))
--   in renderQuery query
--   :}
--   "SELECT * FROM (SELECT * FROM tab AS t) AS sub"
--   </pre>
--   
--   limits and offsets:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectStar
--       (from (Table (#tab `As` #t)) &amp; limit 100 &amp; offset 2 &amp; limit 50 &amp; offset 2)
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t LIMIT 50 OFFSET 4"
--   </pre>
--   
--   parameterized query:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('NotNull 'PGfloat8)]]
--       '[ 'Required ('NotNull 'PGfloat8)]
--       '["col" ::: 'Required ('NotNull 'PGfloat8)]
--     query = selectStar
--       (from (Table (#tab `As` #t)) &amp; where_ (#col .&gt; param @1))
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t WHERE (col &gt; ($1 :: float8))"
--   </pre>
--   
--   aggregation query:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query
--       '[ "tab" :::
--          '[ "col1" ::: 'Required ('NotNull 'PGint4)
--           , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[]
--       '[ "sum" ::: 'Required ('NotNull 'PGint4)
--        , "col1" ::: 'Required ('NotNull 'PGint4) ]
--     query =
--       select (sum_ #col2 `As` #sum :* #col1 `As` #col1 :* Nil)
--       ( from (Table (#tab `As` #table1))
--         &amp; group (By #col1 :* Nil) 
--         &amp; having (#col1 + sum_ #col2 .&gt; 1) )
--   in renderQuery query
--   :}
--   "SELECT sum(col2) AS sum, col1 AS col1 FROM tab AS table1 GROUP BY col1 HAVING ((col1 + sum(col2)) &gt; 1)"
--   </pre>
--   
--   sorted query:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectStar
--       (from (Table (#tab `As` #t)) &amp; orderBy [#col &amp; AscNullsFirst])
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t ORDER BY col ASC NULLS FIRST"
--   </pre>
--   
--   joins:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XFlexibleContexts
--   
--   &gt;&gt;&gt; :{
--   let
--     query :: Query
--       '[ "orders" :::
--            '[ "id"    ::: 'Required ('NotNull 'PGint4)
--             , "price"   ::: 'Required ('NotNull 'PGfloat4)
--             , "customer_id" ::: 'Required ('NotNull 'PGint4)
--             , "shipper_id"  ::: 'Required ('NotNull 'PGint4)
--             ]
--        , "customers" :::
--            '[ "id" ::: 'Required ('NotNull 'PGint4)
--             , "name" ::: 'Required ('NotNull 'PGtext)
--             ]
--        , "shippers" :::
--            '[ "id" ::: 'Required ('NotNull 'PGint4)
--             , "name" ::: 'Required ('NotNull 'PGtext)
--             ]
--        ]
--       '[]
--       '[ "order_price" ::: 'Required ('NotNull 'PGfloat4)
--        , "customer_name" ::: 'Required ('NotNull 'PGtext)
--        , "shipper_name" ::: 'Required ('NotNull 'PGtext)
--        ]
--     query = select
--       ( #o ! #price `As` #order_price :*
--         #c ! #name `As` #customer_name :*
--         #s ! #name `As` #shipper_name :* Nil )
--       ( from (Table (#orders `As` #o)
--         &amp; InnerJoin (Table (#customers `As` #c))
--           (#o ! #customer_id .== #c ! #id)
--         &amp; InnerJoin (Table (#shippers `As` #s))
--           (#o ! #shipper_id .== #s ! #id)) )
--   in renderQuery query
--   :}
--   "SELECT o.price AS order_price, c.name AS customer_name, s.name AS shipper_name FROM orders AS o INNER JOIN customers AS c ON (o.customer_id = c.id) INNER JOIN shippers AS s ON (o.shipper_id = s.id)"
--   </pre>
--   
--   self-join:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectDotStar #t1
--       (from (Table (#tab `As` #t1) &amp; CrossJoin (Table (#tab `As` #t2))))
--   in renderQuery query
--   :}
--   "SELECT t1.* FROM tab AS t1 CROSS JOIN tab AS t2"
--   </pre>
--   
--   set operations:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query =
--       selectStar (from (Table (#tab `As` #t)))
--       `unionAll`
--       selectStar (from (Table (#tab `As` #t)))
--   in renderQuery query
--   :}
--   "(SELECT * FROM tab AS t) UNION ALL (SELECT * FROM tab AS t)"
--   </pre>
newtype Query (schema :: TablesType) (params :: [ColumnType]) (columns :: ColumnsType)
UnsafeQuery :: ByteString -> Query
[renderQuery] :: Query -> ByteString

-- | The results of two queries can be combined using the set operation
--   <a>union</a>. Duplicate rows are eliminated.
union :: Query schema params columns -> Query schema params columns -> Query schema params columns

-- | The results of two queries can be combined using the set operation
--   <a>unionAll</a>, the disjoint union. Duplicate rows are retained.
unionAll :: Query schema params columns -> Query schema params columns -> Query schema params columns

-- | The results of two queries can be combined using the set operation
--   <a>intersect</a>, the intersection. Duplicate rows are eliminated.
intersect :: Query schema params columns -> Query schema params columns -> Query schema params columns

-- | The results of two queries can be combined using the set operation
--   <a>intersectAll</a>, the intersection. Duplicate rows are retained.
intersectAll :: Query schema params columns -> Query schema params columns -> Query schema params columns

-- | The results of two queries can be combined using the set operation
--   <a>except</a>, the set difference. Duplicate rows are eliminated.
except :: Query schema params columns -> Query schema params columns -> Query schema params columns

-- | The results of two queries can be combined using the set operation
--   <a>exceptAll</a>, the set difference. Duplicate rows are retained.
exceptAll :: Query schema params columns -> Query schema params columns -> Query schema params columns

-- | the <a>TableExpression</a> in the <a>select</a> command constructs an
--   intermediate virtual table by possibly combining tables, views,
--   eliminating rows, grouping, etc. This table is finally passed on to
--   processing by the select list. The select list determines which
--   columns of the intermediate table are actually output.
select :: SListI columns => NP (Aliased (Expression tables grouping params)) (column : columns) -> TableExpression schema params tables grouping -> Query schema params (column : columns)

-- | After the select list has been processed, the result table can be
--   subject to the elimination of duplicate rows using
--   <a>selectDistinct</a>.
selectDistinct :: SListI columns => NP (Aliased (Expression tables  'Ungrouped params)) (column : columns) -> TableExpression schema params tables  'Ungrouped -> Query schema params (column : columns)

-- | The simplest kind of query is <a>selectStar</a> which emits all
--   columns that the table expression produces.
selectStar :: HasUnique table tables columns => TableExpression schema params tables  'Ungrouped -> Query schema params columns

-- | A <a>selectDistinctStar</a> emits all columns that the table
--   expression produces and eliminates duplicate rows.
selectDistinctStar :: HasUnique table tables columns => TableExpression schema params tables  'Ungrouped -> Query schema params columns

-- | When working with multiple tables, it can also be useful to ask for
--   all the columns of a particular table, using <a>selectDotStar</a>.
selectDotStar :: HasTable table tables columns => Alias table -> TableExpression schema params tables  'Ungrouped -> Query schema params columns

-- | A <a>selectDistinctDotStar</a> asks for all the columns of a
--   particular table, and eliminates duplicate rows.
selectDistinctDotStar :: HasTable table tables columns => Alias table -> TableExpression schema params tables  'Ungrouped -> Query schema params columns

-- | A <a>TableExpression</a> computes a table. The table expression
--   contains a <a>fromClause</a> that is optionally followed by a
--   <a>whereClause</a>, <a>groupByClause</a>, <a>havingClause</a>,
--   <a>orderByClause</a>, <a>limitClause</a> and <a>offsetClause</a>s.
--   Trivial table expressions simply refer to a table on disk, a so-called
--   base table, but more complex expressions can be used to modify or
--   combine base tables in various ways.
data TableExpression (schema :: TablesType) (params :: [ColumnType]) (tables :: TablesType) (grouping :: Grouping)
TableExpression :: FromClause schema params tables -> [Condition tables  'Ungrouped params] -> GroupByClause tables grouping -> HavingClause tables grouping params -> [SortExpression tables grouping params] -> [Word64] -> [Word64] -> TableExpression

-- | A table reference that can be a table name, or a derived table such as
--   a subquery, a <tt>JOIN</tt> construct, or complex combinations of
--   these.
[fromClause] :: TableExpression -> FromClause schema params tables

-- | optional search coditions, combined with <a>.&amp;&amp;</a>. After the
--   processing of the <a>fromClause</a> is done, each row of the derived
--   virtual table is checked against the search condition. If the result
--   of the condition is true, the row is kept in the output table,
--   otherwise it is discarded. The search condition typically references
--   at least one column of the table generated in the <a>fromClause</a>;
--   this is not required, but otherwise the WHERE clause will be fairly
--   useless.
[whereClause] :: TableExpression -> [Condition tables  'Ungrouped params]

-- | The <a>groupByClause</a> is used to group together those rows in a
--   table that have the same values in all the columns listed. The order
--   in which the columns are listed does not matter. The effect is to
--   combine each set of rows having common values into one group row that
--   represents all rows in the group. This is done to eliminate redundancy
--   in the output and/or compute aggregates that apply to these groups.
[groupByClause] :: TableExpression -> GroupByClause tables grouping

-- | If a table has been grouped using <tt>groupBy</tt>, but only certain
--   groups are of interest, the <a>havingClause</a> can be used, much like
--   a <a>whereClause</a>, to eliminate groups from the result. Expressions
--   in the <a>havingClause</a> can refer both to grouped expressions and
--   to ungrouped expressions (which necessarily involve an aggregate
--   function).
[havingClause] :: TableExpression -> HavingClause tables grouping params

-- | The <a>orderByClause</a> is for optional sorting. When more than one
--   <a>SortExpression</a> is specified, the later (right) values are used
--   to sort rows that are equal according to the earlier (left) values.
[orderByClause] :: TableExpression -> [SortExpression tables grouping params]

-- | The <a>limitClause</a> is combined with <a>min</a> to give a limit
--   count if nonempty. If a limit count is given, no more than that many
--   rows will be returned (but possibly fewer, if the query itself yields
--   fewer rows).
[limitClause] :: TableExpression -> [Word64]

-- | The <a>offsetClause</a> is combined with <a>+</a> to give an offset
--   count if nonempty. The offset count says to skip that many rows before
--   beginning to return rows. The rows are skipped before the limit count
--   is applied.
[offsetClause] :: TableExpression -> [Word64]

-- | Render a <a>TableExpression</a>
renderTableExpression :: TableExpression schema params tables grouping -> ByteString

-- | A <a>from</a> generates a <a>TableExpression</a> from a table
--   reference that can be a table name, or a derived table such as a
--   subquery, a JOIN construct, or complex combinations of these. A
--   <a>from</a> may be transformed by <a>where_</a>, <a>group</a>,
--   <a>having</a>, <a>orderBy</a>, <a>limit</a> and <a>offset</a>, using
--   the <a>&amp;</a> operator to match the left-to-right sequencing of
--   their placement in SQL.
from :: FromClause schema params tables -> TableExpression schema params tables  'Ungrouped

-- | A <a>where_</a> is an endomorphism of <a>TableExpression</a>s which
--   adds a search condition to the <a>whereClause</a>.
where_ :: Condition tables  'Ungrouped params -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping

-- | A <a>group</a> is a transformation of <a>TableExpression</a>s which
--   switches its <a>Grouping</a> from <a>Ungrouped</a> to <a>Grouped</a>.
--   Use <tt>group Nil</tt> to perform a "grand total" aggregation query.
group :: SListI bys => NP (By tables) bys -> TableExpression schema params tables  'Ungrouped -> TableExpression schema params tables ( 'Grouped bys)

-- | A <a>having</a> is an endomorphism of <a>TableExpression</a>s which
--   adds a search condition to the <a>havingClause</a>.
having :: Condition tables ( 'Grouped bys) params -> TableExpression schema params tables ( 'Grouped bys) -> TableExpression schema params tables ( 'Grouped bys)

-- | An <a>orderBy</a> is an endomorphism of <a>TableExpression</a>s which
--   appends an ordering to the right of the <a>orderByClause</a>.
orderBy :: [SortExpression tables grouping params] -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping

-- | A <a>limit</a> is an endomorphism of <a>TableExpression</a>s which
--   adds to the <a>limitClause</a>.
limit :: Word64 -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping

-- | An <a>offset</a> is an endomorphism of <a>TableExpression</a>s which
--   adds to the <a>offsetClause</a>.
offset :: Word64 -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping

-- | A <a>FromClause</a> can be a table name, or a derived table such as a
--   subquery, a <tt>JOIN</tt> construct, or complex combinations of these.
--   
--   <ul>
--   <li>A real <a>Table</a> is a table from the schema.</li>
--   <li><a>Subquery</a> derives a table from a <a>Query</a>.</li>
--   <li>A joined table is a table derived from two other (real or derived)
--   tables according to the rules of the particular join type.
--   <a>CrossJoin</a>, <a>InnerJoin</a>, <a>LeftOuterJoin</a>,
--   <a>RightOuterJoin</a> and <a>FullOuterJoin</a> are available and can
--   be nested using the <a>&amp;</a> operator to match the left-to-right
--   sequencing of their placement in SQL.<ul><li><tt>t1 &amp; CrossJoin
--   t2</tt>. For every possible combination of rows from <tt>t1</tt> and
--   <tt>t2</tt> (i.e., a Cartesian product), the joined table will contain
--   a row consisting of all columns in <tt>t1</tt> followed by all columns
--   in <tt>t2</tt>. If the tables have <tt>n</tt> and <tt>m</tt> rows
--   respectively, the joined table will have <tt>n * m</tt>
--   rows.</li><li><tt>t1 &amp; InnerJoin t2 on</tt>. For each row
--   <tt>r1</tt> of <tt>t1</tt>, the joined table has a row for each row in
--   <tt>t2</tt> that satisfies the <tt>on</tt> condition with
--   <tt>r1</tt></li><li><tt>t1 &amp; LeftOuterJoin t2 on</tt>. First, an
--   inner join is performed. Then, for each row in <tt>t1</tt> that does
--   not satisfy the <tt>on</tt> condition with any row in <tt>t2</tt>, a
--   joined row is added with null values in columns of <tt>t2</tt>. Thus,
--   the joined table always has at least one row for each row in
--   <tt>t1</tt>.</li><li><tt>t1 &amp; RightOuterJoin t2 on</tt>. First, an
--   inner join is performed. Then, for each row in <tt>t2</tt> that does
--   not satisfy the <tt>on</tt> condition with any row in <tt>t1</tt>, a
--   joined row is added with null values in columns of <tt>t1</tt>. This
--   is the converse of a left join: the result table will always have a
--   row for each row in <tt>t2</tt>.</li><li><tt>t1 &amp; FullOuterJoin t2
--   on</tt>. First, an inner join is performed. Then, for each row in
--   <tt>t1</tt> that does not satisfy the <tt>on</tt> condition with any
--   row in <tt>t2</tt>, a joined row is added with null values in columns
--   of <tt>t2</tt>. Also, for each row of <tt>t2</tt> that does not
--   satisfy the join condition with any row in <tt>t1</tt>, a joined row
--   with null values in the columns of <tt>t1</tt> is
--   added.</li></ul></li>
--   </ul>
data FromClause schema params tables
[Table] :: Aliased (Table schema) table -> FromClause schema params '[table]
[Subquery] :: Aliased (Query schema params) table -> FromClause schema params '[table]
[CrossJoin] :: FromClause schema params right -> FromClause schema params left -> FromClause schema params (Join left right)
[InnerJoin] :: FromClause schema params right -> Condition (Join left right)  'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join left right)
[LeftOuterJoin] :: FromClause schema params right -> Condition (Join left right)  'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join left (NullifyTables right))
[RightOuterJoin] :: FromClause schema params right -> Condition (Join left right)  'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join (NullifyTables left) right)
[FullOuterJoin] :: FromClause schema params right -> Condition (Join left right)  'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join (NullifyTables left) (NullifyTables right))

-- | Renders a <a>FromClause</a>.
renderFromClause :: FromClause schema params tables -> ByteString

-- | <a>By</a>s are used in <a>group</a> to reference a list of columns
--   which are then used to group together those rows in a table that have
--   the same values in all the columns listed. <tt>By #col</tt> will
--   reference an unambiguous column <tt>col</tt>; otherwise <tt>By2 (#tab
--   ! #col)</tt> will reference a table qualified column <tt>tab.col</tt>.
data By (tables :: TablesType) (by :: (Symbol, Symbol))
[By] :: (HasUnique table tables columns, HasColumn column columns ty) => Alias column -> By tables '(table, column)
[By2] :: (HasTable table tables columns, HasColumn column columns ty) => (Alias table, Alias column) -> By tables '(table, column)

-- | Renders a <a>By</a>.
renderBy :: By tables tabcolty -> ByteString

-- | A <a>GroupByClause</a> indicates the <a>Grouping</a> of a
--   <a>TableExpression</a>. A <a>NoGroups</a> indicates <a>Ungrouped</a>
--   while a <a>Group</a> indicates <a>Grouped</a>. <tt>NoGroups</tt> is
--   distinguised from <tt>Group Nil</tt> since no aggregation can be done
--   on <tt>NoGroups</tt> while all output <a>Expression</a>s must be
--   aggregated in <tt>Group Nil</tt>.
data GroupByClause tables grouping
[NoGroups] :: GroupByClause tables  'Ungrouped
[Group] :: SListI bys => NP (By tables) bys -> GroupByClause tables ( 'Grouped bys)

-- | Renders a <a>GroupByClause</a>.
renderGroupByClause :: GroupByClause tables grouping -> ByteString

-- | A <a>HavingClause</a> is used to eliminate groups that are not of
--   interest. An <a>Ungrouped</a> <a>TableExpression</a> may only use
--   <a>NoHaving</a> while a <a>Grouped</a> <a>TableExpression</a> must use
--   <a>Having</a> whose conditions are combined with <a>.&amp;&amp;</a>.
data HavingClause tables grouping params
[NoHaving] :: HavingClause tables  'Ungrouped params
[Having] :: [Condition tables ( 'Grouped bys) params] -> HavingClause tables ( 'Grouped bys) params

-- | Render a <a>HavingClause</a>.
renderHavingClause :: HavingClause tables grouping params -> ByteString

-- | <a>SortExpression</a>s are used by <tt>sortBy</tt> to optionally sort
--   the results of a <a>Query</a>. <a>Asc</a> or <a>Desc</a> set the sort
--   direction of a <a>NotNull</a> result column to ascending or
--   descending. Ascending order puts smaller values first, where "smaller"
--   is defined in terms of the <a>.&lt;</a> operator. Similarly,
--   descending order is determined with the <a>.&gt;</a> operator.
--   <a>AscNullsFirst</a>, <a>AscNullsLast</a>, <a>DescNullsFirst</a> and
--   <a>DescNullsLast</a> options are used to determine whether nulls
--   appear before or after non-null values in the sort ordering of a
--   <a>Null</a> result column.
data SortExpression tables grouping params
[Asc] :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> SortExpression tables grouping params
[Desc] :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> SortExpression tables grouping params
[AscNullsFirst] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params
[AscNullsLast] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params
[DescNullsFirst] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params
[DescNullsLast] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params

-- | Render a <a>SortExpression</a>.
renderSortExpression :: SortExpression tables grouping params -> ByteString
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Query.Query schema params columns)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.Query schema params columns)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.Query schema params columns)
instance GHC.Show.Show (Squeal.PostgreSQL.Query.Query schema params columns)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Query.Query schema params columns)
instance GHC.Show.Show (Squeal.PostgreSQL.Query.By tables by)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.By tables by)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.By tables by)
instance GHC.Show.Show (Squeal.PostgreSQL.Query.HavingClause tables grouping params)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.HavingClause tables grouping params)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.HavingClause tables grouping params)
instance GHC.Show.Show (Squeal.PostgreSQL.Query.SortExpression tables grouping params)


-- | Squeal data manipulation language.
module Squeal.PostgreSQL.Manipulation

-- | A <a>Manipulation</a> is a statement which may modify data in the
--   database, but does not alter the schema. Examples are
--   <a>insertInto</a>, <a>update</a> and <a>deleteFrom</a>. A <a>Query</a>
--   is also considered a <a>Manipulation</a> even though it does not
--   modify data.
newtype Manipulation (schema :: TablesType) (params :: [ColumnType]) (columns :: ColumnsType)
UnsafeManipulation :: ByteString -> Manipulation
[renderManipulation] :: Manipulation -> ByteString

-- | Convert a <a>Query</a> into a <a>Manipulation</a>.
queryStatement :: Query schema params columns -> Manipulation schema params columns

-- | When a table is created, it contains no data. The first thing to do
--   before a database can be of much use is to insert data. Data is
--   conceptually inserted one row at a time. Of course you can also insert
--   more than one row, but there is no way to insert less than one row.
--   Even if you know only some column values, a complete row must be
--   created.
--   
--   simple insert:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[] '[]
--     manipulation =
--       insertInto #tab (Values (2 `As` #col1 :* 4 `As` #col2 :* Nil) [])
--         OnConflictDoRaise (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (2, 4);"
--   </pre>
--   
--   parameterized insert:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[ 'Required ('NotNull 'PGint4)
--        , 'Required ('NotNull 'PGint4) ] '[]
--     manipulation =
--       insertInto #tab
--         (Values (param @1 `As` #col1 :* param @2 `As` #col2 :* Nil) [])
--         OnConflictDoRaise (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (($1 :: int4), ($2 :: int4));"
--   </pre>
--   
--   returning insert:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]
--       '["fromOnly" ::: 'Required ('NotNull 'PGint4)]
--     manipulation =
--       insertInto #tab (Values (2 `As` #col1 :* 4 `As` #col2 :* Nil) [])
--         OnConflictDoRaise (Returning (#col1 `As` #fromOnly :* Nil))
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (2, 4) RETURNING col1 AS fromOnly;"
--   </pre>
--   
--   query insert:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4)
--          ]
--        , "other_tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4)
--          ]
--        ] '[] '[]
--     manipulation = 
--       insertInto #tab
--         ( ValuesQuery $
--           selectStar (from (Table (#other_tab `As` #t))) )
--         OnConflictDoRaise (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab SELECT * FROM other_tab AS t;"
--   </pre>
--   
--   upsert:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[] '[ "sum" ::: 'Required ('NotNull 'PGint4)]
--     manipulation =
--       insertInto #tab
--         (Values
--           (2 `As` #col1 :* 4 `As` #col2 :* Nil)
--           [6 `As` #col1 :* 8 `As` #col2 :* Nil])
--         (OnConflictDoUpdate
--           (Set 2 `As` #col1 :* Same `As` #col2 :* Nil)
--           (Just (#col1 .== #col2)))
--         (Returning $ (#col1 + #col2) `As` #sum :* Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (2, 4), (6, 8) ON CONFLICT DO UPDATE SET col1 = 2 WHERE (col1 = col2) RETURNING (col1 + col2) AS sum;"
--   </pre>
insertInto :: (SListI columns, SListI results, HasTable table schema columns) => Alias table -> ValuesClause schema params columns -> ConflictClause columns params -> ReturningClause columns params results -> Manipulation schema params results

-- | A <a>ValuesClause</a> lets you insert either values, free
--   <a>Expression</a>s, or the result of a <a>Query</a>.
data ValuesClause (schema :: TablesType) (params :: [ColumnType]) (columns :: ColumnsType)

-- | at least one row of values
Values :: (NP (Aliased (Expression '[]  'Ungrouped params)) columns) -> [NP (Aliased (Expression '[]  'Ungrouped params)) columns] -> ValuesClause
ValuesQuery :: (Query schema params columns) -> ValuesClause

-- | Render a <a>ValuesClause</a>.
renderValuesClause :: SListI columns => ValuesClause schema params columns -> ByteString

-- | A <a>ReturningClause</a> computes and return value(s) based on each
--   row actually inserted, updated or deleted. This is primarily useful
--   for obtaining values that were supplied by defaults, such as a serial
--   sequence number. However, any expression using the table's columns is
--   allowed. Only rows that were successfully inserted or updated or
--   deleted will be returned. For example, if a row was locked but not
--   updated because an <a>OnConflictDoUpdate</a> condition was not
--   satisfied, the row will not be returned. <a>ReturningStar</a> will
--   return all columns in the row. Use `Returning Nil` in the common case
--   where no return values are desired.
data ReturningClause (columns :: ColumnsType) (params :: [ColumnType]) (results :: ColumnsType)
[ReturningStar] :: ReturningClause columns params columns
[Returning] :: NP (Aliased (Expression '[table ::: columns]  'Ungrouped params)) results -> ReturningClause columns params results

-- | Render a <a>ReturningClause</a>.
renderReturningClause :: SListI results => ReturningClause params columns results -> ByteString

-- | A <a>ConflictClause</a> specifies an action to perform upon a
--   constraint violation. <a>OnConflictDoRaise</a> will raise an error.
--   <a>OnConflictDoNothing</a> simply avoids inserting a row.
--   <a>OnConflictDoUpdate</a> updates the existing row that conflicts with
--   the row proposed for insertion.
data ConflictClause columns params
[OnConflictDoRaise] :: ConflictClause columns params
[OnConflictDoNothing] :: ConflictClause columns params
[OnConflictDoUpdate] :: NP (Aliased (UpdateExpression columns params)) columns -> Maybe (Condition '[table ::: columns]  'Ungrouped params) -> ConflictClause columns params

-- | Render a <a>ConflictClause</a>.
renderConflictClause :: SListI columns => ConflictClause columns params -> ByteString

-- | An <a>update</a> command changes the values of the specified columns
--   in all rows that satisfy the condition.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[] '[]
--     manipulation =
--       update #tab (Set 2 `As` #col1 :* Same `As` #col2 :* Nil)
--         (#col1 ./= #col2) (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "UPDATE tab SET col1 = 2 WHERE (col1 &lt;&gt; col2);"
--   </pre>
update :: (HasTable table schema columns, SListI columns, SListI results) => Alias table -> NP (Aliased (UpdateExpression columns params)) columns -> Condition '[tab ::: columns]  'Ungrouped params -> ReturningClause columns params results -> Manipulation schema params results

-- | Columns to be updated are mentioned with <a>Set</a>; columns which are
--   to remain the same are mentioned with <a>Same</a>.
data UpdateExpression columns params ty

-- | column to remain the same upon update
Same :: UpdateExpression columns params ty

-- | column to be updated
Set :: (forall table. Expression '[table ::: columns]  'Ungrouped params ty) -> UpdateExpression columns params ty

-- | Render an <a>UpdateExpression</a>.
renderUpdateExpression :: Aliased (UpdateExpression params columns) column -> Maybe ByteString

-- | Delete rows of a table.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]
--       '[ "col1" ::: 'Required ('NotNull 'PGint4)
--        , "col2" ::: 'Required ('NotNull 'PGint4) ]
--     manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar
--   in renderManipulation manipulation
--   :}
--   "DELETE FROM tab WHERE (col1 = col2) RETURNING *;"
--   </pre>
deleteFrom :: (SListI results, HasTable table schema columns) => Alias table -> Condition '[table ::: columns]  'Ungrouped params -> ReturningClause columns params results -> Manipulation schema params results
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns)
instance GHC.Show.Show (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns)
instance GHC.Show.Show (Squeal.PostgreSQL.Manipulation.UpdateExpression columns params ty)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Manipulation.UpdateExpression columns params ty)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Manipulation.UpdateExpression columns params ty)


-- | Squeal data definition language.
module Squeal.PostgreSQL.Definition

-- | A <a>Definition</a> is a statement that changes the schema of the
--   database, like a <a>createTable</a>, <a>dropTable</a>, or
--   <a>alterTable</a> command. <a>Definition</a>s may be composed using
--   the <a>&gt;&gt;&gt;</a> operator.
newtype Definition (schema0 :: TablesType) (schema1 :: TablesType)
UnsafeDefinition :: ByteString -> Definition
[renderDefinition] :: Definition -> ByteString

-- | Left-to-right composition
(>>>) :: Category k cat => cat a b -> cat b c -> cat a c
infixr 1 >>>

-- | <a>createTable</a> adds a table to the schema.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedLabels
--   
--   &gt;&gt;&gt; :{
--   renderDefinition $
--     createTable #tab (int `As` #a :* real `As` #b :* Nil) []
--   :}
--   "CREATE TABLE tab (a int, b real);"
--   </pre>
createTable :: (KnownSymbol table, SListI columns) => Alias table -> NP (Aliased TypeExpression) (column : columns) -> [TableConstraint schema (column : columns)] -> Definition schema (Create table (column : columns) schema)

-- | Data types are a way to limit the kind of data that can be stored in a
--   table. For many applications, however, the constraint they provide is
--   too coarse. For example, a column containing a product price should
--   probably only accept positive values. But there is no standard data
--   type that accepts only positive numbers. Another issue is that you
--   might want to constrain column data with respect to other columns or
--   rows. For example, in a table containing product information, there
--   should be only one row for each product number.
--   <a>TableConstraint</a>s give you as much control over the data in your
--   tables as you wish. If a user attempts to store data in a column that
--   would violate a constraint, an error is raised. This applies even if
--   the value came from the default value definition.
newtype TableConstraint (schema :: TablesType) (columns :: ColumnsType)
UnsafeTableConstraint :: ByteString -> TableConstraint
[renderTableConstraint] :: TableConstraint -> ByteString

-- | A <a>check</a> constraint is the most generic <a>TableConstraint</a>
--   type. It allows you to specify that the value in a certain column must
--   satisfy a Boolean (truth-value) expression.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   renderDefinition $
--     createTable #tab
--       ( (int &amp; notNull) `As` #a :*
--         (int &amp; notNull) `As` #b :* Nil )
--       [ check (#a .&gt; #b) ]
--   :}
--   "CREATE TABLE tab (a int NOT NULL, b int NOT NULL, CHECK ((a &gt; b)));"
--   </pre>
check :: Condition '[table ::: columns]  'Ungrouped '[] -> TableConstraint schema columns

-- | A <a>unique</a> constraint ensure that the data contained in a column,
--   or a group of columns, is unique among all the rows in the table.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   renderDefinition $
--     createTable #tab
--       ( int `As` #a :*
--         int `As` #b :* Nil )
--       [ unique (Column #a :* Column #b :* Nil) ]
--   :}
--   "CREATE TABLE tab (a int, b int, UNIQUE (a, b));"
--   </pre>
unique :: SListI subcolumns => NP (Column columns) subcolumns -> TableConstraint schema columns

-- | A <a>primaryKey</a> constraint indicates that a column, or group of
--   columns, can be used as a unique identifier for rows in the table.
--   This requires that the values be both unique and not null.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   renderDefinition $
--     createTable #tab
--       ( serial `As` #id :*
--         (text &amp; notNull) `As` #name :* Nil )
--       [ primaryKey (Column #id :* Nil) ]
--   :}
--   "CREATE TABLE tab (id serial, name text NOT NULL, PRIMARY KEY (id));"
--   </pre>
primaryKey :: (SListI subcolumns, AllNotNull subcolumns) => NP (Column columns) subcolumns -> TableConstraint schema columns

-- | A <a>foreignKey</a> specifies that the values in a column (or a group
--   of columns) must match the values appearing in some row of another
--   table. We say this maintains the referential integrity between two
--   related tables.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition '[]
--       '[ "users" :::
--          '[ "id" ::: 'Optional ('NotNull 'PGint4)
--           , "username" ::: 'Required ('NotNull 'PGtext)
--           ]
--        , "emails" :::
--          '[ "id" ::: 'Optional ('NotNull 'PGint4)
--           , "userid" ::: 'Required ('NotNull 'PGint4)
--           , "email" ::: 'Required ('NotNull 'PGtext)
--           ]
--        ]
--     definition =
--       createTable #users
--         (serial `As` #id :* (text &amp; notNull) `As` #username :* Nil)
--         [primaryKey (Column #id :* Nil)] &gt;&gt;&gt;
--       createTable #emails
--         ( serial `As` #id :*
--           (integer &amp; notNull) `As` #userid :*
--           (text &amp; notNull) `As` #email :* Nil )
--         [ primaryKey (Column #id :* Nil)
--         , foreignKey (Column #userid :* Nil) #users (Column #id :* Nil)
--           OnDeleteCascade OnUpdateRestrict
--         ]
--   in renderDefinition definition
--   :}
--   "CREATE TABLE users (id serial, username text NOT NULL, PRIMARY KEY (id)); CREATE TABLE emails (id serial, userid integer NOT NULL, email text NOT NULL, PRIMARY KEY (id), FOREIGN KEY (userid) REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT);"
--   </pre>
foreignKey :: (HasTable reftable schema refcolumns, SameTypes subcolumns refsubcolumns, AllNotNull subcolumns, SListI subcolumns, SListI refsubcolumns) => NP (Column columns) subcolumns -> Alias reftable -> NP (Column refcolumns) refsubcolumns -> OnDeleteClause -> OnUpdateClause -> TableConstraint schema columns

-- | <tt>OnDelete</tt> indicates what to do with rows that reference a
--   deleted row.
data OnDeleteClause

-- | if any referencing rows still exist when the constraint is checked, an
--   error is raised
OnDeleteNoAction :: OnDeleteClause

-- | prevents deletion of a referenced row
OnDeleteRestrict :: OnDeleteClause

-- | specifies that when a referenced row is deleted, row(s) referencing it
--   should be automatically deleted as well
OnDeleteCascade :: OnDeleteClause

-- | Render <a>OnDeleteClause</a>.
renderOnDeleteClause :: OnDeleteClause -> ByteString

-- | Analagous to <tt>OnDelete</tt> there is also <tt>OnUpdate</tt> which
--   is invoked when a referenced column is changed (updated).
data OnUpdateClause

-- | if any referencing rows has not changed when the constraint is
--   checked, an error is raised
OnUpdateNoAction :: OnUpdateClause

-- | prevents update of a referenced row
OnUpdateRestrict :: OnUpdateClause

-- | the updated values of the referenced column(s) should be copied into
--   the referencing row(s)
OnUpdateCascade :: OnUpdateClause

-- | Render <a>OnUpdateClause</a>.
renderOnUpdateClause :: OnUpdateClause -> ByteString

-- | <a>dropTable</a> removes a table from the schema.
--   
--   <pre>
--   &gt;&gt;&gt; renderDefinition $ dropTable #muh_table
--   "DROP TABLE muh_table;"
--   </pre>
dropTable :: KnownSymbol table => Alias table -> Definition schema (Drop table schema)

-- | <a>alterTable</a> changes the definition of a table from the schema.
alterTable :: HasTable table schema columns0 => Alias table -> AlterColumns columns0 columns1 -> Definition schema (Alter table schema columns1)

-- | <a>alterTableRename</a> changes the name of a table from the schema.
--   
--   <pre>
--   &gt;&gt;&gt; renderDefinition $ alterTableRename #foo #bar
--   "ALTER TABLE foo RENAME TO bar;"
--   </pre>
alterTableRename :: (KnownSymbol table0, KnownSymbol table1) => Alias table0 -> Alias table1 -> Definition schema (Rename table0 table1 schema)

-- | An <a>alterTableAddConstraint</a> adds a table constraint.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--     definition = alterTableAddConstraint #tab (check (#col .&gt; 0))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ADD CHECK ((col &gt; 0));"
--   </pre>
alterTableAddConstraint :: HasTable table schema columns => Alias table -> TableConstraint schema columns -> Definition schema schema

-- | An <a>AlterColumns</a> describes the alteration to perform on the
--   columns of a table.
newtype AlterColumns (columns0 :: ColumnsType) (columns1 :: ColumnsType)
UnsafeAlterColumns :: ByteString -> AlterColumns
[renderAlterColumns] :: AlterColumns -> ByteString

-- | An <a>addColumnDefault</a> adds a new <a>Optional</a> column. The new
--   column is initially filled with whatever default value is given.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Optional ('Null 'PGtext) ]]
--     definition = alterTable #tab
--       (addColumnDefault #col2 (text &amp; default_ "foo"))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ADD COLUMN col2 text DEFAULT E'foo';"
--   </pre>
addColumnDefault :: KnownSymbol column => Alias column -> TypeExpression ( 'Optional ty) -> AlterColumns columns (Create column ( 'Optional ty) columns)

-- | An <a>addColumnDefault</a> adds a new <a>Null</a> column. The new
--   column is initially filled with <tt>NULL</tt>s.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Required ('Null 'PGtext) ]]
--     definition = alterTable #tab (addColumnNull #col2 text)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ADD COLUMN col2 text;"
--   </pre>
addColumnNull :: KnownSymbol column => Alias column -> TypeExpression ( 'Required ( 'Null ty)) -> AlterColumns columns (Create column ( 'Required ( 'Null ty)) columns)

-- | A <a>dropColumn</a> removes a column. Whatever data was in the column
--   disappears. Table constraints involving the column are dropped, too.
--   However, if the column is referenced by a foreign key constraint of
--   another table, PostgreSQL will not silently drop that constraint.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Required ('Null 'PGtext) ]]
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (dropColumn #col2)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab DROP COLUMN col2;"
--   </pre>
dropColumn :: KnownSymbol column => Alias column -> AlterColumns columns (Drop column columns)

-- | Like <a>dropColumn</a> but authorizes dropping everything that depends
--   on the column.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Required ('Null 'PGtext) ]]
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (dropColumnCascade #col2)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab DROP COLUMN col2 CASCADE;"
--   </pre>
dropColumnCascade :: KnownSymbol column => Alias column -> AlterColumns columns (Drop column columns)

-- | A <a>renameColumn</a> renames a column.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["foo" ::: 'Required ('Null 'PGint4)]]
--       '["tab" ::: '["bar" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (renameColumn #foo #bar)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab RENAME COLUMN foo TO bar;"
--   </pre>
renameColumn :: (KnownSymbol column0, KnownSymbol column1) => Alias column0 -> Alias column1 -> AlterColumns columns (Rename column0 column1 columns)

-- | An <a>alterColumn</a> alters a single column.
alterColumn :: (KnownSymbol column, HasColumn column columns ty0) => Alias column -> AlterColumn ty0 ty1 -> AlterColumns columns (Alter column columns ty1)

-- | An <a>AlterColumn</a> describes the alteration to perform on a single
--   column.
newtype AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType)
UnsafeAlterColumn :: ByteString -> AlterColumn
[renderAlterColumn] :: AlterColumn -> ByteString

-- | A <a>setDefault</a> sets a new default for a column. Note that this
--   doesn't affect any existing rows in the table, it just changes the
--   default for future <tt>insertTable</tt> and <tt>updateTable</tt>
--   commands.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col (setDefault 5))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col SET DEFAULT 5;"
--   </pre>
setDefault :: Expression '[]  'Ungrouped '[] ( 'Required ty) -> AlterColumn (optionality ty) ( 'Optional ty)

-- | A <a>dropDefault</a> removes any default value for a column.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col dropDefault)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col DROP DEFAULT;"
--   </pre>
dropDefault :: AlterColumn (optionality ty) ( 'Required ty)

-- | A <a>setNotNull</a> adds a <tt>NOT NULL</tt> constraint to a column.
--   The constraint will be checked immediately, so the table data must
--   satisfy the constraint before it can be added.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col setNotNull)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col SET NOT NULL;"
--   </pre>
setNotNull :: AlterColumn (optionality ( 'Null ty)) (optionality ( 'NotNull ty))

-- | A <a>dropNotNull</a> drops a <tt>NOT NULL</tt> constraint from a
--   column.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col dropNotNull)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col DROP NOT NULL;"
--   </pre>
dropNotNull :: AlterColumn (optionality ( 'NotNull ty)) (optionality ( 'Null ty))

-- | An <a>alterType</a> converts a column to a different data type. This
--   will succeed only if each existing entry in the column can be
--   converted to the new type by an implicit cast.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGnumeric)]]
--     definition =
--       alterTable #tab (alterColumn #col (alterType (numeric &amp; notNull)))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col TYPE numeric NOT NULL;"
--   </pre>
alterType :: TypeExpression ty -> AlterColumn ty0 ty
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1)
instance GHC.Show.Show (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1)
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1)
instance GHC.Show.Show (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1)
instance GHC.Classes.Ord Squeal.PostgreSQL.Definition.OnUpdateClause
instance GHC.Classes.Eq Squeal.PostgreSQL.Definition.OnUpdateClause
instance GHC.Show.Show Squeal.PostgreSQL.Definition.OnUpdateClause
instance GHC.Generics.Generic Squeal.PostgreSQL.Definition.OnUpdateClause
instance GHC.Classes.Ord Squeal.PostgreSQL.Definition.OnDeleteClause
instance GHC.Classes.Eq Squeal.PostgreSQL.Definition.OnDeleteClause
instance GHC.Show.Show Squeal.PostgreSQL.Definition.OnDeleteClause
instance GHC.Generics.Generic Squeal.PostgreSQL.Definition.OnDeleteClause
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.TableConstraint schema columns)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.TableConstraint schema columns)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.TableConstraint schema columns)
instance GHC.Show.Show (Squeal.PostgreSQL.Definition.TableConstraint schema columns)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.TableConstraint schema columns)
instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.Definition schema0 schema1)
instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.Definition schema0 schema1)
instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.Definition schema0 schema1)
instance GHC.Show.Show (Squeal.PostgreSQL.Definition.Definition schema0 schema1)
instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.Definition schema0 schema1)
instance Control.DeepSeq.NFData Squeal.PostgreSQL.Definition.OnUpdateClause
instance Control.DeepSeq.NFData Squeal.PostgreSQL.Definition.OnDeleteClause
instance Control.Category.Category Squeal.PostgreSQL.Schema.TablesType Squeal.PostgreSQL.Definition.Definition


-- | Binary encoding and decoding between Haskell and PostgreSQL types.
module Squeal.PostgreSQL.Binary

-- | A <a>ToParam</a> constraint gives an encoding of a Haskell <a>Type</a>
--   into into the binary format of a PostgreSQL <a>PGType</a>.
class ToParam (x :: Type) (pg :: PGType)

-- | <pre>
--   &gt;&gt;&gt; :set -XTypeApplications -XDataKinds
--   
--   &gt;&gt;&gt; toParam @Bool @'PGbool False
--   K "\NUL"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; toParam @Int16 @'PGint2 0
--   K "\NUL\NUL"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; toParam @Int32 @'PGint4 0
--   K "\NUL\NUL\NUL\NUL"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; :set -XMultiParamTypeClasses
--   
--   &gt;&gt;&gt; newtype Id = Id { getId :: Int16 } deriving Show
--   
--   &gt;&gt;&gt; instance ToParam Id 'PGint2 where toParam = toParam . getId
--   
--   &gt;&gt;&gt; toParam @Id @'PGint2 (Id 1)
--   K "\NUL\SOH"
--   </pre>
toParam :: ToParam x pg => x -> K Encoding pg

-- | A <a>ToColumnParam</a> constraint lifts the <a>ToParam</a> encoding of
--   a <a>Type</a> to a <a>ColumnType</a>, encoding <a>Maybe</a>s to
--   <a>Null</a>s. You should not define instances of <a>ToColumnParam</a>,
--   just use the provided instances.
class ToColumnParam (x :: Type) (ty :: ColumnType)

-- | <pre>
--   &gt;&gt;&gt; toColumnParam @Int16 @('Required ('NotNull 'PGint2)) 0
--   K (Just "\NUL\NUL")
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; toColumnParam @(Maybe Int16) @('Required ('Null 'PGint2)) (Just 0)
--   K (Just "\NUL\NUL")
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; toColumnParam @(Maybe Int16) @('Required ('Null 'PGint2)) Nothing
--   K Nothing
--   </pre>
toColumnParam :: ToColumnParam x ty => x -> K (Maybe ByteString) ty

-- | A <a>ToParams</a> constraint generically sequences the encodings of
--   <a>Type</a>s of the fields of a tuple or record to a row of
--   <a>ColumnType</a>s. You should not define instances of
--   <a>ToParams</a>. Instead define <a>Generic</a> instances which in turn
--   provide <a>ToParams</a> instances.
class SListI tys => ToParams (x :: Type) (tys :: [ColumnType])

-- | <pre>
--   &gt;&gt;&gt; type PGparams = '[ 'Required ('NotNull 'PGbool), 'Required ('Null 'PGint2)]
--   
--   &gt;&gt;&gt; toParams @(Bool, Maybe Int16) @PGparams (False, Just 0)
--   K (Just "\NUL") :* (K (Just "\NUL\NUL") :* Nil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; :set -XDeriveGeneric
--   
--   &gt;&gt;&gt; data Hparams = Hparams { col1 :: Bool, col2 :: Maybe Int16} deriving GHC.Generic
--   
--   &gt;&gt;&gt; instance Generic Hparams
--   
--   &gt;&gt;&gt; toParams @Hparams @PGparams (Hparams False (Just 0))
--   K (Just "\NUL") :* (K (Just "\NUL\NUL") :* Nil)
--   </pre>
toParams :: ToParams x tys => x -> NP (K (Maybe ByteString)) tys

-- | A <a>FromValue</a> constraint gives a parser from the binary format of
--   a PostgreSQL <a>PGType</a> into a Haskell <a>Type</a>.
class FromValue (pg :: PGType) (y :: Type)

-- | <pre>
--   &gt;&gt;&gt; newtype Id = Id { getId :: Int16 } deriving Show
--   
--   &gt;&gt;&gt; instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
--   </pre>
fromValue :: FromValue pg y => proxy pg -> Value y

-- | A <a>FromColumnValue</a> constraint lifts the <a>FromValue</a> parser
--   to a decoding of a <tt>(Symbol, ColumnType)</tt> to a <a>Type</a>,
--   decoding <a>Null</a>s to <a>Maybe</a>s. You should not define
--   instances for <a>FromColumnValue</a>, just use the provided instances.
class FromColumnValue (colty :: (Symbol, ColumnType)) (y :: Type)

-- | <pre>
--   &gt;&gt;&gt; :set -XTypeOperators -XOverloadedStrings
--   
--   &gt;&gt;&gt; newtype Id = Id { getId :: Int16 } deriving Show
--   
--   &gt;&gt;&gt; instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
--   
--   &gt;&gt;&gt; fromColumnValue @("col" ::: 'Required ('NotNull 'PGint2)) @Id (K (Just "\NUL\SOH"))
--   Id {getId = 1}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromColumnValue @("col" ::: 'Required ('Null 'PGint2)) @(Maybe Id) (K (Just "\NUL\SOH"))
--   Just (Id {getId = 1})
--   </pre>
fromColumnValue :: FromColumnValue colty y => K (Maybe ByteString) colty -> y

-- | A <a>FromRow</a> constraint generically sequences the parsings of the
--   columns of a <a>ColumnsType</a> into the fields of a record
--   <a>Type</a> provided they have the same field names. You should not
--   define instances of <a>FromRow</a>. Instead define <a>Generic</a> and
--   <a>HasDatatypeInfo</a> instances which in turn provide <a>FromRow</a>
--   instances.
class SListI results => FromRow (results :: ColumnsType) y

-- | <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; import Data.Text
--   
--   &gt;&gt;&gt; newtype Id = Id { getId :: Int16 } deriving Show
--   
--   &gt;&gt;&gt; instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
--   
--   &gt;&gt;&gt; data Hrow = Hrow { userId :: Id, userName :: Maybe Text } deriving (Show, GHC.Generic)
--   
--   &gt;&gt;&gt; instance Generic Hrow
--   
--   &gt;&gt;&gt; instance HasDatatypeInfo Hrow
--   
--   &gt;&gt;&gt; type PGrow = '["userId" ::: 'Required ('NotNull 'PGint2), "userName" ::: 'Required ('Null 'PGtext)]
--   
--   &gt;&gt;&gt; fromRow @PGrow @Hrow (K (Just "\NUL\SOH") :* K (Just "bloodninja") :* Nil)
--   Hrow {userId = Id {getId = 1}, userName = Just "bloodninja"}
--   </pre>
fromRow :: FromRow results y => NP (K (Maybe ByteString)) results -> y

-- | <a>Only</a> is a 1-tuple type, useful for encoding a single parameter
--   with <a>toParams</a> or decoding a single value with <a>fromRow</a>.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Text
--   
--   &gt;&gt;&gt; toParams @(Only (Maybe Text)) @'[ 'Required ('Null 'PGtext)] (Only (Just "foo"))
--   K (Just "foo") :* Nil
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; type PGShortRow = '["fromOnly" ::: 'Required ('Null 'PGtext)]
--   
--   &gt;&gt;&gt; fromRow @PGShortRow @(Only (Maybe Text)) (K (Just "bar") :* Nil)
--   Only {fromOnly = Just "bar"}
--   </pre>
newtype Only x
Only :: x -> Only x
[fromOnly] :: Only x -> x
instance GHC.Generics.Generic (Squeal.PostgreSQL.Binary.Only x)
instance GHC.Show.Show x => GHC.Show.Show (Squeal.PostgreSQL.Binary.Only x)
instance GHC.Read.Read x => GHC.Read.Read (Squeal.PostgreSQL.Binary.Only x)
instance GHC.Classes.Ord x => GHC.Classes.Ord (Squeal.PostgreSQL.Binary.Only x)
instance GHC.Classes.Eq x => GHC.Classes.Eq (Squeal.PostgreSQL.Binary.Only x)
instance Data.Traversable.Traversable Squeal.PostgreSQL.Binary.Only
instance Data.Foldable.Foldable Squeal.PostgreSQL.Binary.Only
instance GHC.Base.Functor Squeal.PostgreSQL.Binary.Only
instance Generics.SOP.Universe.Generic (Squeal.PostgreSQL.Binary.Only x)
instance Generics.SOP.Universe.HasDatatypeInfo (Squeal.PostgreSQL.Binary.Only x)
instance (Generics.SOP.Sing.SListI (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) results, Generics.SOP.Universe.IsProductType y ys, Generics.SOP.Constraint.AllZip (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) * Squeal.PostgreSQL.Binary.FromColumnValue results ys, Squeal.PostgreSQL.Schema.SameFields (Generics.SOP.Universe.DatatypeInfoOf y) results) => Squeal.PostgreSQL.Binary.FromRow results y
instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromColumnValue ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column ('Squeal.PostgreSQL.Schema.Required ('Squeal.PostgreSQL.Schema.NotNull pg))) y
instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromColumnValue ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column ('Squeal.PostgreSQL.Schema.Required ('Squeal.PostgreSQL.Schema.Null pg))) (GHC.Base.Maybe y)
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGbool GHC.Types.Bool
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGint2 GHC.Int.Int16
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGint4 GHC.Int.Int32
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGint8 GHC.Int.Int64
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGfloat4 GHC.Types.Float
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGfloat8 GHC.Types.Double
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGnumeric Data.Scientific.Scientific
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGuuid Data.UUID.Types.Internal.UUID
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGinet (Network.IP.Addr.NetAddr Network.IP.Addr.IP)
instance Squeal.PostgreSQL.Binary.FromValue ('Squeal.PostgreSQL.Schema.PGchar 1) GHC.Types.Char
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtext Data.Text.Internal.Text
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtext Data.Text.Internal.Lazy.Text
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGbytea Data.ByteString.Internal.ByteString
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGbytea Data.ByteString.Lazy.Internal.ByteString
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGdate Data.Time.Calendar.Days.Day
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtime Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtimetz (Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay, Data.Time.LocalTime.Internal.TimeZone.TimeZone)
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtimestamp Data.Time.LocalTime.Internal.LocalTime.LocalTime
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtimestamptz Data.Time.Clock.Internal.UTCTime.UTCTime
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGinterval Data.Time.Clock.Internal.DiffTime.DiffTime
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGjson Data.Aeson.Types.Internal.Value
instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGjsonb Data.Aeson.Types.Internal.Value
instance (Generics.SOP.Sing.SListI Squeal.PostgreSQL.Schema.ColumnType tys, Generics.SOP.Universe.IsProductType x xs, Generics.SOP.Constraint.AllZip * Squeal.PostgreSQL.Schema.ColumnType Squeal.PostgreSQL.Binary.ToColumnParam xs tys) => Squeal.PostgreSQL.Binary.ToParams x tys
instance Squeal.PostgreSQL.Binary.ToParam x pg => Squeal.PostgreSQL.Binary.ToColumnParam x (optionality ('Squeal.PostgreSQL.Schema.NotNull pg))
instance Squeal.PostgreSQL.Binary.ToParam x pg => Squeal.PostgreSQL.Binary.ToColumnParam (GHC.Base.Maybe x) (optionality ('Squeal.PostgreSQL.Schema.Null pg))
instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Bool 'Squeal.PostgreSQL.Schema.PGbool
instance Squeal.PostgreSQL.Binary.ToParam GHC.Int.Int16 'Squeal.PostgreSQL.Schema.PGint2
instance Squeal.PostgreSQL.Binary.ToParam GHC.Word.Word16 'Squeal.PostgreSQL.Schema.PGint2
instance Squeal.PostgreSQL.Binary.ToParam GHC.Int.Int32 'Squeal.PostgreSQL.Schema.PGint4
instance Squeal.PostgreSQL.Binary.ToParam GHC.Word.Word32 'Squeal.PostgreSQL.Schema.PGint4
instance Squeal.PostgreSQL.Binary.ToParam GHC.Int.Int64 'Squeal.PostgreSQL.Schema.PGint8
instance Squeal.PostgreSQL.Binary.ToParam GHC.Word.Word64 'Squeal.PostgreSQL.Schema.PGint8
instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Float 'Squeal.PostgreSQL.Schema.PGfloat4
instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Double 'Squeal.PostgreSQL.Schema.PGfloat8
instance Squeal.PostgreSQL.Binary.ToParam Data.Scientific.Scientific 'Squeal.PostgreSQL.Schema.PGnumeric
instance Squeal.PostgreSQL.Binary.ToParam Data.UUID.Types.Internal.UUID 'Squeal.PostgreSQL.Schema.PGuuid
instance Squeal.PostgreSQL.Binary.ToParam (Network.IP.Addr.NetAddr Network.IP.Addr.IP) 'Squeal.PostgreSQL.Schema.PGinet
instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Char ('Squeal.PostgreSQL.Schema.PGchar 1)
instance Squeal.PostgreSQL.Binary.ToParam Data.Text.Internal.Text 'Squeal.PostgreSQL.Schema.PGtext
instance Squeal.PostgreSQL.Binary.ToParam Data.Text.Internal.Lazy.Text 'Squeal.PostgreSQL.Schema.PGtext
instance Squeal.PostgreSQL.Binary.ToParam Data.ByteString.Internal.ByteString 'Squeal.PostgreSQL.Schema.PGbytea
instance Squeal.PostgreSQL.Binary.ToParam Data.ByteString.Lazy.Internal.ByteString 'Squeal.PostgreSQL.Schema.PGbytea
instance Squeal.PostgreSQL.Binary.ToParam Data.Time.Calendar.Days.Day 'Squeal.PostgreSQL.Schema.PGdate
instance Squeal.PostgreSQL.Binary.ToParam Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay 'Squeal.PostgreSQL.Schema.PGtime
instance Squeal.PostgreSQL.Binary.ToParam (Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay, Data.Time.LocalTime.Internal.TimeZone.TimeZone) 'Squeal.PostgreSQL.Schema.PGtimetz
instance Squeal.PostgreSQL.Binary.ToParam Data.Time.LocalTime.Internal.LocalTime.LocalTime 'Squeal.PostgreSQL.Schema.PGtimestamp
instance Squeal.PostgreSQL.Binary.ToParam Data.Time.Clock.Internal.UTCTime.UTCTime 'Squeal.PostgreSQL.Schema.PGtimestamptz
instance Squeal.PostgreSQL.Binary.ToParam Data.Time.Clock.Internal.DiffTime.DiffTime 'Squeal.PostgreSQL.Schema.PGinterval
instance Squeal.PostgreSQL.Binary.ToParam Data.Aeson.Types.Internal.Value 'Squeal.PostgreSQL.Schema.PGjson
instance Squeal.PostgreSQL.Binary.ToParam Data.Aeson.Types.Internal.Value 'Squeal.PostgreSQL.Schema.PGjsonb


-- | <a>PQ</a> is where Squeal statements come to actually get run by
--   <tt>LibPQ</tt>. It contains a <a>PQ</a> indexed monad transformer to
--   run <a>Definition</a>s and a <a>MonadPQ</a> constraint for running a
--   <a>Manipulation</a> or <a>Query</a>.
module Squeal.PostgreSQL.PQ

-- | A <a>Connection</a> consists of a <a>LibPQ</a> <a>Connection</a> and a
--   phantom <a>TablesType</a>
newtype Connection (schema :: TablesType)
Connection :: Connection -> Connection
[unConnection] :: Connection -> Connection

-- | Makes a new connection to the database server.
--   
--   This function opens a new database connection using the parameters
--   taken from the string conninfo.
--   
--   The passed string can be empty to use all default parameters, or it
--   can contain one or more parameter settings separated by whitespace.
--   Each parameter setting is in the form keyword = value. Spaces around
--   the equal sign are optional. To write an empty value or a value
--   containing spaces, surround it with single quotes, e.g., keyword = 'a
--   value'. Single quotes and backslashes within the value must be escaped
--   with a backslash, i.e., ' and .
--   
--   To specify the schema you wish to connect with, use type application.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XDataKinds
--   
--   &gt;&gt;&gt; :set -XTypeOperators
--   
--   &gt;&gt;&gt; type Schema = '["tab" ::: '["col" ::: 'Required ('Null 'PGint2)]]
--   
--   &gt;&gt;&gt; :set -XTypeApplications
--   
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; conn &lt;- connectdb @Schema "host=localhost port=5432 dbname=exampledb"
--   </pre>
--   
--   Note that, for now, squeal doesn't offer any protection from
--   connecting with the wrong schema!
connectdb :: forall schema io. MonadBase IO io => ByteString -> io (Connection schema)

-- | Closes the connection to the server.
finish :: MonadBase IO io => Connection schema -> io ()

-- | Do <a>connectdb</a> and <a>finish</a> before and after a computation.
withConnection :: forall schema0 schema1 io x. MonadBaseControl IO io => ByteString -> (Connection schema0 -> io (x, Connection schema1)) -> io x

-- | We keep track of the schema via an Atkey indexed state monad
--   transformer, <a>PQ</a>.
newtype PQ (schema0 :: TablesType) (schema1 :: TablesType) (m :: Type -> Type) (x :: Type)
PQ :: (Connection schema0 -> m (x, Connection schema1)) -> PQ
[runPQ] :: PQ -> Connection schema0 -> m (x, Connection schema1)

-- | Run a <a>PQ</a> and discard the result but keep the <a>Connection</a>.
execPQ :: Functor m => PQ schema0 schema1 m x -> Connection schema0 -> m (Connection schema1)

-- | indexed analog of <a>&lt;*&gt;</a>
pqAp :: Monad m => PQ schema0 schema1 m (x -> y) -> PQ schema1 schema2 m x -> PQ schema0 schema2 m y

-- | indexed analog of <a>=&lt;&lt;</a>
pqBind :: Monad m => (x -> PQ schema1 schema2 m y) -> PQ schema0 schema1 m x -> PQ schema0 schema2 m y

-- | indexed analog of flipped <a>&gt;&gt;</a>
pqThen :: Monad m => PQ schema1 schema2 m y -> PQ schema0 schema1 m x -> PQ schema0 schema2 m y

-- | Run a <a>Definition</a> with <a>exec</a>, we expect that libpq obeys
--   the law
--   
--   <pre>
--   define statement1 &amp; thenDefine statement2 = define (statement1 &gt;&gt;&gt; statement2)
--   </pre>
define :: MonadBase IO io => Definition schema0 schema1 -> PQ schema0 schema1 io (Result '[])

-- | Chain together <a>define</a> actions.
thenDefine :: MonadBase IO io => Definition schema1 schema2 -> PQ schema0 schema1 io x -> PQ schema0 schema2 io (Result '[])

-- | <a>MonadPQ</a> is an <tt>mtl</tt> style constraint, similar to
--   <a>MonadState</a>, for using <tt>LibPQ</tt> to
--   
--   <ul>
--   <li><a>manipulateParams</a> runs a <a>Manipulation</a> with params
--   from a type with a <a>ToParams</a> constraint. It calls
--   <a>execParams</a> and doesn't afraid of anything.</li>
--   <li><a>manipulate</a> is like <a>manipulateParams</a> for a
--   parameter-free statement.</li>
--   <li><a>runQueryParams</a> is like <a>manipulateParams</a> for query
--   statements.</li>
--   <li><a>traversePrepared</a> has the same type signature as a
--   composition of <a>traverse</a> and <a>manipulateParams</a> but
--   provides an optimization by preparing the statement with
--   <a>prepare</a> and then traversing a <a>Traversable</a> container with
--   <a>execPrepared</a>. The temporary prepared statement is then
--   deallocated.</li>
--   <li><a>forPrepared</a> is a flipped <a>traversePrepared</a></li>
--   <li><a>traversePrepared_</a> is like <a>traversePrepared</a> but works
--   on <a>Foldable</a> containers and returns unit.</li>
--   <li><a>forPrepared_</a> is a flipped <a>traversePrepared_</a>.</li>
--   <li><a>liftPQ</a> lets you lift actions from <tt>LibPQ</tt> that
--   require a connection into your monad.</li>
--   </ul>
--   
--   To define an instance, you can minimally define only
--   <a>manipulateParams</a>, <a>traversePrepared</a>,
--   <a>traversePrepared_</a> and <a>liftPQ</a>. Monad transformers get a
--   default instance.
class Monad pq => MonadPQ schema pq | pq -> schema
manipulateParams :: (MonadPQ schema pq, ToParams x params) => Manipulation schema params ys -> x -> pq (Result ys)
manipulateParams :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => ToParams x params => Manipulation schema params ys -> x -> pq (Result ys)
manipulate :: MonadPQ schema pq => Manipulation schema '[] ys -> pq (Result ys)
runQueryParams :: (MonadPQ schema pq, ToParams x params) => Query schema params ys -> x -> pq (Result ys)
runQuery :: MonadPQ schema pq => Query schema '[] ys -> pq (Result ys)
traversePrepared :: (MonadPQ schema pq, ToParams x params, Traversable list) => Manipulation schema params ys -> list x -> pq (list (Result ys))
traversePrepared :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (ToParams x params, Traversable list) => Manipulation schema params ys -> list x -> pq (list (Result ys))
forPrepared :: (MonadPQ schema pq, ToParams x params, Traversable list) => list x -> Manipulation schema params ys -> pq (list (Result ys))
traversePrepared_ :: (MonadPQ schema pq, ToParams x params, Foldable list) => Manipulation schema params '[] -> list x -> pq ()
traversePrepared_ :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (ToParams x params, Foldable list) => Manipulation schema params '[] -> list x -> pq ()
forPrepared_ :: (MonadPQ schema pq, ToParams x params, Foldable list) => list x -> Manipulation schema params '[] -> pq ()
liftPQ :: MonadPQ schema pq => (Connection -> IO a) -> pq a
liftPQ :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (Connection -> IO a) -> pq a

-- | A snapshot of the state of a <a>PQ</a> computation.
type PQRun schema = forall m x. Monad m => PQ schema schema m x -> m (x, Connection schema)

-- | Helper function in defining <a>MonadBaseControl</a> instance for
--   <a>PQ</a>.
pqliftWith :: Functor m => (PQRun schema -> m a) -> PQ schema schema m a

-- | Encapsulates the result of a squeal command run by <tt>LibPQ</tt>.
--   <a>Result</a>s are parameterized by a <a>ColumnsType</a> describing
--   the column names and their types.
newtype Result (columns :: ColumnsType)
Result :: Result -> Result
[unResult] :: Result -> Result

-- | Just newtypes around a <tt>CInt</tt>
newtype RowNumber
RowNumber :: Row -> RowNumber
[unRowNumber] :: RowNumber -> Row

-- | In addition to being newtypes around a <tt>CInt</tt>, a
--   <a>ColumnNumber</a> is parameterized by a <a>Nat</a>ural number and
--   acts as an index into a row.
newtype ColumnNumber (n :: Nat) (cs :: [k]) (c :: k)
UnsafeColumnNumber :: Column -> ColumnNumber
[getColumnNumber] :: ColumnNumber -> Column

-- | <pre>
--   &gt;&gt;&gt; getColumnNumber (columnNumber @5 @'[_,_,_,_,_,_])
--   Col 5
--   </pre>
class KnownNat n => HasColumnNumber n columns column | n columns -> column
columnNumber :: HasColumnNumber n columns column => ColumnNumber n columns column

-- | Get a single value corresponding to a given row and column number from
--   a <a>Result</a>.
getValue :: (FromColumnValue colty y, MonadBase IO io) => RowNumber -> ColumnNumber n columns colty -> Result columns -> io y

-- | Get a row corresponding to a given row number from a <a>Result</a>.
getRow :: (FromRow columns y, MonadBase IO io) => RowNumber -> Result columns -> io y

-- | Get all rows from a <a>Result</a>.
getRows :: (FromRow columns y, MonadBase IO io) => Result columns -> io [y]

-- | Returns the number of rows (tuples) in the query result.
ntuples :: MonadBase IO io => Result columns -> io RowNumber

-- | Intended to be used for unfolding in streaming libraries,
--   <a>nextRow</a> takes a total number of rows (which can be found with
--   <a>ntuples</a>) and a <a>Result</a> and given a row number if it's too
--   large returns <a>Nothing</a>, otherwise returning the row along with
--   the next row number.
nextRow :: (FromRow columns y, MonadBase IO io) => RowNumber -> Result columns -> RowNumber -> io (Maybe (RowNumber, y))

-- | Get the first row if possible from a <a>Result</a>.
firstRow :: (FromRow columns y, MonadBase IO io) => Result columns -> io (Maybe y)

-- | Lifts actions on results from <tt>LibPQ</tt>.
liftResult :: MonadBase IO io => (Result -> IO x) -> Result results -> io x
instance GHC.Base.Functor m => GHC.Base.Functor (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m)
instance forall k (column1 :: k) (columns :: [k]). Squeal.PostgreSQL.PQ.HasColumnNumber k 0 ((':) k column1 columns) column1
instance forall k (n :: GHC.Types.Nat) (columns :: [k]) (column :: k) (column' :: k). (GHC.TypeNats.KnownNat n, Squeal.PostgreSQL.PQ.HasColumnNumber k (n GHC.TypeNats.- 1) columns column) => Squeal.PostgreSQL.PQ.HasColumnNumber k n ((':) k column' columns) column
instance Control.Monad.Base.MonadBase GHC.Types.IO io => Squeal.PostgreSQL.PQ.MonadPQ schema (Squeal.PostgreSQL.PQ.PQ schema schema io)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Identity.IdentityT * m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Reader.ReaderT * r m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.State.Strict.StateT s m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.State.Lazy.StateT s m)
instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Maybe.MaybeT m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Except.ExceptT e m)
instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Cont.ContT * r m)
instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.List.ListT m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Squeal.PostgreSQL.PQ.PQ schema schema m)
instance GHC.Base.Monad m => GHC.Base.Monad (Squeal.PostgreSQL.PQ.PQ schema schema m)
instance Control.Monad.Trans.Class.MonadTrans (Squeal.PostgreSQL.PQ.PQ schema schema)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Squeal.PostgreSQL.PQ.PQ schema schema m)
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Squeal.PostgreSQL.PQ.PQ schema schema m)


-- | Squeal is a deep embedding of PostgreSQL in Haskell. Let's see an
--   example!
--   
--   First, we need some language extensions because Squeal uses modern GHC
--   features.
--   
--   <pre>
--   {-# LANGUAGE
--       DataKinds
--     , DeriveGeneric
--     , OverloadedLabels
--     , OverloadedStrings
--     , TypeApplications
--     , TypeOperators
--   #-}
--   </pre>
--   
--   Here comes the <tt>Main</tt> module and imports.
--   
--   <pre>
--   module Main (main) where
--   
--   import Control.Monad.Base (liftBase)
--   import Data.Int (Int32)
--   import Data.Text (Text)
--   
--   import Squeal.PostgreSQL
--   </pre>
--   
--   We'll use generics to easily convert between Haskell and PostgreSQL
--   values.
--   
--   <pre>
--   import qualified Generics.SOP as SOP
--   import qualified GHC.Generics as GHC
--   </pre>
--   
--   The first step is to define the schema of our database. This is where
--   we use <tt>DataKinds</tt> and <tt>TypeOperators</tt>. The schema
--   consists of a type-level list of tables, a <a>:::</a> pairing of a
--   type level string or <tt>Symbol</tt> and a list a columns, itself a
--   <a>:::</a> pairing of a <tt>Symbol</tt> and a <a>ColumnType</a>. The
--   <a>ColumnType</a> describes the PostgreSQL type of the column as well
--   as whether or not it may contain <tt>NULL</tt> and whether or not
--   inserts and updates can use a <tt>DEFAULT</tt>. For our schema, we'll
--   define two tables, a users table and an emails table.
--   
--   <pre>
--   type Schema =
--     '[ "users"  :::
--          '[ "id"   ::: 'Optional ('NotNull 'PGint4)
--           , "name" ::: 'Required ('NotNull 'PGtext)
--           ]
--      , "emails" :::
--          '[ "id"      ::: 'Optional ('NotNull 'PGint4)
--           , "user_id" ::: 'Required ('NotNull 'PGint4)
--           , "email"   ::: 'Required ('Null 'PGtext)
--           ]
--      ]
--   </pre>
--   
--   Next, we'll write <a>Definition</a>s to set up and tear down the
--   schema. In Squeal, a <a>Definition</a> is a <a>createTable</a>,
--   <a>alterTable</a> or <a>dropTable</a> command and has two type
--   parameters, corresponding to the schema before being run and the
--   schema after. We can compose definitions using <a>&gt;&gt;&gt;</a>.
--   Here and in the rest of our commands we make use of overloaded labels
--   to refer to named tables and columns in our schema.
--   
--   <pre>
--   setup :: Definition '[] Schema
--   setup = 
--     createTable #users
--       ( serial `As` #id :*
--         (text &amp; notNull) `As` #name :* Nil )
--       [ primaryKey (Column #id :* Nil) ]
--     &gt;&gt;&gt;
--     createTable #emails
--       ( serial `As` #id :*
--         (int &amp; notNull) `As` #user_id :*
--         text `As` #email :* Nil )
--       [ primaryKey (Column #id :* Nil)
--       , foreignKey (Column #user_id :* Nil) #users (Column #id :* Nil)
--         OnDeleteCascade OnUpdateCascade ]
--   </pre>
--   
--   Notice that <tt>setup</tt> starts with an empty schema <tt>'[]</tt>
--   and produces <tt>Schema</tt>. In our <a>createTable</a> commands we
--   included <a>TableConstraint</a>s to define primary and foreign keys,
--   making them somewhat complex. Our tear down <a>Definition</a> is
--   simpler.
--   
--   <pre>
--   teardown :: Definition Schema '[]
--   teardown = dropTable #emails &gt;&gt;&gt; dropTable #users
--   </pre>
--   
--   Next, we'll write <a>Manipulation</a>s to insert data into our two
--   tables. A <a>Manipulation</a> is a <a>insertInto</a>, <a>update</a> or
--   <a>deleteFrom</a> command and has three type parameters, the schema it
--   refers to, a list of parameters it can take as input, and a list of
--   columns it produces as output. When we insert into the users table, we
--   will need a parameter for the <tt>name</tt> field but not for the
--   <tt>id</tt> field. Since it's optional, we can use a default value.
--   However, since the emails table refers to the users table, we will
--   need to retrieve the user id that the insert generates and insert it
--   into the emails table. Take a careful look at the type and definition
--   of both of our inserts.
--   
--   <pre>
--   insertUser :: Manipulation Schema
--     '[ 'Required ('NotNull 'PGtext)]
--     '[ "fromOnly" ::: 'Required ('NotNull 'PGint4) ]
--   insertUser = insertInto #users
--     ( Values (def `As` #id :* param @1 `As` #name :* Nil) [] )
--     OnConflictDoNothing (Returning (#id `As` #fromOnly :* Nil))
--   
--   insertEmail :: Manipulation Schema
--     '[ 'Required ('NotNull 'PGint4), 'Required ('Null 'PGtext)] '[]
--   insertEmail = insertInto #emails ( Values
--     ( def `As` #id :*
--       param @1 `As` #user_id :*
--       param @2 `As` #email :* Nil) [] )
--     OnConflictDoNothing (Returning Nil)
--   </pre>
--   
--   Next we write a <a>Query</a> to retrieve users from the database.
--   We're not interested in the ids here, just the usernames and email
--   addresses. We need to use an inner join to get the right result. A
--   <a>Query</a> is like a <a>Manipulation</a> with the same kind of type
--   parameters.
--   
--   <pre>
--   getUsers :: Query Schema '[]
--     '[ "userName" ::: 'Required ('NotNull 'PGtext)
--      , "userEmail" ::: 'Required ('Null 'PGtext) ]
--   getUsers = select
--     (#u ! #name `As` #userName :* #e ! #email `As` #userEmail :* Nil)
--     ( from (Table (#users `As` #u)
--       &amp; InnerJoin (Table (#emails `As` #e))
--         (#u ! #id .== #e ! #user_id)) )
--   </pre>
--   
--   Now that we've defined the SQL side of things, we'll need a Haskell
--   type for users. We give the type <a>Generic</a> and
--   <a>HasDatatypeInfo</a> instances so that we can decode the rows we
--   receive when we run <tt>getUsers</tt>. Notice that the record fields
--   of the <tt>User</tt> type match the column names of <tt>getUsers</tt>.
--   
--   <pre>
--   data User = User { userName :: Text, userEmail :: Maybe Text }
--     deriving (Show, GHC.Generic)
--   instance SOP.Generic User
--   instance SOP.HasDatatypeInfo User
--   </pre>
--   
--   Let's also create some users to add to the database.
--   
--   <pre>
--   users :: [User]
--   users = 
--     [ User "Alice" (Just "alice@gmail.com")
--     , User "Bob" Nothing
--     , User "Carole" (Just "carole@hotmail.com")
--     ]
--   </pre>
--   
--   Now we can put together all the pieces into a program. The program
--   connects to the database, sets up the schema, inserts the user data
--   (using prepared statements as an optimization), queries the user data
--   and prints it out and finally closes the connection. We can thread the
--   changing schema information through by using the indexed <a>PQ</a>
--   monad transformer and when the schema doesn't change we can use
--   <a>Monad</a> and <a>MonadPQ</a> functionality.
--   
--   <pre>
--   main :: IO ()
--   main = void $
--     withConnection "host=localhost port=5432 dbname=exampledb" . runPQ $
--       define setup
--       &amp; pqThen session
--       &amp; thenDefine teardown
--     where
--       session = do
--         idResults &lt;- traversePrepared insertUser (Only . userName &lt;$&gt; users)
--         ids &lt;- traverse (fmap fromOnly . getRow (RowNumber 0)) idResults
--         traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail &lt;$&gt; users))
--         usersResult &lt;- runQuery getUsers
--         usersRows &lt;- getRows usersResult
--         liftBase $ print (usersRows :: [User])
--   </pre>
module Squeal.PostgreSQL
