00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "postgres_fe.h"
00034
00035 #include <unistd.h>
00036 #include <ctype.h>
00037 #ifdef ENABLE_NLS
00038 #include <locale.h>
00039 #endif
00040 #ifdef HAVE_TERMIOS_H
00041 #include <termios.h>
00042 #endif
00043
00044 #include "getopt_long.h"
00045
00046 #include "access/attnum.h"
00047 #include "access/sysattr.h"
00048 #include "access/transam.h"
00049 #include "catalog/pg_cast.h"
00050 #include "catalog/pg_class.h"
00051 #include "catalog/pg_default_acl.h"
00052 #include "catalog/pg_event_trigger.h"
00053 #include "catalog/pg_largeobject.h"
00054 #include "catalog/pg_largeobject_metadata.h"
00055 #include "catalog/pg_proc.h"
00056 #include "catalog/pg_trigger.h"
00057 #include "catalog/pg_type.h"
00058 #include "libpq/libpq-fs.h"
00059
00060 #include "pg_backup_archiver.h"
00061 #include "pg_backup_db.h"
00062 #include "pg_backup_utils.h"
00063 #include "dumputils.h"
00064 #include "parallel.h"
00065
00066 extern char *optarg;
00067 extern int optind,
00068 opterr;
00069
00070
00071 typedef struct
00072 {
00073 const char *descr;
00074 Oid classoid;
00075 Oid objoid;
00076 int objsubid;
00077 } CommentItem;
00078
00079 typedef struct
00080 {
00081 const char *provider;
00082 const char *label;
00083 Oid classoid;
00084 Oid objoid;
00085 int objsubid;
00086 } SecLabelItem;
00087
00088
00089 bool g_verbose;
00090
00091
00092
00093 bool schemaOnly;
00094 bool dataOnly;
00095 int dumpSections;
00096 bool aclsSkip;
00097 const char *lockWaitTimeout;
00098
00099
00100 static const char *username_subquery;
00101
00102
00103 static Oid g_last_builtin_oid;
00104
00105
00106
00107
00108
00109
00110
00111 static SimpleStringList schema_include_patterns = {NULL, NULL};
00112 static SimpleOidList schema_include_oids = {NULL, NULL};
00113 static SimpleStringList schema_exclude_patterns = {NULL, NULL};
00114 static SimpleOidList schema_exclude_oids = {NULL, NULL};
00115
00116 static SimpleStringList table_include_patterns = {NULL, NULL};
00117 static SimpleOidList table_include_oids = {NULL, NULL};
00118 static SimpleStringList table_exclude_patterns = {NULL, NULL};
00119 static SimpleOidList table_exclude_oids = {NULL, NULL};
00120 static SimpleStringList tabledata_exclude_patterns = {NULL, NULL};
00121 static SimpleOidList tabledata_exclude_oids = {NULL, NULL};
00122
00123
00124 static bool include_everything = true;
00125
00126 char g_opaque_type[10];
00127
00128
00129 char g_comment_start[10];
00130 char g_comment_end[10];
00131
00132 static const CatalogId nilCatalogId = {0, 0};
00133
00134
00135 static int binary_upgrade = 0;
00136 static int disable_dollar_quoting = 0;
00137 static int dump_inserts = 0;
00138 static int column_inserts = 0;
00139 static int no_security_labels = 0;
00140 static int no_synchronized_snapshots = 0;
00141 static int no_unlogged_table_data = 0;
00142 static int serializable_deferrable = 0;
00143
00144
00145 static void help(const char *progname);
00146 static void setup_connection(Archive *AH, const char *dumpencoding,
00147 char *use_role);
00148 static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
00149 static void expand_schema_name_patterns(Archive *fout,
00150 SimpleStringList *patterns,
00151 SimpleOidList *oids);
00152 static void expand_table_name_patterns(Archive *fout,
00153 SimpleStringList *patterns,
00154 SimpleOidList *oids);
00155 static NamespaceInfo *findNamespace(Archive *fout, Oid nsoid, Oid objoid);
00156 static void dumpTableData(Archive *fout, TableDataInfo *tdinfo);
00157 static void refreshMatViewData(Archive *fout, TableDataInfo *tdinfo);
00158 static void guessConstraintInheritance(TableInfo *tblinfo, int numTables);
00159 static void dumpComment(Archive *fout, const char *target,
00160 const char *namespace, const char *owner,
00161 CatalogId catalogId, int subid, DumpId dumpId);
00162 static int findComments(Archive *fout, Oid classoid, Oid objoid,
00163 CommentItem **items);
00164 static int collectComments(Archive *fout, CommentItem **items);
00165 static void dumpSecLabel(Archive *fout, const char *target,
00166 const char *namespace, const char *owner,
00167 CatalogId catalogId, int subid, DumpId dumpId);
00168 static int findSecLabels(Archive *fout, Oid classoid, Oid objoid,
00169 SecLabelItem **items);
00170 static int collectSecLabels(Archive *fout, SecLabelItem **items);
00171 static void dumpDumpableObject(Archive *fout, DumpableObject *dobj);
00172 static void dumpNamespace(Archive *fout, NamespaceInfo *nspinfo);
00173 static void dumpExtension(Archive *fout, ExtensionInfo *extinfo);
00174 static void dumpType(Archive *fout, TypeInfo *tyinfo);
00175 static void dumpBaseType(Archive *fout, TypeInfo *tyinfo);
00176 static void dumpEnumType(Archive *fout, TypeInfo *tyinfo);
00177 static void dumpRangeType(Archive *fout, TypeInfo *tyinfo);
00178 static void dumpDomain(Archive *fout, TypeInfo *tyinfo);
00179 static void dumpCompositeType(Archive *fout, TypeInfo *tyinfo);
00180 static void dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo);
00181 static void dumpShellType(Archive *fout, ShellTypeInfo *stinfo);
00182 static void dumpProcLang(Archive *fout, ProcLangInfo *plang);
00183 static void dumpFunc(Archive *fout, FuncInfo *finfo);
00184 static void dumpCast(Archive *fout, CastInfo *cast);
00185 static void dumpOpr(Archive *fout, OprInfo *oprinfo);
00186 static void dumpOpclass(Archive *fout, OpclassInfo *opcinfo);
00187 static void dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo);
00188 static void dumpCollation(Archive *fout, CollInfo *convinfo);
00189 static void dumpConversion(Archive *fout, ConvInfo *convinfo);
00190 static void dumpRule(Archive *fout, RuleInfo *rinfo);
00191 static void dumpAgg(Archive *fout, AggInfo *agginfo);
00192 static void dumpTrigger(Archive *fout, TriggerInfo *tginfo);
00193 static void dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo);
00194 static void dumpTable(Archive *fout, TableInfo *tbinfo);
00195 static void dumpTableSchema(Archive *fout, TableInfo *tbinfo);
00196 static void dumpAttrDef(Archive *fout, AttrDefInfo *adinfo);
00197 static void dumpSequence(Archive *fout, TableInfo *tbinfo);
00198 static void dumpSequenceData(Archive *fout, TableDataInfo *tdinfo);
00199 static void dumpIndex(Archive *fout, IndxInfo *indxinfo);
00200 static void dumpConstraint(Archive *fout, ConstraintInfo *coninfo);
00201 static void dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo);
00202 static void dumpTSParser(Archive *fout, TSParserInfo *prsinfo);
00203 static void dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo);
00204 static void dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo);
00205 static void dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo);
00206 static void dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo);
00207 static void dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo);
00208 static void dumpUserMappings(Archive *fout,
00209 const char *servername, const char *namespace,
00210 const char *owner, CatalogId catalogId, DumpId dumpId);
00211 static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
00212
00213 static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
00214 const char *type, const char *name, const char *subname,
00215 const char *tag, const char *nspname, const char *owner,
00216 const char *acls);
00217
00218 static void getDependencies(Archive *fout);
00219 static void BuildArchiveDependencies(Archive *fout);
00220 static void findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
00221 DumpId **dependencies, int *nDeps, int *allocDeps);
00222
00223 static DumpableObject *createBoundaryObjects(void);
00224 static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
00225 DumpableObject *boundaryObjs);
00226
00227 static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
00228 static void getTableData(TableInfo *tblinfo, int numTables, bool oids);
00229 static void makeTableDataInfo(TableInfo *tbinfo, bool oids);
00230 static void buildMatViewRefreshDependencies(Archive *fout);
00231 static void getTableDataFKConstraints(void);
00232 static char *format_function_arguments(FuncInfo *finfo, char *funcargs);
00233 static char *format_function_arguments_old(Archive *fout,
00234 FuncInfo *finfo, int nallargs,
00235 char **allargtypes,
00236 char **argmodes,
00237 char **argnames);
00238 static char *format_function_signature(Archive *fout,
00239 FuncInfo *finfo, bool honor_quotes);
00240 static const char *convertRegProcReference(Archive *fout,
00241 const char *proc);
00242 static const char *convertOperatorReference(Archive *fout, const char *opr);
00243 static const char *convertTSFunction(Archive *fout, Oid funcOid);
00244 static Oid findLastBuiltinOid_V71(Archive *fout, const char *);
00245 static Oid findLastBuiltinOid_V70(Archive *fout);
00246 static void selectSourceSchema(Archive *fout, const char *schemaName);
00247 static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
00248 static char *myFormatType(const char *typname, int32 typmod);
00249 static void getBlobs(Archive *fout);
00250 static void dumpBlob(Archive *fout, BlobInfo *binfo);
00251 static int dumpBlobs(Archive *fout, void *arg);
00252 static void dumpDatabase(Archive *AH);
00253 static void dumpEncoding(Archive *AH);
00254 static void dumpStdStrings(Archive *AH);
00255 static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
00256 PQExpBuffer upgrade_buffer, Oid pg_type_oid);
00257 static bool binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
00258 PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
00259 static void binary_upgrade_set_pg_class_oids(Archive *fout,
00260 PQExpBuffer upgrade_buffer,
00261 Oid pg_class_oid, bool is_index);
00262 static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
00263 DumpableObject *dobj,
00264 const char *objlabel);
00265 static const char *getAttrName(int attrnum, TableInfo *tblInfo);
00266 static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
00267 static char *get_synchronized_snapshot(Archive *fout);
00268 static PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
00269 static void setupDumpWorker(Archive *AHX, RestoreOptions *ropt);
00270
00271
00272 int
00273 main(int argc, char **argv)
00274 {
00275 int c;
00276 const char *filename = NULL;
00277 const char *format = "p";
00278 const char *dbname = NULL;
00279 const char *pghost = NULL;
00280 const char *pgport = NULL;
00281 const char *username = NULL;
00282 const char *dumpencoding = NULL;
00283 bool oids = false;
00284 TableInfo *tblinfo;
00285 int numTables;
00286 DumpableObject **dobjs;
00287 int numObjs;
00288 DumpableObject *boundaryObjs;
00289 int i;
00290 int numWorkers = 1;
00291 enum trivalue prompt_password = TRI_DEFAULT;
00292 int compressLevel = -1;
00293 int plainText = 0;
00294 int outputClean = 0;
00295 int outputCreateDB = 0;
00296 bool outputBlobs = false;
00297 int outputNoOwner = 0;
00298 char *outputSuperuser = NULL;
00299 char *use_role = NULL;
00300 int optindex;
00301 RestoreOptions *ropt;
00302 ArchiveFormat archiveFormat = archUnknown;
00303 ArchiveMode archiveMode;
00304 Archive *fout;
00305
00306 static int disable_triggers = 0;
00307 static int outputNoTablespaces = 0;
00308 static int use_setsessauth = 0;
00309
00310 static struct option long_options[] = {
00311 {"data-only", no_argument, NULL, 'a'},
00312 {"blobs", no_argument, NULL, 'b'},
00313 {"clean", no_argument, NULL, 'c'},
00314 {"create", no_argument, NULL, 'C'},
00315 {"dbname", required_argument, NULL, 'd'},
00316 {"file", required_argument, NULL, 'f'},
00317 {"format", required_argument, NULL, 'F'},
00318 {"host", required_argument, NULL, 'h'},
00319 {"ignore-version", no_argument, NULL, 'i'},
00320 {"jobs", 1, NULL, 'j'},
00321 {"no-reconnect", no_argument, NULL, 'R'},
00322 {"oids", no_argument, NULL, 'o'},
00323 {"no-owner", no_argument, NULL, 'O'},
00324 {"port", required_argument, NULL, 'p'},
00325 {"schema", required_argument, NULL, 'n'},
00326 {"exclude-schema", required_argument, NULL, 'N'},
00327 {"schema-only", no_argument, NULL, 's'},
00328 {"superuser", required_argument, NULL, 'S'},
00329 {"table", required_argument, NULL, 't'},
00330 {"exclude-table", required_argument, NULL, 'T'},
00331 {"no-password", no_argument, NULL, 'w'},
00332 {"password", no_argument, NULL, 'W'},
00333 {"username", required_argument, NULL, 'U'},
00334 {"verbose", no_argument, NULL, 'v'},
00335 {"no-privileges", no_argument, NULL, 'x'},
00336 {"no-acl", no_argument, NULL, 'x'},
00337 {"compress", required_argument, NULL, 'Z'},
00338 {"encoding", required_argument, NULL, 'E'},
00339 {"help", no_argument, NULL, '?'},
00340 {"version", no_argument, NULL, 'V'},
00341
00342
00343
00344
00345 {"attribute-inserts", no_argument, &column_inserts, 1},
00346 {"binary-upgrade", no_argument, &binary_upgrade, 1},
00347 {"column-inserts", no_argument, &column_inserts, 1},
00348 {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
00349 {"disable-triggers", no_argument, &disable_triggers, 1},
00350 {"exclude-table-data", required_argument, NULL, 4},
00351 {"inserts", no_argument, &dump_inserts, 1},
00352 {"lock-wait-timeout", required_argument, NULL, 2},
00353 {"no-tablespaces", no_argument, &outputNoTablespaces, 1},
00354 {"quote-all-identifiers", no_argument, "e_all_identifiers, 1},
00355 {"role", required_argument, NULL, 3},
00356 {"section", required_argument, NULL, 5},
00357 {"serializable-deferrable", no_argument, &serializable_deferrable, 1},
00358 {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
00359 {"no-security-labels", no_argument, &no_security_labels, 1},
00360 {"no-synchronized-snapshots", no_argument, &no_synchronized_snapshots, 1},
00361 {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
00362
00363 {NULL, 0, NULL, 0}
00364 };
00365
00366 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
00367
00368
00369
00370
00371
00372 init_parallel_dump_utils();
00373
00374 g_verbose = false;
00375
00376 strcpy(g_comment_start, "-- ");
00377 g_comment_end[0] = '\0';
00378 strcpy(g_opaque_type, "opaque");
00379
00380 dataOnly = schemaOnly = false;
00381 dumpSections = DUMP_UNSECTIONED;
00382 lockWaitTimeout = NULL;
00383
00384 progname = get_progname(argv[0]);
00385
00386
00387 if (strcmp(progname, "pg_backup") == 0)
00388 format = "c";
00389
00390 if (argc > 1)
00391 {
00392 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
00393 {
00394 help(progname);
00395 exit_nicely(0);
00396 }
00397 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
00398 {
00399 puts("pg_dump (PostgreSQL) " PG_VERSION);
00400 exit_nicely(0);
00401 }
00402 }
00403
00404 while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:ij:K:n:N:oOp:RsS:t:T:U:vwWxZ:",
00405 long_options, &optindex)) != -1)
00406 {
00407 switch (c)
00408 {
00409 case 'a':
00410 dataOnly = true;
00411 break;
00412
00413 case 'b':
00414 outputBlobs = true;
00415 break;
00416
00417 case 'c':
00418 outputClean = 1;
00419 break;
00420
00421 case 'C':
00422 outputCreateDB = 1;
00423 break;
00424
00425 case 'd':
00426 dbname = pg_strdup(optarg);
00427 break;
00428
00429 case 'E':
00430 dumpencoding = pg_strdup(optarg);
00431 break;
00432
00433 case 'f':
00434 filename = pg_strdup(optarg);
00435 break;
00436
00437 case 'F':
00438 format = pg_strdup(optarg);
00439 break;
00440
00441 case 'h':
00442 pghost = pg_strdup(optarg);
00443 break;
00444
00445 case 'i':
00446
00447 break;
00448
00449 case 'j':
00450 numWorkers = atoi(optarg);
00451 break;
00452
00453 case 'n':
00454 simple_string_list_append(&schema_include_patterns, optarg);
00455 include_everything = false;
00456 break;
00457
00458 case 'N':
00459 simple_string_list_append(&schema_exclude_patterns, optarg);
00460 break;
00461
00462 case 'o':
00463 oids = true;
00464 break;
00465
00466 case 'O':
00467 outputNoOwner = 1;
00468 break;
00469
00470 case 'p':
00471 pgport = pg_strdup(optarg);
00472 break;
00473
00474 case 'R':
00475
00476 break;
00477
00478 case 's':
00479 schemaOnly = true;
00480 break;
00481
00482 case 'S':
00483 outputSuperuser = pg_strdup(optarg);
00484 break;
00485
00486 case 't':
00487 simple_string_list_append(&table_include_patterns, optarg);
00488 include_everything = false;
00489 break;
00490
00491 case 'T':
00492 simple_string_list_append(&table_exclude_patterns, optarg);
00493 break;
00494
00495 case 'U':
00496 username = pg_strdup(optarg);
00497 break;
00498
00499 case 'v':
00500 g_verbose = true;
00501 break;
00502
00503 case 'w':
00504 prompt_password = TRI_NO;
00505 break;
00506
00507 case 'W':
00508 prompt_password = TRI_YES;
00509 break;
00510
00511 case 'x':
00512 aclsSkip = true;
00513 break;
00514
00515 case 'Z':
00516 compressLevel = atoi(optarg);
00517 break;
00518
00519 case 0:
00520
00521 break;
00522
00523 case 2:
00524 lockWaitTimeout = pg_strdup(optarg);
00525 break;
00526
00527 case 3:
00528 use_role = pg_strdup(optarg);
00529 break;
00530
00531 case 4:
00532 simple_string_list_append(&tabledata_exclude_patterns, optarg);
00533 break;
00534
00535 case 5:
00536 set_dump_section(optarg, &dumpSections);
00537 break;
00538
00539 default:
00540 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00541 exit_nicely(1);
00542 }
00543 }
00544
00545
00546
00547
00548
00549 if (optind < argc && dbname == NULL)
00550 dbname = argv[optind++];
00551
00552
00553 if (optind < argc)
00554 {
00555 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
00556 progname, argv[optind]);
00557 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
00558 progname);
00559 exit_nicely(1);
00560 }
00561
00562
00563 if (column_inserts)
00564 dump_inserts = 1;
00565
00566 if (dataOnly && schemaOnly)
00567 exit_horribly(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
00568
00569 if (dataOnly && outputClean)
00570 exit_horribly(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
00571
00572 if (dump_inserts && oids)
00573 {
00574 write_msg(NULL, "options --inserts/--column-inserts and -o/--oids cannot be used together\n");
00575 write_msg(NULL, "(The INSERT command cannot set OIDs.)\n");
00576 exit_nicely(1);
00577 }
00578
00579
00580 archiveFormat = parseArchiveFormat(format, &archiveMode);
00581
00582
00583 if (archiveFormat == archNull)
00584 plainText = 1;
00585
00586
00587 if (compressLevel == -1)
00588 {
00589 if (archiveFormat == archCustom || archiveFormat == archDirectory)
00590 compressLevel = Z_DEFAULT_COMPRESSION;
00591 else
00592 compressLevel = 0;
00593 }
00594
00595
00596
00597
00598
00599
00600 if (numWorkers <= 0
00601 #ifdef WIN32
00602 || numWorkers > MAXIMUM_WAIT_OBJECTS
00603 #endif
00604 )
00605 exit_horribly(NULL, "%s: invalid number of parallel jobs\n", progname);
00606
00607
00608 if (archiveFormat != archDirectory && numWorkers > 1)
00609 exit_horribly(NULL, "parallel backup only supported by the directory format\n");
00610
00611
00612 fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode,
00613 setupDumpWorker);
00614
00615
00616 on_exit_close_archive(fout);
00617
00618 if (fout == NULL)
00619 exit_horribly(NULL, "could not open output file \"%s\" for writing\n", filename);
00620
00621
00622 fout->verbose = g_verbose;
00623
00624
00625
00626
00627
00628 fout->minRemoteVersion = 70000;
00629 fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
00630
00631 fout->numWorkers = numWorkers;
00632
00633
00634
00635
00636
00637 ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password);
00638 setup_connection(fout, dumpencoding, use_role);
00639
00640
00641
00642
00643
00644 if (fout->remoteVersion < 90100)
00645 no_security_labels = 1;
00646
00647
00648
00649
00650
00651 if (fout->remoteVersion >= 90000)
00652 {
00653 PGresult *res = ExecuteSqlQueryForSingleRow(fout, "SELECT pg_catalog.pg_is_in_recovery()");
00654
00655 if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
00656 {
00657
00658
00659
00660
00661 no_unlogged_table_data = true;
00662 }
00663 PQclear(res);
00664 }
00665
00666
00667 if (fout->remoteVersion >= 80100)
00668 username_subquery = "SELECT rolname FROM pg_catalog.pg_roles WHERE oid =";
00669 else if (fout->remoteVersion >= 70300)
00670 username_subquery = "SELECT usename FROM pg_catalog.pg_user WHERE usesysid =";
00671 else
00672 username_subquery = "SELECT usename FROM pg_user WHERE usesysid =";
00673
00674
00675 if (numWorkers > 1 && fout->remoteVersion < 90200
00676 && !no_synchronized_snapshots)
00677 exit_horribly(NULL,
00678 "Synchronized snapshots are not supported by this server version.\n"
00679 "Run with --no-synchronized-snapshots instead if you do not need\n"
00680 "synchronized snapshots.\n");
00681
00682
00683 if (fout->remoteVersion < 70300)
00684 {
00685 if (fout->remoteVersion >= 70100)
00686 g_last_builtin_oid = findLastBuiltinOid_V71(fout,
00687 PQdb(GetConnection(fout)));
00688 else
00689 g_last_builtin_oid = findLastBuiltinOid_V70(fout);
00690 if (g_verbose)
00691 write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid);
00692 }
00693
00694
00695 if (schema_include_patterns.head != NULL)
00696 {
00697 expand_schema_name_patterns(fout, &schema_include_patterns,
00698 &schema_include_oids);
00699 if (schema_include_oids.head == NULL)
00700 exit_horribly(NULL, "No matching schemas were found\n");
00701 }
00702 expand_schema_name_patterns(fout, &schema_exclude_patterns,
00703 &schema_exclude_oids);
00704
00705
00706
00707 if (table_include_patterns.head != NULL)
00708 {
00709 expand_table_name_patterns(fout, &table_include_patterns,
00710 &table_include_oids);
00711 if (table_include_oids.head == NULL)
00712 exit_horribly(NULL, "No matching tables were found\n");
00713 }
00714 expand_table_name_patterns(fout, &table_exclude_patterns,
00715 &table_exclude_oids);
00716
00717 expand_table_name_patterns(fout, &tabledata_exclude_patterns,
00718 &tabledata_exclude_oids);
00719
00720
00721
00722
00723
00724
00725
00726 if (include_everything && !schemaOnly)
00727 outputBlobs = true;
00728
00729
00730
00731
00732
00733 tblinfo = getSchemaData(fout, &numTables);
00734
00735 if (fout->remoteVersion < 80400)
00736 guessConstraintInheritance(tblinfo, numTables);
00737
00738 if (!schemaOnly)
00739 {
00740 getTableData(tblinfo, numTables, oids);
00741 buildMatViewRefreshDependencies(fout);
00742 if (dataOnly)
00743 getTableDataFKConstraints();
00744 }
00745
00746 if (outputBlobs)
00747 getBlobs(fout);
00748
00749
00750
00751
00752 getDependencies(fout);
00753
00754
00755 boundaryObjs = createBoundaryObjects();
00756
00757
00758 getDumpableObjects(&dobjs, &numObjs);
00759
00760
00761
00762
00763 addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 if (fout->remoteVersion >= 70300)
00775 sortDumpableObjectsByTypeName(dobjs, numObjs);
00776 else
00777 sortDumpableObjectsByTypeOid(dobjs, numObjs);
00778
00779
00780 if (archiveFormat == archDirectory && numWorkers > 1)
00781 sortDataAndIndexObjectsBySize(dobjs, numObjs);
00782
00783 sortDumpableObjects(dobjs, numObjs,
00784 boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
00785
00786
00787
00788
00789
00790
00791
00792 dumpEncoding(fout);
00793 dumpStdStrings(fout);
00794
00795
00796 if (include_everything && !dataOnly)
00797 dumpDatabase(fout);
00798
00799
00800 for (i = 0; i < numObjs; i++)
00801 dumpDumpableObject(fout, dobjs[i]);
00802
00803
00804
00805
00806 ropt = NewRestoreOptions();
00807 ropt->filename = filename;
00808 ropt->dropSchema = outputClean;
00809 ropt->dataOnly = dataOnly;
00810 ropt->schemaOnly = schemaOnly;
00811 ropt->dumpSections = dumpSections;
00812 ropt->aclsSkip = aclsSkip;
00813 ropt->superuser = outputSuperuser;
00814 ropt->createDB = outputCreateDB;
00815 ropt->noOwner = outputNoOwner;
00816 ropt->noTablespace = outputNoTablespaces;
00817 ropt->disable_triggers = disable_triggers;
00818 ropt->use_setsessauth = use_setsessauth;
00819
00820 if (compressLevel == -1)
00821 ropt->compression = 0;
00822 else
00823 ropt->compression = compressLevel;
00824
00825 ropt->suppressDumpWarnings = true;
00826
00827 SetArchiveRestoreOptions(fout, ropt);
00828
00829
00830
00831
00832
00833
00834 if (!plainText)
00835 BuildArchiveDependencies(fout);
00836
00837
00838
00839
00840
00841
00842
00843
00844 if (plainText)
00845 RestoreArchive(fout);
00846
00847 CloseArchive(fout);
00848
00849 exit_nicely(0);
00850 }
00851
00852
00853 static void
00854 help(const char *progname)
00855 {
00856 printf(_("%s dumps a database as a text file or to other formats.\n\n"), progname);
00857 printf(_("Usage:\n"));
00858 printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
00859
00860 printf(_("\nGeneral options:\n"));
00861 printf(_(" -f, --file=FILENAME output file or directory name\n"));
00862 printf(_(" -F, --format=c|d|t|p output file format (custom, directory, tar,\n"
00863 " plain text (default))\n"));
00864 printf(_(" -j, --jobs=NUM use this many parallel jobs to dump\n"));
00865 printf(_(" -v, --verbose verbose mode\n"));
00866 printf(_(" -V, --version output version information, then exit\n"));
00867 printf(_(" -Z, --compress=0-9 compression level for compressed formats\n"));
00868 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
00869 printf(_(" -?, --help show this help, then exit\n"));
00870
00871 printf(_("\nOptions controlling the output content:\n"));
00872 printf(_(" -a, --data-only dump only the data, not the schema\n"));
00873 printf(_(" -b, --blobs include large objects in dump\n"));
00874 printf(_(" -c, --clean clean (drop) database objects before recreating\n"));
00875 printf(_(" -C, --create include commands to create database in dump\n"));
00876 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
00877 printf(_(" -n, --schema=SCHEMA dump the named schema(s) only\n"));
00878 printf(_(" -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n"));
00879 printf(_(" -o, --oids include OIDs in dump\n"));
00880 printf(_(" -O, --no-owner skip restoration of object ownership in\n"
00881 " plain-text format\n"));
00882 printf(_(" -s, --schema-only dump only the schema, no data\n"));
00883 printf(_(" -S, --superuser=NAME superuser user name to use in plain-text format\n"));
00884 printf(_(" -t, --table=TABLE dump the named table(s) only\n"));
00885 printf(_(" -T, --exclude-table=TABLE do NOT dump the named table(s)\n"));
00886 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
00887 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
00888 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
00889 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
00890 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
00891 printf(_(" --exclude-table-data=TABLE do NOT dump data for the named table(s)\n"));
00892 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
00893 printf(_(" --no-security-labels do not dump security label assignments\n"));
00894 printf(_(" --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n"));
00895 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
00896 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
00897 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
00898 printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
00899 printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
00900 printf(_(" --use-set-session-authorization\n"
00901 " use SET SESSION AUTHORIZATION commands instead of\n"
00902 " ALTER OWNER commands to set ownership\n"));
00903
00904 printf(_("\nConnection options:\n"));
00905 printf(_(" -d, --dbname=DBNAME database to dump\n"));
00906 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
00907 printf(_(" -p, --port=PORT database server port number\n"));
00908 printf(_(" -U, --username=NAME connect as specified database user\n"));
00909 printf(_(" -w, --no-password never prompt for password\n"));
00910 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
00911 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
00912
00913 printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
00914 "variable value is used.\n\n"));
00915 printf(_("Report bugs to <[email protected]>.\n"));
00916 }
00917
00918 static void
00919 setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
00920 {
00921 PGconn *conn = GetConnection(AH);
00922 const char *std_strings;
00923
00924
00925
00926
00927
00928
00929
00930 if (dumpencoding)
00931 {
00932 if (PQsetClientEncoding(conn, dumpencoding) < 0)
00933 exit_horribly(NULL, "invalid client encoding \"%s\" specified\n",
00934 dumpencoding);
00935 }
00936
00937
00938
00939
00940
00941 AH->encoding = PQclientEncoding(conn);
00942
00943 std_strings = PQparameterStatus(conn, "standard_conforming_strings");
00944 AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
00945
00946
00947 if (!use_role && AH->use_role)
00948 use_role = AH->use_role;
00949
00950
00951 if (use_role && AH->remoteVersion >= 80100)
00952 {
00953 PQExpBuffer query = createPQExpBuffer();
00954
00955 appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
00956 ExecuteSqlStatement(AH, query->data);
00957 destroyPQExpBuffer(query);
00958
00959
00960 if (!AH->use_role)
00961 AH->use_role = strdup(use_role);
00962 }
00963
00964
00965 ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
00966
00967
00968 if (AH->remoteVersion >= 80400)
00969 ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
00970
00971
00972
00973
00974
00975 if (AH->remoteVersion >= 90000)
00976 ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
00977 else if (AH->remoteVersion >= 70400)
00978 ExecuteSqlStatement(AH, "SET extra_float_digits TO 2");
00979
00980
00981
00982
00983
00984 if (AH->remoteVersion >= 80300)
00985 ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
00986
00987
00988
00989
00990 if (AH->remoteVersion >= 70300)
00991 ExecuteSqlStatement(AH, "SET statement_timeout = 0");
00992 if (AH->remoteVersion >= 90300)
00993 ExecuteSqlStatement(AH, "SET lock_timeout = 0");
00994
00995
00996
00997
00998 if (quote_all_identifiers && AH->remoteVersion >= 90100)
00999 ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
01000
01001
01002
01003
01004 ExecuteSqlStatement(AH, "BEGIN");
01005 if (AH->remoteVersion >= 90100)
01006 {
01007 if (serializable_deferrable)
01008 ExecuteSqlStatement(AH,
01009 "SET TRANSACTION ISOLATION LEVEL "
01010 "SERIALIZABLE, READ ONLY, DEFERRABLE");
01011 else
01012 ExecuteSqlStatement(AH,
01013 "SET TRANSACTION ISOLATION LEVEL "
01014 "REPEATABLE READ, READ ONLY");
01015 }
01016 else if (AH->remoteVersion >= 70400)
01017 {
01018
01019 ExecuteSqlStatement(AH,
01020 "SET TRANSACTION ISOLATION LEVEL "
01021 "SERIALIZABLE READ ONLY");
01022 }
01023 else
01024 ExecuteSqlStatement(AH,
01025 "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
01026
01027
01028
01029 if (AH->numWorkers > 1 && AH->remoteVersion >= 90200 && !no_synchronized_snapshots)
01030 {
01031 if (AH->sync_snapshot_id)
01032 {
01033 PQExpBuffer query = createPQExpBuffer();
01034
01035 appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT ");
01036 appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
01037 destroyPQExpBuffer(query);
01038 }
01039 else
01040 AH->sync_snapshot_id = get_synchronized_snapshot(AH);
01041 }
01042 }
01043
01044 static void
01045 setupDumpWorker(Archive *AHX, RestoreOptions *ropt)
01046 {
01047 setup_connection(AHX, NULL, NULL);
01048 }
01049
01050 static char *
01051 get_synchronized_snapshot(Archive *fout)
01052 {
01053 char *query = "SELECT pg_export_snapshot()";
01054 char *result;
01055 PGresult *res;
01056
01057 res = ExecuteSqlQueryForSingleRow(fout, query);
01058 result = strdup(PQgetvalue(res, 0, 0));
01059 PQclear(res);
01060
01061 return result;
01062 }
01063
01064 static ArchiveFormat
01065 parseArchiveFormat(const char *format, ArchiveMode *mode)
01066 {
01067 ArchiveFormat archiveFormat;
01068
01069 *mode = archModeWrite;
01070
01071 if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
01072 {
01073
01074 archiveFormat = archNull;
01075 *mode = archModeAppend;
01076 }
01077 else if (pg_strcasecmp(format, "c") == 0)
01078 archiveFormat = archCustom;
01079 else if (pg_strcasecmp(format, "custom") == 0)
01080 archiveFormat = archCustom;
01081 else if (pg_strcasecmp(format, "d") == 0)
01082 archiveFormat = archDirectory;
01083 else if (pg_strcasecmp(format, "directory") == 0)
01084 archiveFormat = archDirectory;
01085 else if (pg_strcasecmp(format, "p") == 0)
01086 archiveFormat = archNull;
01087 else if (pg_strcasecmp(format, "plain") == 0)
01088 archiveFormat = archNull;
01089 else if (pg_strcasecmp(format, "t") == 0)
01090 archiveFormat = archTar;
01091 else if (pg_strcasecmp(format, "tar") == 0)
01092 archiveFormat = archTar;
01093 else
01094 exit_horribly(NULL, "invalid output format \"%s\" specified\n", format);
01095 return archiveFormat;
01096 }
01097
01098
01099
01100
01101
01102 static void
01103 expand_schema_name_patterns(Archive *fout,
01104 SimpleStringList *patterns,
01105 SimpleOidList *oids)
01106 {
01107 PQExpBuffer query;
01108 PGresult *res;
01109 SimpleStringListCell *cell;
01110 int i;
01111
01112 if (patterns->head == NULL)
01113 return;
01114
01115 if (fout->remoteVersion < 70300)
01116 exit_horribly(NULL, "server version must be at least 7.3 to use schema selection switches\n");
01117
01118 query = createPQExpBuffer();
01119
01120
01121
01122
01123
01124
01125 for (cell = patterns->head; cell; cell = cell->next)
01126 {
01127 if (cell != patterns->head)
01128 appendPQExpBuffer(query, "UNION ALL\n");
01129 appendPQExpBuffer(query,
01130 "SELECT oid FROM pg_catalog.pg_namespace n\n");
01131 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
01132 false, NULL, "n.nspname", NULL, NULL);
01133 }
01134
01135 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
01136
01137 for (i = 0; i < PQntuples(res); i++)
01138 {
01139 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
01140 }
01141
01142 PQclear(res);
01143 destroyPQExpBuffer(query);
01144 }
01145
01146
01147
01148
01149
01150 static void
01151 expand_table_name_patterns(Archive *fout,
01152 SimpleStringList *patterns, SimpleOidList *oids)
01153 {
01154 PQExpBuffer query;
01155 PGresult *res;
01156 SimpleStringListCell *cell;
01157 int i;
01158
01159 if (patterns->head == NULL)
01160 return;
01161
01162 query = createPQExpBuffer();
01163
01164
01165
01166
01167
01168
01169 for (cell = patterns->head; cell; cell = cell->next)
01170 {
01171 if (cell != patterns->head)
01172 appendPQExpBuffer(query, "UNION ALL\n");
01173 appendPQExpBuffer(query,
01174 "SELECT c.oid"
01175 "\nFROM pg_catalog.pg_class c"
01176 "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace"
01177 "\nWHERE c.relkind in ('%c', '%c', '%c', '%c', '%c')\n",
01178 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
01179 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
01180 processSQLNamePattern(GetConnection(fout), query, cell->val, true,
01181 false, "n.nspname", "c.relname", NULL,
01182 "pg_catalog.pg_table_is_visible(c.oid)");
01183 }
01184
01185 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
01186
01187 for (i = 0; i < PQntuples(res); i++)
01188 {
01189 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
01190 }
01191
01192 PQclear(res);
01193 destroyPQExpBuffer(query);
01194 }
01195
01196
01197
01198
01199
01200 static void
01201 selectDumpableNamespace(NamespaceInfo *nsinfo)
01202 {
01203
01204
01205
01206
01207
01208 if (table_include_oids.head != NULL)
01209 nsinfo->dobj.dump = false;
01210 else if (schema_include_oids.head != NULL)
01211 nsinfo->dobj.dump = simple_oid_list_member(&schema_include_oids,
01212 nsinfo->dobj.catId.oid);
01213 else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
01214 strcmp(nsinfo->dobj.name, "information_schema") == 0)
01215 nsinfo->dobj.dump = false;
01216 else
01217 nsinfo->dobj.dump = true;
01218
01219
01220
01221
01222 if (nsinfo->dobj.dump &&
01223 simple_oid_list_member(&schema_exclude_oids,
01224 nsinfo->dobj.catId.oid))
01225 nsinfo->dobj.dump = false;
01226 }
01227
01228
01229
01230
01231
01232 static void
01233 selectDumpableTable(TableInfo *tbinfo)
01234 {
01235
01236
01237
01238
01239 if (table_include_oids.head != NULL)
01240 tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
01241 tbinfo->dobj.catId.oid);
01242 else
01243 tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump;
01244
01245
01246
01247
01248 if (tbinfo->dobj.dump &&
01249 simple_oid_list_member(&table_exclude_oids,
01250 tbinfo->dobj.catId.oid))
01251 tbinfo->dobj.dump = false;
01252 }
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 static void
01268 selectDumpableType(TypeInfo *tyinfo)
01269 {
01270
01271 if (OidIsValid(tyinfo->typrelid) &&
01272 tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
01273 {
01274 TableInfo *tytable = findTableByOid(tyinfo->typrelid);
01275
01276 tyinfo->dobj.objType = DO_DUMMY_TYPE;
01277 if (tytable != NULL)
01278 tyinfo->dobj.dump = tytable->dobj.dump;
01279 else
01280 tyinfo->dobj.dump = false;
01281 return;
01282 }
01283
01284
01285 if (tyinfo->isArray)
01286 {
01287 tyinfo->dobj.objType = DO_DUMMY_TYPE;
01288
01289
01290
01291
01292
01293
01294
01295 }
01296
01297
01298 if (!tyinfo->dobj.namespace->dobj.dump)
01299 tyinfo->dobj.dump = false;
01300
01301
01302 else if (!tyinfo->isDefined)
01303 tyinfo->dobj.dump = false;
01304
01305 else
01306 tyinfo->dobj.dump = true;
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 static void
01318 selectDumpableDefaultACL(DefaultACLInfo *dinfo)
01319 {
01320 if (dinfo->dobj.namespace)
01321 dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump;
01322 else
01323 dinfo->dobj.dump = include_everything;
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336 static void
01337 selectDumpableExtension(ExtensionInfo *extinfo)
01338 {
01339 if (binary_upgrade && extinfo->dobj.catId.oid < (Oid) FirstNormalObjectId)
01340 extinfo->dobj.dump = false;
01341 else
01342 extinfo->dobj.dump = include_everything;
01343 }
01344
01345
01346
01347
01348
01349
01350
01351 static void
01352 selectDumpableObject(DumpableObject *dobj)
01353 {
01354
01355
01356
01357
01358 if (dobj->namespace)
01359 dobj->dump = dobj->namespace->dobj.dump;
01360 else
01361 dobj->dump = true;
01362 }
01363
01364
01365
01366
01367
01368
01369
01370 static int
01371 dumpTableData_copy(Archive *fout, void *dcontext)
01372 {
01373 TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
01374 TableInfo *tbinfo = tdinfo->tdtable;
01375 const char *classname = tbinfo->dobj.name;
01376 const bool hasoids = tbinfo->hasoids;
01377 const bool oids = tdinfo->oids;
01378 PQExpBuffer q = createPQExpBuffer();
01379
01380
01381
01382
01383
01384 PQExpBuffer clistBuf = createPQExpBuffer();
01385 PGconn *conn = GetConnection(fout);
01386 PGresult *res;
01387 int ret;
01388 char *copybuf;
01389 const char *column_list;
01390
01391 if (g_verbose)
01392 write_msg(NULL, "dumping contents of table %s\n", classname);
01393
01394
01395
01396
01397
01398
01399
01400 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
01401
01402
01403
01404
01405
01406
01407
01408 if (fout->remoteVersion >= 70300)
01409 column_list = fmtCopyColumnList(tbinfo, clistBuf);
01410 else
01411 column_list = "";
01412
01413 if (oids && hasoids)
01414 {
01415 appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
01416 fmtQualifiedId(fout->remoteVersion,
01417 tbinfo->dobj.namespace->dobj.name,
01418 classname),
01419 column_list);
01420 }
01421 else if (tdinfo->filtercond)
01422 {
01423
01424 appendPQExpBufferStr(q, "COPY (SELECT ");
01425
01426 if (strlen(column_list) > 2)
01427 {
01428 appendPQExpBufferStr(q, column_list + 1);
01429 q->data[q->len - 1] = ' ';
01430 }
01431 else
01432 appendPQExpBufferStr(q, "* ");
01433 appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
01434 fmtQualifiedId(fout->remoteVersion,
01435 tbinfo->dobj.namespace->dobj.name,
01436 classname),
01437 tdinfo->filtercond);
01438 }
01439 else
01440 {
01441 appendPQExpBuffer(q, "COPY %s %s TO stdout;",
01442 fmtQualifiedId(fout->remoteVersion,
01443 tbinfo->dobj.namespace->dobj.name,
01444 classname),
01445 column_list);
01446 }
01447 res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
01448 PQclear(res);
01449 destroyPQExpBuffer(clistBuf);
01450
01451 for (;;)
01452 {
01453 ret = PQgetCopyData(conn, ©buf, 0);
01454
01455 if (ret < 0)
01456 break;
01457
01458 if (copybuf)
01459 {
01460 WriteData(fout, copybuf, ret);
01461 PQfreemem(copybuf);
01462 }
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509 }
01510 archprintf(fout, "\\.\n\n\n");
01511
01512 if (ret == -2)
01513 {
01514
01515 write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname);
01516 write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
01517 write_msg(NULL, "The command was: %s\n", q->data);
01518 exit_nicely(1);
01519 }
01520
01521
01522 res = PQgetResult(conn);
01523 if (PQresultStatus(res) != PGRES_COMMAND_OK)
01524 {
01525 write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n", classname);
01526 write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
01527 write_msg(NULL, "The command was: %s\n", q->data);
01528 exit_nicely(1);
01529 }
01530 PQclear(res);
01531
01532 destroyPQExpBuffer(q);
01533 return 1;
01534 }
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544 static int
01545 dumpTableData_insert(Archive *fout, void *dcontext)
01546 {
01547 TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
01548 TableInfo *tbinfo = tdinfo->tdtable;
01549 const char *classname = tbinfo->dobj.name;
01550 PQExpBuffer q = createPQExpBuffer();
01551 PGresult *res;
01552 int tuple;
01553 int nfields;
01554 int field;
01555
01556
01557
01558
01559
01560
01561
01562 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
01563
01564 if (fout->remoteVersion >= 70100)
01565 {
01566 appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
01567 "SELECT * FROM ONLY %s",
01568 fmtQualifiedId(fout->remoteVersion,
01569 tbinfo->dobj.namespace->dobj.name,
01570 classname));
01571 }
01572 else
01573 {
01574 appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
01575 "SELECT * FROM %s",
01576 fmtQualifiedId(fout->remoteVersion,
01577 tbinfo->dobj.namespace->dobj.name,
01578 classname));
01579 }
01580 if (tdinfo->filtercond)
01581 appendPQExpBuffer(q, " %s", tdinfo->filtercond);
01582
01583 ExecuteSqlStatement(fout, q->data);
01584
01585 while (1)
01586 {
01587 res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
01588 PGRES_TUPLES_OK);
01589 nfields = PQnfields(res);
01590 for (tuple = 0; tuple < PQntuples(res); tuple++)
01591 {
01592 archprintf(fout, "INSERT INTO %s ", fmtId(classname));
01593 if (nfields == 0)
01594 {
01595
01596 archprintf(fout, "DEFAULT VALUES;\n");
01597 continue;
01598 }
01599 if (column_inserts)
01600 {
01601 resetPQExpBuffer(q);
01602 appendPQExpBuffer(q, "(");
01603 for (field = 0; field < nfields; field++)
01604 {
01605 if (field > 0)
01606 appendPQExpBuffer(q, ", ");
01607 appendPQExpBufferStr(q, fmtId(PQfname(res, field)));
01608 }
01609 appendPQExpBuffer(q, ") ");
01610 archputs(q->data, fout);
01611 }
01612 archprintf(fout, "VALUES (");
01613 for (field = 0; field < nfields; field++)
01614 {
01615 if (field > 0)
01616 archprintf(fout, ", ");
01617 if (PQgetisnull(res, tuple, field))
01618 {
01619 archprintf(fout, "NULL");
01620 continue;
01621 }
01622
01623
01624 switch (PQftype(res, field))
01625 {
01626 case INT2OID:
01627 case INT4OID:
01628 case INT8OID:
01629 case OIDOID:
01630 case FLOAT4OID:
01631 case FLOAT8OID:
01632 case NUMERICOID:
01633 {
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 const char *s = PQgetvalue(res, tuple, field);
01646
01647 if (strspn(s, "0123456789 +-eE.") == strlen(s))
01648 archprintf(fout, "%s", s);
01649 else
01650 archprintf(fout, "'%s'", s);
01651 }
01652 break;
01653
01654 case BITOID:
01655 case VARBITOID:
01656 archprintf(fout, "B'%s'",
01657 PQgetvalue(res, tuple, field));
01658 break;
01659
01660 case BOOLOID:
01661 if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
01662 archprintf(fout, "true");
01663 else
01664 archprintf(fout, "false");
01665 break;
01666
01667 default:
01668
01669 resetPQExpBuffer(q);
01670 appendStringLiteralAH(q,
01671 PQgetvalue(res, tuple, field),
01672 fout);
01673 archputs(q->data, fout);
01674 break;
01675 }
01676 }
01677 archprintf(fout, ");\n");
01678 }
01679
01680 if (PQntuples(res) <= 0)
01681 {
01682 PQclear(res);
01683 break;
01684 }
01685 PQclear(res);
01686 }
01687
01688 archprintf(fout, "\n\n");
01689
01690 ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
01691
01692 destroyPQExpBuffer(q);
01693 return 1;
01694 }
01695
01696
01697
01698
01699
01700
01701
01702
01703 static void
01704 dumpTableData(Archive *fout, TableDataInfo *tdinfo)
01705 {
01706 TableInfo *tbinfo = tdinfo->tdtable;
01707 PQExpBuffer copyBuf = createPQExpBuffer();
01708 PQExpBuffer clistBuf = createPQExpBuffer();
01709 DataDumperPtr dumpFn;
01710 char *copyStmt;
01711
01712 if (!dump_inserts)
01713 {
01714
01715 dumpFn = dumpTableData_copy;
01716
01717 appendPQExpBuffer(copyBuf, "COPY %s ",
01718 fmtId(tbinfo->dobj.name));
01719 appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n",
01720 fmtCopyColumnList(tbinfo, clistBuf),
01721 (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
01722 copyStmt = copyBuf->data;
01723 }
01724 else
01725 {
01726
01727 dumpFn = dumpTableData_insert;
01728 copyStmt = NULL;
01729 }
01730
01731
01732
01733
01734
01735
01736 ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
01737 tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name,
01738 NULL, tbinfo->rolname,
01739 false, "TABLE DATA", SECTION_DATA,
01740 "", "", copyStmt,
01741 &(tbinfo->dobj.dumpId), 1,
01742 dumpFn, tdinfo);
01743
01744 destroyPQExpBuffer(copyBuf);
01745 destroyPQExpBuffer(clistBuf);
01746 }
01747
01748
01749
01750
01751
01752
01753
01754
01755 static void
01756 refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
01757 {
01758 TableInfo *tbinfo = tdinfo->tdtable;
01759 PQExpBuffer q;
01760
01761
01762 if (!tbinfo->isscannable)
01763 return;
01764
01765 q = createPQExpBuffer();
01766
01767 appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
01768 fmtId(tbinfo->dobj.name));
01769
01770 ArchiveEntry(fout,
01771 tdinfo->dobj.catId,
01772 tdinfo->dobj.dumpId,
01773 tbinfo->dobj.name,
01774 tbinfo->dobj.namespace->dobj.name,
01775 NULL,
01776 tbinfo->rolname,
01777 false,
01778 "MATERIALIZED VIEW DATA",
01779 SECTION_POST_DATA,
01780 q->data,
01781 "",
01782 NULL,
01783 tdinfo->dobj.dependencies,
01784 tdinfo->dobj.nDeps,
01785 NULL,
01786 NULL);
01787
01788 destroyPQExpBuffer(q);
01789 }
01790
01791
01792
01793
01794
01795 static void
01796 getTableData(TableInfo *tblinfo, int numTables, bool oids)
01797 {
01798 int i;
01799
01800 for (i = 0; i < numTables; i++)
01801 {
01802 if (tblinfo[i].dobj.dump)
01803 makeTableDataInfo(&(tblinfo[i]), oids);
01804 }
01805 }
01806
01807
01808
01809
01810
01811
01812
01813 static void
01814 makeTableDataInfo(TableInfo *tbinfo, bool oids)
01815 {
01816 TableDataInfo *tdinfo;
01817
01818
01819
01820
01821
01822 if (tbinfo->dataObj != NULL)
01823 return;
01824
01825
01826 if (tbinfo->relkind == RELKIND_VIEW)
01827 return;
01828
01829 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
01830 return;
01831
01832
01833 if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
01834 no_unlogged_table_data)
01835 return;
01836
01837
01838 if (simple_oid_list_member(&tabledata_exclude_oids,
01839 tbinfo->dobj.catId.oid))
01840 return;
01841
01842
01843 tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
01844
01845 if (tbinfo->relkind == RELKIND_MATVIEW)
01846 tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
01847 else
01848 tdinfo->dobj.objType = DO_TABLE_DATA;
01849
01850
01851
01852
01853
01854 tdinfo->dobj.catId.tableoid = 0;
01855 tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
01856 AssignDumpId(&tdinfo->dobj);
01857 tdinfo->dobj.name = tbinfo->dobj.name;
01858 tdinfo->dobj.namespace = tbinfo->dobj.namespace;
01859 tdinfo->tdtable = tbinfo;
01860 tdinfo->oids = oids;
01861 tdinfo->filtercond = NULL;
01862 addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
01863
01864 tbinfo->dataObj = tdinfo;
01865 }
01866
01867
01868
01869
01870
01871
01872
01873
01874 static void
01875 buildMatViewRefreshDependencies(Archive *fout)
01876 {
01877 PQExpBuffer query;
01878 PGresult *res;
01879 int ntups,
01880 i;
01881 int i_classid,
01882 i_objid,
01883 i_refobjid;
01884
01885
01886 if (fout->remoteVersion < 90300)
01887 return;
01888
01889
01890 selectSourceSchema(fout, "pg_catalog");
01891
01892 query = createPQExpBuffer();
01893
01894 appendPQExpBuffer(query, "with recursive w as "
01895 "( "
01896 "select d1.objid, d2.refobjid, c2.relkind as refrelkind "
01897 "from pg_depend d1 "
01898 "join pg_class c1 on c1.oid = d1.objid "
01899 "and c1.relkind = 'm' "
01900 "join pg_rewrite r1 on r1.ev_class = d1.objid "
01901 "join pg_depend d2 on d2.classid = 'pg_rewrite'::regclass "
01902 "and d2.objid = r1.oid "
01903 "and d2.refobjid <> d1.objid "
01904 "join pg_class c2 on c2.oid = d2.refobjid "
01905 "and c2.relkind in ('m','v') "
01906 "where d1.classid = 'pg_class'::regclass "
01907 "union "
01908 "select w.objid, d3.refobjid, c3.relkind "
01909 "from w "
01910 "join pg_rewrite r3 on r3.ev_class = w.refobjid "
01911 "join pg_depend d3 on d3.classid = 'pg_rewrite'::regclass "
01912 "and d3.objid = r3.oid "
01913 "and d3.refobjid <> w.refobjid "
01914 "join pg_class c3 on c3.oid = d3.refobjid "
01915 "and c3.relkind in ('m','v') "
01916 ") "
01917 "select 'pg_class'::regclass::oid as classid, objid, refobjid "
01918 "from w "
01919 "where refrelkind = 'm'");
01920
01921 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
01922
01923 ntups = PQntuples(res);
01924
01925 i_classid = PQfnumber(res, "classid");
01926 i_objid = PQfnumber(res, "objid");
01927 i_refobjid = PQfnumber(res, "refobjid");
01928
01929 for (i = 0; i < ntups; i++)
01930 {
01931 CatalogId objId;
01932 CatalogId refobjId;
01933 DumpableObject *dobj;
01934 DumpableObject *refdobj;
01935 TableInfo *tbinfo;
01936 TableInfo *reftbinfo;
01937
01938 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
01939 objId.oid = atooid(PQgetvalue(res, i, i_objid));
01940 refobjId.tableoid = objId.tableoid;
01941 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
01942
01943 dobj = findObjectByCatalogId(objId);
01944 if (dobj == NULL)
01945 continue;
01946
01947 Assert(dobj->objType == DO_TABLE);
01948 tbinfo = (TableInfo *) dobj;
01949 Assert(tbinfo->relkind == RELKIND_MATVIEW);
01950 dobj = (DumpableObject *) tbinfo->dataObj;
01951 if (dobj == NULL)
01952 continue;
01953 Assert(dobj->objType == DO_REFRESH_MATVIEW);
01954
01955 refdobj = findObjectByCatalogId(refobjId);
01956 if (refdobj == NULL)
01957 continue;
01958
01959 Assert(refdobj->objType == DO_TABLE);
01960 reftbinfo = (TableInfo *) refdobj;
01961 Assert(reftbinfo->relkind == RELKIND_MATVIEW);
01962 refdobj = (DumpableObject *) reftbinfo->dataObj;
01963 if (refdobj == NULL)
01964 continue;
01965 Assert(refdobj->objType == DO_REFRESH_MATVIEW);
01966
01967 addObjectDependency(dobj, refdobj->dumpId);
01968
01969 if (!reftbinfo->isscannable)
01970 tbinfo->isscannable = false;
01971 }
01972
01973 PQclear(res);
01974
01975 destroyPQExpBuffer(query);
01976 }
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990 static void
01991 getTableDataFKConstraints(void)
01992 {
01993 DumpableObject **dobjs;
01994 int numObjs;
01995 int i;
01996
01997
01998 getDumpableObjects(&dobjs, &numObjs);
01999 for (i = 0; i < numObjs; i++)
02000 {
02001 if (dobjs[i]->objType == DO_FK_CONSTRAINT)
02002 {
02003 ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
02004 TableInfo *ftable;
02005
02006
02007 if (cinfo->contable == NULL ||
02008 cinfo->contable->dataObj == NULL)
02009 continue;
02010 ftable = findTableByOid(cinfo->confrelid);
02011 if (ftable == NULL ||
02012 ftable->dataObj == NULL)
02013 continue;
02014
02015
02016
02017
02018
02019 addObjectDependency(&cinfo->contable->dataObj->dobj,
02020 ftable->dataObj->dobj.dumpId);
02021 }
02022 }
02023 free(dobjs);
02024 }
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043 static void
02044 guessConstraintInheritance(TableInfo *tblinfo, int numTables)
02045 {
02046 int i,
02047 j,
02048 k;
02049
02050 for (i = 0; i < numTables; i++)
02051 {
02052 TableInfo *tbinfo = &(tblinfo[i]);
02053 int numParents;
02054 TableInfo **parents;
02055 TableInfo *parent;
02056
02057
02058 if (tbinfo->relkind == RELKIND_SEQUENCE ||
02059 tbinfo->relkind == RELKIND_VIEW)
02060 continue;
02061
02062
02063 if (!tbinfo->dobj.dump)
02064 continue;
02065
02066 numParents = tbinfo->numParents;
02067 parents = tbinfo->parents;
02068
02069 if (numParents == 0)
02070 continue;
02071
02072
02073 for (j = 0; j < tbinfo->ncheck; j++)
02074 {
02075 ConstraintInfo *constr;
02076
02077 constr = &(tbinfo->checkexprs[j]);
02078
02079 for (k = 0; k < numParents; k++)
02080 {
02081 int l;
02082
02083 parent = parents[k];
02084 for (l = 0; l < parent->ncheck; l++)
02085 {
02086 ConstraintInfo *pconstr = &(parent->checkexprs[l]);
02087
02088 if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
02089 {
02090 constr->conislocal = false;
02091 break;
02092 }
02093 }
02094 if (!constr->conislocal)
02095 break;
02096 }
02097 }
02098 }
02099 }
02100
02101
02102
02103
02104
02105
02106 static void
02107 dumpDatabase(Archive *fout)
02108 {
02109 PQExpBuffer dbQry = createPQExpBuffer();
02110 PQExpBuffer delQry = createPQExpBuffer();
02111 PQExpBuffer creaQry = createPQExpBuffer();
02112 PGconn *conn = GetConnection(fout);
02113 PGresult *res;
02114 int i_tableoid,
02115 i_oid,
02116 i_dba,
02117 i_encoding,
02118 i_collate,
02119 i_ctype,
02120 i_frozenxid,
02121 i_tablespace;
02122 CatalogId dbCatId;
02123 DumpId dbDumpId;
02124 const char *datname,
02125 *dba,
02126 *encoding,
02127 *collate,
02128 *ctype,
02129 *tablespace;
02130 uint32 frozenxid;
02131
02132 datname = PQdb(conn);
02133
02134 if (g_verbose)
02135 write_msg(NULL, "saving database definition\n");
02136
02137
02138 selectSourceSchema(fout, "pg_catalog");
02139
02140
02141 if (fout->remoteVersion >= 80400)
02142 {
02143 appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
02144 "(%s datdba) AS dba, "
02145 "pg_encoding_to_char(encoding) AS encoding, "
02146 "datcollate, datctype, datfrozenxid, "
02147 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
02148 "shobj_description(oid, 'pg_database') AS description "
02149
02150 "FROM pg_database "
02151 "WHERE datname = ",
02152 username_subquery);
02153 appendStringLiteralAH(dbQry, datname, fout);
02154 }
02155 else if (fout->remoteVersion >= 80200)
02156 {
02157 appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
02158 "(%s datdba) AS dba, "
02159 "pg_encoding_to_char(encoding) AS encoding, "
02160 "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
02161 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
02162 "shobj_description(oid, 'pg_database') AS description "
02163
02164 "FROM pg_database "
02165 "WHERE datname = ",
02166 username_subquery);
02167 appendStringLiteralAH(dbQry, datname, fout);
02168 }
02169 else if (fout->remoteVersion >= 80000)
02170 {
02171 appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
02172 "(%s datdba) AS dba, "
02173 "pg_encoding_to_char(encoding) AS encoding, "
02174 "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
02175 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace "
02176 "FROM pg_database "
02177 "WHERE datname = ",
02178 username_subquery);
02179 appendStringLiteralAH(dbQry, datname, fout);
02180 }
02181 else if (fout->remoteVersion >= 70100)
02182 {
02183 appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
02184 "(%s datdba) AS dba, "
02185 "pg_encoding_to_char(encoding) AS encoding, "
02186 "NULL AS datcollate, NULL AS datctype, "
02187 "0 AS datfrozenxid, "
02188 "NULL AS tablespace "
02189 "FROM pg_database "
02190 "WHERE datname = ",
02191 username_subquery);
02192 appendStringLiteralAH(dbQry, datname, fout);
02193 }
02194 else
02195 {
02196 appendPQExpBuffer(dbQry, "SELECT "
02197 "(SELECT oid FROM pg_class WHERE relname = 'pg_database') AS tableoid, "
02198 "oid, "
02199 "(%s datdba) AS dba, "
02200 "pg_encoding_to_char(encoding) AS encoding, "
02201 "NULL AS datcollate, NULL AS datctype, "
02202 "0 AS datfrozenxid, "
02203 "NULL AS tablespace "
02204 "FROM pg_database "
02205 "WHERE datname = ",
02206 username_subquery);
02207 appendStringLiteralAH(dbQry, datname, fout);
02208 }
02209
02210 res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
02211
02212 i_tableoid = PQfnumber(res, "tableoid");
02213 i_oid = PQfnumber(res, "oid");
02214 i_dba = PQfnumber(res, "dba");
02215 i_encoding = PQfnumber(res, "encoding");
02216 i_collate = PQfnumber(res, "datcollate");
02217 i_ctype = PQfnumber(res, "datctype");
02218 i_frozenxid = PQfnumber(res, "datfrozenxid");
02219 i_tablespace = PQfnumber(res, "tablespace");
02220
02221 dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
02222 dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
02223 dba = PQgetvalue(res, 0, i_dba);
02224 encoding = PQgetvalue(res, 0, i_encoding);
02225 collate = PQgetvalue(res, 0, i_collate);
02226 ctype = PQgetvalue(res, 0, i_ctype);
02227 frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
02228 tablespace = PQgetvalue(res, 0, i_tablespace);
02229
02230 appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
02231 fmtId(datname));
02232 if (strlen(encoding) > 0)
02233 {
02234 appendPQExpBuffer(creaQry, " ENCODING = ");
02235 appendStringLiteralAH(creaQry, encoding, fout);
02236 }
02237 if (strlen(collate) > 0)
02238 {
02239 appendPQExpBuffer(creaQry, " LC_COLLATE = ");
02240 appendStringLiteralAH(creaQry, collate, fout);
02241 }
02242 if (strlen(ctype) > 0)
02243 {
02244 appendPQExpBuffer(creaQry, " LC_CTYPE = ");
02245 appendStringLiteralAH(creaQry, ctype, fout);
02246 }
02247 if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
02248 appendPQExpBuffer(creaQry, " TABLESPACE = %s",
02249 fmtId(tablespace));
02250 appendPQExpBuffer(creaQry, ";\n");
02251
02252 if (binary_upgrade)
02253 {
02254 appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
02255 appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
02256 "SET datfrozenxid = '%u'\n"
02257 "WHERE datname = ",
02258 frozenxid);
02259 appendStringLiteralAH(creaQry, datname, fout);
02260 appendPQExpBuffer(creaQry, ";\n");
02261
02262 }
02263
02264 appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
02265 fmtId(datname));
02266
02267 dbDumpId = createDumpId();
02268
02269 ArchiveEntry(fout,
02270 dbCatId,
02271 dbDumpId,
02272 datname,
02273 NULL,
02274 NULL,
02275 dba,
02276 false,
02277 "DATABASE",
02278 SECTION_PRE_DATA,
02279 creaQry->data,
02280 delQry->data,
02281 NULL,
02282 NULL,
02283 0,
02284 NULL,
02285 NULL);
02286
02287
02288
02289
02290
02291 if (binary_upgrade)
02292 {
02293 PGresult *lo_res;
02294 PQExpBuffer loFrozenQry = createPQExpBuffer();
02295 PQExpBuffer loOutQry = createPQExpBuffer();
02296 int i_relfrozenxid;
02297
02298
02299
02300
02301 appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
02302 "FROM pg_catalog.pg_class\n"
02303 "WHERE oid = %u;\n",
02304 LargeObjectRelationId);
02305
02306 lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
02307
02308 i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
02309
02310 appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n");
02311 appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
02312 "SET relfrozenxid = '%u'\n"
02313 "WHERE oid = %u;\n",
02314 atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
02315 LargeObjectRelationId);
02316 ArchiveEntry(fout, nilCatalogId, createDumpId(),
02317 "pg_largeobject", NULL, NULL, "",
02318 false, "pg_largeobject", SECTION_PRE_DATA,
02319 loOutQry->data, "", NULL,
02320 NULL, 0,
02321 NULL, NULL);
02322
02323 PQclear(lo_res);
02324
02325
02326
02327
02328 if (fout->remoteVersion >= 90000)
02329 {
02330 resetPQExpBuffer(loFrozenQry);
02331 resetPQExpBuffer(loOutQry);
02332
02333 appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
02334 "FROM pg_catalog.pg_class\n"
02335 "WHERE oid = %u;\n",
02336 LargeObjectMetadataRelationId);
02337
02338 lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
02339
02340 i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
02341
02342 appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n");
02343 appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
02344 "SET relfrozenxid = '%u'\n"
02345 "WHERE oid = %u;\n",
02346 atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
02347 LargeObjectMetadataRelationId);
02348 ArchiveEntry(fout, nilCatalogId, createDumpId(),
02349 "pg_largeobject_metadata", NULL, NULL, "",
02350 false, "pg_largeobject_metadata", SECTION_PRE_DATA,
02351 loOutQry->data, "", NULL,
02352 NULL, 0,
02353 NULL, NULL);
02354
02355 PQclear(lo_res);
02356 }
02357
02358 destroyPQExpBuffer(loFrozenQry);
02359 destroyPQExpBuffer(loOutQry);
02360 }
02361
02362
02363 if (fout->remoteVersion >= 80200)
02364 {
02365
02366
02367
02368
02369 char *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
02370
02371 if (comment && strlen(comment))
02372 {
02373 resetPQExpBuffer(dbQry);
02374
02375
02376
02377
02378
02379 appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
02380 appendStringLiteralAH(dbQry, comment, fout);
02381 appendPQExpBuffer(dbQry, ";\n");
02382
02383 ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
02384 dba, false, "COMMENT", SECTION_NONE,
02385 dbQry->data, "", NULL,
02386 &dbDumpId, 1, NULL, NULL);
02387 }
02388 }
02389 else
02390 {
02391 resetPQExpBuffer(dbQry);
02392 appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname));
02393 dumpComment(fout, dbQry->data, NULL, "",
02394 dbCatId, 0, dbDumpId);
02395 }
02396
02397 PQclear(res);
02398
02399
02400 if (!no_security_labels && fout->remoteVersion >= 90200)
02401 {
02402 PQExpBuffer seclabelQry = createPQExpBuffer();
02403
02404 buildShSecLabelQuery(conn, "pg_database", dbCatId.oid, seclabelQry);
02405 res = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
02406 resetPQExpBuffer(seclabelQry);
02407 emitShSecLabels(conn, res, seclabelQry, "DATABASE", datname);
02408 if (strlen(seclabelQry->data))
02409 ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
02410 dba, false, "SECURITY LABEL", SECTION_NONE,
02411 seclabelQry->data, "", NULL,
02412 &dbDumpId, 1, NULL, NULL);
02413 destroyPQExpBuffer(seclabelQry);
02414 }
02415
02416 destroyPQExpBuffer(dbQry);
02417 destroyPQExpBuffer(delQry);
02418 destroyPQExpBuffer(creaQry);
02419 }
02420
02421
02422
02423
02424
02425 static void
02426 dumpEncoding(Archive *AH)
02427 {
02428 const char *encname = pg_encoding_to_char(AH->encoding);
02429 PQExpBuffer qry = createPQExpBuffer();
02430
02431 if (g_verbose)
02432 write_msg(NULL, "saving encoding = %s\n", encname);
02433
02434 appendPQExpBuffer(qry, "SET client_encoding = ");
02435 appendStringLiteralAH(qry, encname, AH);
02436 appendPQExpBuffer(qry, ";\n");
02437
02438 ArchiveEntry(AH, nilCatalogId, createDumpId(),
02439 "ENCODING", NULL, NULL, "",
02440 false, "ENCODING", SECTION_PRE_DATA,
02441 qry->data, "", NULL,
02442 NULL, 0,
02443 NULL, NULL);
02444
02445 destroyPQExpBuffer(qry);
02446 }
02447
02448
02449
02450
02451
02452 static void
02453 dumpStdStrings(Archive *AH)
02454 {
02455 const char *stdstrings = AH->std_strings ? "on" : "off";
02456 PQExpBuffer qry = createPQExpBuffer();
02457
02458 if (g_verbose)
02459 write_msg(NULL, "saving standard_conforming_strings = %s\n",
02460 stdstrings);
02461
02462 appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
02463 stdstrings);
02464
02465 ArchiveEntry(AH, nilCatalogId, createDumpId(),
02466 "STDSTRINGS", NULL, NULL, "",
02467 false, "STDSTRINGS", SECTION_PRE_DATA,
02468 qry->data, "", NULL,
02469 NULL, 0,
02470 NULL, NULL);
02471
02472 destroyPQExpBuffer(qry);
02473 }
02474
02475
02476
02477
02478
02479
02480 static void
02481 getBlobs(Archive *fout)
02482 {
02483 PQExpBuffer blobQry = createPQExpBuffer();
02484 BlobInfo *binfo;
02485 DumpableObject *bdata;
02486 PGresult *res;
02487 int ntups;
02488 int i;
02489
02490
02491 if (g_verbose)
02492 write_msg(NULL, "reading large objects\n");
02493
02494
02495 selectSourceSchema(fout, "pg_catalog");
02496
02497
02498 if (fout->remoteVersion >= 90000)
02499 appendPQExpBuffer(blobQry,
02500 "SELECT oid, (%s lomowner) AS rolname, lomacl"
02501 " FROM pg_largeobject_metadata",
02502 username_subquery);
02503 else if (fout->remoteVersion >= 70100)
02504 appendPQExpBuffer(blobQry,
02505 "SELECT DISTINCT loid, NULL::oid, NULL::oid"
02506 " FROM pg_largeobject");
02507 else
02508 appendPQExpBuffer(blobQry,
02509 "SELECT oid, NULL::oid, NULL::oid"
02510 " FROM pg_class WHERE relkind = 'l'");
02511
02512 res = ExecuteSqlQuery(fout, blobQry->data, PGRES_TUPLES_OK);
02513
02514 ntups = PQntuples(res);
02515 if (ntups > 0)
02516 {
02517
02518
02519
02520 binfo = (BlobInfo *) pg_malloc(ntups * sizeof(BlobInfo));
02521
02522 for (i = 0; i < ntups; i++)
02523 {
02524 binfo[i].dobj.objType = DO_BLOB;
02525 binfo[i].dobj.catId.tableoid = LargeObjectRelationId;
02526 binfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, 0));
02527 AssignDumpId(&binfo[i].dobj);
02528
02529 binfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, 0));
02530 if (!PQgetisnull(res, i, 1))
02531 binfo[i].rolname = pg_strdup(PQgetvalue(res, i, 1));
02532 else
02533 binfo[i].rolname = "";
02534 if (!PQgetisnull(res, i, 2))
02535 binfo[i].blobacl = pg_strdup(PQgetvalue(res, i, 2));
02536 else
02537 binfo[i].blobacl = NULL;
02538 }
02539
02540
02541
02542
02543
02544 bdata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
02545 bdata->objType = DO_BLOB_DATA;
02546 bdata->catId = nilCatalogId;
02547 AssignDumpId(bdata);
02548 bdata->name = pg_strdup("BLOBS");
02549 }
02550
02551 PQclear(res);
02552 destroyPQExpBuffer(blobQry);
02553 }
02554
02555
02556
02557
02558
02559
02560 static void
02561 dumpBlob(Archive *fout, BlobInfo *binfo)
02562 {
02563 PQExpBuffer cquery = createPQExpBuffer();
02564 PQExpBuffer dquery = createPQExpBuffer();
02565
02566 appendPQExpBuffer(cquery,
02567 "SELECT pg_catalog.lo_create('%s');\n",
02568 binfo->dobj.name);
02569
02570 appendPQExpBuffer(dquery,
02571 "SELECT pg_catalog.lo_unlink('%s');\n",
02572 binfo->dobj.name);
02573
02574 ArchiveEntry(fout, binfo->dobj.catId, binfo->dobj.dumpId,
02575 binfo->dobj.name,
02576 NULL, NULL,
02577 binfo->rolname, false,
02578 "BLOB", SECTION_PRE_DATA,
02579 cquery->data, dquery->data, NULL,
02580 NULL, 0,
02581 NULL, NULL);
02582
02583
02584 resetPQExpBuffer(cquery);
02585 appendPQExpBuffer(cquery, "LARGE OBJECT %s", binfo->dobj.name);
02586
02587
02588 dumpComment(fout, cquery->data,
02589 NULL, binfo->rolname,
02590 binfo->dobj.catId, 0, binfo->dobj.dumpId);
02591
02592
02593 dumpSecLabel(fout, cquery->data,
02594 NULL, binfo->rolname,
02595 binfo->dobj.catId, 0, binfo->dobj.dumpId);
02596
02597
02598 if (binfo->blobacl)
02599 dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
02600 binfo->dobj.name, NULL, cquery->data,
02601 NULL, binfo->rolname, binfo->blobacl);
02602
02603 destroyPQExpBuffer(cquery);
02604 destroyPQExpBuffer(dquery);
02605 }
02606
02607
02608
02609
02610
02611 static int
02612 dumpBlobs(Archive *fout, void *arg)
02613 {
02614 const char *blobQry;
02615 const char *blobFetchQry;
02616 PGconn *conn = GetConnection(fout);
02617 PGresult *res;
02618 char buf[LOBBUFSIZE];
02619 int ntups;
02620 int i;
02621 int cnt;
02622
02623 if (g_verbose)
02624 write_msg(NULL, "saving large objects\n");
02625
02626
02627 selectSourceSchema(fout, "pg_catalog");
02628
02629
02630
02631
02632
02633 if (fout->remoteVersion >= 90000)
02634 blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_largeobject_metadata";
02635 else if (fout->remoteVersion >= 70100)
02636 blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
02637 else
02638 blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";
02639
02640 ExecuteSqlStatement(fout, blobQry);
02641
02642
02643 blobFetchQry = "FETCH 1000 IN bloboid";
02644
02645 do
02646 {
02647
02648 res = ExecuteSqlQuery(fout, blobFetchQry, PGRES_TUPLES_OK);
02649
02650
02651 ntups = PQntuples(res);
02652 for (i = 0; i < ntups; i++)
02653 {
02654 Oid blobOid;
02655 int loFd;
02656
02657 blobOid = atooid(PQgetvalue(res, i, 0));
02658
02659 loFd = lo_open(conn, blobOid, INV_READ);
02660 if (loFd == -1)
02661 exit_horribly(NULL, "could not open large object %u: %s",
02662 blobOid, PQerrorMessage(conn));
02663
02664 StartBlob(fout, blobOid);
02665
02666
02667 do
02668 {
02669 cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
02670 if (cnt < 0)
02671 exit_horribly(NULL, "error reading large object %u: %s",
02672 blobOid, PQerrorMessage(conn));
02673
02674 WriteData(fout, buf, cnt);
02675 } while (cnt > 0);
02676
02677 lo_close(conn, loFd);
02678
02679 EndBlob(fout, blobOid);
02680 }
02681
02682 PQclear(res);
02683 } while (ntups > 0);
02684
02685 return 1;
02686 }
02687
02688 static void
02689 binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
02690 PQExpBuffer upgrade_buffer,
02691 Oid pg_type_oid)
02692 {
02693 PQExpBuffer upgrade_query = createPQExpBuffer();
02694 PGresult *upgrade_res;
02695 Oid pg_type_array_oid;
02696
02697 appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
02698 appendPQExpBuffer(upgrade_buffer,
02699 "SELECT binary_upgrade.set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
02700 pg_type_oid);
02701
02702
02703 appendPQExpBuffer(upgrade_query,
02704 "SELECT typarray "
02705 "FROM pg_catalog.pg_type "
02706 "WHERE pg_type.oid = '%u'::pg_catalog.oid;",
02707 pg_type_oid);
02708
02709 upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
02710
02711 pg_type_array_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "typarray")));
02712
02713 if (OidIsValid(pg_type_array_oid))
02714 {
02715 appendPQExpBuffer(upgrade_buffer,
02716 "\n-- For binary upgrade, must preserve pg_type array oid\n");
02717 appendPQExpBuffer(upgrade_buffer,
02718 "SELECT binary_upgrade.set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
02719 pg_type_array_oid);
02720 }
02721
02722 PQclear(upgrade_res);
02723 destroyPQExpBuffer(upgrade_query);
02724 }
02725
02726 static bool
02727 binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
02728 PQExpBuffer upgrade_buffer,
02729 Oid pg_rel_oid)
02730 {
02731 PQExpBuffer upgrade_query = createPQExpBuffer();
02732 PGresult *upgrade_res;
02733 Oid pg_type_oid;
02734 bool toast_set = false;
02735
02736
02737 appendPQExpBuffer(upgrade_query,
02738 "SELECT c.reltype AS crel, t.reltype AS trel "
02739 "FROM pg_catalog.pg_class c "
02740 "LEFT JOIN pg_catalog.pg_class t ON "
02741 " (c.reltoastrelid = t.oid) "
02742 "WHERE c.oid = '%u'::pg_catalog.oid;",
02743 pg_rel_oid);
02744
02745 upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
02746
02747 pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel")));
02748
02749 binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
02750 pg_type_oid);
02751
02752 if (!PQgetisnull(upgrade_res, 0, PQfnumber(upgrade_res, "trel")))
02753 {
02754
02755 Oid pg_type_toast_oid = atooid(PQgetvalue(upgrade_res, 0,
02756 PQfnumber(upgrade_res, "trel")));
02757
02758 appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n");
02759 appendPQExpBuffer(upgrade_buffer,
02760 "SELECT binary_upgrade.set_next_toast_pg_type_oid('%u'::pg_catalog.oid);\n\n",
02761 pg_type_toast_oid);
02762
02763 toast_set = true;
02764 }
02765
02766 PQclear(upgrade_res);
02767 destroyPQExpBuffer(upgrade_query);
02768
02769 return toast_set;
02770 }
02771
02772 static void
02773 binary_upgrade_set_pg_class_oids(Archive *fout,
02774 PQExpBuffer upgrade_buffer, Oid pg_class_oid,
02775 bool is_index)
02776 {
02777 PQExpBuffer upgrade_query = createPQExpBuffer();
02778 PGresult *upgrade_res;
02779 Oid pg_class_reltoastrelid;
02780 Oid pg_class_reltoastidxid;
02781
02782 appendPQExpBuffer(upgrade_query,
02783 "SELECT c.reltoastrelid, t.reltoastidxid "
02784 "FROM pg_catalog.pg_class c LEFT JOIN "
02785 "pg_catalog.pg_class t ON (c.reltoastrelid = t.oid) "
02786 "WHERE c.oid = '%u'::pg_catalog.oid;",
02787 pg_class_oid);
02788
02789 upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
02790
02791 pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid")));
02792 pg_class_reltoastidxid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastidxid")));
02793
02794 appendPQExpBuffer(upgrade_buffer,
02795 "\n-- For binary upgrade, must preserve pg_class oids\n");
02796
02797 if (!is_index)
02798 {
02799 appendPQExpBuffer(upgrade_buffer,
02800 "SELECT binary_upgrade.set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
02801 pg_class_oid);
02802
02803 if (OidIsValid(pg_class_reltoastrelid))
02804 {
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814 appendPQExpBuffer(upgrade_buffer,
02815 "SELECT binary_upgrade.set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
02816 pg_class_reltoastrelid);
02817
02818
02819 appendPQExpBuffer(upgrade_buffer,
02820 "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
02821 pg_class_reltoastidxid);
02822 }
02823 }
02824 else
02825 appendPQExpBuffer(upgrade_buffer,
02826 "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
02827 pg_class_oid);
02828
02829 appendPQExpBuffer(upgrade_buffer, "\n");
02830
02831 PQclear(upgrade_res);
02832 destroyPQExpBuffer(upgrade_query);
02833 }
02834
02835
02836
02837
02838
02839 static void
02840 binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
02841 DumpableObject *dobj,
02842 const char *objlabel)
02843 {
02844 DumpableObject *extobj = NULL;
02845 int i;
02846
02847 if (!dobj->ext_member)
02848 return;
02849
02850
02851
02852
02853
02854
02855
02856 for (i = 0; i < dobj->nDeps; i++)
02857 {
02858 extobj = findObjectByDumpId(dobj->dependencies[i]);
02859 if (extobj && extobj->objType == DO_EXTENSION)
02860 break;
02861 extobj = NULL;
02862 }
02863 if (extobj == NULL)
02864 exit_horribly(NULL, "could not find parent extension for %s\n", objlabel);
02865
02866 appendPQExpBuffer(upgrade_buffer,
02867 "\n-- For binary upgrade, handle extension membership the hard way\n");
02868 appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s;\n",
02869 fmtId(extobj->name),
02870 objlabel);
02871 }
02872
02873
02874
02875
02876
02877
02878
02879
02880 NamespaceInfo *
02881 getNamespaces(Archive *fout, int *numNamespaces)
02882 {
02883 PGresult *res;
02884 int ntups;
02885 int i;
02886 PQExpBuffer query;
02887 NamespaceInfo *nsinfo;
02888 int i_tableoid;
02889 int i_oid;
02890 int i_nspname;
02891 int i_rolname;
02892 int i_nspacl;
02893
02894
02895
02896
02897
02898 if (fout->remoteVersion < 70300)
02899 {
02900 nsinfo = (NamespaceInfo *) pg_malloc(2 * sizeof(NamespaceInfo));
02901
02902 nsinfo[0].dobj.objType = DO_NAMESPACE;
02903 nsinfo[0].dobj.catId.tableoid = 0;
02904 nsinfo[0].dobj.catId.oid = 0;
02905 AssignDumpId(&nsinfo[0].dobj);
02906 nsinfo[0].dobj.name = pg_strdup("public");
02907 nsinfo[0].rolname = pg_strdup("");
02908 nsinfo[0].nspacl = pg_strdup("");
02909
02910 selectDumpableNamespace(&nsinfo[0]);
02911
02912 nsinfo[1].dobj.objType = DO_NAMESPACE;
02913 nsinfo[1].dobj.catId.tableoid = 0;
02914 nsinfo[1].dobj.catId.oid = 1;
02915 AssignDumpId(&nsinfo[1].dobj);
02916 nsinfo[1].dobj.name = pg_strdup("pg_catalog");
02917 nsinfo[1].rolname = pg_strdup("");
02918 nsinfo[1].nspacl = pg_strdup("");
02919
02920 selectDumpableNamespace(&nsinfo[1]);
02921
02922 *numNamespaces = 2;
02923
02924 return nsinfo;
02925 }
02926
02927 query = createPQExpBuffer();
02928
02929
02930 selectSourceSchema(fout, "pg_catalog");
02931
02932
02933
02934
02935
02936 appendPQExpBuffer(query, "SELECT tableoid, oid, nspname, "
02937 "(%s nspowner) AS rolname, "
02938 "nspacl FROM pg_namespace",
02939 username_subquery);
02940
02941 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
02942
02943 ntups = PQntuples(res);
02944
02945 nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
02946
02947 i_tableoid = PQfnumber(res, "tableoid");
02948 i_oid = PQfnumber(res, "oid");
02949 i_nspname = PQfnumber(res, "nspname");
02950 i_rolname = PQfnumber(res, "rolname");
02951 i_nspacl = PQfnumber(res, "nspacl");
02952
02953 for (i = 0; i < ntups; i++)
02954 {
02955 nsinfo[i].dobj.objType = DO_NAMESPACE;
02956 nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
02957 nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
02958 AssignDumpId(&nsinfo[i].dobj);
02959 nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
02960 nsinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
02961 nsinfo[i].nspacl = pg_strdup(PQgetvalue(res, i, i_nspacl));
02962
02963
02964 selectDumpableNamespace(&nsinfo[i]);
02965
02966 if (strlen(nsinfo[i].rolname) == 0)
02967 write_msg(NULL, "WARNING: owner of schema \"%s\" appears to be invalid\n",
02968 nsinfo[i].dobj.name);
02969 }
02970
02971 PQclear(res);
02972 destroyPQExpBuffer(query);
02973
02974 *numNamespaces = ntups;
02975
02976 return nsinfo;
02977 }
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988 static NamespaceInfo *
02989 findNamespace(Archive *fout, Oid nsoid, Oid objoid)
02990 {
02991 NamespaceInfo *nsinfo;
02992
02993 if (fout->remoteVersion >= 70300)
02994 {
02995 nsinfo = findNamespaceByOid(nsoid);
02996 }
02997 else
02998 {
02999
03000 Oid i;
03001
03002 if (objoid > g_last_builtin_oid)
03003 i = 0;
03004 else
03005 i = 1;
03006 nsinfo = findNamespaceByOid(i);
03007 }
03008
03009 if (nsinfo == NULL)
03010 exit_horribly(NULL, "schema with OID %u does not exist\n", nsoid);
03011
03012 return nsinfo;
03013 }
03014
03015
03016
03017
03018
03019
03020
03021
03022 ExtensionInfo *
03023 getExtensions(Archive *fout, int *numExtensions)
03024 {
03025 PGresult *res;
03026 int ntups;
03027 int i;
03028 PQExpBuffer query;
03029 ExtensionInfo *extinfo;
03030 int i_tableoid;
03031 int i_oid;
03032 int i_extname;
03033 int i_nspname;
03034 int i_extrelocatable;
03035 int i_extversion;
03036 int i_extconfig;
03037 int i_extcondition;
03038
03039
03040
03041
03042 if (fout->remoteVersion < 90100)
03043 {
03044 *numExtensions = 0;
03045 return NULL;
03046 }
03047
03048 query = createPQExpBuffer();
03049
03050
03051 selectSourceSchema(fout, "pg_catalog");
03052
03053 appendPQExpBuffer(query, "SELECT x.tableoid, x.oid, "
03054 "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
03055 "FROM pg_extension x "
03056 "JOIN pg_namespace n ON n.oid = x.extnamespace");
03057
03058 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03059
03060 ntups = PQntuples(res);
03061
03062 extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
03063
03064 i_tableoid = PQfnumber(res, "tableoid");
03065 i_oid = PQfnumber(res, "oid");
03066 i_extname = PQfnumber(res, "extname");
03067 i_nspname = PQfnumber(res, "nspname");
03068 i_extrelocatable = PQfnumber(res, "extrelocatable");
03069 i_extversion = PQfnumber(res, "extversion");
03070 i_extconfig = PQfnumber(res, "extconfig");
03071 i_extcondition = PQfnumber(res, "extcondition");
03072
03073 for (i = 0; i < ntups; i++)
03074 {
03075 extinfo[i].dobj.objType = DO_EXTENSION;
03076 extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03077 extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03078 AssignDumpId(&extinfo[i].dobj);
03079 extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
03080 extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
03081 extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
03082 extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
03083 extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
03084 extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
03085
03086
03087 selectDumpableExtension(&(extinfo[i]));
03088 }
03089
03090 PQclear(res);
03091 destroyPQExpBuffer(query);
03092
03093 *numExtensions = ntups;
03094
03095 return extinfo;
03096 }
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108 TypeInfo *
03109 getTypes(Archive *fout, int *numTypes)
03110 {
03111 PGresult *res;
03112 int ntups;
03113 int i;
03114 PQExpBuffer query = createPQExpBuffer();
03115 TypeInfo *tyinfo;
03116 ShellTypeInfo *stinfo;
03117 int i_tableoid;
03118 int i_oid;
03119 int i_typname;
03120 int i_typnamespace;
03121 int i_typacl;
03122 int i_rolname;
03123 int i_typinput;
03124 int i_typoutput;
03125 int i_typelem;
03126 int i_typrelid;
03127 int i_typrelkind;
03128 int i_typtype;
03129 int i_typisdefined;
03130 int i_isarray;
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 selectSourceSchema(fout, "pg_catalog");
03150
03151 if (fout->remoteVersion >= 90200)
03152 {
03153 appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
03154 "typnamespace, typacl, "
03155 "(%s typowner) AS rolname, "
03156 "typinput::oid AS typinput, "
03157 "typoutput::oid AS typoutput, typelem, typrelid, "
03158 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
03159 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
03160 "typtype, typisdefined, "
03161 "typname[0] = '_' AND typelem != 0 AND "
03162 "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
03163 "FROM pg_type",
03164 username_subquery);
03165 }
03166 else if (fout->remoteVersion >= 80300)
03167 {
03168 appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
03169 "typnamespace, '{=U}' AS typacl, "
03170 "(%s typowner) AS rolname, "
03171 "typinput::oid AS typinput, "
03172 "typoutput::oid AS typoutput, typelem, typrelid, "
03173 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
03174 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
03175 "typtype, typisdefined, "
03176 "typname[0] = '_' AND typelem != 0 AND "
03177 "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
03178 "FROM pg_type",
03179 username_subquery);
03180 }
03181 else if (fout->remoteVersion >= 70300)
03182 {
03183 appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
03184 "typnamespace, '{=U}' AS typacl, "
03185 "(%s typowner) AS rolname, "
03186 "typinput::oid AS typinput, "
03187 "typoutput::oid AS typoutput, typelem, typrelid, "
03188 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
03189 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
03190 "typtype, typisdefined, "
03191 "typname[0] = '_' AND typelem != 0 AS isarray "
03192 "FROM pg_type",
03193 username_subquery);
03194 }
03195 else if (fout->remoteVersion >= 70100)
03196 {
03197 appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
03198 "0::oid AS typnamespace, '{=U}' AS typacl, "
03199 "(%s typowner) AS rolname, "
03200 "typinput::oid AS typinput, "
03201 "typoutput::oid AS typoutput, typelem, typrelid, "
03202 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
03203 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
03204 "typtype, typisdefined, "
03205 "typname[0] = '_' AND typelem != 0 AS isarray "
03206 "FROM pg_type",
03207 username_subquery);
03208 }
03209 else
03210 {
03211 appendPQExpBuffer(query, "SELECT "
03212 "(SELECT oid FROM pg_class WHERE relname = 'pg_type') AS tableoid, "
03213 "oid, typname, "
03214 "0::oid AS typnamespace, '{=U}' AS typacl, "
03215 "(%s typowner) AS rolname, "
03216 "typinput::oid AS typinput, "
03217 "typoutput::oid AS typoutput, typelem, typrelid, "
03218 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
03219 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
03220 "typtype, typisdefined, "
03221 "typname[0] = '_' AND typelem != 0 AS isarray "
03222 "FROM pg_type",
03223 username_subquery);
03224 }
03225
03226 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03227
03228 ntups = PQntuples(res);
03229
03230 tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
03231
03232 i_tableoid = PQfnumber(res, "tableoid");
03233 i_oid = PQfnumber(res, "oid");
03234 i_typname = PQfnumber(res, "typname");
03235 i_typnamespace = PQfnumber(res, "typnamespace");
03236 i_typacl = PQfnumber(res, "typacl");
03237 i_rolname = PQfnumber(res, "rolname");
03238 i_typinput = PQfnumber(res, "typinput");
03239 i_typoutput = PQfnumber(res, "typoutput");
03240 i_typelem = PQfnumber(res, "typelem");
03241 i_typrelid = PQfnumber(res, "typrelid");
03242 i_typrelkind = PQfnumber(res, "typrelkind");
03243 i_typtype = PQfnumber(res, "typtype");
03244 i_typisdefined = PQfnumber(res, "typisdefined");
03245 i_isarray = PQfnumber(res, "isarray");
03246
03247 for (i = 0; i < ntups; i++)
03248 {
03249 tyinfo[i].dobj.objType = DO_TYPE;
03250 tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03251 tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03252 AssignDumpId(&tyinfo[i].dobj);
03253 tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
03254 tyinfo[i].dobj.namespace =
03255 findNamespace(fout,
03256 atooid(PQgetvalue(res, i, i_typnamespace)),
03257 tyinfo[i].dobj.catId.oid);
03258 tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03259 tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl));
03260 tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
03261 tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
03262 tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
03263 tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
03264 tyinfo[i].shellType = NULL;
03265
03266 if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
03267 tyinfo[i].isDefined = true;
03268 else
03269 tyinfo[i].isDefined = false;
03270
03271 if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
03272 tyinfo[i].isArray = true;
03273 else
03274 tyinfo[i].isArray = false;
03275
03276
03277 selectDumpableType(&tyinfo[i]);
03278
03279
03280
03281
03282 tyinfo[i].nDomChecks = 0;
03283 tyinfo[i].domChecks = NULL;
03284 if (tyinfo[i].dobj.dump && tyinfo[i].typtype == TYPTYPE_DOMAIN)
03285 getDomainConstraints(fout, &(tyinfo[i]));
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297 if (tyinfo[i].dobj.dump && (tyinfo[i].typtype == TYPTYPE_BASE ||
03298 tyinfo[i].typtype == TYPTYPE_RANGE))
03299 {
03300 stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
03301 stinfo->dobj.objType = DO_SHELL_TYPE;
03302 stinfo->dobj.catId = nilCatalogId;
03303 AssignDumpId(&stinfo->dobj);
03304 stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
03305 stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
03306 stinfo->baseType = &(tyinfo[i]);
03307 tyinfo[i].shellType = stinfo;
03308
03309
03310
03311
03312
03313
03314 stinfo->dobj.dump = false;
03315
03316
03317
03318
03319
03320
03321
03322 if (fout->remoteVersion < 70300)
03323 {
03324 Oid typinput;
03325 Oid typoutput;
03326 FuncInfo *funcInfo;
03327
03328 typinput = atooid(PQgetvalue(res, i, i_typinput));
03329 typoutput = atooid(PQgetvalue(res, i, i_typoutput));
03330
03331 funcInfo = findFuncByOid(typinput);
03332 if (funcInfo && funcInfo->dobj.dump)
03333 {
03334
03335 addObjectDependency(&tyinfo[i].dobj,
03336 funcInfo->dobj.dumpId);
03337
03338 addObjectDependency(&funcInfo->dobj,
03339 stinfo->dobj.dumpId);
03340
03341 stinfo->dobj.dump = true;
03342 }
03343
03344 funcInfo = findFuncByOid(typoutput);
03345 if (funcInfo && funcInfo->dobj.dump)
03346 {
03347
03348 addObjectDependency(&tyinfo[i].dobj,
03349 funcInfo->dobj.dumpId);
03350
03351 addObjectDependency(&funcInfo->dobj,
03352 stinfo->dobj.dumpId);
03353
03354 stinfo->dobj.dump = true;
03355 }
03356 }
03357 }
03358
03359 if (strlen(tyinfo[i].rolname) == 0 && tyinfo[i].isDefined)
03360 write_msg(NULL, "WARNING: owner of data type \"%s\" appears to be invalid\n",
03361 tyinfo[i].dobj.name);
03362 }
03363
03364 *numTypes = ntups;
03365
03366 PQclear(res);
03367
03368 destroyPQExpBuffer(query);
03369
03370 return tyinfo;
03371 }
03372
03373
03374
03375
03376
03377
03378
03379
03380 OprInfo *
03381 getOperators(Archive *fout, int *numOprs)
03382 {
03383 PGresult *res;
03384 int ntups;
03385 int i;
03386 PQExpBuffer query = createPQExpBuffer();
03387 OprInfo *oprinfo;
03388 int i_tableoid;
03389 int i_oid;
03390 int i_oprname;
03391 int i_oprnamespace;
03392 int i_rolname;
03393 int i_oprkind;
03394 int i_oprcode;
03395
03396
03397
03398
03399
03400
03401
03402 selectSourceSchema(fout, "pg_catalog");
03403
03404 if (fout->remoteVersion >= 70300)
03405 {
03406 appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
03407 "oprnamespace, "
03408 "(%s oprowner) AS rolname, "
03409 "oprkind, "
03410 "oprcode::oid AS oprcode "
03411 "FROM pg_operator",
03412 username_subquery);
03413 }
03414 else if (fout->remoteVersion >= 70100)
03415 {
03416 appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
03417 "0::oid AS oprnamespace, "
03418 "(%s oprowner) AS rolname, "
03419 "oprkind, "
03420 "oprcode::oid AS oprcode "
03421 "FROM pg_operator",
03422 username_subquery);
03423 }
03424 else
03425 {
03426 appendPQExpBuffer(query, "SELECT "
03427 "(SELECT oid FROM pg_class WHERE relname = 'pg_operator') AS tableoid, "
03428 "oid, oprname, "
03429 "0::oid AS oprnamespace, "
03430 "(%s oprowner) AS rolname, "
03431 "oprkind, "
03432 "oprcode::oid AS oprcode "
03433 "FROM pg_operator",
03434 username_subquery);
03435 }
03436
03437 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03438
03439 ntups = PQntuples(res);
03440 *numOprs = ntups;
03441
03442 oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
03443
03444 i_tableoid = PQfnumber(res, "tableoid");
03445 i_oid = PQfnumber(res, "oid");
03446 i_oprname = PQfnumber(res, "oprname");
03447 i_oprnamespace = PQfnumber(res, "oprnamespace");
03448 i_rolname = PQfnumber(res, "rolname");
03449 i_oprkind = PQfnumber(res, "oprkind");
03450 i_oprcode = PQfnumber(res, "oprcode");
03451
03452 for (i = 0; i < ntups; i++)
03453 {
03454 oprinfo[i].dobj.objType = DO_OPERATOR;
03455 oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03456 oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03457 AssignDumpId(&oprinfo[i].dobj);
03458 oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
03459 oprinfo[i].dobj.namespace =
03460 findNamespace(fout,
03461 atooid(PQgetvalue(res, i, i_oprnamespace)),
03462 oprinfo[i].dobj.catId.oid);
03463 oprinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03464 oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
03465 oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
03466
03467
03468 selectDumpableObject(&(oprinfo[i].dobj));
03469
03470 if (strlen(oprinfo[i].rolname) == 0)
03471 write_msg(NULL, "WARNING: owner of operator \"%s\" appears to be invalid\n",
03472 oprinfo[i].dobj.name);
03473 }
03474
03475 PQclear(res);
03476
03477 destroyPQExpBuffer(query);
03478
03479 return oprinfo;
03480 }
03481
03482
03483
03484
03485
03486
03487
03488
03489 CollInfo *
03490 getCollations(Archive *fout, int *numCollations)
03491 {
03492 PGresult *res;
03493 int ntups;
03494 int i;
03495 PQExpBuffer query;
03496 CollInfo *collinfo;
03497 int i_tableoid;
03498 int i_oid;
03499 int i_collname;
03500 int i_collnamespace;
03501 int i_rolname;
03502
03503
03504 if (fout->remoteVersion < 90100)
03505 {
03506 *numCollations = 0;
03507 return NULL;
03508 }
03509
03510 query = createPQExpBuffer();
03511
03512
03513
03514
03515
03516
03517
03518 selectSourceSchema(fout, "pg_catalog");
03519
03520 appendPQExpBuffer(query, "SELECT tableoid, oid, collname, "
03521 "collnamespace, "
03522 "(%s collowner) AS rolname "
03523 "FROM pg_collation",
03524 username_subquery);
03525
03526 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03527
03528 ntups = PQntuples(res);
03529 *numCollations = ntups;
03530
03531 collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
03532
03533 i_tableoid = PQfnumber(res, "tableoid");
03534 i_oid = PQfnumber(res, "oid");
03535 i_collname = PQfnumber(res, "collname");
03536 i_collnamespace = PQfnumber(res, "collnamespace");
03537 i_rolname = PQfnumber(res, "rolname");
03538
03539 for (i = 0; i < ntups; i++)
03540 {
03541 collinfo[i].dobj.objType = DO_COLLATION;
03542 collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03543 collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03544 AssignDumpId(&collinfo[i].dobj);
03545 collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
03546 collinfo[i].dobj.namespace =
03547 findNamespace(fout,
03548 atooid(PQgetvalue(res, i, i_collnamespace)),
03549 collinfo[i].dobj.catId.oid);
03550 collinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03551
03552
03553 selectDumpableObject(&(collinfo[i].dobj));
03554 }
03555
03556 PQclear(res);
03557
03558 destroyPQExpBuffer(query);
03559
03560 return collinfo;
03561 }
03562
03563
03564
03565
03566
03567
03568
03569
03570 ConvInfo *
03571 getConversions(Archive *fout, int *numConversions)
03572 {
03573 PGresult *res;
03574 int ntups;
03575 int i;
03576 PQExpBuffer query = createPQExpBuffer();
03577 ConvInfo *convinfo;
03578 int i_tableoid;
03579 int i_oid;
03580 int i_conname;
03581 int i_connamespace;
03582 int i_rolname;
03583
03584
03585 if (fout->remoteVersion < 70300)
03586 {
03587 *numConversions = 0;
03588 return NULL;
03589 }
03590
03591
03592
03593
03594
03595
03596
03597 selectSourceSchema(fout, "pg_catalog");
03598
03599 appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
03600 "connamespace, "
03601 "(%s conowner) AS rolname "
03602 "FROM pg_conversion",
03603 username_subquery);
03604
03605 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03606
03607 ntups = PQntuples(res);
03608 *numConversions = ntups;
03609
03610 convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
03611
03612 i_tableoid = PQfnumber(res, "tableoid");
03613 i_oid = PQfnumber(res, "oid");
03614 i_conname = PQfnumber(res, "conname");
03615 i_connamespace = PQfnumber(res, "connamespace");
03616 i_rolname = PQfnumber(res, "rolname");
03617
03618 for (i = 0; i < ntups; i++)
03619 {
03620 convinfo[i].dobj.objType = DO_CONVERSION;
03621 convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03622 convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03623 AssignDumpId(&convinfo[i].dobj);
03624 convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
03625 convinfo[i].dobj.namespace =
03626 findNamespace(fout,
03627 atooid(PQgetvalue(res, i, i_connamespace)),
03628 convinfo[i].dobj.catId.oid);
03629 convinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03630
03631
03632 selectDumpableObject(&(convinfo[i].dobj));
03633 }
03634
03635 PQclear(res);
03636
03637 destroyPQExpBuffer(query);
03638
03639 return convinfo;
03640 }
03641
03642
03643
03644
03645
03646
03647
03648
03649 OpclassInfo *
03650 getOpclasses(Archive *fout, int *numOpclasses)
03651 {
03652 PGresult *res;
03653 int ntups;
03654 int i;
03655 PQExpBuffer query = createPQExpBuffer();
03656 OpclassInfo *opcinfo;
03657 int i_tableoid;
03658 int i_oid;
03659 int i_opcname;
03660 int i_opcnamespace;
03661 int i_rolname;
03662
03663
03664
03665
03666
03667
03668
03669 selectSourceSchema(fout, "pg_catalog");
03670
03671 if (fout->remoteVersion >= 70300)
03672 {
03673 appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
03674 "opcnamespace, "
03675 "(%s opcowner) AS rolname "
03676 "FROM pg_opclass",
03677 username_subquery);
03678 }
03679 else if (fout->remoteVersion >= 70100)
03680 {
03681 appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
03682 "0::oid AS opcnamespace, "
03683 "''::name AS rolname "
03684 "FROM pg_opclass");
03685 }
03686 else
03687 {
03688 appendPQExpBuffer(query, "SELECT "
03689 "(SELECT oid FROM pg_class WHERE relname = 'pg_opclass') AS tableoid, "
03690 "oid, opcname, "
03691 "0::oid AS opcnamespace, "
03692 "''::name AS rolname "
03693 "FROM pg_opclass");
03694 }
03695
03696 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03697
03698 ntups = PQntuples(res);
03699 *numOpclasses = ntups;
03700
03701 opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
03702
03703 i_tableoid = PQfnumber(res, "tableoid");
03704 i_oid = PQfnumber(res, "oid");
03705 i_opcname = PQfnumber(res, "opcname");
03706 i_opcnamespace = PQfnumber(res, "opcnamespace");
03707 i_rolname = PQfnumber(res, "rolname");
03708
03709 for (i = 0; i < ntups; i++)
03710 {
03711 opcinfo[i].dobj.objType = DO_OPCLASS;
03712 opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03713 opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03714 AssignDumpId(&opcinfo[i].dobj);
03715 opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
03716 opcinfo[i].dobj.namespace =
03717 findNamespace(fout,
03718 atooid(PQgetvalue(res, i, i_opcnamespace)),
03719 opcinfo[i].dobj.catId.oid);
03720 opcinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03721
03722
03723 selectDumpableObject(&(opcinfo[i].dobj));
03724
03725 if (fout->remoteVersion >= 70300)
03726 {
03727 if (strlen(opcinfo[i].rolname) == 0)
03728 write_msg(NULL, "WARNING: owner of operator class \"%s\" appears to be invalid\n",
03729 opcinfo[i].dobj.name);
03730 }
03731 }
03732
03733 PQclear(res);
03734
03735 destroyPQExpBuffer(query);
03736
03737 return opcinfo;
03738 }
03739
03740
03741
03742
03743
03744
03745
03746
03747 OpfamilyInfo *
03748 getOpfamilies(Archive *fout, int *numOpfamilies)
03749 {
03750 PGresult *res;
03751 int ntups;
03752 int i;
03753 PQExpBuffer query;
03754 OpfamilyInfo *opfinfo;
03755 int i_tableoid;
03756 int i_oid;
03757 int i_opfname;
03758 int i_opfnamespace;
03759 int i_rolname;
03760
03761
03762 if (fout->remoteVersion < 80300)
03763 {
03764 *numOpfamilies = 0;
03765 return NULL;
03766 }
03767
03768 query = createPQExpBuffer();
03769
03770
03771
03772
03773
03774
03775
03776 selectSourceSchema(fout, "pg_catalog");
03777
03778 appendPQExpBuffer(query, "SELECT tableoid, oid, opfname, "
03779 "opfnamespace, "
03780 "(%s opfowner) AS rolname "
03781 "FROM pg_opfamily",
03782 username_subquery);
03783
03784 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03785
03786 ntups = PQntuples(res);
03787 *numOpfamilies = ntups;
03788
03789 opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
03790
03791 i_tableoid = PQfnumber(res, "tableoid");
03792 i_oid = PQfnumber(res, "oid");
03793 i_opfname = PQfnumber(res, "opfname");
03794 i_opfnamespace = PQfnumber(res, "opfnamespace");
03795 i_rolname = PQfnumber(res, "rolname");
03796
03797 for (i = 0; i < ntups; i++)
03798 {
03799 opfinfo[i].dobj.objType = DO_OPFAMILY;
03800 opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03801 opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03802 AssignDumpId(&opfinfo[i].dobj);
03803 opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
03804 opfinfo[i].dobj.namespace =
03805 findNamespace(fout,
03806 atooid(PQgetvalue(res, i, i_opfnamespace)),
03807 opfinfo[i].dobj.catId.oid);
03808 opfinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03809
03810
03811 selectDumpableObject(&(opfinfo[i].dobj));
03812
03813 if (fout->remoteVersion >= 70300)
03814 {
03815 if (strlen(opfinfo[i].rolname) == 0)
03816 write_msg(NULL, "WARNING: owner of operator family \"%s\" appears to be invalid\n",
03817 opfinfo[i].dobj.name);
03818 }
03819 }
03820
03821 PQclear(res);
03822
03823 destroyPQExpBuffer(query);
03824
03825 return opfinfo;
03826 }
03827
03828
03829
03830
03831
03832
03833
03834
03835 AggInfo *
03836 getAggregates(Archive *fout, int *numAggs)
03837 {
03838 PGresult *res;
03839 int ntups;
03840 int i;
03841 PQExpBuffer query = createPQExpBuffer();
03842 AggInfo *agginfo;
03843 int i_tableoid;
03844 int i_oid;
03845 int i_aggname;
03846 int i_aggnamespace;
03847 int i_pronargs;
03848 int i_proargtypes;
03849 int i_rolname;
03850 int i_aggacl;
03851 int i_proiargs;
03852
03853
03854 selectSourceSchema(fout, "pg_catalog");
03855
03856
03857
03858
03859
03860
03861 if (fout->remoteVersion >= 80400)
03862 {
03863 appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
03864 "pronamespace AS aggnamespace, "
03865 "pronargs, proargtypes, "
03866 "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
03867 "(%s proowner) AS rolname, "
03868 "proacl AS aggacl "
03869 "FROM pg_proc p "
03870 "WHERE proisagg AND ("
03871 "pronamespace != "
03872 "(SELECT oid FROM pg_namespace "
03873 "WHERE nspname = 'pg_catalog')",
03874 username_subquery);
03875 if (binary_upgrade && fout->remoteVersion >= 90100)
03876 appendPQExpBuffer(query,
03877 " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
03878 "classid = 'pg_proc'::regclass AND "
03879 "objid = p.oid AND "
03880 "refclassid = 'pg_extension'::regclass AND "
03881 "deptype = 'e')");
03882 appendPQExpBuffer(query, ")");
03883 }
03884 else if (fout->remoteVersion >= 80200)
03885 {
03886 appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
03887 "pronamespace AS aggnamespace, "
03888 "pronargs, proargtypes, "
03889 "NULL::text AS proiargs,"
03890 "(%s proowner) AS rolname, "
03891 "proacl AS aggacl "
03892 "FROM pg_proc p "
03893 "WHERE proisagg AND ("
03894 "pronamespace != "
03895 "(SELECT oid FROM pg_namespace "
03896 "WHERE nspname = 'pg_catalog'))",
03897 username_subquery);
03898 }
03899 else if (fout->remoteVersion >= 70300)
03900 {
03901 appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
03902 "pronamespace AS aggnamespace, "
03903 "CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END AS pronargs, "
03904 "proargtypes, "
03905 "NULL::text AS proiargs, "
03906 "(%s proowner) AS rolname, "
03907 "proacl AS aggacl "
03908 "FROM pg_proc "
03909 "WHERE proisagg "
03910 "AND pronamespace != "
03911 "(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog')",
03912 username_subquery);
03913 }
03914 else if (fout->remoteVersion >= 70100)
03915 {
03916 appendPQExpBuffer(query, "SELECT tableoid, oid, aggname, "
03917 "0::oid AS aggnamespace, "
03918 "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
03919 "aggbasetype AS proargtypes, "
03920 "NULL::text AS proiargs, "
03921 "(%s aggowner) AS rolname, "
03922 "'{=X}' AS aggacl "
03923 "FROM pg_aggregate "
03924 "where oid > '%u'::oid",
03925 username_subquery,
03926 g_last_builtin_oid);
03927 }
03928 else
03929 {
03930 appendPQExpBuffer(query, "SELECT "
03931 "(SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') AS tableoid, "
03932 "oid, aggname, "
03933 "0::oid AS aggnamespace, "
03934 "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
03935 "aggbasetype AS proargtypes, "
03936 "NULL::text AS proiargs, "
03937 "(%s aggowner) AS rolname, "
03938 "'{=X}' AS aggacl "
03939 "FROM pg_aggregate "
03940 "where oid > '%u'::oid",
03941 username_subquery,
03942 g_last_builtin_oid);
03943 }
03944
03945 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
03946
03947 ntups = PQntuples(res);
03948 *numAggs = ntups;
03949
03950 agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
03951
03952 i_tableoid = PQfnumber(res, "tableoid");
03953 i_oid = PQfnumber(res, "oid");
03954 i_aggname = PQfnumber(res, "aggname");
03955 i_aggnamespace = PQfnumber(res, "aggnamespace");
03956 i_pronargs = PQfnumber(res, "pronargs");
03957 i_proargtypes = PQfnumber(res, "proargtypes");
03958 i_rolname = PQfnumber(res, "rolname");
03959 i_aggacl = PQfnumber(res, "aggacl");
03960 i_proiargs = PQfnumber(res, "proiargs");
03961
03962 for (i = 0; i < ntups; i++)
03963 {
03964 agginfo[i].aggfn.dobj.objType = DO_AGG;
03965 agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
03966 agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
03967 AssignDumpId(&agginfo[i].aggfn.dobj);
03968 agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
03969 agginfo[i].aggfn.dobj.namespace =
03970 findNamespace(fout,
03971 atooid(PQgetvalue(res, i, i_aggnamespace)),
03972 agginfo[i].aggfn.dobj.catId.oid);
03973 agginfo[i].aggfn.rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
03974 if (strlen(agginfo[i].aggfn.rolname) == 0)
03975 write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
03976 agginfo[i].aggfn.dobj.name);
03977 agginfo[i].aggfn.lang = InvalidOid;
03978 agginfo[i].aggfn.prorettype = InvalidOid;
03979 agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl));
03980 agginfo[i].aggfn.proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs));
03981 agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
03982 if (agginfo[i].aggfn.nargs == 0)
03983 agginfo[i].aggfn.argtypes = NULL;
03984 else
03985 {
03986 agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
03987 if (fout->remoteVersion >= 70300)
03988 parseOidArray(PQgetvalue(res, i, i_proargtypes),
03989 agginfo[i].aggfn.argtypes,
03990 agginfo[i].aggfn.nargs);
03991 else
03992
03993 agginfo[i].aggfn.argtypes[0] = atooid(PQgetvalue(res, i, i_proargtypes));
03994 }
03995
03996
03997 selectDumpableObject(&(agginfo[i].aggfn.dobj));
03998 }
03999
04000 PQclear(res);
04001
04002 destroyPQExpBuffer(query);
04003
04004 return agginfo;
04005 }
04006
04007
04008
04009
04010
04011
04012
04013
04014 FuncInfo *
04015 getFuncs(Archive *fout, int *numFuncs)
04016 {
04017 PGresult *res;
04018 int ntups;
04019 int i;
04020 PQExpBuffer query = createPQExpBuffer();
04021 FuncInfo *finfo;
04022 int i_tableoid;
04023 int i_oid;
04024 int i_proname;
04025 int i_pronamespace;
04026 int i_rolname;
04027 int i_prolang;
04028 int i_pronargs;
04029 int i_proargtypes;
04030 int i_prorettype;
04031 int i_proacl;
04032 int i_proiargs;
04033
04034
04035 selectSourceSchema(fout, "pg_catalog");
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046
04047
04048
04049
04050
04051
04052
04053 if (fout->remoteVersion >= 80400)
04054 {
04055 appendPQExpBuffer(query,
04056 "SELECT tableoid, oid, proname, prolang, "
04057 "pronargs, proargtypes, prorettype, proacl, "
04058 "pronamespace, "
04059 "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
04060 "(%s proowner) AS rolname "
04061 "FROM pg_proc p "
04062 "WHERE NOT proisagg AND ("
04063 "pronamespace != "
04064 "(SELECT oid FROM pg_namespace "
04065 "WHERE nspname = 'pg_catalog')",
04066 username_subquery);
04067 if (fout->remoteVersion >= 90200)
04068 appendPQExpBuffer(query,
04069 "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
04070 "WHERE classid = 'pg_proc'::regclass AND "
04071 "objid = p.oid AND deptype = 'i')");
04072 if (binary_upgrade && fout->remoteVersion >= 90100)
04073 appendPQExpBuffer(query,
04074 "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
04075 "classid = 'pg_proc'::regclass AND "
04076 "objid = p.oid AND "
04077 "refclassid = 'pg_extension'::regclass AND "
04078 "deptype = 'e')");
04079 appendPQExpBuffer(query, ")");
04080 }
04081 else if (fout->remoteVersion >= 70300)
04082 {
04083 appendPQExpBuffer(query,
04084 "SELECT tableoid, oid, proname, prolang, "
04085 "pronargs, proargtypes, prorettype, proacl, "
04086 "pronamespace, "
04087 "NULL::text AS proiargs,"
04088 "(%s proowner) AS rolname "
04089 "FROM pg_proc p "
04090 "WHERE NOT proisagg AND ("
04091 "pronamespace != "
04092 "(SELECT oid FROM pg_namespace "
04093 "WHERE nspname = 'pg_catalog'))",
04094 username_subquery);
04095 }
04096 else if (fout->remoteVersion >= 70100)
04097 {
04098 appendPQExpBuffer(query,
04099 "SELECT tableoid, oid, proname, prolang, "
04100 "pronargs, proargtypes, prorettype, "
04101 "'{=X}' AS proacl, "
04102 "0::oid AS pronamespace, "
04103 "NULL::text AS proiargs,"
04104 "(%s proowner) AS rolname "
04105 "FROM pg_proc "
04106 "WHERE pg_proc.oid > '%u'::oid",
04107 username_subquery,
04108 g_last_builtin_oid);
04109 }
04110 else
04111 {
04112 appendPQExpBuffer(query,
04113 "SELECT "
04114 "(SELECT oid FROM pg_class "
04115 " WHERE relname = 'pg_proc') AS tableoid, "
04116 "oid, proname, prolang, "
04117 "pronargs, proargtypes, prorettype, "
04118 "'{=X}' AS proacl, "
04119 "0::oid AS pronamespace, "
04120 "NULL::text AS proiargs,"
04121 "(%s proowner) AS rolname "
04122 "FROM pg_proc "
04123 "where pg_proc.oid > '%u'::oid",
04124 username_subquery,
04125 g_last_builtin_oid);
04126 }
04127
04128 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
04129
04130 ntups = PQntuples(res);
04131
04132 *numFuncs = ntups;
04133
04134 finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
04135
04136 i_tableoid = PQfnumber(res, "tableoid");
04137 i_oid = PQfnumber(res, "oid");
04138 i_proname = PQfnumber(res, "proname");
04139 i_pronamespace = PQfnumber(res, "pronamespace");
04140 i_rolname = PQfnumber(res, "rolname");
04141 i_prolang = PQfnumber(res, "prolang");
04142 i_pronargs = PQfnumber(res, "pronargs");
04143 i_proargtypes = PQfnumber(res, "proargtypes");
04144 i_prorettype = PQfnumber(res, "prorettype");
04145 i_proacl = PQfnumber(res, "proacl");
04146 i_proiargs = PQfnumber(res, "proiargs");
04147
04148 for (i = 0; i < ntups; i++)
04149 {
04150 finfo[i].dobj.objType = DO_FUNC;
04151 finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
04152 finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
04153 AssignDumpId(&finfo[i].dobj);
04154 finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
04155 finfo[i].dobj.namespace =
04156 findNamespace(fout,
04157 atooid(PQgetvalue(res, i, i_pronamespace)),
04158 finfo[i].dobj.catId.oid);
04159 finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
04160 finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
04161 finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
04162 finfo[i].proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs));
04163 finfo[i].proacl = pg_strdup(PQgetvalue(res, i, i_proacl));
04164 finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
04165 if (finfo[i].nargs == 0)
04166 finfo[i].argtypes = NULL;
04167 else
04168 {
04169 finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
04170 parseOidArray(PQgetvalue(res, i, i_proargtypes),
04171 finfo[i].argtypes, finfo[i].nargs);
04172 }
04173
04174
04175 selectDumpableObject(&(finfo[i].dobj));
04176
04177 if (strlen(finfo[i].rolname) == 0)
04178 write_msg(NULL,
04179 "WARNING: owner of function \"%s\" appears to be invalid\n",
04180 finfo[i].dobj.name);
04181 }
04182
04183 PQclear(res);
04184
04185 destroyPQExpBuffer(query);
04186
04187 return finfo;
04188 }
04189
04190
04191
04192
04193
04194
04195
04196
04197 TableInfo *
04198 getTables(Archive *fout, int *numTables)
04199 {
04200 PGresult *res;
04201 int ntups;
04202 int i;
04203 PQExpBuffer query = createPQExpBuffer();
04204 TableInfo *tblinfo;
04205 int i_reltableoid;
04206 int i_reloid;
04207 int i_relname;
04208 int i_relnamespace;
04209 int i_relkind;
04210 int i_relacl;
04211 int i_rolname;
04212 int i_relchecks;
04213 int i_relhastriggers;
04214 int i_relhasindex;
04215 int i_relhasrules;
04216 int i_relhasoids;
04217 int i_relfrozenxid;
04218 int i_toastoid;
04219 int i_toastfrozenxid;
04220 int i_relpersistence;
04221 int i_isscannable;
04222 int i_owning_tab;
04223 int i_owning_col;
04224 int i_reltablespace;
04225 int i_reloptions;
04226 int i_toastreloptions;
04227 int i_reloftype;
04228 int i_relpages;
04229
04230
04231 selectSourceSchema(fout, "pg_catalog");
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253 if (fout->remoteVersion >= 90300)
04254 {
04255
04256
04257
04258
04259 appendPQExpBuffer(query,
04260 "SELECT c.tableoid, c.oid, c.relname, "
04261 "c.relacl, c.relkind, c.relnamespace, "
04262 "(%s c.relowner) AS rolname, "
04263 "c.relchecks, c.relhastriggers, "
04264 "c.relhasindex, c.relhasrules, c.relhasoids, "
04265 "c.relfrozenxid, tc.oid AS toid, "
04266 "tc.relfrozenxid AS tfrozenxid, "
04267 "c.relpersistence, "
04268 "CASE WHEN c.relkind = '%c' THEN pg_relation_is_scannable(c.oid) ELSE 't'::bool END as isscannable, "
04269 "c.relpages, "
04270 "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
04271 "d.refobjid AS owning_tab, "
04272 "d.refobjsubid AS owning_col, "
04273 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
04274 "array_to_string(c.reloptions, ', ') AS reloptions, "
04275 "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
04276 "FROM pg_class c "
04277 "LEFT JOIN pg_depend d ON "
04278 "(c.relkind = '%c' AND "
04279 "d.classid = c.tableoid AND d.objid = c.oid AND "
04280 "d.objsubid = 0 AND "
04281 "d.refclassid = c.tableoid AND d.deptype = 'a') "
04282 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
04283 "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
04284 "ORDER BY c.oid",
04285 username_subquery,
04286 RELKIND_MATVIEW,
04287 RELKIND_SEQUENCE,
04288 RELKIND_RELATION, RELKIND_SEQUENCE,
04289 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
04290 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
04291 }
04292 else if (fout->remoteVersion >= 90100)
04293 {
04294
04295
04296
04297
04298 appendPQExpBuffer(query,
04299 "SELECT c.tableoid, c.oid, c.relname, "
04300 "c.relacl, c.relkind, c.relnamespace, "
04301 "(%s c.relowner) AS rolname, "
04302 "c.relchecks, c.relhastriggers, "
04303 "c.relhasindex, c.relhasrules, c.relhasoids, "
04304 "c.relfrozenxid, tc.oid AS toid, "
04305 "tc.relfrozenxid AS tfrozenxid, "
04306 "c.relpersistence, 't'::bool as isscannable, "
04307 "c.relpages, "
04308 "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
04309 "d.refobjid AS owning_tab, "
04310 "d.refobjsubid AS owning_col, "
04311 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
04312 "array_to_string(c.reloptions, ', ') AS reloptions, "
04313 "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
04314 "FROM pg_class c "
04315 "LEFT JOIN pg_depend d ON "
04316 "(c.relkind = '%c' AND "
04317 "d.classid = c.tableoid AND d.objid = c.oid AND "
04318 "d.objsubid = 0 AND "
04319 "d.refclassid = c.tableoid AND d.deptype = 'a') "
04320 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
04321 "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
04322 "ORDER BY c.oid",
04323 username_subquery,
04324 RELKIND_SEQUENCE,
04325 RELKIND_RELATION, RELKIND_SEQUENCE,
04326 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
04327 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
04328 }
04329 else if (fout->remoteVersion >= 90000)
04330 {
04331
04332
04333
04334
04335 appendPQExpBuffer(query,
04336 "SELECT c.tableoid, c.oid, c.relname, "
04337 "c.relacl, c.relkind, c.relnamespace, "
04338 "(%s c.relowner) AS rolname, "
04339 "c.relchecks, c.relhastriggers, "
04340 "c.relhasindex, c.relhasrules, c.relhasoids, "
04341 "c.relfrozenxid, tc.oid AS toid, "
04342 "tc.relfrozenxid AS tfrozenxid, "
04343 "'p' AS relpersistence, 't'::bool as isscannable, "
04344 "c.relpages, "
04345 "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
04346 "d.refobjid AS owning_tab, "
04347 "d.refobjsubid AS owning_col, "
04348 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
04349 "array_to_string(c.reloptions, ', ') AS reloptions, "
04350 "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
04351 "FROM pg_class c "
04352 "LEFT JOIN pg_depend d ON "
04353 "(c.relkind = '%c' AND "
04354 "d.classid = c.tableoid AND d.objid = c.oid AND "
04355 "d.objsubid = 0 AND "
04356 "d.refclassid = c.tableoid AND d.deptype = 'a') "
04357 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
04358 "WHERE c.relkind in ('%c', '%c', '%c', '%c') "
04359 "ORDER BY c.oid",
04360 username_subquery,
04361 RELKIND_SEQUENCE,
04362 RELKIND_RELATION, RELKIND_SEQUENCE,
04363 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
04364 }
04365 else if (fout->remoteVersion >= 80400)
04366 {
04367
04368
04369
04370
04371 appendPQExpBuffer(query,
04372 "SELECT c.tableoid, c.oid, c.relname, "
04373 "c.relacl, c.relkind, c.relnamespace, "
04374 "(%s c.relowner) AS rolname, "
04375 "c.relchecks, c.relhastriggers, "
04376 "c.relhasindex, c.relhasrules, c.relhasoids, "
04377 "c.relfrozenxid, tc.oid AS toid, "
04378 "tc.relfrozenxid AS tfrozenxid, "
04379 "'p' AS relpersistence, 't'::bool as isscannable, "
04380 "c.relpages, "
04381 "NULL AS reloftype, "
04382 "d.refobjid AS owning_tab, "
04383 "d.refobjsubid AS owning_col, "
04384 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
04385 "array_to_string(c.reloptions, ', ') AS reloptions, "
04386 "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
04387 "FROM pg_class c "
04388 "LEFT JOIN pg_depend d ON "
04389 "(c.relkind = '%c' AND "
04390 "d.classid = c.tableoid AND d.objid = c.oid AND "
04391 "d.objsubid = 0 AND "
04392 "d.refclassid = c.tableoid AND d.deptype = 'a') "
04393 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
04394 "WHERE c.relkind in ('%c', '%c', '%c', '%c') "
04395 "ORDER BY c.oid",
04396 username_subquery,
04397 RELKIND_SEQUENCE,
04398 RELKIND_RELATION, RELKIND_SEQUENCE,
04399 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
04400 }
04401 else if (fout->remoteVersion >= 80200)
04402 {
04403
04404
04405
04406
04407 appendPQExpBuffer(query,
04408 "SELECT c.tableoid, c.oid, c.relname, "
04409 "c.relacl, c.relkind, c.relnamespace, "
04410 "(%s c.relowner) AS rolname, "
04411 "c.relchecks, (c.reltriggers <> 0) AS relhastriggers, "
04412 "c.relhasindex, c.relhasrules, c.relhasoids, "
04413 "c.relfrozenxid, tc.oid AS toid, "
04414 "tc.relfrozenxid AS tfrozenxid, "
04415 "'p' AS relpersistence, 't'::bool as isscannable, "
04416 "c.relpages, "
04417 "NULL AS reloftype, "
04418 "d.refobjid AS owning_tab, "
04419 "d.refobjsubid AS owning_col, "
04420 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
04421 "array_to_string(c.reloptions, ', ') AS reloptions, "
04422 "NULL AS toast_reloptions "
04423 "FROM pg_class c "
04424 "LEFT JOIN pg_depend d ON "
04425 "(c.relkind = '%c' AND "
04426 "d.classid = c.tableoid AND d.objid = c.oid AND "
04427 "d.objsubid = 0 AND "
04428 "d.refclassid = c.tableoid AND d.deptype = 'a') "
04429 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
04430 "WHERE c.relkind in ('%c', '%c', '%c', '%c') "
04431 "ORDER BY c.oid",
04432 username_subquery,
04433 RELKIND_SEQUENCE,
04434 RELKIND_RELATION, RELKIND_SEQUENCE,
04435 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
04436 }
04437 else if (fout->remoteVersion >= 80000)
04438 {
04439
04440
04441
04442
04443 appendPQExpBuffer(query,
04444 "SELECT c.tableoid, c.oid, relname, "
04445 "relacl, relkind, relnamespace, "
04446 "(%s relowner) AS rolname, "
04447 "relchecks, (reltriggers <> 0) AS relhastriggers, "
04448 "relhasindex, relhasrules, relhasoids, "
04449 "0 AS relfrozenxid, "
04450 "0 AS toid, "
04451 "0 AS tfrozenxid, "
04452 "'p' AS relpersistence, 't'::bool as isscannable, "
04453 "relpages, "
04454 "NULL AS reloftype, "
04455 "d.refobjid AS owning_tab, "
04456 "d.refobjsubid AS owning_col, "
04457 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
04458 "NULL AS reloptions, "
04459 "NULL AS toast_reloptions "
04460 "FROM pg_class c "
04461 "LEFT JOIN pg_depend d ON "
04462 "(c.relkind = '%c' AND "
04463 "d.classid = c.tableoid AND d.objid = c.oid AND "
04464 "d.objsubid = 0 AND "
04465 "d.refclassid = c.tableoid AND d.deptype = 'i') "
04466 "WHERE relkind in ('%c', '%c', '%c', '%c') "
04467 "ORDER BY c.oid",
04468 username_subquery,
04469 RELKIND_SEQUENCE,
04470 RELKIND_RELATION, RELKIND_SEQUENCE,
04471 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
04472 }
04473 else if (fout->remoteVersion >= 70300)
04474 {
04475
04476
04477
04478
04479 appendPQExpBuffer(query,
04480 "SELECT c.tableoid, c.oid, relname, "
04481 "relacl, relkind, relnamespace, "
04482 "(%s relowner) AS rolname, "
04483 "relchecks, (reltriggers <> 0) AS relhastriggers, "
04484 "relhasindex, relhasrules, relhasoids, "
04485 "0 AS relfrozenxid, "
04486 "0 AS toid, "
04487 "0 AS tfrozenxid, "
04488 "'p' AS relpersistence, 't'::bool as isscannable, "
04489 "relpages, "
04490 "NULL AS reloftype, "
04491 "d.refobjid AS owning_tab, "
04492 "d.refobjsubid AS owning_col, "
04493 "NULL AS reltablespace, "
04494 "NULL AS reloptions, "
04495 "NULL AS toast_reloptions "
04496 "FROM pg_class c "
04497 "LEFT JOIN pg_depend d ON "
04498 "(c.relkind = '%c' AND "
04499 "d.classid = c.tableoid AND d.objid = c.oid AND "
04500 "d.objsubid = 0 AND "
04501 "d.refclassid = c.tableoid AND d.deptype = 'i') "
04502 "WHERE relkind IN ('%c', '%c', '%c', '%c') "
04503 "ORDER BY c.oid",
04504 username_subquery,
04505 RELKIND_SEQUENCE,
04506 RELKIND_RELATION, RELKIND_SEQUENCE,
04507 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
04508 }
04509 else if (fout->remoteVersion >= 70200)
04510 {
04511 appendPQExpBuffer(query,
04512 "SELECT tableoid, oid, relname, relacl, relkind, "
04513 "0::oid AS relnamespace, "
04514 "(%s relowner) AS rolname, "
04515 "relchecks, (reltriggers <> 0) AS relhastriggers, "
04516 "relhasindex, relhasrules, relhasoids, "
04517 "0 AS relfrozenxid, "
04518 "0 AS toid, "
04519 "0 AS tfrozenxid, "
04520 "'p' AS relpersistence, 't'::bool as isscannable, "
04521 "relpages, "
04522 "NULL AS reloftype, "
04523 "NULL::oid AS owning_tab, "
04524 "NULL::int4 AS owning_col, "
04525 "NULL AS reltablespace, "
04526 "NULL AS reloptions, "
04527 "NULL AS toast_reloptions "
04528 "FROM pg_class "
04529 "WHERE relkind IN ('%c', '%c', '%c') "
04530 "ORDER BY oid",
04531 username_subquery,
04532 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
04533 }
04534 else if (fout->remoteVersion >= 70100)
04535 {
04536
04537 appendPQExpBuffer(query,
04538 "SELECT tableoid, oid, relname, relacl, relkind, "
04539 "0::oid AS relnamespace, "
04540 "(%s relowner) AS rolname, "
04541 "relchecks, (reltriggers <> 0) AS relhastriggers, "
04542 "relhasindex, relhasrules, "
04543 "'t'::bool AS relhasoids, "
04544 "0 AS relfrozenxid, "
04545 "0 AS toid, "
04546 "0 AS tfrozenxid, "
04547 "'p' AS relpersistence, 't'::bool as isscannable, "
04548 "relpages, "
04549 "NULL AS reloftype, "
04550 "NULL::oid AS owning_tab, "
04551 "NULL::int4 AS owning_col, "
04552 "NULL AS reltablespace, "
04553 "NULL AS reloptions, "
04554 "NULL AS toast_reloptions "
04555 "FROM pg_class "
04556 "WHERE relkind IN ('%c', '%c', '%c') "
04557 "ORDER BY oid",
04558 username_subquery,
04559 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
04560 }
04561 else
04562 {
04563
04564
04565
04566
04567 appendPQExpBuffer(query,
04568 "SELECT "
04569 "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AS tableoid, "
04570 "oid, relname, relacl, "
04571 "CASE WHEN relhasrules and relkind = 'r' "
04572 " and EXISTS(SELECT rulename FROM pg_rewrite r WHERE "
04573 " r.ev_class = c.oid AND r.ev_type = '1') "
04574 "THEN '%c'::\"char\" "
04575 "ELSE relkind END AS relkind,"
04576 "0::oid AS relnamespace, "
04577 "(%s relowner) AS rolname, "
04578 "relchecks, (reltriggers <> 0) AS relhastriggers, "
04579 "relhasindex, relhasrules, "
04580 "'t'::bool AS relhasoids, "
04581 "0 as relfrozenxid, "
04582 "0 AS toid, "
04583 "0 AS tfrozenxid, "
04584 "'p' AS relpersistence, 't'::bool as isscannable, "
04585 "0 AS relpages, "
04586 "NULL AS reloftype, "
04587 "NULL::oid AS owning_tab, "
04588 "NULL::int4 AS owning_col, "
04589 "NULL AS reltablespace, "
04590 "NULL AS reloptions, "
04591 "NULL AS toast_reloptions "
04592 "FROM pg_class c "
04593 "WHERE relkind IN ('%c', '%c') "
04594 "ORDER BY oid",
04595 RELKIND_VIEW,
04596 username_subquery,
04597 RELKIND_RELATION, RELKIND_SEQUENCE);
04598 }
04599
04600 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
04601
04602 ntups = PQntuples(res);
04603
04604 *numTables = ntups;
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615 tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
04616
04617 i_reltableoid = PQfnumber(res, "tableoid");
04618 i_reloid = PQfnumber(res, "oid");
04619 i_relname = PQfnumber(res, "relname");
04620 i_relnamespace = PQfnumber(res, "relnamespace");
04621 i_relacl = PQfnumber(res, "relacl");
04622 i_relkind = PQfnumber(res, "relkind");
04623 i_rolname = PQfnumber(res, "rolname");
04624 i_relchecks = PQfnumber(res, "relchecks");
04625 i_relhastriggers = PQfnumber(res, "relhastriggers");
04626 i_relhasindex = PQfnumber(res, "relhasindex");
04627 i_relhasrules = PQfnumber(res, "relhasrules");
04628 i_relhasoids = PQfnumber(res, "relhasoids");
04629 i_relfrozenxid = PQfnumber(res, "relfrozenxid");
04630 i_toastoid = PQfnumber(res, "toid");
04631 i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
04632 i_relpersistence = PQfnumber(res, "relpersistence");
04633 i_isscannable = PQfnumber(res, "isscannable");
04634 i_relpages = PQfnumber(res, "relpages");
04635 i_owning_tab = PQfnumber(res, "owning_tab");
04636 i_owning_col = PQfnumber(res, "owning_col");
04637 i_reltablespace = PQfnumber(res, "reltablespace");
04638 i_reloptions = PQfnumber(res, "reloptions");
04639 i_toastreloptions = PQfnumber(res, "toast_reloptions");
04640 i_reloftype = PQfnumber(res, "reloftype");
04641
04642 if (lockWaitTimeout && fout->remoteVersion >= 70300)
04643 {
04644
04645
04646
04647
04648
04649
04650
04651 resetPQExpBuffer(query);
04652 appendPQExpBuffer(query, "SET statement_timeout = ");
04653 appendStringLiteralConn(query, lockWaitTimeout, GetConnection(fout));
04654 ExecuteSqlStatement(fout, query->data);
04655 }
04656
04657 for (i = 0; i < ntups; i++)
04658 {
04659 tblinfo[i].dobj.objType = DO_TABLE;
04660 tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
04661 tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
04662 AssignDumpId(&tblinfo[i].dobj);
04663 tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
04664 tblinfo[i].dobj.namespace =
04665 findNamespace(fout,
04666 atooid(PQgetvalue(res, i, i_relnamespace)),
04667 tblinfo[i].dobj.catId.oid);
04668 tblinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
04669 tblinfo[i].relacl = pg_strdup(PQgetvalue(res, i, i_relacl));
04670 tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
04671 tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
04672 tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
04673 tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
04674 tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
04675 tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
04676 tblinfo[i].isscannable = (strcmp(PQgetvalue(res, i, i_isscannable), "t") == 0);
04677 tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
04678 tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
04679 tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
04680 tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
04681 if (PQgetisnull(res, i, i_reloftype))
04682 tblinfo[i].reloftype = NULL;
04683 else
04684 tblinfo[i].reloftype = pg_strdup(PQgetvalue(res, i, i_reloftype));
04685 tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
04686 if (PQgetisnull(res, i, i_owning_tab))
04687 {
04688 tblinfo[i].owning_tab = InvalidOid;
04689 tblinfo[i].owning_col = 0;
04690 }
04691 else
04692 {
04693 tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
04694 tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
04695 }
04696 tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
04697 tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
04698 tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
04699
04700
04701
04702
04703
04704
04705 if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
04706 tblinfo[i].dobj.dump = false;
04707 else
04708 selectDumpableTable(&tblinfo[i]);
04709 tblinfo[i].interesting = tblinfo[i].dobj.dump;
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722 if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION)
04723 {
04724 resetPQExpBuffer(query);
04725 appendPQExpBuffer(query,
04726 "LOCK TABLE %s IN ACCESS SHARE MODE",
04727 fmtQualifiedId(fout->remoteVersion,
04728 tblinfo[i].dobj.namespace->dobj.name,
04729 tblinfo[i].dobj.name));
04730 ExecuteSqlStatement(fout, query->data);
04731 }
04732
04733
04734 if (strlen(tblinfo[i].rolname) == 0)
04735 write_msg(NULL, "WARNING: owner of table \"%s\" appears to be invalid\n",
04736 tblinfo[i].dobj.name);
04737 }
04738
04739 if (lockWaitTimeout && fout->remoteVersion >= 70300)
04740 {
04741 ExecuteSqlStatement(fout, "SET statement_timeout = 0");
04742 }
04743
04744 PQclear(res);
04745
04746 destroyPQExpBuffer(query);
04747
04748 return tblinfo;
04749 }
04750
04751
04752
04753
04754
04755
04756
04757
04758 void
04759 getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
04760 {
04761 int i;
04762
04763
04764
04765
04766
04767 for (i = 0; i < numTables; i++)
04768 {
04769 TableInfo *seqinfo = &tblinfo[i];
04770 TableInfo *owning_tab;
04771
04772 if (!OidIsValid(seqinfo->owning_tab))
04773 continue;
04774 if (seqinfo->dobj.dump)
04775 continue;
04776 owning_tab = findTableByOid(seqinfo->owning_tab);
04777 if (owning_tab && owning_tab->dobj.dump)
04778 {
04779 seqinfo->interesting = true;
04780 seqinfo->dobj.dump = true;
04781 }
04782 }
04783 }
04784
04785
04786
04787
04788
04789
04790
04791
04792 InhInfo *
04793 getInherits(Archive *fout, int *numInherits)
04794 {
04795 PGresult *res;
04796 int ntups;
04797 int i;
04798 PQExpBuffer query = createPQExpBuffer();
04799 InhInfo *inhinfo;
04800
04801 int i_inhrelid;
04802 int i_inhparent;
04803
04804
04805 selectSourceSchema(fout, "pg_catalog");
04806
04807
04808
04809 appendPQExpBuffer(query, "SELECT inhrelid, inhparent FROM pg_inherits");
04810
04811 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
04812
04813 ntups = PQntuples(res);
04814
04815 *numInherits = ntups;
04816
04817 inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
04818
04819 i_inhrelid = PQfnumber(res, "inhrelid");
04820 i_inhparent = PQfnumber(res, "inhparent");
04821
04822 for (i = 0; i < ntups; i++)
04823 {
04824 inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
04825 inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
04826 }
04827
04828 PQclear(res);
04829
04830 destroyPQExpBuffer(query);
04831
04832 return inhinfo;
04833 }
04834
04835
04836
04837
04838
04839
04840
04841
04842 void
04843 getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
04844 {
04845 int i,
04846 j;
04847 PQExpBuffer query = createPQExpBuffer();
04848 PGresult *res;
04849 IndxInfo *indxinfo;
04850 ConstraintInfo *constrinfo;
04851 int i_tableoid,
04852 i_oid,
04853 i_indexname,
04854 i_indexdef,
04855 i_indnkeys,
04856 i_indkey,
04857 i_indisclustered,
04858 i_contype,
04859 i_conname,
04860 i_condeferrable,
04861 i_condeferred,
04862 i_contableoid,
04863 i_conoid,
04864 i_condef,
04865 i_tablespace,
04866 i_options,
04867 i_relpages;
04868 int ntups;
04869
04870 for (i = 0; i < numTables; i++)
04871 {
04872 TableInfo *tbinfo = &tblinfo[i];
04873
04874
04875 if (tbinfo->relkind != RELKIND_RELATION &&
04876 tbinfo->relkind != RELKIND_MATVIEW)
04877 continue;
04878 if (!tbinfo->hasindex)
04879 continue;
04880
04881
04882 if (!tbinfo->dobj.dump)
04883 continue;
04884
04885 if (g_verbose)
04886 write_msg(NULL, "reading indexes for table \"%s\"\n",
04887 tbinfo->dobj.name);
04888
04889
04890 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900
04901
04902
04903 resetPQExpBuffer(query);
04904 if (fout->remoteVersion >= 90000)
04905 {
04906
04907
04908
04909
04910 appendPQExpBuffer(query,
04911 "SELECT t.tableoid, t.oid, "
04912 "t.relname AS indexname, "
04913 "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
04914 "t.relnatts AS indnkeys, "
04915 "i.indkey, i.indisclustered, "
04916 "t.relpages, "
04917 "c.contype, c.conname, "
04918 "c.condeferrable, c.condeferred, "
04919 "c.tableoid AS contableoid, "
04920 "c.oid AS conoid, "
04921 "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
04922 "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
04923 "array_to_string(t.reloptions, ', ') AS options "
04924 "FROM pg_catalog.pg_index i "
04925 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
04926 "LEFT JOIN pg_catalog.pg_constraint c "
04927 "ON (i.indrelid = c.conrelid AND "
04928 "i.indexrelid = c.conindid AND "
04929 "c.contype IN ('p','u','x')) "
04930 "WHERE i.indrelid = '%u'::pg_catalog.oid "
04931 "AND i.indisvalid AND i.indisready "
04932 "ORDER BY indexname",
04933 tbinfo->dobj.catId.oid);
04934 }
04935 else if (fout->remoteVersion >= 80200)
04936 {
04937 appendPQExpBuffer(query,
04938 "SELECT t.tableoid, t.oid, "
04939 "t.relname AS indexname, "
04940 "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
04941 "t.relnatts AS indnkeys, "
04942 "i.indkey, i.indisclustered, "
04943 "t.relpages, "
04944 "c.contype, c.conname, "
04945 "c.condeferrable, c.condeferred, "
04946 "c.tableoid AS contableoid, "
04947 "c.oid AS conoid, "
04948 "null AS condef, "
04949 "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
04950 "array_to_string(t.reloptions, ', ') AS options "
04951 "FROM pg_catalog.pg_index i "
04952 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
04953 "LEFT JOIN pg_catalog.pg_depend d "
04954 "ON (d.classid = t.tableoid "
04955 "AND d.objid = t.oid "
04956 "AND d.deptype = 'i') "
04957 "LEFT JOIN pg_catalog.pg_constraint c "
04958 "ON (d.refclassid = c.tableoid "
04959 "AND d.refobjid = c.oid) "
04960 "WHERE i.indrelid = '%u'::pg_catalog.oid "
04961 "AND i.indisvalid "
04962 "ORDER BY indexname",
04963 tbinfo->dobj.catId.oid);
04964 }
04965 else if (fout->remoteVersion >= 80000)
04966 {
04967 appendPQExpBuffer(query,
04968 "SELECT t.tableoid, t.oid, "
04969 "t.relname AS indexname, "
04970 "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
04971 "t.relnatts AS indnkeys, "
04972 "i.indkey, i.indisclustered, "
04973 "t.relpages, "
04974 "c.contype, c.conname, "
04975 "c.condeferrable, c.condeferred, "
04976 "c.tableoid AS contableoid, "
04977 "c.oid AS conoid, "
04978 "null AS condef, "
04979 "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
04980 "null AS options "
04981 "FROM pg_catalog.pg_index i "
04982 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
04983 "LEFT JOIN pg_catalog.pg_depend d "
04984 "ON (d.classid = t.tableoid "
04985 "AND d.objid = t.oid "
04986 "AND d.deptype = 'i') "
04987 "LEFT JOIN pg_catalog.pg_constraint c "
04988 "ON (d.refclassid = c.tableoid "
04989 "AND d.refobjid = c.oid) "
04990 "WHERE i.indrelid = '%u'::pg_catalog.oid "
04991 "ORDER BY indexname",
04992 tbinfo->dobj.catId.oid);
04993 }
04994 else if (fout->remoteVersion >= 70300)
04995 {
04996 appendPQExpBuffer(query,
04997 "SELECT t.tableoid, t.oid, "
04998 "t.relname AS indexname, "
04999 "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
05000 "t.relnatts AS indnkeys, "
05001 "i.indkey, i.indisclustered, "
05002 "t.relpages, "
05003 "c.contype, c.conname, "
05004 "c.condeferrable, c.condeferred, "
05005 "c.tableoid AS contableoid, "
05006 "c.oid AS conoid, "
05007 "null AS condef, "
05008 "NULL AS tablespace, "
05009 "null AS options "
05010 "FROM pg_catalog.pg_index i "
05011 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
05012 "LEFT JOIN pg_catalog.pg_depend d "
05013 "ON (d.classid = t.tableoid "
05014 "AND d.objid = t.oid "
05015 "AND d.deptype = 'i') "
05016 "LEFT JOIN pg_catalog.pg_constraint c "
05017 "ON (d.refclassid = c.tableoid "
05018 "AND d.refobjid = c.oid) "
05019 "WHERE i.indrelid = '%u'::pg_catalog.oid "
05020 "ORDER BY indexname",
05021 tbinfo->dobj.catId.oid);
05022 }
05023 else if (fout->remoteVersion >= 70100)
05024 {
05025 appendPQExpBuffer(query,
05026 "SELECT t.tableoid, t.oid, "
05027 "t.relname AS indexname, "
05028 "pg_get_indexdef(i.indexrelid) AS indexdef, "
05029 "t.relnatts AS indnkeys, "
05030 "i.indkey, false AS indisclustered, "
05031 "t.relpages, "
05032 "CASE WHEN i.indisprimary THEN 'p'::char "
05033 "ELSE '0'::char END AS contype, "
05034 "t.relname AS conname, "
05035 "false AS condeferrable, "
05036 "false AS condeferred, "
05037 "0::oid AS contableoid, "
05038 "t.oid AS conoid, "
05039 "null AS condef, "
05040 "NULL AS tablespace, "
05041 "null AS options "
05042 "FROM pg_index i, pg_class t "
05043 "WHERE t.oid = i.indexrelid "
05044 "AND i.indrelid = '%u'::oid "
05045 "ORDER BY indexname",
05046 tbinfo->dobj.catId.oid);
05047 }
05048 else
05049 {
05050 appendPQExpBuffer(query,
05051 "SELECT "
05052 "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AS tableoid, "
05053 "t.oid, "
05054 "t.relname AS indexname, "
05055 "pg_get_indexdef(i.indexrelid) AS indexdef, "
05056 "t.relnatts AS indnkeys, "
05057 "i.indkey, false AS indisclustered, "
05058 "t.relpages, "
05059 "CASE WHEN i.indisprimary THEN 'p'::char "
05060 "ELSE '0'::char END AS contype, "
05061 "t.relname AS conname, "
05062 "false AS condeferrable, "
05063 "false AS condeferred, "
05064 "0::oid AS contableoid, "
05065 "t.oid AS conoid, "
05066 "null AS condef, "
05067 "NULL AS tablespace, "
05068 "null AS options "
05069 "FROM pg_index i, pg_class t "
05070 "WHERE t.oid = i.indexrelid "
05071 "AND i.indrelid = '%u'::oid "
05072 "ORDER BY indexname",
05073 tbinfo->dobj.catId.oid);
05074 }
05075
05076 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05077
05078 ntups = PQntuples(res);
05079
05080 i_tableoid = PQfnumber(res, "tableoid");
05081 i_oid = PQfnumber(res, "oid");
05082 i_indexname = PQfnumber(res, "indexname");
05083 i_indexdef = PQfnumber(res, "indexdef");
05084 i_indnkeys = PQfnumber(res, "indnkeys");
05085 i_indkey = PQfnumber(res, "indkey");
05086 i_indisclustered = PQfnumber(res, "indisclustered");
05087 i_relpages = PQfnumber(res, "relpages");
05088 i_contype = PQfnumber(res, "contype");
05089 i_conname = PQfnumber(res, "conname");
05090 i_condeferrable = PQfnumber(res, "condeferrable");
05091 i_condeferred = PQfnumber(res, "condeferred");
05092 i_contableoid = PQfnumber(res, "contableoid");
05093 i_conoid = PQfnumber(res, "conoid");
05094 i_condef = PQfnumber(res, "condef");
05095 i_tablespace = PQfnumber(res, "tablespace");
05096 i_options = PQfnumber(res, "options");
05097
05098 indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
05099 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
05100
05101 for (j = 0; j < ntups; j++)
05102 {
05103 char contype;
05104
05105 indxinfo[j].dobj.objType = DO_INDEX;
05106 indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
05107 indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
05108 AssignDumpId(&indxinfo[j].dobj);
05109 indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
05110 indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
05111 indxinfo[j].indextable = tbinfo;
05112 indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
05113 indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
05114 indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
05115 indxinfo[j].options = pg_strdup(PQgetvalue(res, j, i_options));
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126 indxinfo[j].indkeys = (Oid *) pg_malloc(INDEX_MAX_KEYS * sizeof(Oid));
05127 parseOidArray(PQgetvalue(res, j, i_indkey),
05128 indxinfo[j].indkeys, INDEX_MAX_KEYS);
05129 indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
05130 indxinfo[j].relpages = atoi(PQgetvalue(res, j, i_relpages));
05131 contype = *(PQgetvalue(res, j, i_contype));
05132
05133 if (contype == 'p' || contype == 'u' || contype == 'x')
05134 {
05135
05136
05137
05138
05139
05140
05141
05142 constrinfo[j].dobj.objType = DO_CONSTRAINT;
05143 constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
05144 constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
05145 AssignDumpId(&constrinfo[j].dobj);
05146 constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
05147 constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
05148 constrinfo[j].contable = tbinfo;
05149 constrinfo[j].condomain = NULL;
05150 constrinfo[j].contype = contype;
05151 if (contype == 'x')
05152 constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
05153 else
05154 constrinfo[j].condef = NULL;
05155 constrinfo[j].confrelid = InvalidOid;
05156 constrinfo[j].conindex = indxinfo[j].dobj.dumpId;
05157 constrinfo[j].condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
05158 constrinfo[j].condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
05159 constrinfo[j].conislocal = true;
05160 constrinfo[j].separate = true;
05161
05162 indxinfo[j].indexconstraint = constrinfo[j].dobj.dumpId;
05163
05164
05165 addObjectDependency(&constrinfo[j].dobj,
05166 tbinfo->dobj.dumpId);
05167 }
05168 else
05169 {
05170
05171 indxinfo[j].indexconstraint = 0;
05172 }
05173 }
05174
05175 PQclear(res);
05176 }
05177
05178 destroyPQExpBuffer(query);
05179 }
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190 void
05191 getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
05192 {
05193 int i,
05194 j;
05195 ConstraintInfo *constrinfo;
05196 PQExpBuffer query;
05197 PGresult *res;
05198 int i_contableoid,
05199 i_conoid,
05200 i_conname,
05201 i_confrelid,
05202 i_condef;
05203 int ntups;
05204
05205
05206 if (fout->remoteVersion < 70300)
05207 return;
05208
05209 query = createPQExpBuffer();
05210
05211 for (i = 0; i < numTables; i++)
05212 {
05213 TableInfo *tbinfo = &tblinfo[i];
05214
05215 if (!tbinfo->hastriggers || !tbinfo->dobj.dump)
05216 continue;
05217
05218 if (g_verbose)
05219 write_msg(NULL, "reading foreign key constraints for table \"%s\"\n",
05220 tbinfo->dobj.name);
05221
05222
05223
05224
05225
05226 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
05227
05228 resetPQExpBuffer(query);
05229 appendPQExpBuffer(query,
05230 "SELECT tableoid, oid, conname, confrelid, "
05231 "pg_catalog.pg_get_constraintdef(oid) AS condef "
05232 "FROM pg_catalog.pg_constraint "
05233 "WHERE conrelid = '%u'::pg_catalog.oid "
05234 "AND contype = 'f'",
05235 tbinfo->dobj.catId.oid);
05236 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05237
05238 ntups = PQntuples(res);
05239
05240 i_contableoid = PQfnumber(res, "tableoid");
05241 i_conoid = PQfnumber(res, "oid");
05242 i_conname = PQfnumber(res, "conname");
05243 i_confrelid = PQfnumber(res, "confrelid");
05244 i_condef = PQfnumber(res, "condef");
05245
05246 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
05247
05248 for (j = 0; j < ntups; j++)
05249 {
05250 constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
05251 constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
05252 constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
05253 AssignDumpId(&constrinfo[j].dobj);
05254 constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
05255 constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
05256 constrinfo[j].contable = tbinfo;
05257 constrinfo[j].condomain = NULL;
05258 constrinfo[j].contype = 'f';
05259 constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
05260 constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
05261 constrinfo[j].conindex = 0;
05262 constrinfo[j].condeferrable = false;
05263 constrinfo[j].condeferred = false;
05264 constrinfo[j].conislocal = true;
05265 constrinfo[j].separate = true;
05266 }
05267
05268 PQclear(res);
05269 }
05270
05271 destroyPQExpBuffer(query);
05272 }
05273
05274
05275
05276
05277
05278
05279 static void
05280 getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
05281 {
05282 int i;
05283 ConstraintInfo *constrinfo;
05284 PQExpBuffer query;
05285 PGresult *res;
05286 int i_tableoid,
05287 i_oid,
05288 i_conname,
05289 i_consrc;
05290 int ntups;
05291
05292
05293 if (fout->remoteVersion < 70300)
05294 return;
05295
05296
05297
05298
05299
05300 selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
05301
05302 query = createPQExpBuffer();
05303
05304 if (fout->remoteVersion >= 90100)
05305 appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
05306 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
05307 "convalidated "
05308 "FROM pg_catalog.pg_constraint "
05309 "WHERE contypid = '%u'::pg_catalog.oid "
05310 "ORDER BY conname",
05311 tyinfo->dobj.catId.oid);
05312
05313 else if (fout->remoteVersion >= 70400)
05314 appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
05315 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
05316 "true as convalidated "
05317 "FROM pg_catalog.pg_constraint "
05318 "WHERE contypid = '%u'::pg_catalog.oid "
05319 "ORDER BY conname",
05320 tyinfo->dobj.catId.oid);
05321 else
05322 appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
05323 "'CHECK (' || consrc || ')' AS consrc, "
05324 "true as convalidated "
05325 "FROM pg_catalog.pg_constraint "
05326 "WHERE contypid = '%u'::pg_catalog.oid "
05327 "ORDER BY conname",
05328 tyinfo->dobj.catId.oid);
05329
05330 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05331
05332 ntups = PQntuples(res);
05333
05334 i_tableoid = PQfnumber(res, "tableoid");
05335 i_oid = PQfnumber(res, "oid");
05336 i_conname = PQfnumber(res, "conname");
05337 i_consrc = PQfnumber(res, "consrc");
05338
05339 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
05340
05341 tyinfo->nDomChecks = ntups;
05342 tyinfo->domChecks = constrinfo;
05343
05344 for (i = 0; i < ntups; i++)
05345 {
05346 bool validated = PQgetvalue(res, i, 4)[0] == 't';
05347
05348 constrinfo[i].dobj.objType = DO_CONSTRAINT;
05349 constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
05350 constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
05351 AssignDumpId(&constrinfo[i].dobj);
05352 constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
05353 constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
05354 constrinfo[i].contable = NULL;
05355 constrinfo[i].condomain = tyinfo;
05356 constrinfo[i].contype = 'c';
05357 constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
05358 constrinfo[i].confrelid = InvalidOid;
05359 constrinfo[i].conindex = 0;
05360 constrinfo[i].condeferrable = false;
05361 constrinfo[i].condeferred = false;
05362 constrinfo[i].conislocal = true;
05363
05364 constrinfo[i].separate = !validated;
05365
05366
05367
05368
05369
05370
05371
05372 if (validated)
05373 addObjectDependency(&tyinfo->dobj,
05374 constrinfo[i].dobj.dumpId);
05375 }
05376
05377 PQclear(res);
05378
05379 destroyPQExpBuffer(query);
05380 }
05381
05382
05383
05384
05385
05386
05387
05388 RuleInfo *
05389 getRules(Archive *fout, int *numRules)
05390 {
05391 PGresult *res;
05392 int ntups;
05393 int i;
05394 PQExpBuffer query = createPQExpBuffer();
05395 RuleInfo *ruleinfo;
05396 int i_tableoid;
05397 int i_oid;
05398 int i_rulename;
05399 int i_ruletable;
05400 int i_ev_type;
05401 int i_is_instead;
05402 int i_ev_enabled;
05403
05404
05405 selectSourceSchema(fout, "pg_catalog");
05406
05407 if (fout->remoteVersion >= 80300)
05408 {
05409 appendPQExpBuffer(query, "SELECT "
05410 "tableoid, oid, rulename, "
05411 "ev_class AS ruletable, ev_type, is_instead, "
05412 "ev_enabled "
05413 "FROM pg_rewrite "
05414 "ORDER BY oid");
05415 }
05416 else if (fout->remoteVersion >= 70100)
05417 {
05418 appendPQExpBuffer(query, "SELECT "
05419 "tableoid, oid, rulename, "
05420 "ev_class AS ruletable, ev_type, is_instead, "
05421 "'O'::char AS ev_enabled "
05422 "FROM pg_rewrite "
05423 "ORDER BY oid");
05424 }
05425 else
05426 {
05427 appendPQExpBuffer(query, "SELECT "
05428 "(SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') AS tableoid, "
05429 "oid, rulename, "
05430 "ev_class AS ruletable, ev_type, is_instead, "
05431 "'O'::char AS ev_enabled "
05432 "FROM pg_rewrite "
05433 "ORDER BY oid");
05434 }
05435
05436 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05437
05438 ntups = PQntuples(res);
05439
05440 *numRules = ntups;
05441
05442 ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
05443
05444 i_tableoid = PQfnumber(res, "tableoid");
05445 i_oid = PQfnumber(res, "oid");
05446 i_rulename = PQfnumber(res, "rulename");
05447 i_ruletable = PQfnumber(res, "ruletable");
05448 i_ev_type = PQfnumber(res, "ev_type");
05449 i_is_instead = PQfnumber(res, "is_instead");
05450 i_ev_enabled = PQfnumber(res, "ev_enabled");
05451
05452 for (i = 0; i < ntups; i++)
05453 {
05454 Oid ruletableoid;
05455
05456 ruleinfo[i].dobj.objType = DO_RULE;
05457 ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
05458 ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
05459 AssignDumpId(&ruleinfo[i].dobj);
05460 ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
05461 ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
05462 ruleinfo[i].ruletable = findTableByOid(ruletableoid);
05463 if (ruleinfo[i].ruletable == NULL)
05464 exit_horribly(NULL, "failed sanity check, parent table OID %u of pg_rewrite entry OID %u not found\n",
05465 ruletableoid, ruleinfo[i].dobj.catId.oid);
05466 ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
05467 ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
05468 ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
05469 ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
05470 ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
05471 if (ruleinfo[i].ruletable)
05472 {
05473
05474
05475
05476
05477
05478
05479
05480 if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
05481 ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
05482 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
05483 {
05484 addObjectDependency(&ruleinfo[i].ruletable->dobj,
05485 ruleinfo[i].dobj.dumpId);
05486
05487 ruleinfo[i].separate = false;
05488 }
05489 else
05490 {
05491 addObjectDependency(&ruleinfo[i].dobj,
05492 ruleinfo[i].ruletable->dobj.dumpId);
05493 ruleinfo[i].separate = true;
05494 }
05495 }
05496 else
05497 ruleinfo[i].separate = true;
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507 ruleinfo[i].reloptions = NULL;
05508 }
05509
05510 PQclear(res);
05511
05512 destroyPQExpBuffer(query);
05513
05514 return ruleinfo;
05515 }
05516
05517
05518
05519
05520
05521
05522
05523
05524 void
05525 getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
05526 {
05527 int i,
05528 j;
05529 PQExpBuffer query = createPQExpBuffer();
05530 PGresult *res;
05531 TriggerInfo *tginfo;
05532 int i_tableoid,
05533 i_oid,
05534 i_tgname,
05535 i_tgfname,
05536 i_tgtype,
05537 i_tgnargs,
05538 i_tgargs,
05539 i_tgisconstraint,
05540 i_tgconstrname,
05541 i_tgconstrrelid,
05542 i_tgconstrrelname,
05543 i_tgenabled,
05544 i_tgdeferrable,
05545 i_tginitdeferred,
05546 i_tgdef;
05547 int ntups;
05548
05549 for (i = 0; i < numTables; i++)
05550 {
05551 TableInfo *tbinfo = &tblinfo[i];
05552
05553 if (!tbinfo->hastriggers || !tbinfo->dobj.dump)
05554 continue;
05555
05556 if (g_verbose)
05557 write_msg(NULL, "reading triggers for table \"%s\"\n",
05558 tbinfo->dobj.name);
05559
05560
05561
05562
05563 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
05564
05565 resetPQExpBuffer(query);
05566 if (fout->remoteVersion >= 90000)
05567 {
05568
05569
05570
05571
05572
05573 appendPQExpBuffer(query,
05574 "SELECT tgname, "
05575 "tgfoid::pg_catalog.regproc AS tgfname, "
05576 "pg_catalog.pg_get_triggerdef(oid, false) AS tgdef, "
05577 "tgenabled, tableoid, oid "
05578 "FROM pg_catalog.pg_trigger t "
05579 "WHERE tgrelid = '%u'::pg_catalog.oid "
05580 "AND NOT tgisinternal",
05581 tbinfo->dobj.catId.oid);
05582 }
05583 else if (fout->remoteVersion >= 80300)
05584 {
05585
05586
05587
05588 appendPQExpBuffer(query,
05589 "SELECT tgname, "
05590 "tgfoid::pg_catalog.regproc AS tgfname, "
05591 "tgtype, tgnargs, tgargs, tgenabled, "
05592 "tgisconstraint, tgconstrname, tgdeferrable, "
05593 "tgconstrrelid, tginitdeferred, tableoid, oid, "
05594 "tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
05595 "FROM pg_catalog.pg_trigger t "
05596 "WHERE tgrelid = '%u'::pg_catalog.oid "
05597 "AND tgconstraint = 0",
05598 tbinfo->dobj.catId.oid);
05599 }
05600 else if (fout->remoteVersion >= 70300)
05601 {
05602
05603
05604
05605
05606
05607 appendPQExpBuffer(query,
05608 "SELECT tgname, "
05609 "tgfoid::pg_catalog.regproc AS tgfname, "
05610 "tgtype, tgnargs, tgargs, tgenabled, "
05611 "tgisconstraint, tgconstrname, tgdeferrable, "
05612 "tgconstrrelid, tginitdeferred, tableoid, oid, "
05613 "tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
05614 "FROM pg_catalog.pg_trigger t "
05615 "WHERE tgrelid = '%u'::pg_catalog.oid "
05616 "AND (NOT tgisconstraint "
05617 " OR NOT EXISTS"
05618 " (SELECT 1 FROM pg_catalog.pg_depend d "
05619 " JOIN pg_catalog.pg_constraint c ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) "
05620 " WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))",
05621 tbinfo->dobj.catId.oid);
05622 }
05623 else if (fout->remoteVersion >= 70100)
05624 {
05625 appendPQExpBuffer(query,
05626 "SELECT tgname, tgfoid::regproc AS tgfname, "
05627 "tgtype, tgnargs, tgargs, tgenabled, "
05628 "tgisconstraint, tgconstrname, tgdeferrable, "
05629 "tgconstrrelid, tginitdeferred, tableoid, oid, "
05630 "(SELECT relname FROM pg_class WHERE oid = tgconstrrelid) "
05631 " AS tgconstrrelname "
05632 "FROM pg_trigger "
05633 "WHERE tgrelid = '%u'::oid",
05634 tbinfo->dobj.catId.oid);
05635 }
05636 else
05637 {
05638 appendPQExpBuffer(query,
05639 "SELECT tgname, tgfoid::regproc AS tgfname, "
05640 "tgtype, tgnargs, tgargs, tgenabled, "
05641 "tgisconstraint, tgconstrname, tgdeferrable, "
05642 "tgconstrrelid, tginitdeferred, "
05643 "(SELECT oid FROM pg_class WHERE relname = 'pg_trigger') AS tableoid, "
05644 "oid, "
05645 "(SELECT relname FROM pg_class WHERE oid = tgconstrrelid) "
05646 " AS tgconstrrelname "
05647 "FROM pg_trigger "
05648 "WHERE tgrelid = '%u'::oid",
05649 tbinfo->dobj.catId.oid);
05650 }
05651 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05652
05653 ntups = PQntuples(res);
05654
05655 i_tableoid = PQfnumber(res, "tableoid");
05656 i_oid = PQfnumber(res, "oid");
05657 i_tgname = PQfnumber(res, "tgname");
05658 i_tgfname = PQfnumber(res, "tgfname");
05659 i_tgtype = PQfnumber(res, "tgtype");
05660 i_tgnargs = PQfnumber(res, "tgnargs");
05661 i_tgargs = PQfnumber(res, "tgargs");
05662 i_tgisconstraint = PQfnumber(res, "tgisconstraint");
05663 i_tgconstrname = PQfnumber(res, "tgconstrname");
05664 i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
05665 i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
05666 i_tgenabled = PQfnumber(res, "tgenabled");
05667 i_tgdeferrable = PQfnumber(res, "tgdeferrable");
05668 i_tginitdeferred = PQfnumber(res, "tginitdeferred");
05669 i_tgdef = PQfnumber(res, "tgdef");
05670
05671 tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
05672
05673 for (j = 0; j < ntups; j++)
05674 {
05675 tginfo[j].dobj.objType = DO_TRIGGER;
05676 tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
05677 tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
05678 AssignDumpId(&tginfo[j].dobj);
05679 tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
05680 tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
05681 tginfo[j].tgtable = tbinfo;
05682 tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
05683 if (i_tgdef >= 0)
05684 {
05685 tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
05686
05687
05688 tginfo[j].tgfname = NULL;
05689 tginfo[j].tgtype = 0;
05690 tginfo[j].tgnargs = 0;
05691 tginfo[j].tgargs = NULL;
05692 tginfo[j].tgisconstraint = false;
05693 tginfo[j].tgdeferrable = false;
05694 tginfo[j].tginitdeferred = false;
05695 tginfo[j].tgconstrname = NULL;
05696 tginfo[j].tgconstrrelid = InvalidOid;
05697 tginfo[j].tgconstrrelname = NULL;
05698 }
05699 else
05700 {
05701 tginfo[j].tgdef = NULL;
05702
05703 tginfo[j].tgfname = pg_strdup(PQgetvalue(res, j, i_tgfname));
05704 tginfo[j].tgtype = atoi(PQgetvalue(res, j, i_tgtype));
05705 tginfo[j].tgnargs = atoi(PQgetvalue(res, j, i_tgnargs));
05706 tginfo[j].tgargs = pg_strdup(PQgetvalue(res, j, i_tgargs));
05707 tginfo[j].tgisconstraint = *(PQgetvalue(res, j, i_tgisconstraint)) == 't';
05708 tginfo[j].tgdeferrable = *(PQgetvalue(res, j, i_tgdeferrable)) == 't';
05709 tginfo[j].tginitdeferred = *(PQgetvalue(res, j, i_tginitdeferred)) == 't';
05710
05711 if (tginfo[j].tgisconstraint)
05712 {
05713 tginfo[j].tgconstrname = pg_strdup(PQgetvalue(res, j, i_tgconstrname));
05714 tginfo[j].tgconstrrelid = atooid(PQgetvalue(res, j, i_tgconstrrelid));
05715 if (OidIsValid(tginfo[j].tgconstrrelid))
05716 {
05717 if (PQgetisnull(res, j, i_tgconstrrelname))
05718 exit_horribly(NULL, "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n",
05719 tginfo[j].dobj.name,
05720 tbinfo->dobj.name,
05721 tginfo[j].tgconstrrelid);
05722 tginfo[j].tgconstrrelname = pg_strdup(PQgetvalue(res, j, i_tgconstrrelname));
05723 }
05724 else
05725 tginfo[j].tgconstrrelname = NULL;
05726 }
05727 else
05728 {
05729 tginfo[j].tgconstrname = NULL;
05730 tginfo[j].tgconstrrelid = InvalidOid;
05731 tginfo[j].tgconstrrelname = NULL;
05732 }
05733 }
05734 }
05735
05736 PQclear(res);
05737 }
05738
05739 destroyPQExpBuffer(query);
05740 }
05741
05742
05743
05744
05745
05746 EventTriggerInfo *
05747 getEventTriggers(Archive *fout, int *numEventTriggers)
05748 {
05749 int i;
05750 PQExpBuffer query = createPQExpBuffer();
05751 PGresult *res;
05752 EventTriggerInfo *evtinfo;
05753 int i_tableoid,
05754 i_oid,
05755 i_evtname,
05756 i_evtevent,
05757 i_evtowner,
05758 i_evttags,
05759 i_evtfname,
05760 i_evtenabled;
05761 int ntups;
05762
05763
05764 if (fout->remoteVersion < 90300)
05765 {
05766 *numEventTriggers = 0;
05767 return NULL;
05768 }
05769
05770
05771 selectSourceSchema(fout, "pg_catalog");
05772
05773 appendPQExpBuffer(query,
05774 "SELECT e.tableoid, e.oid, evtname, evtenabled, "
05775 "evtevent, (%s evtowner) AS evtowner, "
05776 "array_to_string(array("
05777 "select quote_literal(x) "
05778 " from unnest(evttags) as t(x)), ', ') as evttags, "
05779 "e.evtfoid::regproc as evtfname "
05780 "FROM pg_event_trigger e "
05781 "ORDER BY e.oid",
05782 username_subquery);
05783
05784 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05785
05786 ntups = PQntuples(res);
05787
05788 *numEventTriggers = ntups;
05789
05790 evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
05791
05792 i_tableoid = PQfnumber(res, "tableoid");
05793 i_oid = PQfnumber(res, "oid");
05794 i_evtname = PQfnumber(res, "evtname");
05795 i_evtevent = PQfnumber(res, "evtevent");
05796 i_evtowner = PQfnumber(res, "evtowner");
05797 i_evttags = PQfnumber(res, "evttags");
05798 i_evtfname = PQfnumber(res, "evtfname");
05799 i_evtenabled = PQfnumber(res, "evtenabled");
05800
05801 for (i = 0; i < ntups; i++)
05802 {
05803 evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
05804 evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
05805 evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
05806 AssignDumpId(&evtinfo[i].dobj);
05807 evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
05808 evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
05809 evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
05810 evtinfo[i].evtowner = pg_strdup(PQgetvalue(res, i, i_evtowner));
05811 evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
05812 evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
05813 evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
05814 }
05815
05816 PQclear(res);
05817
05818 destroyPQExpBuffer(query);
05819
05820 return evtinfo;
05821 }
05822
05823
05824
05825
05826
05827
05828
05829
05830
05831
05832 ProcLangInfo *
05833 getProcLangs(Archive *fout, int *numProcLangs)
05834 {
05835 PGresult *res;
05836 int ntups;
05837 int i;
05838 PQExpBuffer query = createPQExpBuffer();
05839 ProcLangInfo *planginfo;
05840 int i_tableoid;
05841 int i_oid;
05842 int i_lanname;
05843 int i_lanpltrusted;
05844 int i_lanplcallfoid;
05845 int i_laninline;
05846 int i_lanvalidator;
05847 int i_lanacl;
05848 int i_lanowner;
05849
05850
05851 selectSourceSchema(fout, "pg_catalog");
05852
05853 if (fout->remoteVersion >= 90000)
05854 {
05855
05856 appendPQExpBuffer(query, "SELECT tableoid, oid, "
05857 "lanname, lanpltrusted, lanplcallfoid, "
05858 "laninline, lanvalidator, lanacl, "
05859 "(%s lanowner) AS lanowner "
05860 "FROM pg_language "
05861 "WHERE lanispl "
05862 "ORDER BY oid",
05863 username_subquery);
05864 }
05865 else if (fout->remoteVersion >= 80300)
05866 {
05867
05868 appendPQExpBuffer(query, "SELECT tableoid, oid, "
05869 "lanname, lanpltrusted, lanplcallfoid, "
05870 "lanvalidator, lanacl, "
05871 "(%s lanowner) AS lanowner "
05872 "FROM pg_language "
05873 "WHERE lanispl "
05874 "ORDER BY oid",
05875 username_subquery);
05876 }
05877 else if (fout->remoteVersion >= 80100)
05878 {
05879
05880 appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
05881 "(%s '10') AS lanowner "
05882 "FROM pg_language "
05883 "WHERE lanispl "
05884 "ORDER BY oid",
05885 username_subquery);
05886 }
05887 else if (fout->remoteVersion >= 70400)
05888 {
05889
05890 appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
05891 "(%s '1') AS lanowner "
05892 "FROM pg_language "
05893 "WHERE lanispl "
05894 "ORDER BY oid",
05895 username_subquery);
05896 }
05897 else if (fout->remoteVersion >= 70100)
05898 {
05899
05900 appendPQExpBuffer(query, "SELECT tableoid, oid, * FROM pg_language "
05901 "WHERE lanispl "
05902 "ORDER BY oid");
05903 }
05904 else
05905 {
05906 appendPQExpBuffer(query, "SELECT "
05907 "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, "
05908 "oid, * FROM pg_language "
05909 "WHERE lanispl "
05910 "ORDER BY oid");
05911 }
05912
05913 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
05914
05915 ntups = PQntuples(res);
05916
05917 *numProcLangs = ntups;
05918
05919 planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
05920
05921 i_tableoid = PQfnumber(res, "tableoid");
05922 i_oid = PQfnumber(res, "oid");
05923 i_lanname = PQfnumber(res, "lanname");
05924 i_lanpltrusted = PQfnumber(res, "lanpltrusted");
05925 i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
05926
05927 i_laninline = PQfnumber(res, "laninline");
05928 i_lanvalidator = PQfnumber(res, "lanvalidator");
05929 i_lanacl = PQfnumber(res, "lanacl");
05930 i_lanowner = PQfnumber(res, "lanowner");
05931
05932 for (i = 0; i < ntups; i++)
05933 {
05934 planginfo[i].dobj.objType = DO_PROCLANG;
05935 planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
05936 planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
05937 AssignDumpId(&planginfo[i].dobj);
05938
05939 planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
05940 planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
05941 planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
05942 if (i_laninline >= 0)
05943 planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
05944 else
05945 planginfo[i].laninline = InvalidOid;
05946 if (i_lanvalidator >= 0)
05947 planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
05948 else
05949 planginfo[i].lanvalidator = InvalidOid;
05950 if (i_lanacl >= 0)
05951 planginfo[i].lanacl = pg_strdup(PQgetvalue(res, i, i_lanacl));
05952 else
05953 planginfo[i].lanacl = pg_strdup("{=U}");
05954 if (i_lanowner >= 0)
05955 planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner));
05956 else
05957 planginfo[i].lanowner = pg_strdup("");
05958
05959 if (fout->remoteVersion < 70300)
05960 {
05961
05962
05963
05964
05965
05966 FuncInfo *funcInfo = findFuncByOid(planginfo[i].lanplcallfoid);
05967
05968 if (funcInfo)
05969 addObjectDependency(&planginfo[i].dobj,
05970 funcInfo->dobj.dumpId);
05971 }
05972 }
05973
05974 PQclear(res);
05975
05976 destroyPQExpBuffer(query);
05977
05978 return planginfo;
05979 }
05980
05981
05982
05983
05984
05985
05986
05987 CastInfo *
05988 getCasts(Archive *fout, int *numCasts)
05989 {
05990 PGresult *res;
05991 int ntups;
05992 int i;
05993 PQExpBuffer query = createPQExpBuffer();
05994 CastInfo *castinfo;
05995 int i_tableoid;
05996 int i_oid;
05997 int i_castsource;
05998 int i_casttarget;
05999 int i_castfunc;
06000 int i_castcontext;
06001 int i_castmethod;
06002
06003
06004 selectSourceSchema(fout, "pg_catalog");
06005
06006 if (fout->remoteVersion >= 80400)
06007 {
06008 appendPQExpBuffer(query, "SELECT tableoid, oid, "
06009 "castsource, casttarget, castfunc, castcontext, "
06010 "castmethod "
06011 "FROM pg_cast ORDER BY 3,4");
06012 }
06013 else if (fout->remoteVersion >= 70300)
06014 {
06015 appendPQExpBuffer(query, "SELECT tableoid, oid, "
06016 "castsource, casttarget, castfunc, castcontext, "
06017 "CASE WHEN castfunc = 0 THEN 'b' ELSE 'f' END AS castmethod "
06018 "FROM pg_cast ORDER BY 3,4");
06019 }
06020 else
06021 {
06022 appendPQExpBuffer(query, "SELECT 0 AS tableoid, p.oid, "
06023 "t1.oid AS castsource, t2.oid AS casttarget, "
06024 "p.oid AS castfunc, 'e' AS castcontext, "
06025 "'f' AS castmethod "
06026 "FROM pg_type t1, pg_type t2, pg_proc p "
06027 "WHERE p.pronargs = 1 AND "
06028 "p.proargtypes[0] = t1.oid AND "
06029 "p.prorettype = t2.oid AND p.proname = t2.typname "
06030 "ORDER BY 3,4");
06031 }
06032
06033 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
06034
06035 ntups = PQntuples(res);
06036
06037 *numCasts = ntups;
06038
06039 castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
06040
06041 i_tableoid = PQfnumber(res, "tableoid");
06042 i_oid = PQfnumber(res, "oid");
06043 i_castsource = PQfnumber(res, "castsource");
06044 i_casttarget = PQfnumber(res, "casttarget");
06045 i_castfunc = PQfnumber(res, "castfunc");
06046 i_castcontext = PQfnumber(res, "castcontext");
06047 i_castmethod = PQfnumber(res, "castmethod");
06048
06049 for (i = 0; i < ntups; i++)
06050 {
06051 PQExpBufferData namebuf;
06052 TypeInfo *sTypeInfo;
06053 TypeInfo *tTypeInfo;
06054
06055 castinfo[i].dobj.objType = DO_CAST;
06056 castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
06057 castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
06058 AssignDumpId(&castinfo[i].dobj);
06059 castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
06060 castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
06061 castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
06062 castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
06063 castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
06064
06065
06066
06067
06068
06069
06070 initPQExpBuffer(&namebuf);
06071 sTypeInfo = findTypeByOid(castinfo[i].castsource);
06072 tTypeInfo = findTypeByOid(castinfo[i].casttarget);
06073 if (sTypeInfo && tTypeInfo)
06074 appendPQExpBuffer(&namebuf, "%s %s",
06075 sTypeInfo->dobj.name, tTypeInfo->dobj.name);
06076 castinfo[i].dobj.name = namebuf.data;
06077
06078 if (OidIsValid(castinfo[i].castfunc))
06079 {
06080
06081
06082
06083
06084
06085 FuncInfo *funcInfo;
06086
06087 funcInfo = findFuncByOid(castinfo[i].castfunc);
06088 if (funcInfo)
06089 addObjectDependency(&castinfo[i].dobj,
06090 funcInfo->dobj.dumpId);
06091 }
06092 }
06093
06094 PQclear(res);
06095
06096 destroyPQExpBuffer(query);
06097
06098 return castinfo;
06099 }
06100
06101
06102
06103
06104
06105
06106
06107
06108
06109
06110
06111
06112
06113
06114 void
06115 getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
06116 {
06117 int i,
06118 j;
06119 PQExpBuffer q = createPQExpBuffer();
06120 int i_attnum;
06121 int i_attname;
06122 int i_atttypname;
06123 int i_atttypmod;
06124 int i_attstattarget;
06125 int i_attstorage;
06126 int i_typstorage;
06127 int i_attnotnull;
06128 int i_atthasdef;
06129 int i_attisdropped;
06130 int i_attlen;
06131 int i_attalign;
06132 int i_attislocal;
06133 int i_attoptions;
06134 int i_attcollation;
06135 int i_attfdwoptions;
06136 PGresult *res;
06137 int ntups;
06138 bool hasdefaults;
06139
06140 for (i = 0; i < numTables; i++)
06141 {
06142 TableInfo *tbinfo = &tblinfo[i];
06143
06144
06145 if (tbinfo->relkind == RELKIND_SEQUENCE)
06146 continue;
06147
06148
06149 if (!tbinfo->interesting)
06150 continue;
06151
06152
06153
06154
06155
06156 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
06157
06158
06159
06160
06161
06162
06163
06164
06165
06166
06167 if (g_verbose)
06168 write_msg(NULL, "finding the columns and types of table \"%s\"\n",
06169 tbinfo->dobj.name);
06170
06171 resetPQExpBuffer(q);
06172
06173 if (fout->remoteVersion >= 90200)
06174 {
06175
06176
06177
06178 appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
06179 "a.attstattarget, a.attstorage, t.typstorage, "
06180 "a.attnotnull, a.atthasdef, a.attisdropped, "
06181 "a.attlen, a.attalign, a.attislocal, "
06182 "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
06183 "array_to_string(a.attoptions, ', ') AS attoptions, "
06184 "CASE WHEN a.attcollation <> t.typcollation "
06185 "THEN a.attcollation ELSE 0 END AS attcollation, "
06186 "pg_catalog.array_to_string(ARRAY("
06187 "SELECT pg_catalog.quote_ident(option_name) || "
06188 "' ' || pg_catalog.quote_literal(option_value) "
06189 "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
06190 "ORDER BY option_name"
06191 "), E',\n ') AS attfdwoptions "
06192 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
06193 "ON a.atttypid = t.oid "
06194 "WHERE a.attrelid = '%u'::pg_catalog.oid "
06195 "AND a.attnum > 0::pg_catalog.int2 "
06196 "ORDER BY a.attrelid, a.attnum",
06197 tbinfo->dobj.catId.oid);
06198 }
06199 else if (fout->remoteVersion >= 90100)
06200 {
06201
06202
06203
06204
06205
06206
06207 appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
06208 "a.attstattarget, a.attstorage, t.typstorage, "
06209 "a.attnotnull, a.atthasdef, a.attisdropped, "
06210 "a.attlen, a.attalign, a.attislocal, "
06211 "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
06212 "array_to_string(a.attoptions, ', ') AS attoptions, "
06213 "CASE WHEN a.attcollation <> t.typcollation "
06214 "THEN a.attcollation ELSE 0 END AS attcollation, "
06215 "NULL AS attfdwoptions "
06216 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
06217 "ON a.atttypid = t.oid "
06218 "WHERE a.attrelid = '%u'::pg_catalog.oid "
06219 "AND a.attnum > 0::pg_catalog.int2 "
06220 "ORDER BY a.attrelid, a.attnum",
06221 tbinfo->dobj.catId.oid);
06222 }
06223 else if (fout->remoteVersion >= 90000)
06224 {
06225
06226 appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
06227 "a.attstattarget, a.attstorage, t.typstorage, "
06228 "a.attnotnull, a.atthasdef, a.attisdropped, "
06229 "a.attlen, a.attalign, a.attislocal, "
06230 "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
06231 "array_to_string(a.attoptions, ', ') AS attoptions, "
06232 "0 AS attcollation, "
06233 "NULL AS attfdwoptions "
06234 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
06235 "ON a.atttypid = t.oid "
06236 "WHERE a.attrelid = '%u'::pg_catalog.oid "
06237 "AND a.attnum > 0::pg_catalog.int2 "
06238 "ORDER BY a.attrelid, a.attnum",
06239 tbinfo->dobj.catId.oid);
06240 }
06241 else if (fout->remoteVersion >= 70300)
06242 {
06243
06244 appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
06245 "a.attstattarget, a.attstorage, t.typstorage, "
06246 "a.attnotnull, a.atthasdef, a.attisdropped, "
06247 "a.attlen, a.attalign, a.attislocal, "
06248 "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
06249 "'' AS attoptions, 0 AS attcollation, "
06250 "NULL AS attfdwoptions "
06251 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
06252 "ON a.atttypid = t.oid "
06253 "WHERE a.attrelid = '%u'::pg_catalog.oid "
06254 "AND a.attnum > 0::pg_catalog.int2 "
06255 "ORDER BY a.attrelid, a.attnum",
06256 tbinfo->dobj.catId.oid);
06257 }
06258 else if (fout->remoteVersion >= 70100)
06259 {
06260
06261
06262
06263
06264
06265
06266
06267
06268 appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
06269 "-1 AS attstattarget, a.attstorage, "
06270 "t.typstorage, a.attnotnull, a.atthasdef, "
06271 "false AS attisdropped, a.attlen, "
06272 "a.attalign, true AS attislocal, "
06273 "format_type(t.oid,a.atttypmod) AS atttypname, "
06274 "'' AS attoptions, 0 AS attcollation, "
06275 "NULL AS attfdwoptions "
06276 "FROM pg_attribute a LEFT JOIN pg_type t "
06277 "ON a.atttypid = t.oid "
06278 "WHERE a.attrelid = '%u'::oid "
06279 "AND a.attnum > 0::int2 "
06280 "ORDER BY a.attrelid, a.attnum",
06281 tbinfo->dobj.catId.oid);
06282 }
06283 else
06284 {
06285
06286 appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, "
06287 "-1 AS attstattarget, "
06288 "attstorage, attstorage AS typstorage, "
06289 "attnotnull, atthasdef, false AS attisdropped, "
06290 "attlen, attalign, "
06291 "true AS attislocal, "
06292 "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname, "
06293 "'' AS attoptions, 0 AS attcollation, "
06294 "NULL AS attfdwoptions "
06295 "FROM pg_attribute a "
06296 "WHERE attrelid = '%u'::oid "
06297 "AND attnum > 0::int2 "
06298 "ORDER BY attrelid, attnum",
06299 tbinfo->dobj.catId.oid);
06300 }
06301
06302 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
06303
06304 ntups = PQntuples(res);
06305
06306 i_attnum = PQfnumber(res, "attnum");
06307 i_attname = PQfnumber(res, "attname");
06308 i_atttypname = PQfnumber(res, "atttypname");
06309 i_atttypmod = PQfnumber(res, "atttypmod");
06310 i_attstattarget = PQfnumber(res, "attstattarget");
06311 i_attstorage = PQfnumber(res, "attstorage");
06312 i_typstorage = PQfnumber(res, "typstorage");
06313 i_attnotnull = PQfnumber(res, "attnotnull");
06314 i_atthasdef = PQfnumber(res, "atthasdef");
06315 i_attisdropped = PQfnumber(res, "attisdropped");
06316 i_attlen = PQfnumber(res, "attlen");
06317 i_attalign = PQfnumber(res, "attalign");
06318 i_attislocal = PQfnumber(res, "attislocal");
06319 i_attoptions = PQfnumber(res, "attoptions");
06320 i_attcollation = PQfnumber(res, "attcollation");
06321 i_attfdwoptions = PQfnumber(res, "attfdwoptions");
06322
06323 tbinfo->numatts = ntups;
06324 tbinfo->attnames = (char **) pg_malloc(ntups * sizeof(char *));
06325 tbinfo->atttypnames = (char **) pg_malloc(ntups * sizeof(char *));
06326 tbinfo->atttypmod = (int *) pg_malloc(ntups * sizeof(int));
06327 tbinfo->attstattarget = (int *) pg_malloc(ntups * sizeof(int));
06328 tbinfo->attstorage = (char *) pg_malloc(ntups * sizeof(char));
06329 tbinfo->typstorage = (char *) pg_malloc(ntups * sizeof(char));
06330 tbinfo->attisdropped = (bool *) pg_malloc(ntups * sizeof(bool));
06331 tbinfo->attlen = (int *) pg_malloc(ntups * sizeof(int));
06332 tbinfo->attalign = (char *) pg_malloc(ntups * sizeof(char));
06333 tbinfo->attislocal = (bool *) pg_malloc(ntups * sizeof(bool));
06334 tbinfo->attoptions = (char **) pg_malloc(ntups * sizeof(char *));
06335 tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid));
06336 tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *));
06337 tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool));
06338 tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool));
06339 tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
06340 hasdefaults = false;
06341
06342 for (j = 0; j < ntups; j++)
06343 {
06344 if (j + 1 != atoi(PQgetvalue(res, j, i_attnum)))
06345 exit_horribly(NULL,
06346 "invalid column numbering in table \"%s\"\n",
06347 tbinfo->dobj.name);
06348 tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname));
06349 tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname));
06350 tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
06351 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget));
06352 tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
06353 tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
06354 tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
06355 tbinfo->attlen[j] = atoi(PQgetvalue(res, j, i_attlen));
06356 tbinfo->attalign[j] = *(PQgetvalue(res, j, i_attalign));
06357 tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
06358 tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
06359 tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, i_attoptions));
06360 tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, i_attcollation));
06361 tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, i_attfdwoptions));
06362 tbinfo->attrdefs[j] = NULL;
06363 if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
06364 hasdefaults = true;
06365
06366 tbinfo->inhNotNull[j] = false;
06367 }
06368
06369 PQclear(res);
06370
06371
06372
06373
06374 if (hasdefaults)
06375 {
06376 AttrDefInfo *attrdefs;
06377 int numDefaults;
06378
06379 if (g_verbose)
06380 write_msg(NULL, "finding default expressions of table \"%s\"\n",
06381 tbinfo->dobj.name);
06382
06383 resetPQExpBuffer(q);
06384 if (fout->remoteVersion >= 70300)
06385 {
06386 appendPQExpBuffer(q, "SELECT tableoid, oid, adnum, "
06387 "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc "
06388 "FROM pg_catalog.pg_attrdef "
06389 "WHERE adrelid = '%u'::pg_catalog.oid",
06390 tbinfo->dobj.catId.oid);
06391 }
06392 else if (fout->remoteVersion >= 70200)
06393 {
06394
06395 appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, adnum, "
06396 "pg_get_expr(adbin, adrelid) AS adsrc "
06397 "FROM pg_attrdef "
06398 "WHERE adrelid = '%u'::oid",
06399 tbinfo->dobj.catId.oid);
06400 }
06401 else if (fout->remoteVersion >= 70100)
06402 {
06403
06404 appendPQExpBuffer(q, "SELECT tableoid, oid, adnum, adsrc "
06405 "FROM pg_attrdef "
06406 "WHERE adrelid = '%u'::oid",
06407 tbinfo->dobj.catId.oid);
06408 }
06409 else
06410 {
06411
06412 appendPQExpBuffer(q, "SELECT "
06413 "(SELECT oid FROM pg_class WHERE relname = 'pg_attrdef') AS tableoid, "
06414 "oid, adnum, adsrc "
06415 "FROM pg_attrdef "
06416 "WHERE adrelid = '%u'::oid",
06417 tbinfo->dobj.catId.oid);
06418 }
06419 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
06420
06421 numDefaults = PQntuples(res);
06422 attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
06423
06424 for (j = 0; j < numDefaults; j++)
06425 {
06426 int adnum;
06427
06428 adnum = atoi(PQgetvalue(res, j, 2));
06429
06430 if (adnum <= 0 || adnum > ntups)
06431 exit_horribly(NULL,
06432 "invalid adnum value %d for table \"%s\"\n",
06433 adnum, tbinfo->dobj.name);
06434
06435
06436
06437
06438
06439 if (tbinfo->attisdropped[adnum - 1])
06440 continue;
06441
06442 attrdefs[j].dobj.objType = DO_ATTRDEF;
06443 attrdefs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
06444 attrdefs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1));
06445 AssignDumpId(&attrdefs[j].dobj);
06446 attrdefs[j].adtable = tbinfo;
06447 attrdefs[j].adnum = adnum;
06448 attrdefs[j].adef_expr = pg_strdup(PQgetvalue(res, j, 3));
06449
06450 attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
06451 attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
06452
06453 attrdefs[j].dobj.dump = tbinfo->dobj.dump;
06454
06455
06456
06457
06458
06459
06460
06461 if (tbinfo->relkind == RELKIND_VIEW)
06462 {
06463 attrdefs[j].separate = true;
06464
06465 addObjectDependency(&attrdefs[j].dobj,
06466 tbinfo->dobj.dumpId);
06467 }
06468 else if (!shouldPrintColumn(tbinfo, adnum - 1))
06469 {
06470
06471 attrdefs[j].separate = true;
06472
06473 addObjectDependency(&attrdefs[j].dobj,
06474 tbinfo->dobj.dumpId);
06475 }
06476 else
06477 {
06478 attrdefs[j].separate = false;
06479
06480
06481
06482
06483
06484
06485
06486 addObjectDependency(&tbinfo->dobj,
06487 attrdefs[j].dobj.dumpId);
06488 }
06489
06490 tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
06491 }
06492 PQclear(res);
06493 }
06494
06495
06496
06497
06498 if (tbinfo->ncheck > 0)
06499 {
06500 ConstraintInfo *constrs;
06501 int numConstrs;
06502
06503 if (g_verbose)
06504 write_msg(NULL, "finding check constraints for table \"%s\"\n",
06505 tbinfo->dobj.name);
06506
06507 resetPQExpBuffer(q);
06508 if (fout->remoteVersion >= 90200)
06509 {
06510
06511
06512
06513
06514 appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
06515 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
06516 "conislocal, convalidated "
06517 "FROM pg_catalog.pg_constraint "
06518 "WHERE conrelid = '%u'::pg_catalog.oid "
06519 " AND contype = 'c' "
06520 "ORDER BY conname",
06521 tbinfo->dobj.catId.oid);
06522 }
06523 else if (fout->remoteVersion >= 80400)
06524 {
06525
06526 appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
06527 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
06528 "conislocal, true AS convalidated "
06529 "FROM pg_catalog.pg_constraint "
06530 "WHERE conrelid = '%u'::pg_catalog.oid "
06531 " AND contype = 'c' "
06532 "ORDER BY conname",
06533 tbinfo->dobj.catId.oid);
06534 }
06535 else if (fout->remoteVersion >= 70400)
06536 {
06537 appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
06538 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
06539 "true AS conislocal, true AS convalidated "
06540 "FROM pg_catalog.pg_constraint "
06541 "WHERE conrelid = '%u'::pg_catalog.oid "
06542 " AND contype = 'c' "
06543 "ORDER BY conname",
06544 tbinfo->dobj.catId.oid);
06545 }
06546 else if (fout->remoteVersion >= 70300)
06547 {
06548
06549 appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
06550 "'CHECK (' || consrc || ')' AS consrc, "
06551 "true AS conislocal, true AS convalidated "
06552 "FROM pg_catalog.pg_constraint "
06553 "WHERE conrelid = '%u'::pg_catalog.oid "
06554 " AND contype = 'c' "
06555 "ORDER BY conname",
06556 tbinfo->dobj.catId.oid);
06557 }
06558 else if (fout->remoteVersion >= 70200)
06559 {
06560
06561 appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, "
06562 "rcname AS conname, "
06563 "'CHECK (' || rcsrc || ')' AS consrc, "
06564 "true AS conislocal, true AS convalidated "
06565 "FROM pg_relcheck "
06566 "WHERE rcrelid = '%u'::oid "
06567 "ORDER BY rcname",
06568 tbinfo->dobj.catId.oid);
06569 }
06570 else if (fout->remoteVersion >= 70100)
06571 {
06572 appendPQExpBuffer(q, "SELECT tableoid, oid, "
06573 "rcname AS conname, "
06574 "'CHECK (' || rcsrc || ')' AS consrc, "
06575 "true AS conislocal, true AS convalidated "
06576 "FROM pg_relcheck "
06577 "WHERE rcrelid = '%u'::oid "
06578 "ORDER BY rcname",
06579 tbinfo->dobj.catId.oid);
06580 }
06581 else
06582 {
06583
06584 appendPQExpBuffer(q, "SELECT "
06585 "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
06586 "oid, rcname AS conname, "
06587 "'CHECK (' || rcsrc || ')' AS consrc, "
06588 "true AS conislocal, true AS convalidated "
06589 "FROM pg_relcheck "
06590 "WHERE rcrelid = '%u'::oid "
06591 "ORDER BY rcname",
06592 tbinfo->dobj.catId.oid);
06593 }
06594 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
06595
06596 numConstrs = PQntuples(res);
06597 if (numConstrs != tbinfo->ncheck)
06598 {
06599 write_msg(NULL, ngettext("expected %d check constraint on table \"%s\" but found %d\n",
06600 "expected %d check constraints on table \"%s\" but found %d\n",
06601 tbinfo->ncheck),
06602 tbinfo->ncheck, tbinfo->dobj.name, numConstrs);
06603 write_msg(NULL, "(The system catalogs might be corrupted.)\n");
06604 exit_nicely(1);
06605 }
06606
06607 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
06608 tbinfo->checkexprs = constrs;
06609
06610 for (j = 0; j < numConstrs; j++)
06611 {
06612 bool validated = PQgetvalue(res, j, 5)[0] == 't';
06613
06614 constrs[j].dobj.objType = DO_CONSTRAINT;
06615 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
06616 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1));
06617 AssignDumpId(&constrs[j].dobj);
06618 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, 2));
06619 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
06620 constrs[j].contable = tbinfo;
06621 constrs[j].condomain = NULL;
06622 constrs[j].contype = 'c';
06623 constrs[j].condef = pg_strdup(PQgetvalue(res, j, 3));
06624 constrs[j].confrelid = InvalidOid;
06625 constrs[j].conindex = 0;
06626 constrs[j].condeferrable = false;
06627 constrs[j].condeferred = false;
06628 constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't');
06629
06630
06631
06632
06633
06634
06635 constrs[j].separate = !validated;
06636
06637 constrs[j].dobj.dump = tbinfo->dobj.dump;
06638
06639
06640
06641
06642
06643
06644
06645
06646
06647
06648 if (!constrs[j].separate)
06649 addObjectDependency(&tbinfo->dobj,
06650 constrs[j].dobj.dumpId);
06651
06652
06653
06654
06655
06656
06657 }
06658 PQclear(res);
06659 }
06660 }
06661
06662 destroyPQExpBuffer(q);
06663 }
06664
06665
06666
06667
06668
06669
06670
06671
06672
06673
06674
06675
06676
06677
06678
06679 bool
06680 shouldPrintColumn(TableInfo *tbinfo, int colno)
06681 {
06682 if (binary_upgrade)
06683 return true;
06684 return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]);
06685 }
06686
06687
06688
06689
06690
06691
06692
06693
06694
06695 TSParserInfo *
06696 getTSParsers(Archive *fout, int *numTSParsers)
06697 {
06698 PGresult *res;
06699 int ntups;
06700 int i;
06701 PQExpBuffer query;
06702 TSParserInfo *prsinfo;
06703 int i_tableoid;
06704 int i_oid;
06705 int i_prsname;
06706 int i_prsnamespace;
06707 int i_prsstart;
06708 int i_prstoken;
06709 int i_prsend;
06710 int i_prsheadline;
06711 int i_prslextype;
06712
06713
06714 if (fout->remoteVersion < 80300)
06715 {
06716 *numTSParsers = 0;
06717 return NULL;
06718 }
06719
06720 query = createPQExpBuffer();
06721
06722
06723
06724
06725
06726
06727
06728 selectSourceSchema(fout, "pg_catalog");
06729
06730 appendPQExpBuffer(query, "SELECT tableoid, oid, prsname, prsnamespace, "
06731 "prsstart::oid, prstoken::oid, "
06732 "prsend::oid, prsheadline::oid, prslextype::oid "
06733 "FROM pg_ts_parser");
06734
06735 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
06736
06737 ntups = PQntuples(res);
06738 *numTSParsers = ntups;
06739
06740 prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
06741
06742 i_tableoid = PQfnumber(res, "tableoid");
06743 i_oid = PQfnumber(res, "oid");
06744 i_prsname = PQfnumber(res, "prsname");
06745 i_prsnamespace = PQfnumber(res, "prsnamespace");
06746 i_prsstart = PQfnumber(res, "prsstart");
06747 i_prstoken = PQfnumber(res, "prstoken");
06748 i_prsend = PQfnumber(res, "prsend");
06749 i_prsheadline = PQfnumber(res, "prsheadline");
06750 i_prslextype = PQfnumber(res, "prslextype");
06751
06752 for (i = 0; i < ntups; i++)
06753 {
06754 prsinfo[i].dobj.objType = DO_TSPARSER;
06755 prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
06756 prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
06757 AssignDumpId(&prsinfo[i].dobj);
06758 prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
06759 prsinfo[i].dobj.namespace =
06760 findNamespace(fout,
06761 atooid(PQgetvalue(res, i, i_prsnamespace)),
06762 prsinfo[i].dobj.catId.oid);
06763 prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
06764 prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
06765 prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
06766 prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
06767 prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
06768
06769
06770 selectDumpableObject(&(prsinfo[i].dobj));
06771 }
06772
06773 PQclear(res);
06774
06775 destroyPQExpBuffer(query);
06776
06777 return prsinfo;
06778 }
06779
06780
06781
06782
06783
06784
06785
06786
06787 TSDictInfo *
06788 getTSDictionaries(Archive *fout, int *numTSDicts)
06789 {
06790 PGresult *res;
06791 int ntups;
06792 int i;
06793 PQExpBuffer query;
06794 TSDictInfo *dictinfo;
06795 int i_tableoid;
06796 int i_oid;
06797 int i_dictname;
06798 int i_dictnamespace;
06799 int i_rolname;
06800 int i_dicttemplate;
06801 int i_dictinitoption;
06802
06803
06804 if (fout->remoteVersion < 80300)
06805 {
06806 *numTSDicts = 0;
06807 return NULL;
06808 }
06809
06810 query = createPQExpBuffer();
06811
06812
06813 selectSourceSchema(fout, "pg_catalog");
06814
06815 appendPQExpBuffer(query, "SELECT tableoid, oid, dictname, "
06816 "dictnamespace, (%s dictowner) AS rolname, "
06817 "dicttemplate, dictinitoption "
06818 "FROM pg_ts_dict",
06819 username_subquery);
06820
06821 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
06822
06823 ntups = PQntuples(res);
06824 *numTSDicts = ntups;
06825
06826 dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
06827
06828 i_tableoid = PQfnumber(res, "tableoid");
06829 i_oid = PQfnumber(res, "oid");
06830 i_dictname = PQfnumber(res, "dictname");
06831 i_dictnamespace = PQfnumber(res, "dictnamespace");
06832 i_rolname = PQfnumber(res, "rolname");
06833 i_dictinitoption = PQfnumber(res, "dictinitoption");
06834 i_dicttemplate = PQfnumber(res, "dicttemplate");
06835
06836 for (i = 0; i < ntups; i++)
06837 {
06838 dictinfo[i].dobj.objType = DO_TSDICT;
06839 dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
06840 dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
06841 AssignDumpId(&dictinfo[i].dobj);
06842 dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
06843 dictinfo[i].dobj.namespace =
06844 findNamespace(fout,
06845 atooid(PQgetvalue(res, i, i_dictnamespace)),
06846 dictinfo[i].dobj.catId.oid);
06847 dictinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
06848 dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
06849 if (PQgetisnull(res, i, i_dictinitoption))
06850 dictinfo[i].dictinitoption = NULL;
06851 else
06852 dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
06853
06854
06855 selectDumpableObject(&(dictinfo[i].dobj));
06856 }
06857
06858 PQclear(res);
06859
06860 destroyPQExpBuffer(query);
06861
06862 return dictinfo;
06863 }
06864
06865
06866
06867
06868
06869
06870
06871
06872 TSTemplateInfo *
06873 getTSTemplates(Archive *fout, int *numTSTemplates)
06874 {
06875 PGresult *res;
06876 int ntups;
06877 int i;
06878 PQExpBuffer query;
06879 TSTemplateInfo *tmplinfo;
06880 int i_tableoid;
06881 int i_oid;
06882 int i_tmplname;
06883 int i_tmplnamespace;
06884 int i_tmplinit;
06885 int i_tmpllexize;
06886
06887
06888 if (fout->remoteVersion < 80300)
06889 {
06890 *numTSTemplates = 0;
06891 return NULL;
06892 }
06893
06894 query = createPQExpBuffer();
06895
06896
06897 selectSourceSchema(fout, "pg_catalog");
06898
06899 appendPQExpBuffer(query, "SELECT tableoid, oid, tmplname, "
06900 "tmplnamespace, tmplinit::oid, tmpllexize::oid "
06901 "FROM pg_ts_template");
06902
06903 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
06904
06905 ntups = PQntuples(res);
06906 *numTSTemplates = ntups;
06907
06908 tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
06909
06910 i_tableoid = PQfnumber(res, "tableoid");
06911 i_oid = PQfnumber(res, "oid");
06912 i_tmplname = PQfnumber(res, "tmplname");
06913 i_tmplnamespace = PQfnumber(res, "tmplnamespace");
06914 i_tmplinit = PQfnumber(res, "tmplinit");
06915 i_tmpllexize = PQfnumber(res, "tmpllexize");
06916
06917 for (i = 0; i < ntups; i++)
06918 {
06919 tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
06920 tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
06921 tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
06922 AssignDumpId(&tmplinfo[i].dobj);
06923 tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
06924 tmplinfo[i].dobj.namespace =
06925 findNamespace(fout,
06926 atooid(PQgetvalue(res, i, i_tmplnamespace)),
06927 tmplinfo[i].dobj.catId.oid);
06928 tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
06929 tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
06930
06931
06932 selectDumpableObject(&(tmplinfo[i].dobj));
06933 }
06934
06935 PQclear(res);
06936
06937 destroyPQExpBuffer(query);
06938
06939 return tmplinfo;
06940 }
06941
06942
06943
06944
06945
06946
06947
06948
06949 TSConfigInfo *
06950 getTSConfigurations(Archive *fout, int *numTSConfigs)
06951 {
06952 PGresult *res;
06953 int ntups;
06954 int i;
06955 PQExpBuffer query;
06956 TSConfigInfo *cfginfo;
06957 int i_tableoid;
06958 int i_oid;
06959 int i_cfgname;
06960 int i_cfgnamespace;
06961 int i_rolname;
06962 int i_cfgparser;
06963
06964
06965 if (fout->remoteVersion < 80300)
06966 {
06967 *numTSConfigs = 0;
06968 return NULL;
06969 }
06970
06971 query = createPQExpBuffer();
06972
06973
06974 selectSourceSchema(fout, "pg_catalog");
06975
06976 appendPQExpBuffer(query, "SELECT tableoid, oid, cfgname, "
06977 "cfgnamespace, (%s cfgowner) AS rolname, cfgparser "
06978 "FROM pg_ts_config",
06979 username_subquery);
06980
06981 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
06982
06983 ntups = PQntuples(res);
06984 *numTSConfigs = ntups;
06985
06986 cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
06987
06988 i_tableoid = PQfnumber(res, "tableoid");
06989 i_oid = PQfnumber(res, "oid");
06990 i_cfgname = PQfnumber(res, "cfgname");
06991 i_cfgnamespace = PQfnumber(res, "cfgnamespace");
06992 i_rolname = PQfnumber(res, "rolname");
06993 i_cfgparser = PQfnumber(res, "cfgparser");
06994
06995 for (i = 0; i < ntups; i++)
06996 {
06997 cfginfo[i].dobj.objType = DO_TSCONFIG;
06998 cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
06999 cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
07000 AssignDumpId(&cfginfo[i].dobj);
07001 cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
07002 cfginfo[i].dobj.namespace =
07003 findNamespace(fout,
07004 atooid(PQgetvalue(res, i, i_cfgnamespace)),
07005 cfginfo[i].dobj.catId.oid);
07006 cfginfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
07007 cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
07008
07009
07010 selectDumpableObject(&(cfginfo[i].dobj));
07011 }
07012
07013 PQclear(res);
07014
07015 destroyPQExpBuffer(query);
07016
07017 return cfginfo;
07018 }
07019
07020
07021
07022
07023
07024
07025
07026
07027 FdwInfo *
07028 getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
07029 {
07030 PGresult *res;
07031 int ntups;
07032 int i;
07033 PQExpBuffer query = createPQExpBuffer();
07034 FdwInfo *fdwinfo;
07035 int i_tableoid;
07036 int i_oid;
07037 int i_fdwname;
07038 int i_rolname;
07039 int i_fdwhandler;
07040 int i_fdwvalidator;
07041 int i_fdwacl;
07042 int i_fdwoptions;
07043
07044
07045 if (fout->remoteVersion < 80400)
07046 {
07047 *numForeignDataWrappers = 0;
07048 return NULL;
07049 }
07050
07051
07052 selectSourceSchema(fout, "pg_catalog");
07053
07054 if (fout->remoteVersion >= 90100)
07055 {
07056 appendPQExpBuffer(query, "SELECT tableoid, oid, fdwname, "
07057 "(%s fdwowner) AS rolname, "
07058 "fdwhandler::pg_catalog.regproc, "
07059 "fdwvalidator::pg_catalog.regproc, fdwacl, "
07060 "array_to_string(ARRAY("
07061 "SELECT quote_ident(option_name) || ' ' || "
07062 "quote_literal(option_value) "
07063 "FROM pg_options_to_table(fdwoptions) "
07064 "ORDER BY option_name"
07065 "), E',\n ') AS fdwoptions "
07066 "FROM pg_foreign_data_wrapper",
07067 username_subquery);
07068 }
07069 else
07070 {
07071 appendPQExpBuffer(query, "SELECT tableoid, oid, fdwname, "
07072 "(%s fdwowner) AS rolname, "
07073 "'-' AS fdwhandler, "
07074 "fdwvalidator::pg_catalog.regproc, fdwacl, "
07075 "array_to_string(ARRAY("
07076 "SELECT quote_ident(option_name) || ' ' || "
07077 "quote_literal(option_value) "
07078 "FROM pg_options_to_table(fdwoptions) "
07079 "ORDER BY option_name"
07080 "), E',\n ') AS fdwoptions "
07081 "FROM pg_foreign_data_wrapper",
07082 username_subquery);
07083 }
07084
07085 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
07086
07087 ntups = PQntuples(res);
07088 *numForeignDataWrappers = ntups;
07089
07090 fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
07091
07092 i_tableoid = PQfnumber(res, "tableoid");
07093 i_oid = PQfnumber(res, "oid");
07094 i_fdwname = PQfnumber(res, "fdwname");
07095 i_rolname = PQfnumber(res, "rolname");
07096 i_fdwhandler = PQfnumber(res, "fdwhandler");
07097 i_fdwvalidator = PQfnumber(res, "fdwvalidator");
07098 i_fdwacl = PQfnumber(res, "fdwacl");
07099 i_fdwoptions = PQfnumber(res, "fdwoptions");
07100
07101 for (i = 0; i < ntups; i++)
07102 {
07103 fdwinfo[i].dobj.objType = DO_FDW;
07104 fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
07105 fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
07106 AssignDumpId(&fdwinfo[i].dobj);
07107 fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
07108 fdwinfo[i].dobj.namespace = NULL;
07109 fdwinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
07110 fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
07111 fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
07112 fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
07113 fdwinfo[i].fdwacl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
07114
07115
07116 selectDumpableObject(&(fdwinfo[i].dobj));
07117 }
07118
07119 PQclear(res);
07120
07121 destroyPQExpBuffer(query);
07122
07123 return fdwinfo;
07124 }
07125
07126
07127
07128
07129
07130
07131
07132
07133 ForeignServerInfo *
07134 getForeignServers(Archive *fout, int *numForeignServers)
07135 {
07136 PGresult *res;
07137 int ntups;
07138 int i;
07139 PQExpBuffer query = createPQExpBuffer();
07140 ForeignServerInfo *srvinfo;
07141 int i_tableoid;
07142 int i_oid;
07143 int i_srvname;
07144 int i_rolname;
07145 int i_srvfdw;
07146 int i_srvtype;
07147 int i_srvversion;
07148 int i_srvacl;
07149 int i_srvoptions;
07150
07151
07152 if (fout->remoteVersion < 80400)
07153 {
07154 *numForeignServers = 0;
07155 return NULL;
07156 }
07157
07158
07159 selectSourceSchema(fout, "pg_catalog");
07160
07161 appendPQExpBuffer(query, "SELECT tableoid, oid, srvname, "
07162 "(%s srvowner) AS rolname, "
07163 "srvfdw, srvtype, srvversion, srvacl,"
07164 "array_to_string(ARRAY("
07165 "SELECT quote_ident(option_name) || ' ' || "
07166 "quote_literal(option_value) "
07167 "FROM pg_options_to_table(srvoptions) "
07168 "ORDER BY option_name"
07169 "), E',\n ') AS srvoptions "
07170 "FROM pg_foreign_server",
07171 username_subquery);
07172
07173 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
07174
07175 ntups = PQntuples(res);
07176 *numForeignServers = ntups;
07177
07178 srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
07179
07180 i_tableoid = PQfnumber(res, "tableoid");
07181 i_oid = PQfnumber(res, "oid");
07182 i_srvname = PQfnumber(res, "srvname");
07183 i_rolname = PQfnumber(res, "rolname");
07184 i_srvfdw = PQfnumber(res, "srvfdw");
07185 i_srvtype = PQfnumber(res, "srvtype");
07186 i_srvversion = PQfnumber(res, "srvversion");
07187 i_srvacl = PQfnumber(res, "srvacl");
07188 i_srvoptions = PQfnumber(res, "srvoptions");
07189
07190 for (i = 0; i < ntups; i++)
07191 {
07192 srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
07193 srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
07194 srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
07195 AssignDumpId(&srvinfo[i].dobj);
07196 srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
07197 srvinfo[i].dobj.namespace = NULL;
07198 srvinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
07199 srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
07200 srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
07201 srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
07202 srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
07203 srvinfo[i].srvacl = pg_strdup(PQgetvalue(res, i, i_srvacl));
07204
07205
07206 selectDumpableObject(&(srvinfo[i].dobj));
07207 }
07208
07209 PQclear(res);
07210
07211 destroyPQExpBuffer(query);
07212
07213 return srvinfo;
07214 }
07215
07216
07217
07218
07219
07220
07221
07222
07223 DefaultACLInfo *
07224 getDefaultACLs(Archive *fout, int *numDefaultACLs)
07225 {
07226 DefaultACLInfo *daclinfo;
07227 PQExpBuffer query;
07228 PGresult *res;
07229 int i_oid;
07230 int i_tableoid;
07231 int i_defaclrole;
07232 int i_defaclnamespace;
07233 int i_defaclobjtype;
07234 int i_defaclacl;
07235 int i,
07236 ntups;
07237
07238 if (fout->remoteVersion < 90000)
07239 {
07240 *numDefaultACLs = 0;
07241 return NULL;
07242 }
07243
07244 query = createPQExpBuffer();
07245
07246
07247 selectSourceSchema(fout, "pg_catalog");
07248
07249 appendPQExpBuffer(query, "SELECT oid, tableoid, "
07250 "(%s defaclrole) AS defaclrole, "
07251 "defaclnamespace, "
07252 "defaclobjtype, "
07253 "defaclacl "
07254 "FROM pg_default_acl",
07255 username_subquery);
07256
07257 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
07258
07259 ntups = PQntuples(res);
07260 *numDefaultACLs = ntups;
07261
07262 daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
07263
07264 i_oid = PQfnumber(res, "oid");
07265 i_tableoid = PQfnumber(res, "tableoid");
07266 i_defaclrole = PQfnumber(res, "defaclrole");
07267 i_defaclnamespace = PQfnumber(res, "defaclnamespace");
07268 i_defaclobjtype = PQfnumber(res, "defaclobjtype");
07269 i_defaclacl = PQfnumber(res, "defaclacl");
07270
07271 for (i = 0; i < ntups; i++)
07272 {
07273 Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
07274
07275 daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
07276 daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
07277 daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
07278 AssignDumpId(&daclinfo[i].dobj);
07279
07280 daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
07281
07282 if (nspid != InvalidOid)
07283 daclinfo[i].dobj.namespace = findNamespace(fout, nspid,
07284 daclinfo[i].dobj.catId.oid);
07285 else
07286 daclinfo[i].dobj.namespace = NULL;
07287
07288 daclinfo[i].defaclrole = pg_strdup(PQgetvalue(res, i, i_defaclrole));
07289 daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
07290 daclinfo[i].defaclacl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
07291
07292
07293 selectDumpableDefaultACL(&(daclinfo[i]));
07294 }
07295
07296 PQclear(res);
07297
07298 destroyPQExpBuffer(query);
07299
07300 return daclinfo;
07301 }
07302
07303
07304
07305
07306
07307
07308
07309
07310
07311
07312
07313
07314
07315
07316
07317
07318
07319
07320
07321 static void
07322 dumpComment(Archive *fout, const char *target,
07323 const char *namespace, const char *owner,
07324 CatalogId catalogId, int subid, DumpId dumpId)
07325 {
07326 CommentItem *comments;
07327 int ncomments;
07328
07329
07330 if (strncmp(target, "LARGE OBJECT ", 13) != 0)
07331 {
07332 if (dataOnly)
07333 return;
07334 }
07335 else
07336 {
07337 if (schemaOnly)
07338 return;
07339 }
07340
07341
07342 ncomments = findComments(fout, catalogId.tableoid, catalogId.oid,
07343 &comments);
07344
07345
07346 while (ncomments > 0)
07347 {
07348 if (comments->objsubid == subid)
07349 break;
07350 comments++;
07351 ncomments--;
07352 }
07353
07354
07355 if (ncomments > 0)
07356 {
07357 PQExpBuffer query = createPQExpBuffer();
07358
07359 appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
07360 appendStringLiteralAH(query, comments->descr, fout);
07361 appendPQExpBuffer(query, ";\n");
07362
07363
07364
07365
07366
07367
07368 ArchiveEntry(fout, nilCatalogId, createDumpId(),
07369 target, namespace, NULL, owner,
07370 false, "COMMENT", SECTION_NONE,
07371 query->data, "", NULL,
07372 &(dumpId), 1,
07373 NULL, NULL);
07374
07375 destroyPQExpBuffer(query);
07376 }
07377 }
07378
07379
07380
07381
07382
07383
07384
07385 static void
07386 dumpTableComment(Archive *fout, TableInfo *tbinfo,
07387 const char *reltypename)
07388 {
07389 CommentItem *comments;
07390 int ncomments;
07391 PQExpBuffer query;
07392 PQExpBuffer target;
07393
07394
07395 if (dataOnly)
07396 return;
07397
07398
07399 ncomments = findComments(fout,
07400 tbinfo->dobj.catId.tableoid,
07401 tbinfo->dobj.catId.oid,
07402 &comments);
07403
07404
07405 if (ncomments <= 0)
07406 return;
07407
07408 query = createPQExpBuffer();
07409 target = createPQExpBuffer();
07410
07411 while (ncomments > 0)
07412 {
07413 const char *descr = comments->descr;
07414 int objsubid = comments->objsubid;
07415
07416 if (objsubid == 0)
07417 {
07418 resetPQExpBuffer(target);
07419 appendPQExpBuffer(target, "%s %s", reltypename,
07420 fmtId(tbinfo->dobj.name));
07421
07422 resetPQExpBuffer(query);
07423 appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
07424 appendStringLiteralAH(query, descr, fout);
07425 appendPQExpBuffer(query, ";\n");
07426
07427 ArchiveEntry(fout, nilCatalogId, createDumpId(),
07428 target->data,
07429 tbinfo->dobj.namespace->dobj.name,
07430 NULL, tbinfo->rolname,
07431 false, "COMMENT", SECTION_NONE,
07432 query->data, "", NULL,
07433 &(tbinfo->dobj.dumpId), 1,
07434 NULL, NULL);
07435 }
07436 else if (objsubid > 0 && objsubid <= tbinfo->numatts)
07437 {
07438 resetPQExpBuffer(target);
07439 appendPQExpBuffer(target, "COLUMN %s.",
07440 fmtId(tbinfo->dobj.name));
07441 appendPQExpBuffer(target, "%s",
07442 fmtId(tbinfo->attnames[objsubid - 1]));
07443
07444 resetPQExpBuffer(query);
07445 appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
07446 appendStringLiteralAH(query, descr, fout);
07447 appendPQExpBuffer(query, ";\n");
07448
07449 ArchiveEntry(fout, nilCatalogId, createDumpId(),
07450 target->data,
07451 tbinfo->dobj.namespace->dobj.name,
07452 NULL, tbinfo->rolname,
07453 false, "COMMENT", SECTION_NONE,
07454 query->data, "", NULL,
07455 &(tbinfo->dobj.dumpId), 1,
07456 NULL, NULL);
07457 }
07458
07459 comments++;
07460 ncomments--;
07461 }
07462
07463 destroyPQExpBuffer(query);
07464 destroyPQExpBuffer(target);
07465 }
07466
07467
07468
07469
07470
07471
07472
07473
07474 static int
07475 findComments(Archive *fout, Oid classoid, Oid objoid,
07476 CommentItem **items)
07477 {
07478
07479 static CommentItem *comments = NULL;
07480 static int ncomments = -1;
07481
07482 CommentItem *middle = NULL;
07483 CommentItem *low;
07484 CommentItem *high;
07485 int nmatch;
07486
07487
07488 if (ncomments < 0)
07489 ncomments = collectComments(fout, &comments);
07490
07491
07492
07493
07494
07495
07496 if (fout->remoteVersion < 70200)
07497 classoid = 0;
07498
07499
07500
07501
07502 low = &comments[0];
07503 high = &comments[ncomments - 1];
07504 while (low <= high)
07505 {
07506 middle = low + (high - low) / 2;
07507
07508 if (classoid < middle->classoid)
07509 high = middle - 1;
07510 else if (classoid > middle->classoid)
07511 low = middle + 1;
07512 else if (objoid < middle->objoid)
07513 high = middle - 1;
07514 else if (objoid > middle->objoid)
07515 low = middle + 1;
07516 else
07517 break;
07518 }
07519
07520 if (low > high)
07521 {
07522 *items = NULL;
07523 return 0;
07524 }
07525
07526
07527
07528
07529
07530
07531 nmatch = 1;
07532 while (middle > low)
07533 {
07534 if (classoid != middle[-1].classoid ||
07535 objoid != middle[-1].objoid)
07536 break;
07537 middle--;
07538 nmatch++;
07539 }
07540
07541 *items = middle;
07542
07543 middle += nmatch;
07544 while (middle <= high)
07545 {
07546 if (classoid != middle->classoid ||
07547 objoid != middle->objoid)
07548 break;
07549 middle++;
07550 nmatch++;
07551 }
07552
07553 return nmatch;
07554 }
07555
07556
07557
07558
07559
07560
07561
07562
07563
07564
07565
07566 static int
07567 collectComments(Archive *fout, CommentItem **items)
07568 {
07569 PGresult *res;
07570 PQExpBuffer query;
07571 int i_description;
07572 int i_classoid;
07573 int i_objoid;
07574 int i_objsubid;
07575 int ntups;
07576 int i;
07577 CommentItem *comments;
07578
07579
07580
07581
07582
07583
07584 query = createPQExpBuffer();
07585
07586 if (fout->remoteVersion >= 70300)
07587 {
07588 appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid "
07589 "FROM pg_catalog.pg_description "
07590 "ORDER BY classoid, objoid, objsubid");
07591 }
07592 else if (fout->remoteVersion >= 70200)
07593 {
07594 appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid "
07595 "FROM pg_description "
07596 "ORDER BY classoid, objoid, objsubid");
07597 }
07598 else
07599 {
07600
07601 appendPQExpBuffer(query, "SELECT description, 0 AS classoid, objoid, 0 AS objsubid "
07602 "FROM pg_description "
07603 "ORDER BY objoid");
07604 }
07605
07606 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
07607
07608
07609
07610 i_description = PQfnumber(res, "description");
07611 i_classoid = PQfnumber(res, "classoid");
07612 i_objoid = PQfnumber(res, "objoid");
07613 i_objsubid = PQfnumber(res, "objsubid");
07614
07615 ntups = PQntuples(res);
07616
07617 comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
07618
07619 for (i = 0; i < ntups; i++)
07620 {
07621 comments[i].descr = PQgetvalue(res, i, i_description);
07622 comments[i].classoid = atooid(PQgetvalue(res, i, i_classoid));
07623 comments[i].objoid = atooid(PQgetvalue(res, i, i_objoid));
07624 comments[i].objsubid = atoi(PQgetvalue(res, i, i_objsubid));
07625 }
07626
07627
07628 destroyPQExpBuffer(query);
07629
07630 *items = comments;
07631 return ntups;
07632 }
07633
07634
07635
07636
07637
07638
07639
07640 static void
07641 dumpDumpableObject(Archive *fout, DumpableObject *dobj)
07642 {
07643 switch (dobj->objType)
07644 {
07645 case DO_NAMESPACE:
07646 dumpNamespace(fout, (NamespaceInfo *) dobj);
07647 break;
07648 case DO_EXTENSION:
07649 dumpExtension(fout, (ExtensionInfo *) dobj);
07650 break;
07651 case DO_TYPE:
07652 dumpType(fout, (TypeInfo *) dobj);
07653 break;
07654 case DO_SHELL_TYPE:
07655 dumpShellType(fout, (ShellTypeInfo *) dobj);
07656 break;
07657 case DO_FUNC:
07658 dumpFunc(fout, (FuncInfo *) dobj);
07659 break;
07660 case DO_AGG:
07661 dumpAgg(fout, (AggInfo *) dobj);
07662 break;
07663 case DO_OPERATOR:
07664 dumpOpr(fout, (OprInfo *) dobj);
07665 break;
07666 case DO_OPCLASS:
07667 dumpOpclass(fout, (OpclassInfo *) dobj);
07668 break