diff --git a/ddl/db_test.go b/ddl/db_test.go index e87024fdf63b2..2f415c5457296 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3021,6 +3021,33 @@ func (s *testDBSuite) TestTruncatePartitionAndDropTable(c *C) { hasOldPartitionData = checkPartitionDelRangeDone(c, s, partitionPrefix) c.Assert(hasOldPartitionData, IsFalse) s.testErrorCode(c, "select * from t4;", tmysql.ErrNoSuchTable) + + // Test truncate table partition reassign a new partitionIDs. + s.tk.MustExec("drop table if exists t5;") + s.tk.MustExec("set @@session.tidb_enable_table_partition=1;") + s.tk.MustExec(`create table t5( + id int, name varchar(50), + purchased date + ) + partition by range( year(purchased) ) ( + partition p0 values less than (1990), + partition p1 values less than (1995), + partition p2 values less than (2000), + partition p3 values less than (2005), + partition p4 values less than (2010), + partition p5 values less than (2015) + );`) + is = domain.GetDomain(ctx).InfoSchema() + oldTblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("t5")) + c.Assert(err, IsNil) + oldPID = oldTblInfo.Meta().Partition.Definitions[0].ID + + s.tk.MustExec("truncate table t5;") + is = domain.GetDomain(ctx).InfoSchema() + c.Assert(err, IsNil) + newTblInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t5")) + newPID := newTblInfo.Meta().Partition.Definitions[0].ID + c.Assert(oldPID != newPID, IsTrue) } func (s *testDBSuite) TestPartitionUniqueKeyNeedAllFieldsInPf(c *C) { diff --git a/ddl/partition.go b/ddl/partition.go index b1110209c3e3b..16933b9bf6351 100644 --- a/ddl/partition.go +++ b/ddl/partition.go @@ -417,3 +417,24 @@ func isRangePartitionColUnsignedBigint(cols []*table.Column, pi *model.Partition } return false } + +// truncateTableByReassignPartitionIDs reassign a new partition ids. +func truncateTableByReassignPartitionIDs(job *model.Job, t *meta.Meta, tblInfo *model.TableInfo) error { + newDefs := make([]model.PartitionDefinition, 0, len(tblInfo.Partition.Definitions)) + for _, def := range tblInfo.Partition.Definitions { + pid, err := t.GenGlobalID() + if err != nil { + job.State = model.JobStateCancelled + return errors.Trace(err) + } + newDef := model.PartitionDefinition{ + ID: pid, + Name: def.Name, + LessThan: def.LessThan, + Comment: def.Comment, + } + newDefs = append(newDefs, newDef) + } + tblInfo.Partition.Definitions = newDefs + return nil +} diff --git a/ddl/table.go b/ddl/table.go index 930f871ff43d2..45a5a2372193f 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -209,18 +209,13 @@ func onTruncateTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ erro return ver, errors.Trace(err) } - // We use the new partition ID because all the old data is encoded with the old partition ID, it can not be accessed anymore. var oldPartitionIDs []int64 if tblInfo.GetPartitionInfo() != nil { oldPartitionIDs = getPartitionIDs(tblInfo) - for _, def := range tblInfo.Partition.Definitions { - var pid int64 - pid, err = t.GenGlobalID() - if err != nil { - job.State = model.JobStateCancelled - return ver, errors.Trace(err) - } - def.ID = pid + // We use the new partition ID because all the old data is encoded with the old partition ID, it can not be accessed anymore. + err = truncateTableByReassignPartitionIDs(job, t, tblInfo) + if err != nil { + return ver, errors.Trace(err) } }