diff --git a/sql/core.go b/sql/core.go index f04920cd2a..2ac41547ec 100644 --- a/sql/core.go +++ b/sql/core.go @@ -820,6 +820,7 @@ type TriggerDefinition struct { Name string // The name of this trigger. Trigger names in a database are unique. CreateStatement string // The text of the statement to create this trigger. CreatedAt time.Time // The time that the trigger was created. + Callback func() // Optional Go callback invoked after each row the trigger fires on. Not persisted. } // TriggerDatabase is a Database that supports the creation and execution of triggers. The engine handles all parsing diff --git a/sql/plan/trigger.go b/sql/plan/trigger.go index e335f4a5bc..a8342a194d 100644 --- a/sql/plan/trigger.go +++ b/sql/plan/trigger.go @@ -93,11 +93,12 @@ func (t *TriggerExecutor) CheckPrivileges(ctx *sql.Context, opChecker sql.Privil } type triggerIter struct { - child sql.RowIter - executionLogic sql.Node - triggerTime TriggerTime - triggerEvent TriggerEvent - ctx *sql.Context + child sql.RowIter + executionLogic sql.Node + triggerTime TriggerTime + triggerEvent TriggerEvent + triggerDefinition sql.TriggerDefinition + ctx *sql.Context } // prependRowInPlanForTriggerExecution returns a transformation function that prepends the row given to any row source in a query @@ -172,9 +173,15 @@ func (t *triggerIter) Next(ctx *sql.Context) (row sql.Row, returnErr error) { // For some logic statements, we want to return the result of the logic operation as our row, e.g. a Set that alters // the fields of the new row if ok, returnRow := shouldUseLogicResult(logic, logicRow); ok { + if t.triggerDefinition.Callback != nil { + t.triggerDefinition.Callback() + } return returnRow, nil } + if t.triggerDefinition.Callback != nil { + t.triggerDefinition.Callback() + } return childRow, nil } @@ -228,11 +235,12 @@ func (t *TriggerExecutor) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, e } return &triggerIter{ - child: childIter, - triggerTime: t.TriggerTime, - triggerEvent: t.TriggerEvent, - executionLogic: t.right, - ctx: ctx, + child: childIter, + triggerTime: t.TriggerTime, + triggerEvent: t.TriggerEvent, + triggerDefinition: t.TriggerDefinition, // add this + executionLogic: t.right, + ctx: ctx, }, nil }