diff --git a/doc/formats.md b/doc/formats.md index 0553b119..f272787c 100644 --- a/doc/formats.md +++ b/doc/formats.md @@ -579,84 +579,134 @@ $ fq -d msgpack torepr file.msgpack ### Options -|Name |Default|Description| -|- |- |-| -|`flavour`|default|PostgreSQL flavour: postgres, postgres13, pgpro...| -|`lsn` | |Current LSN for WAL, use "select pg_current_wal_lsn()"| +|Name |Default |Description| +|- |- |-| +|`flavour`|postgres14|PostgreSQL flavour: postgres14, pgproee14.., postgres10| ### Examples Decode file using pg_btree options ``` -$ fq -d pg_btree -o flavour="default" -o lsn="" . file +$ fq -d pg_btree -o flavour="postgres14" . file ``` Decode value as pg_btree ``` -... | pg_btree({flavour:"default",lsn:""}) +... | pg_btree({flavour:"postgres14"}) ``` +### 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 +``` + +### References +- https://www.postgresql.org/docs/current/storage-page-layout.html ## pg_control ### Options -|Name |Default|Description| -|- |- |-| -|`flavour`|default|PostgreSQL flavour: postgres, postgres13, pgpro...| -|`lsn` | |Current LSN for WAL, use "select pg_current_wal_lsn()"| +|Name |Default |Description| +|- |- |-| +|`flavour`|postgres14|PostgreSQL flavour: postgres14, pgproee14.., postgres10| ### Examples Decode file using pg_control options ``` -$ fq -d pg_control -o flavour="default" -o lsn="" . file +$ fq -d pg_control -o flavour="postgres14" . file ``` Decode value as pg_control ``` -... | pg_control({flavour:"default",lsn:""}) +... | pg_control({flavour:"postgres14"}) ``` +### 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 +``` + +### References +- https://github.com/postgres/postgres/blob/REL_14_2/src/include/catalog/pg_control.h ## pg_heap ### Options -|Name |Default|Description| -|- |- |-| -|`flavour`|default|PostgreSQL flavour: postgres, postgres13, pgpro...| -|`lsn` | |Current LSN for WAL, use "select pg_current_wal_lsn()"| +|Name |Default |Description| +|- |- |-| +|`flavour`|postgres14|PostgreSQL flavour: postgres14, pgproee14.., postgres10| ### Examples Decode file using pg_heap options ``` -$ fq -d pg_heap -o flavour="default" -o lsn="" . file +$ fq -d pg_heap -o flavour="postgres14" . file ``` Decode value as pg_heap ``` -... | pg_heap({flavour:"default",lsn:""}) +... | pg_heap({flavour:"postgres14"}) ``` +### 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 +``` + +### References +- https://www.postgresql.org/docs/current/storage-page-layout.html ## pg_wal ### Options -|Name |Default|Description| -|- |- |-| -|`flavour`|default|PostgreSQL flavour: postgres, postgres13, pgpro...| -|`lsn` | |Current LSN for WAL, use "select pg_current_wal_lsn()"| +|Name |Default |Description| +|- |- |-| +|`flavour`|postgres14|PostgreSQL flavour: postgres14, pgproee14.., postgres10| +|`lsn` | |Current LSN for WAL, use "select pg_current_wal_lsn()"| ### Examples Decode file using pg_wal options ``` -$ fq -d pg_wal -o flavour="default" -o lsn="" . file +$ fq -d pg_wal -o flavour="postgres14" -o lsn="" . file ``` Decode value as pg_wal ``` -... | pg_wal({flavour:"default",lsn:""}) +... | pg_wal({flavour:"postgres14",lsn:""}) ``` ## protobuf diff --git a/format/format.go b/format/format.go index ddb8aaed..218c3b74 100644 --- a/format/format.go +++ b/format/format.go @@ -324,6 +324,10 @@ type BitCoinBlockIn struct { } type PostgresIn struct { - Flavour string `doc:"PostgreSQL flavour: postgres, postgres13, pgpro..."` + Flavour string `doc:"PostgreSQL flavour: postgres14, pgproee14.., postgres10"` +} + +type PostgresWalIn struct { + Flavour string `doc:"PostgreSQL flavour: postgres14, pgproee14.., postgres10"` Lsn string `doc:"Current LSN for WAL, use \"select pg_current_wal_lsn()\""` } diff --git a/format/postgres/pg_btree.go b/format/postgres/pg_btree.go index ac62406b..829d4a2c 100644 --- a/format/postgres/pg_btree.go +++ b/format/postgres/pg_btree.go @@ -1,23 +1,28 @@ package postgres import ( + "embed" "github.com/wader/fq/format" "github.com/wader/fq/format/postgres/flavours/postgres14" "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(decode.Format{ Name: format.PG_BTREE, Description: "PostgreSQL btree index file", DecodeFn: decodePgBTree, DecodeInArg: format.PostgresIn{ - Flavour: "default", + Flavour: PG_FLAVOUR_POSTGRES14, }, RootArray: true, RootName: "pages", }) + interp.RegisterFS(pgBTreeFS) } func decodePgBTree(d *decode.D, in any) any { @@ -29,7 +34,7 @@ func decodePgBTree(d *decode.D, in any) any { } switch pgIn.Flavour { - case PG_FLAVOUR_POSTGRES14, PG_FLAVOUR_POSTGRES: + case PG_FLAVOUR_POSTGRES14: return postgres14.DecodePgBTree(d) } diff --git a/format/postgres/pg_btree.md b/format/postgres/pg_btree.md new file mode 100644 index 00000000..ae803e1b --- /dev/null +++ b/format/postgres/pg_btree.md @@ -0,0 +1,14 @@ +### 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 +``` + +### 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 index 7ea4c6cc..c959c18e 100644 --- a/format/postgres/pg_control.go +++ b/format/postgres/pg_control.go @@ -1,6 +1,7 @@ package postgres import ( + "embed" "github.com/wader/fq/format" "github.com/wader/fq/format/postgres/common" "github.com/wader/fq/format/postgres/flavours/pgpro11" @@ -20,15 +21,19 @@ import ( "github.com/wader/fq/pkg/interp" ) +//go:embed pg_control.md +var pgControlFS embed.FS + func init() { interp.RegisterFormat(decode.Format{ Name: format.PG_CONTROL, Description: "PostgreSQL control file", DecodeFn: decodePgControl, DecodeInArg: format.PostgresIn{ - Flavour: "default", + Flavour: PG_FLAVOUR_POSTGRES14, }, }) + interp.RegisterFS(pgControlFS) } //nolint:revive @@ -43,7 +48,6 @@ const ( //nolint:revive const ( - PG_FLAVOUR_POSTGRES = "postgres" PG_FLAVOUR_POSTGRES11 = "postgres11" PG_FLAVOUR_POSTGRES12 = "postgres12" PG_FLAVOUR_POSTGRES13 = "postgres13" @@ -74,7 +78,7 @@ func decodePgControl(d *decode.D, in any) any { return postgres12.DecodePgControl(d, in) case PG_FLAVOUR_POSTGRES13: return postgres13.DecodePgControl(d, in) - case PG_FLAVOUR_POSTGRES14, PG_FLAVOUR_POSTGRES: + case PG_FLAVOUR_POSTGRES14: return postgres14.DecodePgControl(d, in) case PG_FLAVOUR_PGPRO11: return pgpro11.DecodePgControl(d, in) diff --git a/format/postgres/pg_control.md b/format/postgres/pg_control.md new file mode 100644 index 00000000..7c319436 --- /dev/null +++ b/format/postgres/pg_control.md @@ -0,0 +1,14 @@ +### 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 +``` + +### 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 index c8a810cd..04d8fb90 100644 --- a/format/postgres/pg_heap.go +++ b/format/postgres/pg_heap.go @@ -1,6 +1,7 @@ package postgres import ( + "embed" "github.com/wader/fq/format" "github.com/wader/fq/format/postgres/flavours/pgpro11" "github.com/wader/fq/format/postgres/flavours/pgpro12" @@ -22,17 +23,21 @@ import ( // TO DO // oom kill on 1 GB file +//go:embed pg_heap.md +var pgHeapFS embed.FS + func init() { interp.RegisterFormat(decode.Format{ Name: format.PG_HEAP, Description: "PostgreSQL heap file", DecodeFn: decodePgheap, DecodeInArg: format.PostgresIn{ - Flavour: "default", + Flavour: PG_FLAVOUR_POSTGRES14, }, RootArray: true, RootName: "Pages", }) + interp.RegisterFS(pgHeapFS) } func decodePgheap(d *decode.D, in any) any { @@ -50,7 +55,7 @@ func decodePgheap(d *decode.D, in any) any { return postgres12.DecodeHeap(d) case PG_FLAVOUR_POSTGRES13: return postgres13.DecodeHeap(d) - case PG_FLAVOUR_POSTGRES14, PG_FLAVOUR_POSTGRES: + case PG_FLAVOUR_POSTGRES14: return postgres14.DecodeHeap(d) case PG_FLAVOUR_PGPROEE10: return pgproee10.DecodeHeap(d) diff --git a/format/postgres/pg_heap.md b/format/postgres/pg_heap.md new file mode 100644 index 00000000..1efe639c --- /dev/null +++ b/format/postgres/pg_heap.md @@ -0,0 +1,25 @@ +### 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 +``` + +### References +- https://www.postgresql.org/docs/current/storage-page-layout.html \ No newline at end of file diff --git a/format/postgres/pg_wal.go b/format/postgres/pg_wal.go index fcc0d459..3e6a2250 100644 --- a/format/postgres/pg_wal.go +++ b/format/postgres/pg_wal.go @@ -20,8 +20,8 @@ func init() { Name: format.PG_WAL, Description: "PostgreSQL write-ahead log file", DecodeFn: decodePgwal, - DecodeInArg: format.PostgresIn{ - Flavour: "default", + DecodeInArg: format.PostgresWalIn{ + Flavour: PG_FLAVOUR_POSTGRES14, Lsn: "", }, }) @@ -65,7 +65,7 @@ func XLogSegmentOffset(xLogPtr uint32) uint32 { func decodePgwal(d *decode.D, in any) any { d.Endian = decode.LittleEndian - pgIn, ok := in.(format.PostgresIn) + pgIn, ok := in.(format.PostgresWalIn) if !ok { d.Fatalf("DecodeInArg must be PostgresIn!\n") } @@ -82,7 +82,7 @@ func decodePgwal(d *decode.D, in any) any { switch pgIn.Flavour { //case PG_FLAVOUR_POSTGRES11: // return postgres11.DecodePgControl(d, in) - case PG_FLAVOUR_POSTGRES14, PG_FLAVOUR_POSTGRES: + case PG_FLAVOUR_POSTGRES14: return postgres14.DecodePgwal(d, maxOffset) //case PG_FLAVOUR_PGPROEE14: // return pgproee14.DecodePgControl(d, in) diff --git a/format/postgres/postgres.md b/format/postgres/postgres.md deleted file mode 100644 index 153ae019..00000000 --- a/format/postgres/postgres.md +++ /dev/null @@ -1,52 +0,0 @@ -PostgreSQL - -### 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 -``` - -### 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 -``` - -### 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 -``` - -### References -- https://github.com/postgres/postgres/blob/REL_14_2/src/include/catalog/pg_control.h -- https://www.postgresql.org/docs/current/storage-page-layout.html