LCOV - code coverage report
Current view: top level - contrib/oid2name - oid2name.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 38 257 14.8 %
Date: 2020-05-25 05:06:35 Functions: 3 11 27.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13