Skip to content

Commit

Permalink
Add heap infomask flags parser to PostgreSQL
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel Safonov committed Aug 1, 2022
1 parent 01b380e commit 3c6ea87
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 0 deletions.
11 changes: 11 additions & 0 deletions format/postgres/common/pgheap.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,14 @@ func (m lpLenMapper) MapScalar(s scalar.S) (scalar.S, error) {
}

var LpLenMapper = lpLenMapper{}

type Mask struct {
Mask uint64
}

func (m Mask) MapScalar(s scalar.S) (scalar.S, error) {
m1 := s.ActualU()
v := IsMaskSet(m1, m.Mask)
s.Actual = v
return s, nil
}
7 changes: 7 additions & 0 deletions format/postgres/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ func TypeAlign8(alignLen uint64) uint64 {
func RoundDown(alignVal uint64, alignLen uint64) uint64 {
return (alignLen / alignVal) * alignVal
}

func IsMaskSet(value uint64, mask uint64) uint64 {
if (value & mask) == mask {
return 1
}
return 0
}
11 changes: 11 additions & 0 deletions format/postgres/common/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,14 @@ func TestRoundDown(t *testing.T) {
t.Errorf("must be %d\n", 5*pageSize1)
}
}

func TestIsMaskSet(t *testing.T) {
m1 := common.IsMaskSet(0xff+0x1221000, 0xf0)
if m1 != 1 {
t.Errorf("mask must be set\n")
}
m2 := common.IsMaskSet(0xff+0x1221000, 0xf00)
if m2 != 0 {
t.Errorf("mask must be 0\n")
}
}
93 changes: 93 additions & 0 deletions format/postgres/flavours/postgres14/pgheap.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,42 @@ import (
"github.com/wader/fq/pkg/scalar"
)

const (
HEAP_HASNULL = 0x0001 /* has null attribute(s) */
HEAP_HASVARWIDTH = 0x0002 /* has variable-width attribute(s) */
HEAP_HASEXTERNAL = 0x0004 /* has external stored attribute(s) */
HEAP_HASOID_OLD = 0x0008 /* has an object-id field */
HEAP_XMAX_KEYSHR_LOCK = 0x0010 /* xmax is a key-shared locker */
HEAP_COMBOCID = 0x0020 /* t_cid is a combo CID */
HEAP_XMAX_EXCL_LOCK = 0x0040 /* xmax is exclusive locker */
HEAP_XMAX_LOCK_ONLY = 0x0080 /* xmax, if valid, is only a locker */

HEAP_XMAX_SHR_LOCK = HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK

HEAP_LOCK_MASK = HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK

HEAP_XMIN_COMMITTED = 0x0100 /* t_xmin committed */
HEAP_XMIN_INVALID = 0x0200 /* t_xmin invalid/aborted */
HEAP_XMIN_FROZEN = HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID
HEAP_XMAX_COMMITTED = 0x0400 /* t_xmax committed */
HEAP_XMAX_INVALID = 0x0800 /* t_xmax invalid/aborted */
HEAP_XMAX_IS_MULTI = 0x1000 /* t_xmax is a MultiXactId */
HEAP_UPDATED = 0x2000 /* this is UPDATEd version of row */
HEAP_MOVED_OFF = 0x4000 /* moved to another place by pre-9.0
* VACUUM FULL; kept for binary
* upgrade support */
HEAP_MOVED_IN = 0x8000 /* moved from another place by pre-9.0
* VACUUM FULL; kept for binary
* upgrade support */
HEAP_MOVED = HEAP_MOVED_OFF | HEAP_MOVED_IN
)

const (
HEAP_KEYS_UPDATED = 0x2000 /* tuple was updated and key cols modified, or tuple deleted */
HEAP_HOT_UPDATED = 0x4000 /* tuple was HOT-updated */
HEAP_ONLY_TUPLE = 0x8000 /* this is heap-only tuple */
)

