Skip to content

Commit

Permalink
Merge branch 'master' into cancal-job
Browse files Browse the repository at this point in the history
  • Loading branch information
zeminzhou authored Jan 17, 2023
2 parents f49d445 + a879ba2 commit c201301
Show file tree
Hide file tree
Showing 35 changed files with 570 additions and 142 deletions.
4 changes: 2 additions & 2 deletions DEPS.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3582,8 +3582,8 @@ def go_deps():
name = "com_github_tikv_client_go_v2",
build_file_proto_mode = "disable_global",
importpath = "github.com/tikv/client-go/v2",
sum = "h1:RI6bs9TDIIJ96N0lR5uZoGO8QNot4qS/1l+Mobx0InM=",
version = "v2.0.5-0.20230110071533-f313ddf58d73",
sum = "h1:B2FNmPDaGirXpIOgQbqxiukIkT8eOT4tKEahqYE2ers=",
version = "v2.0.5-0.20230112062023-fe5b35c5f5dc",
)
go_repository(
name = "com_github_tikv_pd_client",
Expand Down
4 changes: 4 additions & 0 deletions ddl/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,10 @@ func (w *worker) onModifyColumn(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in
job.State = model.JobStateCancelled
return ver, errors.Trace(err)
}
if tblInfo.Partition != nil {
job.State = model.JobStateCancelled
return ver, errors.Trace(dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs("table is partition table"))
}

changingCol := modifyInfo.changingCol
if changingCol == nil {
Expand Down
38 changes: 38 additions & 0 deletions ddl/db_partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"math/rand"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
Expand Down Expand Up @@ -4528,6 +4529,43 @@ func TestPartitionTableWithAnsiQuotes(t *testing.T) {
` PARTITION "pMax" VALUES LESS THAN (MAXVALUE,MAXVALUE))`))
}

func TestIssue40135Ver2(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")

tk1 := testkit.NewTestKit(t, store)
tk1.MustExec("use test")

tk3 := testkit.NewTestKit(t, store)
tk3.MustExec("use test")

tk.MustExec("CREATE TABLE t40135 ( a int DEFAULT NULL, b varchar(32) DEFAULT 'md', index(a)) PARTITION BY HASH (a) PARTITIONS 6")
tk.MustExec("insert into t40135 values (1, 'md'), (2, 'ma'), (3, 'md'), (4, 'ma'), (5, 'md'), (6, 'ma')")
one := true
hook := &ddl.TestDDLCallback{Do: dom}
var checkErr error
var wg sync.WaitGroup
wg.Add(1)
hook.OnJobRunBeforeExported = func(job *model.Job) {
if job.SchemaState == model.StateDeleteOnly {
tk3.MustExec("delete from t40135 where a = 1")
}
if one {
one = false
go func() {
_, checkErr = tk1.Exec("alter table t40135 modify column a int NULL")
wg.Done()
}()
}
}
dom.DDL().SetHook(hook)
tk.MustExec("alter table t40135 modify column a bigint NULL DEFAULT '6243108' FIRST")
wg.Wait()
require.ErrorContains(t, checkErr, "[ddl:8200]Unsupported modify column: table is partition table")
tk.MustExec("admin check table t40135")
}

func TestAlterModifyPartitionColTruncateWarning(t *testing.T) {
t.Skip("waiting for supporting Modify Partition Column again")
store := testkit.CreateMockStore(t)
Expand Down
25 changes: 25 additions & 0 deletions ddl/fktest/foreign_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1810,3 +1810,28 @@ func TestForeignKeyAndConcurrentDDL(t *testing.T) {
}
}
}

func TestForeignKeyAndRenameIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@foreign_key_checks=1;")
tk.MustExec("use test")
tk.MustExec("create table t1 (id int key, b int, index idx1(b));")
tk.MustExec("create table t2 (id int key, b int, constraint fk foreign key (b) references t1(b));")
tk.MustExec("insert into t1 values (1,1),(2,2)")
tk.MustExec("insert into t2 values (1,1),(2,2)")
tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2)
tk.MustGetDBError("delete from t1 where id=1", plannercore.ErrRowIsReferenced2)
tk.MustExec("alter table t1 rename index idx1 to idx2")
tk.MustExec("alter table t2 rename index fk to idx")
tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2)
tk.MustGetDBError("delete from t1 where id=1", plannercore.ErrRowIsReferenced2)
tk.MustExec("alter table t2 drop foreign key fk")
tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete cascade on update cascade")
tk.MustExec("alter table t1 rename index idx2 to idx3")
tk.MustExec("alter table t2 rename index idx to idx0")
tk.MustExec("delete from t1 where id=1")
tk.MustQuery("select * from t1").Check(testkit.Rows("2 2"))
tk.MustQuery("select * from t2").Check(testkit.Rows("2 2"))
tk.MustExec("admin check table t1,t2")
}
21 changes: 20 additions & 1 deletion executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,9 @@ type LimitExec struct {

// columnIdxsUsedByChild keep column indexes of child executor used for inline projection
columnIdxsUsedByChild []int

// Log the close time when opentracing is enabled.
span opentracing.Span
}

