示例#1
0
func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	startKey := t.RecordKey(0, nil)
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	filterFunc := func(h1 int64, vals1 []interface{}, cols []*column.Col) (bool, error) {
		isExist, h2, err := kvIndex.Exist(txn, vals1, h1)
		if terror.ErrorEqual(err, kv.ErrKeyExists) {
			record1 := &RecordData{Handle: h1, Values: vals1}
			record2 := &RecordData{Handle: h2, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", record2, record1)
		}
		if err != nil {
			return false, errors.Trace(err)
		}
		if !isExist {
			record := &RecordData{Handle: h1, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", nil, record)
		}

		return true, nil
	}
	err := t.IterRecords(txn, startKey, cols, filterFunc)

	if err != nil {
		return errors.Trace(err)
	}

	return nil
}
示例#2
0
文件: tables.go 项目: lovedboy/tidb
// TableFromMeta creates a Table instance from model.TableInfo.
func TableFromMeta(alloc autoid.Allocator, tblInfo *model.TableInfo) (table.Table, error) {
	if tblInfo.State == model.StateNone {
		return nil, errors.Errorf("table %s can't be in none state", tblInfo.Name)
	}

	columns := make([]*column.Col, 0, len(tblInfo.Columns))
	for _, colInfo := range tblInfo.Columns {
		if colInfo.State == model.StateNone {
			return nil, errors.Errorf("column %s can't be in none state", colInfo.Name)
		}

		col := &column.Col{ColumnInfo: *colInfo}
		columns = append(columns, col)
	}

	t := newTable(tblInfo.ID, tblInfo.Name.O, columns, alloc)

	for _, idxInfo := range tblInfo.Indices {
		if idxInfo.State == model.StateNone {
			return nil, errors.Errorf("index %s can't be in none state", idxInfo.Name)
		}

		idx := &column.IndexedCol{
			IndexInfo: *idxInfo,
		}

		idx.X = kv.NewKVIndex(t.IndexPrefix(), idxInfo.Name.L, idxInfo.ID, idxInfo.Unique)

		t.AddIndex(idx)
	}
	t.meta = tblInfo
	return t, nil
}
示例#3
0
文件: tables.go 项目: yzl11/vessel
// TableFromMeta creates a Table instance from model.TableInfo.
func TableFromMeta(alloc autoid.Allocator, tblInfo *model.TableInfo) table.Table {
	if tblInfo.State == model.StateNone {
		log.Fatalf("table %s can't be in none state", tblInfo.Name)
	}

	columns := make([]*column.Col, 0, len(tblInfo.Columns))
	for _, colInfo := range tblInfo.Columns {
		if colInfo.State == model.StateNone {
			log.Fatalf("column %s can't be in none state", colInfo.Name)
		}

		col := &column.Col{ColumnInfo: *colInfo}
		columns = append(columns, col)
	}

	t := NewTable(tblInfo.ID, tblInfo.Name.O, columns, alloc)

	for _, idxInfo := range tblInfo.Indices {
		if idxInfo.State == model.StateNone {
			log.Fatalf("index %s can't be in none state", idxInfo.Name)
		}

		idx := &column.IndexedCol{
			IndexInfo: *idxInfo,
			X:         kv.NewKVIndex(t.indexPrefix, idxInfo.Name.L, idxInfo.Unique),
		}
		t.AddIndex(idx)
	}

	t.state = tblInfo.State
	return t
}
示例#4
0
文件: ddl.go 项目: botvs/tidb
func (d *ddl) buildIndex(ctx context.Context, t table.Table, idxInfo *model.IndexInfo, unique bool) error {
	firstKey := t.FirstKey()
	prefix := t.KeyPrefix()

	txn, err := ctx.GetTxn(false)
	if err != nil {
		return errors.Trace(err)
	}
	it, err := txn.Seek([]byte(firstKey))
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()
	for it.Valid() && strings.HasPrefix(it.Key(), prefix) {
		var err error
		handle, err := util.DecodeHandleFromRowKey(it.Key())
		log.Info("building index...", handle)
		if err != nil {
			return errors.Trace(err)
		}
		// TODO: v is timestamp ?
		// fetch datas
		cols := t.Cols()
		var vals []interface{}
		for _, v := range idxInfo.Columns {
			var (
				data []byte
				val  interface{}
			)
			col := cols[v.Offset]
			k := t.RecordKey(handle, col)
			data, err = txn.Get([]byte(k))
			if err != nil {
				return errors.Trace(err)
			}
			val, err = t.DecodeValue(data, col)
			if err != nil {
				return errors.Trace(err)
			}
			vals = append(vals, val)
		}
		// build index
		kvX := kv.NewKVIndex(t.IndexPrefix(), idxInfo.Name.L, unique)
		err = kvX.Create(txn, vals, handle)
		if err != nil {
			return errors.Trace(err)
		}

		rk := []byte(t.RecordKey(handle, nil))
		it, err = kv.NextUntil(it, util.RowKeyPrefixFilter(rk))
		if err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
示例#5
0
文件: index.go 项目: youprofit/tidb
func (d *ddl) backfillTableIndex(t table.Table, indexInfo *model.IndexInfo, handles []int64, reorgInfo *reorgInfo) error {
	kvX := kv.NewKVIndex(t.IndexPrefix(), indexInfo.Name.L, indexInfo.ID, indexInfo.Unique)

	for _, handle := range handles {
		log.Debug("[ddl] building index...", handle)

		err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
			if err := d.isReorgRunnable(txn); err != nil {
				return errors.Trace(err)
			}

			// first check row exists
			exist, err := checkRowExist(txn, t, handle)
			if err != nil {
				return errors.Trace(err)
			} else if !exist {
				// row doesn't exist, skip it.
				return nil
			}

			var vals []interface{}
			vals, err = fetchRowColVals(txn, t, handle, indexInfo)
			if err != nil {
				return errors.Trace(err)
			}

			exist, _, err = kvX.Exist(txn, vals, handle)
			if err != nil {
				return errors.Trace(err)
			} else if exist {
				// index already exists, skip it.
				return nil
			}

			err = lockRow(txn, t, handle)
			if err != nil {
				return errors.Trace(err)
			}

			// create the index.
			err = kvX.Create(txn, vals, handle)
			if err != nil {
				return errors.Trace(err)
			}

			// update reorg next handle
			return errors.Trace(reorgInfo.UpdateHandle(txn, handle))
		})

		if err != nil {
			return errors.Trace(err)
		}
	}

	return nil
}
示例#6
0
func (s *testIndexSuite) TestCombineIndexSeek(c *C) {
	index := kv.NewKVIndex([]byte("i"), "test", 1, false)

	txn, err := s.s.Begin()
	c.Assert(err, IsNil)

	values := types.MakeDatums("abc", "def")
	err = index.Create(txn, values, 1)
	c.Assert(err, IsNil)

	index2 := kv.NewKVIndex([]byte("i"), "test", 1, false)
	iter, hit, err := index2.Seek(txn, types.MakeDatums("abc", nil))
	c.Assert(err, IsNil)
	defer iter.Close()
	c.Assert(hit, IsFalse)
	_, h, err := iter.Next()
	c.Assert(err, IsNil)
	c.Assert(h, Equals, int64(1))
}
示例#7
0
func (p *testIndexSuit) SetUpSuite(c *C) {
	store, err := tidb.NewStore(tidb.EngineGoLevelDBMemory)
	c.Assert(err, IsNil)
	p.store = store
	p.vars = map[string]interface{}{}
	p.txn, _ = p.store.Begin()
	p.cols = []*column.Col{
		{
			ColumnInfo: model.ColumnInfo{
				ID:           0,
				Name:         model.NewCIStr("id"),
				Offset:       0,
				DefaultValue: 0,
				FieldType:    *types.NewFieldType(mysql.TypeLonglong),
			},
		},
		{
			ColumnInfo: model.ColumnInfo{
				ID:           1,
				Name:         model.NewCIStr("name"),
				Offset:       1,
				DefaultValue: nil,
				FieldType:    *types.NewFieldType(mysql.TypeVarchar),
			},
		},
	}
	p.tbl = tables.NewTable(2, "t2", "test", p.cols, &simpleAllocator{})

	idxCol := &column.IndexedCol{
		IndexInfo: model.IndexInfo{
			Name:  model.NewCIStr("id"),
			Table: model.NewCIStr("t2"),
			Columns: []*model.IndexColumn{
				{
					Name:   model.NewCIStr("id"),
					Offset: 0,
					Length: 0,
				},
			},
			Unique:  false,
			Primary: false,
		},
		X: kv.NewKVIndex("i", "id", false),
	}
	p.tbl.AddIndex(idxCol)

	variable.BindSessionVars(p)

	var i int64
	for i = 0; i < 10; i++ {
		p.tbl.AddRecord(p, []interface{}{i * 10, "hello"})
	}
}
示例#8
0
func (p *testIndexSuit) SetUpSuite(c *C) {
	store, err := tidb.NewStore(tidb.EngineGoLevelDBMemory)
	c.Assert(err, IsNil)
	p.store = store
	se, _ := tidb.CreateSession(store)
	p.ctx = se.(context.Context)
	p.cols = []*column.Col{
		{
			ColumnInfo: model.ColumnInfo{
				ID:           0,
				Name:         model.NewCIStr("id"),
				Offset:       0,
				DefaultValue: 0,
				FieldType:    *types.NewFieldType(mysql.TypeLonglong),
				State:        model.StatePublic,
			},
		},
		{
			ColumnInfo: model.ColumnInfo{
				ID:           1,
				Name:         model.NewCIStr("name"),
				Offset:       1,
				DefaultValue: nil,
				FieldType:    *types.NewFieldType(mysql.TypeVarchar),
				State:        model.StatePublic,
			},
		},
	}
	p.tbl = tables.NewTable(2, "t2", p.cols, &simpleAllocator{})

	idxCol := &column.IndexedCol{
		IndexInfo: model.IndexInfo{
			Name:  model.NewCIStr("id"),
			Table: model.NewCIStr("t2"),
			Columns: []*model.IndexColumn{
				{
					Name:   model.NewCIStr("id"),
					Offset: 0,
					Length: 0,
				},
			},
			Unique:  false,
			Primary: false,
			State:   model.StatePublic,
		},
		X: kv.NewKVIndex("i", "id", 0, false),
	}
	p.tbl.AddIndex(idxCol)
	var i int64
	for i = 0; i < 10; i++ {
		p.tbl.AddRecord(p.ctx, []interface{}{i * 10, "hello"}, 0)
	}
}
示例#9
0
// TableFromMeta creates a Table instance from model.TableInfo.
func TableFromMeta(dbname string, alloc autoid.Allocator, tblInfo *model.TableInfo) table.Table {
	t := NewTable(tblInfo.ID, tblInfo.Name.O, dbname, nil, alloc)

	for _, colInfo := range tblInfo.Columns {
		c := column.Col{ColumnInfo: *colInfo}
		t.Columns = append(t.Columns, &c)
	}

	for _, idxInfo := range tblInfo.Indices {
		idx := &column.IndexedCol{
			IndexInfo: *idxInfo,
			X:         kv.NewKVIndex(t.indexPrefix, idxInfo.Name.L, idxInfo.Unique),
		}
		t.AddIndex(idx)
	}

	return t
}
示例#10
0
func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	it, err := kvIndex.SeekFirst(txn)
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()

	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	for {
		vals1, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return errors.Trace(err)
		}

		vals2, err := t.RowWithCols(txn, h, cols)
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record := &RecordData{Handle: h, Values: vals1}
			err = errors.Errorf("index:%v != record:%v", record, nil)
		}
		if err != nil {
			return errors.Trace(err)
		}
		if !reflect.DeepEqual(vals1, vals2) {
			record1 := &RecordData{Handle: h, Values: vals1}
			record2 := &RecordData{Handle: h, Values: vals2}
			return errors.Errorf("index:%v != record:%v", record1, record2)
		}
	}

	return nil
}
示例#11
0
func (s *testIndexSuite) TestIndex(c *C) {
	index := kv.NewKVIndex([]byte("i"), "test", 0, false)

	// Test ununiq index.
	txn, err := s.s.Begin()
	c.Assert(err, IsNil)

	values := types.MakeDatums(1, 2)
	err = index.Create(txn, values, 1)
	c.Assert(err, IsNil)

	it, err := index.SeekFirst(txn)
	c.Assert(err, IsNil)

	getValues, h, err := it.Next()
	c.Assert(err, IsNil)
	c.Assert(getValues, HasLen, 2)
	c.Assert(getValues[0].GetInt64(), Equals, int64(1))
	c.Assert(getValues[1].GetInt64(), Equals, int64(2))
	c.Assert(h, Equals, int64(1))
	it.Close()

	exist, _, err := index.Exist(txn, values, 100)
	c.Assert(err, IsNil)
	c.Assert(exist, IsFalse)

	exist, _, err = index.Exist(txn, values, 1)
	c.Assert(err, IsNil)
	c.Assert(exist, IsTrue)

	err = index.Delete(txn, values, 1)
	c.Assert(err, IsNil)

	it, err = index.SeekFirst(txn)
	c.Assert(err, IsNil)

	_, _, err = it.Next()
	c.Assert(terror.ErrorEqual(err, io.EOF), IsTrue)
	it.Close()

	err = index.Create(txn, values, 0)
	c.Assert(err, IsNil)

	_, err = index.SeekFirst(txn)
	c.Assert(err, IsNil)

	_, hit, err := index.Seek(txn, values)
	c.Assert(err, IsNil)
	c.Assert(hit, IsTrue)

	err = index.Drop(txn)
	c.Assert(err, IsNil)

	it, hit, err = index.Seek(txn, values)
	c.Assert(err, IsNil)
	c.Assert(hit, IsFalse)

	_, _, err = it.Next()
	c.Assert(terror.ErrorEqual(err, io.EOF), IsTrue)
	it.Close()

	it, err = index.SeekFirst(txn)
	c.Assert(err, IsNil)

	_, _, err = it.Next()
	c.Assert(terror.ErrorEqual(err, io.EOF), IsTrue)
	it.Close()

	err = txn.Commit()
	c.Assert(err, IsNil)

	index = kv.NewKVIndex([]byte("j"), "test", 1, true)

	// Test uniq index.
	txn, err = s.s.Begin()
	c.Assert(err, IsNil)

	err = index.Create(txn, values, 1)
	c.Assert(err, IsNil)

	err = index.Create(txn, values, 2)
	c.Assert(err, NotNil)

	exist, h, err = index.Exist(txn, values, 1)
	c.Assert(err, IsNil)
	c.Assert(h, Equals, int64(1))
	c.Assert(exist, IsTrue)

	exist, h, err = index.Exist(txn, values, 2)
	c.Assert(err, NotNil)
	c.Assert(h, Equals, int64(1))
	c.Assert(exist, IsTrue)

	err = txn.Commit()
	c.Assert(err, IsNil)
}
示例#12
0
func (s *testDBSuite) testAddIndex(c *C) {
	done := make(chan struct{}, 1)

	num := 100
	// first add some rows
	for i := 0; i < num; i++ {
		s.mustExec(c, "insert into t1 values (?, ?, ?)", i, i, i)
	}

	go func() {
		s.mustExec(c, "create index c3_index on t1 (c3)")
		done <- struct{}{}
	}()

	deletedKeys := make(map[int]struct{})

	ticker := time.NewTicker(s.lease / 2)
	defer ticker.Stop()
LOOP:
	for {
		select {
		case <-done:
			break LOOP
		case <-ticker.C:
			step := 10
			// delete some rows, and add some data
			for i := num; i < num+step; i++ {
				n := rand.Intn(num)
				deletedKeys[n] = struct{}{}
				s.mustExec(c, "delete from t1 where c1 = ?", n)
				s.mustExec(c, "insert into t1 values (?, ?, ?)", i, i, i)
			}
			num += step
		}
	}

	// get exists keys
	keys := make([]int, 0, num)
	for i := 0; i < num; i++ {
		if _, ok := deletedKeys[i]; ok {
			continue
		}
		keys = append(keys, i)
	}

	// test index key
	for _, key := range keys {
		rows := s.mustQuery(c, "select c1 from t1 where c3 = ?", key)
		matchRows(c, rows, [][]interface{}{{key}})
	}

	// test delete key not in index
	for key := range deletedKeys {
		rows := s.mustQuery(c, "select c1 from t1 where c3 = ?", key)
		matchRows(c, rows, nil)
	}

	// test index range
	for i := 0; i < 100; i++ {
		index := rand.Intn(len(keys) - 3)
		rows := s.mustQuery(c, "select c1 from t1 where c3 >= ? limit 3", keys[index])
		matchRows(c, rows, [][]interface{}{{keys[index]}, {keys[index+1]}, {keys[index+2]}})
	}

	rows := s.mustQuery(c, "explain select c1 from t1 where c3 >= 100")

	ay := dumpRows(c, rows)
	c.Assert(strings.Contains(fmt.Sprintf("%v", ay), "c3_index"), IsTrue)

	// get all row handles
	ctx := s.s.(context.Context)
	t := s.testGetTable(c, "t1")
	handles := make(map[int64]struct{})
	err := t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
		handles[h] = struct{}{}
		return true, nil
	})
	c.Assert(err, IsNil)

	// check in index
	idx := kv.NewKVIndex(t.IndexPrefix(), "c3_index", false)
	txn, err := ctx.GetTxn(true)
	c.Assert(err, IsNil)
	defer ctx.FinishTxn(true)

	it, err := idx.SeekFirst(txn)
	c.Assert(err, IsNil)
	defer it.Close()

	for {
		_, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		}

		c.Assert(err, IsNil)
		_, ok := handles[h]
		c.Assert(ok, IsTrue)
		delete(handles, h)
	}

	c.Assert(handles, HasLen, 0)
}
示例#13
0
func (s *testDBSuite) testDropIndex(c *C) {
	done := make(chan struct{}, 1)

	s.mustExec(c, "delete from t1")

	num := 100
	//  add some rows
	for i := 0; i < num; i++ {
		s.mustExec(c, "insert into t1 values (?, ?, ?)", i, i, i)
	}

	go func() {
		s.mustExec(c, "drop index c3_index on t1")
		done <- struct{}{}
	}()

	ticker := time.NewTicker(s.lease / 2)
	defer ticker.Stop()
LOOP:
	for {
		select {
		case <-done:
			break LOOP
		case <-ticker.C:
			step := 10
			// delete some rows, and add some data
			for i := num; i < num+step; i++ {
				n := rand.Intn(num)
				s.mustExec(c, "update t1 set c2 = 1 where c1 = ?", n)
				s.mustExec(c, "insert into t1 values (?, ?, ?)", i, i, i)
			}
			num += step
		}
	}

	rows := s.mustQuery(c, "explain select c1 from t1 where c3 >= 0")

	ay := dumpRows(c, rows)
	c.Assert(strings.Contains(fmt.Sprintf("%v", ay), "c3_index"), IsFalse)

	// check in index, must no index in kv
	ctx := s.s.(context.Context)

	handles := make(map[int64]struct{})

	t := s.testGetTable(c, "t1")
	idx := kv.NewKVIndex(t.IndexPrefix(), "c3_index", false)
	txn, err := ctx.GetTxn(true)
	c.Assert(err, IsNil)
	defer ctx.FinishTxn(true)

	it, err := idx.SeekFirst(txn)
	c.Assert(err, IsNil)
	defer it.Close()

	for {
		_, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		}

		c.Assert(err, IsNil)
		handles[h] = struct{}{}
	}

	c.Assert(handles, HasLen, 0)
}
示例#14
0
func (s *testIndexSuite) TestIndex(c *C) {
	index := kv.NewKVIndex("i", "test", false)

	// Test ununiq index.
	txn, err := s.s.Begin()
	c.Assert(err, IsNil)

	values := []interface{}{1, 2}
	err = index.Create(txn, values, 1)
	c.Assert(err, IsNil)

	it, err := index.SeekFirst(txn)
	c.Assert(err, IsNil)

	getValues, h, err := it.Next()
	c.Assert(err, IsNil)
	c.Assert(getValues, HasLen, 2)
	c.Assert(getValues[0], Equals, int64(1))
	c.Assert(getValues[1], Equals, int64(2))
	c.Assert(h, Equals, int64(1))
	it.Close()

	exist, _, err := index.Exist(txn, values, 100)
	c.Assert(err, IsNil)
	c.Assert(exist, IsFalse)

	exist, _, err = index.Exist(txn, values, 1)
	c.Assert(err, IsNil)
	c.Assert(exist, IsTrue)

	err = index.Delete(txn, values, 1)
	c.Assert(err, IsNil)

	it, err = index.SeekFirst(txn)
	c.Assert(err, IsNil)

	_, _, err = it.Next()
	c.Assert(errors2.ErrorEqual(err, io.EOF), IsTrue)
	it.Close()

	err = index.Create(txn, values, 0)
	c.Assert(err, IsNil)

	_, err = index.SeekFirst(txn)
	c.Assert(err, IsNil)

	_, hit, err := index.Seek(txn, values)
	c.Assert(err, IsNil)
	c.Assert(hit, IsTrue)

	err = index.Drop(txn)
	c.Assert(err, IsNil)

	it, hit, err = index.Seek(txn, values)
	c.Assert(err, IsNil)
	c.Assert(hit, IsFalse)

	_, _, err = it.Next()
	c.Assert(errors2.ErrorEqual(err, io.EOF), IsTrue)
	it.Close()

	it, err = index.SeekFirst(txn)
	c.Assert(err, IsNil)

	_, _, err = it.Next()
	c.Assert(errors2.ErrorEqual(err, io.EOF), IsTrue)
	it.Close()

	err = txn.Commit()
	c.Assert(err, IsNil)

	index = kv.NewKVIndex("j", "test", true)

	// Test uniq index.
	txn, err = s.s.Begin()
	c.Assert(err, IsNil)

	err = index.Create(txn, values, 1)
	c.Assert(err, IsNil)

	err = index.Create(txn, values, 2)
	c.Assert(err, NotNil)

	exist, h, err = index.Exist(txn, values, 1)
	c.Assert(err, IsNil)
	c.Assert(h, Equals, int64(1))
	c.Assert(exist, IsTrue)

	exist, h, err = index.Exist(txn, values, 2)
	c.Assert(err, NotNil)
	c.Assert(h, Equals, int64(1))
	c.Assert(exist, IsTrue)

	err = txn.Commit()
	c.Assert(err, IsNil)
}
示例#15
0
func (p *testFromSuit) TestTableDefaultPlan(c *C) {
	pln := &plans.TableDefaultPlan{
		T: p.tbl,
		Fields: []*field.ResultField{
			field.ColToResultField(p.tbl.Cols()[0], "t"),
			field.ColToResultField(p.tbl.Cols()[1], "t"),
		},
	}

	ret := map[int64][]byte{}
	rset := rsets.Recordset{Ctx: p, Plan: pln}
	rset.Do(func(data []interface{}) (bool, error) {
		ret[data[0].(int64)] = data[1].([]byte)
		return true, nil
	})
	excepted := map[int64][]byte{}
	for i := 0; i < 10; i++ {
		excepted[int64(i*10)] = []byte("hello")
	}
	//c.Assert(reflect.DeepEqual(ret, excepted), Equals, true)
	c.Assert(ret, DeepEquals, excepted)

	// expr: id > 0
	expr := &expression.BinaryOperation{
		Op: opcode.GE,
		L: &expression.Ident{
			CIStr: model.NewCIStr("id"),
		},
		R: &expression.Value{
			Val: 5,
		},
	}
	_, filtered, err := pln.FilterForUpdateAndDelete(p, expr)
	c.Assert(err, IsNil)
	c.Assert(filtered, IsFalse)
	// with no index

	idxCol := &column.IndexedCol{
		IndexInfo: model.IndexInfo{
			Name:  model.NewCIStr("id"),
			Table: model.NewCIStr("t"),
			Columns: []*model.IndexColumn{
				{
					Name:   model.NewCIStr("id"),
					Offset: 0,
					Length: 0,
				},
			},
			Unique:  false,
			Primary: false,
			State:   model.StatePublic,
		},
	}

	idxCol.X = kv.NewKVIndex([]byte("i"), "id", 0, false)

	p.tbl.AddIndex(idxCol)

	expr4 := &expression.Ident{
		CIStr: model.NewCIStr("id"),
	}
	_, filtered, err = pln.FilterForUpdateAndDelete(p, expr4)
	c.Assert(err, IsNil)
	// with no index
	c.Assert(filtered, IsTrue)

	expr5 := &expression.IsNull{
		Expr: &expression.Ident{
			CIStr: model.NewCIStr("id"),
		},
		Not: true,
	}
	_, filtered, err = pln.FilterForUpdateAndDelete(p, expr5)
	c.Assert(err, IsNil)
	// with no index
	c.Assert(filtered, IsTrue)
}
示例#16
0
func (p *testFromSuit) TestTableDefaultPlan(c *C) {
	pln := &plans.TableDefaultPlan{
		T: p.tbl,
		Fields: []*field.ResultField{
			field.ColToResultField(p.cols[0], "t"),
			field.ColToResultField(p.cols[1], "t"),
		},
	}

	ret := map[int64]string{}
	pln.Do(p, func(id interface{}, data []interface{}) (bool, error) {
		ret[data[0].(int64)] = data[1].(string)
		return true, nil
	})
	excepted := map[int64]string{}
	for i := 0; i < 10; i++ {
		excepted[int64(i*10)] = "hello"
	}
	c.Assert(reflect.DeepEqual(ret, excepted), Equals, true)

	// expr: id > 0
	expr := &expressions.BinaryOperation{
		Op: opcode.GE,
		L: &expressions.Ident{
			CIStr: model.NewCIStr("id"),
		},
		R: &expressions.Value{
			Val: 5,
		},
	}
	_, filtered, err := pln.FilterForUpdateAndDelete(p, expr)
	c.Assert(err, IsNil)
	c.Assert(filtered, IsFalse)
	// with no index

	idxCol := &column.IndexedCol{
		IndexInfo: model.IndexInfo{
			Name:  model.NewCIStr("id"),
			Table: model.NewCIStr("t"),
			Columns: []*model.IndexColumn{
				{
					Name:   model.NewCIStr("id"),
					Offset: 0,
					Length: 0,
				},
			},
			Unique:  false,
			Primary: false,
		},
		X: kv.NewKVIndex("i", "id", false),
	}
	p.tbl.AddIndex(idxCol)

	expr4 := &expressions.Ident{
		CIStr: model.NewCIStr("id"),
	}
	_, filtered, err = pln.FilterForUpdateAndDelete(p, expr4)
	c.Assert(err, IsNil)
	// with no index
	c.Assert(filtered, IsTrue)

	expr5 := &expressions.IsNull{
		Expr: &expressions.Ident{
			CIStr: model.NewCIStr("id"),
		},
		Not: true,
	}
	_, filtered, err = pln.FilterForUpdateAndDelete(p, expr5)
	c.Assert(err, IsNil)
	// with no index
	c.Assert(filtered, IsTrue)
}
示例#17
0
func (s *testSuite) TestScan(c *C) {
	alloc := autoid.NewAllocator(s.store, s.dbInfo.ID)
	tb, err := tables.TableFromMeta(alloc, s.tbInfo)
	c.Assert(err, IsNil)
	indices := tb.Indices()
	_, err = tb.AddRecord(s.ctx, []interface{}{10, 11})
	c.Assert(err, IsNil)
	s.ctx.FinishTxn(false)

	record1 := &RecordData{Handle: int64(1), Values: []interface{}{int64(10), int64(11)}}
	record2 := &RecordData{Handle: int64(2), Values: []interface{}{int64(20), int64(21)}}
	ver, err := s.store.CurrentVersion()
	c.Assert(err, IsNil)
	records, _, err := ScanSnapshotTableRecord(s.store, ver, tb, int64(1), 1)
	c.Assert(err, IsNil)
	c.Assert(records, DeepEquals, []*RecordData{record1})

	_, err = tb.AddRecord(s.ctx, record2.Values)
	c.Assert(err, IsNil)
	s.ctx.FinishTxn(false)
	txn, err := s.store.Begin()
	c.Assert(err, IsNil)

	records, nextHandle, err := ScanTableRecord(txn, tb, int64(1), 1)
	c.Assert(err, IsNil)
	c.Assert(records, DeepEquals, []*RecordData{record1})
	records, nextHandle, err = ScanTableRecord(txn, tb, nextHandle, 1)
	c.Assert(err, IsNil)
	c.Assert(records, DeepEquals, []*RecordData{record2})
	startHandle := nextHandle
	records, nextHandle, err = ScanTableRecord(txn, tb, startHandle, 1)
	c.Assert(err, IsNil)
	c.Assert(records, IsNil)
	c.Assert(nextHandle, Equals, startHandle)

	idxRow1 := &RecordData{Handle: int64(1), Values: []interface{}{int64(10)}}
	idxRow2 := &RecordData{Handle: int64(2), Values: []interface{}{int64(20)}}
	kvIndex := kv.NewKVIndex(tb.IndexPrefix(), indices[0].Name.L, indices[0].ID, indices[0].Unique)
	idxRows, nextVals, err := ScanIndexData(txn, kvIndex, idxRow1.Values, 2)
	c.Assert(err, IsNil)
	c.Assert(idxRows, DeepEquals, []*RecordData{idxRow1, idxRow2})
	idxRows, nextVals, err = ScanIndexData(txn, kvIndex, idxRow1.Values, 1)
	c.Assert(err, IsNil)
	c.Assert(idxRows, DeepEquals, []*RecordData{idxRow1})
	idxRows, nextVals, err = ScanIndexData(txn, kvIndex, nextVals, 1)
	c.Assert(err, IsNil)
	c.Assert(idxRows, DeepEquals, []*RecordData{idxRow2})
	idxRows, nextVals, err = ScanIndexData(txn, kvIndex, nextVals, 1)
	c.Assert(idxRows, IsNil)
	c.Assert(nextVals, DeepEquals, []interface{}{nil})
	c.Assert(err, IsNil)

	s.testTableData(c, tb, []*RecordData{record1, record2})

	s.testIndex(c, tb, tb.Indices()[0])

	err = tb.RemoveRecord(s.ctx, 1, record1.Values)
	c.Assert(err, IsNil)
	err = tb.RemoveRecord(s.ctx, 2, record2.Values)
	c.Assert(err, IsNil)
}