From 7a055c9ff8be2e001076a696c3c655055ac1f37f Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Mon, 30 Dec 2024 16:46:30 -0500 Subject: [PATCH 1/2] Make `NO ACTION` the default action for foreign keys --- persistent-postgresql/Database/Persist/Postgresql.hs | 6 +++--- persistent/Database/Persist/Quasi.hs | 5 +++-- persistent/Database/Persist/Sql/Internal.hs | 6 +++--- persistent/Database/Persist/Types/Base.hs | 5 +++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/persistent-postgresql/Database/Persist/Postgresql.hs b/persistent-postgresql/Database/Persist/Postgresql.hs index a34aafda6..5b25a1197 100644 --- a/persistent-postgresql/Database/Persist/Postgresql.hs +++ b/persistent-postgresql/Database/Persist/Postgresql.hs @@ -1193,7 +1193,7 @@ findAlters defs edef col@(Column name isNull sqltype def _gen _defConstraintName ) -- We check if we should alter a foreign key. This is almost an equality check, --- except we consider 'Nothing' and 'Just Restrict' equivalent. +-- except we consider 'Nothing' and 'Just NoAction' equivalent. equivalentRef :: Maybe ColumnReference -> Maybe ColumnReference -> Bool equivalentRef Nothing Nothing = True equivalentRef (Just cr1) (Just cr2) = @@ -1204,8 +1204,8 @@ equivalentRef (Just cr1) (Just cr2) = where eqCascade :: Maybe CascadeAction -> Maybe CascadeAction -> Bool eqCascade Nothing Nothing = True - eqCascade Nothing (Just Restrict) = True - eqCascade (Just Restrict) Nothing = True + eqCascade Nothing (Just NoAction) = True + eqCascade (Just NoAction) Nothing = True eqCascade (Just cs1) (Just cs2) = cs1 == cs2 eqCascade _ _ = False equivalentRef _ _ = False diff --git a/persistent/Database/Persist/Quasi.hs b/persistent/Database/Persist/Quasi.hs index 451f92229..985586aca 100644 --- a/persistent/Database/Persist/Quasi.hs +++ b/persistent/Database/Persist/Quasi.hs @@ -434,8 +434,9 @@ AnotherVeryLongTableName These options affects how a referring record behaves when the target record is changed. There are several options: -* 'Restrict' - This is the default. It prevents the action from occurring. -* 'Cascade' - this copies the change to the child record. If a parent record is deleted, then the child record will be deleted too. +* 'NoAction' - This is the default. It prevents the action from occurring, but the check can be deferred until the end of the transaction. +* 'Restrict' - This prevents the action from occurring by immediately aborting a transaction. +* 'Cascade' - This copies the change to the child record. If a parent record is deleted, then the child record will be deleted too. * 'SetNull' - If the parent record is modified, then this sets the reference to @NULL@. This only works on @Maybe@ foreign keys. * 'SetDefault' - This will set the column's value to the @default@ for the column, if specified. diff --git a/persistent/Database/Persist/Sql/Internal.hs b/persistent/Database/Persist/Sql/Internal.hs index c8e099fee..a8875e966 100644 --- a/persistent/Database/Persist/Sql/Internal.hs +++ b/persistent/Database/Persist/Sql/Internal.hs @@ -167,12 +167,12 @@ mkColumns allDefs t overrides = $ ref (fieldDB fd) (fieldReference fd) (fieldAttrs fd) -- a 'Nothing' in the definition means that the QQ migration doesn't - -- specify behavior. the default is RESTRICT. setting this here + -- specify behavior. the default is NO ACTION. setting this here -- explicitly makes migrations run smoother. overrideNothings (FieldCascade { fcOnUpdate = upd, fcOnDelete = del }) = FieldCascade - { fcOnUpdate = upd <|> Just Restrict - , fcOnDelete = del <|> Just Restrict + { fcOnUpdate = upd <|> Just NoAction + , fcOnDelete = del <|> Just NoAction } ref :: FieldNameDB diff --git a/persistent/Database/Persist/Types/Base.hs b/persistent/Database/Persist/Types/Base.hs index cd45d8b3c..4ad626ba9 100644 --- a/persistent/Database/Persist/Types/Base.hs +++ b/persistent/Database/Persist/Types/Base.hs @@ -574,7 +574,7 @@ data ForeignDef = ForeignDef -- This type is used in both parsing the model definitions and performing -- migrations. A 'Nothing' in either of the field values means that the -- user has not specified a 'CascadeAction'. An unspecified 'CascadeAction' --- is defaulted to 'Restrict' when doing migrations. +-- is defaulted to 'NoAction' when doing migrations. -- -- @since 2.11.0 data FieldCascade = FieldCascade @@ -604,7 +604,7 @@ renderFieldCascade (FieldCascade onUpdate onDelete) = -- change. -- -- @since 2.11.0 -data CascadeAction = Cascade | Restrict | SetNull | SetDefault +data CascadeAction = NoAction | Cascade | Restrict | SetNull | SetDefault deriving (Show, Eq, Read, Ord, Lift) -- | Render a 'CascadeAction' to 'Text' such that it can be used in a SQL @@ -613,6 +613,7 @@ data CascadeAction = Cascade | Restrict | SetNull | SetDefault -- @since 2.11.0 renderCascadeAction :: CascadeAction -> Text renderCascadeAction action = case action of + NoAction -> "NO ACTION" Cascade -> "CASCADE" Restrict -> "RESTRICT" SetNull -> "SET NULL" From 0aa6e656a3d493d6b8d1d0fb69d280f1d23511f2 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Mon, 30 Dec 2024 18:01:12 -0500 Subject: [PATCH 2/2] Update changelogs --- persistent-postgresql/ChangeLog.md | 2 ++ persistent/ChangeLog.md | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/persistent-postgresql/ChangeLog.md b/persistent-postgresql/ChangeLog.md index 14cc261c3..3fb4b2de9 100644 --- a/persistent-postgresql/ChangeLog.md +++ b/persistent-postgresql/ChangeLog.md @@ -4,6 +4,8 @@ * [#1547](https://github.com/yesodweb/persistent/pull/1547) * Bump `libpq` bounds +* [#1560](https://github.com/yesodweb/persistent/pull/1560) + * Treat `NO ACTION` as the default action, rather than `RESTRICT`. ## 2.13.6.2 diff --git a/persistent/ChangeLog.md b/persistent/ChangeLog.md index 842f2d552..3865253dc 100644 --- a/persistent/ChangeLog.md +++ b/persistent/ChangeLog.md @@ -1,5 +1,11 @@ # Changelog for persistent +## Unreleased + +* [#1560](https://github.com/yesodweb/persistent/pull/1560) + * Add a `NoAction` option for foreign key constraints. + * Change the default action from `Restrict` to `NoAction`. + ## 2.14.6.3 * [#1544](https://github.com/yesodweb/persistent/pull/1544)