// type = struct PageHeaderData
/* 0 | 8 */ // PageXLogRecPtr pd_lsn;
/* 8 | 2 */ // uint16 pd_checksum;
Expand Down Expand Up @@ -274,7 +310,10 @@ func decodeTuples(d *decode.D) {
/* 23 | 0 */ // bits8 t_bits[];
/* XXX 1-byte padding */
d.FieldU16("t_infomask2")
d.FieldStruct("Infomask2", decodeInfomask2)
d.FieldU16("t_infomask")
d.FieldStruct("Infomask", decodeInfomask)

d.FieldU8("t_hoff")
d.U8()

Expand All @@ -284,6 +323,60 @@ func decodeTuples(d *decode.D) {
} // for ItemsIds
}

func decodeInfomask2(d *decode.D) {
pos := d.Pos() - 16
d.SeekAbs(pos)
d.FieldU16("HEAP_KEYS_UPDATED", common.Mask{Mask: HEAP_KEYS_UPDATED})
d.SeekAbs(pos)
d.FieldU16("HEAP_HOT_UPDATED", common.Mask{Mask: HEAP_HOT_UPDATED})
d.SeekAbs(pos)
d.FieldU16("HEAP_ONLY_TUPLE", common.Mask{Mask: HEAP_ONLY_TUPLE})
}

func decodeInfomask(d *decode.D) {
pos := d.Pos() - 16
d.SeekAbs(pos)
d.FieldU16("HEAP_HASNULL", common.Mask{Mask: HEAP_HASNULL})
d.SeekAbs(pos)
d.FieldU16("HEAP_HASVARWIDTH", common.Mask{Mask: HEAP_HASVARWIDTH})
d.SeekAbs(pos)
d.FieldU16("HEAP_HASEXTERNAL", common.Mask{Mask: HEAP_HASEXTERNAL})
d.SeekAbs(pos)
d.FieldU16("HEAP_HASOID_OLD", common.Mask{Mask: HEAP_HASOID_OLD})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_KEYSHR_LOCK", common.Mask{Mask: HEAP_XMAX_KEYSHR_LOCK})
d.SeekAbs(pos)
d.FieldU16("HEAP_COMBOCID", common.Mask{Mask: HEAP_COMBOCID})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_EXCL_LOCK", common.Mask{Mask: HEAP_XMAX_EXCL_LOCK})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_LOCK_ONLY", common.Mask{Mask: HEAP_XMAX_LOCK_ONLY})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_SHR_LOCK", common.Mask{Mask: HEAP_XMAX_SHR_LOCK})
d.SeekAbs(pos)
d.FieldU16("HEAP_LOCK_MASK", common.Mask{Mask: HEAP_LOCK_MASK})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMIN_COMMITTED", common.Mask{Mask: HEAP_XMIN_COMMITTED})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMIN_INVALID", common.Mask{Mask: HEAP_XMIN_INVALID})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMIN_FROZEN", common.Mask{Mask: HEAP_XMIN_FROZEN})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_COMMITTED", common.Mask{Mask: HEAP_XMAX_COMMITTED})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_INVALID", common.Mask{Mask: HEAP_XMAX_INVALID})
d.SeekAbs(pos)
d.FieldU16("HEAP_XMAX_IS_MULTI", common.Mask{Mask: HEAP_XMAX_IS_MULTI})
d.SeekAbs(pos)
d.FieldU16("HEAP_UPDATED", common.Mask{Mask: HEAP_UPDATED})
d.SeekAbs(pos)
d.FieldU16("HEAP_MOVED_OFF", common.Mask{Mask: HEAP_MOVED_OFF})
d.SeekAbs(pos)
d.FieldU16("HEAP_MOVED_IN", common.Mask{Mask: HEAP_MOVED_IN})
d.SeekAbs(pos)
d.FieldU16("HEAP_MOVED", common.Mask{Mask: HEAP_MOVED})
}

/* 0 | 12 */ // union {
/* 12 */ // HeapTupleFields t_heap;
/* 12 */ // DatumTupleFields t_datum;
Expand Down

0 comments on commit 3c6ea87

Please sign in to comment.