diff --git a/enginetest/queries/trigger_queries.go b/enginetest/queries/trigger_queries.go index 83ed0d5e18..b13296c6d3 100644 --- a/enginetest/queries/trigger_queries.go +++ b/enginetest/queries/trigger_queries.go @@ -310,6 +310,72 @@ var TriggerTests = []ScriptTest{ }, }, }, + { + Name: "issue #9039: trigger insert subquery error", + SetUpScript: []string{ + "create table a (x int primary key, y int default 1, z int)", + "create table b (x int primary key)", + "create table c (x int primary key)", + "create table d (x int primary key)", + "insert into b values (1), (2)", + "insert into d values (1), (2)", + ` +create trigger insert_into_a +after insert on a +for each row replace into c +select * from d join (select * from b where new.x = b.x) as e using (x) +where d.x = new.x`, + "insert into a (x,z) values (2,2)", + }, + Query: "select x from c order by 1", + Expected: []sql.Row{ + {2}, + }, + }, + { + Name: "issue #9039: trigger insert join index error", + SetUpScript: []string{ + "create table a (x int primary key, y int default 1, z int)", + "create table b (x int primary key)", + "create table c (x int primary key)", + "create table d (x int primary key)", + "insert into b values (1), (2)", + "insert into d values (1), (2)", + ` +create trigger insert_into_a +after insert on a +for each row replace into c +select * from d join b using (x) +where d.x = new.x`, + "insert into a (x,z) values (2,2)", + }, + Query: "select x from c order by 1", + Expected: []sql.Row{ + {2}, + }, + }, + { + Name: "issue #9039: trigger insert projection index error", + SetUpScript: []string{ + "create table a (x int primary key, y int default 1, z int)", + "create table b (x int primary key)", + "create table c (x int primary key, y tinyint)", + "create table d (x int primary key)", + "insert into b values (1), (2)", + "insert into d values (1), (2)", + ` +create trigger insert_into_a +after insert on a +for each row replace into c +select d.x+2, 0 from d join b using (x) +where d.x = new.x`, + "insert into a (x,z) values (2,2)", + }, + Query: "select x, y from c order by 1", + Expected: []sql.Row{ + {4, 0}, + }, + }, { Name: "trigger before insert, alter inserted value", SetUpScript: []string{ diff --git a/sql/analyzer/fix_exec_indexes.go b/sql/analyzer/fix_exec_indexes.go index 2c30e3db94..0764666e26 100644 --- a/sql/analyzer/fix_exec_indexes.go +++ b/sql/analyzer/fix_exec_indexes.go @@ -312,6 +312,11 @@ func (s *idxScope) visitChildren(n sql.Node) error { // join subquery aliases continue to enjoy full visibility. sqScope.parentScopes = sqScope.parentScopes[:0] sqScope.lateralScopes = sqScope.lateralScopes[:0] + for _, p := range s.parentScopes { + if p.triggerScope { + sqScope.parentScopes = append(sqScope.parentScopes, p) + } + } } newC, cScope, err := assignIndexesHelper(n.Child, sqScope) if err != nil { diff --git a/sql/rowexec/dml_iters.go b/sql/rowexec/dml_iters.go index 57dfd72555..6da48ac8cf 100644 --- a/sql/rowexec/dml_iters.go +++ b/sql/rowexec/dml_iters.go @@ -193,7 +193,7 @@ func prependRowInPlanForTriggerExecution(row sql.Row) func(c transform.Context) case *plan.Project: // Only prepend rows for projects that aren't the input to inserts and other triggers switch c.Parent.(type) { - case *plan.InsertInto, *plan.Into, *plan.TriggerExecutor, *plan.DeclareCursor: + case *plan.InsertInto, *plan.Into, *plan.TriggerExecutor, *plan.DeclareCursor, *plan.Project: return n, transform.SameTree, nil default: return plan.NewPrependNode(n, row), transform.NewTree, nil @@ -209,6 +209,24 @@ func prependRowInPlanForTriggerExecution(row sql.Row) func(c transform.Context) return n, transform.SameTree, nil } return n.WithProcedure(newNode.(*plan.Procedure)), transform.NewTree, nil + case *plan.InsertInto: + newNode, same, err := transform.NodeWithCtx(n.Source, prependRowForTriggerExecutionSelector, prependRowInPlanForTriggerExecution(row)) + if err != nil { + return nil, transform.SameTree, err + } + if same { + return n, transform.SameTree, nil + } + return n.WithSource(newNode), transform.NewTree, nil + case *plan.SubqueryAlias: + newNode, same, err := transform.NodeWithCtx(n.Child, prependRowForTriggerExecutionSelector, prependRowInPlanForTriggerExecution(row)) + if err != nil { + return nil, transform.SameTree, err + } + if same { + return n, transform.SameTree, nil + } + return n.WithChild(newNode), transform.NewTree, nil default: return n, transform.SameTree, nil }