// Next implements the Executor Next interface.
Expand Down Expand Up @@ -1470,13 +1473,29 @@ func (e *LimitExec) Open(ctx context.Context) error {
e.childResult = tryNewCacheChunk(e.children[0])
e.cursor = 0
e.meetFirstBatch = e.begin == 0
if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil {
e.span = span
}
return nil
}

// Close implements the Executor Close interface.
func (e *LimitExec) Close() error {
start := time.Now()

e.childResult = nil
return e.baseExecutor.Close()
err := e.baseExecutor.Close()

elapsed := time.Since(start)
if elapsed > time.Millisecond {
logutil.BgLogger().Info("limit executor close takes a long time",
zap.Duration("elapsed", elapsed))
if e.span != nil {
span1 := e.span.Tracer().StartSpan("limitExec.Close", opentracing.ChildOf(e.span.Context()), opentracing.StartTime(start))
defer span1.Finish()
}
}
return err
}

func (e *LimitExec) adjustRequiredRows(chk *chunk.Chunk) *chunk.Chunk {
Expand Down
6 changes: 4 additions & 2 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5556,6 +5556,8 @@ func TestAdmin(t *testing.T) {
}))
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk2 := testkit.NewTestKit(t, store)
tk2.MustExec("use test")
tk.MustExec("drop table if exists admin_test")
tk.MustExec("create table admin_test (c1 int, c2 int, c3 int default 1, index (c1))")
tk.MustExec("insert admin_test (c1) values (1),(2),(NULL)")
Expand Down Expand Up @@ -5680,7 +5682,7 @@ func TestAdmin(t *testing.T) {
// check that the result set has no duplication
defer wg.Done()
for i := 0; i < 10; i++ {
result := tk.MustQuery(`admin show ddl job queries 20`)
result := tk2.MustQuery(`admin show ddl job queries 20`)
rows := result.Rows()
rowIDs := make(map[string]struct{})
for _, row := range rows {
Expand Down Expand Up @@ -5711,7 +5713,7 @@ func TestAdmin(t *testing.T) {
// check that the result set has no duplication
defer wg2.Done()
for i := 0; i < 10; i++ {
result := tk.MustQuery(`admin show ddl job queries limit 3 offset 2`)
result := tk2.MustQuery(`admin show ddl job queries limit 3 offset 2`)
rows := result.Rows()
rowIDs := make(map[string]struct{})
for _, row := range rows {
Expand Down
94 changes: 94 additions & 0 deletions executor/fktest/foreign_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2745,3 +2745,97 @@ func TestForeignKeyMetaInKeyColumnUsage(t *testing.T) {
"INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA='test' and TABLE_NAME='t2' and REFERENCED_TABLE_SCHEMA is not null and REFERENCED_COLUMN_NAME is not null;").
Check(testkit.Rows("fk test t2 a test t1 a", "fk test t2 b test t1 b"))
}

func TestForeignKeyAndGeneratedColumn(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@foreign_key_checks=1")
tk.MustExec("use test")
// Test foreign key with parent column is virtual generated column.
tk.MustExec("create table t1 (a int, b int as (a+1) virtual, index(b));")
tk.MustGetErrMsg("create table t2 (a int, b int, constraint fk foreign key(b) references t1(b));", "[schema:3733]Foreign key 'fk' uses virtual column 'b' which is not supported.")
// Test foreign key with child column is virtual generated column.
tk.MustExec("drop table t1")
tk.MustExec("create table t1 (a int key);")
tk.MustGetErrMsg("create table t2 (a int, c int as (a+1) virtual, constraint fk foreign key(c) references t1(a));", "[schema:3733]Foreign key 'fk' uses virtual column 'c' which is not supported.")
// Test foreign key with parent column is stored generated column.
tk.MustExec("drop table if exists t1,t2")
tk.MustExec("create table t1 (a int, b int as (a) stored, index(b));")
tk.MustExec("create table t2 (a int, b int, constraint fk foreign key(b) references t1(b) on delete cascade on update cascade);")
tk.MustExec("insert into t1 (a) values (1),(2)")
tk.MustExec("insert into t2 (a) values (1),(2)")
tk.MustExec("update t2 set b=a")
tk.MustExec("insert into t2 values (1,1),(2,2)")
tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2)
tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 1", "1 1", "2 2", "2 2"))
tk.MustExec("update t1 set a=a+10 where a=1")
tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("2 2", "11 11"))
tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "1 11", "2 2", "2 2"))
tk.MustExec("delete from t1 where a=2")
tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("11 11"))
tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "1 11"))
// Test foreign key with parent and child column is stored generated column.
tk.MustExec("drop table if exists t1,t2")
tk.MustExec("create table t1 (a int, b int as (a) stored, index(b));")
tk.MustGetErrMsg("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on update cascade);", "[ddl:3104]Cannot define foreign key with ON UPDATE CASCADE clause on a generated column.")
tk.MustGetErrMsg("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on delete set null);", "[ddl:3104]Cannot define foreign key with ON DELETE SET NULL clause on a generated column.")
tk.MustExec("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b));")
tk.MustExec("insert into t1 (a) values (1),(2)")
tk.MustExec("insert into t2 (a) values (1),(2)")
tk.MustGetDBError("insert into t2 (a) values (3)", plannercore.ErrNoReferencedRow2)
tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 1", "2 2"))
tk.MustGetDBError("delete from t1 where b=1", plannercore.ErrRowIsReferenced2)
tk.MustGetDBError("update t1 set a=a+10 where a=1", plannercore.ErrRowIsReferenced2)
tk.MustExec("alter table t2 drop foreign key fk")
tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete cascade")
tk.MustExec("delete from t1 where a=1")
tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("2 2"))
tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("2 2"))
}

func TestForeignKeyAndExpressionIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@foreign_key_checks=1")
tk.MustExec("use test")
tk.MustExec("create table t1 (a int, b int, index idx1 (b), index idx2 ((b*2)));")
tk.MustExec("create table t2 (a int, b int, index((b*2)), constraint fk foreign key(b) references t1(b));")
tk.MustExec("insert into t1 values (1,1),(2,2)")
tk.MustExec("insert into t2 values (1,1),(2,2)")
tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2)
tk.MustGetDBError("update t1 set b=b+10 where b=1", plannercore.ErrRowIsReferenced2)
tk.MustGetDBError("delete from t1 where b=1", plannercore.ErrRowIsReferenced2)
tk.MustGetErrMsg("alter table t1 drop index idx1", "[ddl:1553]Cannot drop index 'idx1': needed in a foreign key constraint")
tk.MustGetErrMsg("alter table t2 drop index fk", "[ddl:1553]Cannot drop index 'fk': needed in a foreign key constraint")
tk.MustExec("alter table t2 drop foreign key fk")
tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade")
tk.MustExec("update t1 set b=b+10 where b=1")
tk.MustExec("delete from t1 where b=2")
tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("1 11"))
tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "2 <nil>"))
tk.MustExec("admin check table t1")
tk.MustExec("admin check table t2")
}

func TestForeignKeyAndMultiValuedIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@foreign_key_checks=1")
tk.MustExec("use test")
tk.MustExec("create table t1 (id int primary key, a json, b int generated always as (a->'$.id') stored, index idx1(b), index idx2((cast(a ->'$.data' as signed array))))")
tk.MustExec("create table t2 (id int, b int, constraint fk foreign key(b) references t1(b));")
tk.MustExec(`insert into t1 (id, a) values (1, '{"id": "1", "data": [1,11,111]}')`)
tk.MustExec(`insert into t1 (id, a) values (2, '{"id": "2", "data": [2,22,222]}')`)
tk.MustExec("insert into t2 values (1,1),(2,2)")
tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2)
tk.MustGetDBError(`update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1`, plannercore.ErrRowIsReferenced2)
tk.MustGetDBError(`delete from t1 where id=1`, plannercore.ErrRowIsReferenced2)
tk.MustExec("alter table t2 drop foreign key fk")
tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade")
tk.MustExec(`update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1`)
tk.MustExec(`delete from t1 where id=2`)
tk.MustQuery("select id,b from t1 order by id").Check(testkit.Rows("1 10"))
tk.MustQuery("select id,b from t2 order by id").Check(testkit.Rows("1 10", "2 <nil>"))
tk.MustExec("admin check table t1")
tk.MustExec("admin check table t2")
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ require (
github.com/stretchr/testify v1.8.0
github.com/tdakkota/asciicheck v0.1.1
github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2
github.com/tikv/client-go/v2 v2.0.5-0.20230110071533-f313ddf58d73
github.com/tikv/client-go/v2 v2.0.5-0.20230112062023-fe5b35c5f5dc
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144
github.com/twmb/murmur3 v1.1.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -936,8 +936,8 @@ github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJf
github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU=
github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a h1:J/YdBZ46WKpXsxsW93SG+q0F8KI+yFrcIDT4c/RNoc4=
github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a/go.mod h1:h4xBhSNtOeEosLJ4P7JyKXX7Cabg7AVkWCK5gV2vOrM=
github.com/tikv/client-go/v2 v2.0.5-0.20230110071533-f313ddf58d73 h1:RI6bs9TDIIJ96N0lR5uZoGO8QNot4qS/1l+Mobx0InM=
github.com/tikv/client-go/v2 v2.0.5-0.20230110071533-f313ddf58d73/go.mod h1:dO/2a/xi/EO3eVv9xN5G1VFtd/hythzgTeeCbW5SWuI=
github.com/tikv/client-go/v2 v2.0.5-0.20230112062023-fe5b35c5f5dc h1:B2FNmPDaGirXpIOgQbqxiukIkT8eOT4tKEahqYE2ers=
github.com/tikv/client-go/v2 v2.0.5-0.20230112062023-fe5b35c5f5dc/go.mod h1:dO/2a/xi/EO3eVv9xN5G1VFtd/hythzgTeeCbW5SWuI=
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 h1:ckPpxKcl75mO2N6a4cJXiZH43hvcHPpqc9dh1TmH1nc=
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07/go.mod h1:CipBxPfxPUME+BImx9MUYXCnAVLS3VJUr3mnSJwh40A=
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro=
Expand Down
3 changes: 3 additions & 0 deletions planner/core/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ type planDigester struct {

// NormalizeFlatPlan normalizes a FlatPhysicalPlan and generates plan digest.
func NormalizeFlatPlan(flat *FlatPhysicalPlan) (normalized string, digest *parser.Digest) {
if flat == nil {
return "", parser.NewDigest(nil)
}
selectPlan, selectPlanOffset := flat.Main.GetSelectPlan()
if len(selectPlan) == 0 || !selectPlan[0].IsPhysicalPlan {
return "", parser.NewDigest(nil)
Expand Down
1 change: 1 addition & 0 deletions planner/core/find_best_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,7 @@ func (ds *DataSource) convertToIndexMergeScan(prop *property.PhysicalProperty, c
cop.tablePlan = ts
cop.idxMergePartPlans = scans
cop.idxMergeIsIntersection = path.IndexMergeIsIntersection
cop.idxMergeAccessMVIndex = path.IndexMergeAccessMVIndex
if remainingFilters != nil {
cop.rootTaskConds = remainingFilters
}
Expand Down
2 changes: 1 addition & 1 deletion planner/core/indexmerge_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ func (ds *DataSource) generateIndexMerge4MVIndex(normalPathCnt int, filters []ex

// buildPartialPathUp4MVIndex builds these partial paths up to a complete index merge path.
func (ds *DataSource) buildPartialPathUp4MVIndex(partialPaths []*util.AccessPath, isIntersection bool, remainingFilters []expression.Expression) *util.AccessPath {
indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths}
indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths, IndexMergeAccessMVIndex: true}
indexMergePath.IndexMergeIsIntersection = isIntersection
indexMergePath.TableFilters = remainingFilters

Expand Down
13 changes: 13 additions & 0 deletions planner/core/indexmerge_path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,16 @@ index i_int((cast(j->'$.int' as signed array))))`)
result.Check(testkit.Rows(output[i].Plan...))
}
}

func TestMVIndexIndexMergePlanCache(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(j json, index kj((cast(j as signed array))))`)

tk.MustExec("prepare st from 'select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j))'")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: query accesses generated columns is un-cacheable"))
tk.MustExec("execute st")
tk.MustExec("execute st")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
}
12 changes: 6 additions & 6 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,7 @@ func getUintFromNode(ctx sessionctx.Context, n ast.Node, mustInt64orUint64 bool)
return 0, false, true
}
if mustInt64orUint64 {
if expected := checkParamTypeInt64orUint64(v); !expected {
if expected, _ := CheckParamTypeInt64orUint64(v); !expected {
return 0, false, false
}
}
Expand Down Expand Up @@ -2054,19 +2054,19 @@ func getUintFromNode(ctx sessionctx.Context, n ast.Node, mustInt64orUint64 bool)
return 0, false, false
}

// check param type for plan cache limit, only allow int64 and uint64 now
// CheckParamTypeInt64orUint64 check param type for plan cache limit, only allow int64 and uint64 now
// eg: set @a = 1;
func checkParamTypeInt64orUint64(param *driver.ParamMarkerExpr) bool {
func CheckParamTypeInt64orUint64(param *driver.ParamMarkerExpr) (bool, uint64) {
val := param.GetValue()
switch v := val.(type) {
case int64:
if v >= 0 {
return true
return true, uint64(v)
}
case uint64:
return true
return true, v
}
return false
return false, 0
}

func extractLimitCountOffset(ctx sessionctx.Context, limit *ast.Limit) (count uint64,
Expand Down
Loading

0 comments on commit c201301

Please sign in to comment.