Skip to content

Commit

Permalink
executor: disallow subquery in insert values clause reference upper s…
Browse files Browse the repository at this point in the history
…cope (#16872) (#16952)

Co-authored-by: cfzjywxk <lsswxr@163.com>
Co-authored-by: lysu <sulifx@gmail.com>
  • Loading branch information
3 people authored May 6, 2020
1 parent fecb0c9 commit eccb800
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
26 changes: 26 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5441,3 +5441,29 @@ func (s *testSuite1) TestIssue16854(c *C) {
tk.MustQuery("select distinct a from t order by a").Check(testkit.Rows("WAITING", "PRINTED", "WAITING,PRINTED", "STOCKUP", "WAITING,STOCKUP", "PRINTED,STOCKUP", "WAITING,PRINTED,STOCKUP"))
tk.MustExec("drop table t")
}

// this is from jira issue #5856
func (s *testSuite1) TestInsertValuesWithSubQuery(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test;")
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t2(a int, b int, c int)")
defer tk.MustExec("drop table if exists t2")

// should not reference upper scope
c.Assert(tk.ExecToErr("insert into t2 values (11, 8, (select not b))"), NotNil)
c.Assert(tk.ExecToErr("insert into t2 set a = 11, b = 8, c = (select b))"), NotNil)

// subquery reference target table is allowed
tk.MustExec("insert into t2 values(1, 1, (select b from t2))")
tk.MustQuery("select * from t2").Check(testkit.Rows("1 1 <nil>"))
tk.MustExec("insert into t2 set a = 1, b = 1, c = (select b+1 from t2)")
tk.MustQuery("select * from t2").Check(testkit.Rows("1 1 <nil>", "1 1 2"))

// insert using column should work normally
tk.MustExec("delete from t2")
tk.MustExec("insert into t2 values(2, 4, a)")
tk.MustQuery("select * from t2").Check(testkit.Rows("2 4 2"))
tk.MustExec("insert into t2 set a = 3, b = 5, c = b")
tk.MustQuery("select * from t2").Check(testkit.Rows("2 4 2", "3 5 5"))
}
14 changes: 12 additions & 2 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2139,7 +2139,12 @@ func (b *PlanBuilder) buildSetValuesOfInsert(ctx context.Context, insert *ast.In
return ErrBadGeneratedColumn.GenWithStackByArgs(assign.Column.Name.O, tableInfo.Name.O)
}
b.curClause = fieldList
expr, _, err := b.rewriteWithPreprocess(ctx, assign.Expr, mockTablePlan, nil, nil, true, checkRefColumn)
// subquery in insert values should not reference upper scope
usingPlan := mockTablePlan
if _, ok := assign.Expr.(*ast.SubqueryExpr); ok {
usingPlan = LogicalTableDual{}.Init(b.ctx, b.getSelectOffset())
}
expr, _, err := b.rewriteWithPreprocess(ctx, assign.Expr, usingPlan, nil, nil, true, checkRefColumn)
if err != nil {
return err
}
Expand Down Expand Up @@ -2212,7 +2217,12 @@ func (b *PlanBuilder) buildValuesListOfInsert(ctx context.Context, insert *ast.I
}
default:
b.curClause = fieldList
expr, _, err = b.rewriteWithPreprocess(ctx, valueItem, mockTablePlan, nil, nil, true, checkRefColumn)
// subquery in insert values should not reference upper scope
usingPlan := mockTablePlan
if _, ok := valueItem.(*ast.SubqueryExpr); ok {
usingPlan = LogicalTableDual{}.Init(b.ctx, b.getSelectOffset())
}
expr, _, err = b.rewriteWithPreprocess(ctx, valueItem, usingPlan, nil, nil, true, checkRefColumn)
}
if err != nil {
return err
Expand Down

0 comments on commit eccb800

Please sign in to comment.