@@ -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
@@ -173,11 +175,38 @@ let
173 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])] '[]
175 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])] '[]
174 '[ "col1" ::: 'NotNull 'PGint4
176 '[ "col1" ::: 'NotNull 'PGint4
175 , "col2" ::: 'NotNull 'PGint4 ]
177 , "col2" ::: 'NotNull 'PGint4 ]
176− manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar
178+ manipulation = deleteFrom #tab NoUsing (#col1 .== #col2) ReturningStar
177in printSQL manipulation
179in printSQL manipulation
179DELETE FROM "tab" WHERE ("col1" = "col2") RETURNING *
181DELETE FROM "tab" WHERE ("col1" = "col2") RETURNING *
183+delete and using clause:
187+ manipulation :: Manipulation
188+ '[ "tab" ::: 'Table ('[] :=>
189+ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
190+ , "col2" ::: 'NoDef :=> 'NotNull 'PGint4
192+ , "other_tab" ::: 'Table ('[] :=>
193+ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
194+ , "col2" ::: 'NoDef :=> 'NotNull 'PGint4
196+ , "third_tab" ::: 'Table ('[] :=>
197+ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
198+ , "col2" ::: 'NoDef :=> 'NotNull 'PGint4
202+ deleteFrom #tab (Using (table #other_tab & also (table #third_tab)))
203+ ( (#tab ! #col2 .== #other_tab ! #col2)
204+ .&& (#tab ! #col2 .== #third_tab ! #col2) )
206+in printSQL manipulation
208+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"))
181with manipulation:
210with manipulation:
183>>> type ProductsTable = '[] :=> '["product" ::: 'NoDef :=> 'NotNull 'PGtext, "date" ::: 'Def :=> 'NotNull 'PGdate]
212>>> type ProductsTable = '[] :=> '["product" ::: 'NoDef :=> 'NotNull 'PGtext, "date" ::: 'Def :=> 'NotNull 'PGdate]
@@ -189,7 +218,7 @@ let
189 , "products_deleted" ::: 'Table ProductsTable
218 , "products_deleted" ::: 'Table ProductsTable
190 ] '[ 'NotNull 'PGdate] '[]
219 ] '[ 'NotNull 'PGdate] '[]
191 manipulation = with
220 manipulation = with
192− (deleteFrom #products (#date .< param @1) ReturningStar `as` #deleted_rows)
221+ (deleteFrom #products NoUsing (#date .< param @1) ReturningStar `as` #deleted_rows)
193 (insertQuery_ #products_deleted (selectStar (from (view (#deleted_rows `as` #t)))))
222 (insertQuery_ #products_deleted (selectStar (from (view (#deleted_rows `as` #t)))))
194in printSQL manipulation
223in printSQL manipulation
@@ -471,21 +500,33 @@ update_ tab columns wh = update tab columns wh (Returning Nil)
471DELETE statements
500DELETE statements
472-----------------------------------------}
501-----------------------------------------}
503+data UsingClause schema params from where
504+ NoUsing :: UsingClause schema params '[]
506+ :: FromClause schema params from
507+ -> UsingClause schema params from
474−-- | Delete rows of a table.
509+-- | Delete rows from a table.
475deleteFrom
510deleteFrom
476 :: ( SOP.SListI results
511 :: ( SOP.SListI results
477 , Has tab schema ('Table table)
512 , Has tab schema ('Table table)
478 , row ~ TableToRow table
513 , row ~ TableToRow table
479 , columns ~ TableToColumns table )
514 , columns ~ TableToColumns table )
480 => Alias tab -- ^ table to delete from
515 => Alias tab -- ^ table to delete from
516+ -> UsingClause schema params from
517+ -- ^-- tables to add to the scope - more tables can be added through `also`.
481− -> Condition schema '[tab ::: row] 'Ungrouped params
518+ -> Condition schema (tab ::: row ': from) 'Ungrouped params
482 -- ^ condition under which to delete a row
519 -- ^ condition under which to delete a row
483 -> ReturningClause schema params row results -- ^ results to return
520 -> ReturningClause schema params row results -- ^ results to return
484 -> Manipulation schema params results
521 -> Manipulation schema params results
522+deleteFrom tgt uses cond returning =
523+ let renderUsing NoUsing = mempty
524+ renderUsing (Using fc) = "USING" <+> renderFromClause fc <> " "
485−deleteFrom tab wh returning = UnsafeManipulation $
525+ in UnsafeManipulation $
486− "DELETE FROM" <+> renderAlias tab
526+ "DELETE FROM" <+> renderAlias tgt
527+ <+> renderUsing uses
487− <+> "WHERE" <+> renderExpression wh
528+ <> "WHERE" <+> renderExpression cond
488− <> renderReturningClause returning
529+ <> renderReturningClause returning
490-- | Delete rows returning `Nil`.
531-- | Delete rows returning `Nil`.
491deleteFrom_
532deleteFrom_
@@ -493,7 +534,23 @@ deleteFrom_
493 , row ~ TableToRow table
534 , row ~ TableToRow table
494 , columns ~ TableToColumns table )
535 , columns ~ TableToColumns table )
495 => Alias tab -- ^ table to delete from
536 => Alias tab -- ^ table to delete from
537+ -> UsingClause schema params from
538+ -- ^-- tables to add to the scope - more tables can be added through `also`.
496− -> (forall t. Condition schema '[t ::: row] 'Ungrouped params)
539+ -> Condition schema (tab ::: row ': from) 'Ungrouped params
497 -- ^ condition under which to delete a row
540 -- ^ condition under which to delete a row
498 -> Manipulation schema params '[]
541 -> Manipulation schema params '[]
499−deleteFrom_ tab wh = deleteFrom tab wh (Returning Nil)
542+deleteFrom_ tab uses wh = deleteFrom tab uses wh (Returning Nil)
544+-- | This has the behaviour of a cartesian product, taking all
545+-- possible combinations between @left@ and @right@ - exactly like a
546+-- CROSS JOIN. Used when no "CROSS JOIN" syntax is required but simply
547+-- a comma separated list of tables. Typical case is the `USING` clause
548+-- of a DELETE query.
550+ :: FromClause schema params right
552+ -> FromClause schema params left
554+ -> FromClause schema params (Join left right)
555+also right left = UnsafeFromClause $
556+ renderFromClause left <> "," <+> renderFromClause right