ddl: refactor index schema change test.

This commit is contained in:
qiuyesuifeng
2015-11-10 16:47:46 +08:00
parent f4c1311801
commit 8a86194ecd

View File

@ -79,6 +79,19 @@ func testDropIndex(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblI
return job
}
func RemoveRecord(ctx context.Context, t table.Table, h int64, data []interface{}) error {
if err := t.RemoveRowAllIndex(ctx, h, data); err != nil {
return err
}
// remove row
if err := t.RemoveRow(ctx, h); err != nil {
return err
}
return nil
}
func (s *testIndexSuite) TestIndex(c *C) {
tblInfo := testTableInfo(c, s.d, "t1", 3)
ctx := testNewContext(c, s.d)
@ -160,20 +173,303 @@ func testGetIndex(t table.Table, name string) *column.IndexedCol {
return nil
}
func (s *testIndexSuite) checkAddIndex(c *C, state model.SchemaState, d *ddl, tblInfo *model.TableInfo, handle int64, indexCol *column.IndexedCol, row []interface{}, isDropped bool) {
// ctx := testNewContext(c, d)
func (s *testIndexSuite) checkIndexKVExist(c *C, ctx context.Context, t table.Table, handle int64, indexCol *column.IndexedCol, columnValues []interface{}, isExist bool) {
c.Assert(len(indexCol.Columns), Equals, len(columnValues))
txn, err := ctx.GetTxn(true)
c.Assert(err, IsNil)
exist, _, err := indexCol.X.Exist(txn, columnValues, handle)
c.Assert(err, IsNil)
c.Assert(exist, Equals, isExist)
err = ctx.FinishTxn(false)
c.Assert(err, IsNil)
}
func (s *testIndexSuite) checkNoneIndex(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, indexCol *column.IndexedCol, row []interface{}) {
t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
columnValues := make([]interface{}, len(indexCol.Columns))
for i, column := range indexCol.Columns {
columnValues[i] = row[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
}
func (s *testIndexSuite) checkDeleteOnlyIndex(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, indexCol *column.IndexedCol, row []interface{}, isDropped bool) {
t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
_, err := ctx.GetTxn(true)
c.Assert(err, IsNil)
i := int64(0)
err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
c.Assert(data, DeepEquals, row)
i++
return true, nil
})
c.Assert(err, IsNil)
c.Assert(i, Equals, int64(1))
columnValues := make([]interface{}, len(indexCol.Columns))
for i, column := range indexCol.Columns {
columnValues[i] = row[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, isDropped)
// Test add a new row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
newRow := []interface{}{int64(11), int64(22), int64(33)}
handle, err = t.AddRecord(ctx, newRow)
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
rows := [][]interface{}{row, newRow}
i = int64(0)
t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
c.Assert(data, DeepEquals, rows[i])
i++
return true, nil
})
c.Assert(i, Equals, int64(2))
for i, column := range indexCol.Columns {
columnValues[i] = newRow[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
// Test update a new row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
newUpdateRow := []interface{}{int64(44), int64(55), int64(66)}
touched := map[int]bool{0: true, 1: true, 2: true}
err = t.UpdateRecord(ctx, handle, newRow, newUpdateRow, touched)
c.Assert(err, IsNil)
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
for i, column := range indexCol.Columns {
columnValues[i] = newUpdateRow[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
// Test remove a row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
err = RemoveRecord(ctx, t, handle, newUpdateRow)
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
i = int64(0)
t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
i++
return true, nil
})
c.Assert(i, Equals, int64(1))
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
}
func (s *testIndexSuite) checkWriteOnlyIndex(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, indexCol *column.IndexedCol, row []interface{}, isDropped bool) {
t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
_, err := ctx.GetTxn(true)
c.Assert(err, IsNil)
i := int64(0)
err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
c.Assert(data, DeepEquals, row)
i++
return true, nil
})
c.Assert(err, IsNil)
c.Assert(i, Equals, int64(1))
columnValues := make([]interface{}, len(indexCol.Columns))
for i, column := range indexCol.Columns {
columnValues[i] = row[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, isDropped)
// Test add a new row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
newRow := []interface{}{int64(11), int64(22), int64(33)}
handle, err = t.AddRecord(ctx, newRow)
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
rows := [][]interface{}{row, newRow}
i = int64(0)
t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
c.Assert(data, DeepEquals, rows[i])
i++
return true, nil
})
c.Assert(i, Equals, int64(2))
for i, column := range indexCol.Columns {
columnValues[i] = newRow[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, true)
// Test update a new row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
newUpdateRow := []interface{}{int64(44), int64(55), int64(66)}
touched := map[int]bool{0: true, 1: true, 2: true}
err = t.UpdateRecord(ctx, handle, newRow, newUpdateRow, touched)
c.Assert(err, IsNil)
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
for i, column := range indexCol.Columns {
columnValues[i] = newUpdateRow[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, true)
// Test remove a row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
err = RemoveRecord(ctx, t, handle, newUpdateRow)
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
i = int64(0)
t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
i++
return true, nil
})
c.Assert(i, Equals, int64(1))
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
}
func (s *testIndexSuite) checkPublicIndex(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, indexCol *column.IndexedCol, row []interface{}) {
t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
_, err := ctx.GetTxn(true)
c.Assert(err, IsNil)
i := int64(0)
err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
c.Assert(data, DeepEquals, row)
i++
return true, nil
})
c.Assert(err, IsNil)
c.Assert(i, Equals, int64(1))
columnValues := make([]interface{}, len(indexCol.Columns))
for i, column := range indexCol.Columns {
columnValues[i] = row[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, true)
// Test add a new row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
newRow := []interface{}{int64(11), int64(22), int64(33)}
handle, err = t.AddRecord(ctx, newRow)
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
rows := [][]interface{}{row, newRow}
i = int64(0)
t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
c.Assert(data, DeepEquals, rows[i])
i++
return true, nil
})
c.Assert(i, Equals, int64(2))
for i, column := range indexCol.Columns {
columnValues[i] = newRow[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, true)
// Test update a new row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
newUpdateRow := []interface{}{int64(44), int64(55), int64(66)}
touched := map[int]bool{0: true, 1: true, 2: true}
err = t.UpdateRecord(ctx, handle, newRow, newUpdateRow, touched)
c.Assert(err, IsNil)
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
for i, column := range indexCol.Columns {
columnValues[i] = newUpdateRow[column.Offset]
}
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, true)
// Test remove a row.
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
err = RemoveRecord(ctx, t, handle, newUpdateRow)
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
i = int64(0)
t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
i++
return true, nil
})
c.Assert(i, Equals, int64(1))
s.checkIndexKVExist(c, ctx, t, handle, indexCol, columnValues, false)
}
func (s *testIndexSuite) checkAddOrDropIndex(c *C, state model.SchemaState, d *ddl, tblInfo *model.TableInfo, handle int64, indexCol *column.IndexedCol, row []interface{}, isDropped bool) {
ctx := testNewContext(c, d)
switch state {
case model.StateNone:
// s.checkNoneIndex(c, ctx, d, tblInfo, handle, indexCol)
s.checkNoneIndex(c, ctx, d, tblInfo, handle, indexCol, row)
case model.StateDeleteOnly:
// s.checkDeleteOnlyIndex(c, ctx, d, tblInfo, handle, indexCol, row, isDropped)
s.checkDeleteOnlyIndex(c, ctx, d, tblInfo, handle, indexCol, row, isDropped)
case model.StateWriteOnly:
// s.checkWriteOnlyIndex(c, ctx, d, tblInfo, handle, indexCol, row, isDropped)
s.checkWriteOnlyIndex(c, ctx, d, tblInfo, handle, indexCol, row, isDropped)
case model.StateReorganization:
// do nothing
case model.StatePublic:
// s.checkPublicIndex(c, ctx, d, tblInfo, handle, indexCol, row)
s.checkPublicIndex(c, ctx, d, tblInfo, handle, indexCol, row)
}
}
@ -210,7 +506,7 @@ func (s *testIndexSuite) TestAddIndex(c *C) {
return
}
s.checkAddIndex(c, indexCol.State, d, tblInfo, handle, indexCol, row, false)
s.checkAddOrDropIndex(c, indexCol.State, d, tblInfo, handle, indexCol, row, false)
if indexCol.State == model.StatePublic {
checkOK = true
@ -241,149 +537,72 @@ func (s *testIndexSuite) TestAddIndex(c *C) {
s.d.start()
}
func (s *testIndexSuite) TestIndexState(c *C) {
func (s *testIndexSuite) TestDropIndex(c *C) {
d := newDDL(s.store, nil, nil, 100*time.Millisecond)
defer d.close()
tblInfo := testTableInfo(c, d, "t", 3)
ctx := testNewContext(c, d)
defer ctx.FinishTxn(true)
txn, err := ctx.GetTxn(true)
_, err := ctx.GetTxn(true)
c.Assert(err, IsNil)
testCreateTable(c, ctx, d, s.dbInfo, tblInfo)
defer testDropTable(c, ctx, d, s.dbInfo, tblInfo)
t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
var h int64
h, err = t.AddRecord(ctx, []interface{}{1, 1, 1})
row := []interface{}{int64(1), int64(2), int64(3)}
handle, err := t.AddRecord(ctx, row)
c.Assert(err, IsNil)
ticker := time.NewTicker(d.lease)
done := make(chan *model.Job, 1)
err = ctx.FinishTxn(false)
c.Assert(err, IsNil)
ctx.FinishTxn(false)
go func() {
done <- testCreateIndex(c, ctx, d, s.dbInfo, tblInfo, true, "c1_uni", "c1")
}()
job := testCreateIndex(c, ctx, s.d, s.dbInfo, tblInfo, true, "c1_uni", "c1")
testCheckJobDone(c, d, job, true)
var exist bool
LOOP:
for {
select {
case job := <-done:
testCheckJobDone(c, d, job, true)
break LOOP
case <-ticker.C:
d.close()
err = ctx.FinishTxn(false)
c.Assert(err, IsNil)
t = testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
index := testGetIndex(t, "c1")
if index == nil {
d.start()
continue
}
checkOK := false
oldIndexCol := &column.IndexedCol{}
err = t.RemoveRowAllIndex(ctx, h, []interface{}{1})
c.Assert(err, IsNil)
err = t.RemoveRow(ctx, h)
c.Assert(err, IsNil)
txn, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
exist, _, err = index.X.Exist(txn, []interface{}{1}, h)
c.Assert(err, IsNil)
c.Assert(exist, IsFalse)
h, err = t.AddRecord(ctx, []interface{}{1, 1, 1})
c.Assert(err, IsNil)
txn, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
exist, _, err = index.X.Exist(txn, []interface{}{1}, h)
c.Assert(err, IsNil)
switch index.State {
case model.StateDeleteOnly:
c.Assert(exist, IsFalse)
case model.StateNone:
c.Fatalf("can be none state")
default:
c.Assert(exist, IsTrue)
}
err = ctx.FinishTxn(false)
c.Assert(err, IsNil)
d.start()
tc := &testDDLCallback{}
tc.onJobUpdated = func(job *model.Job) {
if checkOK {
return
}
t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
indexCol := testGetIndex(t, "c1")
if indexCol == nil {
s.checkAddOrDropIndex(c, model.StateNone, d, tblInfo, handle, oldIndexCol, row, true)
checkOK = true
return
}
s.checkAddOrDropIndex(c, indexCol.State, d, tblInfo, handle, indexCol, row, true)
oldIndexCol = indexCol
}
t = testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
c.Assert(t.FindIndexByColName("c1"), NotNil)
d.hook = tc
ctx.FinishTxn(false)
go func() {
done <- testDropIndex(c, ctx, d, s.dbInfo, tblInfo, "c1_uni")
}()
// Use local ddl for callback test.
s.d.close()
LOOP1:
for {
select {
case job := <-done:
testCheckJobDone(c, d, job, false)
break LOOP1
case <-ticker.C:
d.close()
d.close()
d.start()
t = testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
index := testGetIndex(t, "c1")
if index == nil {
d.start()
continue
}
job = testDropIndex(c, ctx, d, s.dbInfo, tblInfo, "c1_uni")
testCheckJobDone(c, d, job, false)
err = t.RemoveRowAllIndex(ctx, h, []interface{}{1})
c.Assert(err, IsNil)
_, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
err = t.RemoveRow(ctx, h)
c.Assert(err, IsNil)
job = testDropTable(c, ctx, d, s.dbInfo, tblInfo)
testCheckJobDone(c, d, job, false)
txn, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
err = ctx.FinishTxn(false)
c.Assert(err, IsNil)
exist, _, err = index.X.Exist(txn, []interface{}{1}, h)
c.Assert(err, IsNil)
c.Assert(exist, IsFalse)
h, err = t.AddRecord(ctx, []interface{}{1, 1, 1})
c.Assert(err, IsNil)
txn, err = ctx.GetTxn(true)
c.Assert(err, IsNil)
exist, _, err = index.X.Exist(txn, []interface{}{1}, h)
c.Assert(err, IsNil)
switch index.State {
case model.StateDeleteOnly:
c.Assert(exist, IsFalse)
case model.StateNone:
c.Fatalf("can be none state")
default:
c.Assert(exist, IsTrue)
}
err = ctx.FinishTxn(false)
c.Assert(err, IsNil)
d.start()
}
}
t = testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
c.Assert(t.FindIndexByColName("c1"), IsNil)
d.close()
s.d.start()
}