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