@@ -109,6 +109,7 @@ func (fkEditor *ForeignKeyEditor) Update(ctx *sql.Context, old sql.Row, new sql.
109109 }
110110 case sql .ForeignKeyReferentialAction_Cascade :
111111 case sql .ForeignKeyReferentialAction_SetNull :
112+ case sql .ForeignKeyReferentialAction_SetDefault :
112113 }
113114 }
114115 if err := fkEditor .Editor .Update (ctx , old , new ); err != nil {
@@ -124,6 +125,10 @@ func (fkEditor *ForeignKeyEditor) Update(ctx *sql.Context, old sql.Row, new sql.
124125 if err := fkEditor .OnUpdateSetNull (ctx , refActionData , old , new , depth + 1 ); err != nil {
125126 return err
126127 }
128+ case sql .ForeignKeyReferentialAction_SetDefault :
129+ if err := fkEditor .OnUpdateSetDefault (ctx , refActionData , old , new , depth + 1 ); err != nil {
130+ return err
131+ }
127132 }
128133 }
129134 return nil
@@ -190,6 +195,58 @@ func (fkEditor *ForeignKeyEditor) OnUpdateCascade(ctx *sql.Context, refActionDat
190195 return err
191196}
192197
198+ // OnUpdateSetDefault handles the ON UPDATE SET DEFAULT referential action.
199+ func (fkEditor * ForeignKeyEditor ) OnUpdateSetDefault (ctx * sql.Context , refActionData ForeignKeyRefActionData , old sql.Row , new sql.Row , depth int ) error {
200+ if ok , err := fkEditor .ColumnsUpdated (ctx , refActionData , old , new ); err != nil {
201+ return err
202+ } else if ! ok {
203+ return nil
204+ }
205+
206+ rowIter , err := refActionData .RowMapper .GetIter (ctx , old , false )
207+ if err != nil {
208+ return err
209+ }
210+ defer rowIter .Close (ctx )
211+ var rowToDefault sql.Row
212+ for rowToDefault , err = rowIter .Next (ctx ); err == nil ; rowToDefault , err = rowIter .Next (ctx ) {
213+ // MySQL seems to have a bug where cyclical foreign keys return an error at a depth of 15 instead of 16.
214+ // This replicates the observed behavior, regardless of whether we're replicating a bug or intentional behavior.
215+ if depth >= 15 {
216+ if fkEditor .Cyclical {
217+ return sql .ErrForeignKeyDepthLimit .New ()
218+ } else if depth > 15 {
219+ return sql .ErrForeignKeyDepthLimit .New ()
220+ }
221+ }
222+
223+ modifiedRow := make (sql.Row , len (rowToDefault ))
224+ for i := range rowToDefault {
225+ // Row contents are nil by default, so we only need to assign the non-affected values
226+ if refActionData .ChildParentMapping [i ] == - 1 {
227+ modifiedRow [i ] = rowToDefault [i ]
228+ } else {
229+ col := refActionData .Editor .Schema [i ]
230+ if col .Default != nil {
231+ newVal , err := col .Default .Eval (ctx , rowToDefault )
232+ if err != nil {
233+ return err
234+ }
235+ modifiedRow [i ] = newVal
236+ }
237+ }
238+ }
239+ err = refActionData .Editor .Update (ctx , rowToDefault , modifiedRow , depth )
240+ if err != nil {
241+ return err
242+ }
243+ }
244+ if err == io .EOF {
245+ return nil
246+ }
247+ return err
248+ }
249+
193250// OnUpdateSetNull handles the ON UPDATE SET NULL referential action.
194251func (fkEditor * ForeignKeyEditor ) OnUpdateSetNull (ctx * sql.Context , refActionData ForeignKeyRefActionData , old sql.Row , new sql.Row , depth int ) error {
195252 if ok , err := fkEditor .ColumnsUpdated (ctx , refActionData , old , new ); err != nil {
@@ -237,6 +294,7 @@ func (fkEditor *ForeignKeyEditor) Delete(ctx *sql.Context, row sql.Row, depth in
237294 }
238295 case sql .ForeignKeyReferentialAction_Cascade :
239296 case sql .ForeignKeyReferentialAction_SetNull :
297+ case sql .ForeignKeyReferentialAction_SetDefault :
240298 }
241299 }
242300 if err := fkEditor .Editor .Delete (ctx , row ); err != nil {
@@ -252,6 +310,10 @@ func (fkEditor *ForeignKeyEditor) Delete(ctx *sql.Context, row sql.Row, depth in
252310 if err := fkEditor .OnDeleteSetNull (ctx , refActionData , row , depth + 1 ); err != nil {
253311 return err
254312 }
313+ case sql .ForeignKeyReferentialAction_SetDefault :
314+ if err := fkEditor .OnDeleteSetDefault (ctx , refActionData , row , depth + 1 ); err != nil {
315+ return err
316+ }
255317 }
256318 }
257319 return nil
@@ -303,6 +365,52 @@ func (fkEditor *ForeignKeyEditor) OnDeleteCascade(ctx *sql.Context, refActionDat
303365 return err
304366}
305367
368+ // OnDeleteSetDefault handles the ON DELETE SET DEFAULT referential action.
369+ func (fkEditor * ForeignKeyEditor ) OnDeleteSetDefault (ctx * sql.Context , refActionData ForeignKeyRefActionData , row sql.Row , depth int ) error {
370+ rowIter , err := refActionData .RowMapper .GetIter (ctx , row , false )
371+ if err != nil {
372+ return err
373+ }
374+ defer rowIter .Close (ctx )
375+ var rowToDefault sql.Row
376+ for rowToDefault , err = rowIter .Next (ctx ); err == nil ; rowToDefault , err = rowIter .Next (ctx ) {
377+ // MySQL seems to have a bug where cyclical foreign keys return an error at a depth of 15 instead of 16.
378+ // This replicates the observed behavior, regardless of whether we're replicating a bug or intentional behavior.
379+ if depth >= 15 {
380+ if fkEditor .Cyclical {
381+ return sql .ErrForeignKeyDepthLimit .New ()
382+ } else if depth > 15 {
383+ return sql .ErrForeignKeyDepthLimit .New ()
384+ }
385+ }
386+
387+ modifiedRow := make (sql.Row , len (rowToDefault ))
388+ for i := range rowToDefault {
389+ // Row contents are nil by default, so we only need to assign the non-affected values
390+ if refActionData .ChildParentMapping [i ] == - 1 {
391+ modifiedRow [i ] = rowToDefault [i ]
392+ } else {
393+ col := refActionData .Editor .Schema [i ]
394+ if col .Default != nil {
395+ newVal , err := col .Default .Eval (ctx , rowToDefault )
396+ if err != nil {
397+ return err
398+ }
399+ modifiedRow [i ] = newVal
400+ }
401+ }
402+ }
403+ err = refActionData .Editor .Update (ctx , rowToDefault , modifiedRow , depth )
404+ if err != nil {
405+ return err
406+ }
407+ }
408+ if err == io .EOF {
409+ return nil
410+ }
411+ return err
412+ }
413+
306414// OnDeleteSetNull handles the ON DELETE SET NULL referential action.
307415func (fkEditor * ForeignKeyEditor ) OnDeleteSetNull (ctx * sql.Context , refActionData ForeignKeyRefActionData , row sql.Row , depth int ) error {
308416 rowIter , err := refActionData .RowMapper .GetIter (ctx , row , false )
0 commit comments