@@ -27,6 +27,7 @@ module Squeal.PostgreSQL.Manipulation
27 , ColumnValue (..)
27 , ColumnValue (..)
28 , ReturningClause (ReturningStar, Returning)
28 , ReturningClause (ReturningStar, Returning)
29 , ConflictClause (OnConflictDoRaise, OnConflictDoNothing, OnConflictDoUpdate)
29 , ConflictClause (OnConflictDoRaise, OnConflictDoNothing, OnConflictDoUpdate)
30 -- * Insert
31 -- * Insert
31 , insertRows
32 , insertRows
32 , insertRow
33 , insertRow
@@ -42,6 +43,7 @@ module Squeal.PostgreSQL.Manipulation
42 -- * Delete
43 -- * Delete
43 , deleteFrom
44 , deleteFrom
44 , deleteFrom_
45 , deleteFrom_
47import Control.DeepSeq
49import Control.DeepSeq
@@ -148,11 +150,31 @@ let
148 manipulation :: Manipulation (DBof (Public Schema)) '[]
150 manipulation :: Manipulation (DBof (Public Schema)) '[]
149 '[ "col1" ::: 'NotNull 'PGint4
151 '[ "col1" ::: 'NotNull 'PGint4
150 , "col2" ::: 'NotNull 'PGint4 ]
152 , "col2" ::: 'NotNull 'PGint4 ]
151− manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar
153+ manipulation = deleteFrom #tab NoUsing (#col1 .== #col2) ReturningStar
152in printSQL manipulation
154in printSQL manipulation
154DELETE FROM "tab" WHERE ("col1" = "col2") RETURNING *
156DELETE FROM "tab" WHERE ("col1" = "col2") RETURNING *
158+delete and using clause:
162+ '[ "tab" ::: 'Table ('[] :=> Columns)
163+ , "other_tab" ::: 'Table ('[] :=> Columns)
164+ , "third_tab" ::: 'Table ('[] :=> Columns) ]
169+ manipulation :: Manipulation (DBof (Public Schema3)) '[] '[]
171+ deleteFrom_ #tab (Using (table #other_tab & also (table #third_tab)))
172+ ( (#tab ! #col2 .== #other_tab ! #col2)
173+ .&& (#tab ! #col2 .== #third_tab ! #col2) )
174+in printSQL manipulation
176+DELETE FROM "tab" USING "other_tab" AS "other_tab", "third_tab" AS "third_tab" WHERE (("tab"."col2" = "other_tab"."col2") AND ("tab"."col2" = "third_tab"."col2"))
156with manipulation:
178with manipulation:
158>>> type ProductsColumns = '["product" ::: 'NoDef :=> 'NotNull 'PGtext, "date" ::: 'Def :=> 'NotNull 'PGdate]
180>>> type ProductsColumns = '["product" ::: 'NoDef :=> 'NotNull 'PGtext, "date" ::: 'Def :=> 'NotNull 'PGdate]
@@ -161,7 +183,7 @@ with manipulation:
162 manipulation :: Manipulation (DBof (Public ProductsSchema)) '[ 'NotNull 'PGdate] '[]
184 manipulation :: Manipulation (DBof (Public ProductsSchema)) '[ 'NotNull 'PGdate] '[]
163 manipulation = with
185 manipulation = with
164− (deleteFrom #products (#date .< param @1) ReturningStar `as` #del)
186+ (deleteFrom #products NoUsing (#date .< param @1) ReturningStar `as` #del)
165 (insertQuery_ #products_deleted (selectStar (from (common (#del)))))
187 (insertQuery_ #products_deleted (selectStar (from (common (#del)))))
166in printSQL manipulation
188in printSQL manipulation
@@ -459,7 +481,13 @@ update_ tab columns wh = update tab columns wh (Returning Nil)
459DELETE statements
481DELETE statements
460-----------------------------------------}
482-----------------------------------------}
484+data UsingClause db params from where
485+ NoUsing :: UsingClause db params '[]
487+ :: FromClause db params from
488+ -> UsingClause db params from
462−-- | Delete rows of a table.
490+-- | Delete rows from a table.
463deleteFrom
491deleteFrom
464 :: ( SOP.SListI results
492 :: ( SOP.SListI results
465 , db ~ (commons :=> schemas)
493 , db ~ (commons :=> schemas)
@@ -468,12 +496,17 @@ deleteFrom
468 , row ~ TableToRow table
496 , row ~ TableToRow table
469 , columns ~ TableToColumns table )
497 , columns ~ TableToColumns table )
470 => QualifiedAlias sch tab -- ^ table to delete from
498 => QualifiedAlias sch tab -- ^ table to delete from
499+ -> UsingClause db params from
471− -> Condition db '[tab ::: row] 'Ungrouped params
500+ -> Condition db (tab ::: row ': from) 'Ungrouped params
472 -- ^ condition under which to delete a row
501 -- ^ condition under which to delete a row
473 -> ReturningClause db params row results -- ^ results to return
502 -> ReturningClause db params row results -- ^ results to return
474 -> Manipulation db params results
503 -> Manipulation db params results
475−deleteFrom tab wh returning = UnsafeManipulation $
504+deleteFrom tab using wh returning = UnsafeManipulation $
476− "DELETE FROM" <+> renderQualifiedAlias tab
506+ <+> renderQualifiedAlias tab
509+ Using tables -> " USING" <+> renderFromClause tables
477 <+> "WHERE" <+> renderExpression wh
510 <+> "WHERE" <+> renderExpression wh
478 <> renderReturningClause returning
511 <> renderReturningClause returning
@@ -485,7 +518,22 @@ deleteFrom_
485 , row ~ TableToRow table
518 , row ~ TableToRow table
486 , columns ~ TableToColumns table )
519 , columns ~ TableToColumns table )
487 => QualifiedAlias sch tab -- ^ table to delete from
520 => QualifiedAlias sch tab -- ^ table to delete from
521+ -> UsingClause db params from
488− -> (forall t. Condition db '[t ::: row] 'Ungrouped params)
522+ -> Condition db (tab ::: row ': from) 'Ungrouped params
489 -- ^ condition under which to delete a row
523 -- ^ condition under which to delete a row
490 -> Manipulation db params '[]
524 -> Manipulation db params '[]
491−deleteFrom_ tab wh = deleteFrom tab wh (Returning Nil)
525+deleteFrom_ tab uses wh = deleteFrom tab uses wh (Returning Nil)
527+-- | This has the behaviour of a cartesian product, taking all
528+-- possible combinations between @left@ and @right@ - exactly like a
529+-- CROSS JOIN. Used when no "CROSS JOIN" syntax is required but simply
530+-- a comma separated list of tables. Typical case is the `USING` clause
531+-- of a DELETE query.
533+ :: FromClause schema params right
535+ -> FromClause schema params left
537+ -> FromClause schema params (Join left right)
538+also right left = UnsafeFromClause $
539+ renderFromClause left <> "," <+> renderFromClause right