github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/storage/memorystorage/catalog.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 memorystorage 16 17 import ( 18 "fmt" 19 20 "github.com/matrixorigin/matrixone/pkg/catalog" 21 "github.com/matrixorigin/matrixone/pkg/container/types" 22 "github.com/matrixorigin/matrixone/pkg/txn/storage/memorystorage/memorytable" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/memoryengine" 25 ) 26 27 var ( 28 index_AccountID = Text("account id") 29 index_AccountID_Name = Text("account id, name") 30 index_DatabaseID = Text("database id") 31 index_DatabaseID_Name = Text("database id, name") 32 index_RelationID = Text("relation id") 33 index_RelationID_IsHidden = Text("relation id, is hidden") 34 index_RelationID_IsPrimary = Text("relation id, is primary") 35 index_RelationID_Name = Text("relation id, name") 36 index_RowID = Text("row id") 37 ) 38 39 type ( 40 DatabaseRowIter = Iter[ID, *DatabaseRow] 41 RelationRowIter = Iter[ID, *RelationRow] 42 AttributeRowIter = Iter[ID, *AttributeRow] 43 ) 44 45 type DatabaseRow struct { 46 ID ID 47 AccountID uint32 // 0 is the sys account 48 Name []byte 49 Typ []byte 50 CreateSql []byte 51 } 52 53 func (d *DatabaseRow) Key() ID { 54 return d.ID 55 } 56 57 func (d *DatabaseRow) Value() *DatabaseRow { 58 return d 59 } 60 61 func (d *DatabaseRow) Indexes() []Tuple { 62 return []Tuple{ 63 {index_AccountID, Uint(d.AccountID)}, 64 {index_AccountID_Name, Uint(d.AccountID), Text(d.Name)}, 65 } 66 } 67 68 func (d *DatabaseRow) UniqueIndexes() []Tuple { 69 return []Tuple{ 70 {index_AccountID_Name, Uint(d.AccountID), Text(d.Name)}, 71 } 72 } 73 74 var _ NamedRow = new(DatabaseRow) 75 76 func (d *DatabaseRow) AttrByName(handler *MemHandler, tx *Transaction, name string) (ret Nullable, err error) { 77 defer func() { 78 if ret.Value != nil { 79 verifyAttr(catalog.MoDatabaseSchema, catalog.MoDatabaseTypes, name, ret.Value) 80 } 81 }() 82 switch name { 83 case catalog.SystemDBAttr_ID: 84 ret.Value = uint64(d.ID) 85 case catalog.SystemDBAttr_Name: 86 ret.Value = d.Name 87 case catalog.SystemDBAttr_CatalogName: 88 ret.Value = []byte("") 89 case catalog.SystemDBAttr_CreateSQL: 90 ret.Value = []byte("") 91 case catalog.SystemDBAttr_Owner: 92 ret.Value = uint32(d.AccountID) 93 case catalog.SystemDBAttr_Creator: 94 ret.Value = uint32(d.AccountID) 95 case catalog.SystemDBAttr_CreateAt: 96 ret.Value = types.Timestamp(0) 97 case catalog.SystemDBAttr_AccID: 98 ret.Value = uint32(d.AccountID) 99 case rowIDColumnName: 100 ret.Value = d.ID.ToRowID() 101 default: 102 panic(fmt.Sprintf("fixme: %s", name)) 103 } 104 return 105 } 106 107 type RelationRow struct { 108 ID ID 109 DatabaseID ID 110 Name []byte 111 Type memoryengine.RelationType 112 Comments []byte 113 Properties map[string]string 114 Partitioned int8 // 1 : the table has partitions. 0 : no partition 115 PartitionDef []byte // partition info for the table has paritions 116 ViewDef []byte 117 Constraint []byte 118 } 119 120 func (r *RelationRow) Key() ID { 121 return r.ID 122 } 123 124 func (r *RelationRow) Value() *RelationRow { 125 return r 126 } 127 128 func (r *RelationRow) Indexes() []Tuple { 129 return []Tuple{ 130 {index_DatabaseID, r.DatabaseID}, 131 {index_DatabaseID_Name, r.DatabaseID, Text(r.Name)}, 132 } 133 } 134 135 func (r *RelationRow) UniqueIndexes() []Tuple { 136 return []Tuple{ 137 {index_DatabaseID_Name, r.DatabaseID, Text(r.Name)}, 138 } 139 } 140 141 var _ NamedRow = new(RelationRow) 142 143 func (r *RelationRow) AttrByName(handler *MemHandler, tx *Transaction, name string) (ret Nullable, err error) { 144 defer func() { 145 if ret.Value != nil { 146 verifyAttr(catalog.MoDatabaseSchema, catalog.MoDatabaseTypes, name, ret.Value) 147 } 148 }() 149 switch name { 150 case catalog.SystemRelAttr_ID: 151 ret.Value = uint64(r.ID) 152 case catalog.SystemRelAttr_Name: 153 ret.Value = r.Name 154 case catalog.SystemRelAttr_DBID: 155 if r.DatabaseID.IsEmpty() { 156 ret.Value = uint64(0) 157 return 158 } 159 db, err := handler.databases.Get(tx, r.DatabaseID) 160 if err != nil { 161 return ret, err 162 } 163 ret.Value = uint64(db.ID) 164 case catalog.SystemRelAttr_DBName: 165 if r.DatabaseID.IsEmpty() { 166 ret.Value = []byte("") 167 return 168 } 169 db, err := handler.databases.Get(tx, r.DatabaseID) 170 if err != nil { 171 return ret, err 172 } 173 ret.Value = db.Name 174 case catalog.SystemRelAttr_Persistence: 175 ret.Value = []byte("") 176 case catalog.SystemRelAttr_Kind: 177 ret.Value = []byte(r.Properties[catalog.SystemRelAttr_Kind]) // tae's logic 178 case catalog.SystemRelAttr_Comment: 179 ret.Value = r.Comments 180 case catalog.SystemRelAttr_Partitioned: 181 ret.Value = r.Partitioned 182 case catalog.SystemRelAttr_Partition: 183 ret.Value = r.PartitionDef 184 case catalog.SystemRelAttr_CreateSQL: 185 ret.Value = []byte(r.Properties[catalog.SystemRelAttr_CreateSQL]) // tae's logic 186 case catalog.SystemRelAttr_Owner: 187 ret.Value = uint32(0) //TODO 188 case catalog.SystemRelAttr_Creator: 189 ret.Value = uint32(0) //TODO 190 case catalog.SystemRelAttr_CreateAt: 191 ret.Value = types.Timestamp(0) //TODO 192 case catalog.SystemRelAttr_AccID: 193 ret.Value = uint32(0) 194 case rowIDColumnName: 195 ret.Value = r.ID.ToRowID() 196 case catalog.SystemRelAttr_ViewDef: 197 ret.Value = []byte(r.ViewDef) 198 case catalog.SystemRelAttr_Constraint: 199 ret.Value = r.Constraint 200 default: 201 panic(fmt.Sprintf("fixme: %s", name)) 202 } 203 return 204 } 205 206 type AttributeRow struct { 207 ID ID 208 RelationID ID 209 Order int 210 Nullable bool 211 engine.Attribute 212 } 213 214 func (a *AttributeRow) Key() ID { 215 return a.ID 216 } 217 218 func (a *AttributeRow) Value() *AttributeRow { 219 return a 220 } 221 222 func (a *AttributeRow) Indexes() []Tuple { 223 return []Tuple{ 224 {index_RelationID, a.RelationID}, 225 {index_RelationID_Name, a.RelationID, Text(a.Name)}, 226 {index_RelationID_IsPrimary, a.RelationID, Bool(a.Primary)}, 227 {index_RelationID_IsHidden, a.RelationID, Bool(a.IsHidden)}, 228 } 229 } 230 231 func (a *AttributeRow) UniqueIndexes() []Tuple { 232 return []Tuple{ 233 {index_RelationID_Name, a.RelationID, Text(a.Name)}, 234 } 235 } 236 237 var _ NamedRow = new(AttributeRow) 238 239 func (a *AttributeRow) AttrByName(handler *MemHandler, tx *Transaction, name string) (ret Nullable, err error) { 240 defer func() { 241 if ret.Value != nil { 242 verifyAttr(catalog.MoDatabaseSchema, catalog.MoDatabaseTypes, name, ret.Value) 243 } 244 }() 245 switch name { 246 case catalog.SystemColAttr_UniqName: 247 ret.Value = []byte(a.Name) 248 case catalog.SystemColAttr_AccID: 249 ret.Value = uint32(0) 250 case catalog.SystemColAttr_Name: 251 ret.Value = []byte(a.Name) 252 case catalog.SystemColAttr_DBID: 253 rel, err := handler.relations.Get(tx, a.RelationID) 254 if err != nil { 255 return ret, err 256 } 257 if rel.DatabaseID.IsEmpty() { 258 ret.Value = uint64(0) 259 return ret, nil 260 } 261 db, err := handler.databases.Get(tx, rel.DatabaseID) 262 if err != nil { 263 return ret, err 264 } 265 ret.Value = uint64(db.ID) 266 case catalog.SystemColAttr_DBName: 267 rel, err := handler.relations.Get(tx, a.RelationID) 268 if err != nil { 269 return ret, err 270 } 271 if rel.DatabaseID.IsEmpty() { 272 ret.Value = []byte("") 273 return ret, nil 274 } 275 db, err := handler.databases.Get(tx, rel.DatabaseID) 276 if err != nil { 277 return ret, err 278 } 279 ret.Value = db.Name 280 case catalog.SystemColAttr_RelID: 281 ret.Value = uint64(a.RelationID) 282 case catalog.SystemColAttr_RelName: 283 rel, err := handler.relations.Get(tx, a.RelationID) 284 if err != nil { 285 return ret, err 286 } 287 ret.Value = rel.Name 288 case catalog.SystemColAttr_Type: 289 data, err := types.Encode(&a.Type) 290 if err != nil { 291 return ret, err 292 } 293 ret.Value = data 294 case catalog.SystemColAttr_Num: 295 ret.Value = int32(a.Order) 296 case catalog.SystemColAttr_Length: 297 ret.Value = int32(a.Type.TypeSize()) 298 case catalog.SystemColAttr_NullAbility: 299 ret.Value = boolToInt8(a.Nullable) 300 case catalog.SystemColAttr_HasExpr: 301 ret.Value = boolToInt8(a.Default != nil) 302 case catalog.SystemColAttr_DefaultExpr: 303 if a.Default != nil { 304 defaultExpr, err := types.Encode(a.Default) 305 if err != nil { 306 return ret, nil 307 } 308 ret.Value = defaultExpr 309 } else { 310 ret.Value = []byte("") 311 } 312 case catalog.SystemColAttr_HasUpdate: 313 ret.Value = boolToInt8(a.OnUpdate != nil) 314 case catalog.SystemColAttr_Update: 315 if a.OnUpdate != nil { 316 expr, err := types.Encode(a.OnUpdate) 317 if err != nil { 318 return ret, nil 319 } 320 ret.Value = expr 321 } else { 322 ret.Value = []byte("") 323 } 324 case catalog.SystemColAttr_IsDropped: 325 ret.Value = boolToInt8(false) 326 case catalog.SystemColAttr_ConstraintType: 327 if a.Primary { 328 ret.Value = []byte("p") 329 } else { 330 ret.Value = []byte("n") 331 } 332 case catalog.SystemColAttr_IsUnsigned: 333 ret.Value = boolToInt8(a.Type.Oid == types.T_uint8 || 334 a.Type.Oid == types.T_uint16 || 335 a.Type.Oid == types.T_uint32 || 336 a.Type.Oid == types.T_uint64 || 337 a.Type.Oid == types.T_uint128) 338 case catalog.SystemColAttr_IsAutoIncrement: 339 ret.Value = boolToInt8(a.AutoIncrement) 340 case catalog.SystemColAttr_IsHidden: 341 ret.Value = boolToInt8(a.IsHidden) 342 case catalog.SystemColAttr_Comment: 343 ret.Value = []byte(a.Comment) 344 case rowIDColumnName: 345 ret.Value = a.ID.ToRowID() 346 case catalog.SystemColAttr_IsClusterBy: 347 ret.Value = boolToInt8(a.ClusterBy) 348 default: 349 panic(fmt.Sprintf("fixme: %s", name)) 350 } 351 return 352 } 353 354 func verifyAttr( 355 names []string, 356 types []types.Type, 357 name string, 358 value any, 359 ) { 360 for i, attrName := range names { 361 if attrName != name { 362 continue 363 } 364 if value == nil { 365 panic(fmt.Sprintf("%s should not be nil", attrName)) 366 } 367 if !memorytable.TypeMatch(value, types[i].Oid) { 368 panic(fmt.Sprintf("%s should be %v typed", name, types[i])) 369 } 370 } 371 }