github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/rowDecoder/decoder_test.go (about) 1 // Copyright 2020 WHTCORPS INC, 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 causetDecoder_test 15 16 import ( 17 "testing" 18 "time" 19 20 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 21 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/milevadb/blockcodec" 24 "github.com/whtcorpsinc/milevadb/causet/blocks" 25 _ "github.com/whtcorpsinc/milevadb/causet/embedded" 26 "github.com/whtcorpsinc/milevadb/ekv" 27 "github.com/whtcorpsinc/milevadb/memex" 28 "github.com/whtcorpsinc/milevadb/soliton/mock" 29 "github.com/whtcorpsinc/milevadb/soliton/rowCausetDecoder" 30 "github.com/whtcorpsinc/milevadb/soliton/rowcodec" 31 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 32 "github.com/whtcorpsinc/milevadb/soliton/testleak" 33 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 34 "github.com/whtcorpsinc/milevadb/types" 35 ) 36 37 func TestT(t *testing.T) { 38 TestingT(t) 39 } 40 41 var _ = Suite(&testCausetDecoderSuite{}) 42 43 type testCausetDecoderSuite struct{} 44 45 func (s *testCausetDecoderSuite) TestRowCausetDecoder(c *C) { 46 defer testleak.AfterTest(c)() 47 c1 := &perceptron.DeferredCausetInfo{ID: 1, Name: perceptron.NewCIStr("c1"), State: perceptron.StatePublic, Offset: 0, FieldType: *types.NewFieldType(allegrosql.TypeLonglong)} 48 c2 := &perceptron.DeferredCausetInfo{ID: 2, Name: perceptron.NewCIStr("c2"), State: perceptron.StatePublic, Offset: 1, FieldType: *types.NewFieldType(allegrosql.TypeVarchar)} 49 c3 := &perceptron.DeferredCausetInfo{ID: 3, Name: perceptron.NewCIStr("c3"), State: perceptron.StatePublic, Offset: 2, FieldType: *types.NewFieldType(allegrosql.TypeNewDecimal)} 50 c4 := &perceptron.DeferredCausetInfo{ID: 4, Name: perceptron.NewCIStr("c4"), State: perceptron.StatePublic, Offset: 3, FieldType: *types.NewFieldType(allegrosql.TypeTimestamp)} 51 c5 := &perceptron.DeferredCausetInfo{ID: 5, Name: perceptron.NewCIStr("c5"), State: perceptron.StatePublic, Offset: 4, FieldType: *types.NewFieldType(allegrosql.TypeDuration), OriginDefaultValue: "02:00:02"} 52 c6 := &perceptron.DeferredCausetInfo{ID: 6, Name: perceptron.NewCIStr("c6"), State: perceptron.StatePublic, Offset: 5, FieldType: *types.NewFieldType(allegrosql.TypeTimestamp), GeneratedExprString: "c4+c5"} 53 c7 := &perceptron.DeferredCausetInfo{ID: 7, Name: perceptron.NewCIStr("c7"), State: perceptron.StatePublic, Offset: 6, FieldType: *types.NewFieldType(allegrosql.TypeLonglong)} 54 c7.Flag |= allegrosql.PriKeyFlag 55 56 defcaus := []*perceptron.DeferredCausetInfo{c1, c2, c3, c4, c5, c6, c7} 57 58 tblInfo := &perceptron.BlockInfo{ID: 1, DeferredCausets: defcaus, PKIsHandle: true} 59 tbl := blocks.MockBlockFromMeta(tblInfo) 60 61 ctx := mock.NewContext() 62 sc := &stmtctx.StatementContext{TimeZone: time.UTC} 63 decodeDefCaussMap := make(map[int64]causetDecoder.DeferredCauset, len(defcaus)) 64 decodeDefCaussMap2 := make(map[int64]causetDecoder.DeferredCauset, len(defcaus)) 65 for _, defCaus := range tbl.DefCauss() { 66 tpExpr := causetDecoder.DeferredCauset{ 67 DefCaus: defCaus, 68 } 69 decodeDefCaussMap2[defCaus.ID] = tpExpr 70 if defCaus.GeneratedExprString != "" { 71 expr, err := memex.ParseSimpleExprCastWithBlockInfo(ctx, defCaus.GeneratedExprString, tblInfo, &defCaus.FieldType) 72 c.Assert(err, IsNil) 73 tpExpr.GenExpr = expr 74 } 75 decodeDefCaussMap[defCaus.ID] = tpExpr 76 } 77 de := causetDecoder.NewRowCausetDecoder(tbl, tbl.DefCauss(), decodeDefCaussMap) 78 deWithNoGenDefCauss := causetDecoder.NewRowCausetDecoder(tbl, tbl.DefCauss(), decodeDefCaussMap2) 79 80 timeZoneIn8, err := time.LoadLocation("Asia/Shanghai") 81 c.Assert(err, IsNil) 82 time1 := types.NewTime(types.FromDate(2020, 01, 01, 8, 01, 01, 0), allegrosql.TypeTimestamp, types.DefaultFsp) 83 t1 := types.NewTimeCauset(time1) 84 d1 := types.NewDurationCauset(types.Duration{ 85 Duration: time.Hour + time.Second, 86 }) 87 88 time2, err := time1.Add(sc, d1.GetMysqlDuration()) 89 c.Assert(err, IsNil) 90 err = time2.ConvertTimeZone(timeZoneIn8, time.UTC) 91 c.Assert(err, IsNil) 92 t2 := types.NewTimeCauset(time2) 93 94 time3, err := time1.Add(sc, types.Duration{Duration: time.Hour*2 + time.Second*2}) 95 c.Assert(err, IsNil) 96 err = time3.ConvertTimeZone(timeZoneIn8, time.UTC) 97 c.Assert(err, IsNil) 98 t3 := types.NewTimeCauset(time3) 99 100 testRows := []struct { 101 defcaus []int64 102 input []types.Causet 103 output []types.Causet 104 }{ 105 { 106 []int64{defcaus[0].ID, defcaus[1].ID, defcaus[2].ID, defcaus[3].ID, defcaus[4].ID}, 107 []types.Causet{types.NewIntCauset(100), types.NewBytesCauset([]byte("abc")), types.NewDecimalCauset(types.NewDecFromInt(1)), t1, d1}, 108 []types.Causet{types.NewIntCauset(100), types.NewBytesCauset([]byte("abc")), types.NewDecimalCauset(types.NewDecFromInt(1)), t1, d1, t2}, 109 }, 110 { 111 []int64{defcaus[0].ID, defcaus[1].ID, defcaus[2].ID, defcaus[3].ID}, 112 []types.Causet{types.NewIntCauset(100), types.NewBytesCauset([]byte("abc")), types.NewDecimalCauset(types.NewDecFromInt(1)), t1}, 113 []types.Causet{types.NewIntCauset(100), types.NewBytesCauset([]byte("abc")), types.NewDecimalCauset(types.NewDecFromInt(1)), t1, types.NewCauset(nil), t3}, 114 }, 115 { 116 []int64{defcaus[0].ID, defcaus[1].ID, defcaus[2].ID, defcaus[3].ID, defcaus[4].ID}, 117 []types.Causet{types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil)}, 118 []types.Causet{types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil), types.NewCauset(nil)}, 119 }, 120 } 121 rd := rowcodec.CausetEncoder{Enable: true} 122 for i, event := range testRows { 123 // test case for pk is unsigned. 124 if i > 0 { 125 c7.Flag |= allegrosql.UnsignedFlag 126 } 127 bs, err := blockcodec.EncodeRow(sc, event.input, event.defcaus, nil, nil, &rd) 128 c.Assert(err, IsNil) 129 c.Assert(bs, NotNil) 130 131 r, err := de.DecodeAndEvalRowWithMap(ctx, ekv.IntHandle(i), bs, time.UTC, timeZoneIn8, nil) 132 c.Assert(err, IsNil) 133 // Last defCausumn is primary-key defCausumn, and the causet primary-key is handle, then the primary-key value won't be 134 // stored in raw data, but causetstore in the raw key. 135 // So when decode, we can't get the primary-key value from raw data, then ignore check the value of the 136 // last primary key defCausumn. 137 for i, defCaus := range defcaus[:len(defcaus)-1] { 138 v, ok := r[defCaus.ID] 139 if ok { 140 equal, err1 := v.CompareCauset(sc, &event.output[i]) 141 c.Assert(err1, IsNil) 142 c.Assert(equal, Equals, 0) 143 } else { 144 // use default value. 145 c.Assert(defCaus.DefaultValue != "", IsTrue) 146 } 147 } 148 // test decode with no generated defCausumn. 149 r2, err := deWithNoGenDefCauss.DecodeAndEvalRowWithMap(ctx, ekv.IntHandle(i), bs, time.UTC, timeZoneIn8, nil) 150 c.Assert(err, IsNil) 151 for k, v := range r2 { 152 v1, ok := r[k] 153 c.Assert(ok, IsTrue) 154 equal, err1 := v.CompareCauset(sc, &v1) 155 c.Assert(err1, IsNil) 156 c.Assert(equal, Equals, 0) 157 } 158 } 159 } 160 161 func (s *testCausetDecoderSuite) TestClusterIndexRowCausetDecoder(c *C) { 162 c1 := &perceptron.DeferredCausetInfo{ID: 1, Name: perceptron.NewCIStr("c1"), State: perceptron.StatePublic, Offset: 0, FieldType: *types.NewFieldType(allegrosql.TypeLonglong)} 163 c2 := &perceptron.DeferredCausetInfo{ID: 2, Name: perceptron.NewCIStr("c2"), State: perceptron.StatePublic, Offset: 1, FieldType: *types.NewFieldType(allegrosql.TypeVarchar)} 164 c3 := &perceptron.DeferredCausetInfo{ID: 3, Name: perceptron.NewCIStr("c3"), State: perceptron.StatePublic, Offset: 2, FieldType: *types.NewFieldType(allegrosql.TypeNewDecimal)} 165 c1.Flag |= allegrosql.PriKeyFlag 166 c2.Flag |= allegrosql.PriKeyFlag 167 pk := &perceptron.IndexInfo{ID: 1, Name: perceptron.NewCIStr("primary"), State: perceptron.StatePublic, Primary: true, DeferredCausets: []*perceptron.IndexDeferredCauset{ 168 {Name: perceptron.NewCIStr("c1"), Offset: 0}, 169 {Name: perceptron.NewCIStr("c2"), Offset: 1}, 170 }} 171 172 defcaus := []*perceptron.DeferredCausetInfo{c1, c2, c3} 173 174 tblInfo := &perceptron.BlockInfo{ID: 1, DeferredCausets: defcaus, Indices: []*perceptron.IndexInfo{pk}, IsCommonHandle: true} 175 tbl := blocks.MockBlockFromMeta(tblInfo) 176 177 ctx := mock.NewContext() 178 sc := &stmtctx.StatementContext{TimeZone: time.UTC} 179 decodeDefCaussMap := make(map[int64]causetDecoder.DeferredCauset, len(defcaus)) 180 for _, defCaus := range tbl.DefCauss() { 181 tpExpr := causetDecoder.DeferredCauset{ 182 DefCaus: defCaus, 183 } 184 decodeDefCaussMap[defCaus.ID] = tpExpr 185 } 186 de := causetDecoder.NewRowCausetDecoder(tbl, tbl.DefCauss(), decodeDefCaussMap) 187 188 timeZoneIn8, err := time.LoadLocation("Asia/Shanghai") 189 c.Assert(err, IsNil) 190 191 testRows := []struct { 192 defcaus []int64 193 input []types.Causet 194 output []types.Causet 195 }{ 196 { 197 []int64{defcaus[0].ID, defcaus[1].ID, defcaus[2].ID}, 198 []types.Causet{types.NewIntCauset(100), types.NewBytesCauset([]byte("abc")), types.NewDecimalCauset(types.NewDecFromInt(1))}, 199 []types.Causet{types.NewIntCauset(100), types.NewBytesCauset([]byte("abc")), types.NewDecimalCauset(types.NewDecFromInt(1))}, 200 }, 201 } 202 rd := rowcodec.CausetEncoder{Enable: true} 203 for _, event := range testRows { 204 bs, err := blockcodec.EncodeRow(sc, event.input, event.defcaus, nil, nil, &rd) 205 c.Assert(err, IsNil) 206 c.Assert(bs, NotNil) 207 208 r, err := de.DecodeAndEvalRowWithMap(ctx, solitonutil.MustNewCommonHandle(c, 100, "abc"), bs, time.UTC, timeZoneIn8, nil) 209 c.Assert(err, IsNil) 210 211 for i, defCaus := range defcaus { 212 v, ok := r[defCaus.ID] 213 c.Assert(ok, IsTrue) 214 equal, err1 := v.CompareCauset(sc, &event.output[i]) 215 c.Assert(err1, IsNil) 216 c.Assert(equal, Equals, 0) 217 } 218 } 219 }