1 /*
2  * pg_filedump.h - PostgreSQL file dump utility for dumping and
3  *				   formatting heap (data), index and control files.
4  *
5  * Copyright (c) 2002-2010 Red Hat, Inc.
6  * Copyright (c) 2011-2021, PostgreSQL Global Development Group
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  * Original Author: Patrick Macdonald <patrickm@redhat.com>
23  */
24 
25 #define FD_VERSION	"14.0"		/* version ID of pg_filedump */
26 #define FD_PG_VERSION	"PostgreSQL 8.x .. 14.x"		/* PG version it works with */
27 
28 #include "postgres.h"
29 
30 #include <time.h>
31 #include <ctype.h>
32 
33 #include "access/gin_private.h"
34 #include "access/gist.h"
35 #include "access/hash.h"
36 #include "access/htup.h"
37 #include "access/htup_details.h"
38 #include "access/itup.h"
39 #include "access/nbtree.h"
40 #include "access/spgist_private.h"
41 #include "catalog/pg_control.h"
42 #include "storage/bufpage.h"
43 
44 /*	Options for Block formatting operations */
45 extern unsigned int blockOptions;
46 
47 typedef enum blockSwitches
48 {
49 	BLOCK_ABSOLUTE = 0x00000001,		/* -a: Absolute(vs Relative) addressing */
50 	BLOCK_BINARY = 0x00000002,			/* -b: Binary dump of block */
51 	BLOCK_FORMAT = 0x00000004,			/* -f: Formatted dump of blocks / control file */
52 	BLOCK_FORCED = 0x00000008,			/* -S: Block size forced */
53 	BLOCK_NO_INTR = 0x00000010,			/* -d: Dump straight blocks */
54 	BLOCK_RANGE = 0x00000020,			/* -R: Specific block range to dump */
55 	BLOCK_CHECKSUMS = 0x00000040,		/* -k: verify block checksums */
56 	BLOCK_DECODE = 0x00000080,			/* -D: Try to decode tuples */
57 	BLOCK_DECODE_TOAST = 0x00000100,	/* -t: Try to decode TOAST values */
58 	BLOCK_IGNORE_OLD = 0x00000200		/* -o: Decode old values */
59 } blockSwitches;
60 
61 /* Segment-related options */
62 extern unsigned int segmentOptions;
63 
64 typedef enum segmentSwitches
65 {
66 	SEGMENT_SIZE_FORCED = 0x00000001,	/* -s: Segment size forced */
67 	SEGMENT_NUMBER_FORCED = 0x00000002, /* -n: Segment number forced */
68 }			segmentSwitches;
69 
70 /* -R[start]:Block range start */
71 extern int	blockStart;
72 
73 /* -R[end]:Block range end */
74 extern int	blockEnd;
75 
76 /* Options for Item formatting operations */
77 extern unsigned int itemOptions;
78 
79 typedef enum itemSwitches
80 {
81 	ITEM_DETAIL = 0x00000001,	/* -i: Display interpreted items */
82 	ITEM_HEAP = 0x00000002,		/* -y: Blocks contain HeapTuple items */
83 	ITEM_INDEX = 0x00000004,	/* -x: Blocks contain IndexTuple items */
84 	ITEM_SPG_INNER = 0x00000008,	/* Blocks contain SpGistInnerTuple items */
85 	ITEM_SPG_LEAF = 0x00000010	/* Blocks contain SpGistLeafTuple items */
86 } itemSwitches;
87 
88 /* Options for Control File formatting operations */
89 extern unsigned int controlOptions;
90 
91 typedef enum controlSwitches
92 {
93 	CONTROL_DUMP = 0x00000001,	/* -c: Dump control file */
94 	CONTROL_FORMAT = BLOCK_FORMAT,	/* -f: Formatted dump of control file */
95 	CONTROL_FORCED = BLOCK_FORCED	/* -S: Block size forced */
96 } controlSwitches;
97 
98 /* Possible value types for the Special Section */
99 typedef enum specialSectionTypes
100 {
101 	SPEC_SECT_NONE,				/* No special section on block */
102 	SPEC_SECT_SEQUENCE,			/* Sequence info in special section */
103 	SPEC_SECT_INDEX_BTREE,		/* BTree index info in special section */
104 	SPEC_SECT_INDEX_HASH,		/* Hash index info in special section */
105 	SPEC_SECT_INDEX_GIST,		/* GIST index info in special section */
106 	SPEC_SECT_INDEX_GIN,		/* GIN index info in special section */
107 	SPEC_SECT_INDEX_SPGIST,		/* SP - GIST index info in special section */
108 	SPEC_SECT_ERROR_UNKNOWN,	/* Unknown error */
109 	SPEC_SECT_ERROR_BOUNDARY	/* Boundary error */
110 }			specialSectionTypes;
111 
112 extern unsigned int specialType;
113 
114 /* Possible return codes from option validation routine.
115  * pg_filedump doesn't do much with them now but maybe in
116  * the future... */
117 typedef enum optionReturnCodes
118 {
119 	OPT_RC_VALID,				/* All options are valid */
120 	OPT_RC_INVALID,				/* Improper option string */
121 	OPT_RC_FILE,				/* File problems */
122 	OPT_RC_DUPLICATE,			/* Duplicate option encountered */
123 	OPT_RC_COPYRIGHT			/* Copyright should be displayed */
124 }			optionReturnCodes;
125 
126 /* Simple macro to check for duplicate options and then set
127  * an option flag for later consumption */
128 #define SET_OPTION(_x,_y,_z) if (_x & _y)				\
129 							   {						\
130 								 rc = OPT_RC_DUPLICATE; \
131 								 duplicateSwitch = _z;	\
132 							   }						\
133 							 else						\
134 							   _x |= _y;
135 
136 #define SEQUENCE_MAGIC 0x1717	/* PostgreSQL defined magic number */
137 #define EOF_ENCOUNTERED (-1)	/* Indicator for partial read */
138 #define BYTES_PER_LINE 16		/* Format the binary 16 bytes per line */
139 
140 /* Constants for pg_relnode.map decoding */
141 #define RELMAPPER_MAGICSIZE   4
142 #define RELMAPPER_FILESIZE    512
143 /* From utils/cache/relmapper.c -- Maybe ask community to put
144  * these into utils/cache/relmapper.h? */
145 #define RELMAPPER_FILEMAGIC   0x592717
146 #define MAX_MAPPINGS          62
147 
148 extern char *fileName;
149 
150 /*
151  * Function Prototypes
152  */
153 unsigned int GetBlockSize(FILE *fp);
154 int DumpFileContents(unsigned int blockOptions, unsigned int controlOptions,
155 					 FILE *fp, unsigned int blockSize, int blockStart,
156 					int blockEnd, bool isToast, Oid toastOid,
157 					unsigned int toastExternalSize, char *toastValue);
158