@@ -54,21 +54,21 @@ module Squeal.PostgreSQL.Query
57− -- ** JSON table expressions
57+ -- ** Json
60 , jsonEach
58 , jsonEach
61 , jsonbEach
59 , jsonbEach
62 , jsonEachAsText
60 , jsonEachAsText
63 , jsonbEachAsText
61 , jsonbEachAsText
64− , jsonPopulateRecordAs
62+ , jsonObjectKeys
65− , jsonbPopulateRecordAs
63+ , jsonbObjectKeys
66− , jsonPopulateRecordSetAs
64+ , jsonPopulateRecord
67− , jsonbPopulateRecordSetAs
65+ , jsonbPopulateRecord
68− , jsonToRecordAs
66+ , jsonPopulateRecordSet
69− , jsonbToRecordAs
67+ , jsonbPopulateRecordSet
70− , jsonToRecordSetAs
68+ , jsonToRecord
71− , jsonbToRecordSetAs
69+ , jsonbToRecord
73 , FromClause (..)
73 , FromClause (..)
@@ -90,8 +90,6 @@ module Squeal.PostgreSQL.Query
90 , SortExpression (..)
90 , SortExpression (..)
91 , renderSortExpression
91 , renderSortExpression
92 -- * Subquery expressions
92 -- * Subquery expressions
93− , unsafeSubqueryExpression
94− , unsafeRowSubqueryExpression
@@ -701,184 +699,144 @@ offset off rels = rels {offsetClause = off : offsetClause rels}
701JSON stuff
699JSON stuff
702-----------------------------------------}
700-----------------------------------------}
704−type PGjson_each_variant val tab =
702+unsafeSetOfFunction
705− '[ tab ::: '[ "key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull val ] ]
703+ :: ByteString
707−-- | The type of a `json_each` `FromClause`.
708−type PGjson_each tab = PGjson_each_variant 'PGjson tab
709−-- | The type of a `jsonb_each` `FromClause`.
710−type PGjsonb_each tab = PGjson_each_variant 'PGjsonb tab
711−-- | The type of a `json_each_text` `FromClause`.
712−type PGjson_each_text tab = PGjson_each_variant 'PGtext tab
713−-- | The type of a `jsonb_each_text` `FromClause`.
714−type PGjsonb_each_text tab = PGjson_each_variant 'PGtext tab
716−unsafeAliasedFromClauseExpression
717− :: Aliased (Expression schema' from' grouping' params') ty'
704+ -> Expression schema '[] 'Ungrouped params ty
718− -> FromClause schema params from
705+ -> Query schema params row
719−unsafeAliasedFromClauseExpression aliasedExpr = UnsafeFromClause
706+unsafeSetOfFunction fun expr = UnsafeQuery $
720− (renderAliasedAs renderExpression aliasedExpr)
707+ "SELECT * FROM " <> fun <> "(" <> renderExpression expr <> ")"
722-- | Expands the outermost JSON object into a set of key/value pairs.
709-- | Expands the outermost JSON object into a set of key/value pairs.
724− :: Aliased (Expression schema '[] 'Ungrouped params) '(tab, nullity 'PGjson)
711+ :: Expression schema '[] 'Ungrouped params (nullity 'PGjson) -- ^ json
725− -> FromClause schema params (PGjson_each tab)
712+ -> Query schema params
726−jsonEach (As jexpr jname) = unsafeAliasedFromClauseExpression
713+ '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGjson]
727− (As (unsafeFunction "json_each" jexpr) jname)
714+jsonEach = unsafeSetOfFunction "json_each"
729-- | Expands the outermost binary JSON object into a set of key/value pairs.
716-- | Expands the outermost binary JSON object into a set of key/value pairs.
731− :: Aliased (Expression schema '[] 'Ungrouped params) '(tab, nullity 'PGjsonb)
718+ :: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -- ^ jsonb
732− -> FromClause schema params (PGjsonb_each tab)
719+ -> Query schema params
733−jsonbEach (As jexpr jname) = unsafeAliasedFromClauseExpression
720+ '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGjsonb]
734− (As (unsafeFunction "jsonb_each" jexpr) jname)
721+jsonbEach = unsafeSetOfFunction "jsonb_each"
736-- | Expands the outermost JSON object into a set of key/value pairs.
723-- | Expands the outermost JSON object into a set of key/value pairs.
737jsonEachAsText
724jsonEachAsText
738− :: Aliased (Expression schema '[] 'Ungrouped params) '(tab, nullity 'PGjson)
725+ :: Expression schema '[] 'Ungrouped params (nullity 'PGjson) -- ^ json
739− -> FromClause schema params (PGjson_each_text tab)
726+ -> Query schema params
740−jsonEachAsText (As jexpr jname) = unsafeAliasedFromClauseExpression
727+ '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGtext]
741− (As (unsafeFunction "json_each" jexpr) jname)
728+jsonEachAsText = unsafeSetOfFunction "json_each_text"
743-- | Expands the outermost binary JSON object into a set of key/value pairs.
730-- | Expands the outermost binary JSON object into a set of key/value pairs.
744jsonbEachAsText
731jsonbEachAsText
745− :: Aliased (Expression schema '[] 'Ungrouped params) '(tab, nullity 'PGjsonb)
732+ :: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -- ^ jsonb
746− -> FromClause schema params (PGjsonb_each_text tab)
733+ -> Query schema params
747−jsonbEachAsText (As jexpr jname) = unsafeAliasedFromClauseExpression
734+ '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGtext]
748− (As (unsafeFunction "jsonb_each" jexpr) jname)
735+jsonbEachAsText = unsafeSetOfFunction "jsonb_each_text"
750−nullRow
737+-- | Returns set of keys in the outermost JSON object.
751− :: Has tab schema ('Table table)
738+jsonObjectKeys
752− => Alias tab
739+ :: Expression schema '[] 'Ungrouped params (nullity 'PGjson)
753− -> Expression schema from grouping params
740+ -> Query schema params '["json_object_keys" ::: 'NotNull 'PGtext]
741+jsonObjectKeys = unsafeSetOfFunction "json_object_keys"
743+-- | Returns set of keys in the outermost JSON object.
745+ :: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
746+ -> Query schema params '["jsonb_object_keys" ::: 'NotNull 'PGtext]
747+jsonbObjectKeys = unsafeSetOfFunction "jsonb_object_keys"
749+unsafePopulateFunction
754− (nullity ('PGcomposite (TableToRow table)))
751+ -> TypeExpression schema (nullity ('PGcomposite row))
755−nullRow tab = UnsafeExpression ("null::"<+>renderAlias tab)
752+ -> Expression schema '[] 'Ungrouped params ty
753+ -> Query schema params row
754+unsafePopulateFunction fun ty expr = UnsafeQuery $
755+ "SELECT * FROM " <> fun <> "("
756+ <> "null::" <> renderTypeExpression ty <> ", "
757+ <> renderExpression expr <> ")"
757-- | Expands the JSON expression to a row whose columns match the record
759-- | Expands the JSON expression to a row whose columns match the record
758-- type defined by the given table.
760-- type defined by the given table.
759−jsonPopulateRecordAs
761+jsonPopulateRecord
760− :: (KnownSymbol alias, Has tab schema ('Table table))
762+ :: TypeExpression schema (nullity ('PGcomposite row))
762 -> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
763 -> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
763− -> Alias alias
764+ -> Query schema params row
764− -> FromClause schema params '[alias ::: TableToRow table]
765+jsonPopulateRecord = unsafePopulateFunction "json_populate_record"
765−jsonPopulateRecordAs tableName expr alias = unsafeAliasedFromClauseExpression
766− (unsafeVariadicFunction "json_populate_record"
767− (nullRow tableName :* expr :* Nil) `As` alias)
769-- | Expands the binary JSON expression to a row whose columns match the record
767-- | Expands the binary JSON expression to a row whose columns match the record
770-- type defined by the given table.
768-- type defined by the given table.
771−jsonbPopulateRecordAs
769+jsonbPopulateRecord
772− :: (KnownSymbol alias, Has tab schema ('Table table))
770+ :: TypeExpression schema (nullity ('PGcomposite row))
774 -> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
771 -> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
775− -> Alias alias
772+ -> Query schema params row
776− -> FromClause schema params '[alias ::: TableToRow table]
777−jsonbPopulateRecordAs tableName expr alias = unsafeAliasedFromClauseExpression
778− (unsafeVariadicFunction "jsonb_populate_record"
773+jsonbPopulateRecord = unsafePopulateFunction "jsonb_populate_record"
779− (nullRow tableName :* expr :* Nil) `As` alias)
781-- | Expands the outermost array of objects in the given JSON expression to a
775-- | Expands the outermost array of objects in the given JSON expression to a
782-- set of rows whose columns match the record type defined by the given table.
776-- set of rows whose columns match the record type defined by the given table.
783−jsonPopulateRecordSetAs
777+jsonPopulateRecordSet
784− :: (KnownSymbol alias, Has tab schema ('Table table))
778+ :: TypeExpression schema (nullity ('PGcomposite row))
786 -> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
779 -> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
787− -> Alias alias
780+ -> Query schema params row
788− -> FromClause schema params '[alias ::: TableToRow table]
789−jsonPopulateRecordSetAs tableName expr alias = unsafeAliasedFromClauseExpression
790− (unsafeVariadicFunction "json_populate_record_set"
781+jsonPopulateRecordSet = unsafePopulateFunction "json_populate_record_set"
791− (nullRow tableName :* expr :* Nil) `As` alias)
793-- | Expands the outermost array of objects in the given binary JSON expression
783-- | Expands the outermost array of objects in the given binary JSON expression
794-- to a set of rows whose columns match the record type defined by the given
784-- to a set of rows whose columns match the record type defined by the given
796−jsonbPopulateRecordSetAs
786+jsonbPopulateRecordSet
797− :: (KnownSymbol alias, Has tab schema ('Table table))
787+ :: TypeExpression schema (nullity ('PGcomposite row))
799 -> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
788 -> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
800− -> Alias alias
789+ -> Query schema params row
801− -> FromClause schema params '[alias ::: TableToRow table]
802−jsonbPopulateRecordSetAs tableName expr alias = unsafeAliasedFromClauseExpression
803− (unsafeVariadicFunction "jsonb_populate_record_set"
790+jsonbPopulateRecordSet = unsafePopulateFunction "jsonb_populate_record_set"
804− (nullRow tableName :* expr :* Nil) `As` alias)
806−renderTableTypeExpression
792+unsafeRecordFunction
807− :: All Top types
793+ :: (SListI row, json `In` PGJsonType)
808− => Aliased (NP (Aliased (TypeExpression schema))) (tab ::: types)
794+ => ByteString
809− -> ByteString
795+ -> Expression schema '[] 'Ungrouped params (nullity json)
810−renderTableTypeExpression (hc `As` tab)
796+ -> NP (Aliased (TypeExpression schema)) row
811− = (renderAlias tab <>)
797+ -> Query schema params row
812− . parenthesized
798+unsafeRecordFunction fun expr types = UnsafeQuery $
813− . commaSeparated
799+ "SELECT * FROM " <> fun <> "("
816− (Proxy :: Proxy Top)
817− (\(ty `As` name) -> Endo
818− ((renderAlias name <+> renderTypeExpression ty):))
821−unsafeTableAliasedFromClauseExpression
823− => Expression schema' from' grouping' params' ty'
824− -> Aliased (NP (Aliased (TypeExpression schema))) (tab ::: types)
825− -> FromClause schema params '[alias ::: types]
826−unsafeTableAliasedFromClauseExpression expr types = UnsafeFromClause
827− (renderExpression expr
800+ <> renderExpression expr <> ")"
828− <+> "AS"
801+ <+> "AS" <+> "x" <> parenthesized (renderCommaSeparated renderTy types)
829− <+> renderTableTypeExpression types)
802+ where
830−
803+ renderTy :: Aliased (TypeExpression schema) ty -> ByteString
804+ renderTy (ty `As` alias) =
805+ renderAlias alias <+> renderTypeExpression ty
831−-- | Builds an arbitrary record from a JSON object. As with all functions
807+-- | Builds an arbitrary record from a JSON object.
832−-- returning record, the caller must explicitly define the structure of the
808+jsonToRecord
833−-- record with an AS clause.
809+ :: SListI row
836 => Expression schema '[] 'Ungrouped params (nullity 'PGjson)
810 => Expression schema '[] 'Ungrouped params (nullity 'PGjson)
837− -> Aliased (NP (Aliased (TypeExpression schema))) (tab ::: types)
811+ -> NP (Aliased (TypeExpression schema)) row
838− -> FromClause schema params '[tab ::: types]
812+ -> Query schema params row
839−jsonToRecordAs expr types =
813+jsonToRecord = unsafeRecordFunction "json_to_record"
840− unsafeTableAliasedFromClauseExpression
814+
841− (unsafeFunction "json_to_record" expr)
844−-- | Builds an arbitrary record from a binary JSON object. As with all functions
815+-- | Builds an arbitrary record from a binary JSON object.
845−-- returning record, the caller must explicitly define the structure of the
816+jsonbToRecord
846−-- record with an AS clause.
817+ :: SListI row
849 => Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
818 => Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
850− -> Aliased (NP (Aliased (TypeExpression schema))) (tab ::: types)
819+ -> NP (Aliased (TypeExpression schema)) row
851− -> FromClause schema params '[tab ::: types]
820+ -> Query schema params row
852−jsonbToRecordAs expr types =
821+jsonbToRecord = unsafeRecordFunction "jsonb_to_record"
853− unsafeTableAliasedFromClauseExpression
822+
854− (unsafeFunction "jsonb_to_record" expr)
857−-- | Builds an arbitrary set of records from a JSON array of objects (see note
823+-- | Builds an arbitrary set of records from a JSON array of objects.
858−-- below). As with all functions returning record, the caller must explicitly
824+jsonToRecordSet
859−-- define the structure of the record with an AS clause.
825+ :: SListI row
862 => Expression schema '[] 'Ungrouped params (nullity 'PGjson)
826 => Expression schema '[] 'Ungrouped params (nullity 'PGjson)
863− -> Aliased (NP (Aliased (TypeExpression schema))) (tab ::: types)
827+ -> NP (Aliased (TypeExpression schema)) row
864− -> FromClause schema params '[tab ::: types]
828+ -> Query schema params row
865−jsonToRecordSetAs expr types =
829+jsonToRecordSet = unsafeRecordFunction "json_to_record_set"
866− unsafeTableAliasedFromClauseExpression
867− (unsafeFunction "json_to_recordset" expr)
870-- | Builds an arbitrary set of records from a binary JSON array of objects (see
831-- | Builds an arbitrary set of records from a binary JSON array of objects (see
871-- note below). As with all functions returning record, the caller must
832-- note below). As with all functions returning record, the caller must
872-- explicitly define the structure of the record with an AS clause.
833-- explicitly define the structure of the record with an AS clause.
873−jsonbToRecordSetAs
834+jsonbToRecordSet
874− :: All Top types
835+ :: SListI row
875 => Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
836 => Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
876− -> Aliased (NP (Aliased (TypeExpression schema))) (tab ::: types)
837+ -> NP (Aliased (TypeExpression schema)) row
877− -> FromClause schema params '[tab ::: types]
838+ -> Query schema params row
878−jsonbToRecordSetAs expr types =
839+jsonbToRecordSet = unsafeRecordFunction "jsonb_to_record_set"
879− unsafeTableAliasedFromClauseExpression
880− (unsafeFunction "jsonb_to_recordset" expr)
883{-----------------------------------------
841{-----------------------------------------
884FROM clauses
842FROM clauses
@@ -908,9 +866,9 @@ subquery = UnsafeFromClause . renderAliasedAs (parenthesized . renderQuery)
909-- | `view` derives a table from a `View`.
867-- | `view` derives a table from a `View`.
911− :: Has view schema ('View rel)
869+ :: Has view schema ('View row)
912 => Aliased Alias (alias ::: view)
870 => Aliased Alias (alias ::: view)
913− -> FromClause schema params '[alias ::: rel]
871+ -> FromClause schema params '[alias ::: row]
914view (vw `As` alias) = UnsafeFromClause $
872view (vw `As` alias) = UnsafeFromClause $
915 renderAlias vw <+> "AS" <+> renderAlias alias
873 renderAlias vw <+> "AS" <+> renderAlias alias
@@ -1143,25 +1101,52 @@ unsafeRowSubqueryExpression
1143unsafeRowSubqueryExpression op xs q = UnsafeExpression $
1101unsafeRowSubqueryExpression op xs q = UnsafeExpression $
1144 renderExpression (row xs) <+> op <+> parenthesized (renderQuery q)
1102 renderExpression (row xs) <+> op <+> parenthesized (renderQuery q)
1104+-- | The right-hand side is a sub`Query`, which must return exactly one column.
1105+-- The left-hand expression is evaluated and compared to each row of the
1106+-- sub`Query` result. The result of `in_` is `true` if any equal subquery row is found.
1107+-- The result is `false` if no equal row is found
1108+-- (including the case where the subquery returns no rows).
1110+-- >>> printSQL $ true `in_` values_ (true `as` #foo)
1111+-- TRUE IN (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1147− :: Expression schema from grp params ty
1113+ :: Expression schema from grp params ty -- ^ expression
1148− -> Query schema params '[alias ::: ty]
1114+ -> Query schema params '[alias ::: ty] -- ^ subquery
1149 -> Condition schema from grp params
1115 -> Condition schema from grp params
1150in_ = unsafeSubqueryExpression "IN"
1116in_ = unsafeSubqueryExpression "IN"
1118+{- | The left-hand side of this form of `rowIn` is a row constructor.
1119+The right-hand side is a sub`Query`,
1120+which must return exactly as many columns as
1121+there are expressions in the left-hand row.
1122+The left-hand expressions are evaluated and compared row-wise to each row
1123+of the subquery result. The result of `rowIn`
1124+is `true` if any equal subquery row is found.
1125+The result is `false` if no equal row is found
1126+(including the case where the subquery returns no rows).
1128+>>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1129+>>> printSQL $ myRow `rowIn` values_ myRow
1130+ROW(1, FALSE) IN (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1153 :: SListI row
1133 :: SListI row
1154− => NP (Aliased (Expression schema from grp params)) row
1134+ => NP (Aliased (Expression schema from grp params)) row -- ^ row constructor
1155− -> Query schema params row
1135+ -> Query schema params row -- ^ subquery
1156 -> Condition schema from grp params
1136 -> Condition schema from grp params
1157rowIn = unsafeRowSubqueryExpression "IN"
1137rowIn = unsafeRowSubqueryExpression "IN"
1139+-- | >>> printSQL $ true `allEq` values_ (true `as` #foo)
1140+-- TRUE ALL = (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1160 :: Expression schema from grp params ty
1142 :: Expression schema from grp params ty
1161 -> Query schema params '[alias ::: ty]
1143 -> Query schema params '[alias ::: ty]
1162 -> Condition schema from grp params
1144 -> Condition schema from grp params
1163allEq = unsafeSubqueryExpression "ALL ="
1145allEq = unsafeSubqueryExpression "ALL ="
1147+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1148+-- >>> printSQL $ myRow `rowAllEq` values_ myRow
1149+-- ROW(1, FALSE) ALL = (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1166 :: SListI row
1151 :: SListI row
1167 => NP (Aliased (Expression schema from grp params)) row
1152 => NP (Aliased (Expression schema from grp params)) row
@@ -1169,12 +1154,17 @@ rowAllEq
1169 -> Condition schema from grp params
1154 -> Condition schema from grp params
1170rowAllEq = unsafeRowSubqueryExpression "ALL ="
1155rowAllEq = unsafeRowSubqueryExpression "ALL ="
1157+-- | >>> printSQL $ true `anyEq` values_ (true `as` #foo)
1158+-- TRUE ANY = (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1173 :: Expression schema from grp params ty
1160 :: Expression schema from grp params ty
1174 -> Query schema params '[alias ::: ty]
1161 -> Query schema params '[alias ::: ty]
1175 -> Condition schema from grp params
1162 -> Condition schema from grp params
1176anyEq = unsafeSubqueryExpression "ANY ="
1163anyEq = unsafeSubqueryExpression "ANY ="
1165+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1166+-- >>> printSQL $ myRow `rowAnyEq` values_ myRow
1167+-- ROW(1, FALSE) ANY = (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1179 :: SListI row
1169 :: SListI row
1180 => NP (Aliased (Expression schema from grp params)) row
1170 => NP (Aliased (Expression schema from grp params)) row
@@ -1182,12 +1172,17 @@ rowAnyEq
1182 -> Condition schema from grp params
1172 -> Condition schema from grp params
1183rowAnyEq = unsafeRowSubqueryExpression "ANY ="
1173rowAnyEq = unsafeRowSubqueryExpression "ANY ="
1175+-- | >>> printSQL $ true `allNeq` values_ (true `as` #foo)
1176+-- TRUE ALL <> (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1186 :: Expression schema from grp params ty
1178 :: Expression schema from grp params ty
1187 -> Query schema params '[alias ::: ty]
1179 -> Query schema params '[alias ::: ty]
1188 -> Condition schema from grp params
1180 -> Condition schema from grp params
1189allNeq = unsafeSubqueryExpression "ALL <>"
1181allNeq = unsafeSubqueryExpression "ALL <>"
1183+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1184+-- >>> printSQL $ myRow `rowAllNeq` values_ myRow
1185+-- ROW(1, FALSE) ALL <> (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1191rowAllNeq
1186rowAllNeq
1192 :: SListI row
1187 :: SListI row
1193 => NP (Aliased (Expression schema from grp params)) row
1188 => NP (Aliased (Expression schema from grp params)) row
@@ -1195,12 +1190,17 @@ rowAllNeq
1195 -> Condition schema from grp params
1190 -> Condition schema from grp params
1196rowAllNeq = unsafeRowSubqueryExpression "ALL <>"
1191rowAllNeq = unsafeRowSubqueryExpression "ALL <>"
1193+-- | >>> printSQL $ true `anyNeq` values_ (true `as` #foo)
1194+-- TRUE ANY <> (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1199 :: Expression schema from grp params ty
1196 :: Expression schema from grp params ty
1200 -> Query schema params '[alias ::: ty]
1197 -> Query schema params '[alias ::: ty]
1201 -> Condition schema from grp params
1198 -> Condition schema from grp params
1202anyNeq = unsafeSubqueryExpression "ANY <>"
1199anyNeq = unsafeSubqueryExpression "ANY <>"
1201+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1202+-- >>> printSQL $ myRow `rowAnyNeq` values_ myRow
1203+-- ROW(1, FALSE) ANY <> (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1204rowAnyNeq
1204rowAnyNeq
1205 :: SListI row
1205 :: SListI row
1206 => NP (Aliased (Expression schema from grp params)) row
1206 => NP (Aliased (Expression schema from grp params)) row
@@ -1208,12 +1208,17 @@ rowAnyNeq
1208 -> Condition schema from grp params
1208 -> Condition schema from grp params
1209rowAnyNeq = unsafeRowSubqueryExpression "ANY <>"
1209rowAnyNeq = unsafeRowSubqueryExpression "ANY <>"
1211+-- | >>> printSQL $ true `allLt` values_ (true `as` #foo)
1212+-- TRUE ALL < (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1212 :: Expression schema from grp params ty
1214 :: Expression schema from grp params ty
1213 -> Query schema params '[alias ::: ty]
1215 -> Query schema params '[alias ::: ty]
1214 -> Condition schema from grp params
1216 -> Condition schema from grp params
1215allLt = unsafeSubqueryExpression "ALL <"
1217allLt = unsafeSubqueryExpression "ALL <"
1219+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1220+-- >>> printSQL $ myRow `rowAllLt` values_ myRow
1221+-- ROW(1, FALSE) ALL < (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1218 :: SListI row
1223 :: SListI row
1219 => NP (Aliased (Expression schema from grp params)) row
1224 => NP (Aliased (Expression schema from grp params)) row
@@ -1221,12 +1226,17 @@ rowAllLt
1221 -> Condition schema from grp params
1226 -> Condition schema from grp params
1222rowAllLt = unsafeRowSubqueryExpression "ALL <"
1227rowAllLt = unsafeRowSubqueryExpression "ALL <"
1229+-- | >>> printSQL $ true `anyLt` values_ (true `as` #foo)
1230+-- TRUE ANY < (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1225 :: Expression schema from grp params ty
1232 :: Expression schema from grp params ty
1226 -> Query schema params '[alias ::: ty]
1233 -> Query schema params '[alias ::: ty]
1227 -> Condition schema from grp params
1234 -> Condition schema from grp params
1228anyLt = unsafeSubqueryExpression "ANY <"
1235anyLt = unsafeSubqueryExpression "ANY <"
1237+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1238+-- >>> printSQL $ myRow `rowAllLt` values_ myRow
1239+-- ROW(1, FALSE) ALL < (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1231 :: SListI row
1241 :: SListI row
1232 => NP (Aliased (Expression schema from grp params)) row
1242 => NP (Aliased (Expression schema from grp params)) row
@@ -1234,12 +1244,17 @@ rowAnyLt
1234 -> Condition schema from grp params
1244 -> Condition schema from grp params
1235rowAnyLt = unsafeRowSubqueryExpression "ANY <"
1245rowAnyLt = unsafeRowSubqueryExpression "ANY <"
1247+-- | >>> printSQL $ true `allLte` values_ (true `as` #foo)
1248+-- TRUE ALL <= (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1238 :: Expression schema from grp params ty
1250 :: Expression schema from grp params ty
1239 -> Query schema params '[alias ::: ty]
1251 -> Query schema params '[alias ::: ty]
1240 -> Condition schema from grp params
1252 -> Condition schema from grp params
1241allLte = unsafeSubqueryExpression "ALL <="
1253allLte = unsafeSubqueryExpression "ALL <="
1255+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1256+-- >>> printSQL $ myRow `rowAllLte` values_ myRow
1257+-- ROW(1, FALSE) ALL <= (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1243rowAllLte
1258rowAllLte
1244 :: SListI row
1259 :: SListI row
1245 => NP (Aliased (Expression schema from grp params)) row
1260 => NP (Aliased (Expression schema from grp params)) row
@@ -1247,12 +1262,17 @@ rowAllLte
1247 -> Condition schema from grp params
1262 -> Condition schema from grp params
1248rowAllLte = unsafeRowSubqueryExpression "ALL <="
1263rowAllLte = unsafeRowSubqueryExpression "ALL <="
1265+-- | >>> printSQL $ true `anyLte` values_ (true `as` #foo)
1266+-- TRUE ANY <= (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1251 :: Expression schema from grp params ty
1268 :: Expression schema from grp params ty
1252 -> Query schema params '[alias ::: ty]
1269 -> Query schema params '[alias ::: ty]
1253 -> Condition schema from grp params
1270 -> Condition schema from grp params
1254anyLte = unsafeSubqueryExpression "ANY <="
1271anyLte = unsafeSubqueryExpression "ANY <="
1273+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1274+-- >>> printSQL $ myRow `rowAnyLte` values_ myRow
1275+-- ROW(1, FALSE) ANY <= (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1256rowAnyLte
1276rowAnyLte
1257 :: SListI row
1277 :: SListI row
1258 => NP (Aliased (Expression schema from grp params)) row
1278 => NP (Aliased (Expression schema from grp params)) row
@@ -1260,12 +1280,17 @@ rowAnyLte
1260 -> Condition schema from grp params
1280 -> Condition schema from grp params
1261rowAnyLte = unsafeRowSubqueryExpression "ANY <="
1281rowAnyLte = unsafeRowSubqueryExpression "ANY <="
1283+-- | >>> printSQL $ true `allGt` values_ (true `as` #foo)
1284+-- TRUE ALL > (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1264 :: Expression schema from grp params ty
1286 :: Expression schema from grp params ty
1265 -> Query schema params '[alias ::: ty]
1287 -> Query schema params '[alias ::: ty]
1266 -> Condition schema from grp params
1288 -> Condition schema from grp params
1267allGt = unsafeSubqueryExpression "ALL >"
1289allGt = unsafeSubqueryExpression "ALL >"
1291+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1292+-- >>> printSQL $ myRow `rowAllGt` values_ myRow
1293+-- ROW(1, FALSE) ALL > (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1270 :: SListI row
1295 :: SListI row
1271 => NP (Aliased (Expression schema from grp params)) row
1296 => NP (Aliased (Expression schema from grp params)) row
@@ -1273,12 +1298,17 @@ rowAllGt
1273 -> Condition schema from grp params
1298 -> Condition schema from grp params
1274rowAllGt = unsafeRowSubqueryExpression "ALL >"
1299rowAllGt = unsafeRowSubqueryExpression "ALL >"
1301+-- | >>> printSQL $ true `anyGt` values_ (true `as` #foo)
1302+-- TRUE ANY > (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1277 :: Expression schema from grp params ty
1304 :: Expression schema from grp params ty
1278 -> Query schema params '[alias ::: ty]
1305 -> Query schema params '[alias ::: ty]
1279 -> Condition schema from grp params
1306 -> Condition schema from grp params
1280anyGt = unsafeSubqueryExpression "ANY >"
1307anyGt = unsafeSubqueryExpression "ANY >"
1309+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1310+-- >>> printSQL $ myRow `rowAnyGt` values_ myRow
1311+-- ROW(1, FALSE) ANY > (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1283 :: SListI row
1313 :: SListI row
1284 => NP (Aliased (Expression schema from grp params)) row
1314 => NP (Aliased (Expression schema from grp params)) row
@@ -1286,12 +1316,17 @@ rowAnyGt
1286 -> Condition schema from grp params
1316 -> Condition schema from grp params
1287rowAnyGt = unsafeRowSubqueryExpression "ANY >"
1317rowAnyGt = unsafeRowSubqueryExpression "ANY >"
1319+-- | >>> printSQL $ true `allGte` values_ (true `as` #foo)
1320+-- TRUE ALL >= (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1290 :: Expression schema from grp params ty
1322 :: Expression schema from grp params ty
1291 -> Query schema params '[alias ::: ty]
1323 -> Query schema params '[alias ::: ty]
1292 -> Condition schema from grp params
1324 -> Condition schema from grp params
1293allGte = unsafeSubqueryExpression "ALL >="
1325allGte = unsafeSubqueryExpression "ALL >="
1327+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1328+-- >>> printSQL $ myRow `rowAllGte` values_ myRow
1329+-- ROW(1, FALSE) ALL >= (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1295rowAllGte
1330rowAllGte
1296 :: SListI row
1331 :: SListI row
1297 => NP (Aliased (Expression schema from grp params)) row
1332 => NP (Aliased (Expression schema from grp params)) row
@@ -1299,12 +1334,17 @@ rowAllGte
1299 -> Condition schema from grp params
1334 -> Condition schema from grp params
1300rowAllGte = unsafeRowSubqueryExpression "ALL >="
1335rowAllGte = unsafeRowSubqueryExpression "ALL >="
1337+-- | >>> printSQL $ true `anyGte` values_ (true `as` #foo)
1338+-- TRUE ANY >= (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
1303 :: Expression schema from grp params ty
1340 :: Expression schema from grp params ty
1304 -> Query schema params '[alias ::: ty]
1341 -> Query schema params '[alias ::: ty]
1305 -> Condition schema from grp params
1342 -> Condition schema from grp params
1306anyGte = unsafeSubqueryExpression "ANY >="
1343anyGte = unsafeSubqueryExpression "ANY >="
1345+-- | >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
1346+-- >>> printSQL $ myRow `rowAnyGte` values_ myRow
1347+-- ROW(1, FALSE) ANY >= (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
1308rowAnyGte
1348rowAnyGte
1309 :: SListI row
1349 :: SListI row
1310 => NP (Aliased (Expression schema from grp params)) row
1350 => NP (Aliased (Expression schema from grp params)) row
@@ -1312,6 +1352,7 @@ rowAnyGte
1312 -> Condition schema from grp params
1352 -> Condition schema from grp params
1313rowAnyGte = unsafeRowSubqueryExpression "ANY >="
1353rowAnyGte = unsafeRowSubqueryExpression "ANY >="
1355+-- | A `CommonTableExpression` is an auxiliary statement in a `with` clause.
1315data CommonTableExpression statement
1356data CommonTableExpression statement
1316 (params :: [NullityType])
1357 (params :: [NullityType])
1317 (schema0 :: SchemaType)
1358 (schema0 :: SchemaType)
@@ -1330,6 +1371,7 @@ instance (KnownSymbol alias, schema1 ~ (alias ::: 'View cte ': schema))
1330 (AlignedList (CommonTableExpression statement params) schema schema1) where
1371 (AlignedList (CommonTableExpression statement params) schema schema1) where
1331 statement `as` alias = single (statement `as` alias)
1372 statement `as` alias = single (statement `as` alias)
1374+-- | render a `CommonTableExpression`.
1333renderCommonTableExpression
1375renderCommonTableExpression
1334 :: (forall sch ps row. statement ps sch row -> ByteString)
1376 :: (forall sch ps row. statement ps sch row -> ByteString)
1335 -> CommonTableExpression statement params schema0 schema1 -> ByteString
1377 -> CommonTableExpression statement params schema0 schema1 -> ByteString
@@ -1337,6 +1379,7 @@ renderCommonTableExpression renderStatement
1337 (CommonTableExpression (statement `As` alias)) =
1379 (CommonTableExpression (statement `As` alias)) =
1338 renderAlias alias <+> "AS" <+> parenthesized (renderStatement statement)
1380 renderAlias alias <+> "AS" <+> parenthesized (renderStatement statement)
1382+-- | render a non-empty `AlignedList` of `CommonTableExpression`s.
1340renderCommonTableExpressions
1383renderCommonTableExpressions
1341 :: (forall sch ps row. statement ps sch row -> ByteString)
1384 :: (forall sch ps row. statement ps sch row -> ByteString)
1342 -> CommonTableExpression statement params schema0 schema1
1385 -> CommonTableExpression statement params schema0 schema1
@@ -1348,9 +1391,9 @@ renderCommonTableExpressions renderStatement cte ctes =
1348 cte' :>> ctes' -> "," <+>
1391 cte' :>> ctes' -> "," <+>
1349 renderCommonTableExpressions renderStatement cte' ctes'
1392 renderCommonTableExpressions renderStatement cte' ctes'
1351−-- | `with` provides a way to write auxiliary statements for use in a larger statement.
1394+-- | `with` provides a way to write auxiliary statements for use in a larger query.
1352−-- These statements, which are often referred to as Common Table Expressions or CTEs,
1395+-- These statements, referred to as `CommonTableExpression`s, can be thought of as
1353−-- can be thought of as defining temporary tables that exist just for one statement.
1396+-- defining temporary tables that exist just for one query.
1354class With statement where
1397class With statement where
1356 :: AlignedList (CommonTableExpression statement params) schema0 schema1
1399 :: AlignedList (CommonTableExpression statement params) schema0 schema1