LCOV - differential code coverage report
Current view: top level - src/bin/pg_dump - pg_restore.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 78.0 % 250 195 55 195
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 2 2 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * pg_restore.c
       4                 :  *  pg_restore is an utility extracting postgres database definitions
       5                 :  *  from a backup archive created by pg_dump using the archiver
       6                 :  *  interface.
       7                 :  *
       8                 :  *  pg_restore will read the backup archive and
       9                 :  *  dump out a script that reproduces
      10                 :  *  the schema of the database in terms of
      11                 :  *        user-defined types
      12                 :  *        user-defined functions
      13                 :  *        tables
      14                 :  *        indexes
      15                 :  *        aggregates
      16                 :  *        operators
      17                 :  *        ACL - grant/revoke
      18                 :  *
      19                 :  * the output script is SQL that is understood by PostgreSQL
      20                 :  *
      21                 :  * Basic process in a restore operation is:
      22                 :  *
      23                 :  *  Open the Archive and read the TOC.
      24                 :  *  Set flags in TOC entries, and *maybe* reorder them.
      25                 :  *  Generate script to stdout
      26                 :  *  Exit
      27                 :  *
      28                 :  * Copyright (c) 2000, Philip Warner
      29                 :  *      Rights are granted to use this software in any way so long
      30                 :  *      as this notice is not removed.
      31                 :  *
      32                 :  *  The author is not responsible for loss or damages that may
      33                 :  *  result from its use.
      34                 :  *
      35                 :  *
      36                 :  * IDENTIFICATION
      37                 :  *      src/bin/pg_dump/pg_restore.c
      38                 :  *
      39                 :  *-------------------------------------------------------------------------
      40                 :  */
      41                 : #include "postgres_fe.h"
      42                 : 
      43                 : #include <ctype.h>
      44                 : #ifdef HAVE_TERMIOS_H
      45                 : #include <termios.h>
      46                 : #endif
      47                 : 
      48                 : #include "dumputils.h"
      49                 : #include "fe_utils/option_utils.h"
      50                 : #include "getopt_long.h"
      51                 : #include "parallel.h"
      52                 : #include "pg_backup_utils.h"
      53                 : 
      54                 : static void usage(const char *progname);
      55                 : 
      56                 : int
      57 CBC          46 : main(int argc, char **argv)
      58                 : {
      59                 :     RestoreOptions *opts;
      60                 :     int         c;
      61                 :     int         exit_code;
      62              46 :     int         numWorkers = 1;
      63                 :     Archive    *AH;
      64                 :     char       *inputFileSpec;
      65                 :     static int  disable_triggers = 0;
      66                 :     static int  enable_row_security = 0;
      67                 :     static int  if_exists = 0;
      68                 :     static int  no_data_for_failed_tables = 0;
      69                 :     static int  outputNoTableAm = 0;
      70                 :     static int  outputNoTablespaces = 0;
      71                 :     static int  use_setsessauth = 0;
      72                 :     static int  no_comments = 0;
      73                 :     static int  no_publications = 0;
      74                 :     static int  no_security_labels = 0;
      75                 :     static int  no_subscriptions = 0;
      76                 :     static int  strict_names = 0;
      77                 : 
      78              46 :     struct option cmdopts[] = {
      79                 :         {"clean", 0, NULL, 'c'},
      80                 :         {"create", 0, NULL, 'C'},
      81                 :         {"data-only", 0, NULL, 'a'},
      82                 :         {"dbname", 1, NULL, 'd'},
      83                 :         {"exit-on-error", 0, NULL, 'e'},
      84                 :         {"exclude-schema", 1, NULL, 'N'},
      85                 :         {"file", 1, NULL, 'f'},
      86                 :         {"format", 1, NULL, 'F'},
      87                 :         {"function", 1, NULL, 'P'},
      88                 :         {"host", 1, NULL, 'h'},
      89                 :         {"index", 1, NULL, 'I'},
      90                 :         {"jobs", 1, NULL, 'j'},
      91                 :         {"list", 0, NULL, 'l'},
      92                 :         {"no-privileges", 0, NULL, 'x'},
      93                 :         {"no-acl", 0, NULL, 'x'},
      94                 :         {"no-owner", 0, NULL, 'O'},
      95                 :         {"no-reconnect", 0, NULL, 'R'},
      96                 :         {"port", 1, NULL, 'p'},
      97                 :         {"no-password", 0, NULL, 'w'},
      98                 :         {"password", 0, NULL, 'W'},
      99                 :         {"schema", 1, NULL, 'n'},
     100                 :         {"schema-only", 0, NULL, 's'},
     101                 :         {"superuser", 1, NULL, 'S'},
     102                 :         {"table", 1, NULL, 't'},
     103                 :         {"trigger", 1, NULL, 'T'},
     104                 :         {"use-list", 1, NULL, 'L'},
     105                 :         {"username", 1, NULL, 'U'},
     106                 :         {"verbose", 0, NULL, 'v'},
     107                 :         {"single-transaction", 0, NULL, '1'},
     108                 : 
     109                 :         /*
     110                 :          * the following options don't have an equivalent short option letter
     111                 :          */
     112                 :         {"disable-triggers", no_argument, &disable_triggers, 1},
     113                 :         {"enable-row-security", no_argument, &enable_row_security, 1},
     114                 :         {"if-exists", no_argument, &if_exists, 1},
     115                 :         {"no-data-for-failed-tables", no_argument, &no_data_for_failed_tables, 1},
     116                 :         {"no-table-access-method", no_argument, &outputNoTableAm, 1},
     117                 :         {"no-tablespaces", no_argument, &outputNoTablespaces, 1},
     118                 :         {"role", required_argument, NULL, 2},
     119                 :         {"section", required_argument, NULL, 3},
     120                 :         {"strict-names", no_argument, &strict_names, 1},
     121                 :         {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
     122                 :         {"no-comments", no_argument, &no_comments, 1},
     123                 :         {"no-publications", no_argument, &no_publications, 1},
     124                 :         {"no-security-labels", no_argument, &no_security_labels, 1},
     125                 :         {"no-subscriptions", no_argument, &no_subscriptions, 1},
     126                 : 
     127                 :         {NULL, 0, NULL, 0}
     128                 :     };
     129                 : 
     130              46 :     pg_logging_init(argv[0]);
     131              46 :     pg_logging_set_level(PG_LOG_WARNING);
     132              46 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
     133                 : 
     134              46 :     init_parallel_dump_utils();
     135                 : 
     136              46 :     opts = NewRestoreOptions();
     137                 : 
     138              46 :     progname = get_progname(argv[0]);
     139                 : 
     140              46 :     if (argc > 1)
     141                 :     {
     142              45 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
     143                 :         {
     144               1 :             usage(progname);
     145               1 :             exit_nicely(0);
     146                 :         }
     147              44 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
     148                 :         {
     149               3 :             puts("pg_restore (PostgreSQL) " PG_VERSION);
     150               3 :             exit_nicely(0);
     151                 :         }
     152                 :     }
     153                 : 
     154             148 :     while ((c = getopt_long(argc, argv, "acCd:ef:F:h:I:j:lL:n:N:Op:P:RsS:t:T:U:vwWx1",
     155             148 :                             cmdopts, NULL)) != -1)
     156                 :     {
     157             108 :         switch (c)
     158                 :         {
     159               2 :             case 'a':           /* Dump data only */
     160               2 :                 opts->dataOnly = 1;
     161               2 :                 break;
     162               3 :             case 'c':           /* clean (i.e., drop) schema prior to create */
     163               3 :                 opts->dropSchema = 1;
     164               3 :                 break;
     165               8 :             case 'C':
     166               8 :                 opts->createDB = 1;
     167               8 :                 break;
     168              11 :             case 'd':
     169              11 :                 opts->cparams.dbname = pg_strdup(optarg);
     170              11 :                 break;
     171               6 :             case 'e':
     172               6 :                 opts->exit_on_error = true;
     173               6 :                 break;
     174              23 :             case 'f':           /* output file name */
     175              23 :                 opts->filename = pg_strdup(optarg);
     176              23 :                 break;
     177               5 :             case 'F':
     178               5 :                 if (strlen(optarg) != 0)
     179               5 :                     opts->formatName = pg_strdup(optarg);
     180               5 :                 break;
     181               6 :             case 'h':
     182               6 :                 if (strlen(optarg) != 0)
     183               6 :                     opts->cparams.pghost = pg_strdup(optarg);
     184               6 :                 break;
     185                 : 
     186               9 :             case 'j':           /* number of restore jobs */
     187               9 :                 if (!option_parse_int(optarg, "-j/--jobs", 1,
     188                 :                                       PG_MAX_JOBS,
     189                 :                                       &numWorkers))
     190               1 :                     exit(1);
     191               8 :                 break;
     192                 : 
     193               5 :             case 'l':           /* Dump the TOC summary */
     194               5 :                 opts->tocSummary = 1;
     195               5 :                 break;
     196                 : 
     197 UBC           0 :             case 'L':           /* input TOC summary file name */
     198               0 :                 opts->tocFile = pg_strdup(optarg);
     199               0 :                 break;
     200                 : 
     201               0 :             case 'n':           /* Dump data for this schema only */
     202               0 :                 simple_string_list_append(&opts->schemaNames, optarg);
     203               0 :                 break;
     204                 : 
     205               0 :             case 'N':           /* Do not dump data for this schema */
     206               0 :                 simple_string_list_append(&opts->schemaExcludeNames, optarg);
     207               0 :                 break;
     208                 : 
     209               0 :             case 'O':
     210               0 :                 opts->noOwner = 1;
     211               0 :                 break;
     212                 : 
     213 CBC           6 :             case 'p':
     214               6 :                 if (strlen(optarg) != 0)
     215               6 :                     opts->cparams.pgport = pg_strdup(optarg);
     216               6 :                 break;
     217 UBC           0 :             case 'R':
     218                 :                 /* no-op, still accepted for backwards compatibility */
     219               0 :                 break;
     220               0 :             case 'P':           /* Function */
     221               0 :                 opts->selTypes = 1;
     222               0 :                 opts->selFunction = 1;
     223               0 :                 simple_string_list_append(&opts->functionNames, optarg);
     224               0 :                 break;
     225               0 :             case 'I':           /* Index */
     226               0 :                 opts->selTypes = 1;
     227               0 :                 opts->selIndex = 1;
     228               0 :                 simple_string_list_append(&opts->indexNames, optarg);
     229               0 :                 break;
     230               0 :             case 'T':           /* Trigger */
     231               0 :                 opts->selTypes = 1;
     232               0 :                 opts->selTrigger = 1;
     233               0 :                 simple_string_list_append(&opts->triggerNames, optarg);
     234               0 :                 break;
     235 CBC           1 :             case 's':           /* dump schema only */
     236               1 :                 opts->schemaOnly = 1;
     237               1 :                 break;
     238 UBC           0 :             case 'S':           /* Superuser username */
     239               0 :                 if (strlen(optarg) != 0)
     240               0 :                     opts->superuser = pg_strdup(optarg);
     241               0 :                 break;
     242               0 :             case 't':           /* Dump specified table(s) only */
     243               0 :                 opts->selTypes = 1;
     244               0 :                 opts->selTable = 1;
     245               0 :                 simple_string_list_append(&opts->tableNames, optarg);
     246               0 :                 break;
     247                 : 
     248 CBC           8 :             case 'U':
     249               8 :                 opts->cparams.username = pg_strdup(optarg);
     250               8 :                 break;
     251                 : 
     252              11 :             case 'v':           /* verbose */
     253              11 :                 opts->verbose = 1;
     254              11 :                 pg_logging_increase_verbosity();
     255              11 :                 break;
     256                 : 
     257 UBC           0 :             case 'w':
     258               0 :                 opts->cparams.promptPassword = TRI_NO;
     259               0 :                 break;
     260                 : 
     261               0 :             case 'W':
     262               0 :                 opts->cparams.promptPassword = TRI_YES;
     263               0 :                 break;
     264                 : 
     265               0 :             case 'x':           /* skip ACL dump */
     266               0 :                 opts->aclsSkip = 1;
     267               0 :                 break;
     268                 : 
     269 CBC           2 :             case '1':           /* Restore data in a single transaction */
     270               2 :                 opts->single_txn = true;
     271               2 :                 opts->exit_on_error = true;
     272               2 :                 break;
     273                 : 
     274               1 :             case 0:
     275                 : 
     276                 :                 /*
     277                 :                  * This covers the long options without a short equivalent.
     278                 :                  */
     279               1 :                 break;
     280                 : 
     281 UBC           0 :             case 2:             /* SET ROLE */
     282               0 :                 opts->use_role = pg_strdup(optarg);
     283               0 :                 break;
     284                 : 
     285               0 :             case 3:             /* section */
     286               0 :                 set_dump_section(optarg, &(opts->dumpSections));
     287               0 :                 break;
     288                 : 
     289 CBC           1 :             default:
     290                 :                 /* getopt_long already emitted a complaint */
     291               1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     292               1 :                 exit_nicely(1);
     293                 :         }
     294                 :     }
     295                 : 
     296                 :     /* Get file name from command line */
     297              40 :     if (optind < argc)
     298              32 :         inputFileSpec = argv[optind++];
     299                 :     else
     300               8 :         inputFileSpec = NULL;
     301                 : 
     302                 :     /* Complain if any arguments remain */
     303              40 :     if (optind < argc)
     304                 :     {
     305               1 :         pg_log_error("too many command-line arguments (first is \"%s\")",
     306                 :                      argv[optind]);
     307               1 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     308               1 :         exit_nicely(1);
     309                 :     }
     310                 : 
     311                 :     /* Complain if neither -f nor -d was specified (except if dumping TOC) */
     312              39 :     if (!opts->cparams.dbname && !opts->filename && !opts->tocSummary)
     313               1 :         pg_fatal("one of -d/--dbname and -f/--file must be specified");
     314                 : 
     315                 :     /* Should get at most one of -d and -f, else user is confused */
     316              38 :     if (opts->cparams.dbname)
     317                 :     {
     318              11 :         if (opts->filename)
     319                 :         {
     320               1 :             pg_log_error("options -d/--dbname and -f/--file cannot be used together");
     321               1 :             pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     322               1 :             exit_nicely(1);
     323                 :         }
     324              10 :         opts->useDB = 1;
     325                 :     }
     326                 : 
     327              37 :     if (opts->dataOnly && opts->schemaOnly)
     328               1 :         pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
     329                 : 
     330              36 :     if (opts->dataOnly && opts->dropSchema)
     331               1 :         pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
     332                 : 
     333                 :     /*
     334                 :      * -C is not compatible with -1, because we can't create a database inside
     335                 :      * a transaction block.
     336                 :      */
     337              35 :     if (opts->createDB && opts->single_txn)
     338               1 :         pg_fatal("options -C/--create and -1/--single-transaction cannot be used together");
     339                 : 
     340                 :     /* Can't do single-txn mode with multiple connections */
     341              34 :     if (opts->single_txn && numWorkers > 1)
     342               1 :         pg_fatal("cannot specify both --single-transaction and multiple jobs");
     343                 : 
     344              33 :     opts->disable_triggers = disable_triggers;
     345              33 :     opts->enable_row_security = enable_row_security;
     346              33 :     opts->noDataForFailedTables = no_data_for_failed_tables;
     347              33 :     opts->noTableAm = outputNoTableAm;
     348              33 :     opts->noTablespace = outputNoTablespaces;
     349              33 :     opts->use_setsessauth = use_setsessauth;
     350              33 :     opts->no_comments = no_comments;
     351              33 :     opts->no_publications = no_publications;
     352              33 :     opts->no_security_labels = no_security_labels;
     353              33 :     opts->no_subscriptions = no_subscriptions;
     354                 : 
     355              33 :     if (if_exists && !opts->dropSchema)
     356               1 :         pg_fatal("option --if-exists requires option -c/--clean");
     357              32 :     opts->if_exists = if_exists;
     358              32 :     opts->strict_names = strict_names;
     359                 : 
     360              32 :     if (opts->formatName)
     361                 :     {
     362               5 :         switch (opts->formatName[0])
     363                 :         {
     364               2 :             case 'c':
     365                 :             case 'C':
     366               2 :                 opts->format = archCustom;
     367               2 :                 break;
     368                 : 
     369               1 :             case 'd':
     370                 :             case 'D':
     371               1 :                 opts->format = archDirectory;
     372               1 :                 break;
     373                 : 
     374               1 :             case 't':
     375                 :             case 'T':
     376               1 :                 opts->format = archTar;
     377               1 :                 break;
     378                 : 
     379               1 :             default:
     380               1 :                 pg_fatal("unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"",
     381                 :                          opts->formatName);
     382                 :         }
     383                 :     }
     384                 : 
     385              31 :     AH = OpenArchive(inputFileSpec, opts->format);
     386                 : 
     387              31 :     SetArchiveOptions(AH, NULL, opts);
     388                 : 
     389                 :     /*
     390                 :      * We don't have a connection yet but that doesn't matter. The connection
     391                 :      * is initialized to NULL and if we terminate through exit_nicely() while
     392                 :      * it's still NULL, the cleanup function will just be a no-op.
     393                 :      */
     394              31 :     on_exit_close_archive(AH);
     395                 : 
     396                 :     /* Let the archiver know how noisy to be */
     397              31 :     AH->verbose = opts->verbose;
     398                 : 
     399                 :     /*
     400                 :      * Whether to keep submitting sql commands as "pg_restore ... | psql ... "
     401                 :      */
     402              31 :     AH->exit_on_error = opts->exit_on_error;
     403                 : 
     404              31 :     if (opts->tocFile)
     405 UBC           0 :         SortTocFromFile(AH);
     406                 : 
     407 CBC          31 :     AH->numWorkers = numWorkers;
     408                 : 
     409              31 :     if (opts->tocSummary)
     410               5 :         PrintTOCSummary(AH);
     411                 :     else
     412                 :     {
     413              26 :         ProcessArchiveRestoreOptions(AH);
     414              26 :         RestoreArchive(AH);
     415                 :     }
     416                 : 
     417                 :     /* done, print a summary of ignored errors */
     418              31 :     if (AH->n_errors)
     419 UBC           0 :         pg_log_warning("errors ignored on restore: %d", AH->n_errors);
     420                 : 
     421                 :     /* AH may be freed in CloseArchive? */
     422 CBC          31 :     exit_code = AH->n_errors ? 1 : 0;
     423                 : 
     424              31 :     CloseArchive(AH);
     425                 : 
     426              31 :     return exit_code;
     427                 : }
     428                 : 
     429                 : static void
     430               1 : usage(const char *progname)
     431                 : {
     432               1 :     printf(_("%s restores a PostgreSQL database from an archive created by pg_dump.\n\n"), progname);
     433               1 :     printf(_("Usage:\n"));
     434               1 :     printf(_("  %s [OPTION]... [FILE]\n"), progname);
     435                 : 
     436               1 :     printf(_("\nGeneral options:\n"));
     437               1 :     printf(_("  -d, --dbname=NAME        connect to database name\n"));
     438               1 :     printf(_("  -f, --file=FILENAME      output file name (- for stdout)\n"));
     439               1 :     printf(_("  -F, --format=c|d|t       backup file format (should be automatic)\n"));
     440               1 :     printf(_("  -l, --list               print summarized TOC of the archive\n"));
     441               1 :     printf(_("  -v, --verbose            verbose mode\n"));
     442               1 :     printf(_("  -V, --version            output version information, then exit\n"));
     443               1 :     printf(_("  -?, --help               show this help, then exit\n"));
     444                 : 
     445               1 :     printf(_("\nOptions controlling the restore:\n"));
     446               1 :     printf(_("  -a, --data-only              restore only the data, no schema\n"));
     447               1 :     printf(_("  -c, --clean                  clean (drop) database objects before recreating\n"));
     448               1 :     printf(_("  -C, --create                 create the target database\n"));
     449               1 :     printf(_("  -e, --exit-on-error          exit on error, default is to continue\n"));
     450               1 :     printf(_("  -I, --index=NAME             restore named index\n"));
     451               1 :     printf(_("  -j, --jobs=NUM               use this many parallel jobs to restore\n"));
     452               1 :     printf(_("  -L, --use-list=FILENAME      use table of contents from this file for\n"
     453                 :              "                               selecting/ordering output\n"));
     454               1 :     printf(_("  -n, --schema=NAME            restore only objects in this schema\n"));
     455               1 :     printf(_("  -N, --exclude-schema=NAME    do not restore objects in this schema\n"));
     456               1 :     printf(_("  -O, --no-owner               skip restoration of object ownership\n"));
     457               1 :     printf(_("  -P, --function=NAME(args)    restore named function\n"));
     458               1 :     printf(_("  -s, --schema-only            restore only the schema, no data\n"));
     459               1 :     printf(_("  -S, --superuser=NAME         superuser user name to use for disabling triggers\n"));
     460               1 :     printf(_("  -t, --table=NAME             restore named relation (table, view, etc.)\n"));
     461               1 :     printf(_("  -T, --trigger=NAME           restore named trigger\n"));
     462               1 :     printf(_("  -x, --no-privileges          skip restoration of access privileges (grant/revoke)\n"));
     463               1 :     printf(_("  -1, --single-transaction     restore as a single transaction\n"));
     464               1 :     printf(_("  --disable-triggers           disable triggers during data-only restore\n"));
     465               1 :     printf(_("  --enable-row-security        enable row security\n"));
     466               1 :     printf(_("  --if-exists                  use IF EXISTS when dropping objects\n"));
     467               1 :     printf(_("  --no-comments                do not restore comments\n"));
     468               1 :     printf(_("  --no-data-for-failed-tables  do not restore data of tables that could not be\n"
     469                 :              "                               created\n"));
     470               1 :     printf(_("  --no-publications            do not restore publications\n"));
     471               1 :     printf(_("  --no-security-labels         do not restore security labels\n"));
     472               1 :     printf(_("  --no-subscriptions           do not restore subscriptions\n"));
     473               1 :     printf(_("  --no-table-access-method     do not restore table access methods\n"));
     474               1 :     printf(_("  --no-tablespaces             do not restore tablespace assignments\n"));
     475               1 :     printf(_("  --section=SECTION            restore named section (pre-data, data, or post-data)\n"));
     476               1 :     printf(_("  --strict-names               require table and/or schema include patterns to\n"
     477                 :              "                               match at least one entity each\n"));
     478               1 :     printf(_("  --use-set-session-authorization\n"
     479                 :              "                               use SET SESSION AUTHORIZATION commands instead of\n"
     480                 :              "                               ALTER OWNER commands to set ownership\n"));
     481                 : 
     482               1 :     printf(_("\nConnection options:\n"));
     483               1 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
     484               1 :     printf(_("  -p, --port=PORT          database server port number\n"));
     485               1 :     printf(_("  -U, --username=NAME      connect as specified database user\n"));
     486               1 :     printf(_("  -w, --no-password        never prompt for password\n"));
     487               1 :     printf(_("  -W, --password           force password prompt (should happen automatically)\n"));
     488               1 :     printf(_("  --role=ROLENAME          do SET ROLE before restore\n"));
     489                 : 
     490               1 :     printf(_("\n"
     491                 :              "The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n"
     492                 :              "multiple times to select multiple objects.\n"));
     493               1 :     printf(_("\nIf no input file name is supplied, then standard input is used.\n\n"));
     494               1 :     printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     495               1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
     496               1 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a