github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/db/test/hidden_test.go (about)

     1  // Copyright 2022 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 test
    16  
    17  import (
    18  	"context"
    19  	"sort"
    20  	"testing"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  	"github.com/matrixorigin/matrixone/pkg/objectio"
    24  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db/testutil"
    28  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils"
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  // Testing Steps
    33  // 1. Mock schema with PK.
    34  // 2. Append data (append rows less than a block) and commit. Scan hidden column and check.
    35  // 3. Append data and the total rows is more than a block. Commit and then compact the full block.
    36  // 4. Scan hidden column and check.
    37  // 5. Append data and the total rows is more than one Object. Commit and then merge sort the full Object.
    38  // 6. Scan hidden column and check.
    39  func TestHiddenWithPK1(t *testing.T) {
    40  	defer testutils.AfterTest(t)()
    41  	testutils.EnsureNoLeak(t)
    42  	ctx := context.Background()
    43  
    44  	tae := testutil.InitTestDB(ctx, ModuleName, t, nil)
    45  	defer tae.Close()
    46  	schema := catalog.MockSchemaAll(13, 2)
    47  	schema.BlockMaxRows = 10
    48  	schema.ObjectMaxBlocks = 2
    49  	bat := catalog.MockBatch(schema, int(schema.BlockMaxRows*4))
    50  	defer bat.Close()
    51  	bats := bat.Split(10)
    52  
    53  	txn, _, rel := testutil.CreateRelationNoCommit(t, tae, testutil.DefaultTestDB, schema, true)
    54  	err := rel.Append(context.Background(), bats[0])
    55  	{
    56  		offsets := make([]uint32, 0)
    57  		it := rel.MakeObjectIt()
    58  		for it.Valid() {
    59  			blk := it.GetObject()
    60  			view, err := blk.GetColumnDataById(context.Background(), 0, schema.PhyAddrKey.Idx, common.DefaultAllocator)
    61  			assert.NoError(t, err)
    62  			defer view.Close()
    63  			fp := blk.Fingerprint()
    64  			_ = view.GetData().Foreach(func(v any, _ bool, _ int) (err error) {
    65  				rid := v.(types.Rowid)
    66  				bid, offset := rid.Decode()
    67  				t.Logf("bid=%s,offset=%d", bid.String(), offset)
    68  				assert.Equal(t, fp.BlockID, bid)
    69  				offsets = append(offsets, offset)
    70  				return
    71  			}, nil)
    72  			it.Next()
    73  		}
    74  		// sort.Slice(offsets, func(i, j int) bool { return offsets[i] < offsets[j] })
    75  		// assert.Equal(t, []uint32{0, 1, 2, 3}, offsets)
    76  	}
    77  	assert.NoError(t, err)
    78  	assert.NoError(t, txn.Commit(context.Background()))
    79  
    80  	txn, rel = testutil.GetDefaultRelation(t, tae, schema.Name)
    81  	{
    82  		blk := testutil.GetOneObject(rel)
    83  		view, err := blk.GetColumnDataByName(context.Background(), 0, catalog.PhyAddrColumnName, common.DefaultAllocator)
    84  		assert.NoError(t, err)
    85  		defer view.Close()
    86  		offsets := make([]uint32, 0)
    87  		fp := blk.Fingerprint()
    88  		t.Log(fp.String())
    89  		_ = view.GetData().Foreach(func(v any, _ bool, _ int) (err error) {
    90  			rid := v.(types.Rowid)
    91  			bid, offset := rid.Decode()
    92  			t.Logf(",bid=%s,offset=%d", bid, offset)
    93  			assert.Equal(t, fp.BlockID, bid)
    94  			offsets = append(offsets, offset)
    95  			return
    96  		}, nil)
    97  		sort.Slice(offsets, func(i, j int) bool { return offsets[i] < offsets[j] })
    98  		assert.Equal(t, []uint32{0, 1, 2, 3}, offsets)
    99  	}
   100  
   101  	assert.NoError(t, err)
   102  	assert.NoError(t, txn.Commit(context.Background()))
   103  
   104  	txn, rel = testutil.GetDefaultRelation(t, tae, schema.Name)
   105  	err = rel.Append(context.Background(), bats[1])
   106  	assert.NoError(t, err)
   107  	err = rel.Append(context.Background(), bats[2])
   108  	assert.NoError(t, err)
   109  	err = rel.Append(context.Background(), bats[3])
   110  	assert.NoError(t, err)
   111  	err = rel.Append(context.Background(), bats[4])
   112  	assert.NoError(t, err)
   113  	err = rel.Append(context.Background(), bats[5])
   114  	assert.NoError(t, err)
   115  	assert.NoError(t, txn.Commit(context.Background()))
   116  
   117  	testutil.CompactBlocks(t, 0, tae, "db", schema, false)
   118  
   119  	t.Log(tae.Catalog.SimplePPString(3))
   120  	txn, rel = testutil.GetDefaultRelation(t, tae, schema.Name)
   121  	{
   122  		it := rel.MakeObjectIt()
   123  		for it.Valid() {
   124  			blk := it.GetObject()
   125  			for j := 0; j < blk.BlkCnt(); j++ {
   126  				view, err := blk.GetColumnDataByName(context.Background(), uint16(j), catalog.PhyAddrColumnName, common.DefaultAllocator)
   127  				assert.NoError(t, err)
   128  				defer view.Close()
   129  				offsets := make([]uint32, 0)
   130  				meta := blk.GetMeta().(*catalog.ObjectEntry)
   131  				t.Logf("%v, blk %d", meta.String(), j)
   132  				_ = view.GetData().Foreach(func(v any, _ bool, _ int) (err error) {
   133  					rid := v.(types.Rowid)
   134  					bid, offset := rid.Decode()
   135  					// t.Logf("sid=%d,bid=%d,offset=%d", sid, bid, offset)
   136  					expectedBid := objectio.NewBlockidWithObjectID(&meta.ID, uint16(j))
   137  					assert.Equal(t, *expectedBid, bid, "expect %v, get %v", expectedBid.String(), bid.String())
   138  					offsets = append(offsets, offset)
   139  					return
   140  				}, nil)
   141  				sort.Slice(offsets, func(i, j int) bool { return offsets[i] < offsets[j] })
   142  				if meta.IsAppendable() {
   143  					assert.Equal(t, []uint32{0, 1, 2, 3}, offsets)
   144  				} else {
   145  					if j != 2 {
   146  						assert.Equal(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, offsets)
   147  					} else {
   148  						assert.Equal(t, []uint32{0, 1, 2, 3}, offsets)
   149  					}
   150  				}
   151  			}
   152  			it.Next()
   153  		}
   154  	}
   155  
   156  	assert.NoError(t, txn.Commit(context.Background()))
   157  	{
   158  		testutil.CompactBlocks(t, 0, tae, "db", schema, false)
   159  		testutil.MergeBlocks(t, 0, tae, "db", schema, false)
   160  	}
   161  
   162  	txn, rel = testutil.GetDefaultRelation(t, tae, schema.Name)
   163  	{
   164  		it := rel.MakeObjectIt()
   165  		objIdx := -1
   166  		for it.Valid() {
   167  			blk := it.GetObject()
   168  			objIdx++
   169  			for j := 0; j < blk.BlkCnt(); j++ {
   170  				view, err := blk.GetColumnDataByName(context.Background(), uint16(j), catalog.PhyAddrColumnName, common.DefaultAllocator)
   171  				assert.NoError(t, err)
   172  				defer view.Close()
   173  				offsets := make([]uint32, 0)
   174  				meta := blk.GetMeta().(*catalog.ObjectEntry)
   175  				t.Log(meta.String())
   176  				t.Log(meta.String())
   177  				_ = view.GetData().Foreach(func(v any, _ bool, _ int) (err error) {
   178  					rid := v.(types.Rowid)
   179  					bid, offset := rid.Decode()
   180  					// t.Logf("sid=%d,bid=%d,offset=%d", sid, bid, offset)
   181  					assert.Equal(t, *objectio.NewBlockidWithObjectID(&meta.ID, uint16(j)), bid)
   182  					offsets = append(offsets, offset)
   183  					return
   184  				}, nil)
   185  				sort.Slice(offsets, func(i, j int) bool { return offsets[i] < offsets[j] })
   186  				if meta.IsAppendable() {
   187  					assert.Equal(t, []uint32{0, 1, 2, 3}, offsets)
   188  				} else {
   189  					if objIdx != 1 {
   190  						assert.Equal(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, offsets)
   191  					} else {
   192  						assert.Equal(t, []uint32{0, 1, 2, 3}, offsets)
   193  					}
   194  				}
   195  
   196  			}
   197  			it.Next()
   198  		}
   199  	}
   200  
   201  	assert.NoError(t, txn.Commit(context.Background()))
   202  	t.Log(tae.Catalog.SimplePPString(common.PPL1))
   203  }
   204  
   205  // Testing Steps
   206  // 1. Mock schema w/o primary key
   207  // 2. Append data (append rows less than a block)
   208  func TestHidden2(t *testing.T) {
   209  	defer testutils.AfterTest(t)()
   210  	testutils.EnsureNoLeak(t)
   211  	ctx := context.Background()
   212  
   213  	tae := testutil.InitTestDB(ctx, ModuleName, t, nil)
   214  	defer tae.Close()
   215  	schema := catalog.MockSchemaAll(3, -1)
   216  	schema.BlockMaxRows = 10
   217  	schema.ObjectMaxBlocks = 2
   218  	bat := catalog.MockBatch(schema, int(schema.BlockMaxRows*4))
   219  	defer bat.Close()
   220  	bats := bat.Split(10)
   221  
   222  	txn, _, rel := testutil.CreateRelationNoCommit(t, tae, testutil.DefaultTestDB, schema, true)
   223  	err := rel.Append(context.Background(), bats[0])
   224  	{
   225  		blk := testutil.GetOneObject(rel)
   226  		var hidden *containers.ColumnView
   227  		for _, def := range schema.ColDefs {
   228  			view, err := blk.GetColumnDataById(context.Background(), 0, def.Idx, common.DefaultAllocator)
   229  			assert.NoError(t, err)
   230  			defer view.Close()
   231  			assert.Equal(t, bats[0].Length(), view.Length())
   232  			if def.IsPhyAddr() {
   233  				hidden = view
   234  			}
   235  		}
   236  		_ = hidden.GetData().Foreach(func(key any, _ bool, _ int) (err error) {
   237  			rid := key.(types.Rowid)
   238  			bid, offset := rid.Decode()
   239  			t.Logf(",bid=%s,offset=%d", bid, offset)
   240  			v, _, err := rel.GetValueByPhyAddrKey(key, schema.PhyAddrKey.Idx)
   241  			assert.NoError(t, err)
   242  			assert.Equal(t, key, v)
   243  			if offset == 1 {
   244  				err = rel.DeleteByPhyAddrKey(key)
   245  				assert.NoError(t, err)
   246  			}
   247  			return
   248  		}, nil)
   249  		for _, def := range schema.ColDefs {
   250  			view, err := blk.GetColumnDataById(context.Background(), 0, def.Idx, common.DefaultAllocator)
   251  			assert.NoError(t, err)
   252  			defer view.Close()
   253  			view.ApplyDeletes()
   254  			assert.Equal(t, bats[0].Length()-1, view.Length())
   255  		}
   256  	}
   257  	assert.NoError(t, err)
   258  	assert.NoError(t, txn.Commit(context.Background()))
   259  
   260  	txn, rel = testutil.GetDefaultRelation(t, tae, schema.Name)
   261  	{
   262  		blk := testutil.GetOneObject(rel)
   263  		var hidden *containers.ColumnView
   264  		for _, def := range schema.ColDefs {
   265  			view, err := blk.GetColumnDataById(context.Background(), 0, def.Idx, common.DefaultAllocator)
   266  			assert.NoError(t, err)
   267  			defer view.Close()
   268  			assert.Equal(t, bats[0].Length()-1, view.Length())
   269  			if def.IsPhyAddr() {
   270  				hidden = view
   271  			}
   272  		}
   273  		_ = hidden.GetData().Foreach(func(key any, _ bool, _ int) (err error) {
   274  			rid := key.(types.Rowid)
   275  			bid, offset := rid.Decode()
   276  			t.Logf(",bid=%s,offset=%d", bid, offset)
   277  			v, _, err := rel.GetValueByPhyAddrKey(key, schema.PhyAddrKey.Idx)
   278  			assert.NoError(t, err)
   279  			assert.Equal(t, key, v)
   280  			if offset == 1 {
   281  				err = rel.DeleteByPhyAddrKey(key)
   282  				assert.NoError(t, err)
   283  			}
   284  			return
   285  		}, nil)
   286  	}
   287  	err = rel.Append(context.Background(), bats[1])
   288  	assert.NoError(t, err)
   289  	err = rel.Append(context.Background(), bats[1])
   290  	assert.NoError(t, err)
   291  	err = rel.Append(context.Background(), bats[1])
   292  	assert.NoError(t, err)
   293  	err = rel.Append(context.Background(), bats[2])
   294  	assert.NoError(t, err)
   295  	err = rel.Append(context.Background(), bats[2])
   296  	assert.NoError(t, err)
   297  	err = rel.Append(context.Background(), bats[2])
   298  	assert.NoError(t, err)
   299  	assert.NoError(t, txn.Commit(context.Background()))
   300  
   301  	testutil.CompactBlocks(t, 0, tae, "db", schema, false)
   302  	testutil.MergeBlocks(t, 0, tae, "db", schema, false)
   303  
   304  	t.Log(tae.Catalog.SimplePPString(common.PPL1))
   305  
   306  	txn, rel = testutil.GetDefaultRelation(t, tae, schema.Name)
   307  	{
   308  		it := rel.MakeObjectIt()
   309  		rows := 0
   310  		for it.Valid() {
   311  			blk := it.GetObject()
   312  			for j := 0; j < blk.BlkCnt(); j++ {
   313  				hidden, err := blk.GetColumnDataById(context.Background(), uint16(j), schema.PhyAddrKey.Idx, common.DefaultAllocator)
   314  				assert.NoError(t, err)
   315  				defer hidden.Close()
   316  				hidden.ApplyDeletes()
   317  				rows += hidden.Length()
   318  			}
   319  			it.Next()
   320  		}
   321  		assert.Equal(t, 26, rows)
   322  	}
   323  	assert.NoError(t, txn.Commit(context.Background()))
   324  	t.Log(tae.Catalog.SimplePPString(common.PPL1))
   325  }