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  }