github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/compile/scopeRemoteRun_test.go (about)

     1  // Copyright 2023 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package compile
    16  
    17  import (
    18  	"context"
    19  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/aggexec"
    20  	"github.com/matrixorigin/matrixone/pkg/testutil"
    21  	"hash/crc32"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/matrixorigin/matrixone/pkg/catalog"
    26  	"github.com/matrixorigin/matrixone/pkg/defines"
    27  
    28  	"github.com/matrixorigin/matrixone/pkg/common/reuse"
    29  
    30  	"github.com/golang/mock/gomock"
    31  	"github.com/google/uuid"
    32  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/source"
    33  	"github.com/stretchr/testify/require"
    34  
    35  	"github.com/matrixorigin/matrixone/pkg/common/morpc"
    36  	"github.com/matrixorigin/matrixone/pkg/common/morpc/mock_morpc"
    37  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    38  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    39  	"github.com/matrixorigin/matrixone/pkg/container/types"
    40  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    41  	mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test"
    42  	"github.com/matrixorigin/matrixone/pkg/pb/pipeline"
    43  	plan2 "github.com/matrixorigin/matrixone/pkg/pb/plan"
    44  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/anti"
    45  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/connector"
    46  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/deletion"
    47  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/dispatch"
    48  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/external"
    49  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/group"
    50  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/hashbuild"
    51  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/insert"
    52  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/intersect"
    53  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/intersectall"
    54  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/join"
    55  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/left"
    56  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/limit"
    57  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/lockop"
    58  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/loopanti"
    59  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/loopjoin"
    60  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/loopleft"
    61  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/loopmark"
    62  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/loopsemi"
    63  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/loopsingle"
    64  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mark"
    65  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/merge"
    66  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mergegroup"
    67  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mergelimit"
    68  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mergeoffset"
    69  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mergeorder"
    70  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mergerecursive"
    71  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/mergetop"
    72  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/minus"
    73  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/offset"
    74  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/onduplicatekey"
    75  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/order"
    76  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/preinsert"
    77  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/preinsertunique"
    78  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/product"
    79  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/projection"
    80  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/restrict"
    81  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/right"
    82  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/rightanti"
    83  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/rightsemi"
    84  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/semi"
    85  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/shuffle"
    86  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/single"
    87  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/table_function"
    88  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/top"
    89  	"github.com/matrixorigin/matrixone/pkg/sql/plan"
    90  	"github.com/matrixorigin/matrixone/pkg/vm"
    91  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    92  )
    93  
    94  func Test_receiveMessageFromCnServer(t *testing.T) {
    95  	ctrl := gomock.NewController(t)
    96  	ctx := context.TODO()
    97  
    98  	streamSender := mock_morpc.NewMockStream(ctrl)
    99  	ch := make(chan morpc.Message)
   100  	streamSender.EXPECT().Receive().Return(ch, nil)
   101  	aggexec.RegisterGroupConcatAgg(0, ",")
   102  	agg0 := aggexec.MakeAgg(
   103  		testutil.NewProcess(), 0, false, []types.Type{types.T_varchar.ToType()}...)
   104  
   105  	bat := &batch.Batch{
   106  		Recursive:  0,
   107  		Ro:         false,
   108  		ShuffleIDX: 0,
   109  		Cnt:        1,
   110  		Attrs:      []string{"1"},
   111  		Vecs:       []*vector.Vector{vector.NewVec(types.T_int64.ToType())},
   112  		Aggs:       []aggexec.AggFuncExec{agg0},
   113  		AuxData:    nil,
   114  	}
   115  	bat.SetRowCount(1)
   116  	data, err := types.Encode(bat)
   117  	require.Nil(t, err)
   118  
   119  	go func() {
   120  		msg := &pipeline.Message{
   121  			Data: data,
   122  		}
   123  		msg.Checksum = crc32.ChecksumIEEE(data)
   124  		ch <- msg
   125  	}()
   126  
   127  	vp := process.New(
   128  		ctx,
   129  		nil,
   130  		nil,
   131  		nil,
   132  		nil,
   133  		nil,
   134  		nil,
   135  		nil,
   136  		nil,
   137  		nil)
   138  	vp.AnalInfos = []*process.AnalyzeInfo{}
   139  	vp.Reg = process.Register{}
   140  	c := reuse.Alloc[Compile](nil)
   141  	c.proc = vp
   142  	s := reuse.Alloc[Scope](nil)
   143  	s.Proc = vp
   144  	sender := &messageSenderOnClient{
   145  		ctx:          ctx,
   146  		streamSender: streamSender,
   147  		c:            c,
   148  	}
   149  	ch2 := make(chan *batch.Batch)
   150  	ctx2, cancel := context.WithTimeout(context.Background(), time.Second)
   151  	defer cancel()
   152  	lastInstruction := vm.Instruction{
   153  		Arg: &connector.Argument{
   154  			Reg: &process.WaitRegister{
   155  				Ctx: ctx2,
   156  				Ch:  ch2,
   157  			},
   158  		},
   159  	}
   160  	err = receiveMessageFromCnServer(c, s, sender, lastInstruction)
   161  	require.Nil(t, err)
   162  }
   163  
   164  func Test_EncodeProcessInfo(t *testing.T) {
   165  	ctrl := gomock.NewController(t)
   166  	txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
   167  	txnOperator.EXPECT().Snapshot().Return(([]byte)("test"), nil)
   168  
   169  	a := reuse.Alloc[process.AnalyzeInfo](nil)
   170  	proc := &process.Process{
   171  		Id:          "1",
   172  		Lim:         process.Limitation{},
   173  		UnixTime:    1000000,
   174  		Ctx:         defines.AttachAccountId(context.TODO(), catalog.System_Account),
   175  		TxnOperator: txnOperator,
   176  		AnalInfos:   []*process.AnalyzeInfo{a},
   177  		SessionInfo: process.SessionInfo{
   178  			Account:        "",
   179  			User:           "",
   180  			Host:           "",
   181  			Role:           "",
   182  			ConnectionID:   0,
   183  			AccountId:      0,
   184  			RoleId:         0,
   185  			UserId:         0,
   186  			LastInsertID:   0,
   187  			Database:       "",
   188  			Version:        "",
   189  			TimeZone:       time.Local,
   190  			StorageEngine:  nil,
   191  			QueryId:        nil,
   192  			ResultColTypes: nil,
   193  			SeqCurValues:   nil,
   194  			SeqDeleteKeys:  nil,
   195  			SeqAddValues:   nil,
   196  			SeqLastValue:   nil,
   197  			SqlHelper:      nil,
   198  		},
   199  	}
   200  	_, err := encodeProcessInfo(proc, "")
   201  	require.Nil(t, err)
   202  }
   203  
   204  func Test_refactorScope(t *testing.T) {
   205  	ctx := context.TODO()
   206  	proc := &process.Process{}
   207  
   208  	s := reuse.Alloc[Scope](nil)
   209  	s.Proc = proc
   210  	c := reuse.Alloc[Compile](nil)
   211  	c.anal = newAnaylze()
   212  	c.ctx = ctx
   213  	c.proc = proc
   214  	rs := appendWriteBackOperator(c, s)
   215  	require.Equal(t, rs.Instructions[1].Idx, -1)
   216  }
   217  
   218  func Test_convertPipelineUuid(t *testing.T) {
   219  	id, _ := uuid.NewV7()
   220  	p := &pipeline.Pipeline{
   221  		UuidsToRegIdx: []*pipeline.UuidToRegIdx{
   222  			{Idx: 1, Uuid: id[:]},
   223  		},
   224  	}
   225  	s := reuse.Alloc[Scope](nil)
   226  	s.RemoteReceivRegInfos = make([]RemoteReceivRegInfo, 0)
   227  	err := convertPipelineUuid(p, s)
   228  	require.Nil(t, err)
   229  }
   230  
   231  func Test_convertScopeRemoteReceivInfo(t *testing.T) {
   232  	id, _ := uuid.NewV7()
   233  	s := reuse.Alloc[Scope](nil)
   234  	s.RemoteReceivRegInfos = []RemoteReceivRegInfo{
   235  		{Idx: 1, Uuid: id},
   236  	}
   237  	ret := convertScopeRemoteReceivInfo(s)
   238  	require.Equal(t, ret[0].Idx, int32(1))
   239  }
   240  
   241  func Test_convertToPipelineInstruction(t *testing.T) {
   242  	exParam := external.ExParam{
   243  		Filter: &external.FilterParam{},
   244  	}
   245  	instructions := []*vm.Instruction{
   246  		{
   247  			Arg: &insert.Argument{
   248  				InsertCtx: &insert.InsertCtx{},
   249  			},
   250  		},
   251  		{
   252  			Arg: &deletion.Argument{
   253  				DeleteCtx: &deletion.DeleteCtx{},
   254  			},
   255  		},
   256  		{
   257  			Arg: &onduplicatekey.Argument{},
   258  		},
   259  		{
   260  			Arg: &preinsert.Argument{},
   261  		},
   262  		{
   263  			Arg: &lockop.Argument{},
   264  		},
   265  		{
   266  			Arg: &preinsertunique.Argument{},
   267  		},
   268  		{
   269  			Arg: &anti.Argument{
   270  				Conditions: [][]*plan.Expr{nil, nil},
   271  			},
   272  		},
   273  		{
   274  			Arg: &shuffle.Argument{},
   275  		},
   276  		{
   277  			Arg: &dispatch.Argument{},
   278  		},
   279  		{
   280  			Arg: &group.Argument{},
   281  		},
   282  		{
   283  			Arg: &join.Argument{
   284  				Conditions: [][]*plan.Expr{nil, nil},
   285  			},
   286  		},
   287  		{
   288  			Arg: &left.Argument{
   289  				Conditions: [][]*plan.Expr{nil, nil},
   290  			},
   291  		},
   292  		{
   293  			Arg: &right.Argument{
   294  				Conditions: [][]*plan.Expr{nil, nil},
   295  			},
   296  		},
   297  		{
   298  			Arg: &rightsemi.Argument{
   299  				Conditions: [][]*plan.Expr{nil, nil},
   300  			},
   301  		},
   302  		{
   303  			Arg: &rightanti.Argument{
   304  				Conditions: [][]*plan.Expr{nil, nil},
   305  			},
   306  		},
   307  		{
   308  			Arg: &limit.Argument{},
   309  		},
   310  		{
   311  			Arg: &loopanti.Argument{},
   312  		},
   313  		{
   314  			Arg: &loopjoin.Argument{},
   315  		},
   316  		{
   317  			Arg: &loopleft.Argument{},
   318  		},
   319  		{
   320  			Arg: &loopsemi.Argument{},
   321  		},
   322  		{
   323  			Arg: &loopsingle.Argument{},
   324  		},
   325  		{
   326  			Arg: &loopmark.Argument{},
   327  		},
   328  		{
   329  			Arg: &offset.Argument{},
   330  		},
   331  		{
   332  			Arg: &order.Argument{},
   333  		},
   334  		{
   335  			Arg: &product.Argument{},
   336  		},
   337  		{
   338  			Arg: &projection.Argument{},
   339  		},
   340  		{
   341  			Arg: &restrict.Argument{},
   342  		},
   343  		{
   344  			Arg: &semi.Argument{
   345  				Conditions: [][]*plan.Expr{nil, nil},
   346  			},
   347  		},
   348  		{
   349  			Arg: &single.Argument{
   350  				Conditions: [][]*plan.Expr{nil, nil},
   351  			},
   352  		},
   353  		{
   354  			Arg: &top.Argument{},
   355  		},
   356  		{
   357  			Arg: &intersect.Argument{},
   358  		},
   359  		{
   360  			Arg: &minus.Argument{},
   361  		},
   362  		{
   363  			Arg: &intersectall.Argument{},
   364  		},
   365  		{
   366  			Arg: &merge.Argument{},
   367  		},
   368  		{
   369  			Arg: &mergerecursive.Argument{},
   370  		},
   371  		{
   372  			Arg: &mergegroup.Argument{},
   373  		},
   374  		{
   375  			Arg: &mergelimit.Argument{},
   376  		},
   377  		{
   378  			Arg: &mergeoffset.Argument{},
   379  		},
   380  		{
   381  			Arg: &mergetop.Argument{},
   382  		},
   383  		{
   384  			Arg: &mergeorder.Argument{},
   385  		},
   386  		//{
   387  		//	Arg: &connector.Argument{},
   388  		//},
   389  		{
   390  			Arg: &mark.Argument{
   391  				Conditions: [][]*plan.Expr{nil, nil},
   392  			},
   393  		},
   394  		{
   395  			Arg: &table_function.Argument{},
   396  		},
   397  		{
   398  			Arg: &hashbuild.Argument{},
   399  		},
   400  		{
   401  			Arg: &external.Argument{
   402  				Es: &external.ExternalParam{
   403  					ExParam: exParam,
   404  				},
   405  			},
   406  		},
   407  		{
   408  			Arg: &source.Argument{},
   409  		},
   410  	}
   411  	ctx := &scopeContext{
   412  		id:       1,
   413  		plan:     nil,
   414  		scope:    nil,
   415  		root:     &scopeContext{},
   416  		parent:   &scopeContext{},
   417  		children: nil,
   418  		pipe:     nil,
   419  		regs:     nil,
   420  	}
   421  	for _, instruction := range instructions {
   422  		_, _, err := convertToPipelineInstruction(instruction, ctx, 1)
   423  		require.Nil(t, err)
   424  	}
   425  }
   426  
   427  func Test_convertToVmInstruction(t *testing.T) {
   428  	ctx := &scopeContext{
   429  		id:       1,
   430  		plan:     nil,
   431  		scope:    nil,
   432  		root:     &scopeContext{},
   433  		parent:   &scopeContext{},
   434  		children: nil,
   435  		pipe:     nil,
   436  		regs:     nil,
   437  	}
   438  	instructions := []*pipeline.Instruction{
   439  		{Op: int32(vm.Deletion), Delete: &pipeline.Deletion{}},
   440  		{Op: int32(vm.Insert), Insert: &pipeline.Insert{}},
   441  		{Op: int32(vm.PreInsert), PreInsert: &pipeline.PreInsert{}},
   442  		{Op: int32(vm.LockOp), LockOp: &pipeline.LockOp{}},
   443  		{Op: int32(vm.PreInsertUnique), PreInsertUnique: &pipeline.PreInsertUnique{}},
   444  		{Op: int32(vm.OnDuplicateKey), OnDuplicateKey: &pipeline.OnDuplicateKey{}},
   445  		{Op: int32(vm.Anti), Anti: &pipeline.AntiJoin{}},
   446  		{Op: int32(vm.Shuffle), Shuffle: &pipeline.Shuffle{}},
   447  		{Op: int32(vm.Dispatch), Dispatch: &pipeline.Dispatch{}},
   448  		{Op: int32(vm.Group), Agg: &pipeline.Group{}},
   449  		{Op: int32(vm.Join), Join: &pipeline.Join{}},
   450  		{Op: int32(vm.Left), LeftJoin: &pipeline.LeftJoin{}},
   451  		{Op: int32(vm.Right), RightJoin: &pipeline.RightJoin{}},
   452  		{Op: int32(vm.RightSemi), RightSemiJoin: &pipeline.RightSemiJoin{}},
   453  		{Op: int32(vm.RightAnti), RightAntiJoin: &pipeline.RightAntiJoin{}},
   454  		{Op: int32(vm.Limit), Limit: 1},
   455  		{Op: int32(vm.LoopAnti), Anti: &pipeline.AntiJoin{}},
   456  		{Op: int32(vm.LoopJoin), Join: &pipeline.Join{}},
   457  		{Op: int32(vm.LoopLeft), LeftJoin: &pipeline.LeftJoin{}},
   458  		{Op: int32(vm.LoopSemi), SemiJoin: &pipeline.SemiJoin{}},
   459  		{Op: int32(vm.LoopSingle), SingleJoin: &pipeline.SingleJoin{}},
   460  		{Op: int32(vm.LoopMark), MarkJoin: &pipeline.MarkJoin{}},
   461  		{Op: int32(vm.Offset), Offset: 0},
   462  		{Op: int32(vm.Order), OrderBy: []*plan.OrderBySpec{}},
   463  		{Op: int32(vm.Product), Product: &pipeline.Product{}},
   464  		{Op: int32(vm.Projection), ProjectList: []*plan.Expr{}},
   465  		{Op: int32(vm.Restrict), Filter: &plan.Expr{}},
   466  		{Op: int32(vm.Semi), SemiJoin: &pipeline.SemiJoin{}},
   467  		{Op: int32(vm.Single), SingleJoin: &pipeline.SingleJoin{}},
   468  		{Op: int32(vm.Mark), MarkJoin: &pipeline.MarkJoin{}},
   469  		{Op: int32(vm.Top), Limit: 1},
   470  		{Op: int32(vm.Intersect), Anti: &pipeline.AntiJoin{}},
   471  		{Op: int32(vm.IntersectAll), Anti: &pipeline.AntiJoin{}},
   472  		{Op: int32(vm.Minus), Anti: &pipeline.AntiJoin{}},
   473  		{Op: int32(vm.Connector), Connect: &pipeline.Connector{}},
   474  		{Op: int32(vm.Merge)},
   475  		{Op: int32(vm.MergeRecursive)},
   476  		{Op: int32(vm.MergeGroup), Agg: &pipeline.Group{}},
   477  		{Op: int32(vm.MergeLimit), Limit: 1},
   478  		{Op: int32(vm.MergeOffset), Offset: 0},
   479  		{Op: int32(vm.MergeTop), Limit: 1},
   480  		{Op: int32(vm.MergeOrder), OrderBy: []*plan.OrderBySpec{}},
   481  		{Op: int32(vm.TableFunction), TableFunction: &pipeline.TableFunction{}},
   482  		{Op: int32(vm.HashBuild), HashBuild: &pipeline.HashBuild{}},
   483  		{Op: int32(vm.External), ExternalScan: &pipeline.ExternalScan{}},
   484  		{Op: int32(vm.Source), StreamScan: &pipeline.StreamScan{}},
   485  	}
   486  	for _, instruction := range instructions {
   487  		_, err := convertToVmInstruction(instruction, ctx, nil)
   488  		require.Nil(t, err)
   489  	}
   490  }
   491  
   492  func Test_mergeAnalyseInfo(t *testing.T) {
   493  	target := newAnaylze()
   494  	a := reuse.Alloc[process.AnalyzeInfo](nil)
   495  	target.analInfos = []*process.AnalyzeInfo{a}
   496  	ana := &pipeline.AnalysisList{
   497  		List: []*plan2.AnalyzeInfo{
   498  			{},
   499  		},
   500  	}
   501  	mergeAnalyseInfo(target, ana)
   502  	require.Equal(t, len(ana.List), 1)
   503  }
   504  
   505  func Test_convertToProcessLimitation(t *testing.T) {
   506  	lim := &pipeline.ProcessLimitation{
   507  		Size: 100,
   508  	}
   509  	limitation := convertToProcessLimitation(lim)
   510  	require.Equal(t, limitation.Size, int64(100))
   511  }
   512  
   513  func Test_convertToProcessSessionInfo(t *testing.T) {
   514  	ti, _ := time.Now().MarshalBinary()
   515  	sei := &pipeline.SessionInfo{
   516  		TimeZone: ti,
   517  	}
   518  	_, err := convertToProcessSessionInfo(sei)
   519  	require.Nil(t, err)
   520  }
   521  
   522  func Test_convertToPlanAnalyzeInfo(t *testing.T) {
   523  	info := reuse.Alloc[process.AnalyzeInfo](nil)
   524  	info.InputRows = 100
   525  	analyzeInfo := convertToPlanAnalyzeInfo(info)
   526  	require.Equal(t, analyzeInfo.InputRows, int64(100))
   527  }
   528  
   529  func Test_decodeBatch(t *testing.T) {
   530  	mp := &mpool.MPool{}
   531  	vp := process.New(
   532  		context.TODO(),
   533  		nil,
   534  		nil,
   535  		nil,
   536  		nil,
   537  		nil,
   538  		nil,
   539  		nil,
   540  		nil,
   541  		nil)
   542  	aggexec.RegisterGroupConcatAgg(0, ",")
   543  	agg0 := aggexec.MakeAgg(
   544  		vp, 0, false, []types.Type{types.T_varchar.ToType()}...)
   545  
   546  	bat := &batch.Batch{
   547  		Recursive:  0,
   548  		Ro:         false,
   549  		ShuffleIDX: 0,
   550  		Cnt:        1,
   551  		Attrs:      []string{"1"},
   552  		Vecs:       []*vector.Vector{vector.NewVec(types.T_int64.ToType())},
   553  		Aggs:       []aggexec.AggFuncExec{agg0},
   554  		AuxData:    nil,
   555  	}
   556  	bat.SetRowCount(1)
   557  	data, err := types.Encode(bat)
   558  	require.Nil(t, err)
   559  	_, err = decodeBatch(mp, data)
   560  	require.Nil(t, err)
   561  }