func (tuple *HeapTuple) Fetch(attnum system.AttrNumber) system.Datum { if attnum <= 0 { switch attnum { case system.CtidAttrNumber: return system.Datum(tuple.self) case system.OidAttrNumber: return system.Datum(tuple.data.Oid()) case system.XminAttrNumber: //return system.Datum(tuple.data.Xmin()) case system.CminAttrNumber: // TODO: case system.XmaxAttrNumber: //return system.Datum(tuple.data.Xmax()) case system.CmaxAttrNumber: // TODO: case system.TableOidAttrNumber: return system.Datum(tuple.tableOid) } } else { td := tuple.data if td.IsNull(attnum) { return nil } // TODO: attcache offset := int(td.hoff) for i := system.AttrNumber(1); i < attnum; i++ { if td.IsNull(i) { continue } attr := tuple.tupdesc.Attrs[i-1] if attr.Type.IsVarlen() { // TODO: } else { offset += int(attr.Type.Len) } } reader := bytes.NewReader(tuple.bytes[offset:]) return system.DatumFromBytes(reader, tuple.tupdesc.Attrs[attnum-1].TypeId) } return nil }
func (rv *RangeVar) OpenRelation() (rel *access.Relation, err error) { /* TODO: Refactor this to RelnameGetOid() */ class_rel, err := access.HeapOpen(access.ClassRelId) if err != nil { return nil, err } defer class_rel.Close() scankeys := []access.ScanKey{ {access.Anum_class_relname, system.Datum(rv.RelationName)}, } scan, err := class_rel.BeginScan(scankeys) if err != nil { return nil, err } defer scan.EndScan() tuple, err := scan.Next() if err != nil { return nil, errors.New("relation not found") } relid := tuple.Get(int32(1)).(system.Oid) return access.HeapOpen(relid) }
func HeapOpen(relid system.Oid, bufMgr storage.BufferManager) (*HeapRelation, error) { if relid == ClassRelId { relation := &HeapRelation{ RelId: relid, RelName: "bp_class", RelDesc: ClassTupleDesc, } relation.initRelFileNode() return relation, nil } else if relid == AttributeRelId { relation := &HeapRelation{ RelId: relid, RelName: "bp_attribute", RelDesc: AttributeTupleDesc, } relation.initRelFileNode() return relation, nil } /* * Collect class information. Currently, nothing but name is stored. */ class_rel, err := HeapOpen(ClassRelId, bufMgr) if err != nil { return nil, err } defer class_rel.Close() var scan_keys []ScanKey scan_keys = []ScanKey{ {system.OidAttrNumber, system.Datum(relid)}, } class_scan, err := class_rel.BeginScan(scan_keys, bufMgr) if err != nil { return nil, err } defer class_scan.EndScan() class_tuple, err := class_scan.Next() relation := &HeapRelation{ RelId: relid, RelName: class_tuple.Fetch(Anum_class_relname).(system.Name), } attr_rel, err := HeapOpen(AttributeRelId, bufMgr) if err != nil { return nil, err } defer attr_rel.Close() scan_keys = []ScanKey{ {Anum_attribute_attrelid, system.Datum(relid)}, } /* * Collect attributes */ attr_scan, err := attr_rel.BeginScan(scan_keys, bufMgr) if err != nil { return nil, err } defer attr_scan.EndScan() var attributes []*Attribute for { attr_tuple, err := attr_scan.Next() if err != nil { break } typid := attr_tuple.Fetch(Anum_attribute_atttypid).(system.Oid) attribute := &Attribute{ Name: attr_tuple.Fetch(Anum_attribute_attname).(system.Name), TypeId: typid, Type: system.TypeRegistry[typid], } attributes = append(attributes, attribute) } relation.RelDesc = &TupleDesc{ Attrs: attributes, } relation.initRelFileNode() return relation, nil }