From 41b41b667eddb5848b58389c30cd67901286dd0c Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Tue, 14 Dec 2021 08:00:00 +0800 Subject: [PATCH 1/9] executor: fix bug when using IndexMerge in transaction Signed-off-by: guo-shaoge --- executor/index_merge_reader.go | 15 ++++---- executor/index_merge_reader_test.go | 53 +++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/executor/index_merge_reader.go b/executor/index_merge_reader.go index cd27a5049b8b5..253d6cdab999b 100644 --- a/executor/index_merge_reader.go +++ b/executor/index_merge_reader.go @@ -139,21 +139,18 @@ func (e *IndexMergeReaderExecutor) Open(ctx context.Context) (err error) { } func (e *IndexMergeReaderExecutor) buildKeyRangesForTable(tbl table.Table) (ranges [][]kv.KeyRange, err error) { + sc := e.ctx.GetSessionVars().StmtCtx for i, plan := range e.partialPlans { _, ok := plan[0].(*plannercore.PhysicalIndexScan) if !ok { - if tbl.Meta().IsCommonHandle { - keyRanges, err := distsql.CommonHandleRangesToKVRanges(e.ctx.GetSessionVars().StmtCtx, []int64{getPhysicalTableID(tbl)}, e.ranges[i]) - if err != nil { - return nil, err - } - ranges = append(ranges, keyRanges) - } else { - ranges = append(ranges, nil) + keyRanges, err := distsql.TableHandleRangesToKVRanges(sc, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, e.ranges[i], nil) + if err != nil { + return nil, err } + ranges = append(ranges, keyRanges) continue } - keyRange, err := distsql.IndexRangesToKVRanges(e.ctx.GetSessionVars().StmtCtx, getPhysicalTableID(tbl), e.indexes[i].ID, e.ranges[i], e.feedbacks[i]) + keyRange, err := distsql.IndexRangesToKVRanges(sc, getPhysicalTableID(tbl), e.indexes[i].ID, e.ranges[i], e.feedbacks[i]) if err != nil { return nil, err } diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 7fc2ac15e9473..133b441785e96 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -199,22 +199,31 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { " └─TableRowIDScan_7 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo")) // Test with normal key. - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) tk.MustExec("insert into t1 values(1, 1, 1, 1);") - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) tk.MustExec("update t1 set c3 = 100 where c3 = 1;") - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) tk.MustExec("delete from t1;") - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) // Test with primary key, so the partialPlan is TableScan. - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) tk.MustExec("insert into t1 values(1, 1, 1, 1);") - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) tk.MustExec("update t1 set c3 = 100 where c3 = 1;") - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) tk.MustExec("delete from t1;") - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("commit;") if i == 1 { tk.MustExec("set tx_isolation = 'REPEATABLE-READ';") @@ -273,21 +282,37 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { tk.MustExec("insert into t1 values(11, 11, 11, 11, 11);") tk.MustExec("insert into t1 values(21, 21, 21, 21, 21);") tk.MustExec("insert into t1 values(31, 31, 31, 31, 31);") - res := tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;").Sort() + + res := tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 20) and c3 < 20;").Sort() + res.Check(testkit.Rows("1 1 1 1 1", "11 11 11 11 11")) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < -1) and c3 < 20;").Sort() res.Check(testkit.Rows("1 1 1 1 1", "11 11 11 11 11")) - res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < 20) and c3 < 20;").Sort() + + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 20) and c3 < 20;").Sort() + res.Check(testkit.Rows("1 1 1 1 1", "11 11 11 11 11")) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < -1) and c3 < 20;").Sort() res.Check(testkit.Rows("1 1 1 1 1", "11 11 11 11 11")) tk.MustExec("update t1 set c3 = 100 where c3 = 1;") - res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;") + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 20) and c3 < 20;") res.Check(testkit.Rows("11 11 11 11 11")) - res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < 20) and c3 < 20;") + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < -1) and c3 < 20;") + res.Check(testkit.Rows("11 11 11 11 11")) + + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 20) and c3 < 20;") + res.Check(testkit.Rows("11 11 11 11 11")) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < -1) and c3 < 20;") res.Check(testkit.Rows("11 11 11 11 11")) tk.MustExec("delete from t1;") - res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;") + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 20) and c3 < 20;") + res.Check(testkit.Rows()) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < -1) and c3 < 20;") + res.Check(testkit.Rows()) + + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 20) and c3 < 20;") res.Check(testkit.Rows()) - res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < 20) and c3 < 20;") + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < -1) and c3 < 20;") res.Check(testkit.Rows()) tk.MustExec("commit;") } From 9e8be70b24b42266ad0cfbfd1985307fa366f44a Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Wed, 15 Dec 2021 19:38:15 +0800 Subject: [PATCH 2/9] fix bugs in memIndexMergeReader.getMemRowsHandle() Signed-off-by: guo-shaoge --- executor/index_merge_reader_test.go | 12 ++++++++++++ executor/mem_reader.go | 29 +++++++++++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 133b441785e96..e21368d5dc950 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -315,6 +315,18 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < -1) and c3 < 20;") res.Check(testkit.Rows()) tk.MustExec("commit;") + + // This is a case generated by sqlgen to test if clusted index is ok. + // Detect the bugs in memIndexMergeReader.getMemRowsHandle(). + tk.MustExec("drop table if exists t1;") + tk.MustExec(`create table t1 (col_30 decimal default 0 , + col_31 char(99) collate utf8_bin default 'sVgzHblmYYtEjVg' not null , + col_37 int unsigned default 377206828 , + primary key idx_16 ( col_37 ) , key idx_19 ( col_31) ) collate utf8mb4_general_ci ;`) + tk.MustExec("begin;") + tk.MustExec("insert ignore into t1 values (388021, '', 416235653);") + tk.MustQuery("select /*+ use_index_merge( t1 ) */ 1 from t1 where ( t1.col_31 in ( 'OiOXzpCs' , 'oaVv' ) or t1.col_37 <= 4059907010 ) and t1.col_30 ;").Check(testkit.Rows("1")) + tk.MustExec("commit;") } func (test *testSerialSuite2) TestIndexMergeReaderMemTracker(c *C) { diff --git a/executor/mem_reader.go b/executor/mem_reader.go index d345d11670c6e..765ea41d0298f 100644 --- a/executor/mem_reader.go +++ b/executor/mem_reader.go @@ -15,6 +15,7 @@ package executor import ( + "fmt" "github.com/pingcap/errors" "github.com/pingcap/tidb/distsql" "github.com/pingcap/tidb/expression" @@ -167,8 +168,6 @@ type memTableReader struct { buffer allocBuf pkColIDs []int64 cacheTable kv.MemBuffer - // Used when extracting handles from row in memTableReader.getMemRowsHandle. - handleCols plannercore.HandleCols } type allocBuf struct { @@ -329,17 +328,23 @@ func (m *memTableReader) getRowData(handle kv.Handle, value []byte) ([][]byte, e // getMemRowsHandle is called when memIndexMergeReader.partialPlans[i] is TableScan. func (m *memTableReader) getMemRowsHandle() ([]kv.Handle, error) { - rows, err := m.getMemRows() + handles := make([]kv.Handle, 0, 16) + err := iterTxnMemBuffer(m.ctx, m.cacheTable, m.kvRanges, func(key, value []byte) error { + handle, err := tablecodec.DecodeRowKey(key) + if err != nil { + return err + } + handles = append(handles, handle) + return nil + }) if err != nil { return nil, err } - handles := make([]kv.Handle, 0, len(rows)) - for _, row := range rows { - handle, err := m.handleCols.BuildHandleByDatums(row) - if err != nil { - return nil, err + + if m.desc { + for i, j := 0, len(handles)-1; i < j; i, j = i+1, j-1 { + handles[i], handles[j] = handles[j], handles[i] } - handles = append(handles, handle) } return handles, nil } @@ -577,7 +582,6 @@ func buildMemIndexMergeReader(us *UnionScanExec, indexMergeReader *IndexMergeRea handleBytes: make([]byte, 0, 16), rd: rd, }, - handleCols: indexMergeReader.handleCols, }) } else { outputOffset := []int{len(indexMergeReader.indexes[i].Columns)} @@ -673,6 +677,11 @@ func (m *memIndexMergeReader) unionHandles(kvRanges [][]kv.KeyRange) (finalHandl switch r := reader.(type) { case *memTableReader: r.kvRanges = kvRanges[i] + tmpRows, err := reader.getMemRows() + if err != nil { + fmt.Println("gjt err: ", err) + } + fmt.Println("gjt rows: ", tmpRows) case *memIndexReader: r.kvRanges = kvRanges[i] default: From 855f48515188bb219f6466470d21b04b2f21f724 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Wed, 15 Dec 2021 19:39:25 +0800 Subject: [PATCH 3/9] fix Signed-off-by: guo-shaoge --- executor/mem_reader.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/executor/mem_reader.go b/executor/mem_reader.go index 765ea41d0298f..01ea39c28518b 100644 --- a/executor/mem_reader.go +++ b/executor/mem_reader.go @@ -677,11 +677,6 @@ func (m *memIndexMergeReader) unionHandles(kvRanges [][]kv.KeyRange) (finalHandl switch r := reader.(type) { case *memTableReader: r.kvRanges = kvRanges[i] - tmpRows, err := reader.getMemRows() - if err != nil { - fmt.Println("gjt err: ", err) - } - fmt.Println("gjt rows: ", tmpRows) case *memIndexReader: r.kvRanges = kvRanges[i] default: From 8d35dce3564764649b2a73d88a42303da153bb28 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Wed, 15 Dec 2021 19:40:58 +0800 Subject: [PATCH 4/9] fix Signed-off-by: guo-shaoge --- executor/mem_reader.go | 1 - 1 file changed, 1 deletion(-) diff --git a/executor/mem_reader.go b/executor/mem_reader.go index 01ea39c28518b..472bb3346db3d 100644 --- a/executor/mem_reader.go +++ b/executor/mem_reader.go @@ -15,7 +15,6 @@ package executor import ( - "fmt" "github.com/pingcap/errors" "github.com/pingcap/tidb/distsql" "github.com/pingcap/tidb/expression" From 6b16bd5ff917f929b8d03b62a390d5bb92220f49 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Wed, 15 Dec 2021 20:55:40 +0800 Subject: [PATCH 5/9] fix didn't split range for partial table reader Signed-off-by: guo-shaoge --- executor/index_merge_reader.go | 8 +++++++- executor/index_merge_reader_test.go | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/executor/index_merge_reader.go b/executor/index_merge_reader.go index 253d6cdab999b..1725c8f75b84b 100644 --- a/executor/index_merge_reader.go +++ b/executor/index_merge_reader.go @@ -143,10 +143,16 @@ func (e *IndexMergeReaderExecutor) buildKeyRangesForTable(tbl table.Table) (rang for i, plan := range e.partialPlans { _, ok := plan[0].(*plannercore.PhysicalIndexScan) if !ok { - keyRanges, err := distsql.TableHandleRangesToKVRanges(sc, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, e.ranges[i], nil) + firstPartRanges, secondPartRanges := distsql.SplitRangesAcrossInt64Boundary(e.ranges[i], false, e.descs[i], tbl.Meta().IsCommonHandle) + firstKeyRanges, err := distsql.TableHandleRangesToKVRanges(sc, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, firstPartRanges, nil) if err != nil { return nil, err } + secondKeyRanges, err1 := distsql.TableHandleRangesToKVRanges(sc, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, secondPartRanges, nil) + if err1 != nil { + return nil, err1 + } + keyRanges := append(firstKeyRanges, secondKeyRanges...) ranges = append(ranges, keyRanges) continue } diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index e21368d5dc950..3affd961c18a4 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -327,6 +327,22 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { tk.MustExec("insert ignore into t1 values (388021, '', 416235653);") tk.MustQuery("select /*+ use_index_merge( t1 ) */ 1 from t1 where ( t1.col_31 in ( 'OiOXzpCs' , 'oaVv' ) or t1.col_37 <= 4059907010 ) and t1.col_30 ;").Check(testkit.Rows("1")) tk.MustExec("commit;") + + tk.MustExec("drop table if exists tbl_3;") + tk.MustExec(`create table tbl_3 ( col_30 decimal , col_31 char(99) , col_32 smallint , + col_33 tinyint unsigned not null , col_34 char(209) , + col_35 char(110) , col_36 int unsigned , col_37 int unsigned , + col_38 decimal(50,15) not null , col_39 char(104), + primary key ( col_37 ) , unique key ( col_33,col_30,col_36,col_39 ) , + unique key ( col_32,col_35 ) , key ( col_31,col_38 ) , + key ( col_31,col_33,col_32,col_35,col_36 ) , + unique key ( col_38,col_34,col_33,col_31,col_30,col_36,col_35,col_37,col_39 ) , + unique key ( col_39,col_32 ) , unique key ( col_30,col_35,col_31,col_38 ) , + key ( col_38,col_32,col_33 ) )`) + tk.MustExec("begin;") + tk.MustExec("insert ignore into tbl_3 values ( 71,'Fipc',-6676,30,'','FgfK',2464927398,4084082400,5602.5868,'' );") + tk.MustQuery("select /*+ use_index_merge( tbl_3 ) */ 1 from tbl_3 where ( tbl_3.col_37 not in ( 1626615245 , 2433569159 ) or tbl_3.col_38 = 0.06 ) ;").Check(testkit.Rows("1")) + tk.MustExec("commit;") } func (test *testSerialSuite2) TestIndexMergeReaderMemTracker(c *C) { From 7c8b82a75d0403a1f39c2aa1871b6e73bec65894 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Thu, 16 Dec 2021 10:36:00 +0800 Subject: [PATCH 6/9] fix Signed-off-by: guo-shaoge --- executor/index_merge_reader.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/executor/index_merge_reader.go b/executor/index_merge_reader.go index 1725c8f75b84b..7fe89de2e3c36 100644 --- a/executor/index_merge_reader.go +++ b/executor/index_merge_reader.go @@ -148,9 +148,9 @@ func (e *IndexMergeReaderExecutor) buildKeyRangesForTable(tbl table.Table) (rang if err != nil { return nil, err } - secondKeyRanges, err1 := distsql.TableHandleRangesToKVRanges(sc, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, secondPartRanges, nil) - if err1 != nil { - return nil, err1 + secondKeyRanges, err := distsql.TableHandleRangesToKVRanges(sc, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, secondPartRanges, nil) + if err != nil { + return nil, err } keyRanges := append(firstKeyRanges, secondKeyRanges...) ranges = append(ranges, keyRanges) From 8f56acdb458383f719aa30b05ec697d8166d16ca Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Fri, 17 Dec 2021 11:45:35 +0800 Subject: [PATCH 7/9] Update executor/index_merge_reader_test.go Co-authored-by: cfzjywxk --- executor/index_merge_reader_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 3affd961c18a4..61700fa26351f 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -316,7 +316,7 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { res.Check(testkit.Rows()) tk.MustExec("commit;") - // This is a case generated by sqlgen to test if clusted index is ok. + // This is a case generated by sqlgen to test if clustered index is ok. // Detect the bugs in memIndexMergeReader.getMemRowsHandle(). tk.MustExec("drop table if exists t1;") tk.MustExec(`create table t1 (col_30 decimal default 0 , From 353f1d3cf78d4edfddc116c63ee1fbde561e5cda Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Fri, 17 Dec 2021 16:13:43 +0800 Subject: [PATCH 8/9] add case Signed-off-by: guo-shaoge --- executor/index_merge_reader_test.go | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 3affd961c18a4..16d3e3c40dd7b 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -315,6 +315,10 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < -1) and c3 < 20;") res.Check(testkit.Rows()) tk.MustExec("commit;") +} + +func (s *testSuite1) TestIndexMergeReaderInTransIssue30685(c *C) { + tk := testkit.NewTestKitWithInit(c, s.store) // This is a case generated by sqlgen to test if clusted index is ok. // Detect the bugs in memIndexMergeReader.getMemRowsHandle(). @@ -343,6 +347,44 @@ func (s *testSuite1) TestIndexMergeInTransaction(c *C) { tk.MustExec("insert ignore into tbl_3 values ( 71,'Fipc',-6676,30,'','FgfK',2464927398,4084082400,5602.5868,'' );") tk.MustQuery("select /*+ use_index_merge( tbl_3 ) */ 1 from tbl_3 where ( tbl_3.col_37 not in ( 1626615245 , 2433569159 ) or tbl_3.col_38 = 0.06 ) ;").Check(testkit.Rows("1")) tk.MustExec("commit;") + + // int + int compound type as clustered index pk. + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 int, c2 int, c3 int, c4 int, primary key(c1, c2) /*T![clustered_index] CLUSTERED */, key(c3));") + + tk.MustExec("begin;") + tk.MustExec("insert into t1 values(1, 1, 1, 1);") + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c3 < 10) and c4 < 10;").Check(testkit.Rows( + "UnionScan_6 1841.86 root lt(test.t1.c4, 10), or(lt(test.t1.c1, -1), lt(test.t1.c3, 10))", + "└─IndexMerge_11 1841.86 root ", + " ├─TableRangeScan_7(Build) 3323.33 cop[tikv] table:t1 range:[-inf,-1), keep order:false, stats:pseudo", + " ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo", + " └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c4, 10)", + " └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo")) + + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c3 < 10) and c4 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c3 < -1) and c4 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c3 < -1) and c4 < 10;").Check(testkit.Rows()) + tk.MustExec("commit;") + + // Single int type as clustered index pk. + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 varchar(100), c2 int, c3 int, c4 int, primary key(c1) /*T![clustered_index] CLUSTERED */, key(c3));") + + tk.MustExec("begin;") + tk.MustExec("insert into t1 values('b', 1, 1, 1);") + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 'a' or c3 < 10) and c4 < 10;").Check(testkit.Rows( + "UnionScan_6 1841.86 root lt(test.t1.c4, 10), or(lt(test.t1.c1, \"a\"), lt(test.t1.c3, 10))", + "└─IndexMerge_11 1841.86 root ", + " ├─TableRangeScan_7(Build) 3323.33 cop[tikv] table:t1 range:[-inf,\"a\"), keep order:false, stats:pseudo", + " ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo", + " └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c4, 10)", + " └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo")) + + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 'a' or c3 < 10) and c4 < 10;").Check(testkit.Rows("b 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 <= 'a' or c3 < -1) and c4 < 10;").Check(testkit.Rows("b 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 'a' or c3 < -1) and c4 < 10;").Check(testkit.Rows()) + tk.MustExec("commit;") } func (test *testSerialSuite2) TestIndexMergeReaderMemTracker(c *C) { From 8ddc1f8a61418b0aae9a51bb783337bf64f595b9 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Sun, 19 Dec 2021 02:50:27 +0800 Subject: [PATCH 9/9] fix Signed-off-by: guo-shaoge --- executor/index_merge_reader_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 5880e1c0edace..80ae4ec6be574 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -382,7 +382,7 @@ func (s *testSuite1) TestIndexMergeReaderInTransIssue30685(c *C) { " └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo")) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 'a' or c3 < 10) and c4 < 10;").Check(testkit.Rows("b 1 1 1")) - tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 <= 'a' or c3 < -1) and c4 < 10;").Check(testkit.Rows("b 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 <= 'b' or c3 < -1) and c4 < 10;").Check(testkit.Rows("b 1 1 1")) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 'a' or c3 < -1) and c4 < 10;").Check(testkit.Rows()) tk.MustExec("commit;") }