Skip to content

Commit 391ad72

Browse files
author
James Cor
committed
merge
2 parents b637a3f + b9d200a commit 391ad72

File tree

14 files changed

+2783
-2944
lines changed

14 files changed

+2783
-2944
lines changed

engine.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func (e *Engine) QueryWithBindings(ctx *sql.Context, query string, parsed sqlpar
460460

461461
// PrepQueryPlanForExecution prepares a query plan for execution and returns the result schema with a row iterator to
462462
// begin spooling results
463-
func (e *Engine) PrepQueryPlanForExecution(ctx *sql.Context, _ string, plan sql.Node) (sql.Schema, sql.RowIter, *sql.QueryFlags, error) {
463+
func (e *Engine) PrepQueryPlanForExecution(ctx *sql.Context, _ string, plan sql.Node, qFlags *sql.QueryFlags) (sql.Schema, sql.RowIter, *sql.QueryFlags, error) {
464464
// Give the integrator a chance to reject the session before proceeding
465465
// TODO: this check doesn't belong here
466466
err := ctx.Session.ValidateSession(ctx)
@@ -496,7 +496,9 @@ func (e *Engine) PrepQueryPlanForExecution(ctx *sql.Context, _ string, plan sql.
496496
return nil, nil, nil, err
497497
}
498498

499-
return plan.Schema(), iter, nil, nil
499+
iter = finalizeIters(ctx, plan, qFlags, iter)
500+
501+
return plan.Schema(), iter, qFlags, nil
500502
}
501503

502504
// BoundQueryPlan returns query plan for the given statement with the given bindings applied
@@ -884,8 +886,9 @@ func findCreateEventNode(planTree sql.Node) (*plan.CreateEvent, error) {
884886
}
885887

886888
// finalizeIters applies the final transformations on sql.RowIter before execution.
887-
func finalizeIters(ctx *sql.Context, analyzed sql.Node, qFlags *sql.QueryFlags, iter sql.RowIter) (sql.RowIter, error) {
889+
func finalizeIters(ctx *sql.Context, analyzed sql.Node, qFlags *sql.QueryFlags, iter sql.RowIter) sql.RowIter {
888890
var err error
891+
iter = rowexec.AddTriggerRollbackIter(ctx, qFlags, iter)
889892
iter, err = rowexec.AddAccumulatorIter(ctx, analyzed, iter)
890893
if err != nil {
891894
return nil, err

enginetest/queries/integration_plans.go

Lines changed: 2728 additions & 2743 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,9 +1082,9 @@ func (h *Handler) executeBoundPlan(
10821082
_ sqlparser.Statement,
10831083
plan sql.Node,
10841084
_ map[string]*querypb.BindVariable,
1085-
_ *sql.QueryFlags,
1085+
qFlags *sql.QueryFlags,
10861086
) (sql.Schema, sql.RowIter, *sql.QueryFlags, error) {
1087-
return h.e.PrepQueryPlanForExecution(ctx, query, plan)
1087+
return h.e.PrepQueryPlanForExecution(ctx, query, plan, qFlags)
10881088
}
10891089

10901090
func bindingsToExprs(bindings map[string]*querypb.BindVariable) (map[string]sqlparser.Expr, error) {

sql/analyzer/rule_ids.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ const (
6868
assignRoutinesId // assignRoutines
6969
modifyUpdateExprsForJoinId // modifyUpdateExprsForJoin
7070
applyUpdateAccumulatorsId // applyUpdateAccumulators
71-
wrapWithRollbackId // wrapWithRollback
7271
applyForeignKeysId // applyForeignKeys
7372

7473
// validate

sql/analyzer/ruleid_string.go

Lines changed: 17 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sql/analyzer/rules.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ func init() {
2222
{applyTriggersId, applyTriggers},
2323
{applyProceduresId, applyProcedures},
2424
{applyUpdateAccumulatorsId, applyUpdateAccumulators},
25-
{wrapWithRollbackId, wrapWithRollback},
2625
{inlineSubqueryAliasRefsId, inlineSubqueryAliasRefs},
2726
{cacheSubqueryAliasesInJoinsId, cacheSubqueryAliasesInJoins},
2827
{BacktickDefaulColumnValueNamesId, backtickDefaultColumnValueNames},

sql/analyzer/triggers.go

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ func applyTrigger(ctx *sql.Context, a *Analyzer, originalNode, n sql.Node, scope
346346

347347
switch n := c.Node.(type) {
348348
case *plan.InsertInto:
349+
qFlags.Set(sql.QFlagTrigger)
349350
if trigger.TriggerTime == sqlparser.BeforeStr {
350351
triggerExecutor := plan.NewTriggerExecutor(n.Source, triggerLogic, plan.InsertTrigger, plan.TriggerTime(trigger.TriggerTime), sql.TriggerDefinition{
351352
Name: trigger.TriggerName,
@@ -359,6 +360,7 @@ func applyTrigger(ctx *sql.Context, a *Analyzer, originalNode, n sql.Node, scope
359360
}), transform.NewTree, nil
360361
}
361362
case *plan.Update:
363+
qFlags.Set(sql.QFlagTrigger)
362364
if trigger.TriggerTime == sqlparser.BeforeStr {
363365
triggerExecutor := plan.NewTriggerExecutor(n.Child, triggerLogic, plan.UpdateTrigger, plan.TriggerTime(trigger.TriggerTime), sql.TriggerDefinition{
364366
Name: trigger.TriggerName,
@@ -387,6 +389,7 @@ func applyTrigger(ctx *sql.Context, a *Analyzer, originalNode, n sql.Node, scope
387389
"does not support triggers; retry with single table deletes")
388390
}
389391

392+
qFlags.Set(sql.QFlagTrigger)
390393
if trigger.TriggerTime == sqlparser.BeforeStr {
391394
triggerExecutor := plan.NewTriggerExecutor(n.Child, triggerLogic, plan.DeleteTrigger, plan.TriggerTime(trigger.TriggerTime), sql.TriggerDefinition{
392395
Name: trigger.TriggerName,
@@ -517,41 +520,3 @@ func orderTriggersAndReverseAfter(triggers []*plan.CreateTrigger) []*plan.Create
517520
func triggerEventsMatch(event plan.TriggerEvent, event2 string) bool {
518521
return strings.ToLower((string)(event)) == strings.ToLower(event2)
519522
}
520-
521-
// wrapWithRollback wraps the entire tree iff it contains a trigger, allowing rollback when a trigger errors
522-
func wrapWithRollback(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) {
523-
// Check if tree contains a TriggerExecutor
524-
containsTrigger := false
525-
transform.Inspect(n, func(n sql.Node) bool {
526-
// After Triggers wrap nodes
527-
if _, ok := n.(*plan.TriggerExecutor); ok {
528-
containsTrigger = true
529-
return false // done, don't bother to recurse
530-
}
531-
532-
// Before Triggers on Inserts are inside Source
533-
if n, ok := n.(*plan.InsertInto); ok {
534-
if _, ok := n.Source.(*plan.TriggerExecutor); ok {
535-
containsTrigger = true
536-
return false
537-
}
538-
}
539-
540-
// Before Triggers on Delete and Update should be in children
541-
return true
542-
})
543-
544-
// No TriggerExecutor, so return same tree
545-
if !containsTrigger {
546-
return n, transform.SameTree, nil
547-
}
548-
549-
// If we don't have a transaction session we can't do rollbacks
550-
_, ok := ctx.Session.(sql.TransactionSession)
551-
if !ok {
552-
return plan.NewNoopTriggerRollback(n), transform.NewTree, nil
553-
}
554-
555-
// Wrap tree with new node
556-
return plan.NewTriggerRollback(n), transform.NewTree, nil
557-
}

sql/plan/trigger.go

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -103,103 +103,3 @@ func (t *TriggerExecutor) CheckPrivileges(ctx *sql.Context, opChecker sql.Privil
103103
func (t *TriggerExecutor) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
104104
return sql.GetCoercibility(ctx, t.left)
105105
}
106-
107-
// TriggerRollback is a node that wraps the entire tree iff it contains a trigger, creates a savepoint, and performs a
108-
// rollback if something went wrong during execution
109-
type TriggerRollback struct {
110-
UnaryNode
111-
}
112-
113-
var _ sql.Node = (*TriggerRollback)(nil)
114-
var _ sql.CollationCoercible = (*TriggerRollback)(nil)
115-
116-
func NewTriggerRollback(child sql.Node) *TriggerRollback {
117-
return &TriggerRollback{
118-
UnaryNode: UnaryNode{Child: child},
119-
}
120-
}
121-
122-
func (t *TriggerRollback) WithChildren(children ...sql.Node) (sql.Node, error) {
123-
if len(children) != 1 {
124-
return nil, sql.ErrInvalidChildrenNumber.New(t, len(children), 1)
125-
}
126-
127-
return NewTriggerRollback(children[0]), nil
128-
}
129-
130-
// CheckPrivileges implements the interface sql.Node.
131-
func (t *TriggerRollback) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool {
132-
return t.Child.CheckPrivileges(ctx, opChecker)
133-
}
134-
135-
// CollationCoercibility implements the interface sql.CollationCoercible.
136-
func (t *TriggerRollback) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
137-
return sql.GetCoercibility(ctx, t.Child)
138-
}
139-
140-
func (t *TriggerRollback) IsReadOnly() bool {
141-
return t.Child.IsReadOnly()
142-
}
143-
144-
func (t *TriggerRollback) String() string {
145-
pr := sql.NewTreePrinter()
146-
_ = pr.WriteNode("TriggerRollback()")
147-
_ = pr.WriteChildren(t.Child.String())
148-
return pr.String()
149-
}
150-
151-
func (t *TriggerRollback) DebugString() string {
152-
pr := sql.NewTreePrinter()
153-
_ = pr.WriteNode("TriggerRollback")
154-
_ = pr.WriteChildren(sql.DebugString(t.Child))
155-
return pr.String()
156-
}
157-
158-
type NoopTriggerRollback struct {
159-
UnaryNode
160-
}
161-
162-
var _ sql.Node = (*NoopTriggerRollback)(nil)
163-
var _ sql.CollationCoercible = (*NoopTriggerRollback)(nil)
164-
165-
func NewNoopTriggerRollback(child sql.Node) *NoopTriggerRollback {
166-
return &NoopTriggerRollback{
167-
UnaryNode: UnaryNode{Child: child},
168-
}
169-
}
170-
171-
func (t *NoopTriggerRollback) WithChildren(children ...sql.Node) (sql.Node, error) {
172-
if len(children) != 1 {
173-
return nil, sql.ErrInvalidChildrenNumber.New(t, len(children), 1)
174-
}
175-
176-
return NewNoopTriggerRollback(children[0]), nil
177-
}
178-
179-
// CheckPrivileges implements the interface sql.Node.
180-
func (t *NoopTriggerRollback) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool {
181-
return t.Child.CheckPrivileges(ctx, opChecker)
182-
}
183-
184-
// CollationCoercibility implements the interface sql.CollationCoercible.
185-
func (t *NoopTriggerRollback) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
186-
return sql.GetCoercibility(ctx, t.Child)
187-
}
188-
189-
func (t *NoopTriggerRollback) IsReadOnly() bool {
190-
return true
191-
}
192-
193-
func (t *NoopTriggerRollback) String() string {
194-
pr := sql.NewTreePrinter()
195-
_ = pr.WriteNode("TriggerRollback()")
196-
_ = pr.WriteChildren(t.Child.String())
197-
return pr.String()
198-
}
199-
200-
func (t *NoopTriggerRollback) DebugString() string {
201-
pr := sql.NewTreePrinter()
202-
_ = pr.WriteNode("TriggerRollback")
203-
_ = pr.WriteChildren(sql.DebugString(t.Child))
204-
return pr.String()
205-
}

sql/query_flags.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const (
4848
QFlagDeferProjections
4949
// QFlagUndeferrableExprs indicates that the query has expressions that cannot be deferred
5050
QFlagUndeferrableExprs
51+
QFlagTrigger
5152
)
5253

5354
type QueryFlags struct {
@@ -69,6 +70,9 @@ func (qp *QueryFlags) Unset(flag int) {
6970
}
7071

7172
func (qp *QueryFlags) IsSet(flag int) bool {
73+
if qp == nil {
74+
return false
75+
}
7276
return qp.Flags.Contains(flag)
7377
}
7478

sql/rowexec/builder.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ type ExecBuilderFunc func(ctx *sql.Context, n sql.Node, r sql.Row) (sql.RowIter,
3131
// sql.ExecSourceRel are also built into the tree.
3232
type BaseBuilder struct {
3333
// if override is provided, we try to build executor with this first
34-
override sql.NodeExecBuilder
35-
triggerSavePointCounter int // tracks the number of save points that have been created by triggers
34+
override sql.NodeExecBuilder
3635
}
3736

3837
func (b *BaseBuilder) Build(ctx *sql.Context, n sql.Node, r sql.Row) (sql.RowIter, error) {

0 commit comments

Comments
 (0)