예제 #1
0
파일: tuple.go 프로젝트: umitanuki/bigpot
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
}
예제 #2
0
파일: query.go 프로젝트: umitanuki/bigpot
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)
}
예제 #3
0
파일: heap.go 프로젝트: umitanuki/bigpot
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
}