Esempio n. 1
0
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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
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))
}
Esempio n. 4
0
func (htup *HeapTupleHeader) Natts() system.AttrNumber {
	return system.AttrNumber(htup.infomask2 & uint16(heapNattsMask))
}