+
diff --git a/format/all/all.fqtest b/format/all/all.fqtest
index 068d8f7e2..0598879ec 100644
--- a/format/all/all.fqtest
+++ b/format/all/all.fqtest
@@ -126,6 +126,9 @@ ogg_page OGG page
opus_packet Opus packet
pcap PCAP packet capture
pcapng PCAPNG packet capture
+pg_btree PostgreSQL btree index file
+pg_control PostgreSQL control file
+pg_heap PostgreSQL heap file
png Portable Network Graphics file
prores_frame Apple ProRes frame
protobuf Protobuf
diff --git a/format/all/all.go b/format/all/all.go
index 2295b75bc..c68a1577b 100644
--- a/format/all/all.go
+++ b/format/all/all.go
@@ -40,6 +40,7 @@ import (
_ "github.com/wader/fq/format/opus"
_ "github.com/wader/fq/format/pcap"
_ "github.com/wader/fq/format/png"
+ _ "github.com/wader/fq/format/postgres"
_ "github.com/wader/fq/format/prores"
_ "github.com/wader/fq/format/protobuf"
_ "github.com/wader/fq/format/riff"
diff --git a/format/format.go b/format/format.go
index 8c921c53a..fab1351b7 100644
--- a/format/format.go
+++ b/format/format.go
@@ -112,6 +112,9 @@ var (
Opus_Packet = &decode.Group{Name: "opus_packet"}
PCAP = &decode.Group{Name: "pcap"}
PCAPNG = &decode.Group{Name: "pcapng"}
+ Pg_BTree = &decode.Group{Name: "pg_btree"}
+ Pg_Control = &decode.Group{Name: "pg_control"}
+ Pg_Heap = &decode.Group{Name: "pg_heap"}
PNG = &decode.Group{Name: "png"}
Prores_Frame = &decode.Group{Name: "prores_frame"}
Protobuf = &decode.Group{Name: "protobuf"}
@@ -339,3 +342,17 @@ type Bitcoin_Block_In struct {
type TLS_In struct {
Keylog string `doc:"NSS Key Log content"`
}
+
+type Pg_Control_In struct {
+ Flavour string `doc:"PostgreSQL flavour: postgres14, pgproee14.., postgres10"`
+}
+
+type Pg_Heap_In struct {
+ Flavour string `doc:"PostgreSQL flavour: postgres14, pgproee14.., postgres10"`
+ Page int `doc:"First page number in file, default is 0"`
+ Segment int `doc:"Segment file number (16790.1 is 1), default is 0"`
+}
+
+type Pg_BTree_In struct {
+ Page int `doc:"First page number in file, default is 0"`
+}
diff --git a/format/postgres/.gitignore b/format/postgres/.gitignore
new file mode 100644
index 000000000..cd0d0072a
--- /dev/null
+++ b/format/postgres/.gitignore
@@ -0,0 +1 @@
+*.sh
\ No newline at end of file
diff --git a/format/postgres/common/checksum.go b/format/postgres/common/checksum.go
new file mode 100644
index 000000000..243263681
--- /dev/null
+++ b/format/postgres/common/checksum.go
@@ -0,0 +1,68 @@
+package common
+
+import "encoding/binary"
+
+const (
+ nSums = 32
+ fnvPrime = 16777619
+ nSumsSize = 4 * nSums
+ mainBlockLen = PageSize / nSumsSize
+ RelSegSize = 131072
+)
+
+var (
+ checksumBaseOffsets = [nSums]uint32{
+ 0x5B1F36E9, 0xB8525960, 0x02AB50AA, 0x1DE66D2A,
+ 0x79FF467A, 0x9BB9F8A3, 0x217E7CD2, 0x83E13D2C,
+ 0xF8D4474F, 0xE39EB970, 0x42C6AE16, 0x993216FA,
+ 0x7B093B5D, 0x98DAFF3C, 0xF718902A, 0x0B1C9CDB,
+ 0xE58F764B, 0x187636BC, 0x5D7B3BB1, 0xE73DE7DE,
+ 0x92BEC979, 0xCCA6C0B2, 0x304A0979, 0x85AA43D4,
+ 0x783125BB, 0x6CA8EAA2, 0xE407EAC6, 0x4B5CFC3E,
+ 0x9FBF8C76, 0x15CA20BE, 0xF2CA9FD3, 0x959BD756,
+ }
+)
+
+func checksumComp(checksum uint32, value uint32) uint32 {
+ tmp := checksum ^ value
+ checksum = tmp*fnvPrime ^ (tmp >> 17)
+ return checksum
+}
+
+func pgChecksumBlock(page []byte) uint32 {
+ sums := [nSums]uint32{0}
+ for i := 0; i < nSums; i++ {
+ sums[i] = checksumBaseOffsets[i]
+ }
+ result := uint32(0)
+
+ for i := 0; i < mainBlockLen; i++ {
+ for j := 0; j < nSums; j++ {
+ v2 := binary.LittleEndian.Uint32(page[i*nSumsSize+j*4:])
+ sums[j] = checksumComp(sums[j], v2)
+ }
+ }
+
+ for i := 0; i < 2; i++ {
+ for j := 0; j < nSums; j++ {
+ sums[j] = checksumComp(sums[j], 0)
+ }
+ }
+
+ for i := 0; i < nSums; i++ {
+ result = result ^ sums[i]
+ }
+
+ return result
+}
+
+func CheckSumBlock(page []byte, blockNumber uint32) uint16 {
+ // set pd_checksum to zero
+ page[8] = 0
+ page[9] = 0
+
+ sum := pgChecksumBlock(page)
+ sum1 := sum ^ blockNumber
+ sum2 := uint16((sum1 % 65535) + 1)
+ return sum2
+}
diff --git a/format/postgres/common/pg_btree/postgres/pg_btree.go b/format/postgres/common/pg_btree/postgres/pg_btree.go
new file mode 100644
index 000000000..0c03f38a8
--- /dev/null
+++ b/format/postgres/common/pg_btree/postgres/pg_btree.go
@@ -0,0 +1,244 @@
+package postgres
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/format/postgres/common/pg_heap/postgres"
+ "github.com/wader/fq/pkg/decode"
+)
+
+const (
+ BTREE_MAGIC = 0x053162
+)
+
+const (
+ INDEX_SIZE_MASK = 0x1FFF
+ INDEX_VAR_MASK = 0x4000
+ INDEX_NULL_MASK = 0x8000
+)
+
+const (
+ IndexTupleDataSize = 8
+)
+
+// struct BTMetaPageData {
+/* 0 | 4 */ // uint32 btm_magic
+/* 4 | 4 */ // uint32 btm_version
+/* 8 | 4 */ // BlockNumber btm_root
+/* 12 | 4 */ // uint32 btm_level
+/* 16 | 4 */ // BlockNumber btm_fastroot
+/* 20 | 4 */ // uint32 btm_fastlevel
+/* 24 | 4 */ // uint32 btm_last_cleanup_num_delpages
+/* XXX 4-byte hole */
+/* 32 | 8 */ // float8 btm_last_cleanup_num_heap_tuples
+/* 40 | 1 */ // _Bool btm_allequalimage
+/* XXX 7-byte padding */
+//
+/* total size (bytes): 48 */
+
+// struct BTPageOpaqueData {
+/* 0 | 4 */ // BlockNumber btpo_prev;
+/* 4 | 4 */ // BlockNumber btpo_next;
+/* 8 | 4 */ // uint32 btpo_level;
+/* 12 | 2 */ // uint16 btpo_flags;
+/* 14 | 2 */ // BTCycleId btpo_cycleid;
+//
+/* total size (bytes): 16 */
+
+// struct IndexTupleData {
+/* 0 | 6 */ // ItemPointerData t_tid;
+/* 6 | 2 */ // unsigned short t_info;
+//
+// IndexTupleData *IndexTuple;
+/* total size (bytes): 8 */
+
+func DecodePgBTree(d *decode.D, pageNr int) {
+ var prevPage *postgres.HeapPage
+
+ for i := pageNr; ; i++ {
+ page := &postgres.HeapPage{}
+ if prevPage != nil {
+ // use prev page
+ page.BytesPosBegin = prevPage.BytesPosEnd
+ }
+ page.BytesPosEnd = int64(common.TypeAlign(common.PageSize, uint64(page.BytesPosBegin)+1))
+ prevPage = page
+
+ pos0 := page.BytesPosBegin * 8
+ d.SeekAbs(pos0)
+
+ if d.End() {
+ return
+ }
+
+ if i == 0 {
+ // first page contains meta information
+ d.FieldStruct("page", func(d *decode.D) {
+ decodeBTreeMetaPage(page, d)
+ })
+ continue
+ }
+
+ d.FieldStruct("page", func(d *decode.D) {
+ decodeBTreePage(page, d)
+ })
+ }
+}
+
+func decodeBTreeMetaPage(page *postgres.HeapPage, d *decode.D) {
+
+ d.FieldStruct("page_header", func(d *decode.D) {
+ postgres.DecodePageHeader(page, d)
+ })
+ d.FieldStruct("meta_page_data", func(d *decode.D) {
+ decodeBTMetaPageData(d)
+ })
+
+ pos0 := d.Pos()
+ pos1 := page.BytesPosSpecial * 8
+ d.FieldRawLen("unused0", pos1-pos0)
+ d.FieldStruct("page_opaque_data", func(d *decode.D) {
+ decodeBTPageOpaqueData(d)
+ })
+ pos2 := d.Pos()
+ bytesPos2 := pos2 / 8
+ if bytesPos2 != page.BytesPosEnd {
+ d.Fatalf("invalid pos after read page_opaque_data on meta page")
+ }
+}
+
+func decodeBTMetaPageData(d *decode.D) {
+ /* 0 | 4 */ // uint32 btm_magic
+ /* 4 | 4 */ // uint32 btm_version
+ /* 8 | 4 */ // BlockNumber btm_root
+ /* 12 | 4 */ // uint32 btm_level
+ /* 16 | 4 */ // BlockNumber btm_fastroot
+ /* 20 | 4 */ // uint32 btm_fastlevel
+ /* 24 | 4 */ // uint32 btm_last_cleanup_num_delpages
+ /* XXX 4-byte hole */
+ /* 32 | 8 */ // float8 btm_last_cleanup_num_heap_tuples
+ /* 40 | 1 */ // _Bool btm_allequalimage
+ /* XXX 7-byte padding */
+
+ btmMagic := d.FieldU32("btm_magic")
+ d.FieldU32("btm_version")
+ d.FieldU32("btm_root")
+ d.FieldU32("btm_level")
+ d.FieldU32("btm_fastroot")
+ d.FieldU32("btm_fastlevel")
+ d.FieldU32("btm_last_cleanup_num_delpages")
+ d.FieldU32("hole0")
+ d.FieldF64("btm_last_cleanup_num_heap_tuples")
+ d.FieldU8("btm_allequalimage")
+ d.FieldU56("padding0")
+
+ if btmMagic != BTREE_MAGIC {
+ d.Fatalf("invalid btmMagic = %X, must be %X", btmMagic, BTREE_MAGIC)
+ }
+}
+
+// struct BTPageOpaqueData {
+/* 0 | 4 */ // BlockNumber btpo_prev;
+/* 4 | 4 */ // BlockNumber btpo_next;
+/* 8 | 4 */ // uint32 btpo_level;
+/* 12 | 2 */ // uint16 btpo_flags;
+/* 14 | 2 */ // BTCycleId btpo_cycleid;
+func decodeBTPageOpaqueData(d *decode.D) {
+ d.FieldU32("btpo_prev")
+ d.FieldU32("btpo_next")
+ d.FieldU32("btpo_level")
+
+ // bits in uint16 LE: 7 - 0 15 - 8
+ d.FieldStruct("btpo_flags", func(d *decode.D) {
+ d.FieldBool("is_incomplete_split")
+ d.FieldBool("has_garbage")
+ d.FieldBool("split_end")
+ isHalfDead := d.FieldBool("is_half_dead")
+ d.FieldBool("is_meta")
+ isDeleted := d.FieldBool("is_deleted")
+ d.FieldBool("is_root")
+ d.FieldBool("is_leaf")
+
+ d.FieldU7("skip1")
+ d.FieldBool("has_full_xid")
+
+ d.FieldValueBool("is_ignore", isDeleted || isHalfDead)
+ })
+
+ d.FieldU16("btpo_cycleid")
+}
+
+func decodeBTreePage(page *postgres.HeapPage, d *decode.D) {
+ d.FieldStruct("page_header", func(d *decode.D) {
+ postgres.DecodePageHeader(page, d)
+ })
+
+ pos0 := d.Pos()
+ pos1 := page.BytesPosSpecial * 8
+ d.SeekAbs(pos1)
+ d.FieldStruct("page_opaque_data", func(d *decode.D) {
+ decodeBTPageOpaqueData(d)
+ })
+ pos2 := d.Pos()
+ bytesPos2 := pos2 / 8
+ if bytesPos2 != page.BytesPosEnd {
+ d.Fatalf("invalid pos after read page_opaque_data on btree page")
+ }
+
+ d.SeekAbs(pos0)
+ postgres.DecodeItemIds(page, d)
+
+ d.FieldArray("tuples", func(d *decode.D) {
+ decodeIndexTuples(page, d)
+ })
+}
+
+func decodeIndexTuples(page *postgres.HeapPage, d *decode.D) {
+
+ for i := 0; i < len(page.ItemIds); i++ {
+ id := page.ItemIds[i]
+ if id.Off == 0 || id.Len == 0 {
+ continue
+ }
+ if id.Flags != common.LP_NORMAL {
+ continue
+ }
+
+ pos := (page.BytesPosBegin * 8) + int64(id.Off)*8
+
+ // seek to tuple with ItemID offset
+ d.SeekAbs(pos)
+ d.FieldStruct("tuple", func(d *decode.D) {
+
+ // IndexTupleData
+ d.FieldStruct("index_tuple_data", func(d *decode.D) {
+ // struct IndexTupleData {
+ /* 0 | 6 */ // ItemPointerData t_tid;
+ /* 6 | 2 */ // unsigned short t_info;
+ //
+ d.FieldStruct("t_tid", func(d *decode.D) {
+ /* 0 | 4 */ // BlockIdData ip_blkid;
+ /* 4 | 2 */ // OffsetNumber ip_posid;
+ d.FieldU32("ip_blkid")
+ d.FieldU16("ip_posid")
+ })
+ tInfo := d.FieldU16("t_info")
+
+ size := tInfo & INDEX_SIZE_MASK
+ hasNulls := (tInfo & INDEX_NULL_MASK) != 0
+ hasVarWidths := (tInfo & INDEX_VAR_MASK) != 0
+ d.FieldStruct("flags", func(d *decode.D) {
+ d.FieldValueBool("has_nulls", hasNulls)
+ d.FieldValueBool("has_var_widths", hasVarWidths)
+ })
+ d.FieldValueUint("size", size)
+ if size < IndexTupleDataSize {
+ d.Fatalf("invalid size of tuple = %d", size)
+ }
+ dataSize := size - IndexTupleDataSize
+ d.FieldRawLen("data", int64(dataSize*8))
+ })
+
+ })
+
+ }
+}
diff --git a/format/postgres/common/pg_control.go b/format/postgres/common/pg_control.go
new file mode 100644
index 000000000..707a08b02
--- /dev/null
+++ b/format/postgres/common/pg_control.go
@@ -0,0 +1,146 @@
+package common
+
+import (
+ "fmt"
+
+ "github.com/wader/fq/pkg/scalar"
+
+ "time"
+)
+
+// typedef enum DBState
+//
+// {
+// DB_STARTUP = 0,
+// DB_SHUTDOWNED,
+// DB_SHUTDOWNED_IN_RECOVERY,
+// DB_SHUTDOWNING,
+// DB_IN_CRASH_RECOVERY,
+// DB_IN_ARCHIVE_RECOVERY,
+// DB_IN_PRODUCTION
+// } DBState;
+var DBState = scalar.UintMap{
+ 0: {Sym: "DB_STARTUP"},
+ 1: {Sym: "DB_SHUTDOWNED"},
+ 2: {Sym: "DB_SHUTDOWNED_IN_RECOVERY"},
+ 3: {Sym: "DB_SHUTDOWNING"},
+ 4: {Sym: "DB_IN_CRASH_RECOVERY"},
+ 5: {Sym: "DB_IN_ARCHIVE_RECOVERY"},
+ 6: {Sym: "DB_IN_PRODUCTION"},
+}
+
+// typedef enum WalLevel
+//
+// {
+// WAL_LEVEL_MINIMAL = 0,
+// WAL_LEVEL_REPLICA,
+// WAL_LEVEL_LOGICAL
+// } WalLevel;
+var WalLevel = scalar.SintMap{
+ 0: {Sym: "WAL_LEVEL_MINIMAL"},
+ 1: {Sym: "WAL_LEVEL_REPLICA"},
+ 2: {Sym: "WAL_LEVEL_LOGICAL"},
+}
+
+type icuVersionMapper struct{}
+
+func (m icuVersionMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ s.ScalarActual()
+ a := s.Actual
+ major := a & 0xff
+ minor := (a >> 8) & 0xff
+ v1 := (a >> 16) & 0xff
+ v2 := (a >> 24) & 0xff
+ s.Sym = fmt.Sprintf("%d.%d.%d.%d", major, minor, v1, v2)
+ return s, nil
+}
+
+var IcuVersionMapper = icuVersionMapper{}
+
+type xLogRecPtrMapper struct{}
+
+func (m xLogRecPtrMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ v := s.Actual
+ s.Sym = fmt.Sprintf("%X/%X", v>>32, uint32(v))
+ return s, nil
+}
+
+var XLogRecPtrMapper = xLogRecPtrMapper{}
+var LocPtrMapper = xLogRecPtrMapper{}
+
+type nextFullXidMapper struct{}
+
+func (m nextFullXidMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ v := s.Actual
+ s.Sym = fmt.Sprintf("%d:%d", v>>32, uint32(v))
+ return s, nil
+}
+
+var NextFullXidMapper = nextFullXidMapper{}
+
+type timeMapper struct{}
+
+func (m timeMapper) MapSint(s scalar.Sint) (scalar.Sint, error) {
+ ut := s.Actual
+ t := time.Unix(ut, 0)
+ s.Sym = t.UTC().Format(time.RFC1123)
+ return s, nil
+}
+
+var TimeMapper = timeMapper{}
+
+// typedef enum
+//
+// {
+// PG_UNKNOWN = 0xFFFF,
+// PG_ORIGINAL = 0,
+// PGPRO_STANDARD = ('P'<<8|'P'),
+// PGPRO_ENTERPRISE = ('P'<<8|'E'),
+// } PgEdition;
+const (
+ PG_UNKNOWN = 0xFFFF
+ PG_ORIGINAL = 0
+ PGPRO_STANDARD = (uint32('P') << 8) | uint32('P')
+ PGPRO_ENTERPRISE = (uint32('P') << 8) | uint32('E')
+
+ PG_UNKNOWN_STR = "(unknown edition)"
+ PG_ORIGINAL_STR = "PostgreSQL"
+ PGPRO_STANDARD_STR = "Postgres Pro Standard"
+ PGPRO_ENTERPRISE_STR = "Postgres Pro Enterprise"
+)
+
+type versionMapper struct{}
+
+func (m versionMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ v := s.Actual
+ v1, v2 := ParsePgProVersion(uint32(v))
+ switch v1 {
+ case PG_UNKNOWN:
+ s.Sym = fmt.Sprintf("%s %d", PG_UNKNOWN_STR, v2)
+ case PG_ORIGINAL:
+ s.Sym = fmt.Sprintf("%s %d", PG_ORIGINAL_STR, v2)
+ case PGPRO_STANDARD:
+ s.Sym = fmt.Sprintf("%s %d", PGPRO_STANDARD_STR, v2)
+ case PGPRO_ENTERPRISE:
+ s.Sym = fmt.Sprintf("%s %d", PGPRO_ENTERPRISE_STR, v2)
+ }
+ return s, nil
+}
+
+var VersionMapper = versionMapper{}
+
+func ParsePgProVersion(v uint32) (pgProVersion uint32, oriVer uint32) {
+ pgProVersion = v >> 16
+ oriVer = v & 0xffff
+ return
+}
+
+type hexMapper struct{}
+
+func (m hexMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ v := s.Actual
+ s.Sym = fmt.Sprintf("%X", v)
+ return s, nil
+}
+
+var HexMapper = hexMapper{}
diff --git a/format/postgres/common/pg_heap.go b/format/postgres/common/pg_heap.go
new file mode 100644
index 000000000..584635d30
--- /dev/null
+++ b/format/postgres/common/pg_heap.go
@@ -0,0 +1,48 @@
+package common
+
+import (
+ "github.com/wader/fq/pkg/scalar"
+)
+
+const (
+ PageSize = 8192
+ FirstNormalTransactionID = 3
+
+ LP_UNUSED = 0 /* unused (should always have lp_len=0) */
+ LP_NORMAL = 1 /* used (should always have lp_len>0) */
+ LP_REDIRECT = 2 /* HOT redirect (should have lp_len=0) */
+ LP_DEAD = 3
+)
+
+func TransactionIDIsNormal(xid uint64) bool {
+ return xid >= FirstNormalTransactionID
+}
+
+type lpFlagsMapper struct{}
+
+func (m lpFlagsMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ switch s.Actual {
+ case LP_UNUSED:
+ s.Sym = "LP_UNUSED"
+ case LP_NORMAL:
+ s.Sym = "LP_NORMAL"
+ case LP_REDIRECT:
+ s.Sym = "LP_REDIRECT"
+ case LP_DEAD:
+ s.Sym = "LP_DEAD"
+ }
+ return s, nil
+}
+
+var LpFlagsMapper = lpFlagsMapper{}
+
+type Mask struct {
+ Mask uint64
+}
+
+func (m Mask) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ m1 := s.Actual
+ v := IsMaskSet(m1, m.Mask)
+ s.Actual = v
+ return s, nil
+}
diff --git a/format/postgres/common/pg_heap/pgproee/decode.go b/format/postgres/common/pg_heap/pgproee/decode.go
new file mode 100644
index 000000000..312c74c6b
--- /dev/null
+++ b/format/postgres/common/pg_heap/pgproee/decode.go
@@ -0,0 +1,16 @@
+package pgproee
+
+import (
+ "github.com/wader/fq/format"
+ "github.com/wader/fq/format/postgres/common/pg_heap/postgres"
+ "github.com/wader/fq/pkg/decode"
+)
+
+func DecodeHeap(d *decode.D, args format.Pg_Heap_In) any {
+ heap := &postgres.Heap{
+ Args: args,
+ DecodePageHeaderData: DecodePageHeaderData,
+ DecodePageSpecial: DecodePageSpecial,
+ }
+ return postgres.Decode(heap, d)
+}
diff --git a/format/postgres/common/pg_heap/pgproee/pg_heap.go b/format/postgres/common/pg_heap/pgproee/pg_heap.go
new file mode 100644
index 000000000..0b4d54be1
--- /dev/null
+++ b/format/postgres/common/pg_heap/pgproee/pg_heap.go
@@ -0,0 +1,57 @@
+package pgproee
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/format/postgres/common/pg_heap/postgres"
+ "github.com/wader/fq/pkg/decode"
+)
+
+// type = struct PageHeaderData {
+/* 0 | 8 */ // PageXLogRecPtr pd_lsn;
+/* 8 | 2 */ // uint16 pd_checksum;
+/* 10 | 2 */ // uint16 pd_flags;
+/* 12 | 2 */ // LocationIndex pd_lower;
+/* 14 | 2 */ // LocationIndex pd_upper;
+/* 16 | 2 */ // LocationIndex pd_special;
+/* 18 | 2 */ // uint16 pd_pagesize_version;
+/* 20 | 0 */ // ItemIdData pd_linp[];
+func DecodePageHeaderData(page *postgres.HeapPage, d *decode.D) {
+ d.FieldStruct("pd_lsn", func(d *decode.D) {
+ /* 0 | 4 */ // uint32 xlogid;
+ /* 4 | 4 */ // uint32 xrecoff;
+ d.FieldU32("xlogid", common.HexMapper)
+ d.FieldU32("xrecoff", common.HexMapper)
+ })
+ page.PdChecksum = uint16(d.FieldU16("pd_checksum"))
+ d.FieldU16("pd_flags")
+ page.PdLower = uint16(d.FieldU16("pd_lower"))
+ page.PdUpper = uint16(d.FieldU16("pd_upper"))
+ page.PdSpecial = uint16(d.FieldU16("pd_special"))
+ page.PdPageSizeVersion = uint16(d.FieldU16("pd_pagesize_version"))
+
+ page.BytesPosSpecial = page.BytesPosBegin + int64(page.PdSpecial)
+ page.PosItemsEnd = (page.BytesPosBegin * 8) + int64(page.PdLower*8)
+ page.PosFreeSpaceEnd = (page.BytesPosBegin * 8) + int64(page.PdUpper*8)
+}
+
+// type = struct HeapPageSpecialData {
+/* 0 | 8 */ // TransactionId pd_xid_base;
+/* 8 | 8 */ // TransactionId pd_multi_base;
+/* 16 | 4 */ // ShortTransactionId pd_prune_xid;
+/* 20 | 4 */ // uint32 pd_magic;
+//
+/* total size (bytes): 24 */
+func DecodePageSpecial(heap *postgres.Heap, d *decode.D) {
+ page := heap.Page
+ special := heap.Special
+
+ specialPos := page.BytesPosSpecial * 8
+ d.SeekAbs(specialPos)
+
+ d.FieldStruct("special_data", func(d *decode.D) {
+ special.PdXidBase = d.FieldU64("pd_xid_base")
+ special.PdMultiBase = d.FieldU64("pd_multi_base")
+ special.PdPruneXid = d.FieldU32("pd_prune_xid")
+ special.PdMagic = d.FieldU32("pd_magic")
+ })
+}
diff --git a/format/postgres/common/pg_heap/postgres/decode.go b/format/postgres/common/pg_heap/postgres/decode.go
new file mode 100644
index 000000000..f16ba0d62
--- /dev/null
+++ b/format/postgres/common/pg_heap/postgres/decode.go
@@ -0,0 +1,14 @@
+package postgres
+
+import (
+ "github.com/wader/fq/format"
+ "github.com/wader/fq/pkg/decode"
+)
+
+func DecodeHeap(d *decode.D, args format.Pg_Heap_In) any {
+ heap := &Heap{
+ Args: args,
+ DecodePageHeaderData: DecodePageHeader,
+ }
+ return Decode(heap, d)
+}
diff --git a/format/postgres/common/pg_heap/postgres/heap_page.go b/format/postgres/common/pg_heap/postgres/heap_page.go
new file mode 100644
index 000000000..db1ddae61
--- /dev/null
+++ b/format/postgres/common/pg_heap/postgres/heap_page.go
@@ -0,0 +1,102 @@
+package postgres
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// HeapPage used in tables, indexes...
+
+// type = struct ItemIdData {
+/* 0: 0 | 4 */ // unsigned int lp_off: 15
+/* 1: 7 | 4 */ // unsigned int lp_flags: 2
+/* 2: 1 | 4 */ // unsigned int lp_len: 15
+//
+/* total size (bytes): 4 */
+
+type ItemID struct {
+ Off uint32 // unsigned int lp_off: 15
+ Flags uint32 // unsigned int lp_flags: 2
+ Len uint32 // unsigned int lp_len: 15
+}
+
+type HeapPage struct {
+ // PageHeaderData fields
+ PdChecksum uint16
+ PdLower uint16
+ PdUpper uint16
+ PdSpecial uint16
+ PdPageSizeVersion uint16
+
+ // calculated bytes positions
+ BytesPosBegin int64 // bytes pos of page's beginning
+ BytesPosEnd int64 // bytes pos of page's ending
+ BytesPosSpecial int64 // bytes pos of page's special
+
+ // calculated bits positions
+ PosItemsEnd int64 // bits pos of items end
+ PosFreeSpaceEnd int64 // bits pos free space end
+
+ // parsed items positions
+ ItemIds []ItemID
+}
+
+func DecodePageHeader(page *HeapPage, d *decode.D) {
+ d.FieldStruct("pd_lsn", func(d *decode.D) {
+ /* 0 | 4 */ // uint32 xlogid;
+ /* 4 | 4 */ // uint32 xrecoff;
+ d.FieldU32("xlogid", common.HexMapper)
+ d.FieldU32("xrecoff", common.HexMapper)
+ })
+ page.PdChecksum = uint16(d.FieldU16("pd_checksum"))
+ d.FieldU16("pd_flags")
+ page.PdLower = uint16(d.FieldU16("pd_lower"))
+ page.PdUpper = uint16(d.FieldU16("pd_upper"))
+ page.PdSpecial = uint16(d.FieldU16("pd_special"))
+ page.PdPageSizeVersion = uint16(d.FieldU16("pd_pagesize_version"))
+ d.FieldU32("pd_prune_xid")
+
+ page.BytesPosSpecial = page.BytesPosBegin + int64(page.PdSpecial)
+ page.PosItemsEnd = (page.BytesPosBegin * 8) + int64(page.PdLower*8)
+ page.PosFreeSpaceEnd = (page.BytesPosBegin * 8) + int64(page.PdUpper*8)
+}
+
+func DecodeItemIds(page *HeapPage, d *decode.D) {
+ d.FieldArray("pd_linp", func(d *decode.D) {
+ decodeItemIdsInternal(page, d)
+ })
+
+ pos0 := d.Pos()
+ if pos0 > page.PosFreeSpaceEnd {
+ d.Fatalf("items overflows free space")
+ }
+ freeSpaceLen := page.PosFreeSpaceEnd - pos0
+ d.FieldRawLen("free_space", freeSpaceLen, scalar.RawHex)
+}
+
+func decodeItemIdsInternal(page *HeapPage, d *decode.D) {
+ for {
+ checkPos := d.Pos()
+ if checkPos >= page.PosItemsEnd {
+ break
+ }
+ /* 0: 0 | 4 */ // unsigned int lp_off: 15
+ /* 1: 7 | 4 */ // unsigned int lp_flags: 2
+ /* 2: 1 | 4 */ // unsigned int lp_len: 15
+ d.FieldStruct("item_id", func(d *decode.D) {
+ itemIDData := d.FieldU32("item_id_data")
+
+ itemID := ItemID{}
+ itemID.Off = uint32(itemIDData & 0x7fff)
+ itemID.Flags = uint32((itemIDData >> 15) & 0x3)
+ itemID.Len = uint32((itemIDData >> 17) & 0x7fff)
+
+ d.FieldValueUint("lp_off", uint64(itemID.Off))
+ d.FieldValueUint("lp_flags", uint64(itemID.Flags), common.LpFlagsMapper)
+ d.FieldValueUint("lp_len", uint64(itemID.Len))
+
+ page.ItemIds = append(page.ItemIds, itemID)
+ })
+ } // for pd_linp
+}
diff --git a/format/postgres/common/pg_heap/postgres/pg_heap.go b/format/postgres/common/pg_heap/postgres/pg_heap.go
new file mode 100644
index 000000000..dd301e62f
--- /dev/null
+++ b/format/postgres/common/pg_heap/postgres/pg_heap.go
@@ -0,0 +1,413 @@
+package postgres
+
+import (
+ "fmt"
+
+ "github.com/wader/fq/format"
+ "github.com/wader/fq/format/postgres/common"
+
+ "github.com/wader/fq/pkg/decode"
+ "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;
+/* 10 | 2 */ // uint16 pd_flags;
+/* 12 | 2 */ // LocationIndex pd_lower;
+/* 14 | 2 */ // LocationIndex pd_upper;
+/* 16 | 2 */ // LocationIndex pd_special;
+/* 18 | 2 */ // uint16 PdPagesizeVersion;
+/* 20 | 4 */ // TransactionId pd_prune_xid;
+/* 24 | 0 */ // ItemIdData pd_linp[];
+//
+/* total size (bytes): 24 */
+
+// type = struct PageXLogRecPtr {
+/* 0 | 4 */ // uint32 xlogid;
+/* 4 | 4 */ // uint32 xrecoff;
+
+/* total size (bytes): 8 */
+
+// typedef uint16 LocationIndex;
+// #define SizeOfPageHeaderData (offsetof(PageHeaderData, pd_linp))
+
+// type = struct HeapTupleHeaderData {
+/* 0 | 12 */ // union {
+/* 12 */ // HeapTupleFields t_heap;
+/* 12 */ // DatumTupleFields t_datum;
+//
+/* total size (bytes): 12 */
+/* } t_choice; //
+/* 12 | 6 */ // ItemPointerData t_ctid;
+/* 18 | 2 */ // uint16 t_infomask2;
+/* 20 | 2 */ // uint16 t_infomask;
+/* 22 | 1 */ // uint8 t_hoff;
+/* 23 | 0 */ // bits8 t_bits[];
+/* XXX 1-byte padding */
+//
+/* total size (bytes): 24 */
+const SizeOfHeapTupleHeaderData = 24
+
+// type = struct HeapTupleFields {
+/* 0 | 4 */ // TransactionId t_xmin;
+/* 4 | 4 */ // TransactionId t_xmax;
+/* 8 | 4 */ // union {
+/* 4 */ // CommandId t_cid;
+/* 4 */ // TransactionId t_xvac;
+// } t_field3;
+/* total size (bytes): 4 */
+//
+/* total size (bytes): 12 */
+
+// type = struct DatumTupleFields {
+/* 0 | 4 */ // int32 datum_len_;
+/* 4 | 4 */ // int32 datum_typmod;
+/* 8 | 4 */ // Oid datum_typeid;
+//
+/* total size (bytes): 12 */
+
+// type = struct ItemPointerData {
+/* 0 | 4 */ // BlockIdData ip_blkid;
+/* 4 | 2 */ // OffsetNumber ip_posid;
+//
+/* total size (bytes): 6 */
+
+type Heap struct {
+ Args format.Pg_Heap_In
+
+ // current Page
+ Page *HeapPage
+ // Page special data
+ Special *PageSpecial
+
+ // current tuple
+ Tuple *TupleD
+
+ DecodePageHeaderData func(page *HeapPage, d *decode.D)
+ DecodePageSpecial func(heap *Heap, d *decode.D)
+}
+
+type PageSpecial struct {
+ // pgproee
+ PdXidBase uint64 // 8 TransactionId pd_xid_base;
+ PdMultiBase uint64 // 8 TransactionId pd_multi_base;
+ PdPruneXid uint64 // 4 ShortTransactionId pd_prune_xid;
+ PdMagic uint64 // 4 uint32 pd_magic;
+}
+
+type TupleD struct {
+ IsMulti bool
+}
+
+func Decode(heap *Heap, d *decode.D) any {
+ decodeHeapPages(heap, d)
+ return nil
+}
+
+func decodeHeapPages(heap *Heap, d *decode.D) {
+ blockNumber := uint32(heap.Args.Page + heap.Args.Segment*common.RelSegSize)
+ count := int64(0)
+ for {
+ if d.End() {
+ return
+ }
+
+ d.FieldStruct("page", func(d *decode.D) {
+ decodeHeapPage(heap, d, blockNumber)
+ })
+ blockNumber++
+ count++
+
+ // end of Page
+ endLen := uint64(d.Pos() / 8)
+ pageEnd := int64(common.TypeAlign(common.PageSize, endLen))
+ pageEnd0 := count * common.PageSize
+ if pageEnd0 != pageEnd {
+ d.Errorf("invalid page %d end expected %d, actual %d, endLen %d\n", count-1, pageEnd0, pageEnd, endLen)
+ }
+ d.SeekAbs(pageEnd0 * 8)
+ }
+}
+
+func decodeHeapPage(heap *Heap, d *decode.D, blockNumber uint32) {
+ page := &HeapPage{}
+ if heap.Page != nil {
+ // use prev page
+ page.BytesPosBegin = heap.Page.BytesPosEnd
+ }
+ page.BytesPosEnd = int64(common.TypeAlign(common.PageSize, uint64(page.BytesPosBegin)+1))
+ heap.Page = page
+ heap.Special = &PageSpecial{}
+
+ checkSum := calcCheckSum(d, blockNumber)
+
+ d.FieldStruct("page_header", func(d *decode.D) {
+ heap.DecodePageHeaderData(page, d)
+
+ d.FieldValueUint("pd_checksum_check", uint64(checkSum))
+ sumEqual := page.PdChecksum == checkSum
+ d.FieldValueBool("pd_checksum_check_equal", sumEqual)
+ })
+
+ DecodeItemIds(page, d)
+
+ if uint64(page.PdSpecial) != common.PageSize && heap.DecodePageSpecial != nil {
+ heap.DecodePageSpecial(heap, d)
+ }
+
+ // Tuples
+ d.FieldArray("tuples", func(d *decode.D) {
+ decodeTuples(heap, d)
+ })
+}
+
+func calcCheckSum(d *decode.D, blockNumber uint32) uint16 {
+ pos0 := d.Pos()
+ pageBuffer := make([]byte, common.PageSize)
+ rdrPage := d.RawLen(int64(common.PageSize * 8))
+ _, err := rdrPage.ReadBits(pageBuffer, int64(common.PageSize*8))
+ if err != nil {
+ d.Fatalf("can't read page, err = %v", err)
+ }
+ sum2 := common.CheckSumBlock(pageBuffer, blockNumber)
+ d.SeekAbs(pos0)
+ return sum2
+}
+
+func decodeTuples(heap *Heap, d *decode.D) {
+ page := heap.Page
+ for i := 0; i < len(page.ItemIds); i++ {
+ id := page.ItemIds[i]
+ if id.Off == 0 || id.Len == 0 {
+ continue
+ }
+ if id.Flags != common.LP_NORMAL {
+ continue
+ }
+
+ pos := (page.BytesPosBegin * 8) + int64(id.Off)*8
+ if id.Len < SizeOfHeapTupleHeaderData {
+ d.Fatalf("item len = %d, is less than %d HeapTupleHeaderData", id.Len, SizeOfHeapTupleHeaderData)
+ }
+ tupleDataLen := id.Len - SizeOfHeapTupleHeaderData
+
+ // seek to tuple with ItemID offset
+ d.SeekAbs(pos)
+
+ // type = struct HeapTupleHeaderData {
+ /* 0 | 12 */ // union {
+ /* 12 */ // HeapTupleFields t_heap;
+ /* 12 */ // DatumTupleFields t_datum;
+ // } t_choice;
+ /* total size (bytes): 12 */
+ //
+ /* 12 | 6 */ // ItemPointerData t_ctid;
+ /* 18 | 2 */ // uint16 t_infomask2;
+ /* 20 | 2 */ // uint16 t_infomask;
+ /* 22 | 1 */ // uint8 t_hoff;
+ /* 23 | 0 */ // bits8 t_bits[];
+ /* XXX 1-byte padding */
+ //
+ /* total size (bytes): 24 */
+ d.FieldStruct("tuple", func(d *decode.D) {
+ heap.Tuple = &TupleD{}
+
+ d.FieldStruct("header", func(d *decode.D) {
+
+ pos1 := d.Pos()
+ // we need infomask before t_xmin, t_xmax
+ d.SeekAbs(pos1 + 18*8)
+ infomask2 := d.FieldU16("t_infomask2")
+ d.FieldStruct("infomask2", func(d *decode.D) {
+ decodeInfomask2(d, infomask2)
+ })
+ infomask := d.FieldU16("t_infomask")
+ d.FieldStruct("infomask", func(d *decode.D) {
+ decodeInfomask(heap, d, infomask)
+ })
+
+ // restore pos and continue
+ d.SeekAbs(pos1)
+ d.FieldStruct("t_choice", func(d *decode.D) {
+ decodeTChoice(heap, d)
+ })
+ d.FieldStruct("t_ctid", func(d *decode.D) {
+ /* 0 | 4 */ // BlockIdData ip_blkid;
+ /* 4 | 2 */ // OffsetNumber ip_posid;
+ d.FieldU32("ip_blkid")
+ d.FieldU16("ip_posid")
+ }) // ItemPointerData t_ctid
+
+ /* 18 | 2 */ // uint16 t_infomask2;
+ /* 20 | 2 */ // uint16 t_infomask;
+ /* 22 | 1 */ // uint8 t_hoff;
+ /* 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)
+ // already done
+ d.SeekRel(32)
+
+ d.FieldU8("t_hoff")
+ d.FieldU8("padding0")
+ }) // HeapTupleHeaderData
+
+ d.FieldRawLen("data", int64(tupleDataLen*8), scalar.RawHex)
+
+ // data alignment
+ pos2 := uint64(d.Pos() / 8)
+ pos1Aligned := common.TypeAlign8(pos2)
+ if pos2 != pos1Aligned {
+ alignedLen := (pos1Aligned - pos2) * 8
+ d.FieldRawLen("padding1", int64(alignedLen), scalar.RawHex)
+ }
+ pos3 := uint64(d.Pos() / 8)
+ pos2Aligned := common.TypeAlign8(pos3)
+ if pos3 != pos2Aligned {
+ d.Fatalf("pos3 isn't aligned, pos2 = %d, pos3 = %d", pos2, pos3)
+ }
+
+ })
+
+ } // for ItemsIds
+}
+
+func decodeInfomask2(d *decode.D, infomask2 uint64) {
+ d.FieldValueBool("heap_keys_updated", common.IsMaskSet0(infomask2, HEAP_KEYS_UPDATED))
+ d.FieldValueBool("heap_hot_updated", common.IsMaskSet0(infomask2, HEAP_HOT_UPDATED))
+ d.FieldValueBool("heap_only_tuple", common.IsMaskSet0(infomask2, HEAP_ONLY_TUPLE))
+}
+
+func decodeInfomask(heap *Heap, d *decode.D, infomask uint64) {
+ tuple := heap.Tuple
+
+ isMulti := common.IsMaskSet0(infomask, HEAP_XMAX_IS_MULTI)
+ tuple.IsMulti = isMulti
+
+ d.FieldValueBool("heap_hasnull", common.IsMaskSet0(infomask, HEAP_HASNULL))
+ d.FieldValueBool("heap_hasvarwidth", common.IsMaskSet0(infomask, HEAP_HASVARWIDTH))
+ d.FieldValueBool("heap_hasexternal", common.IsMaskSet0(infomask, HEAP_HASEXTERNAL))
+ d.FieldValueBool("heap_hasoid_old", common.IsMaskSet0(infomask, HEAP_HASOID_OLD))
+ d.FieldValueBool("heap_xmax_keyshr_lock", common.IsMaskSet0(infomask, HEAP_XMAX_KEYSHR_LOCK))
+ d.FieldValueBool("heap_combocid", common.IsMaskSet0(infomask, HEAP_COMBOCID))
+ d.FieldValueBool("heap_xmax_excl_lock", common.IsMaskSet0(infomask, HEAP_XMAX_EXCL_LOCK))
+ d.FieldValueBool("heap_xmax_lock_only", common.IsMaskSet0(infomask, HEAP_XMAX_LOCK_ONLY))
+ d.FieldValueBool("heap_xmax_shr_lock", common.IsMaskSet0(infomask, HEAP_XMAX_SHR_LOCK))
+ d.FieldValueBool("heap_lock_mask", common.IsMaskSet0(infomask, HEAP_LOCK_MASK))
+ d.FieldValueBool("heap_xmin_committed", common.IsMaskSet0(infomask, HEAP_XMIN_COMMITTED))
+ d.FieldValueBool("heap_xmin_invalid", common.IsMaskSet0(infomask, HEAP_XMIN_INVALID))
+ d.FieldValueBool("heap_xmin_frozen", common.IsMaskSet0(infomask, HEAP_XMIN_FROZEN))
+ d.FieldValueBool("heap_xmax_committed", common.IsMaskSet0(infomask, HEAP_XMAX_COMMITTED))
+ d.FieldValueBool("heap_xmax_invalid", common.IsMaskSet0(infomask, HEAP_XMAX_INVALID))
+ d.FieldValueBool("heap_xmax_is_multi", isMulti)
+ d.FieldValueBool("heap_updated", common.IsMaskSet0(infomask, HEAP_UPDATED))
+ d.FieldValueBool("heap_moved_off", common.IsMaskSet0(infomask, HEAP_MOVED_OFF))
+ d.FieldValueBool("heap_moved_in", common.IsMaskSet0(infomask, HEAP_MOVED_IN))
+ d.FieldValueBool("heap_moved", common.IsMaskSet0(infomask, HEAP_MOVED))
+}
+
+/* 0 | 12 */ // union {
+/* 12 */ // HeapTupleFields t_heap;
+/* 12 */ // DatumTupleFields t_datum;
+// } t_choice;
+func decodeTChoice(heap *Heap, d *decode.D) {
+ special := heap.Special
+ tuple := heap.Tuple
+
+ pos1 := d.Pos()
+ // type = struct HeapTupleFields {
+ /* 0 | 4 */ // TransactionId t_xmin;
+ /* 4 | 4 */ // TransactionId t_xmax;
+ /* 8 | 4 */ // union {
+ /* 4 */ // CommandId t_cid;
+ /* 4 */ // TransactionId t_xvac;
+ // } t_field3;
+ /* total size (bytes): 4 */
+ //
+ /* total size (bytes): 12 */
+ d.FieldStruct("t_heap", func(d *decode.D) {
+ d.FieldU32("t_xmin", TransactionMapper{Heap: heap, Special: special, Tuple: tuple})
+ d.FieldU32("t_xmax", TransactionMapper{Heap: heap, Special: special, Tuple: tuple})
+ d.FieldStruct("t_field3", func(d *decode.D) {
+ pos2 := d.Pos()
+ d.FieldU32("t_cid")
+ d.SeekAbs(pos2)
+ d.FieldU32("t_xvac")
+ }) // t_field3
+ }) // HeapTupleFields t_heap
+
+ // restore position for union
+ d.SeekAbs(pos1)
+ // type = struct DatumTupleFields {
+ /* 0 | 4 */ // int32 datum_len_;
+ /* 4 | 4 */ // int32 datum_typmod;
+ /* 8 | 4 */ // Oid datum_typeid;
+ //
+ /* total size (bytes): 12 */
+ d.FieldStruct("t_datum", func(d *decode.D) {
+ d.FieldS32("datum_len_")
+ d.FieldS32("datum_typmod")
+ d.FieldU32("datum_typeid")
+ }) // DatumTupleFields t_datum
+}
+
+type TransactionMapper struct {
+ Heap *Heap
+ Special *PageSpecial
+ Tuple *TupleD
+}
+
+func (m TransactionMapper) MapUint(s scalar.Uint) (scalar.Uint, error) {
+ xid := s.Actual
+
+ if m.Special.PdXidBase != 0 && m.Tuple.IsMulti && common.TransactionIDIsNormal(xid) {
+ xid64 := xid + m.Special.PdXidBase
+ s.Sym = fmt.Sprintf("%d", xid64)
+ }
+
+ if m.Special.PdMultiBase != 0 && !m.Tuple.IsMulti && common.TransactionIDIsNormal(xid) {
+ xid64 := xid + m.Special.PdMultiBase
+ s.Sym = fmt.Sprintf("%d", xid64)
+ }
+
+ return s, nil
+}
diff --git a/format/postgres/common/utils.go b/format/postgres/common/utils.go
new file mode 100644
index 000000000..18d0b5126
--- /dev/null
+++ b/format/postgres/common/utils.go
@@ -0,0 +1,24 @@
+package common
+
+func TypeAlign(alignVal uint64, alignLen uint64) uint64 {
+ return (alignLen + alignVal - 1) & ^(alignVal - 1)
+}
+
+func TypeAlign8(alignLen uint64) uint64 {
+ return TypeAlign(8, alignLen)
+}
+
+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
+}
+
+func IsMaskSet0(value uint64, mask uint64) bool {
+ return (value & mask) > 0
+}
diff --git a/format/postgres/common/utils_test.go b/format/postgres/common/utils_test.go
new file mode 100644
index 000000000..b7a80a794
--- /dev/null
+++ b/format/postgres/common/utils_test.go
@@ -0,0 +1,88 @@
+package common_test
+
+import (
+ "testing"
+
+ "github.com/wader/fq/format/postgres/common"
+)
+
+func TestTypeAlign(t *testing.T) {
+ expected0 := common.TypeAlign(8192, 8192+0)
+ if expected0 != 8192 {
+ t.Errorf("must be 8192\n")
+ }
+
+ expected1 := common.TypeAlign(8192, 8192+100)
+ if expected1 != 8192*2 {
+ t.Errorf("must be 8192*2\n")
+ }
+
+ expected2 := common.TypeAlign(8192, 0)
+ if expected2 != 0 {
+ t.Errorf("must be 0\n")
+ }
+
+ expected3 := common.TypeAlign(8192, 700)
+ if expected3 != 8192 {
+ t.Errorf("must be 8192\n")
+ }
+
+ expected4 := common.TypeAlign(8192, 8192*2+5000)
+ if expected4 != 8192*3 {
+ t.Errorf("must be 8192*3\n")
+ }
+
+ expected5 := common.TypeAlign(8192, 114720)
+ if expected5 != 122880 {
+ t.Errorf("must be 8192*3\n")
+ }
+}
+
+func TestTypeAlign8(t *testing.T) {
+ expected39 := common.TypeAlign8(39)
+ if expected39 != 40 {
+ t.Errorf("must be 40\n")
+ }
+ expected41 := common.TypeAlign8(41)
+ if expected41 != 48 {
+ t.Errorf("must be 40\n")
+ }
+}
+
+func TestRoundDown(t *testing.T) {
+ const pageSize1 = 8192
+ expected1 := common.RoundDown(pageSize1, 7*pageSize1+35)
+ if expected1 != 7*pageSize1 {
+ t.Errorf("must be %d\n", 7*pageSize1)
+ }
+ expected2 := common.RoundDown(pageSize1, 7*pageSize1-1)
+ if expected2 != 6*pageSize1 {
+ t.Errorf("must be %d\n", 6*pageSize1)
+ }
+
+ const pageSize2 = 7744
+ expected3 := common.RoundDown(pageSize2, 15*pageSize2+61)
+ if expected3 != 15*pageSize2 {
+ t.Errorf("must be %d\n", 15*pageSize2)
+ }
+ expected4 := common.RoundDown(pageSize2, 3*pageSize2-15)
+ if expected4 != 2*pageSize2 {
+ t.Errorf("must be %d\n", 2*pageSize2)
+ }
+
+ expected5 := common.RoundDown(pageSize1, 5*pageSize1)
+ if expected5 != 5*pageSize1 {
+ 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")
+ }
+}
diff --git a/format/postgres/flavours/pgpro10/pg_control.go b/format/postgres/flavours/pgpro10/pg_control.go
new file mode 100644
index 000000000..9cdf53a5e
--- /dev/null
+++ b/format/postgres/flavours/pgpro10/pg_control.go
@@ -0,0 +1,89 @@
+package pgpro10
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+func DecodePgControl(d *decode.D) any {
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldU64("prev_check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU24("hole1")
+
+ d.FieldU32("next_xid_epoch")
+ d.FieldU32("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding1")
+ })
+
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole2")
+
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole3")
+
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole4")
+
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole5")
+
+ d.FieldU32("max_align")
+ d.FieldU32("hole6")
+
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole7")
+
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("crc")
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgpro11/pg_control.go b/format/postgres/flavours/pgpro11/pg_control.go
new file mode 100644
index 000000000..e30c8bf2f
--- /dev/null
+++ b/format/postgres/flavours/pgpro11/pg_control.go
@@ -0,0 +1,220 @@
+package pgpro11
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 80 */ // CheckPoint checkPointCopy;
+/* 120 | 8 */ // XLogRecPtr unloggedLSN;
+/* 128 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 136 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 144 | 8 */ // XLogRecPtr backupStartPoint;
+/* 152 | 8 */ // XLogRecPtr backupEndPoint;
+/* 160 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 164 | 4 */ // int wal_level;
+/* 168 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int MaxConnections;
+/* 176 | 4 */ // int max_worker_processes;
+/* 180 | 4 */ // int max_prepared_xacts;
+/* 184 | 4 */ // int max_locks_per_xact;
+/* 188 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 192 | 4 */ // uint32 maxAlign;
+/* XXX 4-byte hole */
+/* 200 | 8 */ // double floatFormat;
+/* 208 | 4 */ // uint32 blcksz;
+/* 212 | 4 */ // uint32 relseg_size;
+/* 216 | 4 */ // uint32 xlog_blcksz;
+/* 220 | 4 */ // uint32 xlog_seg_size;
+/* 224 | 4 */ // uint32 nameDataLen;
+/* 228 | 4 */ // uint32 indexMaxKeys;
+/* 232 | 4 */ // uint32 toast_max_chunk_size;
+/* 236 | 4 */ // uint32 loblksize;
+/* 240 | 1 */ // _Bool float4ByVal;
+/* 241 | 1 */ // _Bool float8ByVal;
+/* XXX 2-byte hole */
+/* 244 | 4 */ // uint32 data_checksum_version;
+/* 248 | 32 */ // char mock_authentication_nonce[32];
+/* 280 | 4 */ // pg_icu_version icu_version;
+/* 284 | 4 */ // pg_crc32c crc
+//
+/* total size (bytes): 288 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 3-byte hole */
+/* 20 | 4 */ // uint32 nextXidEpoch;
+/* 24 | 4 */ // TransactionId nextXid;
+/* 28 | 4 */ // Oid nextOid;
+/* 32 | 4 */ // MultiXactId nextMulti;
+/* 36 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 40 | 4 */ // TransactionId oldestXid;
+/* 44 | 4 */ // Oid oldestXidDB;
+/* 48 | 4 */ // MultiXactId oldestMulti;
+/* 52 | 4 */ // Oid oldestMultiDB;
+/* 56 | 8 */ // pg_time_t time;
+/* 64 | 4 */ // TransactionId oldestCommitTsXid;
+/* 68 | 4 */ // TransactionId newestCommitTsXid;
+/* 72 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 80 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 80 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 3-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU24("hole1")
+
+ /* 20 | 4 */ // uint32 nextXidEpoch;
+ /* 24 | 4 */ // TransactionId nextXid;
+ /* 28 | 4 */ // Oid nextOid;
+ /* 32 | 4 */ // MultiXactId nextMulti;
+ /* 36 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 40 | 4 */ // TransactionId oldestXid;
+ /* 44 | 4 */ // Oid oldestXidDB;
+ /* 48 | 4 */ // MultiXactId oldestMulti;
+ /* 52 | 4 */ // Oid oldestMultiDB;
+ /* 56 | 8 */ // pg_time_t time;
+ /* 64 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 68 | 4 */ // TransactionId newestCommitTsXid;
+ /* 72 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldU32("next_xid_epoch")
+ d.FieldU32("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding1")
+ })
+
+ /* 120 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 128 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 136 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole2")
+
+ /* 144 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 152 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 160 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole3")
+
+ /* 164 | 4 */ // int wal_level;
+ /* 168 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int MaxConnections;
+ /* 176 | 4 */ // int max_worker_processes;
+ /* 180 | 4 */ // int max_prepared_xacts;
+ /* 184 | 4 */ // int max_locks_per_xact;
+ /* 188 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole5")
+
+ /* 192 | 4 */ // uint32 maxAlign;
+ /* XXX 4-byte hole */
+ d.FieldU32("max_align")
+ d.FieldU32("hole6")
+
+ /* 200 | 8 */ // double floatFormat;
+ /* 208 | 4 */ // uint32 blcksz;
+ /* 212 | 4 */ // uint32 relseg_size;
+ /* 216 | 4 */ // uint32 xlog_blcksz;
+ /* 220 | 4 */ // uint32 xlog_seg_size;
+ /* 224 | 4 */ // uint32 nameDataLen;
+ /* 228 | 4 */ // uint32 indexMaxKeys;
+ /* 232 | 4 */ // uint32 toast_max_chunk_size;
+ /* 236 | 4 */ // uint32 loblksize;
+ /* 240 | 1 */ // _Bool float4ByVal;
+ /* 241 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole7")
+
+ /* 244 | 4 */ // uint32 data_checksum_version;
+ /* 248 | 32 */ // char mock_authentication_nonce[32];
+ /* 280 | 4 */ // pg_icu_version icu_version;
+ /* 284 | 4 */ // pg_crc32c crc
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("crc")
+ /* total size (bytes): 288 */
+
+ d.AssertPos(288 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgpro12/pg_control.go b/format/postgres/flavours/pgpro12/pg_control.go
new file mode 100644
index 000000000..fdeba9413
--- /dev/null
+++ b/format/postgres/flavours/pgpro12/pg_control.go
@@ -0,0 +1,220 @@
+package pgpro12
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 88 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint;
+/* 160 | 8 */ // XLogRecPtr backupEndPoint;
+/* 168 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level;
+/* 176 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections;
+/* 184 | 4 */ // int max_worker_processes;
+/* 188 | 4 */ // int max_wal_senders;
+/* 192 | 4 */ // int max_prepared_xacts;
+/* 196 | 4 */ // int max_locks_per_xact;
+/* 200 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // uint32 maxAlign;
+/* 208 | 8 */ // double floatFormat;
+/* 216 | 4 */ // uint32 blcksz;
+/* 220 | 4 */ // uint32 relseg_size;
+/* 224 | 4 */ // uint32 xlog_blcksz;
+/* 228 | 4 */ // uint32 xlog_seg_size;
+/* 232 | 4 */ // uint32 nameDataLen;
+/* 236 | 4 */ // uint32 indexMaxKeys;
+/* 240 | 4 */ // uint32 toast_max_chunk_size;
+/* 244 | 4 */ // uint32 loblksize;
+/* 248 | 1 */ // _Bool float4ByVal;
+/* 249 | 1 */ // _Bool float8ByVal;
+/* XXX 2-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version;
+/* 256 | 32 */ // char mock_authentication_nonce[32];
+/* 288 | 4 */ // pg_icu_version icu_version;
+/* 292 | 4 */ // pg_crc32c crc;
+//
+/* total size (bytes): 296 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextFullXid;
+/* 32 | 4 */ // Oid nextOid;
+/* 36 | 4 */ // MultiXactId nextMulti;
+/* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 44 | 4 */ // TransactionId oldestXid;
+/* 48 | 4 */ // Oid oldestXidDB;
+/* 52 | 4 */ // MultiXactId oldestMulti;
+/* 56 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 64 | 8 */ // pg_time_t time;
+/* 72 | 4 */ // TransactionId oldestCommitTsXid;
+/* 76 | 4 */ // TransactionId newestCommitTsXid;
+/* 80 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 88 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 88 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextFullXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* 36 | 4 */ // MultiXactId nextMulti;
+ /* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 44 | 4 */ // TransactionId oldestXid;
+ /* 48 | 4 */ // Oid oldestXidDB;
+ /* 52 | 4 */ // MultiXactId oldestMulti;
+ /* 56 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_full_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole2")
+
+ /* 64 | 8 */ // pg_time_t time;
+ /* 72 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 76 | 4 */ // TransactionId newestCommitTsXid;
+ /* 80 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole3")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole5")
+
+ /* 180 | 4 */ // int MaxConnections;
+ /* 184 | 4 */ // int max_worker_processes;
+ /* 188 | 4 */ // int max_wal_senders;
+ /* 192 | 4 */ // int max_prepared_xacts;
+ /* 196 | 4 */ // int max_locks_per_xact;
+ /* 200 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // uint32 maxAlign;
+ /* 208 | 8 */ // double floatFormat;
+ /* 216 | 4 */ // uint32 blcksz;
+ /* 220 | 4 */ // uint32 relseg_size;
+ /* 224 | 4 */ // uint32 xlog_blcksz;
+ /* 228 | 4 */ // uint32 xlog_seg_size;
+ /* 232 | 4 */ // uint32 nameDataLen;
+ /* 236 | 4 */ // uint32 indexMaxKeys;
+ /* 240 | 4 */ // uint32 toast_max_chunk_size;
+ /* 244 | 4 */ // uint32 loblksize;
+ /* 248 | 1 */ // _Bool float4ByVal;
+ /* 249 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_icu_version icu_version;
+ /* 292 | 4 */ // pg_crc32c crc;
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("crc")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgpro13/pg_control.go b/format/postgres/flavours/pgpro13/pg_control.go
new file mode 100644
index 000000000..fb44fb9d9
--- /dev/null
+++ b/format/postgres/flavours/pgpro13/pg_control.go
@@ -0,0 +1,216 @@
+package pgpro13
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 88 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint;
+/* 160 | 8 */ // XLogRecPtr backupEndPoint;
+/* 168 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level;
+/* 176 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections;
+/* 184 | 4 */ // int max_worker_processes;
+/* 188 | 4 */ // int max_wal_senders;
+/* 192 | 4 */ // int max_prepared_xacts;
+/* 196 | 4 */ // int max_locks_per_xact;
+/* 200 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // uint32 maxAlign;
+/* 208 | 8 */ // double floatFormat;
+/* 216 | 4 */ // uint32 blcksz;
+/* 220 | 4 */ // uint32 relseg_size;
+/* 224 | 4 */ // uint32 xlog_blcksz;
+/* 228 | 4 */ // uint32 xlog_seg_size;
+/* 232 | 4 */ // uint32 nameDataLen;
+/* 236 | 4 */ // uint32 indexMaxKeys;
+/* 240 | 4 */ // uint32 toast_max_chunk_size;
+/* 244 | 4 */ // uint32 loblksize;
+/* 248 | 1 */ // _Bool float8ByVal;
+/* XXX 3-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version;
+/* 256 | 32 */ // char mock_authentication_nonce[32];
+/* 288 | 4 */ // pg_icu_version icu_version;
+/* 292 | 4 */ // pg_crc32c crc;
+
+/* total size (bytes): 296 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo
+/* 8 | 4 */ // TimeLineID ThisTimeLineID
+/* 12 | 4 */ // TimeLineID PrevTimeLineID
+/* 16 | 1 */ // _Bool fullPageWrites
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextFullXid
+/* 32 | 4 */ // Oid nextOid
+/* 36 | 4 */ // MultiXactId nextMulti
+/* 40 | 4 */ // MultiXactOffset nextMultiOffset
+/* 44 | 4 */ // TransactionId oldestXid
+/* 48 | 4 */ // Oid oldestXidDB
+/* 52 | 4 */ // MultiXactId oldestMulti
+/* 56 | 4 */ // Oid oldestMultiDB
+/* XXX 4-byte hole */
+/* 64 | 8 */ // pg_time_t time
+/* 72 | 4 */ // TransactionId oldestCommitTsXid
+/* 76 | 4 */ // TransactionId newestCommitTsXid
+/* 80 | 4 */ // TransactionId oldestActiveXid
+/* XXX 4-byte padding */
+
+/* total size (bytes): 88 */
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 88 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextFullXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* 36 | 4 */ // MultiXactId nextMulti;
+ /* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 44 | 4 */ // TransactionId oldestXid;
+ /* 48 | 4 */ // Oid oldestXidDB;
+ /* 52 | 4 */ // MultiXactId oldestMulti;
+ /* 56 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_full_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole2")
+
+ /* 64 | 8 */ // pg_time_t time;
+ /* 72 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 76 | 4 */ // TransactionId newestCommitTsXid;
+ /* 80 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole3")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole5")
+
+ /* 180 | 4 */ // int MaxConnections;
+ /* 184 | 4 */ // int max_worker_processes;
+ /* 188 | 4 */ // int max_wal_senders;
+ /* 192 | 4 */ // int max_prepared_xacts;
+ /* 196 | 4 */ // int max_locks_per_xact;
+ /* 200 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // uint32 maxAlign;
+ /* 208 | 8 */ // double floatFormat;
+ /* 216 | 4 */ // uint32 blcksz;
+ /* 220 | 4 */ // uint32 relseg_size;
+ /* 224 | 4 */ // uint32 xlog_blcksz;
+ /* 228 | 4 */ // uint32 xlog_seg_size;
+ /* 232 | 4 */ // uint32 nameDataLen;
+ /* 236 | 4 */ // uint32 indexMaxKeys;
+ /* 240 | 4 */ // uint32 toast_max_chunk_size;
+ /* 244 | 4 */ // uint32 loblksize;
+ /* 248 | 1 */ // _Bool float8ByVal;
+ /* XXX 3-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_icu_version icu_version;
+ /* 292 | 4 */ // pg_crc32c crc;
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("crc")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgpro14/pg_control.go b/format/postgres/flavours/pgpro14/pg_control.go
new file mode 100644
index 000000000..2832049eb
--- /dev/null
+++ b/format/postgres/flavours/pgpro14/pg_control.go
@@ -0,0 +1,216 @@
+package pgpro14
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 88 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint;
+/* 160 | 8 */ // XLogRecPtr backupEndPoint;
+/* 168 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level;
+/* 176 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections;
+/* 184 | 4 */ // int max_worker_processes;
+/* 188 | 4 */ // int max_wal_senders;
+/* 192 | 4 */ // int max_prepared_xacts;
+/* 196 | 4 */ // int max_locks_per_xact;
+/* 200 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // uint32 maxAlign;
+/* 208 | 8 */ // double floatFormat;
+/* 216 | 4 */ // uint32 blcksz;
+/* 220 | 4 */ // uint32 relseg_size;
+/* 224 | 4 */ // uint32 xlog_blcksz;
+/* 228 | 4 */ // uint32 xlog_seg_size;
+/* 232 | 4 */ // uint32 nameDataLen;
+/* 236 | 4 */ // uint32 indexMaxKeys;
+/* 240 | 4 */ // uint32 toast_max_chunk_size;
+/* 244 | 4 */ // uint32 loblksize;
+/* 248 | 1 */ // _Bool float8ByVal;
+/* XXX 3-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version;
+/* 256 | 32 */ // char mock_authentication_nonce[32];
+/* 288 | 4 */ // pg_icu_version icu_version;
+/* 292 | 4 */ // pg_crc32c crc;
+//
+/* total size (bytes): 296 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextXid;
+/* 32 | 4 */ // Oid nextOid;
+/* 36 | 4 */ // MultiXactId nextMulti;
+/* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 44 | 4 */ // TransactionId oldestXid;
+/* 48 | 4 */ // Oid oldestXidDB;
+/* 52 | 4 */ // MultiXactId oldestMulti;
+/* 56 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 64 | 8 */ // pg_time_t time;
+/* 72 | 4 */ // TransactionId oldestCommitTsXid;
+/* 76 | 4 */ // TransactionId newestCommitTsXid;
+/* 80 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 88 */
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 88 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* 36 | 4 */ // MultiXactId nextMulti;
+ /* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 44 | 4 */ // TransactionId oldestXid;
+ /* 48 | 4 */ // Oid oldestXidDB;
+ /* 52 | 4 */ // MultiXactId oldestMulti;
+ /* 56 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole2")
+
+ /* 64 | 8 */ // pg_time_t time;
+ /* 72 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 76 | 4 */ // TransactionId newestCommitTsXid;
+ /* 80 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole3")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole5")
+
+ /* 180 | 4 */ // int MaxConnections;
+ /* 184 | 4 */ // int max_worker_processes;
+ /* 188 | 4 */ // int max_wal_senders;
+ /* 192 | 4 */ // int max_prepared_xacts;
+ /* 196 | 4 */ // int max_locks_per_xact;
+ /* 200 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // uint32 maxAlign;
+ /* 208 | 8 */ // double floatFormat;
+ /* 216 | 4 */ // uint32 blcksz;
+ /* 220 | 4 */ // uint32 relseg_size;
+ /* 224 | 4 */ // uint32 xlog_blcksz;
+ /* 228 | 4 */ // uint32 xlog_seg_size;
+ /* 232 | 4 */ // uint32 nameDataLen;
+ /* 236 | 4 */ // uint32 indexMaxKeys;
+ /* 240 | 4 */ // uint32 toast_max_chunk_size;
+ /* 244 | 4 */ // uint32 loblksize;
+ /* 248 | 1 */ // _Bool float8ByVal;
+ /* XXX 3-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_icu_version icu_version;
+ /* 292 | 4 */ // pg_crc32c crc;
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("crc")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgproee10/pg_control.go b/format/postgres/flavours/pgproee10/pg_control.go
new file mode 100644
index 000000000..0f9e0e770
--- /dev/null
+++ b/format/postgres/flavours/pgproee10/pg_control.go
@@ -0,0 +1,236 @@
+package pgproee10
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 8 */ // XLogRecPtr prevCheckPoint;
+/* 48 | 120 */ // CheckPoint checkPointCopy;
+/* 168 | 8 */ // XLogRecPtr unloggedLSN;
+/* 176 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 184 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 192 | 8 */ // XLogRecPtr backupStartPoint;
+/* 200 | 8 */ // XLogRecPtr backupEndPoint;
+/* 208 | 1 */ // bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 212 | 4 */ // int wal_level
+/* 216 | 1 */ // bool wal_log_hints
+/* XXX 3-byte hole */
+/* 220 | 4 */ // int MaxConnections
+/* 224 | 4 */ // int max_worker_processes
+/* 228 | 4 */ // int max_prepared_xacts
+/* 232 | 4 */ // int max_locks_per_xact
+/* 236 | 1 */ // bool track_commit_timestamp
+/* XXX 3-byte hole */
+/* 240 | 4 */ // uint32 maxAlign
+/* XXX 4-byte hole */
+/* 248 | 8 */ // double floatFormat
+/* 256 | 4 */ // uint32 blcksz
+/* 260 | 4 */ // uint32 relseg_size
+/* 264 | 4 */ // uint32 xlog_blcksz
+/* 268 | 4 */ // uint32 xlog_seg_size
+/* 272 | 4 */ // uint32 nameDataLen
+/* 276 | 4 */ // uint32 indexMaxKeys
+/* 280 | 4 */ // uint32 toast_max_chunk_size
+/* 284 | 4 */ // uint32 loblksize
+/* 288 | 1 */ // bool float4ByVal
+/* 289 | 1 */ // bool float8ByVal
+/* XXX 2-byte hole */
+/* 292 | 4 */ // uint32 data_checksum_version
+/* 296 | 32 */ // char mock_authentication_nonce[32]
+/* 328 | 4 */ // pg_icu_version icu_version
+/* 332 | 4 */ // uint32 pg_old_version
+/* 336 | 4 */ // pg_crc32c crc
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 344 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo
+/* 8 | 4 */ // TimeLineID ThisTimeLineID
+/* 12 | 4 */ // TimeLineID PrevTimeLineID
+/* 16 | 1 */ // bool fullPageWrites
+/* XXX 7-byte hole */
+/* 24 | 8 */ // TransactionId nextXid
+/* 32 | 4 */ // Oid nextOid
+/* XXX 4-byte hole */
+/* 40 | 8 */ // MultiXactId nextMulti
+/* 48 | 8 */ // MultiXactOffset nextMultiOffset
+/* 56 | 8 */ // TransactionId oldestXid
+/* 64 | 4 */ // Oid oldestXidDB
+/* XXX 4-byte hole */
+/* 72 | 8 */ // MultiXactId oldestMulti
+/* 80 | 4 */ // Oid oldestMultiDB
+/* XXX 4-byte hole */
+/* 88 | 8 */ // pg_time_t time
+/* 96 | 8 */ // TransactionId oldestCommitTsXid
+/* 104 | 8 */ // TransactionId newestCommitTsXid
+/* 112 | 8 */ // TransactionId oldestActiveXid
+//
+/* total size (bytes): 120 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* XXX 4-byte hole */
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 8 */ // XLogRecPtr prevCheckPoint;
+ /* 48 | 120 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldU64("prev_check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("hole2")
+
+ /* 40 | 8 */ // MultiXactId nextMulti;
+ /* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+ /* 56 | 8 */ // TransactionId oldestXid;
+ /* 64 | 4 */ // Oid oldestXidDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_multi")
+ d.FieldU64("next_multi_offset")
+ d.FieldU64("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("hole3")
+
+ /* 72 | 8 */ // MultiXactId oldestMulti;
+ /* 80 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole4")
+
+ /* 88 | 8 */ // pg_time_t time;
+ /* 96 | 8 */ // TransactionId oldestCommitTsXid;
+ /* 104 | 8 */ // TransactionId newestCommitTsXid;
+ /* 112 | 8 */ // TransactionId oldestActiveXid;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("oldest_commit_ts_xid")
+ d.FieldU64("newest_commit_ts_xid")
+ d.FieldU64("oldest_active_xid")
+ })
+
+ /* 168 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 176 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 184 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole5")
+
+ /* 192 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 200 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 208 | 1 */ // bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole6")
+
+ /* 212 | 4 */ // int wal_level
+ /* 216 | 1 */ // bool wal_log_hints
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole7")
+
+ /* 220 | 4 */ // int MaxConnections
+ /* 224 | 4 */ // int max_worker_processes
+ /* 228 | 4 */ // int max_prepared_xacts
+ /* 232 | 4 */ // int max_locks_per_xact
+ /* 236 | 1 */ // bool track_commit_timestamp
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole8")
+
+ /* 240 | 4 */ // uint32 maxAlign
+ /* XXX 4-byte hole */
+ d.FieldU32("max_align")
+ d.FieldU32("hole9")
+
+ /* 248 | 8 */ // double floatFormat
+ /* 256 | 4 */ // uint32 blcksz
+ /* 260 | 4 */ // uint32 relseg_size
+ /* 264 | 4 */ // uint32 xlog_blcksz
+ /* 268 | 4 */ // uint32 xlog_seg_size
+ /* 272 | 4 */ // uint32 nameDataLen
+ /* 276 | 4 */ // uint32 indexMaxKeys
+ /* 280 | 4 */ // uint32 toast_max_chunk_size
+ /* 284 | 4 */ // uint32 loblksize
+ /* 288 | 1 */ // bool float4ByVal
+ /* 289 | 1 */ // bool float8ByVal
+ /* XXX 2-byte hole */
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole10")
+
+ /* 292 | 4 */ // uint32 data_checksum_version
+ /* 296 | 32 */ // char mock_authentication_nonce[32]
+ /* 328 | 4 */ // pg_icu_version icu_version
+ /* 332 | 4 */ // uint32 pg_old_version
+ /* 336 | 4 */ // pg_crc32c crc
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("pg_old_version")
+ d.FieldU32("crc")
+ d.FieldU32("hole11")
+ /* total size (bytes): 344 */
+
+ d.AssertPos(344 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgproee11/pg_control.go b/format/postgres/flavours/pgproee11/pg_control.go
new file mode 100644
index 000000000..21082cf8c
--- /dev/null
+++ b/format/postgres/flavours/pgproee11/pg_control.go
@@ -0,0 +1,238 @@
+package pgproee11
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 120 */ // CheckPoint checkPointCopy;
+/* 160 | 8 */ // XLogRecPtr unloggedLSN;
+/* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 184 | 8 */ // XLogRecPtr backupStartPoint;
+/* 192 | 8 */ // XLogRecPtr backupEndPoint;
+/* 200 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // int wal_level;
+/* 208 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 212 | 4 */ // int MaxConnections;
+/* 216 | 4 */ // int max_worker_processes;
+/* 220 | 4 */ // int max_prepared_xacts;
+/* 224 | 4 */ // int max_locks_per_xact;
+/* 228 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 232 | 4 */ // uint32 maxAlign;
+/* XXX 4-byte hole */
+/* 240 | 8 */ // double floatFormat;
+/* 248 | 4 */ // uint32 blcksz;
+/* 252 | 4 */ // uint32 relseg_size;
+/* 256 | 4 */ // uint32 xlog_blcksz;
+/* 260 | 4 */ // uint32 xlog_seg_size;
+/* 264 | 4 */ // uint32 nameDataLen;
+/* 268 | 4 */ // uint32 indexMaxKeys;
+/* 272 | 4 */ // uint32 toast_max_chunk_size;
+/* 276 | 4 */ // uint32 loblksize;
+/* 280 | 1 */ // _Bool float4ByVal;
+/* 281 | 1 */ // _Bool float8ByVal;
+/* XXX 2-byte hole */
+/* 284 | 4 */ // uint32 data_checksum_version;
+/* 288 | 32 */ // char mock_authentication_nonce[32];
+/* 320 | 4 */ // pg_icu_version icu_version;
+/* 324 | 4 */ // uint32 pg_old_version;
+/* 328 | 4 */ // SnapshotId oldest_snapshot;
+/* 332 | 4 */ // SnapshotId recent_snapshot;
+/* 336 | 4 */ // SnapshotId active_snapshot;
+/* 340 | 4 */ // pg_crc32c crc;
+//
+/* total size (bytes): 344 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // TransactionId nextXid;
+/* 32 | 4 */ // Oid nextOid;
+/* XXX 4-byte hole */
+/* 40 | 8 */ // MultiXactId nextMulti;
+/* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+/* 56 | 8 */ // TransactionId oldestXid;
+/* 64 | 4 */ // Oid oldestXidDB;
+/* XXX 4-byte hole */
+/* 72 | 8 */ // MultiXactId oldestMulti;
+/* 80 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 88 | 8 */ // pg_time_t time;
+/* 96 | 8 */ // TransactionId oldestCommitTsXid;
+/* 104 | 8 */ // TransactionId newestCommitTsXid;
+/* 112 | 8 */ // TransactionId oldestActiveXid;
+//
+/* total size (bytes): 120 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 120 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("hole2")
+
+ /* 40 | 8 */ // MultiXactId nextMulti;
+ /* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+ /* 56 | 8 */ // TransactionId oldestXid;
+ /* 64 | 4 */ // Oid oldestXidDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_multi")
+ d.FieldU64("next_multi_offset")
+ d.FieldU64("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("hole3")
+
+ /* 72 | 8 */ // MultiXactId oldestMulti;
+ /* 80 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole4")
+
+ /* 88 | 8 */ // pg_time_t time;
+ /* 96 | 8 */ // TransactionId oldestCommitTsXid;
+ /* 104 | 8 */ // TransactionId newestCommitTsXid;
+ /* 112 | 8 */ // TransactionId oldestActiveXid;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("oldest_commit_ts_xid")
+ d.FieldU64("newest_commit_ts_xid")
+ d.FieldU64("oldest_active_xid")
+ })
+
+ /* 160 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole5")
+
+ /* 184 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 192 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 200 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // int wal_level;
+ /* 208 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole7")
+
+ /* 212 | 4 */ // int MaxConnections;
+ /* 216 | 4 */ // int max_worker_processes;
+ /* 220 | 4 */ // int max_prepared_xacts;
+ /* 224 | 4 */ // int max_locks_per_xact;
+ /* 228 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole8")
+
+ /* 232 | 4 */ // uint32 maxAlign;
+ /* XXX 4-byte hole */
+ d.FieldU32("max_align")
+ d.FieldU32("hole9")
+
+ /* 240 | 8 */ // double floatFormat;
+ /* 248 | 4 */ // uint32 blcksz;
+ /* 252 | 4 */ // uint32 relseg_size;
+ /* 256 | 4 */ // uint32 xlog_blcksz;
+ /* 260 | 4 */ // uint32 xlog_seg_size;
+ /* 264 | 4 */ // uint32 nameDataLen;
+ /* 268 | 4 */ // uint32 indexMaxKeys;
+ /* 272 | 4 */ // uint32 toast_max_chunk_size;
+ /* 276 | 4 */ // uint32 loblksize;
+ /* 280 | 1 */ // _Bool float4ByVal;
+ /* 281 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole10")
+
+ /* 284 | 4 */ // uint32 data_checksum_version;
+ /* 288 | 32 */ // char mock_authentication_nonce[32];
+ /* 320 | 4 */ // pg_icu_version icu_version;
+ /* 324 | 4 */ // uint32 pg_old_version;
+ /* 328 | 4 */ // SnapshotId oldest_snapshot;
+ /* 332 | 4 */ // SnapshotId recent_snapshot;
+ /* 336 | 4 */ // SnapshotId active_snapshot;
+ /* 340 | 4 */ // pg_crc32c crc;
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("pg_old_version")
+ d.FieldU32("oldest_snapshot")
+ d.FieldU32("recent_snapshot")
+ d.FieldU32("active_snapshot")
+ d.FieldU32("crc")
+ /* total size (bytes): 344 */
+
+ d.AssertPos(344 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgproee12/pg_control.go b/format/postgres/flavours/pgproee12/pg_control.go
new file mode 100644
index 000000000..ea46df5cc
--- /dev/null
+++ b/format/postgres/flavours/pgproee12/pg_control.go
@@ -0,0 +1,237 @@
+package pgproee12
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 120 */ // CheckPoint checkPointCopy;
+/* 160 | 8 */ // XLogRecPtr unloggedLSN;
+/* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 184 | 8 */ // XLogRecPtr backupStartPoint;
+/* 192 | 8 */ // XLogRecPtr backupEndPoint;
+/* 200 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // int wal_level;
+/* 208 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 212 | 4 */ // int MaxConnections;
+/* 216 | 4 */ // int max_worker_processes;
+/* 220 | 4 */ // int max_wal_senders;
+/* 224 | 4 */ // int max_prepared_xacts;
+/* 228 | 4 */ // int max_locks_per_xact;
+/* 232 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 236 | 4 */ // uint32 maxAlign;
+/* 240 | 8 */ // double floatFormat;
+/* 248 | 4 */ // uint32 blcksz;
+/* 252 | 4 */ // uint32 relseg_size;
+/* 256 | 4 */ // uint32 xlog_blcksz;
+/* 260 | 4 */ // uint32 xlog_seg_size;
+/* 264 | 4 */ // uint32 nameDataLen;
+/* 268 | 4 */ // uint32 indexMaxKeys;
+/* 272 | 4 */ // uint32 toast_max_chunk_size;
+/* 276 | 4 */ // uint32 loblksize;
+/* 280 | 1 */ // _Bool float4ByVal;
+/* 281 | 1 */ // _Bool float8ByVal;
+/* XXX 2-byte hole */
+/* 284 | 4 */ // uint32 data_checksum_version;
+/* 288 | 32 */ // char mock_authentication_nonce[32];
+/* 320 | 4 */ // pg_icu_version icu_version;
+/* 324 | 4 */ // uint32 pg_old_version;
+/* 328 | 4 */ // SnapshotId oldest_snapshot;
+/* 332 | 4 */ // SnapshotId recent_snapshot;
+/* 336 | 4 */ // SnapshotId active_snapshot;
+/* 340 | 4 */ // pg_crc32c crc;
+//
+/* total size (bytes): 344 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextFullXid;
+/* 32 | 4 */ // Oid nextOid;
+/* XXX 4-byte hole */
+/* 40 | 8 */ // MultiXactId nextMulti;
+/* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+/* 56 | 8 */ // TransactionId oldestXid;
+/* 64 | 4 */ // Oid oldestXidDB;
+/* XXX 4-byte hole */
+/* 72 | 8 */ // MultiXactId oldestMulti;
+/* 80 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 88 | 8 */ // pg_time_t time;
+/* 96 | 8 */ // TransactionId oldestCommitTsXid;
+/* 104 | 8 */ // TransactionId newestCommitTsXid;
+/* 112 | 8 */ // TransactionId oldestActiveXid;
+//
+/* total size (bytes): 120 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 120 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("hole2")
+
+ /* 40 | 8 */ // MultiXactId nextMulti;
+ /* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+ /* 56 | 8 */ // TransactionId oldestXid;
+ /* 64 | 4 */ // Oid oldestXidDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_multi")
+ d.FieldU64("next_multi_offset")
+ d.FieldU64("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("hole3")
+
+ /* 72 | 8 */ // MultiXactId oldestMulti;
+ /* 80 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole4")
+
+ /* 88 | 8 */ // pg_time_t time;
+ /* 96 | 8 */ // TransactionId oldestCommitTsXid;
+ /* 104 | 8 */ // TransactionId newestCommitTsXid;
+ /* 112 | 8 */ // TransactionId oldestActiveXid;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("oldest_commit_ts_xid")
+ d.FieldU64("newest_commit_ts_xid")
+ d.FieldU64("oldest_active_xid")
+ })
+
+ /* 160 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole5")
+
+ /* 184 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 192 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 200 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // int wal_level;
+ /* 208 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole7")
+
+ /* 212 | 4 */ // int MaxConnections;
+ /* 216 | 4 */ // int max_worker_processes;
+ /* 220 | 4 */ // int max_wal_senders;
+ /* 224 | 4 */ // int max_prepared_xacts;
+ /* 228 | 4 */ // int max_locks_per_xact;
+ /* 232 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole8")
+
+ /* 236 | 4 */ // uint32 maxAlign;
+ /* 240 | 8 */ // double floatFormat;
+ /* 248 | 4 */ // uint32 blcksz;
+ /* 252 | 4 */ // uint32 relseg_size;
+ /* 256 | 4 */ // uint32 xlog_blcksz;
+ /* 260 | 4 */ // uint32 xlog_seg_size;
+ /* 264 | 4 */ // uint32 nameDataLen;
+ /* 268 | 4 */ // uint32 indexMaxKeys;
+ /* 272 | 4 */ // uint32 toast_max_chunk_size;
+ /* 276 | 4 */ // uint32 loblksize;
+ /* 280 | 1 */ // _Bool float4ByVal;
+ /* 281 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole9")
+
+ /* 284 | 4 */ // uint32 data_checksum_version;
+ /* 288 | 32 */ // char mock_authentication_nonce[32];
+ /* 320 | 4 */ // pg_icu_version icu_version;
+ /* 324 | 4 */ // uint32 pg_old_version;
+ /* 328 | 4 */ // SnapshotId oldest_snapshot;
+ /* 332 | 4 */ // SnapshotId recent_snapshot;
+ /* 336 | 4 */ // SnapshotId active_snapshot;
+ /* 340 | 4 */ // pg_crc32c crc;
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("pg_old_version")
+ d.FieldU32("oldest_snapshot")
+ d.FieldU32("recent_snapshot")
+ d.FieldU32("active_snapshot")
+ d.FieldU32("crc")
+ /* total size (bytes): 344 */
+
+ d.AssertPos(344 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgproee13/pg_control.go b/format/postgres/flavours/pgproee13/pg_control.go
new file mode 100644
index 000000000..d3149b5eb
--- /dev/null
+++ b/format/postgres/flavours/pgproee13/pg_control.go
@@ -0,0 +1,229 @@
+package pgproee13
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time
+/* 32 | 8 */ // XLogRecPtr checkPoint
+/* 40 | 120 */ // CheckPoint checkPointCopy
+/* 160 | 8 */ // XLogRecPtr unloggedLSN
+/* 168 | 8 */ // XLogRecPtr minRecoveryPoint
+/* 176 | 4 */ // TimeLineID minRecoveryPointTLI
+/* XXX 4-byte hole */
+/* 184 | 8 */ // XLogRecPtr backupStartPoint
+/* 192 | 8 */ // XLogRecPtr backupEndPoint
+/* 200 | 1 */ // _Bool backupEndRequired
+/* XXX 3-byte hole */
+/* 204 | 4 */ // int wal_level
+/* 208 | 1 */ // _Bool wal_log_hints
+/* XXX 3-byte hole */
+/* 212 | 4 */ // int MaxConnections
+/* 216 | 4 */ // int max_worker_processes
+/* 220 | 4 */ // int max_wal_senders
+/* 224 | 4 */ // int max_prepared_xacts
+/* 228 | 4 */ // int max_locks_per_xact
+/* 232 | 1 */ // _Bool track_commit_timestamp
+/* XXX 3-byte hole */
+/* 236 | 4 */ // uint32 maxAlign
+/* 240 | 8 */ // double floatFormat
+/* 248 | 4 */ // uint32 blcksz
+/* 252 | 4 */ // uint32 relseg_size
+/* 256 | 4 */ // uint32 xlog_blcksz
+/* 260 | 4 */ // uint32 xlog_seg_size
+/* 264 | 4 */ // uint32 nameDataLen
+/* 268 | 4 */ // uint32 indexMaxKeys
+/* 272 | 4 */ // uint32 toast_max_chunk_size
+/* 276 | 4 */ // uint32 loblksize
+/* 280 | 1 */ // _Bool float8ByVal
+/* XXX 3-byte hole */
+/* 284 | 4 */ // uint32 data_checksum_version
+/* 288 | 32 */ // char mock_authentication_nonce[32]
+/* 320 | 4 */ // pg_icu_version icu_version
+/* 324 | 4 */ // uint32 pg_old_version
+/* 328 | 4 */ // pg_crc32c crc
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 336 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo
+/* 8 | 4 */ // TimeLineID ThisTimeLineID
+/* 12 | 4 */ // TimeLineID PrevTimeLineID
+/* 16 | 1 */ // _Bool fullPageWrites
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextFullXid
+/* 32 | 4 */ // Oid nextOid
+/* XXX 4-byte hole */
+/* 40 | 8 */ // MultiXactId nextMulti
+/* 48 | 8 */ // MultiXactOffset nextMultiOffset
+/* 56 | 8 */ // TransactionId oldestXid
+/* 64 | 4 */ // Oid oldestXidDB
+/* XXX 4-byte hole */
+/* 72 | 8 */ // MultiXactId oldestMulti
+/* 80 | 4 */ // Oid oldestMultiDB
+/* XXX 4-byte hole */
+/* 88 | 8 */ // pg_time_t time
+/* 96 | 8 */ // TransactionId oldestCommitTsXid
+/* 104 | 8 */ // TransactionId newestCommitTsXid
+/* 112 | 8 */ // TransactionId oldestActiveXid
+//
+/* total size (bytes): 120 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 120 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("hole2")
+
+ /* 40 | 8 */ // MultiXactId nextMulti;
+ /* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+ /* 56 | 8 */ // TransactionId oldestXid;
+ /* 64 | 4 */ // Oid oldestXidDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_multi")
+ d.FieldU64("next_multi_offset")
+ d.FieldU64("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("hole3")
+
+ /* 72 | 8 */ // MultiXactId oldestMulti;
+ /* 80 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole4")
+
+ /* 88 | 8 */ // pg_time_t time;
+ /* 96 | 8 */ // TransactionId oldestCommitTsXid;
+ /* 104 | 8 */ // TransactionId newestCommitTsXid;
+ /* 112 | 8 */ // TransactionId oldestActiveXid;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("oldest_commit_ts_xid")
+ d.FieldU64("newest_commit_ts_xid")
+ d.FieldU64("oldest_active_xid")
+ })
+
+ /* 160 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole5")
+
+ /* 184 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 192 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 200 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // int wal_level;
+ /* 208 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole7")
+
+ /* 212 | 4 */ // int MaxConnections;
+ /* 216 | 4 */ // int max_worker_processes;
+ /* 220 | 4 */ // int max_wal_senders;
+ /* 224 | 4 */ // int max_prepared_xacts;
+ /* 228 | 4 */ // int max_locks_per_xact;
+ /* 232 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole8")
+
+ /* 236 | 4 */ // uint32 maxAlign;
+ /* 240 | 8 */ // double floatFormat;
+ /* 248 | 4 */ // uint32 blcksz;
+ /* 252 | 4 */ // uint32 relseg_size;
+ /* 256 | 4 */ // uint32 xlog_blcksz;
+ /* 260 | 4 */ // uint32 xlog_seg_size;
+ /* 264 | 4 */ // uint32 nameDataLen;
+ /* 268 | 4 */ // uint32 indexMaxKeys;
+ /* 272 | 4 */ // uint32 toast_max_chunk_size;
+ /* 276 | 4 */ // uint32 loblksize;
+ /* 280 | 1 */ // _Bool float4ByVal;
+ /* 281 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole9")
+
+ /* 284 | 4 */ // uint32 data_checksum_version
+ /* 288 | 32 */ // char mock_authentication_nonce[32]
+ /* 320 | 4 */ // pg_icu_version icu_version
+ /* 324 | 4 */ // uint32 pg_old_version
+ /* 328 | 4 */ // pg_crc32c crc
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("pg_old_version")
+ d.FieldU32("crc")
+ d.FieldU32("padding0")
+ /* total size (bytes): 336 */
+
+ d.AssertPos(336 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgproee14/pg_control.go b/format/postgres/flavours/pgproee14/pg_control.go
new file mode 100644
index 000000000..fd9dd2263
--- /dev/null
+++ b/format/postgres/flavours/pgproee14/pg_control.go
@@ -0,0 +1,228 @@
+package pgproee14
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 120 */ // CheckPoint checkPointCopy;
+/* 160 | 8 */ // XLogRecPtr unloggedLSN;
+/* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 184 | 8 */ // XLogRecPtr backupStartPoint;
+/* 192 | 8 */ // XLogRecPtr backupEndPoint;
+/* 200 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // int wal_level;
+/* 208 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 212 | 4 */ // int MaxConnections;
+/* 216 | 4 */ // int max_worker_processes;
+/* 220 | 4 */ // int max_wal_senders;
+/* 224 | 4 */ // int max_prepared_xacts;
+/* 228 | 4 */ // int max_locks_per_xact;
+/* 232 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 236 | 4 */ // uint32 maxAlign;
+/* 240 | 8 */ // double floatFormat;
+/* 248 | 4 */ // uint32 blcksz;
+/* 252 | 4 */ // uint32 relseg_size;
+/* 256 | 4 */ // uint32 xlog_blcksz;
+/* 260 | 4 */ // uint32 xlog_seg_size;
+/* 264 | 4 */ // uint32 nameDataLen;
+/* 268 | 4 */ // uint32 indexMaxKeys;
+/* 272 | 4 */ // uint32 toast_max_chunk_size;
+/* 276 | 4 */ // uint32 loblksize;
+/* 280 | 1 */ // _Bool float8ByVal;
+/* XXX 3-byte hole */
+/* 284 | 4 */ // uint32 data_checksum_version;
+/* 288 | 32 */ // char mock_authentication_nonce[32];
+/* 320 | 4 */ // pg_icu_version icu_version;
+/* 324 | 4 */ // uint32 pg_old_version;
+/* 328 | 4 */ // pg_crc32c crc;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 336 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextXid;
+/* 32 | 4 */ // Oid nextOid;
+/* XXX 4-byte hole */
+/* 40 | 8 */ // MultiXactId nextMulti;
+/* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+/* 56 | 8 */ // TransactionId oldestXid;
+/* 64 | 4 */ // Oid oldestXidDB;
+/* XXX 4-byte hole */
+/* 72 | 8 */ // MultiXactId oldestMulti;
+/* 80 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 88 | 8 */ // pg_time_t time;
+/* 96 | 8 */ // TransactionId oldestCommitTsXid;
+/* 104 | 8 */ // TransactionId newestCommitTsXid;
+/* 112 | 8 */ // TransactionId oldestActiveXid;
+//
+/* total size (bytes): 120 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 120 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("hole2")
+
+ /* 40 | 8 */ // MultiXactId nextMulti;
+ /* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+ /* 56 | 8 */ // TransactionId oldestXid;
+ /* 64 | 4 */ // Oid oldestXidDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_multi")
+ d.FieldU64("next_multi_offset")
+ d.FieldU64("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("hole3")
+
+ /* 72 | 8 */ // MultiXactId oldestMulti;
+ /* 80 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole4")
+
+ /* 88 | 8 */ // pg_time_t time;
+ /* 96 | 8 */ // TransactionId oldestCommitTsXid;
+ /* 104 | 8 */ // TransactionId newestCommitTsXid;
+ /* 112 | 8 */ // TransactionId oldestActiveXid;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("oldest_commit_ts_xid")
+ d.FieldU64("newest_commit_ts_xid")
+ d.FieldU64("oldest_active_xid")
+ })
+
+ /* 160 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole5")
+
+ /* 184 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 192 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 200 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // int wal_level;
+ /* 208 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole7")
+
+ /* 212 | 4 */ // int MaxConnections;
+ /* 216 | 4 */ // int max_worker_processes;
+ /* 220 | 4 */ // int max_wal_senders;
+ /* 224 | 4 */ // int max_prepared_xacts;
+ /* 228 | 4 */ // int max_locks_per_xact;
+ /* 232 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole8")
+
+ /* 236 | 4 */ // uint32 maxAlign;
+ /* 240 | 8 */ // double floatFormat;
+ /* 248 | 4 */ // uint32 blcksz;
+ /* 252 | 4 */ // uint32 relseg_size;
+ /* 256 | 4 */ // uint32 xlog_blcksz;
+ /* 260 | 4 */ // uint32 xlog_seg_size;
+ /* 264 | 4 */ // uint32 nameDataLen;
+ /* 268 | 4 */ // uint32 indexMaxKeys;
+ /* 272 | 4 */ // uint32 toast_max_chunk_size;
+ /* 276 | 4 */ // uint32 loblksize;
+ /* 280 | 1 */ // _Bool float8ByVal;
+ /* XXX 3-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole9")
+
+ /* 284 | 4 */ // uint32 data_checksum_version;
+ /* 288 | 32 */ // char mock_authentication_nonce[32];
+ /* 320 | 4 */ // pg_icu_version icu_version;
+ /* 324 | 4 */ // uint32 pg_old_version;
+ /* 328 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("icu_version", common.IcuVersionMapper)
+ d.FieldU32("pg_old_version")
+ d.FieldU32("crc")
+ d.FieldU32("padding0")
+ /* total size (bytes): 336 */
+
+ d.AssertPos(336 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/pgproee15/pg_control.go b/format/postgres/flavours/pgproee15/pg_control.go
new file mode 100644
index 000000000..db1e9d92d
--- /dev/null
+++ b/format/postgres/flavours/pgproee15/pg_control.go
@@ -0,0 +1,224 @@
+package pgproee15
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 120 */ // CheckPoint checkPointCopy;
+/* 160 | 8 */ // XLogRecPtr unloggedLSN;
+/* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 184 | 8 */ // XLogRecPtr backupStartPoint;
+/* 192 | 8 */ // XLogRecPtr backupEndPoint;
+/* 200 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // int wal_level;
+/* 208 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 212 | 4 */ // int MaxConnections;
+/* 216 | 4 */ // int max_worker_processes;
+/* 220 | 4 */ // int max_wal_senders;
+/* 224 | 4 */ // int max_prepared_xacts;
+/* 228 | 4 */ // int max_locks_per_xact;
+/* 232 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 236 | 4 */ // uint32 maxAlign;
+/* 240 | 8 */ // double floatFormat;
+/* 248 | 4 */ // uint32 blcksz;
+/* 252 | 4 */ // uint32 relseg_size;
+/* 256 | 4 */ // uint32 xlog_blcksz;
+/* 260 | 4 */ // uint32 xlog_seg_size;
+/* 264 | 4 */ // uint32 nameDataLen;
+/* 268 | 4 */ // uint32 indexMaxKeys;
+/* 272 | 4 */ // uint32 toast_max_chunk_size;
+/* 276 | 4 */ // uint32 loblksize;
+/* 280 | 1 */ // _Bool float8ByVal;
+/* XXX 3-byte hole */
+/* 284 | 4 */ // uint32 data_checksum_version;
+/* 288 | 32 */ // char mock_authentication_nonce[32];
+/* 320 | 4 */ // uint32 pg_old_version;
+/* 324 | 4 */ // pg_crc32c crc;
+
+/* total size (bytes): 328 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextXid;
+/* 32 | 4 */ // Oid nextOid;
+/* XXX 4-byte hole */
+/* 40 | 8 */ // MultiXactId nextMulti;
+/* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+/* 56 | 8 */ // TransactionId oldestXid;
+/* 64 | 4 */ // Oid oldestXidDB;
+/* XXX 4-byte hole */
+/* 72 | 8 */ // MultiXactId oldestMulti;
+/* 80 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 88 | 8 */ // pg_time_t time;
+/* 96 | 8 */ // TransactionId oldestCommitTsXid;
+/* 104 | 8 */ // TransactionId newestCommitTsXid;
+/* 112 | 8 */ // TransactionId oldestActiveXid;
+//
+/* total size (bytes): 120 */
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version", common.VersionMapper)
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 120 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("hole2")
+
+ /* 40 | 8 */ // MultiXactId nextMulti;
+ /* 48 | 8 */ // MultiXactOffset nextMultiOffset;
+ /* 56 | 8 */ // TransactionId oldestXid;
+ /* 64 | 4 */ // Oid oldestXidDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_multi")
+ d.FieldU64("next_multi_offset")
+ d.FieldU64("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("hole3")
+
+ /* 72 | 8 */ // MultiXactId oldestMulti;
+ /* 80 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole4")
+
+ /* 88 | 8 */ // pg_time_t time;
+ /* 96 | 8 */ // TransactionId oldestCommitTsXid;
+ /* 104 | 8 */ // TransactionId newestCommitTsXid;
+ /* 112 | 8 */ // TransactionId oldestActiveXid;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("oldest_commit_ts_xid")
+ d.FieldU64("newest_commit_ts_xid")
+ d.FieldU64("oldest_active_xid")
+ })
+
+ /* 160 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 168 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 176 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole5")
+
+ /* 184 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 192 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 200 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // int wal_level;
+ /* 208 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole7")
+
+ /* 212 | 4 */ // int MaxConnections;
+ /* 216 | 4 */ // int max_worker_processes;
+ /* 220 | 4 */ // int max_wal_senders;
+ /* 224 | 4 */ // int max_prepared_xacts;
+ /* 228 | 4 */ // int max_locks_per_xact;
+ /* 232 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole8")
+
+ /* 236 | 4 */ // uint32 maxAlign;
+ /* 240 | 8 */ // double floatFormat;
+ /* 248 | 4 */ // uint32 blcksz;
+ /* 252 | 4 */ // uint32 relseg_size;
+ /* 256 | 4 */ // uint32 xlog_blcksz;
+ /* 260 | 4 */ // uint32 xlog_seg_size;
+ /* 264 | 4 */ // uint32 nameDataLen;
+ /* 268 | 4 */ // uint32 indexMaxKeys;
+ /* 272 | 4 */ // uint32 toast_max_chunk_size;
+ /* 276 | 4 */ // uint32 loblksize;
+ /* 280 | 1 */ // _Bool float8ByVal;
+ /* XXX 3-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole9")
+
+ /* 284 | 4 */ // uint32 data_checksum_version;
+ /* 288 | 32 */ // char mock_authentication_nonce[32];
+ /* 320 | 4 */ // pg_icu_version icu_version;
+ /* 324 | 4 */ // uint32 pg_old_version;
+ /* 328 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("pg_old_version")
+ d.FieldU32("crc")
+ /* total size (bytes): 328 */
+
+ d.AssertPos(328 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/postgres10/pg_control.go b/format/postgres/flavours/postgres10/pg_control.go
new file mode 100644
index 000000000..ba5e37e34
--- /dev/null
+++ b/format/postgres/flavours/postgres10/pg_control.go
@@ -0,0 +1,224 @@
+package postgres10
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+//type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 8 */ // XLogRecPtr prevCheckPoint;
+/* 48 | 80 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint;
+/* 160 | 8 */ // XLogRecPtr backupEndPoint;
+/* 168 | 1 */ // bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level;
+/* 176 | 1 */ // bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections;
+/* 184 | 4 */ // int max_worker_processes;
+/* 188 | 4 */ // int max_prepared_xacts;
+/* 192 | 4 */ // int max_locks_per_xact;
+/* 196 | 1 */ // bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 200 | 4 */ // uint32 maxAlign;
+/* XXX 4-byte hole */
+/* 208 | 8 */ // double floatFormat;
+/* 216 | 4 */ // uint32 blcksz;
+/* 220 | 4 */ // uint32 relseg_size;
+/* 224 | 4 */ // uint32 xlog_blcksz;
+/* 228 | 4 */ // uint32 xlog_seg_size;
+/* 232 | 4 */ // uint32 nameDataLen;
+/* 236 | 4 */ // uint32 indexMaxKeys;
+/* 240 | 4 */ // uint32 toast_max_chunk_size;
+/* 244 | 4 */ // uint32 loblksize;
+/* 248 | 1 */ // bool float4ByVal;
+/* 249 | 1 */ // bool float8ByVal;
+/* XXX 2-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version;
+/* 256 | 32 */ // char mock_authentication_nonce[32];
+/* 288 | 4 */ // pg_crc32c crc;
+/* XXX 4-byte padding */
+
+/* total size (bytes): 296 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // bool fullPageWrites;
+/* XXX 3-byte hole */
+/* 20 | 4 */ // uint32 nextXidEpoch;
+/* 24 | 4 */ // TransactionId nextXid;
+/* 28 | 4 */ // Oid nextOid;
+/* 32 | 4 */ // MultiXactId nextMulti;
+/* 36 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 40 | 4 */ // TransactionId oldestXid;
+/* 44 | 4 */ // Oid oldestXidDB;
+/* 48 | 4 */ // MultiXactId oldestMulti;
+/* 52 | 4 */ // Oid oldestMultiDB;
+/* 56 | 8 */ // pg_time_t time;
+/* 64 | 4 */ // TransactionId oldestCommitTsXid;
+/* 68 | 4 */ // TransactionId newestCommitTsXid;
+/* 72 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+
+/* total size (bytes): 80 */
+//
+
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version")
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 8 */ // XLogRecPtr prevCheckPoint;
+ /* 48 | 80 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldU64("prev_check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 3-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU24("hole1")
+
+ /* 20 | 4 */ // uint32 nextXidEpoch;
+ /* 24 | 4 */ // TransactionId nextXid;
+ /* 28 | 4 */ // Oid nextOid;
+ /* 32 | 4 */ // MultiXactId nextMulti;
+ /* 36 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 40 | 4 */ // TransactionId oldestXid;
+ /* 44 | 4 */ // Oid oldestXidDB;
+ /* 48 | 4 */ // MultiXactId oldestMulti;
+ /* 52 | 4 */ // Oid oldestMultiDB;
+ /* 56 | 8 */ // pg_time_t time;
+ /* 64 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 68 | 4 */ // TransactionId newestCommitTsXid;
+ /* 72 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldU32("next_xid_epoch")
+ d.FieldU32("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole2")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole3")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole4")
+
+ /* 180 | 4 */ // int MaxConnections;
+ /* 184 | 4 */ // int max_worker_processes;
+ /* 188 | 4 */ // int max_prepared_xacts;
+ /* 192 | 4 */ // int max_locks_per_xact;
+ /* 196 | 1 */ // bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole5")
+
+ /* 200 | 4 */ // uint32 maxAlign;
+ /* XXX 4-byte hole */
+ d.FieldU32("max_align")
+ d.FieldU32("hole6")
+
+ /* 208 | 8 */ // double floatFormat;
+ /* 216 | 4 */ // uint32 blcksz;
+ /* 220 | 4 */ // uint32 relseg_size;
+ /* 224 | 4 */ // uint32 xlog_blcksz;
+ /* 228 | 4 */ // uint32 xlog_seg_size;
+ /* 232 | 4 */ // uint32 nameDataLen;
+ /* 236 | 4 */ // uint32 indexMaxKeys;
+ /* 240 | 4 */ // uint32 toast_max_chunk_size;
+ /* 244 | 4 */ // uint32 loblksize;
+ /* 248 | 1 */ // bool float4ByVal;
+ /* 249 | 1 */ // bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("crc")
+ d.FieldU32("padding1")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/postgres11/pg_control.go b/format/postgres/flavours/postgres11/pg_control.go
new file mode 100644
index 000000000..cc4a76ccb
--- /dev/null
+++ b/format/postgres/flavours/postgres11/pg_control.go
@@ -0,0 +1,220 @@
+package postgres11
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 80 */ // CheckPoint checkPointCopy;
+/* 120 | 8 */ // XLogRecPtr unloggedLSN;
+/* 128 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 136 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 144 | 8 */ // XLogRecPtr backupStartPoint;
+/* 152 | 8 */ // XLogRecPtr backupEndPoint;
+/* 160 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 164 | 4 */ // int wal_level;
+/* 168 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int MaxConnections;
+/* 176 | 4 */ // int max_worker_processes;
+/* 180 | 4 */ // int max_prepared_xacts;
+/* 184 | 4 */ // int max_locks_per_xact;
+/* 188 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 192 | 4 */ // uint32 maxAlign;
+/* XXX 4-byte hole */
+/* 200 | 8 */ // double floatFormat;
+/* 208 | 4 */ // uint32 blcksz;
+/* 212 | 4 */ // uint32 relseg_size;
+/* 216 | 4 */ // uint32 xlog_blcksz;
+/* 220 | 4 */ // uint32 xlog_seg_size;
+/* 224 | 4 */ // uint32 nameDataLen;
+/* 228 | 4 */ // uint32 indexMaxKeys;
+/* 232 | 4 */ // uint32 toast_max_chunk_size;
+/* 236 | 4 */ // uint32 loblksize;
+/* 240 | 1 */ // _Bool float4ByVal;
+/* 241 | 1 */ // _Bool float8ByVal;
+/* XXX 2-byte hole */
+/* 244 | 4 */ // uint32 data_checksum_version;
+/* 248 | 32 */ // char mock_authentication_nonce[32];
+/* 280 | 4 */ // pg_crc32c crc;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 288 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 3-byte hole */
+/* 20 | 4 */ // uint32 nextXidEpoch;
+/* 24 | 4 */ // TransactionId nextXid;
+/* 28 | 4 */ // Oid nextOid;
+/* 32 | 4 */ // MultiXactId nextMulti;
+/* 36 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 40 | 4 */ // TransactionId oldestXid;
+/* 44 | 4 */ // Oid oldestXidDB;
+/* 48 | 4 */ // MultiXactId oldestMulti;
+/* 52 | 4 */ // Oid oldestMultiDB;
+/* 56 | 8 */ // pg_time_t time;
+/* 64 | 4 */ // TransactionId oldestCommitTsXid;
+/* 68 | 4 */ // TransactionId newestCommitTsXid;
+/* 72 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 80 */
+//
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version")
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 80 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 3-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU24("hole1")
+
+ /* 20 | 4 */ // uint32 nextXidEpoch;
+ /* 24 | 4 */ // TransactionId nextXid;
+ /* 28 | 4 */ // Oid nextOid;
+ /* 32 | 4 */ // MultiXactId nextMulti;
+ /* 36 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 40 | 4 */ // TransactionId oldestXid;
+ /* 44 | 4 */ // Oid oldestXidDB;
+ /* 48 | 4 */ // MultiXactId oldestMulti;
+ /* 52 | 4 */ // Oid oldestMultiDB;
+ /* 56 | 8 */ // pg_time_t time;
+ /* 64 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 68 | 4 */ // TransactionId newestCommitTsXid;
+ /* 72 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldU32("next_xid_epoch")
+ d.FieldU32("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 120 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 128 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 136 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole2")
+
+ /* 144 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 152 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 160 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole3")
+
+ /* 164 | 4 */ // int wal_level;
+ /* 168 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int MaxConnections;
+ /* 176 | 4 */ // int max_worker_processes;
+ /* 180 | 4 */ // int max_prepared_xacts;
+ /* 184 | 4 */ // int max_locks_per_xact;
+ /* 188 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole5")
+
+ /* 192 | 4 */ // uint32 maxAlign;
+ /* XXX 4-byte hole */
+ d.FieldU32("max_align")
+ d.FieldU32("hole6")
+
+ /* 200 | 8 */ // double floatFormat;
+ /* 208 | 4 */ // uint32 blcksz;
+ /* 212 | 4 */ // uint32 relseg_size;
+ /* 216 | 4 */ // uint32 xlog_blcksz;
+ /* 220 | 4 */ // uint32 xlog_seg_size;
+ /* 224 | 4 */ // uint32 nameDataLen;
+ /* 228 | 4 */ // uint32 indexMaxKeys;
+ /* 232 | 4 */ // uint32 toast_max_chunk_size;
+ /* 236 | 4 */ // uint32 loblksize;
+ /* 240 | 1 */ // _Bool float4ByVal;
+ /* 241 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("crc")
+ d.FieldU32("padding1")
+ /* total size (bytes): 288 */
+
+ d.AssertPos(288 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/postgres12/pg_control.go b/format/postgres/flavours/postgres12/pg_control.go
new file mode 100644
index 000000000..c0768738c
--- /dev/null
+++ b/format/postgres/flavours/postgres12/pg_control.go
@@ -0,0 +1,219 @@
+package postgres12
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 88 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint;
+/* 160 | 8 */ // XLogRecPtr backupEndPoint;
+/* 168 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level;
+/* 176 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections;
+/* 184 | 4 */ // int max_worker_processes;
+/* 188 | 4 */ // int max_wal_senders;
+/* 192 | 4 */ // int max_prepared_xacts;
+/* 196 | 4 */ // int max_locks_per_xact;
+/* 200 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // uint32 maxAlign;
+/* 208 | 8 */ // double floatFormat;
+/* 216 | 4 */ // uint32 blcksz;
+/* 220 | 4 */ // uint32 relseg_size;
+/* 224 | 4 */ // uint32 xlog_blcksz;
+/* 228 | 4 */ // uint32 xlog_seg_size;
+/* 232 | 4 */ // uint32 nameDataLen;
+/* 236 | 4 */ // uint32 indexMaxKeys;
+/* 240 | 4 */ // uint32 toast_max_chunk_size;
+/* 244 | 4 */ // uint32 loblksize;
+/* 248 | 1 */ // _Bool float4ByVal;
+/* 249 | 1 */ // _Bool float8ByVal;
+/* XXX 2-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version;
+/* 256 | 32 */ // char mock_authentication_nonce[32];
+/* 288 | 4 */ // pg_crc32c crc;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 296 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextFullXid;
+/* 32 | 4 */ // Oid nextOid;
+/* 36 | 4 */ // MultiXactId nextMulti;
+/* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 44 | 4 */ // TransactionId oldestXid;
+/* 48 | 4 */ // Oid oldestXidDB;
+/* 52 | 4 */ // MultiXactId oldestMulti;
+/* 56 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 64 | 8 */ // pg_time_t time;
+/* 72 | 4 */ // TransactionId oldestCommitTsXid;
+/* 76 | 4 */ // TransactionId newestCommitTsXid;
+/* 80 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 88 */
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version")
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 88 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextFullXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* 36 | 4 */ // MultiXactId nextMulti;
+ /* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 44 | 4 */ // TransactionId oldestXid;
+ /* 48 | 4 */ // Oid oldestXidDB;
+ /* 52 | 4 */ // MultiXactId oldestMulti;
+ /* 56 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_full_xid", common.NextFullXidMapper)
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole2")
+
+ /* 64 | 8 */ // pg_time_t time;
+ /* 72 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 76 | 4 */ // TransactionId newestCommitTsXid;
+ /* 80 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole3")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole5")
+
+ /* 180 | 4 */ // int MaxConnections;
+ /* 184 | 4 */ // int max_worker_processes;
+ /* 188 | 4 */ // int max_wal_senders;
+ /* 192 | 4 */ // int max_prepared_xacts;
+ /* 196 | 4 */ // int max_locks_per_xact;
+ /* 200 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // uint32 maxAlign;
+ /* 208 | 8 */ // double floatFormat;
+ /* 216 | 4 */ // uint32 blcksz;
+ /* 220 | 4 */ // uint32 relseg_size;
+ /* 224 | 4 */ // uint32 xlog_blcksz;
+ /* 228 | 4 */ // uint32 xlog_seg_size;
+ /* 232 | 4 */ // uint32 nameDataLen;
+ /* 236 | 4 */ // uint32 indexMaxKeys;
+ /* 240 | 4 */ // uint32 toast_max_chunk_size;
+ /* 244 | 4 */ // uint32 loblksize;
+ /* 248 | 1 */ // _Bool float4ByVal;
+ /* 249 | 1 */ // _Bool float8ByVal;
+ /* XXX 2-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float4_by_val")
+ d.FieldU8("float8_by_val")
+ d.FieldU16("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("crc")
+ d.FieldU32("padding1")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/postgres13/pg_control.go b/format/postgres/flavours/postgres13/pg_control.go
new file mode 100644
index 000000000..f3d6d547e
--- /dev/null
+++ b/format/postgres/flavours/postgres13/pg_control.go
@@ -0,0 +1,216 @@
+package postgres13
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 88 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint
+/* 160 | 8 */ // XLogRecPtr backupEndPoint
+/* 168 | 1 */ // _Bool backupEndRequired
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level
+/* 176 | 1 */ // _Bool wal_log_hints
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections
+/* 184 | 4 */ // int max_worker_processes
+/* 188 | 4 */ // int max_wal_senders
+/* 192 | 4 */ // int max_prepared_xacts
+/* 196 | 4 */ // int max_locks_per_xact
+/* 200 | 1 */ // _Bool track_commit_timestamp
+/* XXX 3-byte hole */
+/* 204 | 4 */ // uint32 maxAlign
+/* 208 | 8 */ // double floatFormat
+/* 216 | 4 */ // uint32 blcksz
+/* 220 | 4 */ // uint32 relseg_size
+/* 224 | 4 */ // uint32 xlog_blcksz
+/* 228 | 4 */ // uint32 xlog_seg_size
+/* 232 | 4 */ // uint32 nameDataLen
+/* 236 | 4 */ // uint32 indexMaxKeys
+/* 240 | 4 */ // uint32 toast_max_chunk_size
+/* 244 | 4 */ // uint32 loblksize
+/* 248 | 1 */ // _Bool float8ByVal
+/* XXX 3-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version
+/* 256 | 32 */ // char mock_authentication_nonce[32]
+/* 288 | 4 */ // pg_crc32c crc
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 296 */
+
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextFullXid
+/* 32 | 4 */ // Oid nextOid
+/* 36 | 4 */ // MultiXactId nextMulti
+/* 40 | 4 */ // MultiXactOffset nextMultiOffset
+/* 44 | 4 */ // TransactionId oldestXid
+/* 48 | 4 */ // Oid oldestXidDB
+/* 52 | 4 */ // MultiXactId oldestMulti
+/* 56 | 4 */ // Oid oldestMultiDB
+/* XXX 4-byte hole */
+/* 64 | 8 */ // pg_time_t time
+/* 72 | 4 */ // TransactionId oldestCommitTsXid
+/* 76 | 4 */ // TransactionId newestCommitTsXid
+/* 80 | 4 */ // TransactionId oldestActiveXid
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 88 */
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version")
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 88 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextFullXid
+ /* 32 | 4 */ // Oid nextOid
+ /* 36 | 4 */ // MultiXactId nextMulti
+ /* 40 | 4 */ // MultiXactOffset nextMultiOffset
+ /* 44 | 4 */ // TransactionId oldestXid
+ /* 48 | 4 */ // Oid oldestXidDB
+ /* 52 | 4 */ // MultiXactId oldestMulti
+ /* 56 | 4 */ // Oid oldestMultiDB
+ /* XXX 4-byte hole */
+ d.FieldU64("next_full_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole2")
+
+ /* 64 | 8 */ // pg_time_t time
+ /* 72 | 4 */ // TransactionId oldestCommitTsXid
+ /* 76 | 4 */ // TransactionId newestCommitTsXid
+ /* 80 | 4 */ // TransactionId oldestActiveXid
+ /* XXX 4-byte padding */
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole3")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole5")
+
+ /* 180 | 4 */ // int MaxConnections
+ /* 184 | 4 */ // int max_worker_processes
+ /* 188 | 4 */ // int max_wal_senders
+ /* 192 | 4 */ // int max_prepared_xacts
+ /* 196 | 4 */ // int max_locks_per_xact
+ /* 200 | 1 */ // _Bool track_commit_timestamp
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // uint32 maxAlign
+ /* 208 | 8 */ // double floatFormat
+ /* 216 | 4 */ // uint32 blcksz
+ /* 220 | 4 */ // uint32 relseg_size
+ /* 224 | 4 */ // uint32 xlog_blcksz
+ /* 228 | 4 */ // uint32 xlog_seg_size
+ /* 232 | 4 */ // uint32 nameDataLen
+ /* 236 | 4 */ // uint32 indexMaxKeys
+ /* 240 | 4 */ // uint32 toast_max_chunk_size
+ /* 244 | 4 */ // uint32 loblksize
+ /* 248 | 1 */ // _Bool float8ByVal
+ /* XXX 3-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("crc")
+ d.FieldU32("padding1")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/flavours/postgres14/pg_control.go b/format/postgres/flavours/postgres14/pg_control.go
new file mode 100644
index 000000000..c9778bda3
--- /dev/null
+++ b/format/postgres/flavours/postgres14/pg_control.go
@@ -0,0 +1,216 @@
+package postgres14
+
+import (
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/scalar"
+)
+
+// type = struct ControlFileData {
+/* 0 | 8 */ // uint64 system_identifier;
+/* 8 | 4 */ // uint32 pg_control_version;
+/* 12 | 4 */ // uint32 catalog_version_no;
+/* 16 | 4 */ // DBState state;
+/* XXX 4-byte hole */
+/* 24 | 8 */ // pg_time_t time;
+/* 32 | 8 */ // XLogRecPtr checkPoint;
+/* 40 | 88 */ // CheckPoint checkPointCopy;
+/* 128 | 8 */ // XLogRecPtr unloggedLSN;
+/* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+/* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+/* XXX 4-byte hole */
+/* 152 | 8 */ // XLogRecPtr backupStartPoint;
+/* 160 | 8 */ // XLogRecPtr backupEndPoint;
+/* 168 | 1 */ // _Bool backupEndRequired;
+/* XXX 3-byte hole */
+/* 172 | 4 */ // int wal_level;
+/* 176 | 1 */ // _Bool wal_log_hints;
+/* XXX 3-byte hole */
+/* 180 | 4 */ // int MaxConnections;
+/* 184 | 4 */ // int max_worker_processes;
+/* 188 | 4 */ // int max_wal_senders;
+/* 192 | 4 */ // int max_prepared_xacts;
+/* 196 | 4 */ // int max_locks_per_xact;
+/* 200 | 1 */ // _Bool track_commit_timestamp;
+/* XXX 3-byte hole */
+/* 204 | 4 */ // uint32 maxAlign;
+/* 208 | 8 */ // double floatFormat;
+/* 216 | 4 */ // uint32 blcksz;
+/* 220 | 4 */ // uint32 relseg_size;
+/* 224 | 4 */ // uint32 xlog_blcksz;
+/* 228 | 4 */ // uint32 xlog_seg_size;
+/* 232 | 4 */ // uint32 nameDataLen;
+/* 236 | 4 */ // uint32 indexMaxKeys;
+/* 240 | 4 */ // uint32 toast_max_chunk_size;
+/* 244 | 4 */ // uint32 loblksize;
+/* 248 | 1 */ // _Bool float8ByVal;
+/* XXX 3-byte hole */
+/* 252 | 4 */ // uint32 data_checksum_version;
+/* 256 | 32 */ // char mock_authentication_nonce[32];
+/* 288 | 4 */ // pg_crc32c crc;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 296 */
+//
+// type = struct CheckPoint {
+/* 0 | 8 */ // XLogRecPtr redo;
+/* 8 | 4 */ // TimeLineID ThisTimeLineID;
+/* 12 | 4 */ // TimeLineID PrevTimeLineID;
+/* 16 | 1 */ // _Bool fullPageWrites;
+/* XXX 7-byte hole */
+/* 24 | 8 */ // FullTransactionId nextXid;
+/* 32 | 4 */ // Oid nextOid;
+/* 36 | 4 */ // MultiXactId nextMulti;
+/* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+/* 44 | 4 */ // TransactionId oldestXid;
+/* 48 | 4 */ // Oid oldestXidDB;
+/* 52 | 4 */ // MultiXactId oldestMulti;
+/* 56 | 4 */ // Oid oldestMultiDB;
+/* XXX 4-byte hole */
+/* 64 | 8 */ // pg_time_t time;
+/* 72 | 4 */ // TransactionId oldestCommitTsXid;
+/* 76 | 4 */ // TransactionId newestCommitTsXid;
+/* 80 | 4 */ // TransactionId oldestActiveXid;
+/* XXX 4-byte padding */
+//
+/* total size (bytes): 88 */
+func DecodePgControl(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ /* 12 | 4 */ // uint32 catalog_version_no;
+ /* 16 | 4 */ // DBState state;
+ /* XXX 4-byte hole */
+ d.FieldU64("system_identifier")
+ d.FieldU32("pg_control_version")
+ d.FieldU32("catalog_version_no")
+ d.FieldU32("state", common.DBState)
+ d.FieldU32("hole0")
+
+ /* 24 | 8 */ // pg_time_t time;
+ /* 32 | 8 */ // XLogRecPtr checkPoint;
+ /* 40 | 88 */ // CheckPoint checkPointCopy;
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU64("check_point", common.XLogRecPtrMapper)
+ d.FieldStruct("check_point_copy", func(d *decode.D) {
+ /* 0 | 8 */ // XLogRecPtr redo;
+ /* 8 | 4 */ // TimeLineID ThisTimeLineID;
+ /* 12 | 4 */ // TimeLineID PrevTimeLineID;
+ /* 16 | 1 */ // _Bool fullPageWrites;
+ /* XXX 7-byte hole */
+ d.FieldU64("redo", common.XLogRecPtrMapper)
+ d.FieldU32("this_time_line_id")
+ d.FieldU32("prev_time_line_id")
+ d.FieldU8("full_page_writes")
+ d.FieldU56("hole1")
+
+ /* 24 | 8 */ // FullTransactionId nextXid;
+ /* 32 | 4 */ // Oid nextOid;
+ /* 36 | 4 */ // MultiXactId nextMulti;
+ /* 40 | 4 */ // MultiXactOffset nextMultiOffset;
+ /* 44 | 4 */ // TransactionId oldestXid;
+ /* 48 | 4 */ // Oid oldestXidDB;
+ /* 52 | 4 */ // MultiXactId oldestMulti;
+ /* 56 | 4 */ // Oid oldestMultiDB;
+ /* XXX 4-byte hole */
+ d.FieldU64("next_xid")
+ d.FieldU32("next_oid")
+ d.FieldU32("next_multi")
+ d.FieldU32("next_multi_offset")
+ d.FieldU32("oldest_xid")
+ d.FieldU32("oldest_xid_db")
+ d.FieldU32("oldest_multi")
+ d.FieldU32("oldest_multi_db")
+ d.FieldU32("hole2")
+
+ /* 64 | 8 */ // pg_time_t time;
+ /* 72 | 4 */ // TransactionId oldestCommitTsXid;
+ /* 76 | 4 */ // TransactionId newestCommitTsXid;
+ /* 80 | 4 */ // TransactionId oldestActiveXid;
+ /* XXX 4-byte padding */
+ d.FieldS64("time", common.TimeMapper)
+ d.FieldU32("oldest_commit_ts_xid")
+ d.FieldU32("newest_commit_ts_xid")
+ d.FieldU32("oldest_active_xid")
+ d.FieldU32("padding0")
+ })
+
+ /* 128 | 8 */ // XLogRecPtr unloggedLSN;
+ /* 136 | 8 */ // XLogRecPtr minRecoveryPoint;
+ /* 144 | 4 */ // TimeLineID minRecoveryPointTLI;
+ /* XXX 4-byte hole */
+ d.FieldU64("unlogged_lsn", common.LocPtrMapper)
+ d.FieldU64("min_recovery_point", common.LocPtrMapper)
+ d.FieldU32("min_recovery_point_tli")
+ d.FieldU32("hole3")
+
+ /* 152 | 8 */ // XLogRecPtr backupStartPoint;
+ /* 160 | 8 */ // XLogRecPtr backupEndPoint;
+ /* 168 | 1 */ // _Bool backupEndRequired;
+ /* XXX 3-byte hole */
+ d.FieldU64("backup_start_point", common.LocPtrMapper)
+ d.FieldU64("backup_end_point", common.LocPtrMapper)
+ d.FieldU8("backup_end_required")
+ d.FieldU24("hole4")
+
+ /* 172 | 4 */ // int wal_level;
+ /* 176 | 1 */ // _Bool wal_log_hints;
+ /* XXX 3-byte hole */
+ d.FieldS32("wal_level", common.WalLevel)
+ d.FieldU8("wal_log_hints")
+ d.FieldU24("hole5")
+
+ /* 180 | 4 */ // int MaxConnections;
+ /* 184 | 4 */ // int max_worker_processes;
+ /* 188 | 4 */ // int max_wal_senders;
+ /* 192 | 4 */ // int max_prepared_xacts;
+ /* 196 | 4 */ // int max_locks_per_xact;
+ /* 200 | 1 */ // _Bool track_commit_timestamp;
+ /* XXX 3-byte hole */
+ d.FieldS32("max_connections")
+ d.FieldS32("max_worker_processes")
+ d.FieldS32("max_wal_senders")
+ d.FieldS32("max_prepared_xacts")
+ d.FieldS32("max_locks_per_xact")
+ d.FieldU8("track_commit_timestamp")
+ d.FieldU24("hole6")
+
+ /* 204 | 4 */ // uint32 maxAlign;
+ /* 208 | 8 */ // double floatFormat;
+ /* 216 | 4 */ // uint32 blcksz;
+ /* 220 | 4 */ // uint32 relseg_size;
+ /* 224 | 4 */ // uint32 xlog_blcksz;
+ /* 228 | 4 */ // uint32 xlog_seg_size;
+ /* 232 | 4 */ // uint32 nameDataLen;
+ /* 236 | 4 */ // uint32 indexMaxKeys;
+ /* 240 | 4 */ // uint32 toast_max_chunk_size;
+ /* 244 | 4 */ // uint32 loblksize;
+ /* 248 | 1 */ // _Bool float8ByVal;
+ /* XXX 3-byte hole */
+ d.FieldU32("max_align")
+ d.FieldF64("float_format")
+ d.FieldU32("blcksz")
+ d.FieldU32("relseg_size")
+ d.FieldU32("xlog_blcksz")
+ d.FieldU32("xlog_seg_size")
+ d.FieldU32("name_data_len")
+ d.FieldU32("index_max_keys")
+ d.FieldU32("toast_max_chunk_size")
+ d.FieldU32("loblksize")
+ d.FieldU8("float8_by_val")
+ d.FieldU24("hole7")
+
+ /* 252 | 4 */ // uint32 data_checksum_version;
+ /* 256 | 32 */ // char mock_authentication_nonce[32];
+ /* 288 | 4 */ // pg_crc32c crc;
+ /* XXX 4-byte padding */
+ d.FieldU32("data_checksum_version")
+ d.FieldRawLen("mock_authentication_nonce", 32*8, scalar.RawHex)
+ d.FieldU32("crc")
+ d.FieldU32("padding1")
+ /* total size (bytes): 296 */
+
+ d.AssertPos(296 * 8)
+ d.FieldRawLen("unused", d.BitsLeft())
+
+ return nil
+}
diff --git a/format/postgres/pg_btree.go b/format/postgres/pg_btree.go
new file mode 100644
index 000000000..9df49ac42
--- /dev/null
+++ b/format/postgres/pg_btree.go
@@ -0,0 +1,37 @@
+package postgres
+
+import (
+ "embed"
+
+ "github.com/wader/fq/format/postgres/common/pg_btree/postgres"
+
+ "github.com/wader/fq/format"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/interp"
+)
+
+//go:embed pg_btree.md
+var pgBTreeFS embed.FS
+
+func init() {
+ interp.RegisterFormat(format.Pg_BTree, &decode.Format{
+ Description: "PostgreSQL btree index file",
+ DecodeFn: decodePgBTree,
+ DefaultInArg: format.Pg_BTree_In{
+ Page: 0,
+ },
+ RootArray: true,
+ RootName: "pages",
+ })
+ interp.RegisterFS(pgBTreeFS)
+}
+
+func decodePgBTree(d *decode.D) any {
+ d.Endian = decode.LittleEndian
+ var pgIn format.Pg_BTree_In
+ if !d.ArgAs(&pgIn) {
+ d.Fatalf("no page specified")
+ }
+ postgres.DecodePgBTree(d, pgIn.Page)
+ return nil
+}
diff --git a/format/postgres/pg_btree.md b/format/postgres/pg_btree.md
new file mode 100644
index 000000000..80a16bc2c
--- /dev/null
+++ b/format/postgres/pg_btree.md
@@ -0,0 +1,19 @@
+### Btree index meta page
+
+```sh
+$ fq -d pg_btree -o flavour=postgres14 ".[0] | d" 16404
+```
+
+### Btree index page
+
+```sh
+$ fq -d pg_btree -o flavour=postgres14 ".[1]" 16404
+```
+
+### Authors
+- Pavel Safonov
+p.n.safonov@gmail.com
+[@pnsafonov](https://github.com/pnsafonov)
+
+### References
+- https://www.postgresql.org/docs/current/storage-page-layout.html
\ No newline at end of file
diff --git a/format/postgres/pg_control.go b/format/postgres/pg_control.go
new file mode 100644
index 000000000..de0c4cabb
--- /dev/null
+++ b/format/postgres/pg_control.go
@@ -0,0 +1,171 @@
+package postgres
+
+import (
+ "embed"
+
+ "github.com/wader/fq/format"
+ "github.com/wader/fq/format/postgres/common"
+ "github.com/wader/fq/format/postgres/flavours/pgpro10"
+ "github.com/wader/fq/format/postgres/flavours/pgpro11"
+ "github.com/wader/fq/format/postgres/flavours/pgpro12"
+ "github.com/wader/fq/format/postgres/flavours/pgpro13"
+ "github.com/wader/fq/format/postgres/flavours/pgpro14"
+ "github.com/wader/fq/format/postgres/flavours/pgproee10"
+ "github.com/wader/fq/format/postgres/flavours/pgproee11"
+ "github.com/wader/fq/format/postgres/flavours/pgproee12"
+ "github.com/wader/fq/format/postgres/flavours/pgproee13"
+ "github.com/wader/fq/format/postgres/flavours/pgproee14"
+ "github.com/wader/fq/format/postgres/flavours/pgproee15"
+ "github.com/wader/fq/format/postgres/flavours/postgres10"
+ "github.com/wader/fq/format/postgres/flavours/postgres11"
+ "github.com/wader/fq/format/postgres/flavours/postgres12"
+ "github.com/wader/fq/format/postgres/flavours/postgres13"
+ "github.com/wader/fq/format/postgres/flavours/postgres14"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/interp"
+)
+
+//go:embed pg_control.md
+var pgControlFS embed.FS
+
+func init() {
+ interp.RegisterFormat(format.Pg_Control, &decode.Format{
+ Description: "PostgreSQL control file",
+ DecodeFn: decodePgControl,
+ DefaultInArg: format.Pg_Control_In{
+ Flavour: "",
+ },
+ })
+ interp.RegisterFS(pgControlFS)
+}
+
+const (
+ PG_CONTROL_VERSION_10 = 1002
+ PG_CONTROL_VERSION_11 = 1100
+ PGPRO_CONTROL_VERSION_11 = 1200
+ PG_CONTROL_VERSION_12 = 1201
+ //PG_CONTROL_VERSION_13 = 1300
+ PG_CONTROL_VERSION_14 = 1300
+ //PG_CONTROL_VERSION_15 = 1300
+)
+
+const (
+ PG_FLAVOUR_POSTGRES10 = "postgres10"
+ PG_FLAVOUR_POSTGRES11 = "postgres11"
+ PG_FLAVOUR_POSTGRES12 = "postgres12"
+ PG_FLAVOUR_POSTGRES13 = "postgres13"
+ PG_FLAVOUR_POSTGRES14 = "postgres14"
+ PG_FLAVOUR_POSTGRES15 = "postgres15"
+ PG_FLAVOUR_PGPRO10 = "pgpro10"
+ PG_FLAVOUR_PGPRO11 = "pgpro11"
+ PG_FLAVOUR_PGPRO12 = "pgpro12"
+ PG_FLAVOUR_PGPRO13 = "pgpro13"
+ PG_FLAVOUR_PGPRO14 = "pgpro14"
+ PG_FLAVOUR_PGPRO15 = "pgpro15"
+ PG_FLAVOUR_PGPROEE10 = "pgproee10"
+ PG_FLAVOUR_PGPROEE11 = "pgproee11"
+ PG_FLAVOUR_PGPROEE12 = "pgproee12"
+ PG_FLAVOUR_PGPROEE13 = "pgproee13"
+ PG_FLAVOUR_PGPROEE14 = "pgproee14"
+ PG_FLAVOUR_PGPROEE15 = "pgproee15"
+)
+
+func decodePgControl(d *decode.D) any {
+ d.Endian = decode.LittleEndian
+
+ var pgIn format.Pg_Control_In
+ if !d.ArgAs(&pgIn) {
+ d.Fatalf("no flavour specified")
+ }
+
+ switch pgIn.Flavour {
+ case PG_FLAVOUR_POSTGRES10:
+ return postgres10.DecodePgControl(d)
+ case PG_FLAVOUR_POSTGRES11:
+ return postgres11.DecodePgControl(d)
+ case PG_FLAVOUR_POSTGRES12:
+ return postgres12.DecodePgControl(d)
+ case PG_FLAVOUR_POSTGRES13:
+ return postgres13.DecodePgControl(d)
+ case PG_FLAVOUR_POSTGRES14, PG_FLAVOUR_POSTGRES15, PG_FLAVOUR_PGPRO15:
+ return postgres14.DecodePgControl(d)
+ case PG_FLAVOUR_PGPRO10:
+ return pgpro10.DecodePgControl(d)
+ case PG_FLAVOUR_PGPRO11:
+ return pgpro11.DecodePgControl(d)
+ case PG_FLAVOUR_PGPRO12:
+ return pgpro12.DecodePgControl(d)
+ case PG_FLAVOUR_PGPRO13:
+ return pgpro13.DecodePgControl(d)
+ case PG_FLAVOUR_PGPRO14:
+ return pgpro14.DecodePgControl(d)
+ case PG_FLAVOUR_PGPROEE10:
+ return pgproee10.DecodePgControl(d)
+ case PG_FLAVOUR_PGPROEE11:
+ return pgproee11.DecodePgControl(d)
+ case PG_FLAVOUR_PGPROEE12:
+ return pgproee12.DecodePgControl(d)
+ case PG_FLAVOUR_PGPROEE13:
+ return pgproee13.DecodePgControl(d)
+ case PG_FLAVOUR_PGPROEE14:
+ return pgproee14.DecodePgControl(d)
+ case PG_FLAVOUR_PGPROEE15:
+ return pgproee15.DecodePgControl(d)
+ default:
+ break
+ }
+
+ return probeForDecode(d)
+}
+
+func probeForDecode(d *decode.D) any {
+ /* 0 | 8 */ // uint64 system_identifier;
+ /* 8 | 4 */ // uint32 pg_control_version;
+ d.U64()
+ pgControlVersion := d.U32()
+ d.SeekAbs(0)
+
+ pgProVersion, oriVersion := common.ParsePgProVersion(uint32(pgControlVersion))
+
+ if pgProVersion == common.PG_ORIGINAL {
+ switch oriVersion {
+ case PG_CONTROL_VERSION_10:
+ return postgres10.DecodePgControl(d)
+ case PG_CONTROL_VERSION_11:
+ return postgres11.DecodePgControl(d)
+ case PG_CONTROL_VERSION_12:
+ return postgres12.DecodePgControl(d)
+ case PG_CONTROL_VERSION_14:
+ return postgres14.DecodePgControl(d)
+ }
+ }
+
+ if pgProVersion == common.PGPRO_STANDARD {
+ switch oriVersion {
+ case PG_CONTROL_VERSION_10:
+ return pgpro10.DecodePgControl(d)
+ case PG_CONTROL_VERSION_11:
+ return pgpro11.DecodePgControl(d)
+ case PG_CONTROL_VERSION_12:
+ return pgpro12.DecodePgControl(d)
+ case PG_CONTROL_VERSION_14:
+ return pgpro14.DecodePgControl(d)
+ }
+ }
+
+ if pgProVersion == common.PGPRO_ENTERPRISE {
+ switch oriVersion {
+ case PG_CONTROL_VERSION_10:
+ return pgproee10.DecodePgControl(d)
+ case PGPRO_CONTROL_VERSION_11:
+ return pgproee11.DecodePgControl(d)
+ case PG_CONTROL_VERSION_12:
+ return pgproee12.DecodePgControl(d)
+ case PG_CONTROL_VERSION_14:
+ return pgproee14.DecodePgControl(d)
+ }
+ }
+
+ d.Fatalf("unsupported PG_CONTROL_VERSION = %d", pgControlVersion)
+ return nil
+}
diff --git a/format/postgres/pg_control.md b/format/postgres/pg_control.md
new file mode 100644
index 000000000..64cd0b463
--- /dev/null
+++ b/format/postgres/pg_control.md
@@ -0,0 +1,19 @@
+### Decode content of pg_control file
+
+```sh
+$ fq -d pg_control -o flavour=postgres14 d pg_control
+```
+
+### Specific fields can be got by request
+
+```sh
+$ fq -d pg_control -o flavour=postgres14 ".state, .check_point_copy.redo, .wal_level" pg_control
+```
+
+### Authors
+- Pavel Safonov
+p.n.safonov@gmail.com
+[@pnsafonov](https://github.com/pnsafonov)
+
+### References
+- https://github.com/postgres/postgres/blob/REL_14_2/src/include/catalog/pg_control.h
\ No newline at end of file
diff --git a/format/postgres/pg_heap.go b/format/postgres/pg_heap.go
new file mode 100644
index 000000000..108210cc5
--- /dev/null
+++ b/format/postgres/pg_heap.go
@@ -0,0 +1,71 @@
+package postgres
+
+import (
+ "embed"
+
+ "github.com/wader/fq/format/postgres/common/pg_heap/pgproee"
+ "github.com/wader/fq/format/postgres/common/pg_heap/postgres"
+
+ "github.com/wader/fq/format"
+ "github.com/wader/fq/pkg/decode"
+ "github.com/wader/fq/pkg/interp"
+)
+
+// TO DO
+// oom kill on 1 GB file
+
+//go:embed pg_heap.md
+var pgHeapFS embed.FS
+
+func init() {
+ interp.RegisterFormat(format.Pg_Heap, &decode.Format{
+ Description: "PostgreSQL heap file",
+ DecodeFn: decodePgheap,
+ DefaultInArg: format.Pg_Heap_In{
+ Flavour: PG_FLAVOUR_POSTGRES14,
+ Page: 0,
+ Segment: 0,
+ },
+ RootArray: true,
+ RootName: "pages",
+ })
+ interp.RegisterFS(pgHeapFS)
+}
+
+func decodePgheap(d *decode.D) any {
+ d.Endian = decode.LittleEndian
+
+ var pgIn format.Pg_Heap_In
+ if !d.ArgAs(&pgIn) {
+ d.Fatalf("no flavour specified")
+ }
+
+ switch pgIn.Flavour {
+ case PG_FLAVOUR_POSTGRES10,
+ PG_FLAVOUR_POSTGRES11,
+ PG_FLAVOUR_POSTGRES12,
+ PG_FLAVOUR_POSTGRES13,
+ PG_FLAVOUR_POSTGRES14,
+ PG_FLAVOUR_POSTGRES15,
+ PG_FLAVOUR_PGPRO10,
+ PG_FLAVOUR_PGPRO11,
+ PG_FLAVOUR_PGPRO12,
+ PG_FLAVOUR_PGPRO13,
+ PG_FLAVOUR_PGPRO14,
+ PG_FLAVOUR_PGPRO15:
+ return postgres.DecodeHeap(d, pgIn)
+
+ case PG_FLAVOUR_PGPROEE10,
+ PG_FLAVOUR_PGPROEE11,
+ PG_FLAVOUR_PGPROEE12,
+ PG_FLAVOUR_PGPROEE13,
+ PG_FLAVOUR_PGPROEE14,
+ PG_FLAVOUR_PGPROEE15:
+ return pgproee.DecodeHeap(d, pgIn)
+
+ default:
+ break
+ }
+
+ return postgres.DecodeHeap(d, pgIn)
+}
diff --git a/format/postgres/pg_heap.md b/format/postgres/pg_heap.md
new file mode 100644
index 000000000..a783d03e2
--- /dev/null
+++ b/format/postgres/pg_heap.md
@@ -0,0 +1,30 @@
+### To see heap page's content
+```sh
+$ fq -d pg_heap -o flavour=postgres14 ".[0]" 16994
+```
+
+### To see page's header
+
+```sh
+$ fq -d pg_heap -o flavour=postgres14 ".[0].page_header" 16994
+```
+
+### First and last item pointers on first page
+
+```sh
+$ fq -d pg_heap -o flavour=postgres14 ".[0].pd_linp[0, -1]" 16994
+```
+
+### First and last tuple on first page
+
+```sh
+$ fq -d pg_heap -o flavour=postgres14 ".[0].tuples[0, -1]" 16994
+```
+
+### Authors
+- Pavel Safonov
+p.n.safonov@gmail.com
+[@pnsafonov](https://github.com/pnsafonov)
+
+### References
+- https://www.postgresql.org/docs/current/storage-page-layout.html
\ No newline at end of file
diff --git a/format/postgres/testdata/flavours/pgpro10/16396 b/format/postgres/testdata/flavours/pgpro10/16396
new file mode 100644
index 000000000..313a45cde
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro10/16396 differ
diff --git a/format/postgres/testdata/flavours/pgpro10/16396_1.fqtest b/format/postgres/testdata/flavours/pgpro10/16396_1.fqtest
new file mode 100644
index 000000000..1cdf666a7
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro10 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x108-0x10b.7 (4)
+0x100| 80 81 f2 00 | .... | item_id_data: 15892864 0x108-0x10b.7 (4)
+ | | | lp_off: 384 0x10c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x10c-NA (0)
+ | | | lp_len: 121 0x10c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro10/16401 b/format/postgres/testdata/flavours/pgpro10/16401
new file mode 100644
index 000000000..cf41ea277
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro10/16401 differ
diff --git a/format/postgres/testdata/flavours/pgpro10/16401_1.fqtest b/format/postgres/testdata/flavours/pgpro10/16401_1.fqtest
new file mode 100644
index 000000000..8c31d3965
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/16401_1.fqtest
@@ -0,0 +1,51 @@
+$ fq -d pg_btree ".[1].pd_linp[0,1,2,3,4,5,6,7,8,9] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[0]{}: item_id 0x2018-0x201b.7 (4)
+0x2010| 00 89 20 00 | .. . | item_id_data: 2132224 0x2018-0x201b.7 (4)
+ | | | lp_off: 2304 0x201c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x201c-NA (0)
+ | | | lp_len: 16 0x201c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[1]{}: item_id 0x201c-0x201f.7 (4)
+0x2010| e0 9f 20 00| .. .| item_id_data: 2138080 0x201c-0x201f.7 (4)
+ | | | lp_off: 8160 0x2020-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2020-NA (0)
+ | | | lp_len: 16 0x2020-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[2]{}: item_id 0x2020-0x2023.7 (4)
+0x2020|d0 9f 20 00 |.. . | item_id_data: 2138064 0x2020-0x2023.7 (4)
+ | | | lp_off: 8144 0x2024-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2024-NA (0)
+ | | | lp_len: 16 0x2024-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[3]{}: item_id 0x2024-0x2027.7 (4)
+0x2020| c0 9f 20 00 | .. . | item_id_data: 2138048 0x2024-0x2027.7 (4)
+ | | | lp_off: 8128 0x2028-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2028-NA (0)
+ | | | lp_len: 16 0x2028-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[4]{}: item_id 0x2028-0x202b.7 (4)
+0x2020| b0 9f 20 00 | .. . | item_id_data: 2138032 0x2028-0x202b.7 (4)
+ | | | lp_off: 8112 0x202c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x202c-NA (0)
+ | | | lp_len: 16 0x202c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[5]{}: item_id 0x202c-0x202f.7 (4)
+0x2020| a0 9f 20 00| .. .| item_id_data: 2138016 0x202c-0x202f.7 (4)
+ | | | lp_off: 8096 0x2030-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2030-NA (0)
+ | | | lp_len: 16 0x2030-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[6]{}: item_id 0x2030-0x2033.7 (4)
+0x2030|90 9f 20 00 |.. . | item_id_data: 2138000 0x2030-0x2033.7 (4)
+ | | | lp_off: 8080 0x2034-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2034-NA (0)
+ | | | lp_len: 16 0x2034-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[7]{}: item_id 0x2034-0x2037.7 (4)
+0x2030| 80 9f 20 00 | .. . | item_id_data: 2137984 0x2034-0x2037.7 (4)
+ | | | lp_off: 8064 0x2038-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2038-NA (0)
+ | | | lp_len: 16 0x2038-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[8]{}: item_id 0x2038-0x203b.7 (4)
+0x2030| 70 9f 20 00 | p. . | item_id_data: 2137968 0x2038-0x203b.7 (4)
+ | | | lp_off: 8048 0x203c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x203c-NA (0)
+ | | | lp_len: 16 0x203c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[9]{}: item_id 0x203c-0x203f.7 (4)
+0x2030| 60 9f 20 00| `. .| item_id_data: 2137952 0x203c-0x203f.7 (4)
+ | | | lp_off: 8032 0x2040-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2040-NA (0)
+ | | | lp_len: 16 0x2040-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro10/16401_2.fqtest b/format/postgres/testdata/flavours/pgpro10/16401_2.fqtest
new file mode 100644
index 000000000..5bf56024c
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/16401_2.fqtest
@@ -0,0 +1,111 @@
+$ fq -d pg_btree ".[1].tuples[0,1,2,3,4,5,6,7,8,9] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[0]{}: tuple 0x2900-0x290f.7 (16)
+ | | | index_tuple_data{}: 0x2900-0x290f.7 (16)
+ | | | t_tid{}: 0x2900-0x2905.7 (6)
+0x2900|00 00 06 00 |.... | ip_blkid: 393216 0x2900-0x2903.7 (4)
+0x2900| 01 00 | .. | ip_posid: 1 0x2904-0x2905.7 (2)
+0x2900| 10 00 | .. | t_info: 16 0x2906-0x2907.7 (2)
+ | | | flags{}: 0x2908-NA (0)
+ | | | has_nulls: false 0x2908-NA (0)
+ | | | has_var_widths: false 0x2908-NA (0)
+ | | | size: 16 0x2908-NA (0)
+0x2900| 6f 01 00 00 00 00 00 00| o.......| data: raw bits 0x2908-0x290f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[1]{}: tuple 0x3fe0-0x3fef.7 (16)
+ | | | index_tuple_data{}: 0x3fe0-0x3fef.7 (16)
+ | | | t_tid{}: 0x3fe0-0x3fe5.7 (6)
+0x3fe0|00 00 00 00 |.... | ip_blkid: 0 0x3fe0-0x3fe3.7 (4)
+0x3fe0| 01 00 | .. | ip_posid: 1 0x3fe4-0x3fe5.7 (2)
+0x3fe0| 10 00 | .. | t_info: 16 0x3fe6-0x3fe7.7 (2)
+ | | | flags{}: 0x3fe8-NA (0)
+ | | | has_nulls: false 0x3fe8-NA (0)
+ | | | has_var_widths: false 0x3fe8-NA (0)
+ | | | size: 16 0x3fe8-NA (0)
+0x3fe0| 01 00 00 00 00 00 00 00| ........| data: raw bits 0x3fe8-0x3fef.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[2]{}: tuple 0x3fd0-0x3fdf.7 (16)
+ | | | index_tuple_data{}: 0x3fd0-0x3fdf.7 (16)
+ | | | t_tid{}: 0x3fd0-0x3fd5.7 (6)
+0x3fd0|00 00 00 00 |.... | ip_blkid: 0 0x3fd0-0x3fd3.7 (4)
+0x3fd0| 02 00 | .. | ip_posid: 2 0x3fd4-0x3fd5.7 (2)
+0x3fd0| 10 00 | .. | t_info: 16 0x3fd6-0x3fd7.7 (2)
+ | | | flags{}: 0x3fd8-NA (0)
+ | | | has_nulls: false 0x3fd8-NA (0)
+ | | | has_var_widths: false 0x3fd8-NA (0)
+ | | | size: 16 0x3fd8-NA (0)
+0x3fd0| 02 00 00 00 00 00 00 00| ........| data: raw bits 0x3fd8-0x3fdf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[3]{}: tuple 0x3fc0-0x3fcf.7 (16)
+ | | | index_tuple_data{}: 0x3fc0-0x3fcf.7 (16)
+ | | | t_tid{}: 0x3fc0-0x3fc5.7 (6)
+0x3fc0|00 00 00 00 |.... | ip_blkid: 0 0x3fc0-0x3fc3.7 (4)
+0x3fc0| 03 00 | .. | ip_posid: 3 0x3fc4-0x3fc5.7 (2)
+0x3fc0| 10 00 | .. | t_info: 16 0x3fc6-0x3fc7.7 (2)
+ | | | flags{}: 0x3fc8-NA (0)
+ | | | has_nulls: false 0x3fc8-NA (0)
+ | | | has_var_widths: false 0x3fc8-NA (0)
+ | | | size: 16 0x3fc8-NA (0)
+0x3fc0| 03 00 00 00 00 00 00 00| ........| data: raw bits 0x3fc8-0x3fcf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[4]{}: tuple 0x3fb0-0x3fbf.7 (16)
+ | | | index_tuple_data{}: 0x3fb0-0x3fbf.7 (16)
+ | | | t_tid{}: 0x3fb0-0x3fb5.7 (6)
+0x3fb0|00 00 00 00 |.... | ip_blkid: 0 0x3fb0-0x3fb3.7 (4)
+0x3fb0| 04 00 | .. | ip_posid: 4 0x3fb4-0x3fb5.7 (2)
+0x3fb0| 10 00 | .. | t_info: 16 0x3fb6-0x3fb7.7 (2)
+ | | | flags{}: 0x3fb8-NA (0)
+ | | | has_nulls: false 0x3fb8-NA (0)
+ | | | has_var_widths: false 0x3fb8-NA (0)
+ | | | size: 16 0x3fb8-NA (0)
+0x3fb0| 04 00 00 00 00 00 00 00| ........| data: raw bits 0x3fb8-0x3fbf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[5]{}: tuple 0x3fa0-0x3faf.7 (16)
+ | | | index_tuple_data{}: 0x3fa0-0x3faf.7 (16)
+ | | | t_tid{}: 0x3fa0-0x3fa5.7 (6)
+0x3fa0|00 00 00 00 |.... | ip_blkid: 0 0x3fa0-0x3fa3.7 (4)
+0x3fa0| 05 00 | .. | ip_posid: 5 0x3fa4-0x3fa5.7 (2)
+0x3fa0| 10 00 | .. | t_info: 16 0x3fa6-0x3fa7.7 (2)
+ | | | flags{}: 0x3fa8-NA (0)
+ | | | has_nulls: false 0x3fa8-NA (0)
+ | | | has_var_widths: false 0x3fa8-NA (0)
+ | | | size: 16 0x3fa8-NA (0)
+0x3fa0| 05 00 00 00 00 00 00 00| ........| data: raw bits 0x3fa8-0x3faf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[6]{}: tuple 0x3f90-0x3f9f.7 (16)
+ | | | index_tuple_data{}: 0x3f90-0x3f9f.7 (16)
+ | | | t_tid{}: 0x3f90-0x3f95.7 (6)
+0x3f90|00 00 00 00 |.... | ip_blkid: 0 0x3f90-0x3f93.7 (4)
+0x3f90| 06 00 | .. | ip_posid: 6 0x3f94-0x3f95.7 (2)
+0x3f90| 10 00 | .. | t_info: 16 0x3f96-0x3f97.7 (2)
+ | | | flags{}: 0x3f98-NA (0)
+ | | | has_nulls: false 0x3f98-NA (0)
+ | | | has_var_widths: false 0x3f98-NA (0)
+ | | | size: 16 0x3f98-NA (0)
+0x3f90| 06 00 00 00 00 00 00 00| ........| data: raw bits 0x3f98-0x3f9f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[7]{}: tuple 0x3f80-0x3f8f.7 (16)
+ | | | index_tuple_data{}: 0x3f80-0x3f8f.7 (16)
+ | | | t_tid{}: 0x3f80-0x3f85.7 (6)
+0x3f80|00 00 00 00 |.... | ip_blkid: 0 0x3f80-0x3f83.7 (4)
+0x3f80| 07 00 | .. | ip_posid: 7 0x3f84-0x3f85.7 (2)
+0x3f80| 10 00 | .. | t_info: 16 0x3f86-0x3f87.7 (2)
+ | | | flags{}: 0x3f88-NA (0)
+ | | | has_nulls: false 0x3f88-NA (0)
+ | | | has_var_widths: false 0x3f88-NA (0)
+ | | | size: 16 0x3f88-NA (0)
+0x3f80| 07 00 00 00 00 00 00 00| ........| data: raw bits 0x3f88-0x3f8f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[8]{}: tuple 0x3f70-0x3f7f.7 (16)
+ | | | index_tuple_data{}: 0x3f70-0x3f7f.7 (16)
+ | | | t_tid{}: 0x3f70-0x3f75.7 (6)
+0x3f70|00 00 00 00 |.... | ip_blkid: 0 0x3f70-0x3f73.7 (4)
+0x3f70| 08 00 | .. | ip_posid: 8 0x3f74-0x3f75.7 (2)
+0x3f70| 10 00 | .. | t_info: 16 0x3f76-0x3f77.7 (2)
+ | | | flags{}: 0x3f78-NA (0)
+ | | | has_nulls: false 0x3f78-NA (0)
+ | | | has_var_widths: false 0x3f78-NA (0)
+ | | | size: 16 0x3f78-NA (0)
+0x3f70| 08 00 00 00 00 00 00 00| ........| data: raw bits 0x3f78-0x3f7f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[9]{}: tuple 0x3f60-0x3f6f.7 (16)
+ | | | index_tuple_data{}: 0x3f60-0x3f6f.7 (16)
+ | | | t_tid{}: 0x3f60-0x3f65.7 (6)
+0x3f60|00 00 00 00 |.... | ip_blkid: 0 0x3f60-0x3f63.7 (4)
+0x3f60| 09 00 | .. | ip_posid: 9 0x3f64-0x3f65.7 (2)
+0x3f60| 10 00 | .. | t_info: 16 0x3f66-0x3f67.7 (2)
+ | | | flags{}: 0x3f68-NA (0)
+ | | | has_nulls: false 0x3f68-NA (0)
+ | | | has_var_widths: false 0x3f68-NA (0)
+ | | | size: 16 0x3f68-NA (0)
+0x3f60| 09 00 00 00 00 00 00 00| ........| data: raw bits 0x3f68-0x3f6f.7 (8)
diff --git a/format/postgres/testdata/flavours/pgpro10/16404 b/format/postgres/testdata/flavours/pgpro10/16404
new file mode 100644
index 000000000..cd06027f7
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro10/16404 differ
diff --git a/format/postgres/testdata/flavours/pgpro10/16404_1.fqtest b/format/postgres/testdata/flavours/pgpro10/16404_1.fqtest
new file mode 100644
index 000000000..d5925a6a3
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/16404_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro10 ".[0].pd_linp[0,-1] | dv" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[99]{}: item_id 0x1a4-0x1a7.7 (4)
+0x1a0| 40 8d 60 00 | @.`. | item_id_data: 6327616 0x1a4-0x1a7.7 (4)
+ | | | lp_off: 3392 0x1a8-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1a8-NA (0)
+ | | | lp_len: 48 0x1a8-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro10/16404_2.fqtest b/format/postgres/testdata/flavours/pgpro10/16404_2.fqtest
new file mode 100644
index 000000000..d1a400d0e
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/16404_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgpro10 ".[0].tuples[0,-1] | dv" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|45 02 00 00 |E... | t_xmin: 581 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|45 02 00 00 |E... | datum_len_: 581 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 08 | .. | t_infomask: 2049 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: false 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: false 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 05 00 00 00 01 00 00 00| ........| data: "0500000001000000033f01005bf5ffff96f592a7438d020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|03 3f 01 00 5b f5 ff ff 96 f5 92 a7 43 8d 02 00|.?..[.......C...|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[99]{}: tuple 0xd40-0xd6f.7 (48)
+ | | | header{}: 0xd40-0xd57.7 (24)
+ | | | t_choice{}: 0xd40-0xd4b.7 (12)
+ | | | t_heap{}: 0xd40-0xd4b.7 (12)
+0xd40|a8 02 00 00 |.... | t_xmin: 680 0xd40-0xd43.7 (4)
+0xd40| 00 00 00 00 | .... | t_xmax: 0 0xd44-0xd47.7 (4)
+ | | | t_field3{}: 0xd48-0xd4b.7 (4)
+0xd40| 03 00 00 00 | .... | t_cid: 3 0xd48-0xd4b.7 (4)
+0xd40| 03 00 00 00 | .... | t_xvac: 3 0xd48-0xd4b.7 (4)
+ | | | t_datum{}: 0xd40-0xd4b.7 (12)
+0xd40|a8 02 00 00 |.... | datum_len_: 680 0xd40-0xd43.7 (4)
+0xd40| 00 00 00 00 | .... | datum_typmod: 0 0xd44-0xd47.7 (4)
+0xd40| 03 00 00 00 | .... | datum_typeid: 3 0xd48-0xd4b.7 (4)
+ | | | t_ctid{}: 0xd4c-0xd51.7 (6)
+0xd40| 00 00 00 00| ....| ip_blkid: 0 0xd4c-0xd4f.7 (4)
+0xd50|64 00 |d. | ip_posid: 100 0xd50-0xd51.7 (2)
+0xd50| 06 00 | .. | t_infomask2: 6 0xd52-0xd53.7 (2)
+ | | | infomask2{}: 0xd54-NA (0)
+ | | | heap_keys_updated: false 0xd54-NA (0)
+ | | | heap_hot_updated: false 0xd54-NA (0)
+ | | | heap_only_tuple: false 0xd54-NA (0)
+0xd50| 01 08 | .. | t_infomask: 2049 0xd54-0xd55.7 (2)
+ | | | infomask{}: 0xd56-NA (0)
+ | | | heap_hasnull: true 0xd56-NA (0)
+ | | | heap_hasvarwidth: false 0xd56-NA (0)
+ | | | heap_hasexternal: false 0xd56-NA (0)
+ | | | heap_hasoid_old: false 0xd56-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0xd56-NA (0)
+ | | | heap_combocid: false 0xd56-NA (0)
+ | | | heap_xmax_excl_lock: false 0xd56-NA (0)
+ | | | heap_xmax_lock_only: false 0xd56-NA (0)
+ | | | heap_xmax_shr_lock: false 0xd56-NA (0)
+ | | | heap_lock_mask: false 0xd56-NA (0)
+ | | | heap_xmin_committed: false 0xd56-NA (0)
+ | | | heap_xmin_invalid: false 0xd56-NA (0)
+ | | | heap_xmin_frozen: false 0xd56-NA (0)
+ | | | heap_xmax_committed: false 0xd56-NA (0)
+ | | | heap_xmax_invalid: true 0xd56-NA (0)
+ | | | heap_xmax_is_multi: false 0xd56-NA (0)
+ | | | heap_updated: false 0xd56-NA (0)
+ | | | heap_moved_off: false 0xd56-NA (0)
+ | | | heap_moved_in: false 0xd56-NA (0)
+ | | | heap_moved: false 0xd56-NA (0)
+0xd50| 18 | . | t_hoff: 24 0xd56-0xd56.7 (1)
+0xd50| 1f | . | padding0: 31 0xd57-0xd57.7 (1)
+0xd50| 02 00 00 00 01 00 00 00| ........| data: "0200000001000000eeda0000ccf7ffff9c2097a7438d020..." (raw bits) 0xd58-0xd6f.7 (24)
+0xd60|ee da 00 00 cc f7 ff ff 9c 20 97 a7 43 8d 02 00|......... ..C...|
diff --git a/format/postgres/testdata/flavours/pgpro10/pg_control b/format/postgres/testdata/flavours/pgpro10/pg_control
new file mode 100644
index 000000000..402d6ac36
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro10/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgpro10/pg_control.fqtest b/format/postgres/testdata/flavours/pgpro10/pg_control.fqtest
new file mode 100644
index 000000000..2029ce532
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/pg_control.fqtest
@@ -0,0 +1,69 @@
+$ fq -d pg_control -o flavour=pgpro10 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|5b 89 68 65 ee 35 3d 63 |[.he.5=c | system_identifier: 7150931081354053979 0x0-0x7.7 (8)
+0x0000| ea 03 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1002" (1347421162) 0x8-0xb.7 (4)
+0x0000| eb d6 05 0c| ....| catalog_version_no: 201709291 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 4a 38 3d 63 00 00 00 00| J8=c....| time: "Wed, 05 Oct 2022 07:54:50 UTC" (1664956490) 0x18-0x1f.7 (8)
+0x0020|d0 54 50 02 00 00 00 00 |.TP..... | check_point: "0/25054D0" (38819024) 0x20-0x27.7 (8)
+0x0020| 28 54 50 02 00 00 00 00| (TP.....| prev_check_point: "0/2505428" (38818856) 0x28-0x2f.7 (8)
+ | | | check_point_copy{}: 0x30-0x7f.7 (80)
+0x0030|98 54 50 02 00 00 00 00 |.TP..... | redo: "0/2505498" (38818968) 0x30-0x37.7 (8)
+0x0030| 01 00 00 00 | .... | this_time_line_id: 1 0x38-0x3b.7 (4)
+0x0030| 01 00 00 00| ....| prev_time_line_id: 1 0x3c-0x3f.7 (4)
+0x0040|01 |. | full_page_writes: 1 0x40-0x40.7 (1)
+0x0040| 00 00 00 | ... | hole1: 0 0x41-0x43.7 (3)
+0x0040| 00 00 00 00 | .... | next_xid_epoch: 0 0x44-0x47.7 (4)
+0x0040| a9 02 00 00 | .... | next_xid: 681 0x48-0x4b.7 (4)
+0x0040| 00 60 00 00| .`..| next_oid: 24576 0x4c-0x4f.7 (4)
+0x0050|01 00 00 00 |.... | next_multi: 1 0x50-0x53.7 (4)
+0x0050| 00 00 00 00 | .... | next_multi_offset: 0 0x54-0x57.7 (4)
+0x0050| 26 02 00 00 | &... | oldest_xid: 550 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_xid_db: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi: 1 0x60-0x63.7 (4)
+0x0060| 01 00 00 00 | .... | oldest_multi_db: 1 0x64-0x67.7 (4)
+0x0060| 4a 38 3d 63 00 00 00 00| J8=c....| time: "Wed, 05 Oct 2022 07:54:50 UTC" (1664956490) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| a9 02 00 00 | .... | oldest_active_xid: 681 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding1: 0 0x7c-0x7f.7 (4)
+0x0080|01 00 00 00 00 00 00 00 |........ | unlogged_lsn: "0/1" (1) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole2: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole3: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole4: 0 0xb1-0xb3.7 (3)
+0x00b0| 5d 00 00 00 | ]... | max_connections: 93 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 00 00 00 00| ....| max_prepared_xacts: 0 0xbc-0xbf.7 (4)
+0x00c0|40 00 00 00 |@... | max_locks_per_xact: 64 0xc0-0xc3.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc4-0xc4.7 (1)
+0x00c0| 00 00 00 | ... | hole5: 0 0xc5-0xc7.7 (3)
+0x00c0| 08 00 00 00 | .... | max_align: 8 0xc8-0xcb.7 (4)
+0x00c0| 00 00 00 00| ....| hole6: 0 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float4_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 01 | . | float8_by_val: 1 0xf9-0xf9.7 (1)
+0x00f0| 00 00 | .. | hole7: 0 0xfa-0xfb.7 (2)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|dd b5 b3 24 2d ff db 10 75 e6 d1 0c 9c d0 92 5d|...$-...u......]| mock_authentication_nonce: "ddb5b3242dffdb1075e6d10c9cd0925d14db0bd3a1a4b84..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|14 db 0b d3 a1 a4 b8 4e 6c fe fd 4d a2 70 10 9b|.......Nl..M.p..|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 7d 09 b6 91 | }... | crc: 2444626301 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro10/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgpro10/pg_control_1.fqtest
new file mode 100644
index 000000000..a748cf5ce
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro10/pg_control_1.fqtest
@@ -0,0 +1,69 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|5b 89 68 65 ee 35 3d 63 |[.he.5=c | system_identifier: 7150931081354053979 0x0-0x7.7 (8)
+0x0000| ea 03 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1002" (1347421162) 0x8-0xb.7 (4)
+0x0000| eb d6 05 0c| ....| catalog_version_no: 201709291 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 4a 38 3d 63 00 00 00 00| J8=c....| time: "Wed, 05 Oct 2022 07:54:50 UTC" (1664956490) 0x18-0x1f.7 (8)
+0x0020|d0 54 50 02 00 00 00 00 |.TP..... | check_point: "0/25054D0" (38819024) 0x20-0x27.7 (8)
+0x0020| 28 54 50 02 00 00 00 00| (TP.....| prev_check_point: "0/2505428" (38818856) 0x28-0x2f.7 (8)
+ | | | check_point_copy{}: 0x30-0x7f.7 (80)
+0x0030|98 54 50 02 00 00 00 00 |.TP..... | redo: "0/2505498" (38818968) 0x30-0x37.7 (8)
+0x0030| 01 00 00 00 | .... | this_time_line_id: 1 0x38-0x3b.7 (4)
+0x0030| 01 00 00 00| ....| prev_time_line_id: 1 0x3c-0x3f.7 (4)
+0x0040|01 |. | full_page_writes: 1 0x40-0x40.7 (1)
+0x0040| 00 00 00 | ... | hole1: 0 0x41-0x43.7 (3)
+0x0040| 00 00 00 00 | .... | next_xid_epoch: 0 0x44-0x47.7 (4)
+0x0040| a9 02 00 00 | .... | next_xid: 681 0x48-0x4b.7 (4)
+0x0040| 00 60 00 00| .`..| next_oid: 24576 0x4c-0x4f.7 (4)
+0x0050|01 00 00 00 |.... | next_multi: 1 0x50-0x53.7 (4)
+0x0050| 00 00 00 00 | .... | next_multi_offset: 0 0x54-0x57.7 (4)
+0x0050| 26 02 00 00 | &... | oldest_xid: 550 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_xid_db: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi: 1 0x60-0x63.7 (4)
+0x0060| 01 00 00 00 | .... | oldest_multi_db: 1 0x64-0x67.7 (4)
+0x0060| 4a 38 3d 63 00 00 00 00| J8=c....| time: "Wed, 05 Oct 2022 07:54:50 UTC" (1664956490) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| a9 02 00 00 | .... | oldest_active_xid: 681 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding1: 0 0x7c-0x7f.7 (4)
+0x0080|01 00 00 00 00 00 00 00 |........ | unlogged_lsn: "0/1" (1) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole2: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole3: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole4: 0 0xb1-0xb3.7 (3)
+0x00b0| 5d 00 00 00 | ]... | max_connections: 93 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 00 00 00 00| ....| max_prepared_xacts: 0 0xbc-0xbf.7 (4)
+0x00c0|40 00 00 00 |@... | max_locks_per_xact: 64 0xc0-0xc3.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc4-0xc4.7 (1)
+0x00c0| 00 00 00 | ... | hole5: 0 0xc5-0xc7.7 (3)
+0x00c0| 08 00 00 00 | .... | max_align: 8 0xc8-0xcb.7 (4)
+0x00c0| 00 00 00 00| ....| hole6: 0 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float4_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 01 | . | float8_by_val: 1 0xf9-0xf9.7 (1)
+0x00f0| 00 00 | .. | hole7: 0 0xfa-0xfb.7 (2)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|dd b5 b3 24 2d ff db 10 75 e6 d1 0c 9c d0 92 5d|...$-...u......]| mock_authentication_nonce: "ddb5b3242dffdb1075e6d10c9cd0925d14db0bd3a1a4b84..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|14 db 0b d3 a1 a4 b8 4e 6c fe fd 4d a2 70 10 9b|.......Nl..M.p..|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 7d 09 b6 91 | }... | crc: 2444626301 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro11/16396 b/format/postgres/testdata/flavours/pgpro11/16396
new file mode 100644
index 000000000..0dcd3b81f
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro11/16396 differ
diff --git a/format/postgres/testdata/flavours/pgpro11/16396_1.fqtest b/format/postgres/testdata/flavours/pgpro11/16396_1.fqtest
new file mode 100644
index 000000000..60dd9ac15
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro11/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro11 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x108-0x10b.7 (4)
+0x100| 80 81 f2 00 | .... | item_id_data: 15892864 0x108-0x10b.7 (4)
+ | | | lp_off: 384 0x10c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x10c-NA (0)
+ | | | lp_len: 121 0x10c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro11/16406 b/format/postgres/testdata/flavours/pgpro11/16406
new file mode 100644
index 000000000..320a72ed4
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro11/16406 differ
diff --git a/format/postgres/testdata/flavours/pgpro11/16406_1.fqtest b/format/postgres/testdata/flavours/pgpro11/16406_1.fqtest
new file mode 100644
index 000000000..cab27dffb
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro11/16406_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro11 ".[0].pd_linp[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[156]{}: item_id 0x288-0x28b.7 (4)
+0x280| 90 82 60 00 | ..`. | item_id_data: 6324880 0x288-0x28b.7 (4)
+ | | | lp_off: 656 0x28c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x28c-NA (0)
+ | | | lp_len: 48 0x28c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro11/16406_2.fqtest b/format/postgres/testdata/flavours/pgpro11/16406_2.fqtest
new file mode 100644
index 000000000..b4b6ef196
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro11/16406_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgpro11 ".[0].tuples[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|47 02 00 00 |G... | t_xmin: 583 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|47 02 00 00 |G... | datum_len_: 583 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 08 | .. | t_infomask: 2049 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: false 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: false 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 0d 00 00 00 02 00 00 00| ........| data: "0d00000002000000ccf20100f8feffffc43021b0218a020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|cc f2 01 00 f8 fe ff ff c4 30 21 b0 21 8a 02 00|.........0!.!...|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[156]{}: tuple 0x290-0x2bf.7 (48)
+ | | | header{}: 0x290-0x2a7.7 (24)
+ | | | t_choice{}: 0x290-0x29b.7 (12)
+ | | | t_heap{}: 0x290-0x29b.7 (12)
+0x290|e3 02 00 00 |.... | t_xmin: 739 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | t_xmax: 0 0x294-0x297.7 (4)
+ | | | t_field3{}: 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_cid: 3 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_xvac: 3 0x298-0x29b.7 (4)
+ | | | t_datum{}: 0x290-0x29b.7 (12)
+0x290|e3 02 00 00 |.... | datum_len_: 739 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | datum_typmod: 0 0x294-0x297.7 (4)
+0x290| 03 00 00 00 | .... | datum_typeid: 3 0x298-0x29b.7 (4)
+ | | | t_ctid{}: 0x29c-0x2a1.7 (6)
+0x290| 00 00 00 00| ....| ip_blkid: 0 0x29c-0x29f.7 (4)
+0x2a0|9d 00 |.. | ip_posid: 157 0x2a0-0x2a1.7 (2)
+0x2a0| 06 00 | .. | t_infomask2: 6 0x2a2-0x2a3.7 (2)
+ | | | infomask2{}: 0x2a4-NA (0)
+ | | | heap_keys_updated: false 0x2a4-NA (0)
+ | | | heap_hot_updated: false 0x2a4-NA (0)
+ | | | heap_only_tuple: false 0x2a4-NA (0)
+0x2a0| 01 08 | .. | t_infomask: 2049 0x2a4-0x2a5.7 (2)
+ | | | infomask{}: 0x2a6-NA (0)
+ | | | heap_hasnull: true 0x2a6-NA (0)
+ | | | heap_hasvarwidth: false 0x2a6-NA (0)
+ | | | heap_hasexternal: false 0x2a6-NA (0)
+ | | | heap_hasoid_old: false 0x2a6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2a6-NA (0)
+ | | | heap_combocid: false 0x2a6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2a6-NA (0)
+ | | | heap_xmax_lock_only: false 0x2a6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2a6-NA (0)
+ | | | heap_lock_mask: false 0x2a6-NA (0)
+ | | | heap_xmin_committed: false 0x2a6-NA (0)
+ | | | heap_xmin_invalid: false 0x2a6-NA (0)
+ | | | heap_xmin_frozen: false 0x2a6-NA (0)
+ | | | heap_xmax_committed: false 0x2a6-NA (0)
+ | | | heap_xmax_invalid: true 0x2a6-NA (0)
+ | | | heap_xmax_is_multi: false 0x2a6-NA (0)
+ | | | heap_updated: false 0x2a6-NA (0)
+ | | | heap_moved_off: false 0x2a6-NA (0)
+ | | | heap_moved_in: false 0x2a6-NA (0)
+ | | | heap_moved: false 0x2a6-NA (0)
+0x2a0| 18 | . | t_hoff: 24 0x2a6-0x2a6.7 (1)
+0x2a0| 1f | . | padding0: 31 0x2a7-0x2a7.7 (1)
+0x2a0| 09 00 00 00 03 00 00 00| ........| data: "0900000003000000b2e003007bf8fffffda429b0218a020..." (raw bits) 0x2a8-0x2bf.7 (24)
+0x2b0|b2 e0 03 00 7b f8 ff ff fd a4 29 b0 21 8a 02 00|....{.....).!...|
diff --git a/format/postgres/testdata/flavours/pgpro11/pg_control b/format/postgres/testdata/flavours/pgpro11/pg_control
new file mode 100644
index 000000000..609630656
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro11/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgpro11/pg_control.fqtest b/format/postgres/testdata/flavours/pgpro11/pg_control.fqtest
new file mode 100644
index 000000000..27fee75e7
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro11/pg_control.fqtest
@@ -0,0 +1,68 @@
+$ fq -d pg_control -o flavour=pgpro11 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|90 49 6c b5 6e a8 08 63 |.Il.n..c | system_identifier: 7136138803012192656 0x0-0x7.7 (8)
+0x0000| 4c 04 50 50 | L.PP | pg_control_version: "Postgres Pro Standard 1100" (1347421260) 0x8-0xb.7 (4)
+0x0000| 1d 5d 07 0c| .]..| catalog_version_no: 201809181 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 94 a9 08 63 00 00 00 00| ...c....| time: "Fri, 26 Aug 2022 11:08:04 UTC" (1661512084) 0x18-0x1f.7 (8)
+0x0020|58 d8 f2 03 00 00 00 00 |X....... | check_point: "0/3F2D858" (66246744) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x77.7 (80)
+0x0020| 20 d8 f2 03 00 00 00 00| .......| redo: "0/3F2D820" (66246688) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 | ... | hole1: 0 0x39-0x3b.7 (3)
+0x0030| 00 00 00 00| ....| next_xid_epoch: 0 0x3c-0x3f.7 (4)
+0x0040|0e 0e 00 00 |.... | next_xid: 3598 0x40-0x43.7 (4)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x44-0x47.7 (4)
+0x0040| 01 00 00 00 | .... | next_multi: 1 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| next_multi_offset: 0 0x4c-0x4f.7 (4)
+0x0050|34 02 00 00 |4... | oldest_xid: 564 0x50-0x53.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_multi: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi_db: 1 0x5c-0x5f.7 (4)
+0x0060|94 a9 08 63 00 00 00 00 |...c.... | time: "Fri, 26 Aug 2022 11:08:04 UTC" (1661512084) 0x60-0x67.7 (8)
+0x0060| 00 00 00 00 | .... | oldest_commit_ts_xid: 0 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| newest_commit_ts_xid: 0 0x6c-0x6f.7 (4)
+0x0070|0e 0e 00 00 |.... | oldest_active_xid: 3598 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | padding1: 0 0x74-0x77.7 (4)
+0x0070| 01 00 00 00 00 00 00 00| ........| unlogged_lsn: "0/1" (1) 0x78-0x7f.7 (8)
+0x0080|00 00 00 00 00 00 00 00 |........ | min_recovery_point: "0/0" (0) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 | .... | min_recovery_point_tli: 0 0x88-0x8b.7 (4)
+0x0080| 00 00 00 00| ....| hole2: 0 0x8c-0x8f.7 (4)
+0x0090|00 00 00 00 00 00 00 00 |........ | backup_start_point: "0/0" (0) 0x90-0x97.7 (8)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_end_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 |. | backup_end_required: 0 0xa0-0xa0.7 (1)
+0x00a0| 00 00 00 | ... | hole3: 0 0xa1-0xa3.7 (3)
+0x00a0| 01 00 00 00 | .... | wal_level: "WAL_LEVEL_REPLICA" (1) 0xa4-0xa7.7 (4)
+0x00a0| 00 | . | wal_log_hints: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| c2 00 00 00| ....| max_connections: 194 0xac-0xaf.7 (4)
+0x00b0|08 00 00 00 |.... | max_worker_processes: 8 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | max_prepared_xacts: 0 0xb4-0xb7.7 (4)
+0x00b0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xb8-0xbb.7 (4)
+0x00b0| 00 | . | track_commit_timestamp: 0 0xbc-0xbc.7 (1)
+0x00b0| 00 00 00| ...| hole5: 0 0xbd-0xbf.7 (3)
+0x00c0|08 00 00 00 |.... | max_align: 8 0xc0-0xc3.7 (4)
+0x00c0| 00 00 00 00 | .... | hole6: 0 0xc4-0xc7.7 (4)
+0x00c0| 00 00 00 00 87 d6 32 41| ......2A| float_format: 1.234567e+06 0xc8-0xcf.7 (8)
+0x00d0|00 20 00 00 |. .. | blcksz: 8192 0xd0-0xd3.7 (4)
+0x00d0| 00 00 02 00 | .... | relseg_size: 131072 0xd4-0xd7.7 (4)
+0x00d0| 00 20 00 00 | . .. | xlog_blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 00 01| ....| xlog_seg_size: 16777216 0xdc-0xdf.7 (4)
+0x00e0|40 00 00 00 |@... | name_data_len: 64 0xe0-0xe3.7 (4)
+0x00e0| 20 00 00 00 | ... | index_max_keys: 32 0xe4-0xe7.7 (4)
+0x00e0| cc 07 00 00 | .... | toast_max_chunk_size: 1996 0xe8-0xeb.7 (4)
+0x00e0| 00 08 00 00| ....| loblksize: 2048 0xec-0xef.7 (4)
+0x00f0|01 |. | float4_by_val: 1 0xf0-0xf0.7 (1)
+0x00f0| 01 | . | float8_by_val: 1 0xf1-0xf1.7 (1)
+0x00f0| 00 00 | .. | hole7: 0 0xf2-0xf3.7 (2)
+0x00f0| 01 00 00 00 | .... | data_checksum_version: 1 0xf4-0xf7.7 (4)
+0x00f0| f6 a2 53 c7 68 b8 81 35| ..S.h..5| mock_authentication_nonce: "f6a253c768b8813567e90b7670f403b446b7807d992f1c9..." (raw bits) 0xf8-0x117.7 (32)
+0x0100|67 e9 0b 76 70 f4 03 b4 46 b7 80 7d 99 2f 1c 9b|g..vp...F..}./..|
+0x0110|cb 85 91 74 a5 e6 75 51 |...t..uQ |
+0x0110| 3c 03 00 00 | <... | icu_version: "60.3.0.0" (828) 0x118-0x11b.7 (4)
+0x0110| b0 52 3e d2| .R>.| crc: 3527299760 0x11c-0x11f.7 (4)
+0x0120|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................| unused: raw bits 0x120-0x1fff.7 (7904)
+* |until 0x1fff.7 (end) (7904) | |
diff --git a/format/postgres/testdata/flavours/pgpro11/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgpro11/pg_control_1.fqtest
new file mode 100644
index 000000000..9bea13b31
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro11/pg_control_1.fqtest
@@ -0,0 +1,68 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|90 49 6c b5 6e a8 08 63 |.Il.n..c | system_identifier: 7136138803012192656 0x0-0x7.7 (8)
+0x0000| 4c 04 50 50 | L.PP | pg_control_version: "Postgres Pro Standard 1100" (1347421260) 0x8-0xb.7 (4)
+0x0000| 1d 5d 07 0c| .]..| catalog_version_no: 201809181 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 94 a9 08 63 00 00 00 00| ...c....| time: "Fri, 26 Aug 2022 11:08:04 UTC" (1661512084) 0x18-0x1f.7 (8)
+0x0020|58 d8 f2 03 00 00 00 00 |X....... | check_point: "0/3F2D858" (66246744) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x77.7 (80)
+0x0020| 20 d8 f2 03 00 00 00 00| .......| redo: "0/3F2D820" (66246688) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 | ... | hole1: 0 0x39-0x3b.7 (3)
+0x0030| 00 00 00 00| ....| next_xid_epoch: 0 0x3c-0x3f.7 (4)
+0x0040|0e 0e 00 00 |.... | next_xid: 3598 0x40-0x43.7 (4)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x44-0x47.7 (4)
+0x0040| 01 00 00 00 | .... | next_multi: 1 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| next_multi_offset: 0 0x4c-0x4f.7 (4)
+0x0050|34 02 00 00 |4... | oldest_xid: 564 0x50-0x53.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_multi: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi_db: 1 0x5c-0x5f.7 (4)
+0x0060|94 a9 08 63 00 00 00 00 |...c.... | time: "Fri, 26 Aug 2022 11:08:04 UTC" (1661512084) 0x60-0x67.7 (8)
+0x0060| 00 00 00 00 | .... | oldest_commit_ts_xid: 0 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| newest_commit_ts_xid: 0 0x6c-0x6f.7 (4)
+0x0070|0e 0e 00 00 |.... | oldest_active_xid: 3598 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | padding1: 0 0x74-0x77.7 (4)
+0x0070| 01 00 00 00 00 00 00 00| ........| unlogged_lsn: "0/1" (1) 0x78-0x7f.7 (8)
+0x0080|00 00 00 00 00 00 00 00 |........ | min_recovery_point: "0/0" (0) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 | .... | min_recovery_point_tli: 0 0x88-0x8b.7 (4)
+0x0080| 00 00 00 00| ....| hole2: 0 0x8c-0x8f.7 (4)
+0x0090|00 00 00 00 00 00 00 00 |........ | backup_start_point: "0/0" (0) 0x90-0x97.7 (8)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_end_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 |. | backup_end_required: 0 0xa0-0xa0.7 (1)
+0x00a0| 00 00 00 | ... | hole3: 0 0xa1-0xa3.7 (3)
+0x00a0| 01 00 00 00 | .... | wal_level: "WAL_LEVEL_REPLICA" (1) 0xa4-0xa7.7 (4)
+0x00a0| 00 | . | wal_log_hints: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| c2 00 00 00| ....| max_connections: 194 0xac-0xaf.7 (4)
+0x00b0|08 00 00 00 |.... | max_worker_processes: 8 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | max_prepared_xacts: 0 0xb4-0xb7.7 (4)
+0x00b0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xb8-0xbb.7 (4)
+0x00b0| 00 | . | track_commit_timestamp: 0 0xbc-0xbc.7 (1)
+0x00b0| 00 00 00| ...| hole5: 0 0xbd-0xbf.7 (3)
+0x00c0|08 00 00 00 |.... | max_align: 8 0xc0-0xc3.7 (4)
+0x00c0| 00 00 00 00 | .... | hole6: 0 0xc4-0xc7.7 (4)
+0x00c0| 00 00 00 00 87 d6 32 41| ......2A| float_format: 1.234567e+06 0xc8-0xcf.7 (8)
+0x00d0|00 20 00 00 |. .. | blcksz: 8192 0xd0-0xd3.7 (4)
+0x00d0| 00 00 02 00 | .... | relseg_size: 131072 0xd4-0xd7.7 (4)
+0x00d0| 00 20 00 00 | . .. | xlog_blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 00 01| ....| xlog_seg_size: 16777216 0xdc-0xdf.7 (4)
+0x00e0|40 00 00 00 |@... | name_data_len: 64 0xe0-0xe3.7 (4)
+0x00e0| 20 00 00 00 | ... | index_max_keys: 32 0xe4-0xe7.7 (4)
+0x00e0| cc 07 00 00 | .... | toast_max_chunk_size: 1996 0xe8-0xeb.7 (4)
+0x00e0| 00 08 00 00| ....| loblksize: 2048 0xec-0xef.7 (4)
+0x00f0|01 |. | float4_by_val: 1 0xf0-0xf0.7 (1)
+0x00f0| 01 | . | float8_by_val: 1 0xf1-0xf1.7 (1)
+0x00f0| 00 00 | .. | hole7: 0 0xf2-0xf3.7 (2)
+0x00f0| 01 00 00 00 | .... | data_checksum_version: 1 0xf4-0xf7.7 (4)
+0x00f0| f6 a2 53 c7 68 b8 81 35| ..S.h..5| mock_authentication_nonce: "f6a253c768b8813567e90b7670f403b446b7807d992f1c9..." (raw bits) 0xf8-0x117.7 (32)
+0x0100|67 e9 0b 76 70 f4 03 b4 46 b7 80 7d 99 2f 1c 9b|g..vp...F..}./..|
+0x0110|cb 85 91 74 a5 e6 75 51 |...t..uQ |
+0x0110| 3c 03 00 00 | <... | icu_version: "60.3.0.0" (828) 0x118-0x11b.7 (4)
+0x0110| b0 52 3e d2| .R>.| crc: 3527299760 0x11c-0x11f.7 (4)
+0x0120|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................| unused: raw bits 0x120-0x1fff.7 (7904)
+* |until 0x1fff.7 (end) (7904) | |
diff --git a/format/postgres/testdata/flavours/pgpro12/16396 b/format/postgres/testdata/flavours/pgpro12/16396
new file mode 100644
index 000000000..03d1f2449
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro12/16396 differ
diff --git a/format/postgres/testdata/flavours/pgpro12/16396_1.fqtest b/format/postgres/testdata/flavours/pgpro12/16396_1.fqtest
new file mode 100644
index 000000000..25f8d346e
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro12/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro12 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x108-0x10b.7 (4)
+0x100| 80 81 f2 00 | .... | item_id_data: 15892864 0x108-0x10b.7 (4)
+ | | | lp_off: 384 0x10c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x10c-NA (0)
+ | | | lp_len: 121 0x10c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro12/16406 b/format/postgres/testdata/flavours/pgpro12/16406
new file mode 100644
index 000000000..1caa6bb2a
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro12/16406 differ
diff --git a/format/postgres/testdata/flavours/pgpro12/16406_1.fqtest b/format/postgres/testdata/flavours/pgpro12/16406_1.fqtest
new file mode 100644
index 000000000..d01ff6a05
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro12/16406_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro12 ".[0].pd_linp[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[156]{}: item_id 0x288-0x28b.7 (4)
+0x280| 90 82 60 00 | ..`. | item_id_data: 6324880 0x288-0x28b.7 (4)
+ | | | lp_off: 656 0x28c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x28c-NA (0)
+ | | | lp_len: 48 0x28c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro12/16406_2.fqtest b/format/postgres/testdata/flavours/pgpro12/16406_2.fqtest
new file mode 100644
index 000000000..c483effa9
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro12/16406_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgpro12 ".[0].tuples[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|f3 01 00 00 |.... | t_xmin: 499 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|f3 01 00 00 |.... | datum_len_: 499 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 09 | .. | t_infomask: 2305 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: true 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: true 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 61 00 00 00 08 00 00 00| a.......| data: "61000000080000003aaa080009040000d1b3823d1f8a020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|3a aa 08 00 09 04 00 00 d1 b3 82 3d 1f 8a 02 00|:..........=....|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[156]{}: tuple 0x290-0x2bf.7 (48)
+ | | | header{}: 0x290-0x2a7.7 (24)
+ | | | t_choice{}: 0x290-0x29b.7 (12)
+ | | | t_heap{}: 0x290-0x29b.7 (12)
+0x290|8f 02 00 00 |.... | t_xmin: 655 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | t_xmax: 0 0x294-0x297.7 (4)
+ | | | t_field3{}: 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_cid: 3 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_xvac: 3 0x298-0x29b.7 (4)
+ | | | t_datum{}: 0x290-0x29b.7 (12)
+0x290|8f 02 00 00 |.... | datum_len_: 655 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | datum_typmod: 0 0x294-0x297.7 (4)
+0x290| 03 00 00 00 | .... | datum_typeid: 3 0x298-0x29b.7 (4)
+ | | | t_ctid{}: 0x29c-0x2a1.7 (6)
+0x290| 00 00 00 00| ....| ip_blkid: 0 0x29c-0x29f.7 (4)
+0x2a0|9d 00 |.. | ip_posid: 157 0x2a0-0x2a1.7 (2)
+0x2a0| 06 00 | .. | t_infomask2: 6 0x2a2-0x2a3.7 (2)
+ | | | infomask2{}: 0x2a4-NA (0)
+ | | | heap_keys_updated: false 0x2a4-NA (0)
+ | | | heap_hot_updated: false 0x2a4-NA (0)
+ | | | heap_only_tuple: false 0x2a4-NA (0)
+0x2a0| 01 09 | .. | t_infomask: 2305 0x2a4-0x2a5.7 (2)
+ | | | infomask{}: 0x2a6-NA (0)
+ | | | heap_hasnull: true 0x2a6-NA (0)
+ | | | heap_hasvarwidth: false 0x2a6-NA (0)
+ | | | heap_hasexternal: false 0x2a6-NA (0)
+ | | | heap_hasoid_old: false 0x2a6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2a6-NA (0)
+ | | | heap_combocid: false 0x2a6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2a6-NA (0)
+ | | | heap_xmax_lock_only: false 0x2a6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2a6-NA (0)
+ | | | heap_lock_mask: false 0x2a6-NA (0)
+ | | | heap_xmin_committed: true 0x2a6-NA (0)
+ | | | heap_xmin_invalid: false 0x2a6-NA (0)
+ | | | heap_xmin_frozen: true 0x2a6-NA (0)
+ | | | heap_xmax_committed: false 0x2a6-NA (0)
+ | | | heap_xmax_invalid: true 0x2a6-NA (0)
+ | | | heap_xmax_is_multi: false 0x2a6-NA (0)
+ | | | heap_updated: false 0x2a6-NA (0)
+ | | | heap_moved_off: false 0x2a6-NA (0)
+ | | | heap_moved_in: false 0x2a6-NA (0)
+ | | | heap_moved: false 0x2a6-NA (0)
+0x2a0| 18 | . | t_hoff: 24 0x2a6-0x2a6.7 (1)
+0x2a0| 1f | . | padding0: 31 0x2a7-0x2a7.7 (1)
+0x2a0| 26 00 00 00 01 00 00 00| &.......| data: "2600000001000000c5900800c5f6ffffe658893d1f8a020..." (raw bits) 0x2a8-0x2bf.7 (24)
+0x2b0|c5 90 08 00 c5 f6 ff ff e6 58 89 3d 1f 8a 02 00|.........X.=....|
diff --git a/format/postgres/testdata/flavours/pgpro12/pg_control b/format/postgres/testdata/flavours/pgpro12/pg_control
new file mode 100644
index 000000000..021e23640
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro12/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgpro12/pg_control.fqtest b/format/postgres/testdata/flavours/pgpro12/pg_control.fqtest
new file mode 100644
index 000000000..d24e3420a
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro12/pg_control.fqtest
@@ -0,0 +1,68 @@
+$ fq -d pg_control -o flavour=pgpro12 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|86 c9 07 43 7d 7e 08 63 |...C}~.c | system_identifier: 7136092686029146502 0x0-0x7.7 (8)
+0x0000| b1 04 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1201" (1347421361) 0x8-0xb.7 (4)
+0x0000| 97 eb 08 0c| ....| catalog_version_no: 201911191 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| b0 81 08 63 00 00 00 00| ...c....| time: "Fri, 26 Aug 2022 08:17:52 UTC" (1661501872) 0x18-0x1f.7 (8)
+0x0020|90 5d 59 09 00 00 00 00 |.]Y..... | check_point: "0/9595D90" (156851600) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| 58 5d 59 09 00 00 00 00| X]Y.....| redo: "0/9595D58" (156851544) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|5d 0f 00 00 00 00 00 00 |]....... | next_full_xid: 3933 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| e0 01 00 00 | .... | oldest_xid: 480 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| ad 81 08 63 00 00 00 00| ...c....| time: "Fri, 26 Aug 2022 08:17:49 UTC" (1661501869) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| 5d 0f 00 00 | ]... | oldest_active_xid: 3933 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| c2 00 00 00 | .... | max_connections: 194 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float4_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 01 | . | float8_by_val: 1 0xf9-0xf9.7 (1)
+0x00f0| 00 00 | .. | hole7: 0 0xfa-0xfb.7 (2)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|ee 89 1b 8b f8 aa 7f f5 9a d9 10 da e0 68 9b 40|.............h.@| mock_authentication_nonce: "ee891b8bf8aa7ff59ad910dae0689b40dd36952da495341..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|dd 36 95 2d a4 95 34 14 72 f7 7d c0 2c 04 6e 19|.6.-..4.r.}.,.n.|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 47 73 b3 44 | Gs.D | crc: 1152611143 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro12/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgpro12/pg_control_1.fqtest
new file mode 100644
index 000000000..2aeba887e
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro12/pg_control_1.fqtest
@@ -0,0 +1,68 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|86 c9 07 43 7d 7e 08 63 |...C}~.c | system_identifier: 7136092686029146502 0x0-0x7.7 (8)
+0x0000| b1 04 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1201" (1347421361) 0x8-0xb.7 (4)
+0x0000| 97 eb 08 0c| ....| catalog_version_no: 201911191 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| b0 81 08 63 00 00 00 00| ...c....| time: "Fri, 26 Aug 2022 08:17:52 UTC" (1661501872) 0x18-0x1f.7 (8)
+0x0020|90 5d 59 09 00 00 00 00 |.]Y..... | check_point: "0/9595D90" (156851600) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| 58 5d 59 09 00 00 00 00| X]Y.....| redo: "0/9595D58" (156851544) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|5d 0f 00 00 00 00 00 00 |]....... | next_full_xid: 3933 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| e0 01 00 00 | .... | oldest_xid: 480 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| ad 81 08 63 00 00 00 00| ...c....| time: "Fri, 26 Aug 2022 08:17:49 UTC" (1661501869) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| 5d 0f 00 00 | ]... | oldest_active_xid: 3933 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| c2 00 00 00 | .... | max_connections: 194 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float4_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 01 | . | float8_by_val: 1 0xf9-0xf9.7 (1)
+0x00f0| 00 00 | .. | hole7: 0 0xfa-0xfb.7 (2)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|ee 89 1b 8b f8 aa 7f f5 9a d9 10 da e0 68 9b 40|.............h.@| mock_authentication_nonce: "ee891b8bf8aa7ff59ad910dae0689b40dd36952da495341..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|dd 36 95 2d a4 95 34 14 72 f7 7d c0 2c 04 6e 19|.6.-..4.r.}.,.n.|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 47 73 b3 44 | Gs.D | crc: 1152611143 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro13/16396 b/format/postgres/testdata/flavours/pgpro13/16396
new file mode 100644
index 000000000..71dec0d65
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro13/16396 differ
diff --git a/format/postgres/testdata/flavours/pgpro13/16396_1.fqtest b/format/postgres/testdata/flavours/pgpro13/16396_1.fqtest
new file mode 100644
index 000000000..99656fd71
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro13/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro13 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x108-0x10b.7 (4)
+0x100| 80 81 f2 00 | .... | item_id_data: 15892864 0x108-0x10b.7 (4)
+ | | | lp_off: 384 0x10c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x10c-NA (0)
+ | | | lp_len: 121 0x10c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro13/16406 b/format/postgres/testdata/flavours/pgpro13/16406
new file mode 100644
index 000000000..7a1017db2
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro13/16406 differ
diff --git a/format/postgres/testdata/flavours/pgpro13/16406_1.fqtest b/format/postgres/testdata/flavours/pgpro13/16406_1.fqtest
new file mode 100644
index 000000000..2305739fc
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro13/16406_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro13 ".[0].pd_linp[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[156]{}: item_id 0x288-0x28b.7 (4)
+0x280| 90 82 60 00 | ..`. | item_id_data: 6324880 0x288-0x28b.7 (4)
+ | | | lp_off: 656 0x28c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x28c-NA (0)
+ | | | lp_len: 48 0x28c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro13/16406_2.fqtest b/format/postgres/testdata/flavours/pgpro13/16406_2.fqtest
new file mode 100644
index 000000000..101bcd12a
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro13/16406_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgpro13 ".[0].tuples[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|f2 01 00 00 |.... | t_xmin: 498 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|f2 01 00 00 |.... | datum_len_: 498 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 09 | .. | t_infomask: 2305 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: true 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: true 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 4e 00 00 00 04 00 00 00| N.......| data: "4e0000000400000053b40a00d6ffffff9982147e1d8a020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|53 b4 0a 00 d6 ff ff ff 99 82 14 7e 1d 8a 02 00|S..........~....|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[156]{}: tuple 0x290-0x2bf.7 (48)
+ | | | header{}: 0x290-0x2a7.7 (24)
+ | | | t_choice{}: 0x290-0x29b.7 (12)
+ | | | t_heap{}: 0x290-0x29b.7 (12)
+0x290|8e 02 00 00 |.... | t_xmin: 654 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | t_xmax: 0 0x294-0x297.7 (4)
+ | | | t_field3{}: 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_cid: 3 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_xvac: 3 0x298-0x29b.7 (4)
+ | | | t_datum{}: 0x290-0x29b.7 (12)
+0x290|8e 02 00 00 |.... | datum_len_: 654 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | datum_typmod: 0 0x294-0x297.7 (4)
+0x290| 03 00 00 00 | .... | datum_typeid: 3 0x298-0x29b.7 (4)
+ | | | t_ctid{}: 0x29c-0x2a1.7 (6)
+0x290| 00 00 00 00| ....| ip_blkid: 0 0x29c-0x29f.7 (4)
+0x2a0|9d 00 |.. | ip_posid: 157 0x2a0-0x2a1.7 (2)
+0x2a0| 06 00 | .. | t_infomask2: 6 0x2a2-0x2a3.7 (2)
+ | | | infomask2{}: 0x2a4-NA (0)
+ | | | heap_keys_updated: false 0x2a4-NA (0)
+ | | | heap_hot_updated: false 0x2a4-NA (0)
+ | | | heap_only_tuple: false 0x2a4-NA (0)
+0x2a0| 01 09 | .. | t_infomask: 2305 0x2a4-0x2a5.7 (2)
+ | | | infomask{}: 0x2a6-NA (0)
+ | | | heap_hasnull: true 0x2a6-NA (0)
+ | | | heap_hasvarwidth: false 0x2a6-NA (0)
+ | | | heap_hasexternal: false 0x2a6-NA (0)
+ | | | heap_hasoid_old: false 0x2a6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2a6-NA (0)
+ | | | heap_combocid: false 0x2a6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2a6-NA (0)
+ | | | heap_xmax_lock_only: false 0x2a6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2a6-NA (0)
+ | | | heap_lock_mask: false 0x2a6-NA (0)
+ | | | heap_xmin_committed: true 0x2a6-NA (0)
+ | | | heap_xmin_invalid: false 0x2a6-NA (0)
+ | | | heap_xmin_frozen: true 0x2a6-NA (0)
+ | | | heap_xmax_committed: false 0x2a6-NA (0)
+ | | | heap_xmax_invalid: true 0x2a6-NA (0)
+ | | | heap_xmax_is_multi: false 0x2a6-NA (0)
+ | | | heap_updated: false 0x2a6-NA (0)
+ | | | heap_moved_off: false 0x2a6-NA (0)
+ | | | heap_moved_in: false 0x2a6-NA (0)
+ | | | heap_moved: false 0x2a6-NA (0)
+0x2a0| 18 | . | t_hoff: 24 0x2a6-0x2a6.7 (1)
+0x2a0| 1f | . | padding0: 31 0x2a7-0x2a7.7 (1)
+0x2a0| 44 00 00 00 09 00 00 00| D.......| data: "44000000090000003f9b0e00fc090000446d1c7e1d8a020..." (raw bits) 0x2a8-0x2bf.7 (24)
+0x2b0|3f 9b 0e 00 fc 09 00 00 44 6d 1c 7e 1d 8a 02 00|?.......Dm.~....|
diff --git a/format/postgres/testdata/flavours/pgpro13/pg_control b/format/postgres/testdata/flavours/pgpro13/pg_control
new file mode 100644
index 000000000..45bd9e3b0
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro13/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgpro13/pg_control.fqtest b/format/postgres/testdata/flavours/pgpro13/pg_control.fqtest
new file mode 100644
index 000000000..4a3982a39
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro13/pg_control.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control -o flavour=pgpro13 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|87 29 2c b8 c2 62 08 63 |.),..b.c | system_identifier: 7136062198021630343 0x0-0x7.7 (8)
+0x0000| 14 05 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1300" (1347421460) 0x8-0xb.7 (4)
+0x0000| 1d 6e 0a 0c| .n..| catalog_version_no: 202010141 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 33 65 08 63 00 00 00 00| 3e.c....| time: "Fri, 26 Aug 2022 06:16:19 UTC" (1661494579) 0x18-0x1f.7 (8)
+0x0020|90 84 80 09 00 00 00 00 |........ | check_point: "0/9808490" (159417488) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| 58 84 80 09 00 00 00 00| X.......| redo: "0/9808458" (159417432) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|4e 24 00 00 00 00 00 00 |N$...... | next_full_xid: 9294 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| df 01 00 00 | .... | oldest_xid: 479 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 2f 65 08 63 00 00 00 00| /e.c....| time: "Fri, 26 Aug 2022 06:16:15 UTC" (1661494575) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| 4e 24 00 00 | N$.. | oldest_active_xid: 9294 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| c2 00 00 00 | .... | max_connections: 194 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|69 11 33 1c d8 dc 8e d9 81 2b f6 69 c0 c7 ae e0|i.3......+.i....| mock_authentication_nonce: "6911331cd8dc8ed9812bf669c0c7aee023a99bdd6909509..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|23 a9 9b dd 69 09 50 92 83 53 15 57 f6 8e ca 7e|#...i.P..S.W...~|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 0f 58 38 03 | .X8. | crc: 54024207 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro14/16396 b/format/postgres/testdata/flavours/pgpro14/16396
new file mode 100644
index 000000000..be8f5843b
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro14/16396 differ
diff --git a/format/postgres/testdata/flavours/pgpro14/16396_1.fqtest b/format/postgres/testdata/flavours/pgpro14/16396_1.fqtest
new file mode 100644
index 000000000..c4f713b21
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro14 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[71]{}: item_id 0x134-0x137.7 (4)
+0x130| 80 81 f2 00 | .... | item_id_data: 15892864 0x134-0x137.7 (4)
+ | | | lp_off: 384 0x138-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x138-NA (0)
+ | | | lp_len: 121 0x138-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro14/16404 b/format/postgres/testdata/flavours/pgpro14/16404
new file mode 100644
index 000000000..abe4e237a
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro14/16404 differ
diff --git a/format/postgres/testdata/flavours/pgpro14/16404_1.fqtest b/format/postgres/testdata/flavours/pgpro14/16404_1.fqtest
new file mode 100644
index 000000000..562588332
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/16404_1.fqtest
@@ -0,0 +1,51 @@
+$ fq -d pg_btree ".[1].pd_linp[0,1,2,3,4,5,6,7,8,9] | dv" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[0]{}: item_id 0x2018-0x201b.7 (4)
+0x2010| 00 89 20 00 | .. . | item_id_data: 2132224 0x2018-0x201b.7 (4)
+ | | | lp_off: 2304 0x201c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x201c-NA (0)
+ | | | lp_len: 16 0x201c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[1]{}: item_id 0x201c-0x201f.7 (4)
+0x2010| e0 9f 20 00| .. .| item_id_data: 2138080 0x201c-0x201f.7 (4)
+ | | | lp_off: 8160 0x2020-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2020-NA (0)
+ | | | lp_len: 16 0x2020-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[2]{}: item_id 0x2020-0x2023.7 (4)
+0x2020|d0 9f 20 00 |.. . | item_id_data: 2138064 0x2020-0x2023.7 (4)
+ | | | lp_off: 8144 0x2024-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2024-NA (0)
+ | | | lp_len: 16 0x2024-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[3]{}: item_id 0x2024-0x2027.7 (4)
+0x2020| c0 9f 20 00 | .. . | item_id_data: 2138048 0x2024-0x2027.7 (4)
+ | | | lp_off: 8128 0x2028-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2028-NA (0)
+ | | | lp_len: 16 0x2028-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[4]{}: item_id 0x2028-0x202b.7 (4)
+0x2020| b0 9f 20 00 | .. . | item_id_data: 2138032 0x2028-0x202b.7 (4)
+ | | | lp_off: 8112 0x202c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x202c-NA (0)
+ | | | lp_len: 16 0x202c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[5]{}: item_id 0x202c-0x202f.7 (4)
+0x2020| a0 9f 20 00| .. .| item_id_data: 2138016 0x202c-0x202f.7 (4)
+ | | | lp_off: 8096 0x2030-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2030-NA (0)
+ | | | lp_len: 16 0x2030-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[6]{}: item_id 0x2030-0x2033.7 (4)
+0x2030|90 9f 20 00 |.. . | item_id_data: 2138000 0x2030-0x2033.7 (4)
+ | | | lp_off: 8080 0x2034-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2034-NA (0)
+ | | | lp_len: 16 0x2034-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[7]{}: item_id 0x2034-0x2037.7 (4)
+0x2030| 80 9f 20 00 | .. . | item_id_data: 2137984 0x2034-0x2037.7 (4)
+ | | | lp_off: 8064 0x2038-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2038-NA (0)
+ | | | lp_len: 16 0x2038-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[8]{}: item_id 0x2038-0x203b.7 (4)
+0x2030| 70 9f 20 00 | p. . | item_id_data: 2137968 0x2038-0x203b.7 (4)
+ | | | lp_off: 8048 0x203c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x203c-NA (0)
+ | | | lp_len: 16 0x203c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[9]{}: item_id 0x203c-0x203f.7 (4)
+0x2030| 60 9f 20 00| `. .| item_id_data: 2137952 0x203c-0x203f.7 (4)
+ | | | lp_off: 8032 0x2040-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2040-NA (0)
+ | | | lp_len: 16 0x2040-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro14/16404_2.fqtest b/format/postgres/testdata/flavours/pgpro14/16404_2.fqtest
new file mode 100644
index 000000000..db1251e5f
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/16404_2.fqtest
@@ -0,0 +1,111 @@
+$ fq -d pg_btree ".[1].tuples[0,1,2,3,4,5,6,7,8,9] | dv" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[0]{}: tuple 0x2900-0x290f.7 (16)
+ | | | index_tuple_data{}: 0x2900-0x290f.7 (16)
+ | | | t_tid{}: 0x2900-0x2905.7 (6)
+0x2900|00 00 06 00 |.... | ip_blkid: 393216 0x2900-0x2903.7 (4)
+0x2900| 01 00 | .. | ip_posid: 1 0x2904-0x2905.7 (2)
+0x2900| 10 20 | . | t_info: 8208 0x2906-0x2907.7 (2)
+ | | | flags{}: 0x2908-NA (0)
+ | | | has_nulls: false 0x2908-NA (0)
+ | | | has_var_widths: false 0x2908-NA (0)
+ | | | size: 16 0x2908-NA (0)
+0x2900| 6f 01 00 00 00 00 00 00| o.......| data: raw bits 0x2908-0x290f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[1]{}: tuple 0x3fe0-0x3fef.7 (16)
+ | | | index_tuple_data{}: 0x3fe0-0x3fef.7 (16)
+ | | | t_tid{}: 0x3fe0-0x3fe5.7 (6)
+0x3fe0|00 00 00 00 |.... | ip_blkid: 0 0x3fe0-0x3fe3.7 (4)
+0x3fe0| 01 00 | .. | ip_posid: 1 0x3fe4-0x3fe5.7 (2)
+0x3fe0| 10 00 | .. | t_info: 16 0x3fe6-0x3fe7.7 (2)
+ | | | flags{}: 0x3fe8-NA (0)
+ | | | has_nulls: false 0x3fe8-NA (0)
+ | | | has_var_widths: false 0x3fe8-NA (0)
+ | | | size: 16 0x3fe8-NA (0)
+0x3fe0| 01 00 00 00 00 00 00 00| ........| data: raw bits 0x3fe8-0x3fef.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[2]{}: tuple 0x3fd0-0x3fdf.7 (16)
+ | | | index_tuple_data{}: 0x3fd0-0x3fdf.7 (16)
+ | | | t_tid{}: 0x3fd0-0x3fd5.7 (6)
+0x3fd0|00 00 00 00 |.... | ip_blkid: 0 0x3fd0-0x3fd3.7 (4)
+0x3fd0| 02 00 | .. | ip_posid: 2 0x3fd4-0x3fd5.7 (2)
+0x3fd0| 10 00 | .. | t_info: 16 0x3fd6-0x3fd7.7 (2)
+ | | | flags{}: 0x3fd8-NA (0)
+ | | | has_nulls: false 0x3fd8-NA (0)
+ | | | has_var_widths: false 0x3fd8-NA (0)
+ | | | size: 16 0x3fd8-NA (0)
+0x3fd0| 02 00 00 00 00 00 00 00| ........| data: raw bits 0x3fd8-0x3fdf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[3]{}: tuple 0x3fc0-0x3fcf.7 (16)
+ | | | index_tuple_data{}: 0x3fc0-0x3fcf.7 (16)
+ | | | t_tid{}: 0x3fc0-0x3fc5.7 (6)
+0x3fc0|00 00 00 00 |.... | ip_blkid: 0 0x3fc0-0x3fc3.7 (4)
+0x3fc0| 03 00 | .. | ip_posid: 3 0x3fc4-0x3fc5.7 (2)
+0x3fc0| 10 00 | .. | t_info: 16 0x3fc6-0x3fc7.7 (2)
+ | | | flags{}: 0x3fc8-NA (0)
+ | | | has_nulls: false 0x3fc8-NA (0)
+ | | | has_var_widths: false 0x3fc8-NA (0)
+ | | | size: 16 0x3fc8-NA (0)
+0x3fc0| 03 00 00 00 00 00 00 00| ........| data: raw bits 0x3fc8-0x3fcf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[4]{}: tuple 0x3fb0-0x3fbf.7 (16)
+ | | | index_tuple_data{}: 0x3fb0-0x3fbf.7 (16)
+ | | | t_tid{}: 0x3fb0-0x3fb5.7 (6)
+0x3fb0|00 00 00 00 |.... | ip_blkid: 0 0x3fb0-0x3fb3.7 (4)
+0x3fb0| 04 00 | .. | ip_posid: 4 0x3fb4-0x3fb5.7 (2)
+0x3fb0| 10 00 | .. | t_info: 16 0x3fb6-0x3fb7.7 (2)
+ | | | flags{}: 0x3fb8-NA (0)
+ | | | has_nulls: false 0x3fb8-NA (0)
+ | | | has_var_widths: false 0x3fb8-NA (0)
+ | | | size: 16 0x3fb8-NA (0)
+0x3fb0| 04 00 00 00 00 00 00 00| ........| data: raw bits 0x3fb8-0x3fbf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[5]{}: tuple 0x3fa0-0x3faf.7 (16)
+ | | | index_tuple_data{}: 0x3fa0-0x3faf.7 (16)
+ | | | t_tid{}: 0x3fa0-0x3fa5.7 (6)
+0x3fa0|00 00 00 00 |.... | ip_blkid: 0 0x3fa0-0x3fa3.7 (4)
+0x3fa0| 05 00 | .. | ip_posid: 5 0x3fa4-0x3fa5.7 (2)
+0x3fa0| 10 00 | .. | t_info: 16 0x3fa6-0x3fa7.7 (2)
+ | | | flags{}: 0x3fa8-NA (0)
+ | | | has_nulls: false 0x3fa8-NA (0)
+ | | | has_var_widths: false 0x3fa8-NA (0)
+ | | | size: 16 0x3fa8-NA (0)
+0x3fa0| 05 00 00 00 00 00 00 00| ........| data: raw bits 0x3fa8-0x3faf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[6]{}: tuple 0x3f90-0x3f9f.7 (16)
+ | | | index_tuple_data{}: 0x3f90-0x3f9f.7 (16)
+ | | | t_tid{}: 0x3f90-0x3f95.7 (6)
+0x3f90|00 00 00 00 |.... | ip_blkid: 0 0x3f90-0x3f93.7 (4)
+0x3f90| 06 00 | .. | ip_posid: 6 0x3f94-0x3f95.7 (2)
+0x3f90| 10 00 | .. | t_info: 16 0x3f96-0x3f97.7 (2)
+ | | | flags{}: 0x3f98-NA (0)
+ | | | has_nulls: false 0x3f98-NA (0)
+ | | | has_var_widths: false 0x3f98-NA (0)
+ | | | size: 16 0x3f98-NA (0)
+0x3f90| 06 00 00 00 00 00 00 00| ........| data: raw bits 0x3f98-0x3f9f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[7]{}: tuple 0x3f80-0x3f8f.7 (16)
+ | | | index_tuple_data{}: 0x3f80-0x3f8f.7 (16)
+ | | | t_tid{}: 0x3f80-0x3f85.7 (6)
+0x3f80|00 00 00 00 |.... | ip_blkid: 0 0x3f80-0x3f83.7 (4)
+0x3f80| 07 00 | .. | ip_posid: 7 0x3f84-0x3f85.7 (2)
+0x3f80| 10 00 | .. | t_info: 16 0x3f86-0x3f87.7 (2)
+ | | | flags{}: 0x3f88-NA (0)
+ | | | has_nulls: false 0x3f88-NA (0)
+ | | | has_var_widths: false 0x3f88-NA (0)
+ | | | size: 16 0x3f88-NA (0)
+0x3f80| 07 00 00 00 00 00 00 00| ........| data: raw bits 0x3f88-0x3f8f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[8]{}: tuple 0x3f70-0x3f7f.7 (16)
+ | | | index_tuple_data{}: 0x3f70-0x3f7f.7 (16)
+ | | | t_tid{}: 0x3f70-0x3f75.7 (6)
+0x3f70|00 00 00 00 |.... | ip_blkid: 0 0x3f70-0x3f73.7 (4)
+0x3f70| 08 00 | .. | ip_posid: 8 0x3f74-0x3f75.7 (2)
+0x3f70| 10 00 | .. | t_info: 16 0x3f76-0x3f77.7 (2)
+ | | | flags{}: 0x3f78-NA (0)
+ | | | has_nulls: false 0x3f78-NA (0)
+ | | | has_var_widths: false 0x3f78-NA (0)
+ | | | size: 16 0x3f78-NA (0)
+0x3f70| 08 00 00 00 00 00 00 00| ........| data: raw bits 0x3f78-0x3f7f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[9]{}: tuple 0x3f60-0x3f6f.7 (16)
+ | | | index_tuple_data{}: 0x3f60-0x3f6f.7 (16)
+ | | | t_tid{}: 0x3f60-0x3f65.7 (6)
+0x3f60|00 00 00 00 |.... | ip_blkid: 0 0x3f60-0x3f63.7 (4)
+0x3f60| 09 00 | .. | ip_posid: 9 0x3f64-0x3f65.7 (2)
+0x3f60| 10 00 | .. | t_info: 16 0x3f66-0x3f67.7 (2)
+ | | | flags{}: 0x3f68-NA (0)
+ | | | has_nulls: false 0x3f68-NA (0)
+ | | | has_var_widths: false 0x3f68-NA (0)
+ | | | size: 16 0x3f68-NA (0)
+0x3f60| 09 00 00 00 00 00 00 00| ........| data: raw bits 0x3f68-0x3f6f.7 (8)
diff --git a/format/postgres/testdata/flavours/pgpro14/16406 b/format/postgres/testdata/flavours/pgpro14/16406
new file mode 100644
index 000000000..5d6646d60
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro14/16406 differ
diff --git a/format/postgres/testdata/flavours/pgpro14/16406_1.fqtest b/format/postgres/testdata/flavours/pgpro14/16406_1.fqtest
new file mode 100644
index 000000000..5db6b6cf3
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/16406_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgpro14 ".[0].pd_linp[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[156]{}: item_id 0x288-0x28b.7 (4)
+0x280| 90 82 60 00 | ..`. | item_id_data: 6324880 0x288-0x28b.7 (4)
+ | | | lp_off: 656 0x28c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x28c-NA (0)
+ | | | lp_len: 48 0x28c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro14/16406_2.fqtest b/format/postgres/testdata/flavours/pgpro14/16406_2.fqtest
new file mode 100644
index 000000000..5bcf38e98
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/16406_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgpro14 ".[0].tuples[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|f1 02 00 00 |.... | t_xmin: 753 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|f1 02 00 00 |.... | datum_len_: 753 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 09 | .. | t_infomask: 2305 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: true 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: true 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 04 00 00 00 01 00 00 00| ........| data: "040000000100000075840100f2fcffff00853c937688020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|75 84 01 00 f2 fc ff ff 00 85 3c 93 76 88 02 00|u.........<.v...|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[156]{}: tuple 0x290-0x2bf.7 (48)
+ | | | header{}: 0x290-0x2a7.7 (24)
+ | | | t_choice{}: 0x290-0x29b.7 (12)
+ | | | t_heap{}: 0x290-0x29b.7 (12)
+0x290|8d 03 00 00 |.... | t_xmin: 909 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | t_xmax: 0 0x294-0x297.7 (4)
+ | | | t_field3{}: 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_cid: 3 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_xvac: 3 0x298-0x29b.7 (4)
+ | | | t_datum{}: 0x290-0x29b.7 (12)
+0x290|8d 03 00 00 |.... | datum_len_: 909 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | datum_typmod: 0 0x294-0x297.7 (4)
+0x290| 03 00 00 00 | .... | datum_typeid: 3 0x298-0x29b.7 (4)
+ | | | t_ctid{}: 0x29c-0x2a1.7 (6)
+0x290| 00 00 00 00| ....| ip_blkid: 0 0x29c-0x29f.7 (4)
+0x2a0|9d 00 |.. | ip_posid: 157 0x2a0-0x2a1.7 (2)
+0x2a0| 06 00 | .. | t_infomask2: 6 0x2a2-0x2a3.7 (2)
+ | | | infomask2{}: 0x2a4-NA (0)
+ | | | heap_keys_updated: false 0x2a4-NA (0)
+ | | | heap_hot_updated: false 0x2a4-NA (0)
+ | | | heap_only_tuple: false 0x2a4-NA (0)
+0x2a0| 01 09 | .. | t_infomask: 2305 0x2a4-0x2a5.7 (2)
+ | | | infomask{}: 0x2a6-NA (0)
+ | | | heap_hasnull: true 0x2a6-NA (0)
+ | | | heap_hasvarwidth: false 0x2a6-NA (0)
+ | | | heap_hasexternal: false 0x2a6-NA (0)
+ | | | heap_hasoid_old: false 0x2a6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2a6-NA (0)
+ | | | heap_combocid: false 0x2a6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2a6-NA (0)
+ | | | heap_xmax_lock_only: false 0x2a6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2a6-NA (0)
+ | | | heap_lock_mask: false 0x2a6-NA (0)
+ | | | heap_xmin_committed: true 0x2a6-NA (0)
+ | | | heap_xmin_invalid: false 0x2a6-NA (0)
+ | | | heap_xmin_frozen: true 0x2a6-NA (0)
+ | | | heap_xmax_committed: false 0x2a6-NA (0)
+ | | | heap_xmax_invalid: true 0x2a6-NA (0)
+ | | | heap_xmax_is_multi: false 0x2a6-NA (0)
+ | | | heap_updated: false 0x2a6-NA (0)
+ | | | heap_moved_off: false 0x2a6-NA (0)
+ | | | heap_moved_in: false 0x2a6-NA (0)
+ | | | heap_moved: false 0x2a6-NA (0)
+0x2a0| 18 | . | t_hoff: 24 0x2a6-0x2a6.7 (1)
+0x2a0| 1f | . | padding0: 31 0x2a7-0x2a7.7 (1)
+0x2a0| 09 00 00 00 01 00 00 00| ........| data: "09000000010000004ff60000b70c00006e1f43937688020..." (raw bits) 0x2a8-0x2bf.7 (24)
+0x2b0|4f f6 00 00 b7 0c 00 00 6e 1f 43 93 76 88 02 00|O.......n.C.v...|
diff --git a/format/postgres/testdata/flavours/pgpro14/pg_control b/format/postgres/testdata/flavours/pgpro14/pg_control
new file mode 100644
index 000000000..709d74a6a
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro14/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgpro14/pg_control.fqtest b/format/postgres/testdata/flavours/pgpro14/pg_control.fqtest
new file mode 100644
index 000000000..efe64e2f3
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/pg_control.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control -o flavour=pgpro14 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|93 99 98 16 b2 a9 ec 62 |.......b | system_identifier: 7128258892569024915 0x0-0x7.7 (8)
+0x0000| 14 05 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1300" (1347421460) 0x8-0xb.7 (4)
+0x0000| 59 f4 0b 0c| Y...| catalog_version_no: 202110041 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 7b ac ec 62 00 00 00 00| {..b....| time: "Fri, 05 Aug 2022 05:36:59 UTC" (1659677819) 0x18-0x1f.7 (8)
+0x0020|58 b8 d5 02 00 00 00 00 |X....... | check_point: "0/2D5B858" (47560792) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| 20 b8 d5 02 00 00 00 00| .......| redo: "0/2D5B820" (47560736) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|24 45 00 00 00 00 00 00 |$E...... | next_xid: 17700 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| dd 02 00 00 | .... | oldest_xid: 733 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 7b ac ec 62 00 00 00 00| {..b....| time: "Fri, 05 Aug 2022 05:36:59 UTC" (1659677819) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| 24 45 00 00 | $E.. | oldest_active_xid: 17700 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| c2 00 00 00 | .... | max_connections: 194 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|fe e1 b1 f5 c4 52 ba e6 c9 ac dc ce 6c ed 4a cd|.....R......l.J.| mock_authentication_nonce: "fee1b1f5c452bae6c9acdcce6ced4acd5ee657c0f6e4c7a..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|5e e6 57 c0 f6 e4 c7 a5 b0 e0 95 3f 1d e7 b2 5e|^.W........?...^|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 95 77 34 f0 | .w4. | crc: 4029970325 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro14/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgpro14/pg_control_1.fqtest
new file mode 100644
index 000000000..8c439e8d7
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro14/pg_control_1.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|93 99 98 16 b2 a9 ec 62 |.......b | system_identifier: 7128258892569024915 0x0-0x7.7 (8)
+0x0000| 14 05 50 50 | ..PP | pg_control_version: "Postgres Pro Standard 1300" (1347421460) 0x8-0xb.7 (4)
+0x0000| 59 f4 0b 0c| Y...| catalog_version_no: 202110041 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 7b ac ec 62 00 00 00 00| {..b....| time: "Fri, 05 Aug 2022 05:36:59 UTC" (1659677819) 0x18-0x1f.7 (8)
+0x0020|58 b8 d5 02 00 00 00 00 |X....... | check_point: "0/2D5B858" (47560792) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| 20 b8 d5 02 00 00 00 00| .......| redo: "0/2D5B820" (47560736) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|24 45 00 00 00 00 00 00 |$E...... | next_xid: 17700 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| dd 02 00 00 | .... | oldest_xid: 733 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 7b ac ec 62 00 00 00 00| {..b....| time: "Fri, 05 Aug 2022 05:36:59 UTC" (1659677819) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| 24 45 00 00 | $E.. | oldest_active_xid: 17700 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| c2 00 00 00 | .... | max_connections: 194 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|fe e1 b1 f5 c4 52 ba e6 c9 ac dc ce 6c ed 4a cd|.....R......l.J.| mock_authentication_nonce: "fee1b1f5c452bae6c9acdcce6ced4acd5ee657c0f6e4c7a..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|5e e6 57 c0 f6 e4 c7 a5 b0 e0 95 3f 1d e7 b2 5e|^.W........?...^|
+0x0120|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x120-0x123.7 (4)
+0x0120| 95 77 34 f0 | .w4. | crc: 4029970325 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgpro15/16400 b/format/postgres/testdata/flavours/pgpro15/16400
new file mode 100644
index 000000000..66469ebe0
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro15/16400 differ
diff --git a/format/postgres/testdata/flavours/pgpro15/16400.fqtest b/format/postgres/testdata/flavours/pgpro15/16400.fqtest
new file mode 100644
index 000000000..d380b11c3
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro15/16400.fqtest
@@ -0,0 +1,21 @@
+$ fq -d pg_heap -o flavour=pgpro15 ".[0].pd_linp[0, 1, 2, -1] | dv" 16400
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[1]{}: item_id 0x1c-0x1f.7 (4)
+0x10| 00 9f f2 00| ....| item_id_data: 15900416 0x1c-0x1f.7 (4)
+ | | | lp_off: 7936 0x20-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x20-NA (0)
+ | | | lp_len: 121 0x20-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[2]{}: item_id 0x20-0x23.7 (4)
+0x20|80 9e f2 00 |.... | item_id_data: 15900288 0x20-0x23.7 (4)
+ | | | lp_off: 7808 0x24-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x24-NA (0)
+ | | | lp_len: 121 0x24-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x108-0x10b.7 (4)
+0x100| 80 81 f2 00 | .... | item_id_data: 15892864 0x108-0x10b.7 (4)
+ | | | lp_off: 384 0x10c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x10c-NA (0)
+ | | | lp_len: 121 0x10c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgpro15/16401 b/format/postgres/testdata/flavours/pgpro15/16401
new file mode 100644
index 000000000..402a178ca
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro15/16401 differ
diff --git a/format/postgres/testdata/flavours/pgpro15/16401.fqtest b/format/postgres/testdata/flavours/pgpro15/16401.fqtest
new file mode 100644
index 000000000..5dd2f55f5
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro15/16401.fqtest
@@ -0,0 +1,93 @@
+$ fq -d pg_heap -o flavour=pgpro15 ".[0].tuples[0,-1] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fe0-0x1fff.7 (32)
+ | | | header{}: 0x1fe0-0x1ff7.7 (24)
+ | | | t_choice{}: 0x1fe0-0x1feb.7 (12)
+ | | | t_heap{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|ea 02 00 00 |.... | t_xmin: 746 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | t_xmax: 0 0x1fe4-0x1fe7.7 (4)
+ | | | t_field3{}: 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_cid: 4 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_xvac: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_datum{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|ea 02 00 00 |.... | datum_len_: 746 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | datum_typmod: 0 0x1fe4-0x1fe7.7 (4)
+0x1fe0| 04 00 00 00 | .... | datum_typeid: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_ctid{}: 0x1fec-0x1ff1.7 (6)
+0x1fe0| 00 00 00 00| ....| ip_blkid: 0 0x1fec-0x1fef.7 (4)
+0x1ff0|01 00 |.. | ip_posid: 1 0x1ff0-0x1ff1.7 (2)
+0x1ff0| 03 00 | .. | t_infomask2: 3 0x1ff2-0x1ff3.7 (2)
+ | | | infomask2{}: 0x1ff4-NA (0)
+ | | | heap_keys_updated: false 0x1ff4-NA (0)
+ | | | heap_hot_updated: false 0x1ff4-NA (0)
+ | | | heap_only_tuple: false 0x1ff4-NA (0)
+0x1ff0| 01 09 | .. | t_infomask: 2305 0x1ff4-0x1ff5.7 (2)
+ | | | infomask{}: 0x1ff6-NA (0)
+ | | | heap_hasnull: true 0x1ff6-NA (0)
+ | | | heap_hasvarwidth: false 0x1ff6-NA (0)
+ | | | heap_hasexternal: false 0x1ff6-NA (0)
+ | | | heap_hasoid_old: false 0x1ff6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1ff6-NA (0)
+ | | | heap_combocid: false 0x1ff6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1ff6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1ff6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1ff6-NA (0)
+ | | | heap_lock_mask: false 0x1ff6-NA (0)
+ | | | heap_xmin_committed: true 0x1ff6-NA (0)
+ | | | heap_xmin_invalid: false 0x1ff6-NA (0)
+ | | | heap_xmin_frozen: true 0x1ff6-NA (0)
+ | | | heap_xmax_committed: false 0x1ff6-NA (0)
+ | | | heap_xmax_invalid: true 0x1ff6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1ff6-NA (0)
+ | | | heap_updated: false 0x1ff6-NA (0)
+ | | | heap_moved_off: false 0x1ff6-NA (0)
+ | | | heap_moved_in: false 0x1ff6-NA (0)
+ | | | heap_moved: false 0x1ff6-NA (0)
+0x1ff0| 18 | . | t_hoff: 24 0x1ff6-0x1ff6.7 (1)
+0x1ff0| 03 | . | padding0: 3 0x1ff7-0x1ff7.7 (1)
+0x1ff0| 01 00 00 00 00 00 00 00| ........| data: "0100000000000000" (raw bits) 0x1ff8-0x1fff.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fe0-0x1fff.7 (32)
+ | | | header{}: 0x1fe0-0x1ff7.7 (24)
+ | | | t_choice{}: 0x1fe0-0x1feb.7 (12)
+ | | | t_heap{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|ea 02 00 00 |.... | t_xmin: 746 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | t_xmax: 0 0x1fe4-0x1fe7.7 (4)
+ | | | t_field3{}: 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_cid: 4 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_xvac: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_datum{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|ea 02 00 00 |.... | datum_len_: 746 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | datum_typmod: 0 0x1fe4-0x1fe7.7 (4)
+0x1fe0| 04 00 00 00 | .... | datum_typeid: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_ctid{}: 0x1fec-0x1ff1.7 (6)
+0x1fe0| 00 00 00 00| ....| ip_blkid: 0 0x1fec-0x1fef.7 (4)
+0x1ff0|01 00 |.. | ip_posid: 1 0x1ff0-0x1ff1.7 (2)
+0x1ff0| 03 00 | .. | t_infomask2: 3 0x1ff2-0x1ff3.7 (2)
+ | | | infomask2{}: 0x1ff4-NA (0)
+ | | | heap_keys_updated: false 0x1ff4-NA (0)
+ | | | heap_hot_updated: false 0x1ff4-NA (0)
+ | | | heap_only_tuple: false 0x1ff4-NA (0)
+0x1ff0| 01 09 | .. | t_infomask: 2305 0x1ff4-0x1ff5.7 (2)
+ | | | infomask{}: 0x1ff6-NA (0)
+ | | | heap_hasnull: true 0x1ff6-NA (0)
+ | | | heap_hasvarwidth: false 0x1ff6-NA (0)
+ | | | heap_hasexternal: false 0x1ff6-NA (0)
+ | | | heap_hasoid_old: false 0x1ff6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1ff6-NA (0)
+ | | | heap_combocid: false 0x1ff6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1ff6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1ff6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1ff6-NA (0)
+ | | | heap_lock_mask: false 0x1ff6-NA (0)
+ | | | heap_xmin_committed: true 0x1ff6-NA (0)
+ | | | heap_xmin_invalid: false 0x1ff6-NA (0)
+ | | | heap_xmin_frozen: true 0x1ff6-NA (0)
+ | | | heap_xmax_committed: false 0x1ff6-NA (0)
+ | | | heap_xmax_invalid: true 0x1ff6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1ff6-NA (0)
+ | | | heap_updated: false 0x1ff6-NA (0)
+ | | | heap_moved_off: false 0x1ff6-NA (0)
+ | | | heap_moved_in: false 0x1ff6-NA (0)
+ | | | heap_moved: false 0x1ff6-NA (0)
+0x1ff0| 18 | . | t_hoff: 24 0x1ff6-0x1ff6.7 (1)
+0x1ff0| 03 | . | padding0: 3 0x1ff7-0x1ff7.7 (1)
+0x1ff0| 01 00 00 00 00 00 00 00| ........| data: "0100000000000000" (raw bits) 0x1ff8-0x1fff.7 (8)
diff --git a/format/postgres/testdata/flavours/pgpro15/pg_control b/format/postgres/testdata/flavours/pgpro15/pg_control
new file mode 100644
index 000000000..99e741428
Binary files /dev/null and b/format/postgres/testdata/flavours/pgpro15/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgpro15/pg_control.fqtest b/format/postgres/testdata/flavours/pgpro15/pg_control.fqtest
new file mode 100644
index 000000000..89c551134
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgpro15/pg_control.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control -o flavour=pgpro15 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|f8 12 a5 c3 34 4b 3d 64 |....4K=d | system_identifier: 7223012067364901624 0x0-0x7.7 (8)
+0x0000| 14 05 50 50 | ..PP | pg_control_version: 1347421460 0x8-0xb.7 (4)
+0x0000| 2f 77 0d 0c| /w..| catalog_version_no: 202209071 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 0a 4d 3d 64 00 00 00 00| .M=d....| time: "Mon, 17 Apr 2023 13:43:38 UTC" (1681739018) 0x18-0x1f.7 (8)
+0x0020|e8 7d 44 02 00 00 00 00 |.}D..... | check_point: "0/2447DE8" (38043112) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| b0 7d 44 02 00 00 00 00| .}D.....| redo: "0/2447DB0" (38043056) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|f1 02 00 00 00 00 00 00 |........ | next_xid: 753 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| d2 02 00 00 | .... | oldest_xid: 722 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 0a 4d 3d 64 00 00 00 00| .M=d....| time: "Mon, 17 Apr 2023 13:43:38 UTC" (1681739018) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| f1 02 00 00 | .... | oldest_active_xid: 753 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| e8 03 00 00 | .... | max_connections: 1000 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|60 21 4c 88 7b 12 7c b0 ff 76 63 70 44 87 22 b5|`!L.{.|..vcpD.".| mock_authentication_nonce: "60214c887b127cb0ff766370448722b5ed43f9b5ccc03d6..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|ed 43 f9 b5 cc c0 3d 6b 18 2d 7e a8 e6 fe fd 8a|.C....=k.-~.....|
+0x0120|94 8a c3 00 |.... | crc: 12814996 0x120-0x123.7 (4)
+0x0120| 00 00 00 00 | .... | padding1: 0 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/pgproee10/16396 b/format/postgres/testdata/flavours/pgproee10/16396
new file mode 100644
index 000000000..df3cac55e
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee10/16396 differ
diff --git a/format/postgres/testdata/flavours/pgproee10/16396_1.fqtest b/format/postgres/testdata/flavours/pgproee10/16396_1.fqtest
new file mode 100644
index 000000000..b711337e1
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee10 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| 68 9f f2 00 | h... | item_id_data: 15900520 0x14-0x17.7 (4)
+ | | | lp_off: 8040 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 121 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[67]{}: item_id 0x120-0x123.7 (4)
+0x120|68 81 f2 00 |h... | item_id_data: 15892840 0x120-0x123.7 (4)
+ | | | lp_off: 360 0x124-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x124-NA (0)
+ | | | lp_len: 121 0x124-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee10/16401 b/format/postgres/testdata/flavours/pgproee10/16401
new file mode 100644
index 000000000..0e3cab270
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee10/16401 differ
diff --git a/format/postgres/testdata/flavours/pgproee10/16401_1.fqtest b/format/postgres/testdata/flavours/pgproee10/16401_1.fqtest
new file mode 100644
index 000000000..fe8970105
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/16401_1.fqtest
@@ -0,0 +1,51 @@
+$ fq -d pg_btree ".[1].pd_linp[0,1,2,3,4,5,6,7,8,9] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[0]{}: item_id 0x2018-0x201b.7 (4)
+0x2010| e0 9f 20 00 | .. . | item_id_data: 2138080 0x2018-0x201b.7 (4)
+ | | | lp_off: 8160 0x201c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x201c-NA (0)
+ | | | lp_len: 16 0x201c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[1]{}: item_id 0x201c-0x201f.7 (4)
+0x2010| d0 9f 20 00| .. .| item_id_data: 2138064 0x201c-0x201f.7 (4)
+ | | | lp_off: 8144 0x2020-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2020-NA (0)
+ | | | lp_len: 16 0x2020-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[2]{}: item_id 0x2020-0x2023.7 (4)
+0x2020|c0 9f 20 00 |.. . | item_id_data: 2138048 0x2020-0x2023.7 (4)
+ | | | lp_off: 8128 0x2024-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2024-NA (0)
+ | | | lp_len: 16 0x2024-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[3]{}: item_id 0x2024-0x2027.7 (4)
+0x2020| b0 9f 20 00 | .. . | item_id_data: 2138032 0x2024-0x2027.7 (4)
+ | | | lp_off: 8112 0x2028-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2028-NA (0)
+ | | | lp_len: 16 0x2028-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[4]{}: item_id 0x2028-0x202b.7 (4)
+0x2020| a0 9f 20 00 | .. . | item_id_data: 2138016 0x2028-0x202b.7 (4)
+ | | | lp_off: 8096 0x202c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x202c-NA (0)
+ | | | lp_len: 16 0x202c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[5]{}: item_id 0x202c-0x202f.7 (4)
+0x2020| 90 9f 20 00| .. .| item_id_data: 2138000 0x202c-0x202f.7 (4)
+ | | | lp_off: 8080 0x2030-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2030-NA (0)
+ | | | lp_len: 16 0x2030-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[6]{}: item_id 0x2030-0x2033.7 (4)
+0x2030|a0 88 20 00 |.. . | item_id_data: 2132128 0x2030-0x2033.7 (4)
+ | | | lp_off: 2208 0x2034-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2034-NA (0)
+ | | | lp_len: 16 0x2034-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[7]{}: item_id 0x2034-0x2037.7 (4)
+0x2030| 80 9f 20 00 | .. . | item_id_data: 2137984 0x2034-0x2037.7 (4)
+ | | | lp_off: 8064 0x2038-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2038-NA (0)
+ | | | lp_len: 16 0x2038-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[8]{}: item_id 0x2038-0x203b.7 (4)
+0x2030| 70 9f 20 00 | p. . | item_id_data: 2137968 0x2038-0x203b.7 (4)
+ | | | lp_off: 8048 0x203c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x203c-NA (0)
+ | | | lp_len: 16 0x203c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[9]{}: item_id 0x203c-0x203f.7 (4)
+0x2030| 60 9f 20 00| `. .| item_id_data: 2137952 0x203c-0x203f.7 (4)
+ | | | lp_off: 8032 0x2040-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2040-NA (0)
+ | | | lp_len: 16 0x2040-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee10/16401_2.fqtest b/format/postgres/testdata/flavours/pgproee10/16401_2.fqtest
new file mode 100644
index 000000000..ae930063d
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/16401_2.fqtest
@@ -0,0 +1,111 @@
+$ fq -d pg_btree ".[1].tuples[0,1,2,3,4,5,6,7,8,9] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[0]{}: tuple 0x3fe0-0x3fef.7 (16)
+ | | | index_tuple_data{}: 0x3fe0-0x3fef.7 (16)
+ | | | t_tid{}: 0x3fe0-0x3fe5.7 (6)
+0x3fe0|00 00 00 00 |.... | ip_blkid: 0 0x3fe0-0x3fe3.7 (4)
+0x3fe0| 01 00 | .. | ip_posid: 1 0x3fe4-0x3fe5.7 (2)
+0x3fe0| 10 00 | .. | t_info: 16 0x3fe6-0x3fe7.7 (2)
+ | | | flags{}: 0x3fe8-NA (0)
+ | | | has_nulls: false 0x3fe8-NA (0)
+ | | | has_var_widths: false 0x3fe8-NA (0)
+ | | | size: 16 0x3fe8-NA (0)
+0x3fe0| 01 00 00 00 00 00 00 00| ........| data: raw bits 0x3fe8-0x3fef.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[1]{}: tuple 0x3fd0-0x3fdf.7 (16)
+ | | | index_tuple_data{}: 0x3fd0-0x3fdf.7 (16)
+ | | | t_tid{}: 0x3fd0-0x3fd5.7 (6)
+0x3fd0|00 00 00 00 |.... | ip_blkid: 0 0x3fd0-0x3fd3.7 (4)
+0x3fd0| 02 00 | .. | ip_posid: 2 0x3fd4-0x3fd5.7 (2)
+0x3fd0| 10 00 | .. | t_info: 16 0x3fd6-0x3fd7.7 (2)
+ | | | flags{}: 0x3fd8-NA (0)
+ | | | has_nulls: false 0x3fd8-NA (0)
+ | | | has_var_widths: false 0x3fd8-NA (0)
+ | | | size: 16 0x3fd8-NA (0)
+0x3fd0| 02 00 00 00 00 00 00 00| ........| data: raw bits 0x3fd8-0x3fdf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[2]{}: tuple 0x3fc0-0x3fcf.7 (16)
+ | | | index_tuple_data{}: 0x3fc0-0x3fcf.7 (16)
+ | | | t_tid{}: 0x3fc0-0x3fc5.7 (6)
+0x3fc0|00 00 00 00 |.... | ip_blkid: 0 0x3fc0-0x3fc3.7 (4)
+0x3fc0| 03 00 | .. | ip_posid: 3 0x3fc4-0x3fc5.7 (2)
+0x3fc0| 10 00 | .. | t_info: 16 0x3fc6-0x3fc7.7 (2)
+ | | | flags{}: 0x3fc8-NA (0)
+ | | | has_nulls: false 0x3fc8-NA (0)
+ | | | has_var_widths: false 0x3fc8-NA (0)
+ | | | size: 16 0x3fc8-NA (0)
+0x3fc0| 03 00 00 00 00 00 00 00| ........| data: raw bits 0x3fc8-0x3fcf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[3]{}: tuple 0x3fb0-0x3fbf.7 (16)
+ | | | index_tuple_data{}: 0x3fb0-0x3fbf.7 (16)
+ | | | t_tid{}: 0x3fb0-0x3fb5.7 (6)
+0x3fb0|00 00 00 00 |.... | ip_blkid: 0 0x3fb0-0x3fb3.7 (4)
+0x3fb0| 04 00 | .. | ip_posid: 4 0x3fb4-0x3fb5.7 (2)
+0x3fb0| 10 00 | .. | t_info: 16 0x3fb6-0x3fb7.7 (2)
+ | | | flags{}: 0x3fb8-NA (0)
+ | | | has_nulls: false 0x3fb8-NA (0)
+ | | | has_var_widths: false 0x3fb8-NA (0)
+ | | | size: 16 0x3fb8-NA (0)
+0x3fb0| 04 00 00 00 00 00 00 00| ........| data: raw bits 0x3fb8-0x3fbf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[4]{}: tuple 0x3fa0-0x3faf.7 (16)
+ | | | index_tuple_data{}: 0x3fa0-0x3faf.7 (16)
+ | | | t_tid{}: 0x3fa0-0x3fa5.7 (6)
+0x3fa0|00 00 00 00 |.... | ip_blkid: 0 0x3fa0-0x3fa3.7 (4)
+0x3fa0| 05 00 | .. | ip_posid: 5 0x3fa4-0x3fa5.7 (2)
+0x3fa0| 10 00 | .. | t_info: 16 0x3fa6-0x3fa7.7 (2)
+ | | | flags{}: 0x3fa8-NA (0)
+ | | | has_nulls: false 0x3fa8-NA (0)
+ | | | has_var_widths: false 0x3fa8-NA (0)
+ | | | size: 16 0x3fa8-NA (0)
+0x3fa0| 05 00 00 00 00 00 00 00| ........| data: raw bits 0x3fa8-0x3faf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[5]{}: tuple 0x3f90-0x3f9f.7 (16)
+ | | | index_tuple_data{}: 0x3f90-0x3f9f.7 (16)
+ | | | t_tid{}: 0x3f90-0x3f95.7 (6)
+0x3f90|00 00 00 00 |.... | ip_blkid: 0 0x3f90-0x3f93.7 (4)
+0x3f90| 06 00 | .. | ip_posid: 6 0x3f94-0x3f95.7 (2)
+0x3f90| 10 00 | .. | t_info: 16 0x3f96-0x3f97.7 (2)
+ | | | flags{}: 0x3f98-NA (0)
+ | | | has_nulls: false 0x3f98-NA (0)
+ | | | has_var_widths: false 0x3f98-NA (0)
+ | | | size: 16 0x3f98-NA (0)
+0x3f90| 06 00 00 00 00 00 00 00| ........| data: raw bits 0x3f98-0x3f9f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[6]{}: tuple 0x28a0-0x28af.7 (16)
+ | | | index_tuple_data{}: 0x28a0-0x28af.7 (16)
+ | | | t_tid{}: 0x28a0-0x28a5.7 (6)
+0x28a0|00 00 f4 40 |...@ | ip_blkid: 1089732608 0x28a0-0x28a3.7 (4)
+0x28a0| 07 00 | .. | ip_posid: 7 0x28a4-0x28a5.7 (2)
+0x28a0| 10 00 | .. | t_info: 16 0x28a6-0x28a7.7 (2)
+ | | | flags{}: 0x28a8-NA (0)
+ | | | has_nulls: false 0x28a8-NA (0)
+ | | | has_var_widths: false 0x28a8-NA (0)
+ | | | size: 16 0x28a8-NA (0)
+0x28a0| 07 00 00 00 00 00 00 00| ........| data: raw bits 0x28a8-0x28af.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[7]{}: tuple 0x3f80-0x3f8f.7 (16)
+ | | | index_tuple_data{}: 0x3f80-0x3f8f.7 (16)
+ | | | t_tid{}: 0x3f80-0x3f85.7 (6)
+0x3f80|00 00 00 00 |.... | ip_blkid: 0 0x3f80-0x3f83.7 (4)
+0x3f80| 07 00 | .. | ip_posid: 7 0x3f84-0x3f85.7 (2)
+0x3f80| 10 00 | .. | t_info: 16 0x3f86-0x3f87.7 (2)
+ | | | flags{}: 0x3f88-NA (0)
+ | | | has_nulls: false 0x3f88-NA (0)
+ | | | has_var_widths: false 0x3f88-NA (0)
+ | | | size: 16 0x3f88-NA (0)
+0x3f80| 07 00 00 00 00 00 00 00| ........| data: raw bits 0x3f88-0x3f8f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[8]{}: tuple 0x3f70-0x3f7f.7 (16)
+ | | | index_tuple_data{}: 0x3f70-0x3f7f.7 (16)
+ | | | t_tid{}: 0x3f70-0x3f75.7 (6)
+0x3f70|00 00 00 00 |.... | ip_blkid: 0 0x3f70-0x3f73.7 (4)
+0x3f70| 08 00 | .. | ip_posid: 8 0x3f74-0x3f75.7 (2)
+0x3f70| 10 00 | .. | t_info: 16 0x3f76-0x3f77.7 (2)
+ | | | flags{}: 0x3f78-NA (0)
+ | | | has_nulls: false 0x3f78-NA (0)
+ | | | has_var_widths: false 0x3f78-NA (0)
+ | | | size: 16 0x3f78-NA (0)
+0x3f70| 08 00 00 00 00 00 00 00| ........| data: raw bits 0x3f78-0x3f7f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[9]{}: tuple 0x3f60-0x3f6f.7 (16)
+ | | | index_tuple_data{}: 0x3f60-0x3f6f.7 (16)
+ | | | t_tid{}: 0x3f60-0x3f65.7 (6)
+0x3f60|00 00 00 00 |.... | ip_blkid: 0 0x3f60-0x3f63.7 (4)
+0x3f60| 09 00 | .. | ip_posid: 9 0x3f64-0x3f65.7 (2)
+0x3f60| 10 00 | .. | t_info: 16 0x3f66-0x3f67.7 (2)
+ | | | flags{}: 0x3f68-NA (0)
+ | | | has_nulls: false 0x3f68-NA (0)
+ | | | has_var_widths: false 0x3f68-NA (0)
+ | | | size: 16 0x3f68-NA (0)
+0x3f60| 09 00 00 00 00 00 00 00| ........| data: raw bits 0x3f68-0x3f6f.7 (8)
diff --git a/format/postgres/testdata/flavours/pgproee10/16403 b/format/postgres/testdata/flavours/pgproee10/16403
new file mode 100644
index 000000000..14839e897
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee10/16403 differ
diff --git a/format/postgres/testdata/flavours/pgproee10/16403_1.fqtest b/format/postgres/testdata/flavours/pgproee10/16403_1.fqtest
new file mode 100644
index 000000000..5789951b2
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/16403_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee10 ".[0].pd_linp[0,-1] | dv" 16403
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| b8 9f 60 00 | ..`. | item_id_data: 6332344 0x14-0x17.7 (4)
+ | | | lp_off: 8120 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 48 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[155]{}: item_id 0x280-0x283.7 (4)
+0x280|a8 82 60 00 |..`. | item_id_data: 6324904 0x280-0x283.7 (4)
+ | | | lp_off: 680 0x284-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x284-NA (0)
+ | | | lp_len: 48 0x284-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee10/16403_2.fqtest b/format/postgres/testdata/flavours/pgproee10/16403_2.fqtest
new file mode 100644
index 000000000..a1fecbc21
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/16403_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgproee10 ".[0].tuples[0,-1] | dv" 16403
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fb8-0x1fe7.7 (48)
+ | | | header{}: 0x1fb8-0x1fcf.7 (24)
+ | | | t_choice{}: 0x1fb8-0x1fc3.7 (12)
+ | | | t_heap{}: 0x1fb8-0x1fc3.7 (12)
+0x1fb0| 03 00 00 00 | .... | t_xmin: 3 0x1fb8-0x1fbb.7 (4)
+0x1fb0| 00 00 00 00| ....| t_xmax: 0 0x1fbc-0x1fbf.7 (4)
+ | | | t_field3{}: 0x1fc0-0x1fc3.7 (4)
+0x1fc0|03 00 00 00 |.... | t_cid: 3 0x1fc0-0x1fc3.7 (4)
+0x1fc0|03 00 00 00 |.... | t_xvac: 3 0x1fc0-0x1fc3.7 (4)
+ | | | t_datum{}: 0x1fb8-0x1fc3.7 (12)
+0x1fb0| 03 00 00 00 | .... | datum_len_: 3 0x1fb8-0x1fbb.7 (4)
+0x1fb0| 00 00 00 00| ....| datum_typmod: 0 0x1fbc-0x1fbf.7 (4)
+0x1fc0|03 00 00 00 |.... | datum_typeid: 3 0x1fc0-0x1fc3.7 (4)
+ | | | t_ctid{}: 0x1fc4-0x1fc9.7 (6)
+0x1fc0| 00 00 00 00 | .... | ip_blkid: 0 0x1fc4-0x1fc7.7 (4)
+0x1fc0| 01 00 | .. | ip_posid: 1 0x1fc8-0x1fc9.7 (2)
+0x1fc0| 06 00 | .. | t_infomask2: 6 0x1fca-0x1fcb.7 (2)
+ | | | infomask2{}: 0x1fcc-NA (0)
+ | | | heap_keys_updated: false 0x1fcc-NA (0)
+ | | | heap_hot_updated: false 0x1fcc-NA (0)
+ | | | heap_only_tuple: false 0x1fcc-NA (0)
+0x1fc0| 01 09 | .. | t_infomask: 2305 0x1fcc-0x1fcd.7 (2)
+ | | | infomask{}: 0x1fce-NA (0)
+ | | | heap_hasnull: true 0x1fce-NA (0)
+ | | | heap_hasvarwidth: false 0x1fce-NA (0)
+ | | | heap_hasexternal: false 0x1fce-NA (0)
+ | | | heap_hasoid_old: false 0x1fce-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fce-NA (0)
+ | | | heap_combocid: false 0x1fce-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fce-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fce-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fce-NA (0)
+ | | | heap_lock_mask: false 0x1fce-NA (0)
+ | | | heap_xmin_committed: true 0x1fce-NA (0)
+ | | | heap_xmin_invalid: false 0x1fce-NA (0)
+ | | | heap_xmin_frozen: true 0x1fce-NA (0)
+ | | | heap_xmax_committed: false 0x1fce-NA (0)
+ | | | heap_xmax_invalid: true 0x1fce-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fce-NA (0)
+ | | | heap_updated: false 0x1fce-NA (0)
+ | | | heap_moved_off: false 0x1fce-NA (0)
+ | | | heap_moved_in: false 0x1fce-NA (0)
+ | | | heap_moved: false 0x1fce-NA (0)
+0x1fc0| 18 | . | t_hoff: 24 0x1fce-0x1fce.7 (1)
+0x1fc0| 1f| .| padding0: 31 0x1fcf-0x1fcf.7 (1)
+0x1fd0|09 00 00 00 01 00 00 00 43 ff 00 00 f7 0e 00 00|........C.......| data: "090000000100000043ff0000f70e000043c144237a88020..." (raw bits) 0x1fd0-0x1fe7.7 (24)
+0x1fe0|43 c1 44 23 7a 88 02 00 |C.D#z... |
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[155]{}: tuple 0x2a8-0x2d7.7 (48)
+ | | | header{}: 0x2a8-0x2bf.7 (24)
+ | | | t_choice{}: 0x2a8-0x2b3.7 (12)
+ | | | t_heap{}: 0x2a8-0x2b3.7 (12)
+0x2a0| 9e 00 00 00 | .... | t_xmin: 158 0x2a8-0x2ab.7 (4)
+0x2a0| 00 00 00 00| ....| t_xmax: 0 0x2ac-0x2af.7 (4)
+ | | | t_field3{}: 0x2b0-0x2b3.7 (4)
+0x2b0|03 00 00 00 |.... | t_cid: 3 0x2b0-0x2b3.7 (4)
+0x2b0|03 00 00 00 |.... | t_xvac: 3 0x2b0-0x2b3.7 (4)
+ | | | t_datum{}: 0x2a8-0x2b3.7 (12)
+0x2a0| 9e 00 00 00 | .... | datum_len_: 158 0x2a8-0x2ab.7 (4)
+0x2a0| 00 00 00 00| ....| datum_typmod: 0 0x2ac-0x2af.7 (4)
+0x2b0|03 00 00 00 |.... | datum_typeid: 3 0x2b0-0x2b3.7 (4)
+ | | | t_ctid{}: 0x2b4-0x2b9.7 (6)
+0x2b0| 00 00 00 00 | .... | ip_blkid: 0 0x2b4-0x2b7.7 (4)
+0x2b0| 9c 00 | .. | ip_posid: 156 0x2b8-0x2b9.7 (2)
+0x2b0| 06 00 | .. | t_infomask2: 6 0x2ba-0x2bb.7 (2)
+ | | | infomask2{}: 0x2bc-NA (0)
+ | | | heap_keys_updated: false 0x2bc-NA (0)
+ | | | heap_hot_updated: false 0x2bc-NA (0)
+ | | | heap_only_tuple: false 0x2bc-NA (0)
+0x2b0| 01 09 | .. | t_infomask: 2305 0x2bc-0x2bd.7 (2)
+ | | | infomask{}: 0x2be-NA (0)
+ | | | heap_hasnull: true 0x2be-NA (0)
+ | | | heap_hasvarwidth: false 0x2be-NA (0)
+ | | | heap_hasexternal: false 0x2be-NA (0)
+ | | | heap_hasoid_old: false 0x2be-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2be-NA (0)
+ | | | heap_combocid: false 0x2be-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2be-NA (0)
+ | | | heap_xmax_lock_only: false 0x2be-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2be-NA (0)
+ | | | heap_lock_mask: false 0x2be-NA (0)
+ | | | heap_xmin_committed: true 0x2be-NA (0)
+ | | | heap_xmin_invalid: false 0x2be-NA (0)
+ | | | heap_xmin_frozen: true 0x2be-NA (0)
+ | | | heap_xmax_committed: false 0x2be-NA (0)
+ | | | heap_xmax_invalid: true 0x2be-NA (0)
+ | | | heap_xmax_is_multi: false 0x2be-NA (0)
+ | | | heap_updated: false 0x2be-NA (0)
+ | | | heap_moved_off: false 0x2be-NA (0)
+ | | | heap_moved_in: false 0x2be-NA (0)
+ | | | heap_moved: false 0x2be-NA (0)
+0x2b0| 18 | . | t_hoff: 24 0x2be-0x2be.7 (1)
+0x2b0| 1f| .| padding0: 31 0x2bf-0x2bf.7 (1)
+0x2c0|09 00 00 00 01 00 00 00 17 13 00 00 50 ed ff ff|............P...| data: "09000000010000001713000050edffffe8934c237a88020..." (raw bits) 0x2c0-0x2d7.7 (24)
+0x2d0|e8 93 4c 23 7a 88 02 00 |..L#z... |
diff --git a/format/postgres/testdata/flavours/pgproee10/pg_control b/format/postgres/testdata/flavours/pgproee10/pg_control
new file mode 100644
index 000000000..0b10f4461
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee10/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgproee10/pg_control.fqtest b/format/postgres/testdata/flavours/pgproee10/pg_control.fqtest
new file mode 100644
index 000000000..83a5b9e1d
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/pg_control.fqtest
@@ -0,0 +1,73 @@
+$ fq -d pg_control -o flavour=pgproee10 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|5d f9 43 10 53 e5 ec 62 |].C.S..b | system_identifier: 7128324455138589021 0x0-0x7.7 (8)
+0x0000| ea 03 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1002" (1346700266) 0x8-0xb.7 (4)
+0x0000| ec d6 05 0c| ....| catalog_version_no: 201709292 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 27 e8 ec 62 00 00 00 00| '..b....| time: "Fri, 05 Aug 2022 09:51:35 UTC" (1659693095) 0x18-0x1f.7 (8)
+0x0020|58 27 fc 02 00 00 00 00 |X'...... | check_point: "0/2FC2758" (50079576) 0x20-0x27.7 (8)
+0x0020| 68 26 fc 02 00 00 00 00| h&......| prev_check_point: "0/2FC2668" (50079336) 0x28-0x2f.7 (8)
+ | | | check_point_copy{}: 0x30-0xa7.7 (120)
+0x0030|08 27 fc 02 00 00 00 00 |.'...... | redo: "0/2FC2708" (50079496) 0x30-0x37.7 (8)
+0x0030| 01 00 00 00 | .... | this_time_line_id: 1 0x38-0x3b.7 (4)
+0x0030| 01 00 00 00| ....| prev_time_line_id: 1 0x3c-0x3f.7 (4)
+0x0040|01 |. | full_page_writes: 1 0x40-0x40.7 (1)
+0x0040| 00 00 00 00 00 00 00 | ....... | hole1: 0 0x41-0x47.7 (7)
+0x0040| 56 34 0c 54 02 00 00 00| V4.T....| next_xid: 10000020566 0x48-0x4f.7 (8)
+0x0050|00 60 00 00 |.`.. | next_oid: 24576 0x50-0x53.7 (4)
+0x0050| 00 00 00 00 | .... | hole2: 0 0x54-0x57.7 (4)
+0x0050| 00 f2 05 2a 01 00 00 00| ...*....| next_multi: 5000000000 0x58-0x5f.7 (8)
+0x0060|00 00 00 00 00 00 00 00 |........ | next_multi_offset: 0 0x60-0x67.7 (8)
+0x0060| 23 e6 0b 54 02 00 00 00| #..T....| oldest_xid: 10000000547 0x68-0x6f.7 (8)
+0x0070|01 00 00 00 |.... | oldest_xid_db: 1 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | hole3: 0 0x74-0x77.7 (4)
+0x0070| 00 f2 05 2a 01 00 00 00| ...*....| oldest_multi: 5000000000 0x78-0x7f.7 (8)
+0x0080|01 00 00 00 |.... | oldest_multi_db: 1 0x80-0x83.7 (4)
+0x0080| 00 00 00 00 | .... | hole4: 0 0x84-0x87.7 (4)
+0x0080| 27 e8 ec 62 00 00 00 00| '..b....| time: "Fri, 05 Aug 2022 09:51:35 UTC" (1659693095) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | oldest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| 00 00 00 00 00 00 00 00| ........| newest_commit_ts_xid: 0 0x98-0x9f.7 (8)
+0x00a0|56 34 0c 54 02 00 00 00 |V4.T.... | oldest_active_xid: 10000020566 0xa0-0xa7.7 (8)
+0x00a0| 01 00 00 00 00 00 00 00| ........| unlogged_lsn: "0/1" (1) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 00 00 00 00 |........ | min_recovery_point: "0/0" (0) 0xb0-0xb7.7 (8)
+0x00b0| 00 00 00 00 | .... | min_recovery_point_tli: 0 0xb8-0xbb.7 (4)
+0x00b0| 00 00 00 00| ....| hole5: 0 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_start_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 00 00 00 00 00 00 00| ........| backup_end_point: "0/0" (0) 0xc8-0xcf.7 (8)
+0x00d0|00 |. | backup_end_required: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole6: 0 0xd1-0xd3.7 (3)
+0x00d0| 01 00 00 00 | .... | wal_level: "WAL_LEVEL_REPLICA" (1) 0xd4-0xd7.7 (4)
+0x00d0| 00 | . | wal_log_hints: 0 0xd8-0xd8.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd9-0xdb.7 (3)
+0x00d0| 5d 00 00 00| ]...| max_connections: 93 0xdc-0xdf.7 (4)
+0x00e0|08 00 00 00 |.... | max_worker_processes: 8 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 00 | .... | max_prepared_xacts: 0 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe8-0xeb.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xec-0xec.7 (1)
+0x00e0| 00 00 00| ...| hole8: 0 0xed-0xef.7 (3)
+0x00f0|08 00 00 00 |.... | max_align: 8 0xf0-0xf3.7 (4)
+0x00f0| 00 00 00 00 | .... | hole9: 0 0xf4-0xf7.7 (4)
+0x00f0| 00 00 00 00 87 d6 32 41| ......2A| float_format: 1.234567e+06 0xf8-0xff.7 (8)
+0x0100|00 20 00 00 |. .. | blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 02 00 | .... | relseg_size: 131072 0x104-0x107.7 (4)
+0x0100| 00 20 00 00 | . .. | xlog_blcksz: 8192 0x108-0x10b.7 (4)
+0x0100| 00 00 00 01| ....| xlog_seg_size: 16777216 0x10c-0x10f.7 (4)
+0x0110|40 00 00 00 |@... | name_data_len: 64 0x110-0x113.7 (4)
+0x0110| 20 00 00 00 | ... | index_max_keys: 32 0x114-0x117.7 (4)
+0x0110| cc 07 00 00 | .... | toast_max_chunk_size: 1996 0x118-0x11b.7 (4)
+0x0110| 00 08 00 00| ....| loblksize: 2048 0x11c-0x11f.7 (4)
+0x0120|01 |. | float4_by_val: 1 0x120-0x120.7 (1)
+0x0120| 01 | . | float8_by_val: 1 0x121-0x121.7 (1)
+0x0120| 00 00 | .. | hole10: 0 0x122-0x123.7 (2)
+0x0120| 01 00 00 00 | .... | data_checksum_version: 1 0x124-0x127.7 (4)
+0x0120| 39 2f 4a cd c5 9d 4d 3b| 9/J...M;| mock_authentication_nonce: "392f4acdc59d4d3b2c9968b782191526dbfa9ba84acd37d..." (raw bits) 0x128-0x147.7 (32)
+0x0130|2c 99 68 b7 82 19 15 26 db fa 9b a8 4a cd 37 dc|,.h....&....J.7.|
+0x0140|4f 6f 86 e9 6a ca f1 45 |Oo..j..E |
+0x0140| 3c 03 00 00 | <... | icu_version: "60.3.0.0" (828) 0x148-0x14b.7 (4)
+0x0140| 00 00 ff ff| ....| pg_old_version: 4294901760 0x14c-0x14f.7 (4)
+0x0150|f6 54 89 ec |.T.. | crc: 3968423158 0x150-0x153.7 (4)
+0x0150| 00 00 00 00 | .... | hole11: 0 0x154-0x157.7 (4)
+0x0150| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x158-0x1fff.7 (7848)
+0x0160|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7848) | |
diff --git a/format/postgres/testdata/flavours/pgproee10/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgproee10/pg_control_1.fqtest
new file mode 100644
index 000000000..c52b3b953
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee10/pg_control_1.fqtest
@@ -0,0 +1,73 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|5d f9 43 10 53 e5 ec 62 |].C.S..b | system_identifier: 7128324455138589021 0x0-0x7.7 (8)
+0x0000| ea 03 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1002" (1346700266) 0x8-0xb.7 (4)
+0x0000| ec d6 05 0c| ....| catalog_version_no: 201709292 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 27 e8 ec 62 00 00 00 00| '..b....| time: "Fri, 05 Aug 2022 09:51:35 UTC" (1659693095) 0x18-0x1f.7 (8)
+0x0020|58 27 fc 02 00 00 00 00 |X'...... | check_point: "0/2FC2758" (50079576) 0x20-0x27.7 (8)
+0x0020| 68 26 fc 02 00 00 00 00| h&......| prev_check_point: "0/2FC2668" (50079336) 0x28-0x2f.7 (8)
+ | | | check_point_copy{}: 0x30-0xa7.7 (120)
+0x0030|08 27 fc 02 00 00 00 00 |.'...... | redo: "0/2FC2708" (50079496) 0x30-0x37.7 (8)
+0x0030| 01 00 00 00 | .... | this_time_line_id: 1 0x38-0x3b.7 (4)
+0x0030| 01 00 00 00| ....| prev_time_line_id: 1 0x3c-0x3f.7 (4)
+0x0040|01 |. | full_page_writes: 1 0x40-0x40.7 (1)
+0x0040| 00 00 00 00 00 00 00 | ....... | hole1: 0 0x41-0x47.7 (7)
+0x0040| 56 34 0c 54 02 00 00 00| V4.T....| next_xid: 10000020566 0x48-0x4f.7 (8)
+0x0050|00 60 00 00 |.`.. | next_oid: 24576 0x50-0x53.7 (4)
+0x0050| 00 00 00 00 | .... | hole2: 0 0x54-0x57.7 (4)
+0x0050| 00 f2 05 2a 01 00 00 00| ...*....| next_multi: 5000000000 0x58-0x5f.7 (8)
+0x0060|00 00 00 00 00 00 00 00 |........ | next_multi_offset: 0 0x60-0x67.7 (8)
+0x0060| 23 e6 0b 54 02 00 00 00| #..T....| oldest_xid: 10000000547 0x68-0x6f.7 (8)
+0x0070|01 00 00 00 |.... | oldest_xid_db: 1 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | hole3: 0 0x74-0x77.7 (4)
+0x0070| 00 f2 05 2a 01 00 00 00| ...*....| oldest_multi: 5000000000 0x78-0x7f.7 (8)
+0x0080|01 00 00 00 |.... | oldest_multi_db: 1 0x80-0x83.7 (4)
+0x0080| 00 00 00 00 | .... | hole4: 0 0x84-0x87.7 (4)
+0x0080| 27 e8 ec 62 00 00 00 00| '..b....| time: "Fri, 05 Aug 2022 09:51:35 UTC" (1659693095) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | oldest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| 00 00 00 00 00 00 00 00| ........| newest_commit_ts_xid: 0 0x98-0x9f.7 (8)
+0x00a0|56 34 0c 54 02 00 00 00 |V4.T.... | oldest_active_xid: 10000020566 0xa0-0xa7.7 (8)
+0x00a0| 01 00 00 00 00 00 00 00| ........| unlogged_lsn: "0/1" (1) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 00 00 00 00 |........ | min_recovery_point: "0/0" (0) 0xb0-0xb7.7 (8)
+0x00b0| 00 00 00 00 | .... | min_recovery_point_tli: 0 0xb8-0xbb.7 (4)
+0x00b0| 00 00 00 00| ....| hole5: 0 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_start_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 00 00 00 00 00 00 00| ........| backup_end_point: "0/0" (0) 0xc8-0xcf.7 (8)
+0x00d0|00 |. | backup_end_required: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole6: 0 0xd1-0xd3.7 (3)
+0x00d0| 01 00 00 00 | .... | wal_level: "WAL_LEVEL_REPLICA" (1) 0xd4-0xd7.7 (4)
+0x00d0| 00 | . | wal_log_hints: 0 0xd8-0xd8.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd9-0xdb.7 (3)
+0x00d0| 5d 00 00 00| ]...| max_connections: 93 0xdc-0xdf.7 (4)
+0x00e0|08 00 00 00 |.... | max_worker_processes: 8 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 00 | .... | max_prepared_xacts: 0 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe8-0xeb.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xec-0xec.7 (1)
+0x00e0| 00 00 00| ...| hole8: 0 0xed-0xef.7 (3)
+0x00f0|08 00 00 00 |.... | max_align: 8 0xf0-0xf3.7 (4)
+0x00f0| 00 00 00 00 | .... | hole9: 0 0xf4-0xf7.7 (4)
+0x00f0| 00 00 00 00 87 d6 32 41| ......2A| float_format: 1.234567e+06 0xf8-0xff.7 (8)
+0x0100|00 20 00 00 |. .. | blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 02 00 | .... | relseg_size: 131072 0x104-0x107.7 (4)
+0x0100| 00 20 00 00 | . .. | xlog_blcksz: 8192 0x108-0x10b.7 (4)
+0x0100| 00 00 00 01| ....| xlog_seg_size: 16777216 0x10c-0x10f.7 (4)
+0x0110|40 00 00 00 |@... | name_data_len: 64 0x110-0x113.7 (4)
+0x0110| 20 00 00 00 | ... | index_max_keys: 32 0x114-0x117.7 (4)
+0x0110| cc 07 00 00 | .... | toast_max_chunk_size: 1996 0x118-0x11b.7 (4)
+0x0110| 00 08 00 00| ....| loblksize: 2048 0x11c-0x11f.7 (4)
+0x0120|01 |. | float4_by_val: 1 0x120-0x120.7 (1)
+0x0120| 01 | . | float8_by_val: 1 0x121-0x121.7 (1)
+0x0120| 00 00 | .. | hole10: 0 0x122-0x123.7 (2)
+0x0120| 01 00 00 00 | .... | data_checksum_version: 1 0x124-0x127.7 (4)
+0x0120| 39 2f 4a cd c5 9d 4d 3b| 9/J...M;| mock_authentication_nonce: "392f4acdc59d4d3b2c9968b782191526dbfa9ba84acd37d..." (raw bits) 0x128-0x147.7 (32)
+0x0130|2c 99 68 b7 82 19 15 26 db fa 9b a8 4a cd 37 dc|,.h....&....J.7.|
+0x0140|4f 6f 86 e9 6a ca f1 45 |Oo..j..E |
+0x0140| 3c 03 00 00 | <... | icu_version: "60.3.0.0" (828) 0x148-0x14b.7 (4)
+0x0140| 00 00 ff ff| ....| pg_old_version: 4294901760 0x14c-0x14f.7 (4)
+0x0150|f6 54 89 ec |.T.. | crc: 3968423158 0x150-0x153.7 (4)
+0x0150| 00 00 00 00 | .... | hole11: 0 0x154-0x157.7 (4)
+0x0150| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x158-0x1fff.7 (7848)
+0x0160|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7848) | |
diff --git a/format/postgres/testdata/flavours/pgproee11/90150 b/format/postgres/testdata/flavours/pgproee11/90150
new file mode 100644
index 000000000..cc6f4fc69
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee11/90150 differ
diff --git a/format/postgres/testdata/flavours/pgproee11/90150_1.fqtest b/format/postgres/testdata/flavours/pgproee11/90150_1.fqtest
new file mode 100644
index 000000000..1e08c13b2
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee11/90150_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee11 ".[0].pd_linp[0,-1] | dv" 90150
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| 68 9f f2 00 | h... | item_id_data: 15900520 0x14-0x17.7 (4)
+ | | | lp_off: 8040 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 121 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x104-0x107.7 (4)
+0x100| 68 81 f2 00 | h... | item_id_data: 15892840 0x104-0x107.7 (4)
+ | | | lp_off: 360 0x108-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x108-NA (0)
+ | | | lp_len: 121 0x108-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee11/90153 b/format/postgres/testdata/flavours/pgproee11/90153
new file mode 100644
index 000000000..6a32191cc
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee11/90153 differ
diff --git a/format/postgres/testdata/flavours/pgproee11/90153_2.fqtest b/format/postgres/testdata/flavours/pgproee11/90153_2.fqtest
new file mode 100644
index 000000000..520105c02
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee11/90153_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgproee11 ".[0].tuples[0,-1] | dv" 90153
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x11d8-0x11ff.7 (40)
+ | | | header{}: 0x11d8-0x11ef.7 (24)
+ | | | t_choice{}: 0x11d8-0x11e3.7 (12)
+ | | | t_heap{}: 0x11d8-0x11e3.7 (12)
+0x11d0| 66 b2 02 00 | f... | t_xmin: 176742 0x11d8-0x11db.7 (4)
+0x11d0| 00 00 00 00| ....| t_xmax: 0 0x11dc-0x11df.7 (4)
+ | | | t_field3{}: 0x11e0-0x11e3.7 (4)
+0x11e0|01 00 00 00 |.... | t_cid: 1 0x11e0-0x11e3.7 (4)
+0x11e0|01 00 00 00 |.... | t_xvac: 1 0x11e0-0x11e3.7 (4)
+ | | | t_datum{}: 0x11d8-0x11e3.7 (12)
+0x11d0| 66 b2 02 00 | f... | datum_len_: 176742 0x11d8-0x11db.7 (4)
+0x11d0| 00 00 00 00| ....| datum_typmod: 0 0x11dc-0x11df.7 (4)
+0x11e0|01 00 00 00 |.... | datum_typeid: 1 0x11e0-0x11e3.7 (4)
+ | | | t_ctid{}: 0x11e4-0x11e9.7 (6)
+0x11e0| 00 00 00 00 | .... | ip_blkid: 0 0x11e4-0x11e7.7 (4)
+0x11e0| 04 00 | .. | ip_posid: 4 0x11e8-0x11e9.7 (2)
+0x11e0| 04 80 | .. | t_infomask2: 32772 0x11ea-0x11eb.7 (2)
+ | | | infomask2{}: 0x11ec-NA (0)
+ | | | heap_keys_updated: false 0x11ec-NA (0)
+ | | | heap_hot_updated: false 0x11ec-NA (0)
+ | | | heap_only_tuple: true 0x11ec-NA (0)
+0x11e0| 01 29 | .) | t_infomask: 10497 0x11ec-0x11ed.7 (2)
+ | | | infomask{}: 0x11ee-NA (0)
+ | | | heap_hasnull: true 0x11ee-NA (0)
+ | | | heap_hasvarwidth: false 0x11ee-NA (0)
+ | | | heap_hasexternal: false 0x11ee-NA (0)
+ | | | heap_hasoid_old: false 0x11ee-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x11ee-NA (0)
+ | | | heap_combocid: false 0x11ee-NA (0)
+ | | | heap_xmax_excl_lock: false 0x11ee-NA (0)
+ | | | heap_xmax_lock_only: false 0x11ee-NA (0)
+ | | | heap_xmax_shr_lock: false 0x11ee-NA (0)
+ | | | heap_lock_mask: false 0x11ee-NA (0)
+ | | | heap_xmin_committed: true 0x11ee-NA (0)
+ | | | heap_xmin_invalid: false 0x11ee-NA (0)
+ | | | heap_xmin_frozen: true 0x11ee-NA (0)
+ | | | heap_xmax_committed: false 0x11ee-NA (0)
+ | | | heap_xmax_invalid: true 0x11ee-NA (0)
+ | | | heap_xmax_is_multi: false 0x11ee-NA (0)
+ | | | heap_updated: true 0x11ee-NA (0)
+ | | | heap_moved_off: false 0x11ee-NA (0)
+ | | | heap_moved_in: false 0x11ee-NA (0)
+ | | | heap_moved: false 0x11ee-NA (0)
+0x11e0| 18 | . | t_hoff: 24 0x11ee-0x11ee.7 (1)
+0x11e0| 07| .| padding0: 7 0x11ef-0x11ef.7 (1)
+0x11f0|65 00 00 00 0b 00 00 00 4f f8 00 00 |e.......O... | data: "650000000b0000004ff80000" (raw bits) 0x11f0-0x11fb.7 (12)
+0x11f0| 00 00 00 00| ....| padding1: "00000000" (raw bits) 0x11fc-0x11ff.7 (4)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[99]{}: tuple 0x1818-0x183f.7 (40)
+ | | | header{}: 0x1818-0x182f.7 (24)
+ | | | t_choice{}: 0x1818-0x1823.7 (12)
+ | | | t_heap{}: 0x1818-0x1823.7 (12)
+0x1810| 54 b0 02 00 | T... | t_xmin: 176212 0x1818-0x181b.7 (4)
+0x1810| 00 00 00 00| ....| t_xmax: 0 0x181c-0x181f.7 (4)
+ | | | t_field3{}: 0x1820-0x1823.7 (4)
+0x1820|01 00 00 00 |.... | t_cid: 1 0x1820-0x1823.7 (4)
+0x1820|01 00 00 00 |.... | t_xvac: 1 0x1820-0x1823.7 (4)
+ | | | t_datum{}: 0x1818-0x1823.7 (12)
+0x1810| 54 b0 02 00 | T... | datum_len_: 176212 0x1818-0x181b.7 (4)
+0x1810| 00 00 00 00| ....| datum_typmod: 0 0x181c-0x181f.7 (4)
+0x1820|01 00 00 00 |.... | datum_typeid: 1 0x1820-0x1823.7 (4)
+ | | | t_ctid{}: 0x1824-0x1829.7 (6)
+0x1820| 00 00 00 00 | .... | ip_blkid: 0 0x1824-0x1827.7 (4)
+0x1820| fe 00 | .. | ip_posid: 254 0x1828-0x1829.7 (2)
+0x1820| 04 80 | .. | t_infomask2: 32772 0x182a-0x182b.7 (2)
+ | | | infomask2{}: 0x182c-NA (0)
+ | | | heap_keys_updated: false 0x182c-NA (0)
+ | | | heap_hot_updated: false 0x182c-NA (0)
+ | | | heap_only_tuple: true 0x182c-NA (0)
+0x1820| 01 29 | .) | t_infomask: 10497 0x182c-0x182d.7 (2)
+ | | | infomask{}: 0x182e-NA (0)
+ | | | heap_hasnull: true 0x182e-NA (0)
+ | | | heap_hasvarwidth: false 0x182e-NA (0)
+ | | | heap_hasexternal: false 0x182e-NA (0)
+ | | | heap_hasoid_old: false 0x182e-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x182e-NA (0)
+ | | | heap_combocid: false 0x182e-NA (0)
+ | | | heap_xmax_excl_lock: false 0x182e-NA (0)
+ | | | heap_xmax_lock_only: false 0x182e-NA (0)
+ | | | heap_xmax_shr_lock: false 0x182e-NA (0)
+ | | | heap_lock_mask: false 0x182e-NA (0)
+ | | | heap_xmin_committed: true 0x182e-NA (0)
+ | | | heap_xmin_invalid: false 0x182e-NA (0)
+ | | | heap_xmin_frozen: true 0x182e-NA (0)
+ | | | heap_xmax_committed: false 0x182e-NA (0)
+ | | | heap_xmax_invalid: true 0x182e-NA (0)
+ | | | heap_xmax_is_multi: false 0x182e-NA (0)
+ | | | heap_updated: true 0x182e-NA (0)
+ | | | heap_moved_off: false 0x182e-NA (0)
+ | | | heap_moved_in: false 0x182e-NA (0)
+ | | | heap_moved: false 0x182e-NA (0)
+0x1820| 18 | . | t_hoff: 24 0x182e-0x182e.7 (1)
+0x1820| 07| .| padding0: 7 0x182f-0x182f.7 (1)
+0x1830|64 00 00 00 0a 00 00 00 41 59 00 00 |d.......AY.. | data: "640000000a00000041590000" (raw bits) 0x1830-0x183b.7 (12)
+0x1830| 00 00 00 00| ....| padding1: "00000000" (raw bits) 0x183c-0x183f.7 (4)
diff --git a/format/postgres/testdata/flavours/pgproee11/pg_control b/format/postgres/testdata/flavours/pgproee11/pg_control
new file mode 100644
index 000000000..901423dd6
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee11/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgproee11/pg_control.fqtest b/format/postgres/testdata/flavours/pgproee11/pg_control.fqtest
new file mode 100644
index 000000000..efcd405ca
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee11/pg_control.fqtest
@@ -0,0 +1,73 @@
+$ fq -d pg_control -o flavour=pgproee11 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|34 c9 ea 6a e6 00 bf 62 |4..j...b | system_identifier: 7115406925904922932 0x0-0x7.7 (8)
+0x0000| b0 04 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1200" (1346700464) 0x8-0xb.7 (4)
+0x0000| 1e 5d 07 0c| .]..| catalog_version_no: 201809182 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| d8 f9 e8 62 00 00 00 00| ...b....| time: "Tue, 02 Aug 2022 10:18:00 UTC" (1659435480) 0x18-0x1f.7 (8)
+0x0020|88 3a 35 00 04 00 00 00 |.:5..... | check_point: "4/353A88" (17183357576) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| 40 56 52 c8 03 00 00 00| @VR.....| redo: "3/C8525640" (16245741120) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|02 4f f2 54 02 00 00 00 |.O.T.... | next_xid: 10015100674 0x40-0x47.7 (8)
+0x0040| 00 80 01 00 | .... | next_oid: 98304 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|3b e6 0b 54 02 00 00 00 |;..T.... | oldest_xid: 10000000571 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|ca f8 e8 62 00 00 00 00 |...b.... | time: "Tue, 02 Aug 2022 10:13:30 UTC" (1659435210) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| f8 4e f2 54 02 00 00 00| .N.T....| oldest_active_xid: 10015100664 0x98-0x9f.7 (8)
+0x00a0|01 00 00 00 00 00 00 00 |........ | unlogged_lsn: "0/1" (1) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| 8b 01 00 00 | .... | max_connections: 395 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 00 00 00 00| ....| max_prepared_xacts: 0 0xdc-0xdf.7 (4)
+0x00e0|40 00 00 00 |@... | max_locks_per_xact: 64 0xe0-0xe3.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe4-0xe4.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe5-0xe7.7 (3)
+0x00e0| 08 00 00 00 | .... | max_align: 8 0xe8-0xeb.7 (4)
+0x00e0| 00 00 00 00| ....| hole9: 0 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float4_by_val: 1 0x118-0x118.7 (1)
+0x0110| 01 | . | float8_by_val: 1 0x119-0x119.7 (1)
+0x0110| 00 00 | .. | hole10: 0 0x11a-0x11b.7 (2)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|4c 9a 5d 04 f1 83 24 46 3c 50 3e 7d 42 94 69 a7|L.]...$F}B.i.| mock_authentication_nonce: "4c9a5d04f18324463c503e7d429469a70fe34aacd9f4cb2..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|0f e3 4a ac d9 f4 cb 2a 42 d2 2b 5e 7c f0 1c c9|..J....*B.+^|...|
+0x0140|32 02 00 00 |2... | icu_version: "50.2.0.0" (562) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| 01 00 00 00 | .... | oldest_snapshot: 1 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| recent_snapshot: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 |.... | active_snapshot: 0 0x150-0x153.7 (4)
+0x0150| 5d a0 25 99 | ].%. | crc: 2569379933 0x154-0x157.7 (4)
+0x0150| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x158-0x1fff.7 (7848)
+0x0160|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7848) | |
diff --git a/format/postgres/testdata/flavours/pgproee11/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgproee11/pg_control_1.fqtest
new file mode 100644
index 000000000..40aa062f5
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee11/pg_control_1.fqtest
@@ -0,0 +1,73 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|34 c9 ea 6a e6 00 bf 62 |4..j...b | system_identifier: 7115406925904922932 0x0-0x7.7 (8)
+0x0000| b0 04 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1200" (1346700464) 0x8-0xb.7 (4)
+0x0000| 1e 5d 07 0c| .]..| catalog_version_no: 201809182 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| d8 f9 e8 62 00 00 00 00| ...b....| time: "Tue, 02 Aug 2022 10:18:00 UTC" (1659435480) 0x18-0x1f.7 (8)
+0x0020|88 3a 35 00 04 00 00 00 |.:5..... | check_point: "4/353A88" (17183357576) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| 40 56 52 c8 03 00 00 00| @VR.....| redo: "3/C8525640" (16245741120) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|02 4f f2 54 02 00 00 00 |.O.T.... | next_xid: 10015100674 0x40-0x47.7 (8)
+0x0040| 00 80 01 00 | .... | next_oid: 98304 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|3b e6 0b 54 02 00 00 00 |;..T.... | oldest_xid: 10000000571 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|ca f8 e8 62 00 00 00 00 |...b.... | time: "Tue, 02 Aug 2022 10:13:30 UTC" (1659435210) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| f8 4e f2 54 02 00 00 00| .N.T....| oldest_active_xid: 10015100664 0x98-0x9f.7 (8)
+0x00a0|01 00 00 00 00 00 00 00 |........ | unlogged_lsn: "0/1" (1) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| 8b 01 00 00 | .... | max_connections: 395 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 00 00 00 00| ....| max_prepared_xacts: 0 0xdc-0xdf.7 (4)
+0x00e0|40 00 00 00 |@... | max_locks_per_xact: 64 0xe0-0xe3.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe4-0xe4.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe5-0xe7.7 (3)
+0x00e0| 08 00 00 00 | .... | max_align: 8 0xe8-0xeb.7 (4)
+0x00e0| 00 00 00 00| ....| hole9: 0 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float4_by_val: 1 0x118-0x118.7 (1)
+0x0110| 01 | . | float8_by_val: 1 0x119-0x119.7 (1)
+0x0110| 00 00 | .. | hole10: 0 0x11a-0x11b.7 (2)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|4c 9a 5d 04 f1 83 24 46 3c 50 3e 7d 42 94 69 a7|L.]...$F
}B.i.| mock_authentication_nonce: "4c9a5d04f18324463c503e7d429469a70fe34aacd9f4cb2..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|0f e3 4a ac d9 f4 cb 2a 42 d2 2b 5e 7c f0 1c c9|..J....*B.+^|...|
+0x0140|32 02 00 00 |2... | icu_version: "50.2.0.0" (562) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| 01 00 00 00 | .... | oldest_snapshot: 1 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| recent_snapshot: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 |.... | active_snapshot: 0 0x150-0x153.7 (4)
+0x0150| 5d a0 25 99 | ].%. | crc: 2569379933 0x154-0x157.7 (4)
+0x0150| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x158-0x1fff.7 (7848)
+0x0160|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7848) | |
diff --git a/format/postgres/testdata/flavours/pgproee12/16396 b/format/postgres/testdata/flavours/pgproee12/16396
new file mode 100644
index 000000000..1f84d49a4
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee12/16396 differ
diff --git a/format/postgres/testdata/flavours/pgproee12/16396_1.fqtest b/format/postgres/testdata/flavours/pgproee12/16396_1.fqtest
new file mode 100644
index 000000000..73997b281
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee12/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee12 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| 68 9f f2 00 | h... | item_id_data: 15900520 0x14-0x17.7 (4)
+ | | | lp_off: 8040 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 121 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[65]{}: item_id 0x118-0x11b.7 (4)
+0x110| 68 81 f2 00 | h... | item_id_data: 15892840 0x118-0x11b.7 (4)
+ | | | lp_off: 360 0x11c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x11c-NA (0)
+ | | | lp_len: 121 0x11c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee12/16406 b/format/postgres/testdata/flavours/pgproee12/16406
new file mode 100644
index 000000000..c642a51a0
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee12/16406 differ
diff --git a/format/postgres/testdata/flavours/pgproee12/16406_1.fqtest b/format/postgres/testdata/flavours/pgproee12/16406_1.fqtest
new file mode 100644
index 000000000..8b10391ae
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee12/16406_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee12 ".[0].pd_linp[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| b8 9f 60 00 | ..`. | item_id_data: 6332344 0x14-0x17.7 (4)
+ | | | lp_off: 8120 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 48 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[155]{}: item_id 0x280-0x283.7 (4)
+0x280|a8 82 60 00 |..`. | item_id_data: 6324904 0x280-0x283.7 (4)
+ | | | lp_off: 680 0x284-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x284-NA (0)
+ | | | lp_len: 48 0x284-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee12/16406_2.fqtest b/format/postgres/testdata/flavours/pgproee12/16406_2.fqtest
new file mode 100644
index 000000000..05871daeb
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee12/16406_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgproee12 ".[0].tuples[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fb8-0x1fe7.7 (48)
+ | | | header{}: 0x1fb8-0x1fcf.7 (24)
+ | | | t_choice{}: 0x1fb8-0x1fc3.7 (12)
+ | | | t_heap{}: 0x1fb8-0x1fc3.7 (12)
+0x1fb0| 03 00 00 00 | .... | t_xmin: 3 0x1fb8-0x1fbb.7 (4)
+0x1fb0| 00 00 00 00| ....| t_xmax: 0 0x1fbc-0x1fbf.7 (4)
+ | | | t_field3{}: 0x1fc0-0x1fc3.7 (4)
+0x1fc0|03 00 00 00 |.... | t_cid: 3 0x1fc0-0x1fc3.7 (4)
+0x1fc0|03 00 00 00 |.... | t_xvac: 3 0x1fc0-0x1fc3.7 (4)
+ | | | t_datum{}: 0x1fb8-0x1fc3.7 (12)
+0x1fb0| 03 00 00 00 | .... | datum_len_: 3 0x1fb8-0x1fbb.7 (4)
+0x1fb0| 00 00 00 00| ....| datum_typmod: 0 0x1fbc-0x1fbf.7 (4)
+0x1fc0|03 00 00 00 |.... | datum_typeid: 3 0x1fc0-0x1fc3.7 (4)
+ | | | t_ctid{}: 0x1fc4-0x1fc9.7 (6)
+0x1fc0| 00 00 00 00 | .... | ip_blkid: 0 0x1fc4-0x1fc7.7 (4)
+0x1fc0| 01 00 | .. | ip_posid: 1 0x1fc8-0x1fc9.7 (2)
+0x1fc0| 06 00 | .. | t_infomask2: 6 0x1fca-0x1fcb.7 (2)
+ | | | infomask2{}: 0x1fcc-NA (0)
+ | | | heap_keys_updated: false 0x1fcc-NA (0)
+ | | | heap_hot_updated: false 0x1fcc-NA (0)
+ | | | heap_only_tuple: false 0x1fcc-NA (0)
+0x1fc0| 01 09 | .. | t_infomask: 2305 0x1fcc-0x1fcd.7 (2)
+ | | | infomask{}: 0x1fce-NA (0)
+ | | | heap_hasnull: true 0x1fce-NA (0)
+ | | | heap_hasvarwidth: false 0x1fce-NA (0)
+ | | | heap_hasexternal: false 0x1fce-NA (0)
+ | | | heap_hasoid_old: false 0x1fce-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fce-NA (0)
+ | | | heap_combocid: false 0x1fce-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fce-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fce-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fce-NA (0)
+ | | | heap_lock_mask: false 0x1fce-NA (0)
+ | | | heap_xmin_committed: true 0x1fce-NA (0)
+ | | | heap_xmin_invalid: false 0x1fce-NA (0)
+ | | | heap_xmin_frozen: true 0x1fce-NA (0)
+ | | | heap_xmax_committed: false 0x1fce-NA (0)
+ | | | heap_xmax_invalid: true 0x1fce-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fce-NA (0)
+ | | | heap_updated: false 0x1fce-NA (0)
+ | | | heap_moved_off: false 0x1fce-NA (0)
+ | | | heap_moved_in: false 0x1fce-NA (0)
+ | | | heap_moved: false 0x1fce-NA (0)
+0x1fc0| 18 | . | t_hoff: 24 0x1fce-0x1fce.7 (1)
+0x1fc0| 1f| .| padding0: 31 0x1fcf-0x1fcf.7 (1)
+0x1fd0|02 00 00 00 01 00 00 00 38 fd 00 00 89 0c 00 00|........8.......| data: "020000000100000038fd0000890c0000c025676d6388020..." (raw bits) 0x1fd0-0x1fe7.7 (24)
+0x1fe0|c0 25 67 6d 63 88 02 00 |.%gmc... |
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[155]{}: tuple 0x2a8-0x2d7.7 (48)
+ | | | header{}: 0x2a8-0x2bf.7 (24)
+ | | | t_choice{}: 0x2a8-0x2b3.7 (12)
+ | | | t_heap{}: 0x2a8-0x2b3.7 (12)
+0x2a0| 9e 00 00 00 | .... | t_xmin: 158 0x2a8-0x2ab.7 (4)
+0x2a0| 00 00 00 00| ....| t_xmax: 0 0x2ac-0x2af.7 (4)
+ | | | t_field3{}: 0x2b0-0x2b3.7 (4)
+0x2b0|03 00 00 00 |.... | t_cid: 3 0x2b0-0x2b3.7 (4)
+0x2b0|03 00 00 00 |.... | t_xvac: 3 0x2b0-0x2b3.7 (4)
+ | | | t_datum{}: 0x2a8-0x2b3.7 (12)
+0x2a0| 9e 00 00 00 | .... | datum_len_: 158 0x2a8-0x2ab.7 (4)
+0x2a0| 00 00 00 00| ....| datum_typmod: 0 0x2ac-0x2af.7 (4)
+0x2b0|03 00 00 00 |.... | datum_typeid: 3 0x2b0-0x2b3.7 (4)
+ | | | t_ctid{}: 0x2b4-0x2b9.7 (6)
+0x2b0| 00 00 00 00 | .... | ip_blkid: 0 0x2b4-0x2b7.7 (4)
+0x2b0| 9c 00 | .. | ip_posid: 156 0x2b8-0x2b9.7 (2)
+0x2b0| 06 00 | .. | t_infomask2: 6 0x2ba-0x2bb.7 (2)
+ | | | infomask2{}: 0x2bc-NA (0)
+ | | | heap_keys_updated: false 0x2bc-NA (0)
+ | | | heap_hot_updated: false 0x2bc-NA (0)
+ | | | heap_only_tuple: false 0x2bc-NA (0)
+0x2b0| 01 09 | .. | t_infomask: 2305 0x2bc-0x2bd.7 (2)
+ | | | infomask{}: 0x2be-NA (0)
+ | | | heap_hasnull: true 0x2be-NA (0)
+ | | | heap_hasvarwidth: false 0x2be-NA (0)
+ | | | heap_hasexternal: false 0x2be-NA (0)
+ | | | heap_hasoid_old: false 0x2be-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2be-NA (0)
+ | | | heap_combocid: false 0x2be-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2be-NA (0)
+ | | | heap_xmax_lock_only: false 0x2be-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2be-NA (0)
+ | | | heap_lock_mask: false 0x2be-NA (0)
+ | | | heap_xmin_committed: true 0x2be-NA (0)
+ | | | heap_xmin_invalid: false 0x2be-NA (0)
+ | | | heap_xmin_frozen: true 0x2be-NA (0)
+ | | | heap_xmax_committed: false 0x2be-NA (0)
+ | | | heap_xmax_invalid: true 0x2be-NA (0)
+ | | | heap_xmax_is_multi: false 0x2be-NA (0)
+ | | | heap_updated: false 0x2be-NA (0)
+ | | | heap_moved_off: false 0x2be-NA (0)
+ | | | heap_moved_in: false 0x2be-NA (0)
+ | | | heap_moved: false 0x2be-NA (0)
+0x2b0| 18 | . | t_hoff: 24 0x2be-0x2be.7 (1)
+0x2b0| 1f| .| padding0: 31 0x2bf-0x2bf.7 (1)
+0x2c0|08 00 00 00 01 00 00 00 e4 f5 00 00 c9 06 00 00|................| data: "0800000001000000e4f50000c9060000d0a36f6d6388020..." (raw bits) 0x2c0-0x2d7.7 (24)
+0x2d0|d0 a3 6f 6d 63 88 02 00 |..omc... |
diff --git a/format/postgres/testdata/flavours/pgproee12/pg_control b/format/postgres/testdata/flavours/pgproee12/pg_control
new file mode 100644
index 000000000..d0c9f9d1d
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee12/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgproee12/pg_control.fqtest b/format/postgres/testdata/flavours/pgproee12/pg_control.fqtest
new file mode 100644
index 000000000..6f4bfd839
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee12/pg_control.fqtest
@@ -0,0 +1,73 @@
+$ fq -d pg_control -o flavour=pgproee12 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|d8 09 ef 93 89 69 eb 62 |.....i.b | system_identifier: 7127906874857294296 0x0-0x7.7 (8)
+0x0000| b1 04 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1201" (1346700465) 0x8-0xb.7 (4)
+0x0000| a1 eb 08 0c| ....| catalog_version_no: 201911201 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| db 6a eb 62 00 00 00 00| .j.b....| time: "Thu, 04 Aug 2022 06:44:43 UTC" (1659595483) 0x18-0x1f.7 (8)
+0x0020|b8 77 07 03 00 00 00 00 |.w...... | check_point: "0/30777B8" (50821048) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| 68 77 07 03 00 00 00 00| hw......| redo: "0/3077768" (50820968) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|db 34 0c 54 02 00 00 00 |.4.T.... | next_xid: 10000020699 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|e9 e5 0b 54 02 00 00 00 |...T.... | oldest_xid: 10000000489 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|db 6a eb 62 00 00 00 00 |.j.b.... | time: "Thu, 04 Aug 2022 06:44:43 UTC" (1659595483) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| db 34 0c 54 02 00 00 00| .4.T....| oldest_active_xid: 10000020699 0x98-0x9f.7 (8)
+0x00a0|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| 8a 01 00 00 | .... | max_connections: 394 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 0a 00 00 00| ....| max_wal_senders: 10 0xdc-0xdf.7 (4)
+0x00e0|00 00 00 00 |.... | max_prepared_xacts: 0 0xe0-0xe3.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe4-0xe7.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe8-0xe8.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe9-0xeb.7 (3)
+0x00e0| 08 00 00 00| ....| max_align: 8 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float4_by_val: 1 0x118-0x118.7 (1)
+0x0110| 01 | . | float8_by_val: 1 0x119-0x119.7 (1)
+0x0110| 00 00 | .. | hole9: 0 0x11a-0x11b.7 (2)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|0b db 53 d2 42 ff 02 95 74 e6 aa 87 ff 98 4b 67|..S.B...t.....Kg| mock_authentication_nonce: "0bdb53d242ff029574e6aa87ff984b67e4a76678383559a..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|e4 a7 66 78 38 35 59 a3 14 f2 65 01 9e 61 8c e4|..fx85Y...e..a..|
+0x0140|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| 01 00 00 00 | .... | oldest_snapshot: 1 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| recent_snapshot: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 |.... | active_snapshot: 0 0x150-0x153.7 (4)
+0x0150| f4 4f d7 dd | .O.. | crc: 3721875444 0x154-0x157.7 (4)
+0x0150| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x158-0x1fff.7 (7848)
+0x0160|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7848) | |
diff --git a/format/postgres/testdata/flavours/pgproee12/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgproee12/pg_control_1.fqtest
new file mode 100644
index 000000000..ba494ba16
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee12/pg_control_1.fqtest
@@ -0,0 +1,73 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|d8 09 ef 93 89 69 eb 62 |.....i.b | system_identifier: 7127906874857294296 0x0-0x7.7 (8)
+0x0000| b1 04 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1201" (1346700465) 0x8-0xb.7 (4)
+0x0000| a1 eb 08 0c| ....| catalog_version_no: 201911201 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| db 6a eb 62 00 00 00 00| .j.b....| time: "Thu, 04 Aug 2022 06:44:43 UTC" (1659595483) 0x18-0x1f.7 (8)
+0x0020|b8 77 07 03 00 00 00 00 |.w...... | check_point: "0/30777B8" (50821048) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| 68 77 07 03 00 00 00 00| hw......| redo: "0/3077768" (50820968) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|db 34 0c 54 02 00 00 00 |.4.T.... | next_xid: 10000020699 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|e9 e5 0b 54 02 00 00 00 |...T.... | oldest_xid: 10000000489 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|db 6a eb 62 00 00 00 00 |.j.b.... | time: "Thu, 04 Aug 2022 06:44:43 UTC" (1659595483) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| db 34 0c 54 02 00 00 00| .4.T....| oldest_active_xid: 10000020699 0x98-0x9f.7 (8)
+0x00a0|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| 8a 01 00 00 | .... | max_connections: 394 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 0a 00 00 00| ....| max_wal_senders: 10 0xdc-0xdf.7 (4)
+0x00e0|00 00 00 00 |.... | max_prepared_xacts: 0 0xe0-0xe3.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe4-0xe7.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe8-0xe8.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe9-0xeb.7 (3)
+0x00e0| 08 00 00 00| ....| max_align: 8 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float4_by_val: 1 0x118-0x118.7 (1)
+0x0110| 01 | . | float8_by_val: 1 0x119-0x119.7 (1)
+0x0110| 00 00 | .. | hole9: 0 0x11a-0x11b.7 (2)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|0b db 53 d2 42 ff 02 95 74 e6 aa 87 ff 98 4b 67|..S.B...t.....Kg| mock_authentication_nonce: "0bdb53d242ff029574e6aa87ff984b67e4a76678383559a..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|e4 a7 66 78 38 35 59 a3 14 f2 65 01 9e 61 8c e4|..fx85Y...e..a..|
+0x0140|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| 01 00 00 00 | .... | oldest_snapshot: 1 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| recent_snapshot: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 |.... | active_snapshot: 0 0x150-0x153.7 (4)
+0x0150| f4 4f d7 dd | .O.. | crc: 3721875444 0x154-0x157.7 (4)
+0x0150| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x158-0x1fff.7 (7848)
+0x0160|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7848) | |
diff --git a/format/postgres/testdata/flavours/pgproee13/16396 b/format/postgres/testdata/flavours/pgproee13/16396
new file mode 100644
index 000000000..a64fa4fb5
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee13/16396 differ
diff --git a/format/postgres/testdata/flavours/pgproee13/16396_1.fqtest b/format/postgres/testdata/flavours/pgproee13/16396_1.fqtest
new file mode 100644
index 000000000..1fbe7b824
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee13/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee13 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| 68 9f f2 00 | h... | item_id_data: 15900520 0x14-0x17.7 (4)
+ | | | lp_off: 8040 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 121 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[68]{}: item_id 0x124-0x127.7 (4)
+0x120| 68 81 f2 00 | h... | item_id_data: 15892840 0x124-0x127.7 (4)
+ | | | lp_off: 360 0x128-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x128-NA (0)
+ | | | lp_len: 121 0x128-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee13/16406 b/format/postgres/testdata/flavours/pgproee13/16406
new file mode 100644
index 000000000..01627660b
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee13/16406 differ
diff --git a/format/postgres/testdata/flavours/pgproee13/16406_1.fqtest b/format/postgres/testdata/flavours/pgproee13/16406_1.fqtest
new file mode 100644
index 000000000..25156cd8f
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee13/16406_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee13 ".[0].pd_linp[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| b8 9f 60 00 | ..`. | item_id_data: 6332344 0x14-0x17.7 (4)
+ | | | lp_off: 8120 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 48 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[155]{}: item_id 0x280-0x283.7 (4)
+0x280|a8 82 60 00 |..`. | item_id_data: 6324904 0x280-0x283.7 (4)
+ | | | lp_off: 680 0x284-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x284-NA (0)
+ | | | lp_len: 48 0x284-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee13/16406_2.fqtest b/format/postgres/testdata/flavours/pgproee13/16406_2.fqtest
new file mode 100644
index 000000000..f2bd51aa5
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee13/16406_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=pgproee13 ".[0].tuples[0,-1] | dv" 16406
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fb8-0x1fe7.7 (48)
+ | | | header{}: 0x1fb8-0x1fcf.7 (24)
+ | | | t_choice{}: 0x1fb8-0x1fc3.7 (12)
+ | | | t_heap{}: 0x1fb8-0x1fc3.7 (12)
+0x1fb0| 03 00 00 00 | .... | t_xmin: 3 0x1fb8-0x1fbb.7 (4)
+0x1fb0| 00 00 00 00| ....| t_xmax: 0 0x1fbc-0x1fbf.7 (4)
+ | | | t_field3{}: 0x1fc0-0x1fc3.7 (4)
+0x1fc0|03 00 00 00 |.... | t_cid: 3 0x1fc0-0x1fc3.7 (4)
+0x1fc0|03 00 00 00 |.... | t_xvac: 3 0x1fc0-0x1fc3.7 (4)
+ | | | t_datum{}: 0x1fb8-0x1fc3.7 (12)
+0x1fb0| 03 00 00 00 | .... | datum_len_: 3 0x1fb8-0x1fbb.7 (4)
+0x1fb0| 00 00 00 00| ....| datum_typmod: 0 0x1fbc-0x1fbf.7 (4)
+0x1fc0|03 00 00 00 |.... | datum_typeid: 3 0x1fc0-0x1fc3.7 (4)
+ | | | t_ctid{}: 0x1fc4-0x1fc9.7 (6)
+0x1fc0| 00 00 00 00 | .... | ip_blkid: 0 0x1fc4-0x1fc7.7 (4)
+0x1fc0| 01 00 | .. | ip_posid: 1 0x1fc8-0x1fc9.7 (2)
+0x1fc0| 06 00 | .. | t_infomask2: 6 0x1fca-0x1fcb.7 (2)
+ | | | infomask2{}: 0x1fcc-NA (0)
+ | | | heap_keys_updated: false 0x1fcc-NA (0)
+ | | | heap_hot_updated: false 0x1fcc-NA (0)
+ | | | heap_only_tuple: false 0x1fcc-NA (0)
+0x1fc0| 01 09 | .. | t_infomask: 2305 0x1fcc-0x1fcd.7 (2)
+ | | | infomask{}: 0x1fce-NA (0)
+ | | | heap_hasnull: true 0x1fce-NA (0)
+ | | | heap_hasvarwidth: false 0x1fce-NA (0)
+ | | | heap_hasexternal: false 0x1fce-NA (0)
+ | | | heap_hasoid_old: false 0x1fce-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fce-NA (0)
+ | | | heap_combocid: false 0x1fce-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fce-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fce-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fce-NA (0)
+ | | | heap_lock_mask: false 0x1fce-NA (0)
+ | | | heap_xmin_committed: true 0x1fce-NA (0)
+ | | | heap_xmin_invalid: false 0x1fce-NA (0)
+ | | | heap_xmin_frozen: true 0x1fce-NA (0)
+ | | | heap_xmax_committed: false 0x1fce-NA (0)
+ | | | heap_xmax_invalid: true 0x1fce-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fce-NA (0)
+ | | | heap_updated: false 0x1fce-NA (0)
+ | | | heap_moved_off: false 0x1fce-NA (0)
+ | | | heap_moved_in: false 0x1fce-NA (0)
+ | | | heap_moved: false 0x1fce-NA (0)
+0x1fc0| 18 | . | t_hoff: 24 0x1fce-0x1fce.7 (1)
+0x1fc0| 1f| .| padding0: 31 0x1fcf-0x1fcf.7 (1)
+0x1fd0|01 00 00 00 01 00 00 00 76 cd 00 00 3d fc ff ff|........v...=...| data: "010000000100000076cd00003dfcffff088e15d47788020..." (raw bits) 0x1fd0-0x1fe7.7 (24)
+0x1fe0|08 8e 15 d4 77 88 02 00 |....w... |
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[155]{}: tuple 0x2a8-0x2d7.7 (48)
+ | | | header{}: 0x2a8-0x2bf.7 (24)
+ | | | t_choice{}: 0x2a8-0x2b3.7 (12)
+ | | | t_heap{}: 0x2a8-0x2b3.7 (12)
+0x2a0| 9e 00 00 00 | .... | t_xmin: 158 0x2a8-0x2ab.7 (4)
+0x2a0| 00 00 00 00| ....| t_xmax: 0 0x2ac-0x2af.7 (4)
+ | | | t_field3{}: 0x2b0-0x2b3.7 (4)
+0x2b0|03 00 00 00 |.... | t_cid: 3 0x2b0-0x2b3.7 (4)
+0x2b0|03 00 00 00 |.... | t_xvac: 3 0x2b0-0x2b3.7 (4)
+ | | | t_datum{}: 0x2a8-0x2b3.7 (12)
+0x2a0| 9e 00 00 00 | .... | datum_len_: 158 0x2a8-0x2ab.7 (4)
+0x2a0| 00 00 00 00| ....| datum_typmod: 0 0x2ac-0x2af.7 (4)
+0x2b0|03 00 00 00 |.... | datum_typeid: 3 0x2b0-0x2b3.7 (4)
+ | | | t_ctid{}: 0x2b4-0x2b9.7 (6)
+0x2b0| 00 00 00 00 | .... | ip_blkid: 0 0x2b4-0x2b7.7 (4)
+0x2b0| 9c 00 | .. | ip_posid: 156 0x2b8-0x2b9.7 (2)
+0x2b0| 06 00 | .. | t_infomask2: 6 0x2ba-0x2bb.7 (2)
+ | | | infomask2{}: 0x2bc-NA (0)
+ | | | heap_keys_updated: false 0x2bc-NA (0)
+ | | | heap_hot_updated: false 0x2bc-NA (0)
+ | | | heap_only_tuple: false 0x2bc-NA (0)
+0x2b0| 01 09 | .. | t_infomask: 2305 0x2bc-0x2bd.7 (2)
+ | | | infomask{}: 0x2be-NA (0)
+ | | | heap_hasnull: true 0x2be-NA (0)
+ | | | heap_hasvarwidth: false 0x2be-NA (0)
+ | | | heap_hasexternal: false 0x2be-NA (0)
+ | | | heap_hasoid_old: false 0x2be-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2be-NA (0)
+ | | | heap_combocid: false 0x2be-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2be-NA (0)
+ | | | heap_xmax_lock_only: false 0x2be-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2be-NA (0)
+ | | | heap_lock_mask: false 0x2be-NA (0)
+ | | | heap_xmin_committed: true 0x2be-NA (0)
+ | | | heap_xmin_invalid: false 0x2be-NA (0)
+ | | | heap_xmin_frozen: true 0x2be-NA (0)
+ | | | heap_xmax_committed: false 0x2be-NA (0)
+ | | | heap_xmax_invalid: true 0x2be-NA (0)
+ | | | heap_xmax_is_multi: false 0x2be-NA (0)
+ | | | heap_updated: false 0x2be-NA (0)
+ | | | heap_moved_off: false 0x2be-NA (0)
+ | | | heap_moved_in: false 0x2be-NA (0)
+ | | | heap_moved: false 0x2be-NA (0)
+0x2b0| 18 | . | t_hoff: 24 0x2be-0x2be.7 (1)
+0x2b0| 1f| .| padding0: 31 0x2bf-0x2bf.7 (1)
+0x2c0|04 00 00 00 01 00 00 00 71 8a 00 00 81 fb ff ff|........q.......| data: "0400000001000000718a000081fbffff546f1cd47788020..." (raw bits) 0x2c0-0x2d7.7 (24)
+0x2d0|54 6f 1c d4 77 88 02 00 |To..w... |
diff --git a/format/postgres/testdata/flavours/pgproee13/pg_control b/format/postgres/testdata/flavours/pgproee13/pg_control
new file mode 100644
index 000000000..dd72a1945
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee13/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgproee13/pg_control.fqtest b/format/postgres/testdata/flavours/pgproee13/pg_control.fqtest
new file mode 100644
index 000000000..3c053a7a0
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee13/pg_control.fqtest
@@ -0,0 +1,69 @@
+$ fq -d pg_control -o flavour=pgproee13 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|5f 69 c1 ec 6b bc ec 62 |_i..k..b | system_identifier: 7128279481940273503 0x0-0x7.7 (8)
+0x0000| 14 05 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1300" (1346700564) 0x8-0xb.7 (4)
+0x0000| 27 6e 0a 0c| 'n..| catalog_version_no: 202010151 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 66 c2 ec 62 00 00 00 00| f..b....| time: "Fri, 05 Aug 2022 07:10:30 UTC" (1659683430) 0x18-0x1f.7 (8)
+0x0020|78 0a e9 02 00 00 00 00 |x....... | check_point: "0/2E90A78" (48827000) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| 28 0a e9 02 00 00 00 00| (.......| redo: "0/2E90A28" (48826920) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|92 29 0c 54 02 00 00 00 |.).T.... | next_xid: 10000017810 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|eb e5 0b 54 02 00 00 00 |...T.... | oldest_xid: 10000000491 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|65 c2 ec 62 00 00 00 00 |e..b.... | time: "Fri, 05 Aug 2022 07:10:29 UTC" (1659683429) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| 92 29 0c 54 02 00 00 00| .).T....| oldest_active_xid: 10000017810 0x98-0x9f.7 (8)
+0x00a0|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| 5d 00 00 00 | ]... | max_connections: 93 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 0a 00 00 00| ....| max_wal_senders: 10 0xdc-0xdf.7 (4)
+0x00e0|00 00 00 00 |.... | max_prepared_xacts: 0 0xe0-0xe3.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe4-0xe7.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe8-0xe8.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe9-0xeb.7 (3)
+0x00e0| 08 00 00 00| ....| max_align: 8 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float8_by_val: 1 0x118-0x118.7 (1)
+0x0110| 00 00 00 | ... | hole9: 0 0x119-0x11b.7 (3)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|9e 64 59 21 b6 ed 30 38 f8 be c1 a7 82 40 df cd|.dY!..08.....@..| mock_authentication_nonce: "9e645921b6ed3038f8bec1a78240dfcd0cbfdafcba223be..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|0c bf da fc ba 22 3b e1 e7 b2 79 50 c6 03 84 39|.....";...yP...9|
+0x0140|3c 03 00 00 |<... | icu_version: "60.3.0.0" (828) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| ab b4 06 87 | .... | crc: 2265363627 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| padding0: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................| unused: raw bits 0x150-0x1fff.7 (7856)
+* |until 0x1fff.7 (end) (7856) | |
diff --git a/format/postgres/testdata/flavours/pgproee14/.gitignore b/format/postgres/testdata/flavours/pgproee14/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/format/postgres/testdata/flavours/pgproee14/16396 b/format/postgres/testdata/flavours/pgproee14/16396
new file mode 100644
index 000000000..94e33cabf
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee14/16396 differ
diff --git a/format/postgres/testdata/flavours/pgproee14/16396_1.fqtest b/format/postgres/testdata/flavours/pgproee14/16396_1.fqtest
new file mode 100644
index 000000000..ac487d369
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee14/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=pgproee14 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| 53 00 01 00 | S... | item_id_data: 65619 0x14-0x17.7 (4)
+ | | | lp_off: 83 0x18-NA (0)
+ | | | lp_flags: "LP_REDIRECT" (2) 0x18-NA (0)
+ | | | lp_len: 0 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[85]{}: item_id 0x168-0x16b.7 (4)
+0x160| e8 81 f2 00 | .... | item_id_data: 15892968 0x168-0x16b.7 (4)
+ | | | lp_off: 488 0x16c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x16c-NA (0)
+ | | | lp_len: 121 0x16c-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee14/16404 b/format/postgres/testdata/flavours/pgproee14/16404
new file mode 100644
index 000000000..83827438a
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee14/16404 differ
diff --git a/format/postgres/testdata/flavours/pgproee14/16404_1.fqtest b/format/postgres/testdata/flavours/pgproee14/16404_1.fqtest
new file mode 100644
index 000000000..a38f9f839
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee14/16404_1.fqtest
@@ -0,0 +1,51 @@
+$ fq -d pg_btree ".[1].pd_linp[0,1,2,3,4,5,6,7,8,9] | dv" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[0]{}: item_id 0x2018-0x201b.7 (4)
+0x2010| e0 9f 20 00 | .. . | item_id_data: 2138080 0x2018-0x201b.7 (4)
+ | | | lp_off: 8160 0x201c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x201c-NA (0)
+ | | | lp_len: 16 0x201c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[1]{}: item_id 0x201c-0x201f.7 (4)
+0x2010| d0 9f 20 00| .. .| item_id_data: 2138064 0x201c-0x201f.7 (4)
+ | | | lp_off: 8144 0x2020-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2020-NA (0)
+ | | | lp_len: 16 0x2020-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[2]{}: item_id 0x2020-0x2023.7 (4)
+0x2020|c0 9f 20 00 |.. . | item_id_data: 2138048 0x2020-0x2023.7 (4)
+ | | | lp_off: 8128 0x2024-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2024-NA (0)
+ | | | lp_len: 16 0x2024-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[3]{}: item_id 0x2024-0x2027.7 (4)
+0x2020| b0 9f 20 00 | .. . | item_id_data: 2138032 0x2024-0x2027.7 (4)
+ | | | lp_off: 8112 0x2028-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2028-NA (0)
+ | | | lp_len: 16 0x2028-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[4]{}: item_id 0x2028-0x202b.7 (4)
+0x2020| a0 9f 20 00 | .. . | item_id_data: 2138016 0x2028-0x202b.7 (4)
+ | | | lp_off: 8096 0x202c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x202c-NA (0)
+ | | | lp_len: 16 0x202c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[5]{}: item_id 0x202c-0x202f.7 (4)
+0x2020| 90 9f 20 00| .. .| item_id_data: 2138000 0x202c-0x202f.7 (4)
+ | | | lp_off: 8080 0x2030-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2030-NA (0)
+ | | | lp_len: 16 0x2030-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[6]{}: item_id 0x2030-0x2033.7 (4)
+0x2030|80 9f 20 00 |.. . | item_id_data: 2137984 0x2030-0x2033.7 (4)
+ | | | lp_off: 8064 0x2034-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2034-NA (0)
+ | | | lp_len: 16 0x2034-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[7]{}: item_id 0x2034-0x2037.7 (4)
+0x2030| 70 9f 20 00 | p. . | item_id_data: 2137968 0x2034-0x2037.7 (4)
+ | | | lp_off: 8048 0x2038-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2038-NA (0)
+ | | | lp_len: 16 0x2038-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[8]{}: item_id 0x2038-0x203b.7 (4)
+0x2030| 60 9f 20 00 | `. . | item_id_data: 2137952 0x2038-0x203b.7 (4)
+ | | | lp_off: 8032 0x203c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x203c-NA (0)
+ | | | lp_len: 16 0x203c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[9]{}: item_id 0x203c-0x203f.7 (4)
+0x2030| 50 9f 20 00| P. .| item_id_data: 2137936 0x203c-0x203f.7 (4)
+ | | | lp_off: 8016 0x2040-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2040-NA (0)
+ | | | lp_len: 16 0x2040-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee14/16404_2.fqtest b/format/postgres/testdata/flavours/pgproee14/16404_2.fqtest
new file mode 100644
index 000000000..f18d5de30
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee14/16404_2.fqtest
@@ -0,0 +1,111 @@
+$ fq -d pg_btree ".[1].tuples[0,1,2,3,4,5,6,7,8,9] | dv" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[0]{}: tuple 0x3fe0-0x3fef.7 (16)
+ | | | index_tuple_data{}: 0x3fe0-0x3fef.7 (16)
+ | | | t_tid{}: 0x3fe0-0x3fe5.7 (6)
+0x3fe0|00 00 00 00 |.... | ip_blkid: 0 0x3fe0-0x3fe3.7 (4)
+0x3fe0| 01 00 | .. | ip_posid: 1 0x3fe4-0x3fe5.7 (2)
+0x3fe0| 10 00 | .. | t_info: 16 0x3fe6-0x3fe7.7 (2)
+ | | | flags{}: 0x3fe8-NA (0)
+ | | | has_nulls: false 0x3fe8-NA (0)
+ | | | has_var_widths: false 0x3fe8-NA (0)
+ | | | size: 16 0x3fe8-NA (0)
+0x3fe0| 01 00 00 00 00 00 00 00| ........| data: raw bits 0x3fe8-0x3fef.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[1]{}: tuple 0x3fd0-0x3fdf.7 (16)
+ | | | index_tuple_data{}: 0x3fd0-0x3fdf.7 (16)
+ | | | t_tid{}: 0x3fd0-0x3fd5.7 (6)
+0x3fd0|00 00 00 00 |.... | ip_blkid: 0 0x3fd0-0x3fd3.7 (4)
+0x3fd0| 02 00 | .. | ip_posid: 2 0x3fd4-0x3fd5.7 (2)
+0x3fd0| 10 00 | .. | t_info: 16 0x3fd6-0x3fd7.7 (2)
+ | | | flags{}: 0x3fd8-NA (0)
+ | | | has_nulls: false 0x3fd8-NA (0)
+ | | | has_var_widths: false 0x3fd8-NA (0)
+ | | | size: 16 0x3fd8-NA (0)
+0x3fd0| 02 00 00 00 00 00 00 00| ........| data: raw bits 0x3fd8-0x3fdf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[2]{}: tuple 0x3fc0-0x3fcf.7 (16)
+ | | | index_tuple_data{}: 0x3fc0-0x3fcf.7 (16)
+ | | | t_tid{}: 0x3fc0-0x3fc5.7 (6)
+0x3fc0|00 00 00 00 |.... | ip_blkid: 0 0x3fc0-0x3fc3.7 (4)
+0x3fc0| 03 00 | .. | ip_posid: 3 0x3fc4-0x3fc5.7 (2)
+0x3fc0| 10 00 | .. | t_info: 16 0x3fc6-0x3fc7.7 (2)
+ | | | flags{}: 0x3fc8-NA (0)
+ | | | has_nulls: false 0x3fc8-NA (0)
+ | | | has_var_widths: false 0x3fc8-NA (0)
+ | | | size: 16 0x3fc8-NA (0)
+0x3fc0| 03 00 00 00 00 00 00 00| ........| data: raw bits 0x3fc8-0x3fcf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[3]{}: tuple 0x3fb0-0x3fbf.7 (16)
+ | | | index_tuple_data{}: 0x3fb0-0x3fbf.7 (16)
+ | | | t_tid{}: 0x3fb0-0x3fb5.7 (6)
+0x3fb0|00 00 00 00 |.... | ip_blkid: 0 0x3fb0-0x3fb3.7 (4)
+0x3fb0| 04 00 | .. | ip_posid: 4 0x3fb4-0x3fb5.7 (2)
+0x3fb0| 10 00 | .. | t_info: 16 0x3fb6-0x3fb7.7 (2)
+ | | | flags{}: 0x3fb8-NA (0)
+ | | | has_nulls: false 0x3fb8-NA (0)
+ | | | has_var_widths: false 0x3fb8-NA (0)
+ | | | size: 16 0x3fb8-NA (0)
+0x3fb0| 04 00 00 00 00 00 00 00| ........| data: raw bits 0x3fb8-0x3fbf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[4]{}: tuple 0x3fa0-0x3faf.7 (16)
+ | | | index_tuple_data{}: 0x3fa0-0x3faf.7 (16)
+ | | | t_tid{}: 0x3fa0-0x3fa5.7 (6)
+0x3fa0|00 00 00 00 |.... | ip_blkid: 0 0x3fa0-0x3fa3.7 (4)
+0x3fa0| 05 00 | .. | ip_posid: 5 0x3fa4-0x3fa5.7 (2)
+0x3fa0| 10 00 | .. | t_info: 16 0x3fa6-0x3fa7.7 (2)
+ | | | flags{}: 0x3fa8-NA (0)
+ | | | has_nulls: false 0x3fa8-NA (0)
+ | | | has_var_widths: false 0x3fa8-NA (0)
+ | | | size: 16 0x3fa8-NA (0)
+0x3fa0| 05 00 00 00 00 00 00 00| ........| data: raw bits 0x3fa8-0x3faf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[5]{}: tuple 0x3f90-0x3f9f.7 (16)
+ | | | index_tuple_data{}: 0x3f90-0x3f9f.7 (16)
+ | | | t_tid{}: 0x3f90-0x3f95.7 (6)
+0x3f90|00 00 00 00 |.... | ip_blkid: 0 0x3f90-0x3f93.7 (4)
+0x3f90| 06 00 | .. | ip_posid: 6 0x3f94-0x3f95.7 (2)
+0x3f90| 10 00 | .. | t_info: 16 0x3f96-0x3f97.7 (2)
+ | | | flags{}: 0x3f98-NA (0)
+ | | | has_nulls: false 0x3f98-NA (0)
+ | | | has_var_widths: false 0x3f98-NA (0)
+ | | | size: 16 0x3f98-NA (0)
+0x3f90| 06 00 00 00 00 00 00 00| ........| data: raw bits 0x3f98-0x3f9f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[6]{}: tuple 0x3f80-0x3f8f.7 (16)
+ | | | index_tuple_data{}: 0x3f80-0x3f8f.7 (16)
+ | | | t_tid{}: 0x3f80-0x3f85.7 (6)
+0x3f80|00 00 00 00 |.... | ip_blkid: 0 0x3f80-0x3f83.7 (4)
+0x3f80| 07 00 | .. | ip_posid: 7 0x3f84-0x3f85.7 (2)
+0x3f80| 10 00 | .. | t_info: 16 0x3f86-0x3f87.7 (2)
+ | | | flags{}: 0x3f88-NA (0)
+ | | | has_nulls: false 0x3f88-NA (0)
+ | | | has_var_widths: false 0x3f88-NA (0)
+ | | | size: 16 0x3f88-NA (0)
+0x3f80| 07 00 00 00 00 00 00 00| ........| data: raw bits 0x3f88-0x3f8f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[7]{}: tuple 0x3f70-0x3f7f.7 (16)
+ | | | index_tuple_data{}: 0x3f70-0x3f7f.7 (16)
+ | | | t_tid{}: 0x3f70-0x3f75.7 (6)
+0x3f70|00 00 00 00 |.... | ip_blkid: 0 0x3f70-0x3f73.7 (4)
+0x3f70| 08 00 | .. | ip_posid: 8 0x3f74-0x3f75.7 (2)
+0x3f70| 10 00 | .. | t_info: 16 0x3f76-0x3f77.7 (2)
+ | | | flags{}: 0x3f78-NA (0)
+ | | | has_nulls: false 0x3f78-NA (0)
+ | | | has_var_widths: false 0x3f78-NA (0)
+ | | | size: 16 0x3f78-NA (0)
+0x3f70| 08 00 00 00 00 00 00 00| ........| data: raw bits 0x3f78-0x3f7f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[8]{}: tuple 0x3f60-0x3f6f.7 (16)
+ | | | index_tuple_data{}: 0x3f60-0x3f6f.7 (16)
+ | | | t_tid{}: 0x3f60-0x3f65.7 (6)
+0x3f60|00 00 00 00 |.... | ip_blkid: 0 0x3f60-0x3f63.7 (4)
+0x3f60| 09 00 | .. | ip_posid: 9 0x3f64-0x3f65.7 (2)
+0x3f60| 10 00 | .. | t_info: 16 0x3f66-0x3f67.7 (2)
+ | | | flags{}: 0x3f68-NA (0)
+ | | | has_nulls: false 0x3f68-NA (0)
+ | | | has_var_widths: false 0x3f68-NA (0)
+ | | | size: 16 0x3f68-NA (0)
+0x3f60| 09 00 00 00 00 00 00 00| ........| data: raw bits 0x3f68-0x3f6f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[9]{}: tuple 0x3f50-0x3f5f.7 (16)
+ | | | index_tuple_data{}: 0x3f50-0x3f5f.7 (16)
+ | | | t_tid{}: 0x3f50-0x3f55.7 (6)
+0x3f50|00 00 00 00 |.... | ip_blkid: 0 0x3f50-0x3f53.7 (4)
+0x3f50| 0a 00 | .. | ip_posid: 10 0x3f54-0x3f55.7 (2)
+0x3f50| 10 00 | .. | t_info: 16 0x3f56-0x3f57.7 (2)
+ | | | flags{}: 0x3f58-NA (0)
+ | | | has_nulls: false 0x3f58-NA (0)
+ | | | has_var_widths: false 0x3f58-NA (0)
+ | | | size: 16 0x3f58-NA (0)
+0x3f50| 0a 00 00 00 00 00 00 00| ........| data: raw bits 0x3f58-0x3f5f.7 (8)
diff --git a/format/postgres/testdata/flavours/pgproee14/16451 b/format/postgres/testdata/flavours/pgproee14/16451
new file mode 100644
index 000000000..c2f0571fa
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee14/16451 differ
diff --git a/format/postgres/testdata/flavours/pgproee14/16451_1.fqtest b/format/postgres/testdata/flavours/pgproee14/16451_1.fqtest
new file mode 100644
index 000000000..a0501efd4
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee14/16451_1.fqtest
@@ -0,0 +1,143 @@
+$ fq -d pg_heap -o flavour=pgproee14 ".[0].tuples[1,2,3] | dv" 16451
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[1]{}: tuple 0x1f78-0x1faf.7 (56)
+ | | | header{}: 0x1f78-0x1f8f.7 (24)
+ | | | t_choice{}: 0x1f78-0x1f83.7 (12)
+ | | | t_heap{}: 0x1f78-0x1f83.7 (12)
+0x1f70| 04 00 00 00 | .... | t_xmin: 4 0x1f78-0x1f7b.7 (4)
+0x1f70| 00 00 00 00| ....| t_xmax: 0 0x1f7c-0x1f7f.7 (4)
+ | | | t_field3{}: 0x1f80-0x1f83.7 (4)
+0x1f80|00 00 00 00 |.... | t_cid: 0 0x1f80-0x1f83.7 (4)
+0x1f80|00 00 00 00 |.... | t_xvac: 0 0x1f80-0x1f83.7 (4)
+ | | | t_datum{}: 0x1f78-0x1f83.7 (12)
+0x1f70| 04 00 00 00 | .... | datum_len_: 4 0x1f78-0x1f7b.7 (4)
+0x1f70| 00 00 00 00| ....| datum_typmod: 0 0x1f7c-0x1f7f.7 (4)
+0x1f80|00 00 00 00 |.... | datum_typeid: 0 0x1f80-0x1f83.7 (4)
+ | | | t_ctid{}: 0x1f84-0x1f89.7 (6)
+0x1f80| 00 00 00 00 | .... | ip_blkid: 0 0x1f84-0x1f87.7 (4)
+0x1f80| 02 00 | .. | ip_posid: 2 0x1f88-0x1f89.7 (2)
+0x1f80| 03 00 | .. | t_infomask2: 3 0x1f8a-0x1f8b.7 (2)
+ | | | infomask2{}: 0x1f8c-NA (0)
+ | | | heap_keys_updated: false 0x1f8c-NA (0)
+ | | | heap_hot_updated: false 0x1f8c-NA (0)
+ | | | heap_only_tuple: false 0x1f8c-NA (0)
+0x1f80| 02 09 | .. | t_infomask: 2306 0x1f8c-0x1f8d.7 (2)
+ | | | infomask{}: 0x1f8e-NA (0)
+ | | | heap_hasnull: false 0x1f8e-NA (0)
+ | | | heap_hasvarwidth: true 0x1f8e-NA (0)
+ | | | heap_hasexternal: false 0x1f8e-NA (0)
+ | | | heap_hasoid_old: false 0x1f8e-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1f8e-NA (0)
+ | | | heap_combocid: false 0x1f8e-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1f8e-NA (0)
+ | | | heap_xmax_lock_only: false 0x1f8e-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1f8e-NA (0)
+ | | | heap_lock_mask: false 0x1f8e-NA (0)
+ | | | heap_xmin_committed: true 0x1f8e-NA (0)
+ | | | heap_xmin_invalid: false 0x1f8e-NA (0)
+ | | | heap_xmin_frozen: true 0x1f8e-NA (0)
+ | | | heap_xmax_committed: false 0x1f8e-NA (0)
+ | | | heap_xmax_invalid: true 0x1f8e-NA (0)
+ | | | heap_xmax_is_multi: false 0x1f8e-NA (0)
+ | | | heap_updated: false 0x1f8e-NA (0)
+ | | | heap_moved_off: false 0x1f8e-NA (0)
+ | | | heap_moved_in: false 0x1f8e-NA (0)
+ | | | heap_moved: false 0x1f8e-NA (0)
+0x1f80| 18 | . | t_hoff: 24 0x1f8e-0x1f8e.7 (1)
+0x1f80| 00| .| padding0: 0 0x1f8f-0x1f8f.7 (1)
+0x1f90|02 00 00 00 23 31 31 31 31 31 31 31 31 31 31 31|....#11111111111| data: "02000000233131313131313131313131313131313100000..." (raw bits) 0x1f90-0x1faf.7 (32)
+0x1fa0|31 31 31 31 31 00 00 00 ce fa be ba ff ff ff ff|11111...........|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[2]{}: tuple 0x1f40-0x1f77.7 (56)
+ | | | header{}: 0x1f40-0x1f57.7 (24)
+ | | | t_choice{}: 0x1f40-0x1f4b.7 (12)
+ | | | t_heap{}: 0x1f40-0x1f4b.7 (12)
+0x1f40|04 00 00 00 |.... | t_xmin: 4 0x1f40-0x1f43.7 (4)
+0x1f40| 00 00 00 00 | .... | t_xmax: 0 0x1f44-0x1f47.7 (4)
+ | | | t_field3{}: 0x1f48-0x1f4b.7 (4)
+0x1f40| 00 00 00 00 | .... | t_cid: 0 0x1f48-0x1f4b.7 (4)
+0x1f40| 00 00 00 00 | .... | t_xvac: 0 0x1f48-0x1f4b.7 (4)
+ | | | t_datum{}: 0x1f40-0x1f4b.7 (12)
+0x1f40|04 00 00 00 |.... | datum_len_: 4 0x1f40-0x1f43.7 (4)
+0x1f40| 00 00 00 00 | .... | datum_typmod: 0 0x1f44-0x1f47.7 (4)
+0x1f40| 00 00 00 00 | .... | datum_typeid: 0 0x1f48-0x1f4b.7 (4)
+ | | | t_ctid{}: 0x1f4c-0x1f51.7 (6)
+0x1f40| 00 00 00 00| ....| ip_blkid: 0 0x1f4c-0x1f4f.7 (4)
+0x1f50|03 00 |.. | ip_posid: 3 0x1f50-0x1f51.7 (2)
+0x1f50| 03 00 | .. | t_infomask2: 3 0x1f52-0x1f53.7 (2)
+ | | | infomask2{}: 0x1f54-NA (0)
+ | | | heap_keys_updated: false 0x1f54-NA (0)
+ | | | heap_hot_updated: false 0x1f54-NA (0)
+ | | | heap_only_tuple: false 0x1f54-NA (0)
+0x1f50| 02 09 | .. | t_infomask: 2306 0x1f54-0x1f55.7 (2)
+ | | | infomask{}: 0x1f56-NA (0)
+ | | | heap_hasnull: false 0x1f56-NA (0)
+ | | | heap_hasvarwidth: true 0x1f56-NA (0)
+ | | | heap_hasexternal: false 0x1f56-NA (0)
+ | | | heap_hasoid_old: false 0x1f56-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1f56-NA (0)
+ | | | heap_combocid: false 0x1f56-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1f56-NA (0)
+ | | | heap_xmax_lock_only: false 0x1f56-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1f56-NA (0)
+ | | | heap_lock_mask: false 0x1f56-NA (0)
+ | | | heap_xmin_committed: true 0x1f56-NA (0)
+ | | | heap_xmin_invalid: false 0x1f56-NA (0)
+ | | | heap_xmin_frozen: true 0x1f56-NA (0)
+ | | | heap_xmax_committed: false 0x1f56-NA (0)
+ | | | heap_xmax_invalid: true 0x1f56-NA (0)
+ | | | heap_xmax_is_multi: false 0x1f56-NA (0)
+ | | | heap_updated: false 0x1f56-NA (0)
+ | | | heap_moved_off: false 0x1f56-NA (0)
+ | | | heap_moved_in: false 0x1f56-NA (0)
+ | | | heap_moved: false 0x1f56-NA (0)
+0x1f50| 18 | . | t_hoff: 24 0x1f56-0x1f56.7 (1)
+0x1f50| 00 | . | padding0: 0 0x1f57-0x1f57.7 (1)
+0x1f50| 03 00 00 00 23 32 32 32| ....#222| data: "03000000233232323232323232323232323232323200000..." (raw bits) 0x1f58-0x1f77.7 (32)
+0x1f60|32 32 32 32 32 32 32 32 32 32 32 32 32 00 00 00|2222222222222...|
+0x1f70|ef cd ab 89 ff ff ff ff |........ |
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[3]{}: tuple 0x1f08-0x1f3f.7 (56)
+ | | | header{}: 0x1f08-0x1f1f.7 (24)
+ | | | t_choice{}: 0x1f08-0x1f13.7 (12)
+ | | | t_heap{}: 0x1f08-0x1f13.7 (12)
+0x1f00| 04 00 00 00 | .... | t_xmin: 4 0x1f08-0x1f0b.7 (4)
+0x1f00| 00 00 00 00| ....| t_xmax: 0 0x1f0c-0x1f0f.7 (4)
+ | | | t_field3{}: 0x1f10-0x1f13.7 (4)
+0x1f10|00 00 00 00 |.... | t_cid: 0 0x1f10-0x1f13.7 (4)
+0x1f10|00 00 00 00 |.... | t_xvac: 0 0x1f10-0x1f13.7 (4)
+ | | | t_datum{}: 0x1f08-0x1f13.7 (12)
+0x1f00| 04 00 00 00 | .... | datum_len_: 4 0x1f08-0x1f0b.7 (4)
+0x1f00| 00 00 00 00| ....| datum_typmod: 0 0x1f0c-0x1f0f.7 (4)
+0x1f10|00 00 00 00 |.... | datum_typeid: 0 0x1f10-0x1f13.7 (4)
+ | | | t_ctid{}: 0x1f14-0x1f19.7 (6)
+0x1f10| 00 00 00 00 | .... | ip_blkid: 0 0x1f14-0x1f17.7 (4)
+0x1f10| 04 00 | .. | ip_posid: 4 0x1f18-0x1f19.7 (2)
+0x1f10| 03 00 | .. | t_infomask2: 3 0x1f1a-0x1f1b.7 (2)
+ | | | infomask2{}: 0x1f1c-NA (0)
+ | | | heap_keys_updated: false 0x1f1c-NA (0)
+ | | | heap_hot_updated: false 0x1f1c-NA (0)
+ | | | heap_only_tuple: false 0x1f1c-NA (0)
+0x1f10| 02 09 | .. | t_infomask: 2306 0x1f1c-0x1f1d.7 (2)
+ | | | infomask{}: 0x1f1e-NA (0)
+ | | | heap_hasnull: false 0x1f1e-NA (0)
+ | | | heap_hasvarwidth: true 0x1f1e-NA (0)
+ | | | heap_hasexternal: false 0x1f1e-NA (0)
+ | | | heap_hasoid_old: false 0x1f1e-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1f1e-NA (0)
+ | | | heap_combocid: false 0x1f1e-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1f1e-NA (0)
+ | | | heap_xmax_lock_only: false 0x1f1e-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1f1e-NA (0)
+ | | | heap_lock_mask: false 0x1f1e-NA (0)
+ | | | heap_xmin_committed: true 0x1f1e-NA (0)
+ | | | heap_xmin_invalid: false 0x1f1e-NA (0)
+ | | | heap_xmin_frozen: true 0x1f1e-NA (0)
+ | | | heap_xmax_committed: false 0x1f1e-NA (0)
+ | | | heap_xmax_invalid: true 0x1f1e-NA (0)
+ | | | heap_xmax_is_multi: false 0x1f1e-NA (0)
+ | | | heap_updated: false 0x1f1e-NA (0)
+ | | | heap_moved_off: false 0x1f1e-NA (0)
+ | | | heap_moved_in: false 0x1f1e-NA (0)
+ | | | heap_moved: false 0x1f1e-NA (0)
+0x1f10| 18 | . | t_hoff: 24 0x1f1e-0x1f1e.7 (1)
+0x1f10| 00| .| padding0: 0 0x1f1f-0x1f1f.7 (1)
+0x1f20|04 00 00 00 23 33 33 33 33 33 33 33 33 33 33 33|....#33333333333| data: "04000000233333333333333333333333333333333300000..." (raw bits) 0x1f20-0x1f3f.7 (32)
+0x1f30|33 33 33 33 33 00 00 00 af be ad de ff ff ff ff|33333...........|
diff --git a/format/postgres/testdata/flavours/pgproee14/pg_control b/format/postgres/testdata/flavours/pgproee14/pg_control
new file mode 100644
index 000000000..b11d3f35c
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee14/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgproee14/pg_control.fqtest b/format/postgres/testdata/flavours/pgproee14/pg_control.fqtest
new file mode 100644
index 000000000..2ea711c9a
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee14/pg_control.fqtest
@@ -0,0 +1,69 @@
+$ fq -d pg_control -o flavour=pgproee14 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|a8 63 95 9f 7f b7 ba 62 |.c.....b | system_identifier: 7114200320151217064 0x0-0x7.7 (8)
+0x0000| 14 05 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1300" (1346700564) 0x8-0xb.7 (4)
+0x0000| 97 5f 0d 0c| ._..| catalog_version_no: 202203031 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 90 74 c2 62 00 00 00 00| .t.b....| time: "Mon, 04 Jul 2022 05:03:12 UTC" (1656910992) 0x18-0x1f.7 (8)
+0x0020|f8 01 a0 01 00 00 00 00 |........ | check_point: "0/1A001F8" (27263480) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| a8 01 a0 01 00 00 00 00| ........| redo: "0/1A001A8" (27263400) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|f1 e6 0b 54 02 00 00 00 |...T.... | next_xid: 10000000753 0x40-0x47.7 (8)
+0x0040| d3 35 00 00 | .5.. | next_oid: 13779 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|e8 e6 0b 54 02 00 00 00 |...T.... | oldest_xid: 10000000744 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|90 74 c2 62 00 00 00 00 |.t.b.... | time: "Mon, 04 Jul 2022 05:03:12 UTC" (1656910992) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| f1 e6 0b 54 02 00 00 00| ...T....| oldest_active_xid: 10000000753 0x98-0x9f.7 (8)
+0x00a0|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| c6 00 00 00 | .... | max_connections: 198 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 0a 00 00 00| ....| max_wal_senders: 10 0xdc-0xdf.7 (4)
+0x00e0|00 00 00 00 |.... | max_prepared_xacts: 0 0xe0-0xe3.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe4-0xe7.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe8-0xe8.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe9-0xeb.7 (3)
+0x00e0| 08 00 00 00| ....| max_align: 8 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float8_by_val: 1 0x118-0x118.7 (1)
+0x0110| 00 00 00 | ... | hole9: 0 0x119-0x11b.7 (3)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|dd f2 b7 da 2f 4a 5c ac 5d ce e9 34 21 d6 a8 03|..../J\.]..4!...| mock_authentication_nonce: "ddf2b7da2f4a5cac5dcee93421d6a803d6a08dabff41769..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|d6 a0 8d ab ff 41 76 97 f5 d1 72 b0 db 8e 80 cb|.....Av...r.....|
+0x0140|43 01 00 00 |C... | icu_version: "67.1.0.0" (323) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| 73 33 90 20 | s3. | crc: 546321267 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| padding0: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................| unused: raw bits 0x150-0x1fff.7 (7856)
+* |until 0x1fff.7 (end) (7856) | |
diff --git a/format/postgres/testdata/flavours/pgproee14/pg_control_1.fqtest b/format/postgres/testdata/flavours/pgproee14/pg_control_1.fqtest
new file mode 100644
index 000000000..22160cad5
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee14/pg_control_1.fqtest
@@ -0,0 +1,69 @@
+$ fq -d pg_control dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|a8 63 95 9f 7f b7 ba 62 |.c.....b | system_identifier: 7114200320151217064 0x0-0x7.7 (8)
+0x0000| 14 05 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1300" (1346700564) 0x8-0xb.7 (4)
+0x0000| 97 5f 0d 0c| ._..| catalog_version_no: 202203031 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 90 74 c2 62 00 00 00 00| .t.b....| time: "Mon, 04 Jul 2022 05:03:12 UTC" (1656910992) 0x18-0x1f.7 (8)
+0x0020|f8 01 a0 01 00 00 00 00 |........ | check_point: "0/1A001F8" (27263480) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| a8 01 a0 01 00 00 00 00| ........| redo: "0/1A001A8" (27263400) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|f1 e6 0b 54 02 00 00 00 |...T.... | next_xid: 10000000753 0x40-0x47.7 (8)
+0x0040| d3 35 00 00 | .5.. | next_oid: 13779 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|e8 e6 0b 54 02 00 00 00 |...T.... | oldest_xid: 10000000744 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|90 74 c2 62 00 00 00 00 |.t.b.... | time: "Mon, 04 Jul 2022 05:03:12 UTC" (1656910992) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| f1 e6 0b 54 02 00 00 00| ...T....| oldest_active_xid: 10000000753 0x98-0x9f.7 (8)
+0x00a0|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| c6 00 00 00 | .... | max_connections: 198 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 0a 00 00 00| ....| max_wal_senders: 10 0xdc-0xdf.7 (4)
+0x00e0|00 00 00 00 |.... | max_prepared_xacts: 0 0xe0-0xe3.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe4-0xe7.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe8-0xe8.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe9-0xeb.7 (3)
+0x00e0| 08 00 00 00| ....| max_align: 8 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float8_by_val: 1 0x118-0x118.7 (1)
+0x0110| 00 00 00 | ... | hole9: 0 0x119-0x11b.7 (3)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|dd f2 b7 da 2f 4a 5c ac 5d ce e9 34 21 d6 a8 03|..../J\.]..4!...| mock_authentication_nonce: "ddf2b7da2f4a5cac5dcee93421d6a803d6a08dabff41769..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|d6 a0 8d ab ff 41 76 97 f5 d1 72 b0 db 8e 80 cb|.....Av...r.....|
+0x0140|43 01 00 00 |C... | icu_version: "67.1.0.0" (323) 0x140-0x143.7 (4)
+0x0140| 00 00 ff ff | .... | pg_old_version: 4294901760 0x144-0x147.7 (4)
+0x0140| 73 33 90 20 | s3. | crc: 546321267 0x148-0x14b.7 (4)
+0x0140| 00 00 00 00| ....| padding0: 0 0x14c-0x14f.7 (4)
+0x0150|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................| unused: raw bits 0x150-0x1fff.7 (7856)
+* |until 0x1fff.7 (end) (7856) | |
diff --git a/format/postgres/testdata/flavours/pgproee15/16400 b/format/postgres/testdata/flavours/pgproee15/16400
new file mode 100644
index 000000000..46a749434
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee15/16400 differ
diff --git a/format/postgres/testdata/flavours/pgproee15/16400.fqtest b/format/postgres/testdata/flavours/pgproee15/16400.fqtest
new file mode 100644
index 000000000..5bfcd2618
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee15/16400.fqtest
@@ -0,0 +1,21 @@
+$ fq -d pg_heap -o flavour=pgproee15 ".[0].pd_linp[0, 1, 2, -1] | dv" 16400
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x14-0x17.7 (4)
+0x10| 68 9f f2 00 | h... | item_id_data: 15900520 0x14-0x17.7 (4)
+ | | | lp_off: 8040 0x18-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x18-NA (0)
+ | | | lp_len: 121 0x18-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[1]{}: item_id 0x18-0x1b.7 (4)
+0x10| e8 9e f2 00 | .... | item_id_data: 15900392 0x18-0x1b.7 (4)
+ | | | lp_off: 7912 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[2]{}: item_id 0x1c-0x1f.7 (4)
+0x10| 68 9e f2 00| h...| item_id_data: 15900264 0x1c-0x1f.7 (4)
+ | | | lp_off: 7784 0x20-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x20-NA (0)
+ | | | lp_len: 121 0x20-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x104-0x107.7 (4)
+0x100| 68 81 f2 00 | h... | item_id_data: 15892840 0x104-0x107.7 (4)
+ | | | lp_off: 360 0x108-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x108-NA (0)
+ | | | lp_len: 121 0x108-NA (0)
diff --git a/format/postgres/testdata/flavours/pgproee15/16401 b/format/postgres/testdata/flavours/pgproee15/16401
new file mode 100644
index 000000000..bdd30fedb
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee15/16401 differ
diff --git a/format/postgres/testdata/flavours/pgproee15/16401.fqtest b/format/postgres/testdata/flavours/pgproee15/16401.fqtest
new file mode 100644
index 000000000..af042c711
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee15/16401.fqtest
@@ -0,0 +1,93 @@
+$ fq -d pg_heap -o flavour=pgproee15 ".[0].tuples[0,-1] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fc8-0x1fe7.7 (32)
+ | | | header{}: 0x1fc8-0x1fdf.7 (24)
+ | | | t_choice{}: 0x1fc8-0x1fd3.7 (12)
+ | | | t_heap{}: 0x1fc8-0x1fd3.7 (12)
+0x1fc0| 03 00 00 00 | .... | t_xmin: 3 0x1fc8-0x1fcb.7 (4)
+0x1fc0| 00 00 00 00| ....| t_xmax: 0 0x1fcc-0x1fcf.7 (4)
+ | | | t_field3{}: 0x1fd0-0x1fd3.7 (4)
+0x1fd0|04 00 00 00 |.... | t_cid: 4 0x1fd0-0x1fd3.7 (4)
+0x1fd0|04 00 00 00 |.... | t_xvac: 4 0x1fd0-0x1fd3.7 (4)
+ | | | t_datum{}: 0x1fc8-0x1fd3.7 (12)
+0x1fc0| 03 00 00 00 | .... | datum_len_: 3 0x1fc8-0x1fcb.7 (4)
+0x1fc0| 00 00 00 00| ....| datum_typmod: 0 0x1fcc-0x1fcf.7 (4)
+0x1fd0|04 00 00 00 |.... | datum_typeid: 4 0x1fd0-0x1fd3.7 (4)
+ | | | t_ctid{}: 0x1fd4-0x1fd9.7 (6)
+0x1fd0| 00 00 00 00 | .... | ip_blkid: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 01 00 | .. | ip_posid: 1 0x1fd8-0x1fd9.7 (2)
+0x1fd0| 03 00 | .. | t_infomask2: 3 0x1fda-0x1fdb.7 (2)
+ | | | infomask2{}: 0x1fdc-NA (0)
+ | | | heap_keys_updated: false 0x1fdc-NA (0)
+ | | | heap_hot_updated: false 0x1fdc-NA (0)
+ | | | heap_only_tuple: false 0x1fdc-NA (0)
+0x1fd0| 01 09 | .. | t_infomask: 2305 0x1fdc-0x1fdd.7 (2)
+ | | | infomask{}: 0x1fde-NA (0)
+ | | | heap_hasnull: true 0x1fde-NA (0)
+ | | | heap_hasvarwidth: false 0x1fde-NA (0)
+ | | | heap_hasexternal: false 0x1fde-NA (0)
+ | | | heap_hasoid_old: false 0x1fde-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fde-NA (0)
+ | | | heap_combocid: false 0x1fde-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fde-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fde-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fde-NA (0)
+ | | | heap_lock_mask: false 0x1fde-NA (0)
+ | | | heap_xmin_committed: true 0x1fde-NA (0)
+ | | | heap_xmin_invalid: false 0x1fde-NA (0)
+ | | | heap_xmin_frozen: true 0x1fde-NA (0)
+ | | | heap_xmax_committed: false 0x1fde-NA (0)
+ | | | heap_xmax_invalid: true 0x1fde-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fde-NA (0)
+ | | | heap_updated: false 0x1fde-NA (0)
+ | | | heap_moved_off: false 0x1fde-NA (0)
+ | | | heap_moved_in: false 0x1fde-NA (0)
+ | | | heap_moved: false 0x1fde-NA (0)
+0x1fd0| 18 | . | t_hoff: 24 0x1fde-0x1fde.7 (1)
+0x1fd0| 03| .| padding0: 3 0x1fdf-0x1fdf.7 (1)
+0x1fe0|01 00 00 00 00 00 00 00 |........ | data: "0100000000000000" (raw bits) 0x1fe0-0x1fe7.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fc8-0x1fe7.7 (32)
+ | | | header{}: 0x1fc8-0x1fdf.7 (24)
+ | | | t_choice{}: 0x1fc8-0x1fd3.7 (12)
+ | | | t_heap{}: 0x1fc8-0x1fd3.7 (12)
+0x1fc0| 03 00 00 00 | .... | t_xmin: 3 0x1fc8-0x1fcb.7 (4)
+0x1fc0| 00 00 00 00| ....| t_xmax: 0 0x1fcc-0x1fcf.7 (4)
+ | | | t_field3{}: 0x1fd0-0x1fd3.7 (4)
+0x1fd0|04 00 00 00 |.... | t_cid: 4 0x1fd0-0x1fd3.7 (4)
+0x1fd0|04 00 00 00 |.... | t_xvac: 4 0x1fd0-0x1fd3.7 (4)
+ | | | t_datum{}: 0x1fc8-0x1fd3.7 (12)
+0x1fc0| 03 00 00 00 | .... | datum_len_: 3 0x1fc8-0x1fcb.7 (4)
+0x1fc0| 00 00 00 00| ....| datum_typmod: 0 0x1fcc-0x1fcf.7 (4)
+0x1fd0|04 00 00 00 |.... | datum_typeid: 4 0x1fd0-0x1fd3.7 (4)
+ | | | t_ctid{}: 0x1fd4-0x1fd9.7 (6)
+0x1fd0| 00 00 00 00 | .... | ip_blkid: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 01 00 | .. | ip_posid: 1 0x1fd8-0x1fd9.7 (2)
+0x1fd0| 03 00 | .. | t_infomask2: 3 0x1fda-0x1fdb.7 (2)
+ | | | infomask2{}: 0x1fdc-NA (0)
+ | | | heap_keys_updated: false 0x1fdc-NA (0)
+ | | | heap_hot_updated: false 0x1fdc-NA (0)
+ | | | heap_only_tuple: false 0x1fdc-NA (0)
+0x1fd0| 01 09 | .. | t_infomask: 2305 0x1fdc-0x1fdd.7 (2)
+ | | | infomask{}: 0x1fde-NA (0)
+ | | | heap_hasnull: true 0x1fde-NA (0)
+ | | | heap_hasvarwidth: false 0x1fde-NA (0)
+ | | | heap_hasexternal: false 0x1fde-NA (0)
+ | | | heap_hasoid_old: false 0x1fde-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fde-NA (0)
+ | | | heap_combocid: false 0x1fde-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fde-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fde-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fde-NA (0)
+ | | | heap_lock_mask: false 0x1fde-NA (0)
+ | | | heap_xmin_committed: true 0x1fde-NA (0)
+ | | | heap_xmin_invalid: false 0x1fde-NA (0)
+ | | | heap_xmin_frozen: true 0x1fde-NA (0)
+ | | | heap_xmax_committed: false 0x1fde-NA (0)
+ | | | heap_xmax_invalid: true 0x1fde-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fde-NA (0)
+ | | | heap_updated: false 0x1fde-NA (0)
+ | | | heap_moved_off: false 0x1fde-NA (0)
+ | | | heap_moved_in: false 0x1fde-NA (0)
+ | | | heap_moved: false 0x1fde-NA (0)
+0x1fd0| 18 | . | t_hoff: 24 0x1fde-0x1fde.7 (1)
+0x1fd0| 03| .| padding0: 3 0x1fdf-0x1fdf.7 (1)
+0x1fe0|01 00 00 00 00 00 00 00 |........ | data: "0100000000000000" (raw bits) 0x1fe0-0x1fe7.7 (8)
diff --git a/format/postgres/testdata/flavours/pgproee15/pg_control b/format/postgres/testdata/flavours/pgproee15/pg_control
new file mode 100644
index 000000000..7181ef53e
Binary files /dev/null and b/format/postgres/testdata/flavours/pgproee15/pg_control differ
diff --git a/format/postgres/testdata/flavours/pgproee15/pg_control.fqtest b/format/postgres/testdata/flavours/pgproee15/pg_control.fqtest
new file mode 100644
index 000000000..41cd787a2
--- /dev/null
+++ b/format/postgres/testdata/flavours/pgproee15/pg_control.fqtest
@@ -0,0 +1,68 @@
+$ fq -d pg_control -o flavour=pgproee15 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|ec e2 14 a9 01 43 36 64 |.....C6d | system_identifier: 7221032726945915628 0x0-0x7.7 (8)
+0x0000| 14 05 45 50 | ..EP | pg_control_version: "Postgres Pro Enterprise 1300" (1346700564) 0x8-0xb.7 (4)
+0x0000| 39 77 0d 0c| 9w..| catalog_version_no: 202209081 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 6b 44 36 64 00 00 00 00| kD6d....| time: "Wed, 12 Apr 2023 05:40:59 UTC" (1681278059) 0x18-0x1f.7 (8)
+0x0020|e0 5f 4b 02 00 00 00 00 |._K..... | check_point: "0/24B5FE0" (38494176) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x9f.7 (120)
+0x0020| 98 5f 4b 02 00 00 00 00| ._K.....| redo: "0/24B5F98" (38494104) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|fd e6 0b 54 02 00 00 00 |...T.... | next_xid: 10000000765 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 00 00 00 00| ....| hole2: 0 0x4c-0x4f.7 (4)
+0x0050|00 f2 05 2a 01 00 00 00 |...*.... | next_multi: 5000000000 0x50-0x57.7 (8)
+0x0050| 00 00 00 00 00 00 00 00| ........| next_multi_offset: 0 0x58-0x5f.7 (8)
+0x0060|dd e6 0b 54 02 00 00 00 |...T.... | oldest_xid: 10000000733 0x60-0x67.7 (8)
+0x0060| 01 00 00 00 | .... | oldest_xid_db: 1 0x68-0x6b.7 (4)
+0x0060| 00 00 00 00| ....| hole3: 0 0x6c-0x6f.7 (4)
+0x0070|00 f2 05 2a 01 00 00 00 |...*.... | oldest_multi: 5000000000 0x70-0x77.7 (8)
+0x0070| 01 00 00 00 | .... | oldest_multi_db: 1 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| hole4: 0 0x7c-0x7f.7 (4)
+0x0080|6a 44 36 64 00 00 00 00 |jD6d.... | time: "Wed, 12 Apr 2023 05:40:58 UTC" (1681278058) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| oldest_commit_ts_xid: 0 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 00 00 00 00 |........ | newest_commit_ts_xid: 0 0x90-0x97.7 (8)
+0x0090| fd e6 0b 54 02 00 00 00| ...T....| oldest_active_xid: 10000000765 0x98-0x9f.7 (8)
+0x00a0|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0xa0-0xa7.7 (8)
+0x00a0| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0xa8-0xaf.7 (8)
+0x00b0|00 00 00 00 |.... | min_recovery_point_tli: 0 0xb0-0xb3.7 (4)
+0x00b0| 00 00 00 00 | .... | hole5: 0 0xb4-0xb7.7 (4)
+0x00b0| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0xb8-0xbf.7 (8)
+0x00c0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xc0-0xc7.7 (8)
+0x00c0| 00 | . | backup_end_required: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xcc-0xcf.7 (4)
+0x00d0|00 |. | wal_log_hints: 0 0xd0-0xd0.7 (1)
+0x00d0| 00 00 00 | ... | hole7: 0 0xd1-0xd3.7 (3)
+0x00d0| e8 03 00 00 | .... | max_connections: 1000 0xd4-0xd7.7 (4)
+0x00d0| 08 00 00 00 | .... | max_worker_processes: 8 0xd8-0xdb.7 (4)
+0x00d0| 0a 00 00 00| ....| max_wal_senders: 10 0xdc-0xdf.7 (4)
+0x00e0|00 00 00 00 |.... | max_prepared_xacts: 0 0xe0-0xe3.7 (4)
+0x00e0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xe4-0xe7.7 (4)
+0x00e0| 00 | . | track_commit_timestamp: 0 0xe8-0xe8.7 (1)
+0x00e0| 00 00 00 | ... | hole8: 0 0xe9-0xeb.7 (3)
+0x00e0| 08 00 00 00| ....| max_align: 8 0xec-0xef.7 (4)
+0x00f0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xf0-0xf7.7 (8)
+0x00f0| 00 20 00 00 | . .. | blcksz: 8192 0xf8-0xfb.7 (4)
+0x00f0| 00 00 02 00| ....| relseg_size: 131072 0xfc-0xff.7 (4)
+0x0100|00 20 00 00 |. .. | xlog_blcksz: 8192 0x100-0x103.7 (4)
+0x0100| 00 00 00 01 | .... | xlog_seg_size: 16777216 0x104-0x107.7 (4)
+0x0100| 40 00 00 00 | @... | name_data_len: 64 0x108-0x10b.7 (4)
+0x0100| 20 00 00 00| ...| index_max_keys: 32 0x10c-0x10f.7 (4)
+0x0110|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0x110-0x113.7 (4)
+0x0110| 00 08 00 00 | .... | loblksize: 2048 0x114-0x117.7 (4)
+0x0110| 01 | . | float8_by_val: 1 0x118-0x118.7 (1)
+0x0110| 00 00 00 | ... | hole9: 0 0x119-0x11b.7 (3)
+0x0110| 01 00 00 00| ....| data_checksum_version: 1 0x11c-0x11f.7 (4)
+0x0120|5d 3a ed 2c 34 c4 d9 66 0d 9d bf 3d e6 05 ab 45|]:.,4..f...=...E| mock_authentication_nonce: "5d3aed2c34c4d9660d9dbf3de605ab455baa4974c5effab..." (raw bits) 0x120-0x13f.7 (32)
+0x0130|5b aa 49 74 c5 ef fa b6 23 82 65 97 28 22 49 36|[.It....#.e.("I6|
+0x0140|00 00 ff ff |.... | pg_old_version: 4294901760 0x140-0x143.7 (4)
+0x0140| 8a 18 1f b9 | .... | crc: 3105822858 0x144-0x147.7 (4)
+0x0140| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x148-0x1fff.7 (7864)
+0x0150|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7864) | |
diff --git a/format/postgres/testdata/flavours/postgres10/16396 b/format/postgres/testdata/flavours/postgres10/16396
new file mode 100644
index 000000000..5efa6d272
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres10/16396 differ
diff --git a/format/postgres/testdata/flavours/postgres10/16396_1.fqtest b/format/postgres/testdata/flavours/postgres10/16396_1.fqtest
new file mode 100644
index 000000000..3f00055ea
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres10/16396_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=postgres10 ".[0].pd_linp[0,-1] | dv" 16396
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[75]{}: item_id 0x144-0x147.7 (4)
+0x140| 80 82 f2 00 | .... | item_id_data: 15893120 0x144-0x147.7 (4)
+ | | | lp_off: 640 0x148-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x148-NA (0)
+ | | | lp_len: 121 0x148-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres10/16401 b/format/postgres/testdata/flavours/postgres10/16401
new file mode 100644
index 000000000..c7e3c112f
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres10/16401 differ
diff --git a/format/postgres/testdata/flavours/postgres10/16401_1.fqtest b/format/postgres/testdata/flavours/postgres10/16401_1.fqtest
new file mode 100644
index 000000000..8c31d3965
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres10/16401_1.fqtest
@@ -0,0 +1,51 @@
+$ fq -d pg_btree ".[1].pd_linp[0,1,2,3,4,5,6,7,8,9] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[0]{}: item_id 0x2018-0x201b.7 (4)
+0x2010| 00 89 20 00 | .. . | item_id_data: 2132224 0x2018-0x201b.7 (4)
+ | | | lp_off: 2304 0x201c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x201c-NA (0)
+ | | | lp_len: 16 0x201c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[1]{}: item_id 0x201c-0x201f.7 (4)
+0x2010| e0 9f 20 00| .. .| item_id_data: 2138080 0x201c-0x201f.7 (4)
+ | | | lp_off: 8160 0x2020-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2020-NA (0)
+ | | | lp_len: 16 0x2020-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[2]{}: item_id 0x2020-0x2023.7 (4)
+0x2020|d0 9f 20 00 |.. . | item_id_data: 2138064 0x2020-0x2023.7 (4)
+ | | | lp_off: 8144 0x2024-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2024-NA (0)
+ | | | lp_len: 16 0x2024-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[3]{}: item_id 0x2024-0x2027.7 (4)
+0x2020| c0 9f 20 00 | .. . | item_id_data: 2138048 0x2024-0x2027.7 (4)
+ | | | lp_off: 8128 0x2028-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2028-NA (0)
+ | | | lp_len: 16 0x2028-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[4]{}: item_id 0x2028-0x202b.7 (4)
+0x2020| b0 9f 20 00 | .. . | item_id_data: 2138032 0x2028-0x202b.7 (4)
+ | | | lp_off: 8112 0x202c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x202c-NA (0)
+ | | | lp_len: 16 0x202c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[5]{}: item_id 0x202c-0x202f.7 (4)
+0x2020| a0 9f 20 00| .. .| item_id_data: 2138016 0x202c-0x202f.7 (4)
+ | | | lp_off: 8096 0x2030-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2030-NA (0)
+ | | | lp_len: 16 0x2030-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[6]{}: item_id 0x2030-0x2033.7 (4)
+0x2030|90 9f 20 00 |.. . | item_id_data: 2138000 0x2030-0x2033.7 (4)
+ | | | lp_off: 8080 0x2034-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2034-NA (0)
+ | | | lp_len: 16 0x2034-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[7]{}: item_id 0x2034-0x2037.7 (4)
+0x2030| 80 9f 20 00 | .. . | item_id_data: 2137984 0x2034-0x2037.7 (4)
+ | | | lp_off: 8064 0x2038-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2038-NA (0)
+ | | | lp_len: 16 0x2038-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[8]{}: item_id 0x2038-0x203b.7 (4)
+0x2030| 70 9f 20 00 | p. . | item_id_data: 2137968 0x2038-0x203b.7 (4)
+ | | | lp_off: 8048 0x203c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x203c-NA (0)
+ | | | lp_len: 16 0x203c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].pd_linp[9]{}: item_id 0x203c-0x203f.7 (4)
+0x2030| 60 9f 20 00| `. .| item_id_data: 2137952 0x203c-0x203f.7 (4)
+ | | | lp_off: 8032 0x2040-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x2040-NA (0)
+ | | | lp_len: 16 0x2040-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres10/16401_2.fqtest b/format/postgres/testdata/flavours/postgres10/16401_2.fqtest
new file mode 100644
index 000000000..5bf56024c
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres10/16401_2.fqtest
@@ -0,0 +1,111 @@
+$ fq -d pg_btree ".[1].tuples[0,1,2,3,4,5,6,7,8,9] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[0]{}: tuple 0x2900-0x290f.7 (16)
+ | | | index_tuple_data{}: 0x2900-0x290f.7 (16)
+ | | | t_tid{}: 0x2900-0x2905.7 (6)
+0x2900|00 00 06 00 |.... | ip_blkid: 393216 0x2900-0x2903.7 (4)
+0x2900| 01 00 | .. | ip_posid: 1 0x2904-0x2905.7 (2)
+0x2900| 10 00 | .. | t_info: 16 0x2906-0x2907.7 (2)
+ | | | flags{}: 0x2908-NA (0)
+ | | | has_nulls: false 0x2908-NA (0)
+ | | | has_var_widths: false 0x2908-NA (0)
+ | | | size: 16 0x2908-NA (0)
+0x2900| 6f 01 00 00 00 00 00 00| o.......| data: raw bits 0x2908-0x290f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[1]{}: tuple 0x3fe0-0x3fef.7 (16)
+ | | | index_tuple_data{}: 0x3fe0-0x3fef.7 (16)
+ | | | t_tid{}: 0x3fe0-0x3fe5.7 (6)
+0x3fe0|00 00 00 00 |.... | ip_blkid: 0 0x3fe0-0x3fe3.7 (4)
+0x3fe0| 01 00 | .. | ip_posid: 1 0x3fe4-0x3fe5.7 (2)
+0x3fe0| 10 00 | .. | t_info: 16 0x3fe6-0x3fe7.7 (2)
+ | | | flags{}: 0x3fe8-NA (0)
+ | | | has_nulls: false 0x3fe8-NA (0)
+ | | | has_var_widths: false 0x3fe8-NA (0)
+ | | | size: 16 0x3fe8-NA (0)
+0x3fe0| 01 00 00 00 00 00 00 00| ........| data: raw bits 0x3fe8-0x3fef.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[2]{}: tuple 0x3fd0-0x3fdf.7 (16)
+ | | | index_tuple_data{}: 0x3fd0-0x3fdf.7 (16)
+ | | | t_tid{}: 0x3fd0-0x3fd5.7 (6)
+0x3fd0|00 00 00 00 |.... | ip_blkid: 0 0x3fd0-0x3fd3.7 (4)
+0x3fd0| 02 00 | .. | ip_posid: 2 0x3fd4-0x3fd5.7 (2)
+0x3fd0| 10 00 | .. | t_info: 16 0x3fd6-0x3fd7.7 (2)
+ | | | flags{}: 0x3fd8-NA (0)
+ | | | has_nulls: false 0x3fd8-NA (0)
+ | | | has_var_widths: false 0x3fd8-NA (0)
+ | | | size: 16 0x3fd8-NA (0)
+0x3fd0| 02 00 00 00 00 00 00 00| ........| data: raw bits 0x3fd8-0x3fdf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[3]{}: tuple 0x3fc0-0x3fcf.7 (16)
+ | | | index_tuple_data{}: 0x3fc0-0x3fcf.7 (16)
+ | | | t_tid{}: 0x3fc0-0x3fc5.7 (6)
+0x3fc0|00 00 00 00 |.... | ip_blkid: 0 0x3fc0-0x3fc3.7 (4)
+0x3fc0| 03 00 | .. | ip_posid: 3 0x3fc4-0x3fc5.7 (2)
+0x3fc0| 10 00 | .. | t_info: 16 0x3fc6-0x3fc7.7 (2)
+ | | | flags{}: 0x3fc8-NA (0)
+ | | | has_nulls: false 0x3fc8-NA (0)
+ | | | has_var_widths: false 0x3fc8-NA (0)
+ | | | size: 16 0x3fc8-NA (0)
+0x3fc0| 03 00 00 00 00 00 00 00| ........| data: raw bits 0x3fc8-0x3fcf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[4]{}: tuple 0x3fb0-0x3fbf.7 (16)
+ | | | index_tuple_data{}: 0x3fb0-0x3fbf.7 (16)
+ | | | t_tid{}: 0x3fb0-0x3fb5.7 (6)
+0x3fb0|00 00 00 00 |.... | ip_blkid: 0 0x3fb0-0x3fb3.7 (4)
+0x3fb0| 04 00 | .. | ip_posid: 4 0x3fb4-0x3fb5.7 (2)
+0x3fb0| 10 00 | .. | t_info: 16 0x3fb6-0x3fb7.7 (2)
+ | | | flags{}: 0x3fb8-NA (0)
+ | | | has_nulls: false 0x3fb8-NA (0)
+ | | | has_var_widths: false 0x3fb8-NA (0)
+ | | | size: 16 0x3fb8-NA (0)
+0x3fb0| 04 00 00 00 00 00 00 00| ........| data: raw bits 0x3fb8-0x3fbf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[5]{}: tuple 0x3fa0-0x3faf.7 (16)
+ | | | index_tuple_data{}: 0x3fa0-0x3faf.7 (16)
+ | | | t_tid{}: 0x3fa0-0x3fa5.7 (6)
+0x3fa0|00 00 00 00 |.... | ip_blkid: 0 0x3fa0-0x3fa3.7 (4)
+0x3fa0| 05 00 | .. | ip_posid: 5 0x3fa4-0x3fa5.7 (2)
+0x3fa0| 10 00 | .. | t_info: 16 0x3fa6-0x3fa7.7 (2)
+ | | | flags{}: 0x3fa8-NA (0)
+ | | | has_nulls: false 0x3fa8-NA (0)
+ | | | has_var_widths: false 0x3fa8-NA (0)
+ | | | size: 16 0x3fa8-NA (0)
+0x3fa0| 05 00 00 00 00 00 00 00| ........| data: raw bits 0x3fa8-0x3faf.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[6]{}: tuple 0x3f90-0x3f9f.7 (16)
+ | | | index_tuple_data{}: 0x3f90-0x3f9f.7 (16)
+ | | | t_tid{}: 0x3f90-0x3f95.7 (6)
+0x3f90|00 00 00 00 |.... | ip_blkid: 0 0x3f90-0x3f93.7 (4)
+0x3f90| 06 00 | .. | ip_posid: 6 0x3f94-0x3f95.7 (2)
+0x3f90| 10 00 | .. | t_info: 16 0x3f96-0x3f97.7 (2)
+ | | | flags{}: 0x3f98-NA (0)
+ | | | has_nulls: false 0x3f98-NA (0)
+ | | | has_var_widths: false 0x3f98-NA (0)
+ | | | size: 16 0x3f98-NA (0)
+0x3f90| 06 00 00 00 00 00 00 00| ........| data: raw bits 0x3f98-0x3f9f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[7]{}: tuple 0x3f80-0x3f8f.7 (16)
+ | | | index_tuple_data{}: 0x3f80-0x3f8f.7 (16)
+ | | | t_tid{}: 0x3f80-0x3f85.7 (6)
+0x3f80|00 00 00 00 |.... | ip_blkid: 0 0x3f80-0x3f83.7 (4)
+0x3f80| 07 00 | .. | ip_posid: 7 0x3f84-0x3f85.7 (2)
+0x3f80| 10 00 | .. | t_info: 16 0x3f86-0x3f87.7 (2)
+ | | | flags{}: 0x3f88-NA (0)
+ | | | has_nulls: false 0x3f88-NA (0)
+ | | | has_var_widths: false 0x3f88-NA (0)
+ | | | size: 16 0x3f88-NA (0)
+0x3f80| 07 00 00 00 00 00 00 00| ........| data: raw bits 0x3f88-0x3f8f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[8]{}: tuple 0x3f70-0x3f7f.7 (16)
+ | | | index_tuple_data{}: 0x3f70-0x3f7f.7 (16)
+ | | | t_tid{}: 0x3f70-0x3f75.7 (6)
+0x3f70|00 00 00 00 |.... | ip_blkid: 0 0x3f70-0x3f73.7 (4)
+0x3f70| 08 00 | .. | ip_posid: 8 0x3f74-0x3f75.7 (2)
+0x3f70| 10 00 | .. | t_info: 16 0x3f76-0x3f77.7 (2)
+ | | | flags{}: 0x3f78-NA (0)
+ | | | has_nulls: false 0x3f78-NA (0)
+ | | | has_var_widths: false 0x3f78-NA (0)
+ | | | size: 16 0x3f78-NA (0)
+0x3f70| 08 00 00 00 00 00 00 00| ........| data: raw bits 0x3f78-0x3f7f.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1].tuples[9]{}: tuple 0x3f60-0x3f6f.7 (16)
+ | | | index_tuple_data{}: 0x3f60-0x3f6f.7 (16)
+ | | | t_tid{}: 0x3f60-0x3f65.7 (6)
+0x3f60|00 00 00 00 |.... | ip_blkid: 0 0x3f60-0x3f63.7 (4)
+0x3f60| 09 00 | .. | ip_posid: 9 0x3f64-0x3f65.7 (2)
+0x3f60| 10 00 | .. | t_info: 16 0x3f66-0x3f67.7 (2)
+ | | | flags{}: 0x3f68-NA (0)
+ | | | has_nulls: false 0x3f68-NA (0)
+ | | | has_var_widths: false 0x3f68-NA (0)
+ | | | size: 16 0x3f68-NA (0)
+0x3f60| 09 00 00 00 00 00 00 00| ........| data: raw bits 0x3f68-0x3f6f.7 (8)
diff --git a/format/postgres/testdata/flavours/postgres10/16407 b/format/postgres/testdata/flavours/postgres10/16407
new file mode 100644
index 000000000..631e77ea7
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres10/16407 differ
diff --git a/format/postgres/testdata/flavours/postgres10/16407_1.fqtest b/format/postgres/testdata/flavours/postgres10/16407_1.fqtest
new file mode 100644
index 000000000..2e97e7550
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres10/16407_1.fqtest
@@ -0,0 +1,11 @@
+$ fq -d pg_heap -o flavour=postgres10 ".[0].pd_linp[0,-1] | dv" 16407
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[156]{}: item_id 0x288-0x28b.7 (4)
+0x280| 90 82 60 00 | ..`. | item_id_data: 6324880 0x288-0x28b.7 (4)
+ | | | lp_off: 656 0x28c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x28c-NA (0)
+ | | | lp_len: 48 0x28c-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres10/16407_2.fqtest b/format/postgres/testdata/flavours/postgres10/16407_2.fqtest
new file mode 100644
index 000000000..ef6d2cba9
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres10/16407_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=postgres10 ".[0].tuples[0,-1] | dv" 16407
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|76 74 00 00 |vt.. | t_xmin: 29814 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|76 74 00 00 |vt.. | datum_len_: 29814 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 09 | .. | t_infomask: 2305 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: true 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: true 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 03 00 00 00 01 00 00 00| ........| data: "0300000001000000ba38000005100000b26ab433368d020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|ba 38 00 00 05 10 00 00 b2 6a b4 33 36 8d 02 00|.8.......j.36...|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[156]{}: tuple 0x290-0x2bf.7 (48)
+ | | | header{}: 0x290-0x2a7.7 (24)
+ | | | t_choice{}: 0x290-0x29b.7 (12)
+ | | | t_heap{}: 0x290-0x29b.7 (12)
+0x290|12 75 00 00 |.u.. | t_xmin: 29970 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | t_xmax: 0 0x294-0x297.7 (4)
+ | | | t_field3{}: 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_cid: 3 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_xvac: 3 0x298-0x29b.7 (4)
+ | | | t_datum{}: 0x290-0x29b.7 (12)
+0x290|12 75 00 00 |.u.. | datum_len_: 29970 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | datum_typmod: 0 0x294-0x297.7 (4)
+0x290| 03 00 00 00 | .... | datum_typeid: 3 0x298-0x29b.7 (4)
+ | | | t_ctid{}: 0x29c-0x2a1.7 (6)
+0x290| 00 00 00 00| ....| ip_blkid: 0 0x29c-0x29f.7 (4)
+0x2a0|9d 00 |.. | ip_posid: 157 0x2a0-0x2a1.7 (2)
+0x2a0| 06 00 | .. | t_infomask2: 6 0x2a2-0x2a3.7 (2)
+ | | | infomask2{}: 0x2a4-NA (0)
+ | | | heap_keys_updated: false 0x2a4-NA (0)
+ | | | heap_hot_updated: false 0x2a4-NA (0)
+ | | | heap_only_tuple: false 0x2a4-NA (0)
+0x2a0| 01 09 | .. | t_infomask: 2305 0x2a4-0x2a5.7 (2)
+ | | | infomask{}: 0x2a6-NA (0)
+ | | | heap_hasnull: true 0x2a6-NA (0)
+ | | | heap_hasvarwidth: false 0x2a6-NA (0)
+ | | | heap_hasexternal: false 0x2a6-NA (0)
+ | | | heap_hasoid_old: false 0x2a6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2a6-NA (0)
+ | | | heap_combocid: false 0x2a6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2a6-NA (0)
+ | | | heap_xmax_lock_only: false 0x2a6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2a6-NA (0)
+ | | | heap_lock_mask: false 0x2a6-NA (0)
+ | | | heap_xmin_committed: true 0x2a6-NA (0)
+ | | | heap_xmin_invalid: false 0x2a6-NA (0)
+ | | | heap_xmin_frozen: true 0x2a6-NA (0)
+ | | | heap_xmax_committed: false 0x2a6-NA (0)
+ | | | heap_xmax_invalid: true 0x2a6-NA (0)
+ | | | heap_xmax_is_multi: false 0x2a6-NA (0)
+ | | | heap_updated: false 0x2a6-NA (0)
+ | | | heap_moved_off: false 0x2a6-NA (0)
+ | | | heap_moved_in: false 0x2a6-NA (0)
+ | | | heap_moved: false 0x2a6-NA (0)
+0x2a0| 18 | . | t_hoff: 24 0x2a6-0x2a6.7 (1)
+0x2a0| 1f | . | padding0: 31 0x2a7-0x2a7.7 (1)
+0x2a0| 06 00 00 00 01 00 00 00| ........| data: "06000000010000001d950000a6fbffff6d42bb33368d020..." (raw bits) 0x2a8-0x2bf.7 (24)
+0x2b0|1d 95 00 00 a6 fb ff ff 6d 42 bb 33 36 8d 02 00|........mB.36...|
diff --git a/format/postgres/testdata/flavours/postgres10/pg_control b/format/postgres/testdata/flavours/postgres10/pg_control
new file mode 100644
index 000000000..f0df88c1b
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres10/pg_control differ
diff --git a/format/postgres/testdata/flavours/postgres10/pg_control.fqtest b/format/postgres/testdata/flavours/postgres10/pg_control.fqtest
new file mode 100644
index 000000000..88f44fabb
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres10/pg_control.fqtest
@@ -0,0 +1,69 @@
+$ fq -d pg_control -o flavour=postgres10 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|4c 79 b0 59 c5 4b 3c 63 |Ly.Y.K.... |
+* |until 0x1f8.7 (97) | |
+0x1f0| 00 00 00 00 00 00 00| .......| padding1: "00000000000000" (raw bits) 0x1f9-0x1ff.7 (7)
diff --git a/format/postgres/testdata/flavours/postgres13/16407 b/format/postgres/testdata/flavours/postgres13/16407
new file mode 100644
index 000000000..b09838f31
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres13/16407 differ
diff --git a/format/postgres/testdata/flavours/postgres13/16407_1.fqtest b/format/postgres/testdata/flavours/postgres13/16407_1.fqtest
new file mode 100644
index 000000000..4b1d02b03
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres13/16407_1.fqtest
@@ -0,0 +1,16 @@
+$ fq -d pg_heap -o flavour=postgres13 ".[0].pd_linp[0, 1, -1] | dv" 16407
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| d0 9f 60 00 | ..`. | item_id_data: 6332368 0x18-0x1b.7 (4)
+ | | | lp_off: 8144 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 48 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[1]{}: item_id 0x1c-0x1f.7 (4)
+0x10| a0 9f 60 00| ..`.| item_id_data: 6332320 0x1c-0x1f.7 (4)
+ | | | lp_off: 8096 0x20-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x20-NA (0)
+ | | | lp_len: 48 0x20-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[156]{}: item_id 0x288-0x28b.7 (4)
+0x280| 90 82 60 00 | ..`. | item_id_data: 6324880 0x288-0x28b.7 (4)
+ | | | lp_off: 656 0x28c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x28c-NA (0)
+ | | | lp_len: 48 0x28c-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres13/16407_2.fqtest b/format/postgres/testdata/flavours/postgres13/16407_2.fqtest
new file mode 100644
index 000000000..a0bb5c8f2
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres13/16407_2.fqtest
@@ -0,0 +1,95 @@
+$ fq -d pg_heap -o flavour=postgres13 ".[0].tuples[0,-1] | dv" 16407
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fd0-0x1fff.7 (48)
+ | | | header{}: 0x1fd0-0x1fe7.7 (24)
+ | | | t_choice{}: 0x1fd0-0x1fdb.7 (12)
+ | | | t_heap{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|fd 01 00 00 |.... | t_xmin: 509 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | t_xmax: 0 0x1fd4-0x1fd7.7 (4)
+ | | | t_field3{}: 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_cid: 3 0x1fd8-0x1fdb.7 (4)
+0x1fd0| 03 00 00 00 | .... | t_xvac: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_datum{}: 0x1fd0-0x1fdb.7 (12)
+0x1fd0|fd 01 00 00 |.... | datum_len_: 509 0x1fd0-0x1fd3.7 (4)
+0x1fd0| 00 00 00 00 | .... | datum_typmod: 0 0x1fd4-0x1fd7.7 (4)
+0x1fd0| 03 00 00 00 | .... | datum_typeid: 3 0x1fd8-0x1fdb.7 (4)
+ | | | t_ctid{}: 0x1fdc-0x1fe1.7 (6)
+0x1fd0| 00 00 00 00| ....| ip_blkid: 0 0x1fdc-0x1fdf.7 (4)
+0x1fe0|01 00 |.. | ip_posid: 1 0x1fe0-0x1fe1.7 (2)
+0x1fe0| 06 00 | .. | t_infomask2: 6 0x1fe2-0x1fe3.7 (2)
+ | | | infomask2{}: 0x1fe4-NA (0)
+ | | | heap_keys_updated: false 0x1fe4-NA (0)
+ | | | heap_hot_updated: false 0x1fe4-NA (0)
+ | | | heap_only_tuple: false 0x1fe4-NA (0)
+0x1fe0| 01 09 | .. | t_infomask: 2305 0x1fe4-0x1fe5.7 (2)
+ | | | infomask{}: 0x1fe6-NA (0)
+ | | | heap_hasnull: true 0x1fe6-NA (0)
+ | | | heap_hasvarwidth: false 0x1fe6-NA (0)
+ | | | heap_hasexternal: false 0x1fe6-NA (0)
+ | | | heap_hasoid_old: false 0x1fe6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1fe6-NA (0)
+ | | | heap_combocid: false 0x1fe6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1fe6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1fe6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1fe6-NA (0)
+ | | | heap_lock_mask: false 0x1fe6-NA (0)
+ | | | heap_xmin_committed: true 0x1fe6-NA (0)
+ | | | heap_xmin_invalid: false 0x1fe6-NA (0)
+ | | | heap_xmin_frozen: true 0x1fe6-NA (0)
+ | | | heap_xmax_committed: false 0x1fe6-NA (0)
+ | | | heap_xmax_invalid: true 0x1fe6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1fe6-NA (0)
+ | | | heap_updated: false 0x1fe6-NA (0)
+ | | | heap_moved_off: false 0x1fe6-NA (0)
+ | | | heap_moved_in: false 0x1fe6-NA (0)
+ | | | heap_moved: false 0x1fe6-NA (0)
+0x1fe0| 18 | . | t_hoff: 24 0x1fe6-0x1fe6.7 (1)
+0x1fe0| 1f | . | padding0: 31 0x1fe7-0x1fe7.7 (1)
+0x1fe0| 06 00 00 00 01 00 00 00| ........| data: "060000000100000091220000141000008f939dc26888020..." (raw bits) 0x1fe8-0x1fff.7 (24)
+0x1ff0|91 22 00 00 14 10 00 00 8f 93 9d c2 68 88 02 00|."..........h...|
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[156]{}: tuple 0x290-0x2bf.7 (48)
+ | | | header{}: 0x290-0x2a7.7 (24)
+ | | | t_choice{}: 0x290-0x29b.7 (12)
+ | | | t_heap{}: 0x290-0x29b.7 (12)
+0x290|99 02 00 00 |.... | t_xmin: 665 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | t_xmax: 0 0x294-0x297.7 (4)
+ | | | t_field3{}: 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_cid: 3 0x298-0x29b.7 (4)
+0x290| 03 00 00 00 | .... | t_xvac: 3 0x298-0x29b.7 (4)
+ | | | t_datum{}: 0x290-0x29b.7 (12)
+0x290|99 02 00 00 |.... | datum_len_: 665 0x290-0x293.7 (4)
+0x290| 00 00 00 00 | .... | datum_typmod: 0 0x294-0x297.7 (4)
+0x290| 03 00 00 00 | .... | datum_typeid: 3 0x298-0x29b.7 (4)
+ | | | t_ctid{}: 0x29c-0x2a1.7 (6)
+0x290| 00 00 00 00| ....| ip_blkid: 0 0x29c-0x29f.7 (4)
+0x2a0|9d 00 |.. | ip_posid: 157 0x2a0-0x2a1.7 (2)
+0x2a0| 06 00 | .. | t_infomask2: 6 0x2a2-0x2a3.7 (2)
+ | | | infomask2{}: 0x2a4-NA (0)
+ | | | heap_keys_updated: false 0x2a4-NA (0)
+ | | | heap_hot_updated: false 0x2a4-NA (0)
+ | | | heap_only_tuple: false 0x2a4-NA (0)
+0x2a0| 01 09 | .. | t_infomask: 2305 0x2a4-0x2a5.7 (2)
+ | | | infomask{}: 0x2a6-NA (0)
+ | | | heap_hasnull: true 0x2a6-NA (0)
+ | | | heap_hasvarwidth: false 0x2a6-NA (0)
+ | | | heap_hasexternal: false 0x2a6-NA (0)
+ | | | heap_hasoid_old: false 0x2a6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x2a6-NA (0)
+ | | | heap_combocid: false 0x2a6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x2a6-NA (0)
+ | | | heap_xmax_lock_only: false 0x2a6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x2a6-NA (0)
+ | | | heap_lock_mask: false 0x2a6-NA (0)
+ | | | heap_xmin_committed: true 0x2a6-NA (0)
+ | | | heap_xmin_invalid: false 0x2a6-NA (0)
+ | | | heap_xmin_frozen: true 0x2a6-NA (0)
+ | | | heap_xmax_committed: false 0x2a6-NA (0)
+ | | | heap_xmax_invalid: true 0x2a6-NA (0)
+ | | | heap_xmax_is_multi: false 0x2a6-NA (0)
+ | | | heap_updated: false 0x2a6-NA (0)
+ | | | heap_moved_off: false 0x2a6-NA (0)
+ | | | heap_moved_in: false 0x2a6-NA (0)
+ | | | heap_moved: false 0x2a6-NA (0)
+0x2a0| 18 | . | t_hoff: 24 0x2a6-0x2a6.7 (1)
+0x2a0| 1f | . | padding0: 31 0x2a7-0x2a7.7 (1)
+0x2a0| 09 00 00 00 01 00 00 00| ........| data: "0900000001000000ce39000086130000159eb7c26888020..." (raw bits) 0x2a8-0x2bf.7 (24)
+0x2b0|ce 39 00 00 86 13 00 00 15 9e b7 c2 68 88 02 00|.9..........h...|
diff --git a/format/postgres/testdata/flavours/postgres13/pg_control b/format/postgres/testdata/flavours/postgres13/pg_control
new file mode 100644
index 000000000..5db795fe7
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres13/pg_control differ
diff --git a/format/postgres/testdata/flavours/postgres13/pg_control.fqtest b/format/postgres/testdata/flavours/postgres13/pg_control.fqtest
new file mode 100644
index 000000000..8cf6db535
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres13/pg_control.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control -o flavour=postgres13 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|02 a4 3e eb fc 7f d5 62 |..>....b | system_identifier: 7121739110011544578 0x0-0x7.7 (8)
+0x0000| 14 05 00 00 | .... | pg_control_version: 1300 0x8-0xb.7 (4)
+0x0000| a1 62 0a 0c| .b..| catalog_version_no: 202007201 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 3f c4 eb 62 00 00 00 00| ?..b....| time: "Thu, 04 Aug 2022 13:06:07 UTC" (1659618367) 0x18-0x1f.7 (8)
+0x0020|58 7c 77 02 00 00 00 00 |X|w..... | check_point: "0/2777C58" (41385048) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| 20 7c 77 02 00 00 00 00| |w.....| redo: "0/2777C20" (41384992) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|db 30 00 00 00 00 00 00 |.0...... | next_full_xid: 12507 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| de 01 00 00 | .... | oldest_xid: 478 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 3f c4 eb 62 00 00 00 00| ?..b....| time: "Thu, 04 Aug 2022 13:06:07 UTC" (1659618367) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| db 30 00 00 | .0.. | oldest_active_xid: 12507 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| e8 03 00 00 | .... | max_connections: 1000 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 00 00 00 00| ....| data_checksum_version: 0 0xfc-0xff.7 (4)
+0x0100|40 30 6a 6b 3a 01 12 b3 9c 0d aa 29 b2 39 3b e3|@0jk:......).9;.| mock_authentication_nonce: "40306a6b3a0112b39c0daa29b2393be3a10e6a9823b4df2..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|a1 0e 6a 98 23 b4 df 24 8c 37 a9 12 8c 5a 12 cb|..j.#..$.7...Z..|
+0x0120|47 ec c5 c2 |G... | crc: 3267750983 0x120-0x123.7 (4)
+0x0120| 00 00 00 00 | .... | padding1: 0 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/postgres14/.gitignore b/format/postgres/testdata/flavours/postgres14/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/format/postgres/testdata/flavours/postgres14/16404 b/format/postgres/testdata/flavours/postgres14/16404
new file mode 100644
index 000000000..b77a6190b
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres14/16404 differ
diff --git a/format/postgres/testdata/flavours/postgres14/16404_1.fqtest b/format/postgres/testdata/flavours/postgres14/16404_1.fqtest
new file mode 100644
index 000000000..a824952b8
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres14/16404_1.fqtest
@@ -0,0 +1,45 @@
+$ fq -d pg_btree -o flavour=postgres14 ".[0] | d" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0]{}: page
+ | | | page_header{}:
+ | | | pd_lsn{}:
+0x0000|00 00 00 00 |.... | xlogid: "0" (0)
+0x0000| f0 42 20 09 | .B . | xrecoff: "92042F0" (153109232)
+0x0000| 00 00 | .. | pd_checksum: 0
+0x0000| 00 00 | .. | pd_flags: 0
+0x0000| 48 00 | H. | pd_lower: 72
+0x0000| f0 1f| ..| pd_upper: 8176
+0x0010|f0 1f |.. | pd_special: 8176
+0x0010| 04 20 | . | pd_pagesize_version: 8196
+0x0010| 00 00 00 00 | .... | pd_prune_xid: 0
+ | | | meta_page_data{}:
+0x0010| 62 31 05 00 | b1.. | btm_magic: 340322
+0x0010| 04 00 00 00| ....| btm_version: 4
+0x0020|22 01 00 00 |"... | btm_root: 290
+0x0020| 02 00 00 00 | .... | btm_level: 2
+0x0020| 22 01 00 00 | "... | btm_fastroot: 290
+0x0020| 02 00 00 00| ....| btm_fastlevel: 2
+0x0030|00 00 00 00 |.... | btm_last_cleanup_num_delpages: 0
+0x0030| 00 00 00 00 | .... | hole0: 0
+0x0030| 00 00 00 00 00 00 f0 bf| ........| btm_last_cleanup_num_heap_tuples: -1
+0x0040|01 |. | btm_allequalimage: 1
+0x0040| 00 00 00 00 00 00 00 | ....... | padding0: 0
+0x0040| 00 00 00 00 00 00 00 00| ........| unused0: raw bits
+0x0050|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fef.7 (8104) | |
+ | | | page_opaque_data{}:
+0x1ff0|00 00 00 00 |.... | btpo_prev: 0
+0x1ff0| 00 00 00 00 | .... | btpo_next: 0
+0x1ff0| 00 00 00 00 | .... | btpo_level: 0
+ | | | btpo_flags{}:
+0x1ff0| 08 | . | is_incomplete_split: false
+0x1ff0| 08 | . | has_garbage: false
+0x1ff0| 08 | . | split_end: false
+0x1ff0| 08 | . | is_half_dead: false
+0x1ff0| 08 | . | is_meta: true
+0x1ff0| 08 | . | is_deleted: false
+0x1ff0| 08 | . | is_root: false
+0x1ff0| 08 | . | is_leaf: false
+0x1ff0| 00 | . | skip1: 0
+0x1ff0| 00 | . | has_full_xid: false
+ | | | is_ignore: false
+0x1ff0| 00 00| ..| btpo_cycleid: 0
diff --git a/format/postgres/testdata/flavours/postgres14/16404_2.fqtest b/format/postgres/testdata/flavours/postgres14/16404_2.fqtest
new file mode 100644
index 000000000..b94f131ba
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres14/16404_2.fqtest
@@ -0,0 +1,881 @@
+$ fq -d pg_btree -o flavour=postgres14 ".[] | d" 16404
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0]{}: page
+ | | | page_header{}:
+ | | | pd_lsn{}:
+0x0000|00 00 00 00 |.... | xlogid: "0" (0)
+0x0000| f0 42 20 09 | .B . | xrecoff: "92042F0" (153109232)
+0x0000| 00 00 | .. | pd_checksum: 0
+0x0000| 00 00 | .. | pd_flags: 0
+0x0000| 48 00 | H. | pd_lower: 72
+0x0000| f0 1f| ..| pd_upper: 8176
+0x0010|f0 1f |.. | pd_special: 8176
+0x0010| 04 20 | . | pd_pagesize_version: 8196
+0x0010| 00 00 00 00 | .... | pd_prune_xid: 0
+ | | | meta_page_data{}:
+0x0010| 62 31 05 00 | b1.. | btm_magic: 340322
+0x0010| 04 00 00 00| ....| btm_version: 4
+0x0020|22 01 00 00 |"... | btm_root: 290
+0x0020| 02 00 00 00 | .... | btm_level: 2
+0x0020| 22 01 00 00 | "... | btm_fastroot: 290
+0x0020| 02 00 00 00| ....| btm_fastlevel: 2
+0x0030|00 00 00 00 |.... | btm_last_cleanup_num_delpages: 0
+0x0030| 00 00 00 00 | .... | hole0: 0
+0x0030| 00 00 00 00 00 00 f0 bf| ........| btm_last_cleanup_num_heap_tuples: -1
+0x0040|01 |. | btm_allequalimage: 1
+0x0040| 00 00 00 00 00 00 00 | ....... | padding0: 0
+0x0040| 00 00 00 00 00 00 00 00| ........| unused0: raw bits
+0x0050|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fef.7 (8104) | |
+ | | | page_opaque_data{}:
+0x1ff0|00 00 00 00 |.... | btpo_prev: 0
+0x1ff0| 00 00 00 00 | .... | btpo_next: 0
+0x1ff0| 00 00 00 00 | .... | btpo_level: 0
+ | | | btpo_flags{}:
+0x1ff0| 08 | . | is_incomplete_split: false
+0x1ff0| 08 | . | has_garbage: false
+0x1ff0| 08 | . | split_end: false
+0x1ff0| 08 | . | is_half_dead: false
+0x1ff0| 08 | . | is_meta: true
+0x1ff0| 08 | . | is_deleted: false
+0x1ff0| 08 | . | is_root: false
+0x1ff0| 08 | . | is_leaf: false
+0x1ff0| 00 | . | skip1: 0
+0x1ff0| 00 | . | has_full_xid: false
+ | | | is_ignore: false
+0x1ff0| 00 00| ..| btpo_cycleid: 0
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[1]{}: page
+ | | | page_header{}:
+ | | | pd_lsn{}:
+0x2000|00 00 00 00 |.... | xlogid: "0" (0)
+0x2000| 68 c2 e8 07 | h... | xrecoff: "7E8C268" (132694632)
+0x2000| 00 00 | .. | pd_checksum: 0
+0x2000| 00 00 | .. | pd_flags: 0
+0x2000| d4 05 | .. | pd_lower: 1492
+0x2000| 00 09| ..| pd_upper: 2304
+0x2010|f0 1f |.. | pd_special: 8176
+0x2010| 04 20 | . | pd_pagesize_version: 8196
+0x2010| 00 00 00 00 | .... | pd_prune_xid: 0
+ | | | pd_linp[0:367]:
+ | | | [0]{}: item_id
+0x2010| 00 89 20 00 | .. . | item_id_data: 2132224
+ | | | lp_off: 2304
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [1]{}: item_id
+0x2010| e0 9f 20 00| .. .| item_id_data: 2138080
+ | | | lp_off: 8160
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [2]{}: item_id
+0x2020|d0 9f 20 00 |.. . | item_id_data: 2138064
+ | | | lp_off: 8144
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [3]{}: item_id
+0x2020| c0 9f 20 00 | .. . | item_id_data: 2138048
+ | | | lp_off: 8128
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [4]{}: item_id
+0x2020| b0 9f 20 00 | .. . | item_id_data: 2138032
+ | | | lp_off: 8112
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [5]{}: item_id
+0x2020| a0 9f 20 00| .. .| item_id_data: 2138016
+ | | | lp_off: 8096
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [6]{}: item_id
+0x2030|90 9f 20 00 |.. . | item_id_data: 2138000
+ | | | lp_off: 8080
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [7]{}: item_id
+0x2030| 80 9f 20 00 | .. . | item_id_data: 2137984
+ | | | lp_off: 8064
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [8]{}: item_id
+0x2030| 70 9f 20 00 | p. . | item_id_data: 2137968
+ | | | lp_off: 8048
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [9]{}: item_id
+0x2030| 60 9f 20 00| `. .| item_id_data: 2137952
+ | | | lp_off: 8032
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [10]{}: item_id
+0x2040|50 9f 20 00 |P. . | item_id_data: 2137936
+ | | | lp_off: 8016
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [11]{}: item_id
+0x2040| 40 9f 20 00 | @. . | item_id_data: 2137920
+ | | | lp_off: 8000
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [12]{}: item_id
+0x2040| 30 9f 20 00 | 0. . | item_id_data: 2137904
+ | | | lp_off: 7984
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [13]{}: item_id
+0x2040| 20 9f 20 00| . .| item_id_data: 2137888
+ | | | lp_off: 7968
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [14]{}: item_id
+0x2050|10 9f 20 00 |.. . | item_id_data: 2137872
+ | | | lp_off: 7952
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [15]{}: item_id
+0x2050| 00 9f 20 00 | .. . | item_id_data: 2137856
+ | | | lp_off: 7936
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [16]{}: item_id
+0x2050| f0 9e 20 00 | .. . | item_id_data: 2137840
+ | | | lp_off: 7920
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [17]{}: item_id
+0x2050| e0 9e 20 00| .. .| item_id_data: 2137824
+ | | | lp_off: 7904
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [18]{}: item_id
+0x2060|d0 9e 20 00 |.. . | item_id_data: 2137808
+ | | | lp_off: 7888
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [19]{}: item_id
+0x2060| c0 9e 20 00 | .. . | item_id_data: 2137792
+ | | | lp_off: 7872
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [20]{}: item_id
+0x2060| b0 9e 20 00 | .. . | item_id_data: 2137776
+ | | | lp_off: 7856
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [21]{}: item_id
+0x2060| a0 9e 20 00| .. .| item_id_data: 2137760
+ | | | lp_off: 7840
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [22]{}: item_id
+0x2070|90 9e 20 00 |.. . | item_id_data: 2137744
+ | | | lp_off: 7824
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [23]{}: item_id
+0x2070| 80 9e 20 00 | .. . | item_id_data: 2137728
+ | | | lp_off: 7808
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [24]{}: item_id
+0x2070| 70 9e 20 00 | p. . | item_id_data: 2137712
+ | | | lp_off: 7792
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [25]{}: item_id
+0x2070| 60 9e 20 00| `. .| item_id_data: 2137696
+ | | | lp_off: 7776
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [26]{}: item_id
+0x2080|50 9e 20 00 |P. . | item_id_data: 2137680
+ | | | lp_off: 7760
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [27]{}: item_id
+0x2080| 40 9e 20 00 | @. . | item_id_data: 2137664
+ | | | lp_off: 7744
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [28]{}: item_id
+0x2080| 30 9e 20 00 | 0. . | item_id_data: 2137648
+ | | | lp_off: 7728
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [29]{}: item_id
+0x2080| 20 9e 20 00| . .| item_id_data: 2137632
+ | | | lp_off: 7712
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [30]{}: item_id
+0x2090|10 9e 20 00 |.. . | item_id_data: 2137616
+ | | | lp_off: 7696
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [31]{}: item_id
+0x2090| 00 9e 20 00 | .. . | item_id_data: 2137600
+ | | | lp_off: 7680
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [32]{}: item_id
+0x2090| f0 9d 20 00 | .. . | item_id_data: 2137584
+ | | | lp_off: 7664
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [33]{}: item_id
+0x2090| e0 9d 20 00| .. .| item_id_data: 2137568
+ | | | lp_off: 7648
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [34]{}: item_id
+0x20a0|d0 9d 20 00 |.. . | item_id_data: 2137552
+ | | | lp_off: 7632
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [35]{}: item_id
+0x20a0| c0 9d 20 00 | .. . | item_id_data: 2137536
+ | | | lp_off: 7616
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [36]{}: item_id
+0x20a0| b0 9d 20 00 | .. . | item_id_data: 2137520
+ | | | lp_off: 7600
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [37]{}: item_id
+0x20a0| a0 9d 20 00| .. .| item_id_data: 2137504
+ | | | lp_off: 7584
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [38]{}: item_id
+0x20b0|90 9d 20 00 |.. . | item_id_data: 2137488
+ | | | lp_off: 7568
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [39]{}: item_id
+0x20b0| 80 9d 20 00 | .. . | item_id_data: 2137472
+ | | | lp_off: 7552
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [40]{}: item_id
+0x20b0| 70 9d 20 00 | p. . | item_id_data: 2137456
+ | | | lp_off: 7536
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [41]{}: item_id
+0x20b0| 60 9d 20 00| `. .| item_id_data: 2137440
+ | | | lp_off: 7520
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [42]{}: item_id
+0x20c0|50 9d 20 00 |P. . | item_id_data: 2137424
+ | | | lp_off: 7504
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [43]{}: item_id
+0x20c0| 40 9d 20 00 | @. . | item_id_data: 2137408
+ | | | lp_off: 7488
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [44]{}: item_id
+0x20c0| 30 9d 20 00 | 0. . | item_id_data: 2137392
+ | | | lp_off: 7472
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [45]{}: item_id
+0x20c0| 20 9d 20 00| . .| item_id_data: 2137376
+ | | | lp_off: 7456
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [46]{}: item_id
+0x20d0|10 9d 20 00 |.. . | item_id_data: 2137360
+ | | | lp_off: 7440
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [47]{}: item_id
+0x20d0| 00 9d 20 00 | .. . | item_id_data: 2137344
+ | | | lp_off: 7424
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [48]{}: item_id
+0x20d0| f0 9c 20 00 | .. . | item_id_data: 2137328
+ | | | lp_off: 7408
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [49]{}: item_id
+0x20d0| e0 9c 20 00| .. .| item_id_data: 2137312
+ | | | lp_off: 7392
+ | | | lp_flags: "LP_NORMAL" (1)
+ | | | lp_len: 16
+ | | | [50:367]: ...
+0x25d0| 00 00 00 00 00 00 00 00 00 00 00 00| ............| free_space: "00000000000000000000000000000000000000000000000..." (raw bits)
+0x25e0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x28ff.7 (812) | |
+ | | | tuples[0:367]:
+ | | | [0]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x2900|00 00 06 00 |.... | ip_blkid: 393216
+0x2900| 01 00 | .. | ip_posid: 1
+0x2900| 10 20 | . | t_info: 8208
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x2900| 6f 01 00 00 00 00 00 00| o.......| data: raw bits
+ | | | [1]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3fe0|00 00 00 00 |.... | ip_blkid: 0
+0x3fe0| 01 00 | .. | ip_posid: 1
+0x3fe0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3fe0| 01 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [2]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3fd0|00 00 00 00 |.... | ip_blkid: 0
+0x3fd0| 02 00 | .. | ip_posid: 2
+0x3fd0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3fd0| 02 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [3]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3fc0|00 00 00 00 |.... | ip_blkid: 0
+0x3fc0| 03 00 | .. | ip_posid: 3
+0x3fc0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3fc0| 03 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [4]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3fb0|00 00 00 00 |.... | ip_blkid: 0
+0x3fb0| 04 00 | .. | ip_posid: 4
+0x3fb0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3fb0| 04 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [5]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3fa0|00 00 00 00 |.... | ip_blkid: 0
+0x3fa0| 05 00 | .. | ip_posid: 5
+0x3fa0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3fa0| 05 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [6]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f90|00 00 00 00 |.... | ip_blkid: 0
+0x3f90| 06 00 | .. | ip_posid: 6
+0x3f90| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f90| 06 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [7]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f80|00 00 00 00 |.... | ip_blkid: 0
+0x3f80| 07 00 | .. | ip_posid: 7
+0x3f80| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f80| 07 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [8]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f70|00 00 00 00 |.... | ip_blkid: 0
+0x3f70| 08 00 | .. | ip_posid: 8
+0x3f70| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f70| 08 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [9]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f60|00 00 00 00 |.... | ip_blkid: 0
+0x3f60| 09 00 | .. | ip_posid: 9
+0x3f60| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f60| 09 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [10]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f50|00 00 00 00 |.... | ip_blkid: 0
+0x3f50| 0a 00 | .. | ip_posid: 10
+0x3f50| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f50| 0a 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [11]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f40|00 00 00 00 |.... | ip_blkid: 0
+0x3f40| 0b 00 | .. | ip_posid: 11
+0x3f40| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f40| 0b 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [12]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f30|00 00 00 00 |.... | ip_blkid: 0
+0x3f30| 0c 00 | .. | ip_posid: 12
+0x3f30| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f30| 0c 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [13]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f20|00 00 00 00 |.... | ip_blkid: 0
+0x3f20| 0d 00 | .. | ip_posid: 13
+0x3f20| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f20| 0d 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [14]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f10|00 00 00 00 |.... | ip_blkid: 0
+0x3f10| 0e 00 | .. | ip_posid: 14
+0x3f10| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f10| 0e 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [15]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3f00|00 00 00 00 |.... | ip_blkid: 0
+0x3f00| 0f 00 | .. | ip_posid: 15
+0x3f00| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3f00| 0f 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [16]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3ef0|00 00 00 00 |.... | ip_blkid: 0
+0x3ef0| 10 00 | .. | ip_posid: 16
+0x3ef0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3ef0| 10 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [17]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3ee0|00 00 00 00 |.... | ip_blkid: 0
+0x3ee0| 11 00 | .. | ip_posid: 17
+0x3ee0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3ee0| 11 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [18]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3ed0|00 00 00 00 |.... | ip_blkid: 0
+0x3ed0| 12 00 | .. | ip_posid: 18
+0x3ed0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3ed0| 12 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [19]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3ec0|00 00 00 00 |.... | ip_blkid: 0
+0x3ec0| 13 00 | .. | ip_posid: 19
+0x3ec0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3ec0| 13 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [20]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3eb0|00 00 00 00 |.... | ip_blkid: 0
+0x3eb0| 14 00 | .. | ip_posid: 20
+0x3eb0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3eb0| 14 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [21]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3ea0|00 00 00 00 |.... | ip_blkid: 0
+0x3ea0| 15 00 | .. | ip_posid: 21
+0x3ea0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3ea0| 15 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [22]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e90|00 00 00 00 |.... | ip_blkid: 0
+0x3e90| 16 00 | .. | ip_posid: 22
+0x3e90| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e90| 16 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [23]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e80|00 00 00 00 |.... | ip_blkid: 0
+0x3e80| 17 00 | .. | ip_posid: 23
+0x3e80| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e80| 17 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [24]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e70|00 00 00 00 |.... | ip_blkid: 0
+0x3e70| 18 00 | .. | ip_posid: 24
+0x3e70| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e70| 18 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [25]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e60|00 00 00 00 |.... | ip_blkid: 0
+0x3e60| 19 00 | .. | ip_posid: 25
+0x3e60| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e60| 19 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [26]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e50|00 00 00 00 |.... | ip_blkid: 0
+0x3e50| 1a 00 | .. | ip_posid: 26
+0x3e50| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e50| 1a 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [27]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e40|00 00 00 00 |.... | ip_blkid: 0
+0x3e40| 1b 00 | .. | ip_posid: 27
+0x3e40| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e40| 1b 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [28]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e30|00 00 00 00 |.... | ip_blkid: 0
+0x3e30| 1c 00 | .. | ip_posid: 28
+0x3e30| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e30| 1c 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [29]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e20|00 00 00 00 |.... | ip_blkid: 0
+0x3e20| 1d 00 | .. | ip_posid: 29
+0x3e20| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e20| 1d 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [30]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e10|00 00 00 00 |.... | ip_blkid: 0
+0x3e10| 1e 00 | .. | ip_posid: 30
+0x3e10| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e10| 1e 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [31]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3e00|00 00 00 00 |.... | ip_blkid: 0
+0x3e00| 1f 00 | .. | ip_posid: 31
+0x3e00| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3e00| 1f 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [32]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3df0|00 00 00 00 |.... | ip_blkid: 0
+0x3df0| 20 00 | . | ip_posid: 32
+0x3df0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3df0| 20 00 00 00 00 00 00 00| .......| data: raw bits
+ | | | [33]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3de0|00 00 00 00 |.... | ip_blkid: 0
+0x3de0| 21 00 | !. | ip_posid: 33
+0x3de0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3de0| 21 00 00 00 00 00 00 00| !.......| data: raw bits
+ | | | [34]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3dd0|00 00 00 00 |.... | ip_blkid: 0
+0x3dd0| 22 00 | ". | ip_posid: 34
+0x3dd0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3dd0| 22 00 00 00 00 00 00 00| ".......| data: raw bits
+ | | | [35]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3dc0|00 00 00 00 |.... | ip_blkid: 0
+0x3dc0| 23 00 | #. | ip_posid: 35
+0x3dc0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3dc0| 23 00 00 00 00 00 00 00| #.......| data: raw bits
+ | | | [36]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3db0|00 00 00 00 |.... | ip_blkid: 0
+0x3db0| 24 00 | $. | ip_posid: 36
+0x3db0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3db0| 24 00 00 00 00 00 00 00| $.......| data: raw bits
+ | | | [37]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3da0|00 00 00 00 |.... | ip_blkid: 0
+0x3da0| 25 00 | %. | ip_posid: 37
+0x3da0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3da0| 25 00 00 00 00 00 00 00| %.......| data: raw bits
+ | | | [38]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d90|00 00 00 00 |.... | ip_blkid: 0
+0x3d90| 26 00 | &. | ip_posid: 38
+0x3d90| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d90| 26 00 00 00 00 00 00 00| &.......| data: raw bits
+ | | | [39]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d80|00 00 00 00 |.... | ip_blkid: 0
+0x3d80| 27 00 | '. | ip_posid: 39
+0x3d80| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d80| 27 00 00 00 00 00 00 00| '.......| data: raw bits
+ | | | [40]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d70|00 00 00 00 |.... | ip_blkid: 0
+0x3d70| 28 00 | (. | ip_posid: 40
+0x3d70| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d70| 28 00 00 00 00 00 00 00| (.......| data: raw bits
+ | | | [41]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d60|00 00 00 00 |.... | ip_blkid: 0
+0x3d60| 29 00 | ). | ip_posid: 41
+0x3d60| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d60| 29 00 00 00 00 00 00 00| ).......| data: raw bits
+ | | | [42]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d50|00 00 00 00 |.... | ip_blkid: 0
+0x3d50| 2a 00 | *. | ip_posid: 42
+0x3d50| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d50| 2a 00 00 00 00 00 00 00| *.......| data: raw bits
+ | | | [43]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d40|00 00 00 00 |.... | ip_blkid: 0
+0x3d40| 2b 00 | +. | ip_posid: 43
+0x3d40| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d40| 2b 00 00 00 00 00 00 00| +.......| data: raw bits
+ | | | [44]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d30|00 00 00 00 |.... | ip_blkid: 0
+0x3d30| 2c 00 | ,. | ip_posid: 44
+0x3d30| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d30| 2c 00 00 00 00 00 00 00| ,.......| data: raw bits
+ | | | [45]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d20|00 00 00 00 |.... | ip_blkid: 0
+0x3d20| 2d 00 | -. | ip_posid: 45
+0x3d20| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d20| 2d 00 00 00 00 00 00 00| -.......| data: raw bits
+ | | | [46]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d10|00 00 00 00 |.... | ip_blkid: 0
+0x3d10| 2e 00 | .. | ip_posid: 46
+0x3d10| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d10| 2e 00 00 00 00 00 00 00| ........| data: raw bits
+ | | | [47]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3d00|00 00 00 00 |.... | ip_blkid: 0
+0x3d00| 2f 00 | /. | ip_posid: 47
+0x3d00| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3d00| 2f 00 00 00 00 00 00 00| /.......| data: raw bits
+ | | | [48]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3cf0|00 00 00 00 |.... | ip_blkid: 0
+0x3cf0| 30 00 | 0. | ip_posid: 48
+0x3cf0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3cf0| 30 00 00 00 00 00 00 00| 0.......| data: raw bits
+ | | | [49]{}: tuple
+ | | | index_tuple_data{}:
+ | | | t_tid{}:
+0x3ce0|00 00 00 00 |.... | ip_blkid: 0
+0x3ce0| 31 00 | 1. | ip_posid: 49
+0x3ce0| 10 00 | .. | t_info: 16
+ | | | flags{}:
+ | | | has_nulls: false
+ | | | has_var_widths: false
+ | | | size: 16
+0x3ce0| 31 00 00 00 00 00 00 00| 1.......| data: raw bits
+ | | | [50:367]: ...
+ | | | page_opaque_data{}:
+0x3ff0|00 00 00 00 |.... | btpo_prev: 0
+0x3ff0| 02 00 00 00 | .... | btpo_next: 2
+0x3ff0| 00 00 00 00 | .... | btpo_level: 0
+ | | | btpo_flags{}:
+0x3ff0| 01 | . | is_incomplete_split: false
+0x3ff0| 01 | . | has_garbage: false
+0x3ff0| 01 | . | split_end: false
+0x3ff0| 01 | . | is_half_dead: false
+0x3ff0| 01 | . | is_meta: false
+0x3ff0| 01 | . | is_deleted: false
+0x3ff0| 01 | . | is_root: false
+0x3ff0| 01 | . | is_leaf: true
+0x3ff0| 00 | . | skip1: 0
+0x3ff0| 00 | . | has_full_xid: false
+ | | | is_ignore: false
+0x3ff0| 00 00| ..| btpo_cycleid: 0
diff --git a/format/postgres/testdata/flavours/postgres14/16994 b/format/postgres/testdata/flavours/postgres14/16994
new file mode 100644
index 000000000..c54d30aa4
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres14/16994 differ
diff --git a/format/postgres/testdata/flavours/postgres14/16994_1.fqtest b/format/postgres/testdata/flavours/postgres14/16994_1.fqtest
new file mode 100644
index 000000000..d5da3d8ef
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres14/16994_1.fqtest
@@ -0,0 +1,21 @@
+$ fq -d pg_heap -o flavour=postgres14 ".[0].pd_linp[0, 1, 2, -1] | dv" 16994
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 00 80 01 00 | .... | item_id_data: 98304 0x18-0x1b.7 (4)
+ | | | lp_off: 0 0x1c-NA (0)
+ | | | lp_flags: "LP_DEAD" (3) 0x1c-NA (0)
+ | | | lp_len: 0 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[1]{}: item_id 0x1c-0x1f.7 (4)
+0x10| e0 9f 38 00| ..8.| item_id_data: 3710944 0x1c-0x1f.7 (4)
+ | | | lp_off: 8160 0x20-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x20-NA (0)
+ | | | lp_len: 28 0x20-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[2]{}: item_id 0x20-0x23.7 (4)
+0x20|c0 9f 38 00 |..8. | item_id_data: 3710912 0x20-0x23.7 (4)
+ | | | lp_off: 8128 0x24-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x24-NA (0)
+ | | | lp_len: 28 0x24-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[225]{}: item_id 0x39c-0x39f.7 (4)
+0x390| e0 83 38 00| ..8.| item_id_data: 3703776 0x39c-0x39f.7 (4)
+ | | | lp_off: 992 0x3a0-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x3a0-NA (0)
+ | | | lp_len: 28 0x3a0-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres14/33233 b/format/postgres/testdata/flavours/postgres14/33233
new file mode 100644
index 000000000..ee5e51844
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres14/33233 differ
diff --git a/format/postgres/testdata/flavours/postgres14/33233_1.fqtest b/format/postgres/testdata/flavours/postgres14/33233_1.fqtest
new file mode 100644
index 000000000..13cfb15dc
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres14/33233_1.fqtest
@@ -0,0 +1,16 @@
+$ fq -d pg_heap -o flavour=postgres14 ".[0].pd_linp[0, 1, -1] | dv" 33233
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 4d 00 01 00 | M... | item_id_data: 65613 0x18-0x1b.7 (4)
+ | | | lp_off: 77 0x1c-NA (0)
+ | | | lp_flags: "LP_REDIRECT" (2) 0x1c-NA (0)
+ | | | lp_len: 0 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[1]{}: item_id 0x1c-0x1f.7 (4)
+0x10| 6a 00 01 00| j...| item_id_data: 65642 0x1c-0x1f.7 (4)
+ | | | lp_off: 106 0x20-NA (0)
+ | | | lp_flags: "LP_REDIRECT" (2) 0x20-NA (0)
+ | | | lp_len: 0 0x20-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[119]{}: item_id 0x1f4-0x1f7.7 (4)
+0x1f0| 80 82 f2 00 | .... | item_id_data: 15893120 0x1f4-0x1f7.7 (4)
+ | | | lp_off: 640 0x1f8-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1f8-NA (0)
+ | | | lp_len: 121 0x1f8-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres14/33233_2.fqtest b/format/postgres/testdata/flavours/postgres14/33233_2.fqtest
new file mode 100644
index 000000000..418e17635
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres14/33233_2.fqtest
@@ -0,0 +1,99 @@
+$ fq -d pg_heap -o flavour=postgres14 ".[0].tuples[0,-1] | dv" 33233
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1f80-0x1fff.7 (128)
+ | | | header{}: 0x1f80-0x1f97.7 (24)
+ | | | t_choice{}: 0x1f80-0x1f8b.7 (12)
+ | | | t_heap{}: 0x1f80-0x1f8b.7 (12)
+0x1f80|86 10 18 00 |.... | t_xmin: 1577094 0x1f80-0x1f83.7 (4)
+0x1f80| 00 00 00 00 | .... | t_xmax: 0 0x1f84-0x1f87.7 (4)
+ | | | t_field3{}: 0x1f88-0x1f8b.7 (4)
+0x1f80| 0f 00 00 00 | .... | t_cid: 15 0x1f88-0x1f8b.7 (4)
+0x1f80| 0f 00 00 00 | .... | t_xvac: 15 0x1f88-0x1f8b.7 (4)
+ | | | t_datum{}: 0x1f80-0x1f8b.7 (12)
+0x1f80|86 10 18 00 |.... | datum_len_: 1577094 0x1f80-0x1f83.7 (4)
+0x1f80| 00 00 00 00 | .... | datum_typmod: 0 0x1f84-0x1f87.7 (4)
+0x1f80| 0f 00 00 00 | .... | datum_typeid: 15 0x1f88-0x1f8b.7 (4)
+ | | | t_ctid{}: 0x1f8c-0x1f91.7 (6)
+0x1f80| 00 00 00 00| ....| ip_blkid: 0 0x1f8c-0x1f8f.7 (4)
+0x1f90|15 00 |.. | ip_posid: 21 0x1f90-0x1f91.7 (2)
+0x1f90| 04 00 | .. | t_infomask2: 4 0x1f92-0x1f93.7 (2)
+ | | | infomask2{}: 0x1f94-NA (0)
+ | | | heap_keys_updated: false 0x1f94-NA (0)
+ | | | heap_hot_updated: false 0x1f94-NA (0)
+ | | | heap_only_tuple: false 0x1f94-NA (0)
+0x1f90| 02 09 | .. | t_infomask: 2306 0x1f94-0x1f95.7 (2)
+ | | | infomask{}: 0x1f96-NA (0)
+ | | | heap_hasnull: false 0x1f96-NA (0)
+ | | | heap_hasvarwidth: true 0x1f96-NA (0)
+ | | | heap_hasexternal: false 0x1f96-NA (0)
+ | | | heap_hasoid_old: false 0x1f96-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1f96-NA (0)
+ | | | heap_combocid: false 0x1f96-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1f96-NA (0)
+ | | | heap_xmax_lock_only: false 0x1f96-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1f96-NA (0)
+ | | | heap_lock_mask: false 0x1f96-NA (0)
+ | | | heap_xmin_committed: true 0x1f96-NA (0)
+ | | | heap_xmin_invalid: false 0x1f96-NA (0)
+ | | | heap_xmin_frozen: true 0x1f96-NA (0)
+ | | | heap_xmax_committed: false 0x1f96-NA (0)
+ | | | heap_xmax_invalid: true 0x1f96-NA (0)
+ | | | heap_xmax_is_multi: false 0x1f96-NA (0)
+ | | | heap_updated: false 0x1f96-NA (0)
+ | | | heap_moved_off: false 0x1f96-NA (0)
+ | | | heap_moved_in: false 0x1f96-NA (0)
+ | | | heap_moved: false 0x1f96-NA (0)
+0x1f90| 18 | . | t_hoff: 24 0x1f96-0x1f96.7 (1)
+0x1f90| 00 | . | padding0: 0 0x1f97-0x1f97.7 (1)
+0x1f90| 15 00 00 00 01 00 00 00| ........| data: "150000000100000000000000ab202020202020202020202..." (raw bits) 0x1f98-0x1ff8.7 (97)
+0x1fa0|00 00 00 00 ab 20 20 20 20 20 20 20 20 20 20 20|..... |
+* |until 0x1ff8.7 (97) | |
+0x1ff0| 00 00 00 00 00 00 00| .......| padding1: "00000000000000" (raw bits) 0x1ff9-0x1fff.7 (7)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[58]{}: tuple 0x280-0x2ff.7 (128)
+ | | | header{}: 0x280-0x297.7 (24)
+ | | | t_choice{}: 0x280-0x28b.7 (12)
+ | | | t_heap{}: 0x280-0x28b.7 (12)
+0x280|96 58 1c 00 |.X.. | t_xmin: 1857686 0x280-0x283.7 (4)
+0x280| 00 00 00 00 | .... | t_xmax: 0 0x284-0x287.7 (4)
+ | | | t_field3{}: 0x288-0x28b.7 (4)
+0x280| 00 00 00 00 | .... | t_cid: 0 0x288-0x28b.7 (4)
+0x280| 00 00 00 00 | .... | t_xvac: 0 0x288-0x28b.7 (4)
+ | | | t_datum{}: 0x280-0x28b.7 (12)
+0x280|96 58 1c 00 |.X.. | datum_len_: 1857686 0x280-0x283.7 (4)
+0x280| 00 00 00 00 | .... | datum_typmod: 0 0x284-0x287.7 (4)
+0x280| 00 00 00 00 | .... | datum_typeid: 0 0x288-0x28b.7 (4)
+ | | | t_ctid{}: 0x28c-0x291.7 (6)
+0x280| 00 00 00 00| ....| ip_blkid: 0 0x28c-0x28f.7 (4)
+0x290|78 00 |x. | ip_posid: 120 0x290-0x291.7 (2)
+0x290| 04 80 | .. | t_infomask2: 32772 0x292-0x293.7 (2)
+ | | | infomask2{}: 0x294-NA (0)
+ | | | heap_keys_updated: false 0x294-NA (0)
+ | | | heap_hot_updated: false 0x294-NA (0)
+ | | | heap_only_tuple: true 0x294-NA (0)
+0x290| 02 29 | .) | t_infomask: 10498 0x294-0x295.7 (2)
+ | | | infomask{}: 0x296-NA (0)
+ | | | heap_hasnull: false 0x296-NA (0)
+ | | | heap_hasvarwidth: true 0x296-NA (0)
+ | | | heap_hasexternal: false 0x296-NA (0)
+ | | | heap_hasoid_old: false 0x296-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x296-NA (0)
+ | | | heap_combocid: false 0x296-NA (0)
+ | | | heap_xmax_excl_lock: false 0x296-NA (0)
+ | | | heap_xmax_lock_only: false 0x296-NA (0)
+ | | | heap_xmax_shr_lock: false 0x296-NA (0)
+ | | | heap_lock_mask: false 0x296-NA (0)
+ | | | heap_xmin_committed: true 0x296-NA (0)
+ | | | heap_xmin_invalid: false 0x296-NA (0)
+ | | | heap_xmin_frozen: true 0x296-NA (0)
+ | | | heap_xmax_committed: false 0x296-NA (0)
+ | | | heap_xmax_invalid: true 0x296-NA (0)
+ | | | heap_xmax_is_multi: false 0x296-NA (0)
+ | | | heap_updated: true 0x296-NA (0)
+ | | | heap_moved_off: false 0x296-NA (0)
+ | | | heap_moved_in: false 0x296-NA (0)
+ | | | heap_moved: false 0x296-NA (0)
+0x290| 18 | . | t_hoff: 24 0x296-0x296.7 (1)
+0x290| 00 | . | padding0: 0 0x297-0x297.7 (1)
+0x290| 21 00 00 00 01 00 00 00| !.......| data: "210000000100000053fdffffab202020202020202020202..." (raw bits) 0x298-0x2f8.7 (97)
+0x2a0|53 fd ff ff ab 20 20 20 20 20 20 20 20 20 20 20|S.... |
+* |until 0x2f8.7 (97) | |
+0x2f0| 00 00 00 00 00 00 00| .......| padding1: "00000000000000" (raw bits) 0x2f9-0x2ff.7 (7)
diff --git a/format/postgres/testdata/flavours/postgres14/pg_control b/format/postgres/testdata/flavours/postgres14/pg_control
new file mode 100644
index 000000000..8306f77d0
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres14/pg_control differ
diff --git a/format/postgres/testdata/flavours/postgres14/pg_control.fqtest b/format/postgres/testdata/flavours/postgres14/pg_control.fqtest
new file mode 100644
index 000000000..b941f4df1
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres14/pg_control.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control -o flavour=postgres14 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|68 e7 dd 05 b3 88 b3 61 |h......a | system_identifier: 7040120944989169512 0x0-0x7.7 (8)
+0x0000| 14 05 00 00 | .... | pg_control_version: 1300 0x8-0xb.7 (4)
+0x0000| 2d e9 0b 0c| -...| catalog_version_no: 202107181 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 46 a1 c2 62 00 00 00 00| F..b....| time: "Mon, 04 Jul 2022 08:13:58 UTC" (1656922438) 0x18-0x1f.7 (8)
+0x0020|c0 88 d6 9a 00 00 00 00 |........ | check_point: "0/9AD688C0" (2597750976) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| c0 88 d6 9a 00 00 00 00| ........| redo: "0/9AD688C0" (2597750976) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|4b ab 1c 00 00 00 00 00 |K....... | next_xid: 1878859 0x40-0x47.7 (8)
+0x0040| dd 81 00 00 | .... | next_oid: 33245 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| d6 02 00 00 | .... | oldest_xid: 726 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 46 a1 c2 62 00 00 00 00| F..b....| time: "Mon, 04 Jul 2022 08:13:58 UTC" (1656922438) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| 00 00 00 00 | .... | oldest_active_xid: 0 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| 64 00 00 00 | d... | max_connections: 100 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 00 00 00 00| ....| data_checksum_version: 0 0xfc-0xff.7 (4)
+0x0100|00 45 fd 64 7e d4 d3 53 82 75 0a b7 d6 be c1 9a|.E.d~..S.u......| mock_authentication_nonce: "0045fd647ed4d35382750ab7d6bec19a77af72bae00f728..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|77 af 72 ba e0 0f 72 80 4a 57 43 fb 76 c8 98 8c|w.r...r.JWC.v...|
+0x0120|4b 76 27 eb |Kv'. | crc: 3945231947 0x120-0x123.7 (4)
+0x0120| 00 00 00 00 | .... | padding1: 0 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/flavours/postgres15/16400 b/format/postgres/testdata/flavours/postgres15/16400
new file mode 100644
index 000000000..f43ce0cc7
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres15/16400 differ
diff --git a/format/postgres/testdata/flavours/postgres15/16400.fqtest b/format/postgres/testdata/flavours/postgres15/16400.fqtest
new file mode 100644
index 000000000..dd209b1cd
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres15/16400.fqtest
@@ -0,0 +1,21 @@
+$ fq -d pg_heap -o flavour=postgres15 ".[0].pd_linp[0, 1, 2, -1] | dv" 16400
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[0]{}: item_id 0x18-0x1b.7 (4)
+0x10| 80 9f f2 00 | .... | item_id_data: 15900544 0x18-0x1b.7 (4)
+ | | | lp_off: 8064 0x1c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x1c-NA (0)
+ | | | lp_len: 121 0x1c-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[1]{}: item_id 0x1c-0x1f.7 (4)
+0x10| 00 9f f2 00| ....| item_id_data: 15900416 0x1c-0x1f.7 (4)
+ | | | lp_off: 7936 0x20-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x20-NA (0)
+ | | | lp_len: 121 0x20-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[2]{}: item_id 0x20-0x23.7 (4)
+0x20|80 9e f2 00 |.... | item_id_data: 15900288 0x20-0x23.7 (4)
+ | | | lp_off: 7808 0x24-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x24-NA (0)
+ | | | lp_len: 121 0x24-NA (0)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].pd_linp[60]{}: item_id 0x108-0x10b.7 (4)
+0x100| 80 81 f2 00 | .... | item_id_data: 15892864 0x108-0x10b.7 (4)
+ | | | lp_off: 384 0x10c-NA (0)
+ | | | lp_flags: "LP_NORMAL" (1) 0x10c-NA (0)
+ | | | lp_len: 121 0x10c-NA (0)
diff --git a/format/postgres/testdata/flavours/postgres15/16401 b/format/postgres/testdata/flavours/postgres15/16401
new file mode 100644
index 000000000..5765b6f85
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres15/16401 differ
diff --git a/format/postgres/testdata/flavours/postgres15/16401.fqtest b/format/postgres/testdata/flavours/postgres15/16401.fqtest
new file mode 100644
index 000000000..94358c027
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres15/16401.fqtest
@@ -0,0 +1,93 @@
+$ fq -d pg_heap -o flavour=postgres15 ".[0].tuples[0,-1] | dv" 16401
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fe0-0x1fff.7 (32)
+ | | | header{}: 0x1fe0-0x1ff7.7 (24)
+ | | | t_choice{}: 0x1fe0-0x1feb.7 (12)
+ | | | t_heap{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|e3 02 00 00 |.... | t_xmin: 739 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | t_xmax: 0 0x1fe4-0x1fe7.7 (4)
+ | | | t_field3{}: 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_cid: 4 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_xvac: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_datum{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|e3 02 00 00 |.... | datum_len_: 739 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | datum_typmod: 0 0x1fe4-0x1fe7.7 (4)
+0x1fe0| 04 00 00 00 | .... | datum_typeid: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_ctid{}: 0x1fec-0x1ff1.7 (6)
+0x1fe0| 00 00 00 00| ....| ip_blkid: 0 0x1fec-0x1fef.7 (4)
+0x1ff0|01 00 |.. | ip_posid: 1 0x1ff0-0x1ff1.7 (2)
+0x1ff0| 03 00 | .. | t_infomask2: 3 0x1ff2-0x1ff3.7 (2)
+ | | | infomask2{}: 0x1ff4-NA (0)
+ | | | heap_keys_updated: false 0x1ff4-NA (0)
+ | | | heap_hot_updated: false 0x1ff4-NA (0)
+ | | | heap_only_tuple: false 0x1ff4-NA (0)
+0x1ff0| 01 09 | .. | t_infomask: 2305 0x1ff4-0x1ff5.7 (2)
+ | | | infomask{}: 0x1ff6-NA (0)
+ | | | heap_hasnull: true 0x1ff6-NA (0)
+ | | | heap_hasvarwidth: false 0x1ff6-NA (0)
+ | | | heap_hasexternal: false 0x1ff6-NA (0)
+ | | | heap_hasoid_old: false 0x1ff6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1ff6-NA (0)
+ | | | heap_combocid: false 0x1ff6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1ff6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1ff6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1ff6-NA (0)
+ | | | heap_lock_mask: false 0x1ff6-NA (0)
+ | | | heap_xmin_committed: true 0x1ff6-NA (0)
+ | | | heap_xmin_invalid: false 0x1ff6-NA (0)
+ | | | heap_xmin_frozen: true 0x1ff6-NA (0)
+ | | | heap_xmax_committed: false 0x1ff6-NA (0)
+ | | | heap_xmax_invalid: true 0x1ff6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1ff6-NA (0)
+ | | | heap_updated: false 0x1ff6-NA (0)
+ | | | heap_moved_off: false 0x1ff6-NA (0)
+ | | | heap_moved_in: false 0x1ff6-NA (0)
+ | | | heap_moved: false 0x1ff6-NA (0)
+0x1ff0| 18 | . | t_hoff: 24 0x1ff6-0x1ff6.7 (1)
+0x1ff0| 03 | . | padding0: 3 0x1ff7-0x1ff7.7 (1)
+0x1ff0| 01 00 00 00 00 00 00 00| ........| data: "0100000000000000" (raw bits) 0x1ff8-0x1fff.7 (8)
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tuples[0]{}: tuple 0x1fe0-0x1fff.7 (32)
+ | | | header{}: 0x1fe0-0x1ff7.7 (24)
+ | | | t_choice{}: 0x1fe0-0x1feb.7 (12)
+ | | | t_heap{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|e3 02 00 00 |.... | t_xmin: 739 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | t_xmax: 0 0x1fe4-0x1fe7.7 (4)
+ | | | t_field3{}: 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_cid: 4 0x1fe8-0x1feb.7 (4)
+0x1fe0| 04 00 00 00 | .... | t_xvac: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_datum{}: 0x1fe0-0x1feb.7 (12)
+0x1fe0|e3 02 00 00 |.... | datum_len_: 739 0x1fe0-0x1fe3.7 (4)
+0x1fe0| 00 00 00 00 | .... | datum_typmod: 0 0x1fe4-0x1fe7.7 (4)
+0x1fe0| 04 00 00 00 | .... | datum_typeid: 4 0x1fe8-0x1feb.7 (4)
+ | | | t_ctid{}: 0x1fec-0x1ff1.7 (6)
+0x1fe0| 00 00 00 00| ....| ip_blkid: 0 0x1fec-0x1fef.7 (4)
+0x1ff0|01 00 |.. | ip_posid: 1 0x1ff0-0x1ff1.7 (2)
+0x1ff0| 03 00 | .. | t_infomask2: 3 0x1ff2-0x1ff3.7 (2)
+ | | | infomask2{}: 0x1ff4-NA (0)
+ | | | heap_keys_updated: false 0x1ff4-NA (0)
+ | | | heap_hot_updated: false 0x1ff4-NA (0)
+ | | | heap_only_tuple: false 0x1ff4-NA (0)
+0x1ff0| 01 09 | .. | t_infomask: 2305 0x1ff4-0x1ff5.7 (2)
+ | | | infomask{}: 0x1ff6-NA (0)
+ | | | heap_hasnull: true 0x1ff6-NA (0)
+ | | | heap_hasvarwidth: false 0x1ff6-NA (0)
+ | | | heap_hasexternal: false 0x1ff6-NA (0)
+ | | | heap_hasoid_old: false 0x1ff6-NA (0)
+ | | | heap_xmax_keyshr_lock: false 0x1ff6-NA (0)
+ | | | heap_combocid: false 0x1ff6-NA (0)
+ | | | heap_xmax_excl_lock: false 0x1ff6-NA (0)
+ | | | heap_xmax_lock_only: false 0x1ff6-NA (0)
+ | | | heap_xmax_shr_lock: false 0x1ff6-NA (0)
+ | | | heap_lock_mask: false 0x1ff6-NA (0)
+ | | | heap_xmin_committed: true 0x1ff6-NA (0)
+ | | | heap_xmin_invalid: false 0x1ff6-NA (0)
+ | | | heap_xmin_frozen: true 0x1ff6-NA (0)
+ | | | heap_xmax_committed: false 0x1ff6-NA (0)
+ | | | heap_xmax_invalid: true 0x1ff6-NA (0)
+ | | | heap_xmax_is_multi: false 0x1ff6-NA (0)
+ | | | heap_updated: false 0x1ff6-NA (0)
+ | | | heap_moved_off: false 0x1ff6-NA (0)
+ | | | heap_moved_in: false 0x1ff6-NA (0)
+ | | | heap_moved: false 0x1ff6-NA (0)
+0x1ff0| 18 | . | t_hoff: 24 0x1ff6-0x1ff6.7 (1)
+0x1ff0| 03 | . | padding0: 3 0x1ff7-0x1ff7.7 (1)
+0x1ff0| 01 00 00 00 00 00 00 00| ........| data: "0100000000000000" (raw bits) 0x1ff8-0x1fff.7 (8)
diff --git a/format/postgres/testdata/flavours/postgres15/pg_control b/format/postgres/testdata/flavours/postgres15/pg_control
new file mode 100644
index 000000000..14a875bf0
Binary files /dev/null and b/format/postgres/testdata/flavours/postgres15/pg_control differ
diff --git a/format/postgres/testdata/flavours/postgres15/pg_control.fqtest b/format/postgres/testdata/flavours/postgres15/pg_control.fqtest
new file mode 100644
index 000000000..434c3c77d
--- /dev/null
+++ b/format/postgres/testdata/flavours/postgres15/pg_control.fqtest
@@ -0,0 +1,67 @@
+$ fq -d pg_control -o flavour=postgres15 dv pg_control
+ |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: pg_control (pg_control) 0x0-0x1fff.7 (8192)
+0x0000|6c a6 bc 14 92 e4 33 64 |l.....3d | system_identifier: 7220365943669302892 0x0-0x7.7 (8)
+0x0000| 14 05 00 00 | .... | pg_control_version: 1300 0x8-0xb.7 (4)
+0x0000| 25 77 0d 0c| %w..| catalog_version_no: 202209061 0xc-0xf.7 (4)
+0x0010|06 00 00 00 |.... | state: "DB_IN_PRODUCTION" (6) 0x10-0x13.7 (4)
+0x0010| 00 00 00 00 | .... | hole0: 0 0x14-0x17.7 (4)
+0x0010| 27 ec 33 64 00 00 00 00| '.3d....| time: "Mon, 10 Apr 2023 10:59:51 UTC" (1681124391) 0x18-0x1f.7 (8)
+0x0020|f8 f9 42 02 00 00 00 00 |..B..... | check_point: "0/242F9F8" (37943800) 0x20-0x27.7 (8)
+ | | | check_point_copy{}: 0x28-0x7f.7 (88)
+0x0020| c0 f9 42 02 00 00 00 00| ..B.....| redo: "0/242F9C0" (37943744) 0x28-0x2f.7 (8)
+0x0030|01 00 00 00 |.... | this_time_line_id: 1 0x30-0x33.7 (4)
+0x0030| 01 00 00 00 | .... | prev_time_line_id: 1 0x34-0x37.7 (4)
+0x0030| 01 | . | full_page_writes: 1 0x38-0x38.7 (1)
+0x0030| 00 00 00 00 00 00 00| .......| hole1: 0 0x39-0x3f.7 (7)
+0x0040|ea 02 00 00 00 00 00 00 |........ | next_xid: 746 0x40-0x47.7 (8)
+0x0040| 00 60 00 00 | .`.. | next_oid: 24576 0x48-0x4b.7 (4)
+0x0040| 01 00 00 00| ....| next_multi: 1 0x4c-0x4f.7 (4)
+0x0050|00 00 00 00 |.... | next_multi_offset: 0 0x50-0x53.7 (4)
+0x0050| cc 02 00 00 | .... | oldest_xid: 716 0x54-0x57.7 (4)
+0x0050| 01 00 00 00 | .... | oldest_xid_db: 1 0x58-0x5b.7 (4)
+0x0050| 01 00 00 00| ....| oldest_multi: 1 0x5c-0x5f.7 (4)
+0x0060|01 00 00 00 |.... | oldest_multi_db: 1 0x60-0x63.7 (4)
+0x0060| 00 00 00 00 | .... | hole2: 0 0x64-0x67.7 (4)
+0x0060| 27 ec 33 64 00 00 00 00| '.3d....| time: "Mon, 10 Apr 2023 10:59:51 UTC" (1681124391) 0x68-0x6f.7 (8)
+0x0070|00 00 00 00 |.... | oldest_commit_ts_xid: 0 0x70-0x73.7 (4)
+0x0070| 00 00 00 00 | .... | newest_commit_ts_xid: 0 0x74-0x77.7 (4)
+0x0070| ea 02 00 00 | .... | oldest_active_xid: 746 0x78-0x7b.7 (4)
+0x0070| 00 00 00 00| ....| padding0: 0 0x7c-0x7f.7 (4)
+0x0080|e8 03 00 00 00 00 00 00 |........ | unlogged_lsn: "0/3E8" (1000) 0x80-0x87.7 (8)
+0x0080| 00 00 00 00 00 00 00 00| ........| min_recovery_point: "0/0" (0) 0x88-0x8f.7 (8)
+0x0090|00 00 00 00 |.... | min_recovery_point_tli: 0 0x90-0x93.7 (4)
+0x0090| 00 00 00 00 | .... | hole3: 0 0x94-0x97.7 (4)
+0x0090| 00 00 00 00 00 00 00 00| ........| backup_start_point: "0/0" (0) 0x98-0x9f.7 (8)
+0x00a0|00 00 00 00 00 00 00 00 |........ | backup_end_point: "0/0" (0) 0xa0-0xa7.7 (8)
+0x00a0| 00 | . | backup_end_required: 0 0xa8-0xa8.7 (1)
+0x00a0| 00 00 00 | ... | hole4: 0 0xa9-0xab.7 (3)
+0x00a0| 01 00 00 00| ....| wal_level: "WAL_LEVEL_REPLICA" (1) 0xac-0xaf.7 (4)
+0x00b0|00 |. | wal_log_hints: 0 0xb0-0xb0.7 (1)
+0x00b0| 00 00 00 | ... | hole5: 0 0xb1-0xb3.7 (3)
+0x00b0| e8 03 00 00 | .... | max_connections: 1000 0xb4-0xb7.7 (4)
+0x00b0| 08 00 00 00 | .... | max_worker_processes: 8 0xb8-0xbb.7 (4)
+0x00b0| 0a 00 00 00| ....| max_wal_senders: 10 0xbc-0xbf.7 (4)
+0x00c0|00 00 00 00 |.... | max_prepared_xacts: 0 0xc0-0xc3.7 (4)
+0x00c0| 40 00 00 00 | @... | max_locks_per_xact: 64 0xc4-0xc7.7 (4)
+0x00c0| 00 | . | track_commit_timestamp: 0 0xc8-0xc8.7 (1)
+0x00c0| 00 00 00 | ... | hole6: 0 0xc9-0xcb.7 (3)
+0x00c0| 08 00 00 00| ....| max_align: 8 0xcc-0xcf.7 (4)
+0x00d0|00 00 00 00 87 d6 32 41 |......2A | float_format: 1.234567e+06 0xd0-0xd7.7 (8)
+0x00d0| 00 20 00 00 | . .. | blcksz: 8192 0xd8-0xdb.7 (4)
+0x00d0| 00 00 02 00| ....| relseg_size: 131072 0xdc-0xdf.7 (4)
+0x00e0|00 20 00 00 |. .. | xlog_blcksz: 8192 0xe0-0xe3.7 (4)
+0x00e0| 00 00 00 01 | .... | xlog_seg_size: 16777216 0xe4-0xe7.7 (4)
+0x00e0| 40 00 00 00 | @... | name_data_len: 64 0xe8-0xeb.7 (4)
+0x00e0| 20 00 00 00| ...| index_max_keys: 32 0xec-0xef.7 (4)
+0x00f0|cc 07 00 00 |.... | toast_max_chunk_size: 1996 0xf0-0xf3.7 (4)
+0x00f0| 00 08 00 00 | .... | loblksize: 2048 0xf4-0xf7.7 (4)
+0x00f0| 01 | . | float8_by_val: 1 0xf8-0xf8.7 (1)
+0x00f0| 00 00 00 | ... | hole7: 0 0xf9-0xfb.7 (3)
+0x00f0| 01 00 00 00| ....| data_checksum_version: 1 0xfc-0xff.7 (4)
+0x0100|77 a5 b6 b0 15 ae 34 8a e2 a1 87 a2 0e 81 df 5c|w.....4........\| mock_authentication_nonce: "77a5b6b015ae348ae2a187a20e81df5c2d061053e3bc79e..." (raw bits) 0x100-0x11f.7 (32)
+0x0110|2d 06 10 53 e3 bc 79 e3 04 a7 64 df 23 57 d6 b0|-..S..y...d.#W..|
+0x0120|d9 db d0 cd |.... | crc: 3453017049 0x120-0x123.7 (4)
+0x0120| 00 00 00 00 | .... | padding1: 0 0x124-0x127.7 (4)
+0x0120| 00 00 00 00 00 00 00 00| ........| unused: raw bits 0x128-0x1fff.7 (7896)
+0x0130|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
+* |until 0x1fff.7 (end) (7896) | |
diff --git a/format/postgres/testdata/how_to.md b/format/postgres/testdata/how_to.md
new file mode 100644
index 000000000..0cfb0646b
--- /dev/null
+++ b/format/postgres/testdata/how_to.md
@@ -0,0 +1,133 @@
+## How to generate PostgreSQL test data
+
+### 1) install postgres
+Use this links to add repository and install PostgreSQL:
+- https://www.postgresql.org/download/linux/
+- https://www.postgresql.org/download/linux/redhat/
+- https://www.postgresql.org/download/linux/debian/
+
+You may install PostgreSQL with OS repository. But it may contains not all versions of PostgreSQL.
+
+### 2) use default intallation location of postgres.
+If you don't want default location.
+You may remove cluster and init it again.
+
+\# Detect PGDATA location:
+```shell
+ps aux | grep postgre
+
+postgres 887 0.0 0.0 4334456 13608 ? Ss 07:48 0:00 /usr/pgsql-14/bin/postmaster -D /u02/data
+```
+Result is:
+- `/u02/data` - is PGDATA location
+- `/usr/pgsql-14/bin` - location of PostgreSQL bin
+
+### 3) init tables
+
+\# use postgres user
+```shell
+sudo su postgres
+```
+
+\# then init pgbench tables
+```shell
+/usr/pgsql-14/bin/pgbench -i
+```
+
+\# run simple test
+```shell
+/usr/pgsql-14/bin/pgbench -T 60 -j 100
+```
+
+### 4) run commands in psql
+
+\# start psql
+```shell
+/usr/pgsql-14/bin/psql
+```
+
+\# display tables
+```psql
+\dt+
+
+Schema | Name | Type | Owner | Persistence | Access method | Size | Description
+--------+------------------+-------+----------+-------------+---------------+--------+-------------
+public | pgbench_accounts | table | postgres | permanent | heap | 13 MB |
+public | pgbench_branches | table | postgres | permanent | heap | 40 kB |
+public | pgbench_history | table | postgres | permanent | heap | 968 kB |
+public | pgbench_tellers | table | postgres | permanent | heap | 40 kB |
+```
+
+\# run CHECKPOINT to avoid partially written data
+```psql
+CHECKPOINT;
+```
+
+\# detect location of tables
+```psql
+SELECT pg_relation_filepath('pgbench_history');
+pg_relation_filepath
+----------------------
+base/13746/24599
+```
+
+`base/13746/24599` - location of table in PGDATA
+
+### 5) use root account to copy table file
+
+\# login in root
+```shell
+sudo su
+```
+
+\# go to PGDATA
+```shell
+cd /u02/data
+```
+
+\# copy table file
+```shell
+cp base/13746/24599 /home/user
+```
+
+\# change persmissions
+```shell
+chwon user:user /home/user/24599
+chmod 644 /home/user/24599
+```
+
+### 6) Copy tables files to local with scp
+```shell
+scp user@192.168.0.100:~/24599 .
+```
+
+### 7) You may want to cut 2 pages (8192 * 2) from table
+```shell
+head -c 16384 ./245991 > ./24599_2pages
+```
+
+### 8) Locate pg_control file
+`global/pg_control` inside PGDATA
+
+### 9) Locate btree index
+Get info about index:
+```psql
+\d pgbench_accounts
+ Table "public.pgbench_accounts"
+ Column | Type | Collation | Nullable | Default
+----------+---------------+-----------+----------+---------
+ aid | integer | | not null |
+ bid | integer | | |
+ abalance | integer | | |
+ filler | character(84) | | |
+Indexes:
+ "pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
+```
+Then get path of pgbench_accounts_pkey:
+```psql
+select pg_relation_filepath('pgbench_accounts_pkey');
+ pg_relation_filepath
+----------------------
+ base/13746/24596
+```
+`base/13746/24596` - is a path inside PGDATA of btree index pgbench_accounts_pkey.
\ No newline at end of file
diff --git a/pkg/decode/decode.go b/pkg/decode/decode.go
index 71052a28e..95e4a5d26 100644
--- a/pkg/decode/decode.go
+++ b/pkg/decode/decode.go
@@ -818,7 +818,6 @@ func (d *D) FieldGet(name string) *Value {
}
return nil
}
-
func (d *D) FieldMustGet(name string) *Value {
if v := d.FieldGet(name); v != nil {
return v
@@ -889,6 +888,12 @@ func (d *D) FieldRangeFn(name string, firstBit int64, nBits int64, fn func() *Va
return v
}
+func (d *D) AssertPos(pos int64) {
+ if d.Pos() != pos {
+ panic(DecoderError{Reason: fmt.Sprintf("expected bits position %d", pos), Pos: d.Pos()})
+ }
+}
+
func (d *D) AssertAtLeastBitsLeft(nBits int64) {
if d.Options.Force {
return