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 }