diff --git a/executor/executor_test.go b/executor/executor_test.go index d9af095abff4f..ac06eb6fdf59f 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -1838,6 +1838,13 @@ func (s *testSuiteP1) TestGeneratedColumnRead(c *C) { result = tk.MustQuery(`SELECT * FROM test_gc_read ORDER BY a`) result.Check(testkit.Rows(`10 `, `11 2 13 22 26`, `13 4 17 52 34`, `18 8 26 144 52`)) + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int)") + tk.MustExec("insert into t values(18)") + tk.MustExec("update test_gc_read set a = a+1 where a in (select a from t)") + result = tk.MustQuery("select * from test_gc_read order by a") + result.Check(testkit.Rows(`10 `, `11 2 13 22 26`, `13 4 17 52 34`, `19 8 27 152 54`)) + // Test different types between generation expression and generated column. tk.MustExec(`CREATE TABLE test_gc_read_cast(a VARCHAR(255), b VARCHAR(255), c INT AS (JSON_EXTRACT(a, b)), d INT AS (JSON_EXTRACT(a, b)) STORED)`) tk.MustExec(`INSERT INTO test_gc_read_cast (a, b) VALUES ('{"a": "3"}', '$.a')`) diff --git a/executor/update_test.go b/executor/update_test.go index 1bf05f2dd525d..257ebb2a9ae28 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -225,3 +225,13 @@ func (s *testUpdateSuite) TestUpdateSchemaChange(c *C) { tk.MustQuery(`select * from t;`).Check(testkit.Rows( `1 2`)) } + +func (s *testUpdateSuite) TestUpdateMultiDatabaseTable(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop database if exists test2") + tk.MustExec("create database test2") + tk.MustExec("create table t(a int, b int generated always as (a+1) virtual)") + tk.MustExec("create table test2.t(a int, b int generated always as (a+1) virtual)") + tk.MustExec("update t, test2.t set test.t.a=1") +} diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 74a1e52b01939..883d8a5921f00 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -3013,8 +3013,6 @@ func (b *PlanBuilder) buildUpdateLists( // If columns in set list contains generated columns, raise error. // And, fill virtualAssignments here; that's for generated columns. virtualAssignments := make([]*ast.Assignment, 0) - tableAsName := make(map[*model.TableInfo][]*model.CIStr) - extractTableAsNameForUpdate(p, tableAsName) for _, tn := range tableList { tableInfo := tn.TableInfo @@ -3030,12 +3028,10 @@ func (b *PlanBuilder) buildUpdateLists( if _, ok := modifyColumns[columnFullName]; ok { return nil, nil, false, ErrBadGeneratedColumn.GenWithStackByArgs(colInfo.Name.O, tableInfo.Name.O) } - for _, asName := range tableAsName[tableInfo] { - virtualAssignments = append(virtualAssignments, &ast.Assignment{ - Column: &ast.ColumnName{Table: *asName, Name: colInfo.Name}, - Expr: tableVal.Cols()[i].GeneratedExpr, - }) - } + virtualAssignments = append(virtualAssignments, &ast.Assignment{ + Column: &ast.ColumnName{Schema: tn.Schema, Table: tn.Name, Name: colInfo.Name}, + Expr: tableVal.Cols()[i].GeneratedExpr, + }) } } @@ -3096,47 +3092,6 @@ func (b *PlanBuilder) buildUpdateLists( return newList, p, allAssignmentsAreConstant, nil } -// extractTableAsNameForUpdate extracts tables' alias names for update. -func extractTableAsNameForUpdate(p LogicalPlan, asNames map[*model.TableInfo][]*model.CIStr) { - switch x := p.(type) { - case *DataSource: - alias := extractTableAlias(p) - if alias != nil { - if _, ok := asNames[x.tableInfo]; !ok { - asNames[x.tableInfo] = make([]*model.CIStr, 0, 1) - } - asNames[x.tableInfo] = append(asNames[x.tableInfo], &alias.tblName) - } - case *LogicalProjection: - if !x.calculateGenCols { - return - } - - ds, isDS := x.Children()[0].(*DataSource) - if !isDS { - // try to extract the DataSource below a LogicalUnionScan. - if us, isUS := x.Children()[0].(*LogicalUnionScan); isUS { - ds, isDS = us.Children()[0].(*DataSource) - } - } - if !isDS { - return - } - - alias := extractTableAlias(x) - if alias != nil { - if _, ok := asNames[ds.tableInfo]; !ok { - asNames[ds.tableInfo] = make([]*model.CIStr, 0, 1) - } - asNames[ds.tableInfo] = append(asNames[ds.tableInfo], &alias.tblName) - } - default: - for _, child := range p.Children() { - extractTableAsNameForUpdate(child, asNames) - } - } -} - func (b *PlanBuilder) buildDelete(ctx context.Context, delete *ast.DeleteStmt) (Plan, error) { b.pushSelectOffset(0) b.pushTableHints(delete.TableHints, typeDelete, 0) @@ -3946,6 +3901,7 @@ func extractTableList(node ast.ResultSetNode, input []*ast.TableName, asName boo if x.AsName.L != "" && asName { newTableName := *s newTableName.Name = x.AsName + newTableName.Schema = model.NewCIStr("") input = append(input, &newTableName) } else { input = append(input, s)