Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * oid2name, a PostgreSQL app to map OIDs on the filesystem
3 : : * to table and database names.
4 : : *
5 : : * Originally by
6 : : * B. Palmer, bpalmer@crimelabs.net 1-17-2001
7 : : *
8 : : * contrib/oid2name/oid2name.c
9 : : */
10 : : #include "postgres_fe.h"
11 : :
12 : : #include "catalog/pg_class_d.h"
13 : : #include "common/connect.h"
14 : : #include "common/logging.h"
15 : : #include "common/string.h"
16 : : #include "getopt_long.h"
17 : : #include "libpq-fe.h"
18 : : #include "pg_getopt.h"
19 : :
20 : : /* an extensible array to keep track of elements to show */
21 : : typedef struct
22 : : {
23 : : char **array;
24 : : int num;
25 : : int alloc;
26 : : } eary;
27 : :
28 : : /* these are the opts structures for command line params */
29 : : struct options
30 : : {
31 : : eary *tables;
32 : : eary *oids;
33 : : eary *filenumbers;
34 : :
35 : : bool quiet;
36 : : bool systables;
37 : : bool indexes;
38 : : bool nodb;
39 : : bool extended;
40 : : bool tablespaces;
41 : :
42 : : char *dbname;
43 : : char *hostname;
44 : : char *port;
45 : : char *username;
46 : : const char *progname;
47 : : };
48 : :
49 : : /* function prototypes */
50 : : static void help(const char *progname);
51 : : void get_opts(int argc, char **argv, struct options *my_opts);
52 : : void add_one_elt(char *eltname, eary *eary);
53 : : char *get_comma_elts(eary *eary);
54 : : PGconn *sql_conn(struct options *my_opts);
55 : : int sql_exec(PGconn *conn, const char *todo, bool quiet);
56 : : void sql_exec_dumpalldbs(PGconn *conn, struct options *opts);
57 : : void sql_exec_dumpalltables(PGconn *conn, struct options *opts);
58 : : void sql_exec_searchtables(PGconn *conn, struct options *opts);
59 : : void sql_exec_dumpalltbspc(PGconn *conn, struct options *opts);
60 : :
61 : : /* function to parse command line options and check for some usage errors. */
62 : : void
2489 tgl@sss.pgh.pa.us 63 :CBC 3 : get_opts(int argc, char **argv, struct options *my_opts)
64 : : {
65 : : static struct option long_options[] = {
66 : : {"dbname", required_argument, NULL, 'd'},
67 : : {"host", required_argument, NULL, 'h'},
68 : : {"host", required_argument, NULL, 'H'}, /* deprecated */
69 : : {"filenode", required_argument, NULL, 'f'},
70 : : {"indexes", no_argument, NULL, 'i'},
71 : : {"oid", required_argument, NULL, 'o'},
72 : : {"port", required_argument, NULL, 'p'},
73 : : {"quiet", no_argument, NULL, 'q'},
74 : : {"tablespaces", no_argument, NULL, 's'},
75 : : {"system-objects", no_argument, NULL, 'S'},
76 : : {"table", required_argument, NULL, 't'},
77 : : {"username", required_argument, NULL, 'U'},
78 : : {"version", no_argument, NULL, 'V'},
79 : : {"extended", no_argument, NULL, 'x'},
80 : : {"help", no_argument, NULL, '?'},
81 : : {NULL, 0, NULL, 0}
82 : : };
83 : :
84 : : int c;
85 : : const char *progname;
86 : : int optindex;
87 : :
1682 michael@paquier.xyz 88 : 3 : pg_logging_init(argv[0]);
5525 peter_e@gmx.net 89 : 3 : progname = get_progname(argv[0]);
90 : :
91 : : /* set the defaults */
7149 tgl@sss.pgh.pa.us 92 : 3 : my_opts->quiet = false;
93 : 3 : my_opts->systables = false;
94 : 3 : my_opts->indexes = false;
95 : 3 : my_opts->nodb = false;
96 : 3 : my_opts->extended = false;
97 : 3 : my_opts->tablespaces = false;
7073 neilc@samurai.com 98 : 3 : my_opts->dbname = NULL;
99 : 3 : my_opts->hostname = NULL;
100 : 3 : my_opts->port = NULL;
101 : 3 : my_opts->username = NULL;
4302 rhaas@postgresql.org 102 : 3 : my_opts->progname = progname;
103 : :
5525 peter_e@gmx.net 104 [ + - ]: 3 : if (argc > 1)
105 : : {
106 [ + + - + ]: 3 : if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
107 : : {
108 : 1 : help(progname);
109 : 1 : exit(0);
110 : : }
111 [ + + - + ]: 2 : if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
112 : : {
113 : 1 : puts("oid2name (PostgreSQL) " PG_VERSION);
114 : 1 : exit(0);
115 : : }
116 : : }
117 : :
118 : : /* get opts */
2056 michael@paquier.xyz 119 [ + - ]: 1 : while ((c = getopt_long(argc, argv, "d:f:h:H:io:p:qsSt:U:x", long_options, &optindex)) != -1)
120 : : {
8424 bruce@momjian.us 121 [ - - - - : 1 : switch (c)
- - - - -
- - - + ]
122 : : {
123 : : /* specify the database */
8424 bruce@momjian.us 124 :UBC 0 : case 'd':
4212 tgl@sss.pgh.pa.us 125 : 0 : my_opts->dbname = pg_strdup(optarg);
8424 bruce@momjian.us 126 : 0 : break;
127 : :
128 : : /* specify one filenumber to show */
7149 tgl@sss.pgh.pa.us 129 : 0 : case 'f':
648 rhaas@postgresql.org 130 : 0 : add_one_elt(optarg, my_opts->filenumbers);
8424 bruce@momjian.us 131 : 0 : break;
132 : :
133 : : /* host to connect to */
2056 michael@paquier.xyz 134 : 0 : case 'H': /* deprecated */
135 : : case 'h':
4212 tgl@sss.pgh.pa.us 136 : 0 : my_opts->hostname = pg_strdup(optarg);
8424 bruce@momjian.us 137 : 0 : break;
138 : :
139 : : /* also display indexes */
2056 michael@paquier.xyz 140 : 0 : case 'i':
141 : 0 : my_opts->indexes = true;
142 : 0 : break;
143 : :
144 : : /* specify one Oid to show */
145 : 0 : case 'o':
146 : 0 : add_one_elt(optarg, my_opts->oids);
147 : 0 : break;
148 : :
149 : : /* port to connect to on remote host */
8424 bruce@momjian.us 150 : 0 : case 'p':
4212 tgl@sss.pgh.pa.us 151 : 0 : my_opts->port = pg_strdup(optarg);
8424 bruce@momjian.us 152 : 0 : break;
153 : :
154 : : /* don't show headers */
2056 michael@paquier.xyz 155 : 0 : case 'q':
156 : 0 : my_opts->quiet = true;
157 : 0 : break;
158 : :
159 : : /* dump tablespaces only */
160 : 0 : case 's':
161 : 0 : my_opts->tablespaces = true;
8424 bruce@momjian.us 162 : 0 : break;
163 : :
164 : : /* display system tables */
7149 tgl@sss.pgh.pa.us 165 : 0 : case 'S':
166 : 0 : my_opts->systables = true;
167 : 0 : break;
168 : :
169 : : /* specify one tablename to show */
2056 michael@paquier.xyz 170 : 0 : case 't':
171 : 0 : add_one_elt(optarg, my_opts->tables);
172 : 0 : break;
173 : :
174 : : /* username */
175 : 0 : case 'U':
176 : 0 : my_opts->username = pg_strdup(optarg);
7149 tgl@sss.pgh.pa.us 177 : 0 : break;
178 : :
179 : : /* display extra columns */
8424 bruce@momjian.us 180 : 0 : case 'x':
7149 tgl@sss.pgh.pa.us 181 : 0 : my_opts->extended = true;
182 : 0 : break;
183 : :
5525 peter_e@gmx.net 184 :CBC 1 : default:
185 : : /* getopt_long already emitted a complaint */
737 tgl@sss.pgh.pa.us 186 : 1 : pg_log_error_hint("Try \"%s --help\" for more information.", progname);
5525 peter_e@gmx.net 187 : 1 : exit(1);
188 : : }
189 : : }
190 : :
1690 peter@eisentraut.org 191 [ # # ]:UBC 0 : if (optind < argc)
192 : : {
737 tgl@sss.pgh.pa.us 193 : 0 : pg_log_error("too many command-line arguments (first is \"%s\")",
194 : : argv[optind]);
195 : 0 : pg_log_error_hint("Try \"%s --help\" for more information.", progname);
1690 peter@eisentraut.org 196 : 0 : exit(1);
197 : : }
8481 bruce@momjian.us 198 : 0 : }
199 : :
200 : : static void
5525 peter_e@gmx.net 201 :CBC 1 : help(const char *progname)
202 : : {
203 : 1 : printf("%s helps examining the file structure used by PostgreSQL.\n\n"
204 : : "Usage:\n"
205 : : " %s [OPTION]...\n"
206 : : "\nOptions:\n"
207 : : " -f, --filenode=FILENODE show info for table with given file node\n"
208 : : " -i, --indexes show indexes and sequences too\n"
209 : : " -o, --oid=OID show info for table with given OID\n"
210 : : " -q, --quiet quiet (don't show headers)\n"
211 : : " -s, --tablespaces show all tablespaces\n"
212 : : " -S, --system-objects show system objects too\n"
213 : : " -t, --table=TABLE show info for named table\n"
214 : : " -V, --version output version information, then exit\n"
215 : : " -x, --extended extended (show additional columns)\n"
216 : : " -?, --help show this help, then exit\n"
217 : : "\nConnection options:\n"
218 : : " -d, --dbname=DBNAME database to connect to\n"
219 : : " -h, --host=HOSTNAME database server host or socket directory\n"
220 : : " -H (same as -h, deprecated)\n"
221 : : " -p, --port=PORT database server port number\n"
222 : : " -U, --username=USERNAME connect as specified database user\n"
223 : : "\nThe default action is to show all database OIDs.\n\n"
224 : : "Report bugs to <%s>.\n"
225 : : "%s home page: <%s>\n",
226 : : progname, progname, PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_URL);
227 : 1 : }
228 : :
229 : : /*
230 : : * add_one_elt
231 : : *
232 : : * Add one element to a (possibly empty) eary struct.
233 : : */
234 : : void
5421 bruce@momjian.us 235 :UBC 0 : add_one_elt(char *eltname, eary *eary)
236 : : {
7149 tgl@sss.pgh.pa.us 237 [ # # ]: 0 : if (eary->alloc == 0)
238 : : {
5421 bruce@momjian.us 239 : 0 : eary ->alloc = 8;
4212 tgl@sss.pgh.pa.us 240 : 0 : eary ->array = (char **) pg_malloc(8 * sizeof(char *));
241 : : }
7149 242 [ # # ]: 0 : else if (eary->num >= eary->alloc)
243 : : {
5421 bruce@momjian.us 244 : 0 : eary ->alloc *= 2;
4212 tgl@sss.pgh.pa.us 245 : 0 : eary ->array = (char **) pg_realloc(eary->array,
2489 246 : 0 : eary->alloc * sizeof(char *));
247 : : }
248 : :
4212 249 : 0 : eary ->array[eary->num] = pg_strdup(eltname);
5421 bruce@momjian.us 250 : 0 : eary ->num++;
7149 tgl@sss.pgh.pa.us 251 : 0 : }
252 : :
253 : : /*
254 : : * get_comma_elts
255 : : *
256 : : * Return the elements of an eary as a (freshly allocated) single string, in
257 : : * single quotes, separated by commas and properly escaped for insertion in an
258 : : * SQL statement.
259 : : */
260 : : char *
5421 bruce@momjian.us 261 : 0 : get_comma_elts(eary *eary)
262 : : {
263 : : char *ret,
264 : : *ptr;
265 : : int i,
6756 266 : 0 : length = 0;
267 : :
7149 tgl@sss.pgh.pa.us 268 [ # # ]: 0 : if (eary->num == 0)
4212 269 : 0 : return pg_strdup("");
270 : :
271 : : /*
272 : : * PQescapeString wants 2 * length + 1 bytes of breath space. Add two
273 : : * chars per element for the single quotes and one for the comma.
274 : : */
7149 275 [ # # ]: 0 : for (i = 0; i < eary->num; i++)
276 : 0 : length += strlen(eary->array[i]);
277 : :
4212 278 : 0 : ret = (char *) pg_malloc(length * 2 + 4 * eary->num);
7149 279 : 0 : ptr = ret;
280 : :
281 [ # # ]: 0 : for (i = 0; i < eary->num; i++)
282 : : {
283 [ # # ]: 0 : if (i != 0)
284 : 0 : sprintf(ptr++, ",");
285 : 0 : sprintf(ptr++, "'");
286 : 0 : ptr += PQescapeString(ptr, eary->array[i], strlen(eary->array[i]));
287 : 0 : sprintf(ptr++, "'");
288 : : }
289 : :
290 : 0 : return ret;
291 : : }
292 : :
293 : : /* establish connection with database. */
294 : : PGconn *
2489 295 : 0 : sql_conn(struct options *my_opts)
296 : : {
297 : : PGconn *conn;
1319 298 : 0 : char *password = NULL;
299 : : bool new_pass;
300 : : PGresult *res;
301 : :
302 : : /*
303 : : * Start the connection. Loop until we have a password if requested by
304 : : * backend.
305 : : */
306 : : do
307 : : {
308 : : #define PARAMS_ARRAY_SIZE 7
309 : :
310 : : const char *keywords[PARAMS_ARRAY_SIZE];
311 : : const char *values[PARAMS_ARRAY_SIZE];
312 : :
4302 rhaas@postgresql.org 313 : 0 : keywords[0] = "host";
314 : 0 : values[0] = my_opts->hostname;
315 : 0 : keywords[1] = "port";
316 : 0 : values[1] = my_opts->port;
317 : 0 : keywords[2] = "user";
318 : 0 : values[2] = my_opts->username;
319 : 0 : keywords[3] = "password";
1319 tgl@sss.pgh.pa.us 320 : 0 : values[3] = password;
4302 rhaas@postgresql.org 321 : 0 : keywords[4] = "dbname";
322 : 0 : values[4] = my_opts->dbname;
323 : 0 : keywords[5] = "fallback_application_name";
324 : 0 : values[5] = my_opts->progname;
325 : 0 : keywords[6] = NULL;
326 : 0 : values[6] = NULL;
327 : :
5969 tgl@sss.pgh.pa.us 328 : 0 : new_pass = false;
4302 rhaas@postgresql.org 329 : 0 : conn = PQconnectdbParams(keywords, values, true);
330 : :
5969 tgl@sss.pgh.pa.us 331 [ # # ]: 0 : if (!conn)
737 332 : 0 : pg_fatal("could not connect to database %s",
333 : : my_opts->dbname);
334 : :
5969 335 [ # # # # ]: 0 : if (PQstatus(conn) == CONNECTION_BAD &&
336 [ # # ]: 0 : PQconnectionNeedsPassword(conn) &&
337 : : !password)
338 : : {
339 : 0 : PQfinish(conn);
1319 340 : 0 : password = simple_prompt("Password: ", false);
5969 341 : 0 : new_pass = true;
342 : : }
343 [ # # ]: 0 : } while (new_pass);
344 : :
345 : : /* check to see that the backend connection was successfully made */
346 [ # # ]: 0 : if (PQstatus(conn) == CONNECTION_BAD)
347 : : {
1178 348 : 0 : pg_log_error("%s", PQerrorMessage(conn));
8424 bruce@momjian.us 349 : 0 : PQfinish(conn);
350 : 0 : exit(1);
351 : : }
352 : :
2239 noah@leadboat.com 353 : 0 : res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL);
354 [ # # ]: 0 : if (PQresultStatus(res) != PGRES_TUPLES_OK)
355 : : {
1682 michael@paquier.xyz 356 : 0 : pg_log_error("could not clear search_path: %s",
357 : : PQerrorMessage(conn));
2239 noah@leadboat.com 358 : 0 : PQclear(res);
359 : 0 : PQfinish(conn);
737 tgl@sss.pgh.pa.us 360 : 0 : exit(1);
361 : : }
2239 noah@leadboat.com 362 : 0 : PQclear(res);
363 : :
364 : : /* return the conn if good */
8424 bruce@momjian.us 365 : 0 : return conn;
366 : : }
367 : :
368 : : /*
369 : : * Actual code to make call to the database and print the output data.
370 : : */
371 : : int
7149 tgl@sss.pgh.pa.us 372 : 0 : sql_exec(PGconn *conn, const char *todo, bool quiet)
373 : : {
374 : : PGresult *res;
375 : :
376 : : int nfields;
377 : : int nrows;
378 : : int i,
379 : : j,
380 : : l;
381 : : int *length;
382 : : char *pad;
383 : :
384 : : /* make the call */
8424 bruce@momjian.us 385 : 0 : res = PQexec(conn, todo);
386 : :
387 : : /* check and deal with errors */
388 [ # # # # ]: 0 : if (!res || PQresultStatus(res) > 2)
389 : : {
1682 michael@paquier.xyz 390 : 0 : pg_log_error("query failed: %s", PQerrorMessage(conn));
737 tgl@sss.pgh.pa.us 391 : 0 : pg_log_error_detail("Query was: %s", todo);
392 : :
8424 bruce@momjian.us 393 : 0 : PQclear(res);
394 : 0 : PQfinish(conn);
737 tgl@sss.pgh.pa.us 395 : 0 : exit(1);
396 : : }
397 : :
398 : : /* get the number of fields */
7149 399 : 0 : nrows = PQntuples(res);
400 : 0 : nfields = PQnfields(res);
401 : :
402 : : /* for each field, get the needed width */
4212 403 : 0 : length = (int *) pg_malloc(sizeof(int) * nfields);
7149 404 [ # # ]: 0 : for (j = 0; j < nfields; j++)
405 : 0 : length[j] = strlen(PQfname(res, j));
406 : :
407 [ # # ]: 0 : for (i = 0; i < nrows; i++)
408 : : {
409 [ # # ]: 0 : for (j = 0; j < nfields; j++)
410 : : {
6756 bruce@momjian.us 411 : 0 : l = strlen(PQgetvalue(res, i, j));
7149 tgl@sss.pgh.pa.us 412 [ # # ]: 0 : if (l > length[j])
413 : 0 : length[j] = strlen(PQgetvalue(res, i, j));
414 : : }
415 : : }
416 : :
417 : : /* print a header */
418 [ # # ]: 0 : if (!quiet)
419 : : {
420 [ # # ]: 0 : for (j = 0, l = 0; j < nfields; j++)
421 : : {
422 : 0 : fprintf(stdout, "%*s", length[j] + 2, PQfname(res, j));
423 : 0 : l += length[j] + 2;
424 : : }
425 : 0 : fprintf(stdout, "\n");
4212 426 : 0 : pad = (char *) pg_malloc(l + 1);
653 peter@eisentraut.org 427 : 0 : memset(pad, '-', l);
7149 tgl@sss.pgh.pa.us 428 : 0 : pad[l] = '\0';
429 : 0 : fprintf(stdout, "%s\n", pad);
430 : 0 : free(pad);
431 : : }
432 : :
433 : : /* for each row, dump the information */
434 [ # # ]: 0 : for (i = 0; i < nrows; i++)
435 : : {
436 [ # # ]: 0 : for (j = 0; j < nfields; j++)
437 : 0 : fprintf(stdout, "%*s", length[j] + 2, PQgetvalue(res, i, j));
438 : 0 : fprintf(stdout, "\n");
439 : : }
440 : :
441 : : /* cleanup */
8424 bruce@momjian.us 442 : 0 : PQclear(res);
7149 tgl@sss.pgh.pa.us 443 : 0 : free(length);
444 : :
8424 bruce@momjian.us 445 : 0 : return 0;
446 : : }
447 : :
448 : : /*
449 : : * Dump all databases. There are no system objects to worry about.
450 : : */
451 : : void
2489 tgl@sss.pgh.pa.us 452 : 0 : sql_exec_dumpalldbs(PGconn *conn, struct options *opts)
453 : : {
454 : : char todo[1024];
455 : :
456 : : /* get the oid and database name from the system pg_database table */
7100 457 : 0 : snprintf(todo, sizeof(todo),
458 : : "SELECT d.oid AS \"Oid\", datname AS \"Database Name\", "
459 : : "spcname AS \"Tablespace\" FROM pg_catalog.pg_database d JOIN pg_catalog.pg_tablespace t ON "
460 : : "(dattablespace = t.oid) ORDER BY 2");
461 : :
7149 462 : 0 : sql_exec(conn, todo, opts->quiet);
8481 bruce@momjian.us 463 : 0 : }
464 : :
465 : : /*
466 : : * Dump all tables, indexes and sequences in the current database.
467 : : */
468 : : void
2489 tgl@sss.pgh.pa.us 469 : 0 : sql_exec_dumpalltables(PGconn *conn, struct options *opts)
470 : : {
471 : : char todo[1024];
7149 472 : 0 : char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
473 : :
7100 474 : 0 : snprintf(todo, sizeof(todo),
475 : : "SELECT pg_catalog.pg_relation_filenode(c.oid) as \"Filenode\", relname as \"Table Name\" %s "
476 : : "FROM pg_catalog.pg_class c "
477 : : " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
478 : : " LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),"
479 : : " pg_catalog.pg_tablespace t "
480 : : "WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ","
481 : : CppAsString2(RELKIND_MATVIEW) "%s%s) AND "
482 : : " %s"
483 : : " t.oid = CASE"
484 : : " WHEN reltablespace <> 0 THEN reltablespace"
485 : : " ELSE dattablespace"
486 : : " END "
487 : : "ORDER BY relname",
7149 488 [ # # ]: 0 : opts->extended ? addfields : "",
2593 489 [ # # ]: 0 : opts->indexes ? "," CppAsString2(RELKIND_INDEX) "," CppAsString2(RELKIND_SEQUENCE) : "",
490 [ # # ]: 0 : opts->systables ? "," CppAsString2(RELKIND_TOASTVALUE) : "",
6108 491 [ # # ]: 0 : opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_toast' AND");
492 : :
7149 493 : 0 : sql_exec(conn, todo, opts->quiet);
8481 bruce@momjian.us 494 : 0 : }
495 : :
496 : : /*
497 : : * Show oid, filenumber, name, schema and tablespace for each of the
498 : : * given objects in the current database.
499 : : */
500 : : void
2489 tgl@sss.pgh.pa.us 501 : 0 : sql_exec_searchtables(PGconn *conn, struct options *opts)
502 : : {
503 : : char *todo;
504 : : char *qualifiers,
505 : : *ptr;
506 : : char *comma_oids,
507 : : *comma_filenumbers,
508 : : *comma_tables;
7149 509 : 0 : bool written = false;
510 : 0 : char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
511 : :
512 : : /* get tables qualifiers, whether names, filenumbers, or OIDs */
513 : 0 : comma_oids = get_comma_elts(opts->oids);
514 : 0 : comma_tables = get_comma_elts(opts->tables);
648 rhaas@postgresql.org 515 : 0 : comma_filenumbers = get_comma_elts(opts->filenumbers);
516 : :
517 : : /* 80 extra chars for SQL expression */
4212 tgl@sss.pgh.pa.us 518 : 0 : qualifiers = (char *) pg_malloc(strlen(comma_oids) + strlen(comma_tables) +
648 rhaas@postgresql.org 519 : 0 : strlen(comma_filenumbers) + 80);
7149 tgl@sss.pgh.pa.us 520 : 0 : ptr = qualifiers;
521 : :
522 [ # # ]: 0 : if (opts->oids->num > 0)
523 : : {
524 : 0 : ptr += sprintf(ptr, "c.oid IN (%s)", comma_oids);
525 : 0 : written = true;
526 : : }
648 rhaas@postgresql.org 527 [ # # ]: 0 : if (opts->filenumbers->num > 0)
528 : : {
7149 tgl@sss.pgh.pa.us 529 [ # # ]: 0 : if (written)
530 : 0 : ptr += sprintf(ptr, " OR ");
648 rhaas@postgresql.org 531 : 0 : ptr += sprintf(ptr, "pg_catalog.pg_relation_filenode(c.oid) IN (%s)",
532 : : comma_filenumbers);
7149 tgl@sss.pgh.pa.us 533 : 0 : written = true;
534 : : }
535 [ # # ]: 0 : if (opts->tables->num > 0)
536 : : {
537 [ # # ]: 0 : if (written)
538 : 0 : ptr += sprintf(ptr, " OR ");
539 : 0 : sprintf(ptr, "c.relname ~~ ANY (ARRAY[%s])", comma_tables);
540 : : }
541 : 0 : free(comma_oids);
542 : 0 : free(comma_tables);
648 rhaas@postgresql.org 543 : 0 : free(comma_filenumbers);
544 : :
545 : : /* now build the query */
1536 alvherre@alvh.no-ip. 546 : 0 : todo = psprintf("SELECT pg_catalog.pg_relation_filenode(c.oid) as \"Filenode\", relname as \"Table Name\" %s\n"
547 : : "FROM pg_catalog.pg_class c\n"
548 : : " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
549 : : " LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),\n"
550 : : " pg_catalog.pg_tablespace t\n"
551 : : "WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ","
552 : : CppAsString2(RELKIND_MATVIEW) ","
553 : : CppAsString2(RELKIND_INDEX) ","
554 : : CppAsString2(RELKIND_SEQUENCE) ","
555 : : CppAsString2(RELKIND_TOASTVALUE) ") AND\n"
556 : : " t.oid = CASE\n"
557 : : " WHEN reltablespace <> 0 THEN reltablespace\n"
558 : : " ELSE dattablespace\n"
559 : : " END AND\n"
560 : : " (%s)\n"
561 : : "ORDER BY relname\n",
3631 bruce@momjian.us 562 [ # # ]: 0 : opts->extended ? addfields : "",
563 : : qualifiers);
564 : :
7149 tgl@sss.pgh.pa.us 565 : 0 : free(qualifiers);
566 : :
567 : 0 : sql_exec(conn, todo, opts->quiet);
8481 bruce@momjian.us 568 : 0 : }
569 : :
570 : : void
2489 tgl@sss.pgh.pa.us 571 : 0 : sql_exec_dumpalltbspc(PGconn *conn, struct options *opts)
572 : : {
573 : : char todo[1024];
574 : :
7100 575 : 0 : snprintf(todo, sizeof(todo),
576 : : "SELECT oid AS \"Oid\", spcname as \"Tablespace Name\"\n"
577 : : "FROM pg_catalog.pg_tablespace");
578 : :
7149 579 : 0 : sql_exec(conn, todo, opts->quiet);
8481 bruce@momjian.us 580 : 0 : }
581 : :
582 : : int
8424 bruce@momjian.us 583 :CBC 3 : main(int argc, char **argv)
584 : : {
585 : : struct options *my_opts;
586 : : PGconn *pgconn;
587 : :
4212 tgl@sss.pgh.pa.us 588 : 3 : my_opts = (struct options *) pg_malloc(sizeof(struct options));
589 : :
590 : 3 : my_opts->oids = (eary *) pg_malloc(sizeof(eary));
591 : 3 : my_opts->tables = (eary *) pg_malloc(sizeof(eary));
648 rhaas@postgresql.org 592 : 3 : my_opts->filenumbers = (eary *) pg_malloc(sizeof(eary));
593 : :
7149 tgl@sss.pgh.pa.us 594 : 3 : my_opts->oids->num = my_opts->oids->alloc = 0;
595 : 3 : my_opts->tables->num = my_opts->tables->alloc = 0;
648 rhaas@postgresql.org 596 : 3 : my_opts->filenumbers->num = my_opts->filenumbers->alloc = 0;
597 : :
598 : : /* parse the opts */
8424 bruce@momjian.us 599 : 3 : get_opts(argc, argv, my_opts);
600 : :
7149 tgl@sss.pgh.pa.us 601 [ # # ]:UBC 0 : if (my_opts->dbname == NULL)
602 : : {
6872 603 : 0 : my_opts->dbname = "postgres";
7149 604 : 0 : my_opts->nodb = true;
605 : : }
606 : 0 : pgconn = sql_conn(my_opts);
607 : :
608 : : /* display only tablespaces */
609 [ # # ]: 0 : if (my_opts->tablespaces)
610 : : {
7977 bruce@momjian.us 611 [ # # ]: 0 : if (!my_opts->quiet)
7149 tgl@sss.pgh.pa.us 612 : 0 : printf("All tablespaces:\n");
613 : 0 : sql_exec_dumpalltbspc(pgconn, my_opts);
614 : :
615 : 0 : PQfinish(pgconn);
616 : 0 : exit(0);
617 : : }
618 : :
619 : : /* display the given elements in the database */
620 [ # # ]: 0 : if (my_opts->oids->num > 0 ||
621 [ # # ]: 0 : my_opts->tables->num > 0 ||
648 rhaas@postgresql.org 622 [ # # ]: 0 : my_opts->filenumbers->num > 0)
623 : : {
7977 bruce@momjian.us 624 [ # # ]: 0 : if (!my_opts->quiet)
7149 tgl@sss.pgh.pa.us 625 : 0 : printf("From database \"%s\":\n", my_opts->dbname);
626 : 0 : sql_exec_searchtables(pgconn, my_opts);
627 : :
628 : 0 : PQfinish(pgconn);
629 : 0 : exit(0);
630 : : }
631 : :
632 : : /* no elements given; dump the given database */
633 [ # # # # ]: 0 : if (my_opts->dbname && !my_opts->nodb)
634 : : {
7977 bruce@momjian.us 635 [ # # ]: 0 : if (!my_opts->quiet)
7149 tgl@sss.pgh.pa.us 636 : 0 : printf("From database \"%s\":\n", my_opts->dbname);
637 : 0 : sql_exec_dumpalltables(pgconn, my_opts);
638 : :
639 : 0 : PQfinish(pgconn);
640 : 0 : exit(0);
641 : : }
642 : :
643 : : /* no database either; dump all databases */
7977 bruce@momjian.us 644 [ # # ]: 0 : if (!my_opts->quiet)
645 : 0 : printf("All databases:\n");
7149 tgl@sss.pgh.pa.us 646 : 0 : sql_exec_dumpalldbs(pgconn, my_opts);
647 : :
648 : 0 : PQfinish(pgconn);
6118 649 : 0 : return 0;
650 : : }
|