github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/table/tables/tables_test.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package tables_test
    15  
    16  import (
    17  	"testing"
    18  
    19  	. "github.com/insionng/yougam/libraries/pingcap/check"
    20  	"github.com/insionng/yougam/libraries/pingcap/tidb"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/column"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/kv"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/store/localstore"
    28  	"github.com/insionng/yougam/libraries/pingcap/tidb/store/localstore/goleveldb"
    29  	"github.com/insionng/yougam/libraries/pingcap/tidb/table/tables"
    30  	"github.com/insionng/yougam/libraries/pingcap/tidb/util"
    31  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak"
    32  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/types"
    33  )
    34  
    35  func TestT(t *testing.T) {
    36  	TestingT(t)
    37  }
    38  
    39  var _ = Suite(&testSuite{})
    40  
    41  type testSuite struct {
    42  	store kv.Storage
    43  	se    tidb.Session
    44  }
    45  
    46  func (ts *testSuite) SetUpSuite(c *C) {
    47  	driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}}
    48  	store, err := driver.Open("memory")
    49  	c.Check(err, IsNil)
    50  	ts.store = store
    51  	ts.se, err = tidb.CreateSession(ts.store)
    52  	c.Assert(err, IsNil)
    53  }
    54  
    55  func (ts *testSuite) TestBasic(c *C) {
    56  	_, err := ts.se.Execute("CREATE TABLE test.t (a int primary key auto_increment, b varchar(255) unique)")
    57  	c.Assert(err, IsNil)
    58  	ctx := ts.se.(context.Context)
    59  	dom := sessionctx.GetDomain(ctx)
    60  	tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
    61  	c.Assert(err, IsNil)
    62  	c.Assert(tb.Meta().ID, Greater, int64(0))
    63  	c.Assert(tb.Meta().Name.L, Equals, "t")
    64  	c.Assert(tb.Meta(), NotNil)
    65  	c.Assert(tb.Indices(), NotNil)
    66  	c.Assert(string(tb.FirstKey()), Not(Equals), "")
    67  	c.Assert(string(tb.IndexPrefix()), Not(Equals), "")
    68  	c.Assert(string(tb.RecordPrefix()), Not(Equals), "")
    69  	c.Assert(tables.FindIndexByColName(tb, "b"), NotNil)
    70  
    71  	autoid, err := tb.AllocAutoID()
    72  	c.Assert(err, IsNil)
    73  	c.Assert(autoid, Greater, int64(0))
    74  
    75  	rid, err := tb.AddRecord(ctx, types.MakeDatums(1, "abc"))
    76  	c.Assert(err, IsNil)
    77  	c.Assert(rid, Greater, int64(0))
    78  	row, err := tb.Row(ctx, rid)
    79  	c.Assert(err, IsNil)
    80  	c.Assert(len(row), Equals, 2)
    81  	c.Assert(row[0].GetInt64(), Equals, int64(1))
    82  
    83  	_, err = tb.AddRecord(ctx, types.MakeDatums(1, "aba"))
    84  	c.Assert(err, NotNil)
    85  	_, err = tb.AddRecord(ctx, types.MakeDatums(2, "abc"))
    86  	c.Assert(err, NotNil)
    87  
    88  	c.Assert(tb.UpdateRecord(ctx, rid, types.MakeDatums(1, "abc"), types.MakeDatums(1, "cba"), map[int]bool{0: false, 1: true}), IsNil)
    89  
    90  	tb.IterRecords(ctx, tb.FirstKey(), tb.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) {
    91  		return true, nil
    92  	})
    93  
    94  	indexCnt := func() int {
    95  		cnt, err2 := countEntriesWithPrefix(ctx, tb.IndexPrefix())
    96  		c.Assert(err2, IsNil)
    97  		return cnt
    98  	}
    99  
   100  	// RowWithCols test
   101  	vals, err := tb.RowWithCols(ctx, 1, tb.Cols())
   102  	c.Assert(err, IsNil)
   103  	c.Assert(vals, HasLen, 2)
   104  	c.Assert(vals[0].GetInt64(), Equals, int64(1))
   105  	cols := []*column.Col{tb.Cols()[1]}
   106  	vals, err = tb.RowWithCols(ctx, 1, cols)
   107  	c.Assert(err, IsNil)
   108  	c.Assert(vals, HasLen, 1)
   109  	c.Assert(vals[0].GetBytes(), DeepEquals, []byte("cba"))
   110  
   111  	// Make sure there is index data in the storage.
   112  	c.Assert(indexCnt(), Greater, 0)
   113  	c.Assert(tb.RemoveRecord(ctx, rid, types.MakeDatums(1, "cba")), IsNil)
   114  	// Make sure index data is also removed after tb.RemoveRecord().
   115  	c.Assert(indexCnt(), Equals, 0)
   116  	_, err = tb.AddRecord(ctx, types.MakeDatums(1, "abc"))
   117  	c.Assert(err, IsNil)
   118  	c.Assert(indexCnt(), Greater, 0)
   119  	// Make sure index data is also removed after tb.Truncate().
   120  	c.Assert(tb.Truncate(ctx), IsNil)
   121  	c.Assert(indexCnt(), Equals, 0)
   122  
   123  	_, err = ts.se.Execute("drop table test.t")
   124  	c.Assert(err, IsNil)
   125  }
   126  
   127  func countEntriesWithPrefix(ctx context.Context, prefix []byte) (int, error) {
   128  	txn, err := ctx.GetTxn(false)
   129  	if err != nil {
   130  		return 0, err
   131  	}
   132  	cnt := 0
   133  	err = util.ScanMetaWithPrefix(txn, prefix, func(k kv.Key, v []byte) bool {
   134  		cnt++
   135  		return true
   136  	})
   137  	return cnt, err
   138  }
   139  
   140  func (ts *testSuite) TestTypes(c *C) {
   141  	_, err := ts.se.Execute("CREATE TABLE test.t (c1 tinyint, c2 smallint, c3 int, c4 bigint, c5 text, c6 blob, c7 varchar(64), c8 time, c9 timestamp not null default CURRENT_TIMESTAMP, c10 decimal)")
   142  	c.Assert(err, IsNil)
   143  	ctx := ts.se.(context.Context)
   144  	dom := sessionctx.GetDomain(ctx)
   145  	_, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
   146  	c.Assert(err, IsNil)
   147  	_, err = ts.se.Execute("insert test.t values (1, 2, 3, 4, '5', '6', '7', '10:10:10', null, 1.4)")
   148  	c.Assert(err, IsNil)
   149  	rs, err := ts.se.Execute("select * from test.t where c1 = 1")
   150  	c.Assert(err, IsNil)
   151  	row, err := rs[0].Next()
   152  	c.Assert(err, IsNil)
   153  	c.Assert(row.Data, NotNil)
   154  	_, err = ts.se.Execute("drop table test.t")
   155  	c.Assert(err, IsNil)
   156  
   157  	_, err = ts.se.Execute("CREATE TABLE test.t (c1 tinyint unsigned, c2 smallint unsigned, c3 int unsigned, c4 bigint unsigned, c5 double, c6 bit(8))")
   158  	c.Assert(err, IsNil)
   159  	_, err = ts.se.Execute("insert test.t values (1, 2, 3, 4, 5, 6)")
   160  	c.Assert(err, IsNil)
   161  	rs, err = ts.se.Execute("select * from test.t where c1 = 1")
   162  	c.Assert(err, IsNil)
   163  	row, err = rs[0].Next()
   164  	c.Assert(err, IsNil)
   165  	c.Assert(row.Data, NotNil)
   166  	c.Assert(row.Data[5].GetMysqlBit(), Equals, mysql.Bit{Value: 6, Width: 8})
   167  	_, err = ts.se.Execute("drop table test.t")
   168  	c.Assert(err, IsNil)
   169  
   170  	_, err = ts.se.Execute("CREATE TABLE test.t (c1 enum('a', 'b', 'c'))")
   171  	c.Assert(err, IsNil)
   172  	_, err = ts.se.Execute("insert test.t values ('a'), (2), ('c')")
   173  	c.Assert(err, IsNil)
   174  	rs, err = ts.se.Execute("select c1 + 1 from test.t where c1 = 1")
   175  	c.Assert(err, IsNil)
   176  	row, err = rs[0].Next()
   177  	c.Assert(err, IsNil)
   178  	c.Assert(row.Data, NotNil)
   179  	c.Assert(row.Data[0].GetFloat64(), DeepEquals, float64(2))
   180  	_, err = ts.se.Execute("drop table test.t")
   181  	c.Assert(err, IsNil)
   182  }
   183  
   184  func (ts *testSuite) TestUniqueIndexMultipleNullEntries(c *C) {
   185  	_, err := ts.se.Execute("CREATE TABLE test.t (a int primary key auto_increment, b varchar(255) unique)")
   186  	c.Assert(err, IsNil)
   187  	ctx := ts.se.(context.Context)
   188  	dom := sessionctx.GetDomain(ctx)
   189  	tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
   190  	c.Assert(err, IsNil)
   191  	c.Assert(tb.Meta().ID, Greater, int64(0))
   192  	c.Assert(tb.Meta().Name.L, Equals, "t")
   193  	c.Assert(tb.Meta(), NotNil)
   194  	c.Assert(tb.Indices(), NotNil)
   195  	c.Assert(string(tb.FirstKey()), Not(Equals), "")
   196  	c.Assert(string(tb.IndexPrefix()), Not(Equals), "")
   197  	c.Assert(string(tb.RecordPrefix()), Not(Equals), "")
   198  	c.Assert(tables.FindIndexByColName(tb, "b"), NotNil)
   199  
   200  	autoid, err := tb.AllocAutoID()
   201  	c.Assert(err, IsNil)
   202  	c.Assert(autoid, Greater, int64(0))
   203  
   204  	_, err = tb.AddRecord(ctx, types.MakeDatums(1, nil))
   205  	c.Assert(err, IsNil)
   206  	_, err = tb.AddRecord(ctx, types.MakeDatums(2, nil))
   207  	c.Assert(err, IsNil)
   208  	_, err = ts.se.Execute("drop table test.t")
   209  	c.Assert(err, IsNil)
   210  }
   211  
   212  func (ts *testSuite) TestRowKeyCodec(c *C) {
   213  	table := []struct {
   214  		tableID int64
   215  		h       int64
   216  		ID      int64
   217  	}{
   218  		{1, 1234567890, 0},
   219  		{2, 1, 0},
   220  		{3, -1, 0},
   221  		{4, -1, 1},
   222  	}
   223  
   224  	for _, t := range table {
   225  		b := tables.EncodeRecordKey(t.tableID, t.h, t.ID)
   226  		tableID, handle, columnID, err := tables.DecodeRecordKey(b)
   227  		c.Assert(err, IsNil)
   228  		c.Assert(tableID, Equals, t.tableID)
   229  		c.Assert(handle, Equals, t.h)
   230  		c.Assert(columnID, Equals, t.ID)
   231  
   232  		handle, err = tables.DecodeRecordKeyHandle(b)
   233  		c.Assert(err, IsNil)
   234  		c.Assert(handle, Equals, t.h)
   235  	}
   236  
   237  	// test error
   238  	tbl := []string{
   239  		"",
   240  		"x",
   241  		"t1",
   242  		"t12345678",
   243  		"t12345678_i",
   244  		"t12345678_r1",
   245  		"t12345678_r1234567",
   246  		"t12345678_r123456781",
   247  	}
   248  
   249  	for _, t := range tbl {
   250  		_, err := tables.DecodeRecordKeyHandle(kv.Key(t))
   251  		c.Assert(err, NotNil)
   252  	}
   253  }
   254  
   255  func (ts *testSuite) TestUnsignedPK(c *C) {
   256  	defer testleak.AfterTest(c)()
   257  	_, err := ts.se.Execute("CREATE TABLE test.tPK (a bigint unsigned primary key, b varchar(255))")
   258  	c.Assert(err, IsNil)
   259  	ctx := ts.se.(context.Context)
   260  	dom := sessionctx.GetDomain(ctx)
   261  	tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("tPK"))
   262  	c.Assert(err, IsNil)
   263  
   264  	rid, err := tb.AddRecord(ctx, types.MakeDatums(1, "abc"))
   265  	c.Assert(err, IsNil)
   266  	row, err := tb.Row(ctx, rid)
   267  	c.Assert(err, IsNil)
   268  	c.Assert(len(row), Equals, 2)
   269  	c.Assert(row[0].Kind(), Equals, types.KindUint64)
   270  }