diff --git a/pkg/server/handler/optimizor/plan_replayer_test.go b/pkg/server/handler/optimizor/plan_replayer_test.go index dc49ffdc665b9..144e26311c7eb 100644 --- a/pkg/server/handler/optimizor/plan_replayer_test.go +++ b/pkg/server/handler/optimizor/plan_replayer_test.go @@ -186,7 +186,7 @@ func TestDumpPlanReplayerAPI(t *testing.T) { tk.MustExec(fmt.Sprintf(`plan replayer load "%s"`, path)) // 3-3. assert that the count and modify count in the stats is as expected - rows := tk.MustQuery("show stats_meta") + rows := tk.MustQuery(`show stats_meta where table_name="t"`) require.True(t, rows.Next(), "unexpected data") var dbName, tableName string var modifyCount, count int64 @@ -217,6 +217,7 @@ func prepareData4PlanReplayer(t *testing.T, client *testserverclient.TestServerC tk.MustExec("create table t(a int)") tk.MustExec("CREATE TABLE authors (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100) NOT NULL,email VARCHAR(100) UNIQUE NOT NULL);") tk.MustExec("CREATE TABLE books (id INT PRIMARY KEY AUTO_INCREMENT,title VARCHAR(200) NOT NULL,publication_date DATE NOT NULL,author_id INT,FOREIGN KEY (author_id) REFERENCES authors(id) ON DELETE CASCADE);") + tk.MustExec("create table tt(a int, b varchar(10)) PARTITION BY HASH(a) PARTITIONS 4;") err = h.HandleDDLEvent(<-h.DDLEventCh()) require.NoError(t, err) tk.MustExec("insert into t values(1), (2), (3), (4)") @@ -224,6 +225,9 @@ func prepareData4PlanReplayer(t *testing.T, client *testserverclient.TestServerC tk.MustExec("analyze table t") tk.MustExec("insert into t values(5), (6), (7), (8)") require.NoError(t, h.DumpStatsDeltaToKV(true)) + tk.MustExec("INSERT INTO tt (a, b) VALUES (1, 'str1'), (2, 'str2'), (3, 'str3'), (4, 'str4'),(5, 'str5'), (6, 'str6'), (7, 'str7'), (8, 'str8'),(9, 'str9'), (10, 'str10'), (11, 'str11'), (12, 'str12'),(13, 'str13'), (14, 'str14'), (15, 'str15'), (16, 'str16'),(17, 'str17'), (18, 'str18'), (19, 'str19'), (20, 'str20'),(21, 'str21'), (22, 'str22'), (23, 'str23'), (24, 'str24'),(25, 'str25'), (26, 'str26'), (27, 'str27'), (28, 'str28'),(29, 'str29'), (30, 'str30'), (31, 'str31'), (32, 'str32'),(33, 'str33'), (34, 'str34'), (35, 'str35'), (36, 'str36'),(37, 'str37'), (38, 'str38'), (39, 'str39'), (40, 'str40'),(41, 'str41'), (42, 'str42'), (43, 'str43'), (44, 'str44'),(45, 'str45'), (46, 'str46'), (47, 'str47'), (48, 'str48'),(49, 'str49'), (50, 'str50'), (51, 'str51'), (52, 'str52'),(53, 'str53'), (54, 'str54'), (55, 'str55'), (56, 'str56'),(57, 'str57'), (58, 'str58'), (59, 'str59'), (60, 'str60'),(61, 'str61'), (62, 'str62'), (63, 'str63'), (64, 'str64'),(65, 'str65'), (66, 'str66'), (67, 'str67'), (68, 'str68'),(69, 'str69'), (70, 'str70'), (71, 'str71'), (72, 'str72'),(73, 'str73'), (74, 'str74'), (75, 'str75'), (76, 'str76'),(77, 'str77'), (78, 'str78'), (79, 'str79'), (80, 'str80'),(81, 'str81'), (82, 'str82'), (83, 'str83'), (84, 'str84'),(85, 'str85'), (86, 'str86'), (87, 'str87'), (88, 'str88'),(89, 'str89'), (90, 'str90'), (91, 'str91'), (92, 'str92'),(93, 'str93'), (94, 'str94'), (95, 'str95'), (96, 'str96'),(97, 'str97'), (98, 'str98'), (99, 'str99'), (100, 'str100');") + require.NoError(t, h.DumpStatsDeltaToKV(true)) + tk.MustExec("analyze table tt") rows := tk.MustQuery("plan replayer dump explain select * from t") require.True(t, rows.Next(), "unexpected data") var filename string @@ -425,8 +429,12 @@ func prepareData4Issue43192(t *testing.T, client *testserverclient.TestServerCli tk.MustExec("create database planReplayer") tk.MustExec("use planReplayer") - tk.MustExec("create table t(a int, b int, INDEX ia (a), INDEX ib (b));") + tk.MustExec("create table t(a int, b int, INDEX ia (a), INDEX ib (b)) PARTITION BY HASH(a) PARTITIONS 4;") err = h.HandleDDLEvent(<-h.DDLEventCh()) + tk.MustExec("INSERT INTO t (a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4),(5, 5), (6, 6), (7, 7), (8, 8),(9, 9), (10, 10), (11, 11), (12, 12),(13, 13), (14, 14), (15, 15), (16, 16),(17, 17), (18, 18), (19, 19), (20, 20),(21, 21), (22, 22), (23, 23), (24, 24),(25, 25), (26, 26), (27, 27), (28, 28),(29, 29), (30, 30), (31, 31), (32, 32),(33, 33), (34, 34), (35, 35), (36, 36),(37, 37), (38, 38), (39, 39), (40, 40),(41, 41), (42, 42), (43, 43), (44, 44),(45, 45), (46, 46), (47, 47), (48, 48),(49, 49), (50, 50), (51, 51), (52, 52),(53, 53), (54, 54), (55, 55), (56, 56),(57, 57), (58, 58), (59, 59), (60, 60),(61, 61), (62, 62), (63, 63), (64, 64),(65, 65), (66, 66), (67, 67), (68, 68),(69, 69), (70, 70), (71, 71), (72, 72),(73, 73), (74, 74), (75, 75), (76, 76),(77, 77), (78, 78), (79, 79), (80, 80),(81, 81), (82, 82), (83, 83), (84, 84),(85, 85), (86, 86), (87, 87), (88, 88),(89, 89), (90, 90), (91, 91), (92, 92),(93, 93), (94, 94), (95, 95), (96, 96),(97, 97), (98, 98), (99, 99), (100, 100);") + require.NoError(t, h.DumpStatsDeltaToKV(true)) + tk.MustExec("analyze table t") + require.NoError(t, err) tk.MustExec("create global binding for select a, b from t where a in (1, 2, 3) using select a, b from t use index (ib) where a in (1, 2, 3)") rows := tk.MustQuery("plan replayer dump explain select a, b from t where a in (1, 2, 3)") diff --git a/pkg/statistics/histogram.go b/pkg/statistics/histogram.go index 92c6d3b19b0da..fc3b948f27aaa 100644 --- a/pkg/statistics/histogram.go +++ b/pkg/statistics/histogram.go @@ -772,8 +772,8 @@ func HistogramToProto(hg *Histogram) *tipb.Histogram { for i := 0; i < hg.Len(); i++ { bkt := &tipb.Bucket{ Count: hg.Buckets[i].Count, - LowerBound: hg.GetLower(i).GetBytes(), - UpperBound: hg.GetUpper(i).GetBytes(), + LowerBound: DeepSlice(hg.GetLower(i).GetBytes()), + UpperBound: DeepSlice(hg.GetUpper(i).GetBytes()), Repeats: hg.Buckets[i].Repeat, Ndv: &hg.Buckets[i].NDV, } @@ -782,6 +782,13 @@ func HistogramToProto(hg *Histogram) *tipb.Histogram { return protoHg } +// DeepSlice sallowly clones a slice. +func DeepSlice[T any](s []T) []T { + r := make([]T, len(s)) + copy(r, s) + return r +} + // HistogramFromProto converts Histogram from its protobuf representation. // Note that we will set BytesDatum for the lower/upper bound in the bucket, the decode will // be after all histograms merged.