func (htup *HeapTupleHeader) Oid() system.Oid { if htup.infomask&heapHasOid != 0 { ptr := uintptr(unsafe.Pointer(htup)) + uintptr(htup.hoff) - unsafe.Sizeof(system.Oid(0)) return *(*system.Oid)(unsafe.Pointer(ptr)) } return system.InvalidOid }
func FormHeapTuple(values []system.Datum, tupdesc *TupleDesc) *HeapTuple { natts := len(tupdesc.Attrs) hasnull := false for _, value := range values { if value == nil { hasnull = true //} else if att.attlen == -1 // TODO: flatten toast value } } length := unsafe.Offsetof(HeapTupleHeader{}.bits) if hasnull { length += uintptr(bitmapLength(natts)) } if tupdesc.hasOid { length += unsafe.Sizeof(system.Oid(0)) } length = system.MaxAlign(length) hoff := uint8(length) data_len := computeHeapDataSize(values, tupdesc) length += data_len tuple_data := make([]byte, length) tuple := &HeapTuple{ tupdesc: tupdesc, tableOid: system.InvalidOid, } tuple.SetData(tuple_data, system.InvalidItemPointer) td := tuple.data td.SetNatts(system.AttrNumber(natts)) td.hoff = hoff if tupdesc.hasOid { td.infomask = heapHasOid } bits := []byte(nil) if hasnull { bits = tuple.bytes[unsafe.Offsetof(td.bits):hoff] } data := tuple.bytes[hoff:] td.fill(values, tupdesc, bits, data) return tuple }
func (s *MySuite) TestHeapTuple(c *C) { values := []system.Datum{ system.Int4(1), system.Oid(999990), nil, system.Name("fooname"), } tupdesc := &TupleDesc{ Attrs: []*Attribute{ { Name: "col1", TypeId: system.Int4Type, }, { Name: "col2", TypeId: system.OidType, }, { Name: "col3nil", TypeId: system.NameType, }, { Name: "col4", TypeId: system.NameType, }, }, } initTupleDesc(tupdesc) htuple := FormHeapTuple(values, tupdesc) c.Check(htuple.Fetch(1), Equals, values[0]) c.Check(htuple.Fetch(2), Equals, values[1]) c.Check(htuple.Fetch(3), Equals, values[2]) c.Check(htuple.Fetch(4), Equals, values[3]) c.Check(htuple.data.Oid(), Equals, system.InvalidOid) c.Check(htuple.data.HasNulls(), Equals, true) c.Check(htuple.data.Natts(), Equals, system.AttrNumber(4)) }