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;
07669 case DO_OPFAMILY:
07670 dumpOpfamily(fout, (OpfamilyInfo *) dobj);
07671 break;
07672 case DO_COLLATION:
07673 dumpCollation(fout, (CollInfo *) dobj);
07674 break;
07675 case DO_CONVERSION:
07676 dumpConversion(fout, (ConvInfo *) dobj);
07677 break;
07678 case DO_TABLE:
07679 dumpTable(fout, (TableInfo *) dobj);
07680 break;
07681 case DO_ATTRDEF:
07682 dumpAttrDef(fout, (AttrDefInfo *) dobj);
07683 break;
07684 case DO_INDEX:
07685 dumpIndex(fout, (IndxInfo *) dobj);
07686 break;
07687 case DO_REFRESH_MATVIEW:
07688 refreshMatViewData(fout, (TableDataInfo *) dobj);
07689 break;
07690 case DO_RULE:
07691 dumpRule(fout, (RuleInfo *) dobj);
07692 break;
07693 case DO_TRIGGER:
07694 dumpTrigger(fout, (TriggerInfo *) dobj);
07695 break;
07696 case DO_EVENT_TRIGGER:
07697 dumpEventTrigger(fout, (EventTriggerInfo *) dobj);
07698 break;
07699 case DO_CONSTRAINT:
07700 dumpConstraint(fout, (ConstraintInfo *) dobj);
07701 break;
07702 case DO_FK_CONSTRAINT:
07703 dumpConstraint(fout, (ConstraintInfo *) dobj);
07704 break;
07705 case DO_PROCLANG:
07706 dumpProcLang(fout, (ProcLangInfo *) dobj);
07707 break;
07708 case DO_CAST:
07709 dumpCast(fout, (CastInfo *) dobj);
07710 break;
07711 case DO_TABLE_DATA:
07712 if (((TableDataInfo *) dobj)->tdtable->relkind == RELKIND_SEQUENCE)
07713 dumpSequenceData(fout, (TableDataInfo *) dobj);
07714 else
07715 dumpTableData(fout, (TableDataInfo *) dobj);
07716 break;
07717 case DO_DUMMY_TYPE:
07718
07719 break;
07720 case DO_TSPARSER:
07721 dumpTSParser(fout, (TSParserInfo *) dobj);
07722 break;
07723 case DO_TSDICT:
07724 dumpTSDictionary(fout, (TSDictInfo *) dobj);
07725 break;
07726 case DO_TSTEMPLATE:
07727 dumpTSTemplate(fout, (TSTemplateInfo *) dobj);
07728 break;
07729 case DO_TSCONFIG:
07730 dumpTSConfig(fout, (TSConfigInfo *) dobj);
07731 break;
07732 case DO_FDW:
07733 dumpForeignDataWrapper(fout, (FdwInfo *) dobj);
07734 break;
07735 case DO_FOREIGN_SERVER:
07736 dumpForeignServer(fout, (ForeignServerInfo *) dobj);
07737 break;
07738 case DO_DEFAULT_ACL:
07739 dumpDefaultACL(fout, (DefaultACLInfo *) dobj);
07740 break;
07741 case DO_BLOB:
07742 dumpBlob(fout, (BlobInfo *) dobj);
07743 break;
07744 case DO_BLOB_DATA:
07745 ArchiveEntry(fout, dobj->catId, dobj->dumpId,
07746 dobj->name, NULL, NULL, "",
07747 false, "BLOBS", SECTION_DATA,
07748 "", "", NULL,
07749 NULL, 0,
07750 dumpBlobs, NULL);
07751 break;
07752 case DO_PRE_DATA_BOUNDARY:
07753 case DO_POST_DATA_BOUNDARY:
07754
07755 break;
07756 }
07757 }
07758
07759
07760
07761
07762
07763 static void
07764 dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
07765 {
07766 PQExpBuffer q;
07767 PQExpBuffer delq;
07768 PQExpBuffer labelq;
07769 char *qnspname;
07770
07771
07772 if (!nspinfo->dobj.dump || dataOnly)
07773 return;
07774
07775
07776 if (strlen(nspinfo->dobj.name) == 0)
07777 return;
07778
07779 q = createPQExpBuffer();
07780 delq = createPQExpBuffer();
07781 labelq = createPQExpBuffer();
07782
07783 qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
07784
07785 appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
07786
07787 appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
07788
07789 appendPQExpBuffer(labelq, "SCHEMA %s", qnspname);
07790
07791 if (binary_upgrade)
07792 binary_upgrade_extension_member(q, &nspinfo->dobj, labelq->data);
07793
07794 ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
07795 nspinfo->dobj.name,
07796 NULL, NULL,
07797 nspinfo->rolname,
07798 false, "SCHEMA", SECTION_PRE_DATA,
07799 q->data, delq->data, NULL,
07800 NULL, 0,
07801 NULL, NULL);
07802
07803
07804 dumpComment(fout, labelq->data,
07805 NULL, nspinfo->rolname,
07806 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
07807 dumpSecLabel(fout, labelq->data,
07808 NULL, nspinfo->rolname,
07809 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
07810
07811 dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId, "SCHEMA",
07812 qnspname, NULL, nspinfo->dobj.name, NULL,
07813 nspinfo->rolname, nspinfo->nspacl);
07814
07815 free(qnspname);
07816
07817 destroyPQExpBuffer(q);
07818 destroyPQExpBuffer(delq);
07819 destroyPQExpBuffer(labelq);
07820 }
07821
07822
07823
07824
07825
07826 static void
07827 dumpExtension(Archive *fout, ExtensionInfo *extinfo)
07828 {
07829 PQExpBuffer q;
07830 PQExpBuffer delq;
07831 PQExpBuffer labelq;
07832 char *qextname;
07833
07834
07835 if (!extinfo->dobj.dump || dataOnly)
07836 return;
07837
07838 q = createPQExpBuffer();
07839 delq = createPQExpBuffer();
07840 labelq = createPQExpBuffer();
07841
07842 qextname = pg_strdup(fmtId(extinfo->dobj.name));
07843
07844 appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
07845
07846 if (!binary_upgrade)
07847 {
07848
07849
07850
07851
07852
07853
07854
07855
07856
07857
07858 appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
07859 qextname, fmtId(extinfo->namespace));
07860 }
07861 else
07862 {
07863 int i;
07864 int n;
07865
07866 appendPQExpBuffer(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
07867
07868
07869
07870
07871
07872
07873
07874
07875 appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
07876
07877 appendPQExpBuffer(q,
07878 "SELECT binary_upgrade.create_empty_extension(");
07879 appendStringLiteralAH(q, extinfo->dobj.name, fout);
07880 appendPQExpBuffer(q, ", ");
07881 appendStringLiteralAH(q, extinfo->namespace, fout);
07882 appendPQExpBuffer(q, ", ");
07883 appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
07884 appendStringLiteralAH(q, extinfo->extversion, fout);
07885 appendPQExpBuffer(q, ", ");
07886
07887
07888
07889
07890
07891
07892 if (strlen(extinfo->extconfig) > 2)
07893 appendStringLiteralAH(q, extinfo->extconfig, fout);
07894 else
07895 appendPQExpBuffer(q, "NULL");
07896 appendPQExpBuffer(q, ", ");
07897 if (strlen(extinfo->extcondition) > 2)
07898 appendStringLiteralAH(q, extinfo->extcondition, fout);
07899 else
07900 appendPQExpBuffer(q, "NULL");
07901 appendPQExpBuffer(q, ", ");
07902 appendPQExpBuffer(q, "ARRAY[");
07903 n = 0;
07904 for (i = 0; i < extinfo->dobj.nDeps; i++)
07905 {
07906 DumpableObject *extobj;
07907
07908 extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
07909 if (extobj && extobj->objType == DO_EXTENSION)
07910 {
07911 if (n++ > 0)
07912 appendPQExpBuffer(q, ",");
07913 appendStringLiteralAH(q, extobj->name, fout);
07914 }
07915 }
07916 appendPQExpBuffer(q, "]::pg_catalog.text[]");
07917 appendPQExpBuffer(q, ");\n");
07918 }
07919
07920 appendPQExpBuffer(labelq, "EXTENSION %s", qextname);
07921
07922 ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
07923 extinfo->dobj.name,
07924 NULL, NULL,
07925 "",
07926 false, "EXTENSION", SECTION_PRE_DATA,
07927 q->data, delq->data, NULL,
07928 NULL, 0,
07929 NULL, NULL);
07930
07931
07932 dumpComment(fout, labelq->data,
07933 NULL, "",
07934 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
07935 dumpSecLabel(fout, labelq->data,
07936 NULL, "",
07937 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
07938
07939 free(qextname);
07940
07941 destroyPQExpBuffer(q);
07942 destroyPQExpBuffer(delq);
07943 destroyPQExpBuffer(labelq);
07944 }
07945
07946
07947
07948
07949
07950 static void
07951 dumpType(Archive *fout, TypeInfo *tyinfo)
07952 {
07953
07954 if (!tyinfo->dobj.dump || dataOnly)
07955 return;
07956
07957
07958 if (tyinfo->typtype == TYPTYPE_BASE)
07959 dumpBaseType(fout, tyinfo);
07960 else if (tyinfo->typtype == TYPTYPE_DOMAIN)
07961 dumpDomain(fout, tyinfo);
07962 else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
07963 dumpCompositeType(fout, tyinfo);
07964 else if (tyinfo->typtype == TYPTYPE_ENUM)
07965 dumpEnumType(fout, tyinfo);
07966 else if (tyinfo->typtype == TYPTYPE_RANGE)
07967 dumpRangeType(fout, tyinfo);
07968 else
07969 write_msg(NULL, "WARNING: typtype of data type \"%s\" appears to be invalid\n",
07970 tyinfo->dobj.name);
07971 }
07972
07973
07974
07975
07976
07977 static void
07978 dumpEnumType(Archive *fout, TypeInfo *tyinfo)
07979 {
07980 PQExpBuffer q = createPQExpBuffer();
07981 PQExpBuffer delq = createPQExpBuffer();
07982 PQExpBuffer labelq = createPQExpBuffer();
07983 PQExpBuffer query = createPQExpBuffer();
07984 PGresult *res;
07985 int num,
07986 i;
07987 Oid enum_oid;
07988 char *qtypname;
07989 char *label;
07990
07991
07992 selectSourceSchema(fout, "pg_catalog");
07993
07994 if (fout->remoteVersion >= 90100)
07995 appendPQExpBuffer(query, "SELECT oid, enumlabel "
07996 "FROM pg_catalog.pg_enum "
07997 "WHERE enumtypid = '%u'"
07998 "ORDER BY enumsortorder",
07999 tyinfo->dobj.catId.oid);
08000 else
08001 appendPQExpBuffer(query, "SELECT oid, enumlabel "
08002 "FROM pg_catalog.pg_enum "
08003 "WHERE enumtypid = '%u'"
08004 "ORDER BY oid",
08005 tyinfo->dobj.catId.oid);
08006
08007 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
08008
08009 num = PQntuples(res);
08010
08011 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
08012
08013
08014
08015
08016
08017
08018 appendPQExpBuffer(delq, "DROP TYPE %s.",
08019 fmtId(tyinfo->dobj.namespace->dobj.name));
08020 appendPQExpBuffer(delq, "%s;\n",
08021 qtypname);
08022
08023 if (binary_upgrade)
08024 binary_upgrade_set_type_oids_by_type_oid(fout, q,
08025 tyinfo->dobj.catId.oid);
08026
08027 appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
08028 qtypname);
08029
08030 if (!binary_upgrade)
08031 {
08032
08033 for (i = 0; i < num; i++)
08034 {
08035 label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));
08036 if (i > 0)
08037 appendPQExpBuffer(q, ",");
08038 appendPQExpBuffer(q, "\n ");
08039 appendStringLiteralAH(q, label, fout);
08040 }
08041 }
08042
08043 appendPQExpBuffer(q, "\n);\n");
08044
08045 if (binary_upgrade)
08046 {
08047
08048 for (i = 0; i < num; i++)
08049 {
08050 enum_oid = atooid(PQgetvalue(res, i, PQfnumber(res, "oid")));
08051 label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));
08052
08053 if (i == 0)
08054 appendPQExpBuffer(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
08055 appendPQExpBuffer(q,
08056 "SELECT binary_upgrade.set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
08057 enum_oid);
08058 appendPQExpBuffer(q, "ALTER TYPE %s.",
08059 fmtId(tyinfo->dobj.namespace->dobj.name));
08060 appendPQExpBuffer(q, "%s ADD VALUE ",
08061 qtypname);
08062 appendStringLiteralAH(q, label, fout);
08063 appendPQExpBuffer(q, ";\n\n");
08064 }
08065 }
08066
08067 appendPQExpBuffer(labelq, "TYPE %s", qtypname);
08068
08069 if (binary_upgrade)
08070 binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
08071
08072 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
08073 tyinfo->dobj.name,
08074 tyinfo->dobj.namespace->dobj.name,
08075 NULL,
08076 tyinfo->rolname, false,
08077 "TYPE", SECTION_PRE_DATA,
08078 q->data, delq->data, NULL,
08079 NULL, 0,
08080 NULL, NULL);
08081
08082
08083 dumpComment(fout, labelq->data,
08084 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08085 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08086 dumpSecLabel(fout, labelq->data,
08087 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08088 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08089
08090 dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
08091 qtypname, NULL, tyinfo->dobj.name,
08092 tyinfo->dobj.namespace->dobj.name,
08093 tyinfo->rolname, tyinfo->typacl);
08094
08095 PQclear(res);
08096 destroyPQExpBuffer(q);
08097 destroyPQExpBuffer(delq);
08098 destroyPQExpBuffer(labelq);
08099 destroyPQExpBuffer(query);
08100 }
08101
08102
08103
08104
08105
08106 static void
08107 dumpRangeType(Archive *fout, TypeInfo *tyinfo)
08108 {
08109 PQExpBuffer q = createPQExpBuffer();
08110 PQExpBuffer delq = createPQExpBuffer();
08111 PQExpBuffer labelq = createPQExpBuffer();
08112 PQExpBuffer query = createPQExpBuffer();
08113 PGresult *res;
08114 Oid collationOid;
08115 char *qtypname;
08116 char *procname;
08117
08118
08119
08120
08121
08122 selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
08123
08124 appendPQExpBuffer(query,
08125 "SELECT pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
08126 "opc.opcname AS opcname, "
08127 "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
08128 " WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
08129 "opc.opcdefault, "
08130 "CASE WHEN rngcollation = st.typcollation THEN 0 "
08131 " ELSE rngcollation END AS collation, "
08132 "rngcanonical, rngsubdiff "
08133 "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
08134 " pg_catalog.pg_opclass opc "
08135 "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
08136 "rngtypid = '%u'",
08137 tyinfo->dobj.catId.oid);
08138
08139 res = ExecuteSqlQueryForSingleRow(fout, query->data);
08140
08141 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
08142
08143
08144
08145
08146
08147
08148 appendPQExpBuffer(delq, "DROP TYPE %s.",
08149 fmtId(tyinfo->dobj.namespace->dobj.name));
08150 appendPQExpBuffer(delq, "%s;\n",
08151 qtypname);
08152
08153 if (binary_upgrade)
08154 binary_upgrade_set_type_oids_by_type_oid(fout,
08155 q, tyinfo->dobj.catId.oid);
08156
08157 appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
08158 qtypname);
08159
08160 appendPQExpBuffer(q, "\n subtype = %s",
08161 PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
08162
08163
08164 if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
08165 {
08166 char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
08167 char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
08168
08169
08170 appendPQExpBuffer(q, ",\n subtype_opclass = %s.",
08171 fmtId(nspname));
08172 appendPQExpBuffer(q, "%s", fmtId(opcname));
08173 }
08174
08175 collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
08176 if (OidIsValid(collationOid))
08177 {
08178 CollInfo *coll = findCollationByOid(collationOid);
08179
08180 if (coll)
08181 {
08182
08183 appendPQExpBuffer(q, ",\n collation = %s.",
08184 fmtId(coll->dobj.namespace->dobj.name));
08185 appendPQExpBuffer(q, "%s",
08186 fmtId(coll->dobj.name));
08187 }
08188 }
08189
08190 procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
08191 if (strcmp(procname, "-") != 0)
08192 appendPQExpBuffer(q, ",\n canonical = %s", procname);
08193
08194 procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
08195 if (strcmp(procname, "-") != 0)
08196 appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
08197
08198 appendPQExpBuffer(q, "\n);\n");
08199
08200 appendPQExpBuffer(labelq, "TYPE %s", qtypname);
08201
08202 if (binary_upgrade)
08203 binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
08204
08205 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
08206 tyinfo->dobj.name,
08207 tyinfo->dobj.namespace->dobj.name,
08208 NULL,
08209 tyinfo->rolname, false,
08210 "TYPE", SECTION_PRE_DATA,
08211 q->data, delq->data, NULL,
08212 NULL, 0,
08213 NULL, NULL);
08214
08215
08216 dumpComment(fout, labelq->data,
08217 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08218 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08219 dumpSecLabel(fout, labelq->data,
08220 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08221 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08222
08223 dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
08224 qtypname, NULL, tyinfo->dobj.name,
08225 tyinfo->dobj.namespace->dobj.name,
08226 tyinfo->rolname, tyinfo->typacl);
08227
08228 PQclear(res);
08229 destroyPQExpBuffer(q);
08230 destroyPQExpBuffer(delq);
08231 destroyPQExpBuffer(labelq);
08232 destroyPQExpBuffer(query);
08233 }
08234
08235
08236
08237
08238
08239 static void
08240 dumpBaseType(Archive *fout, TypeInfo *tyinfo)
08241 {
08242 PQExpBuffer q = createPQExpBuffer();
08243 PQExpBuffer delq = createPQExpBuffer();
08244 PQExpBuffer labelq = createPQExpBuffer();
08245 PQExpBuffer query = createPQExpBuffer();
08246 PGresult *res;
08247 char *qtypname;
08248 char *typlen;
08249 char *typinput;
08250 char *typoutput;
08251 char *typreceive;
08252 char *typsend;
08253 char *typmodin;
08254 char *typmodout;
08255 char *typanalyze;
08256 Oid typreceiveoid;
08257 Oid typsendoid;
08258 Oid typmodinoid;
08259 Oid typmodoutoid;
08260 Oid typanalyzeoid;
08261 char *typcategory;
08262 char *typispreferred;
08263 char *typdelim;
08264 char *typbyval;
08265 char *typalign;
08266 char *typstorage;
08267 char *typcollatable;
08268 char *typdefault;
08269 bool typdefault_is_literal = false;
08270
08271
08272 selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
08273
08274
08275 if (fout->remoteVersion >= 90100)
08276 {
08277 appendPQExpBuffer(query, "SELECT typlen, "
08278 "typinput, typoutput, typreceive, typsend, "
08279 "typmodin, typmodout, typanalyze, "
08280 "typreceive::pg_catalog.oid AS typreceiveoid, "
08281 "typsend::pg_catalog.oid AS typsendoid, "
08282 "typmodin::pg_catalog.oid AS typmodinoid, "
08283 "typmodout::pg_catalog.oid AS typmodoutoid, "
08284 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
08285 "typcategory, typispreferred, "
08286 "typdelim, typbyval, typalign, typstorage, "
08287 "(typcollation <> 0) AS typcollatable, "
08288 "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
08289 "FROM pg_catalog.pg_type "
08290 "WHERE oid = '%u'::pg_catalog.oid",
08291 tyinfo->dobj.catId.oid);
08292 }
08293 else if (fout->remoteVersion >= 80400)
08294 {
08295 appendPQExpBuffer(query, "SELECT typlen, "
08296 "typinput, typoutput, typreceive, typsend, "
08297 "typmodin, typmodout, typanalyze, "
08298 "typreceive::pg_catalog.oid AS typreceiveoid, "
08299 "typsend::pg_catalog.oid AS typsendoid, "
08300 "typmodin::pg_catalog.oid AS typmodinoid, "
08301 "typmodout::pg_catalog.oid AS typmodoutoid, "
08302 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
08303 "typcategory, typispreferred, "
08304 "typdelim, typbyval, typalign, typstorage, "
08305 "false AS typcollatable, "
08306 "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
08307 "FROM pg_catalog.pg_type "
08308 "WHERE oid = '%u'::pg_catalog.oid",
08309 tyinfo->dobj.catId.oid);
08310 }
08311 else if (fout->remoteVersion >= 80300)
08312 {
08313
08314 appendPQExpBuffer(query, "SELECT typlen, "
08315 "typinput, typoutput, typreceive, typsend, "
08316 "typmodin, typmodout, typanalyze, "
08317 "typreceive::pg_catalog.oid AS typreceiveoid, "
08318 "typsend::pg_catalog.oid AS typsendoid, "
08319 "typmodin::pg_catalog.oid AS typmodinoid, "
08320 "typmodout::pg_catalog.oid AS typmodoutoid, "
08321 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
08322 "'U' AS typcategory, false AS typispreferred, "
08323 "typdelim, typbyval, typalign, typstorage, "
08324 "false AS typcollatable, "
08325 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
08326 "FROM pg_catalog.pg_type "
08327 "WHERE oid = '%u'::pg_catalog.oid",
08328 tyinfo->dobj.catId.oid);
08329 }
08330 else if (fout->remoteVersion >= 80000)
08331 {
08332 appendPQExpBuffer(query, "SELECT typlen, "
08333 "typinput, typoutput, typreceive, typsend, "
08334 "'-' AS typmodin, '-' AS typmodout, "
08335 "typanalyze, "
08336 "typreceive::pg_catalog.oid AS typreceiveoid, "
08337 "typsend::pg_catalog.oid AS typsendoid, "
08338 "0 AS typmodinoid, 0 AS typmodoutoid, "
08339 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
08340 "'U' AS typcategory, false AS typispreferred, "
08341 "typdelim, typbyval, typalign, typstorage, "
08342 "false AS typcollatable, "
08343 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
08344 "FROM pg_catalog.pg_type "
08345 "WHERE oid = '%u'::pg_catalog.oid",
08346 tyinfo->dobj.catId.oid);
08347 }
08348 else if (fout->remoteVersion >= 70400)
08349 {
08350 appendPQExpBuffer(query, "SELECT typlen, "
08351 "typinput, typoutput, typreceive, typsend, "
08352 "'-' AS typmodin, '-' AS typmodout, "
08353 "'-' AS typanalyze, "
08354 "typreceive::pg_catalog.oid AS typreceiveoid, "
08355 "typsend::pg_catalog.oid AS typsendoid, "
08356 "0 AS typmodinoid, 0 AS typmodoutoid, "
08357 "0 AS typanalyzeoid, "
08358 "'U' AS typcategory, false AS typispreferred, "
08359 "typdelim, typbyval, typalign, typstorage, "
08360 "false AS typcollatable, "
08361 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
08362 "FROM pg_catalog.pg_type "
08363 "WHERE oid = '%u'::pg_catalog.oid",
08364 tyinfo->dobj.catId.oid);
08365 }
08366 else if (fout->remoteVersion >= 70300)
08367 {
08368 appendPQExpBuffer(query, "SELECT typlen, "
08369 "typinput, typoutput, "
08370 "'-' AS typreceive, '-' AS typsend, "
08371 "'-' AS typmodin, '-' AS typmodout, "
08372 "'-' AS typanalyze, "
08373 "0 AS typreceiveoid, 0 AS typsendoid, "
08374 "0 AS typmodinoid, 0 AS typmodoutoid, "
08375 "0 AS typanalyzeoid, "
08376 "'U' AS typcategory, false AS typispreferred, "
08377 "typdelim, typbyval, typalign, typstorage, "
08378 "false AS typcollatable, "
08379 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
08380 "FROM pg_catalog.pg_type "
08381 "WHERE oid = '%u'::pg_catalog.oid",
08382 tyinfo->dobj.catId.oid);
08383 }
08384 else if (fout->remoteVersion >= 70200)
08385 {
08386
08387
08388
08389
08390 appendPQExpBuffer(query, "SELECT typlen, "
08391 "typinput, typoutput, "
08392 "'-' AS typreceive, '-' AS typsend, "
08393 "'-' AS typmodin, '-' AS typmodout, "
08394 "'-' AS typanalyze, "
08395 "0 AS typreceiveoid, 0 AS typsendoid, "
08396 "0 AS typmodinoid, 0 AS typmodoutoid, "
08397 "0 AS typanalyzeoid, "
08398 "'U' AS typcategory, false AS typispreferred, "
08399 "typdelim, typbyval, typalign, typstorage, "
08400 "false AS typcollatable, "
08401 "NULL AS typdefaultbin, typdefault "
08402 "FROM pg_type "
08403 "WHERE oid = '%u'::oid",
08404 tyinfo->dobj.catId.oid);
08405 }
08406 else if (fout->remoteVersion >= 70100)
08407 {
08408
08409
08410
08411
08412 appendPQExpBuffer(query, "SELECT typlen, "
08413 "typinput, typoutput, "
08414 "'-' AS typreceive, '-' AS typsend, "
08415 "'-' AS typmodin, '-' AS typmodout, "
08416 "'-' AS typanalyze, "
08417 "0 AS typreceiveoid, 0 AS typsendoid, "
08418 "0 AS typmodinoid, 0 AS typmodoutoid, "
08419 "0 AS typanalyzeoid, "
08420 "'U' AS typcategory, false AS typispreferred, "
08421 "typdelim, typbyval, typalign, typstorage, "
08422 "false AS typcollatable, "
08423 "NULL AS typdefaultbin, NULL AS typdefault "
08424 "FROM pg_type "
08425 "WHERE oid = '%u'::oid",
08426 tyinfo->dobj.catId.oid);
08427 }
08428 else
08429 {
08430 appendPQExpBuffer(query, "SELECT typlen, "
08431 "typinput, typoutput, "
08432 "'-' AS typreceive, '-' AS typsend, "
08433 "'-' AS typmodin, '-' AS typmodout, "
08434 "'-' AS typanalyze, "
08435 "0 AS typreceiveoid, 0 AS typsendoid, "
08436 "0 AS typmodinoid, 0 AS typmodoutoid, "
08437 "0 AS typanalyzeoid, "
08438 "'U' AS typcategory, false AS typispreferred, "
08439 "typdelim, typbyval, typalign, "
08440 "'p'::char AS typstorage, "
08441 "false AS typcollatable, "
08442 "NULL AS typdefaultbin, NULL AS typdefault "
08443 "FROM pg_type "
08444 "WHERE oid = '%u'::oid",
08445 tyinfo->dobj.catId.oid);
08446 }
08447
08448 res = ExecuteSqlQueryForSingleRow(fout, query->data);
08449
08450 typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
08451 typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
08452 typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
08453 typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
08454 typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
08455 typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
08456 typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
08457 typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
08458 typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
08459 typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
08460 typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
08461 typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
08462 typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
08463 typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
08464 typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
08465 typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
08466 typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
08467 typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
08468 typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
08469 typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
08470 if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
08471 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
08472 else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
08473 {
08474 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
08475 typdefault_is_literal = true;
08476 }
08477 else
08478 typdefault = NULL;
08479
08480 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
08481
08482
08483
08484
08485
08486
08487
08488 appendPQExpBuffer(delq, "DROP TYPE %s.",
08489 fmtId(tyinfo->dobj.namespace->dobj.name));
08490 appendPQExpBuffer(delq, "%s CASCADE;\n",
08491 qtypname);
08492
08493
08494 if (binary_upgrade)
08495 binary_upgrade_set_type_oids_by_type_oid(fout, q,
08496 tyinfo->dobj.catId.oid);
08497
08498 appendPQExpBuffer(q,
08499 "CREATE TYPE %s (\n"
08500 " INTERNALLENGTH = %s",
08501 qtypname,
08502 (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
08503
08504 if (fout->remoteVersion >= 70300)
08505 {
08506
08507 appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
08508 appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
08509 if (OidIsValid(typreceiveoid))
08510 appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
08511 if (OidIsValid(typsendoid))
08512 appendPQExpBuffer(q, ",\n SEND = %s", typsend);
08513 if (OidIsValid(typmodinoid))
08514 appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
08515 if (OidIsValid(typmodoutoid))
08516 appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
08517 if (OidIsValid(typanalyzeoid))
08518 appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
08519 }
08520 else
08521 {
08522
08523
08524 appendPQExpBuffer(q, ",\n INPUT = %s", fmtId(typinput));
08525 appendPQExpBuffer(q, ",\n OUTPUT = %s", fmtId(typoutput));
08526
08527 }
08528
08529 if (strcmp(typcollatable, "t") == 0)
08530 appendPQExpBuffer(q, ",\n COLLATABLE = true");
08531
08532 if (typdefault != NULL)
08533 {
08534 appendPQExpBuffer(q, ",\n DEFAULT = ");
08535 if (typdefault_is_literal)
08536 appendStringLiteralAH(q, typdefault, fout);
08537 else
08538 appendPQExpBufferStr(q, typdefault);
08539 }
08540
08541 if (OidIsValid(tyinfo->typelem))
08542 {
08543 char *elemType;
08544
08545
08546 selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
08547 elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroAsOpaque);
08548 appendPQExpBuffer(q, ",\n ELEMENT = %s", elemType);
08549 free(elemType);
08550 }
08551
08552 if (strcmp(typcategory, "U") != 0)
08553 {
08554 appendPQExpBuffer(q, ",\n CATEGORY = ");
08555 appendStringLiteralAH(q, typcategory, fout);
08556 }
08557
08558 if (strcmp(typispreferred, "t") == 0)
08559 appendPQExpBuffer(q, ",\n PREFERRED = true");
08560
08561 if (typdelim && strcmp(typdelim, ",") != 0)
08562 {
08563 appendPQExpBuffer(q, ",\n DELIMITER = ");
08564 appendStringLiteralAH(q, typdelim, fout);
08565 }
08566
08567 if (strcmp(typalign, "c") == 0)
08568 appendPQExpBuffer(q, ",\n ALIGNMENT = char");
08569 else if (strcmp(typalign, "s") == 0)
08570 appendPQExpBuffer(q, ",\n ALIGNMENT = int2");
08571 else if (strcmp(typalign, "i") == 0)
08572 appendPQExpBuffer(q, ",\n ALIGNMENT = int4");
08573 else if (strcmp(typalign, "d") == 0)
08574 appendPQExpBuffer(q, ",\n ALIGNMENT = double");
08575
08576 if (strcmp(typstorage, "p") == 0)
08577 appendPQExpBuffer(q, ",\n STORAGE = plain");
08578 else if (strcmp(typstorage, "e") == 0)
08579 appendPQExpBuffer(q, ",\n STORAGE = external");
08580 else if (strcmp(typstorage, "x") == 0)
08581 appendPQExpBuffer(q, ",\n STORAGE = extended");
08582 else if (strcmp(typstorage, "m") == 0)
08583 appendPQExpBuffer(q, ",\n STORAGE = main");
08584
08585 if (strcmp(typbyval, "t") == 0)
08586 appendPQExpBuffer(q, ",\n PASSEDBYVALUE");
08587
08588 appendPQExpBuffer(q, "\n);\n");
08589
08590 appendPQExpBuffer(labelq, "TYPE %s", qtypname);
08591
08592 if (binary_upgrade)
08593 binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
08594
08595 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
08596 tyinfo->dobj.name,
08597 tyinfo->dobj.namespace->dobj.name,
08598 NULL,
08599 tyinfo->rolname, false,
08600 "TYPE", SECTION_PRE_DATA,
08601 q->data, delq->data, NULL,
08602 NULL, 0,
08603 NULL, NULL);
08604
08605
08606 dumpComment(fout, labelq->data,
08607 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08608 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08609 dumpSecLabel(fout, labelq->data,
08610 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08611 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08612
08613 dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
08614 qtypname, NULL, tyinfo->dobj.name,
08615 tyinfo->dobj.namespace->dobj.name,
08616 tyinfo->rolname, tyinfo->typacl);
08617
08618 PQclear(res);
08619 destroyPQExpBuffer(q);
08620 destroyPQExpBuffer(delq);
08621 destroyPQExpBuffer(labelq);
08622 destroyPQExpBuffer(query);
08623 }
08624
08625
08626
08627
08628
08629 static void
08630 dumpDomain(Archive *fout, TypeInfo *tyinfo)
08631 {
08632 PQExpBuffer q = createPQExpBuffer();
08633 PQExpBuffer delq = createPQExpBuffer();
08634 PQExpBuffer labelq = createPQExpBuffer();
08635 PQExpBuffer query = createPQExpBuffer();
08636 PGresult *res;
08637 int i;
08638 char *qtypname;
08639 char *typnotnull;
08640 char *typdefn;
08641 char *typdefault;
08642 Oid typcollation;
08643 bool typdefault_is_literal = false;
08644
08645
08646 selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
08647
08648
08649 if (fout->remoteVersion >= 90100)
08650 {
08651
08652 appendPQExpBuffer(query, "SELECT t.typnotnull, "
08653 "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
08654 "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
08655 "t.typdefault, "
08656 "CASE WHEN t.typcollation <> u.typcollation "
08657 "THEN t.typcollation ELSE 0 END AS typcollation "
08658 "FROM pg_catalog.pg_type t "
08659 "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
08660 "WHERE t.oid = '%u'::pg_catalog.oid",
08661 tyinfo->dobj.catId.oid);
08662 }
08663 else
08664 {
08665
08666 appendPQExpBuffer(query, "SELECT typnotnull, "
08667 "pg_catalog.format_type(typbasetype, typtypmod) AS typdefn, "
08668 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
08669 "typdefault, 0 AS typcollation "
08670 "FROM pg_catalog.pg_type "
08671 "WHERE oid = '%u'::pg_catalog.oid",
08672 tyinfo->dobj.catId.oid);
08673 }
08674
08675 res = ExecuteSqlQueryForSingleRow(fout, query->data);
08676
08677 typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
08678 typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
08679 if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
08680 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
08681 else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
08682 {
08683 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
08684 typdefault_is_literal = true;
08685 }
08686 else
08687 typdefault = NULL;
08688 typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
08689
08690 if (binary_upgrade)
08691 binary_upgrade_set_type_oids_by_type_oid(fout, q,
08692 tyinfo->dobj.catId.oid);
08693
08694 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
08695
08696 appendPQExpBuffer(q,
08697 "CREATE DOMAIN %s AS %s",
08698 qtypname,
08699 typdefn);
08700
08701
08702 if (OidIsValid(typcollation))
08703 {
08704 CollInfo *coll;
08705
08706 coll = findCollationByOid(typcollation);
08707 if (coll)
08708 {
08709
08710 appendPQExpBuffer(q, " COLLATE %s.",
08711 fmtId(coll->dobj.namespace->dobj.name));
08712 appendPQExpBuffer(q, "%s",
08713 fmtId(coll->dobj.name));
08714 }
08715 }
08716
08717 if (typnotnull[0] == 't')
08718 appendPQExpBuffer(q, " NOT NULL");
08719
08720 if (typdefault != NULL)
08721 {
08722 appendPQExpBuffer(q, " DEFAULT ");
08723 if (typdefault_is_literal)
08724 appendStringLiteralAH(q, typdefault, fout);
08725 else
08726 appendPQExpBufferStr(q, typdefault);
08727 }
08728
08729 PQclear(res);
08730
08731
08732
08733
08734 for (i = 0; i < tyinfo->nDomChecks; i++)
08735 {
08736 ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
08737
08738 if (!domcheck->separate)
08739 appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
08740 fmtId(domcheck->dobj.name), domcheck->condef);
08741 }
08742
08743 appendPQExpBuffer(q, ";\n");
08744
08745
08746
08747
08748 appendPQExpBuffer(delq, "DROP DOMAIN %s.",
08749 fmtId(tyinfo->dobj.namespace->dobj.name));
08750 appendPQExpBuffer(delq, "%s;\n",
08751 qtypname);
08752
08753 appendPQExpBuffer(labelq, "DOMAIN %s", qtypname);
08754
08755 if (binary_upgrade)
08756 binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
08757
08758 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
08759 tyinfo->dobj.name,
08760 tyinfo->dobj.namespace->dobj.name,
08761 NULL,
08762 tyinfo->rolname, false,
08763 "DOMAIN", SECTION_PRE_DATA,
08764 q->data, delq->data, NULL,
08765 NULL, 0,
08766 NULL, NULL);
08767
08768
08769 dumpComment(fout, labelq->data,
08770 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08771 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08772 dumpSecLabel(fout, labelq->data,
08773 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08774 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08775
08776 dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
08777 qtypname, NULL, tyinfo->dobj.name,
08778 tyinfo->dobj.namespace->dobj.name,
08779 tyinfo->rolname, tyinfo->typacl);
08780
08781 destroyPQExpBuffer(q);
08782 destroyPQExpBuffer(delq);
08783 destroyPQExpBuffer(labelq);
08784 destroyPQExpBuffer(query);
08785 }
08786
08787
08788
08789
08790
08791
08792 static void
08793 dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
08794 {
08795 PQExpBuffer q = createPQExpBuffer();
08796 PQExpBuffer dropped = createPQExpBuffer();
08797 PQExpBuffer delq = createPQExpBuffer();
08798 PQExpBuffer labelq = createPQExpBuffer();
08799 PQExpBuffer query = createPQExpBuffer();
08800 PGresult *res;
08801 char *qtypname;
08802 int ntups;
08803 int i_attname;
08804 int i_atttypdefn;
08805 int i_attlen;
08806 int i_attalign;
08807 int i_attisdropped;
08808 int i_attcollation;
08809 int i_typrelid;
08810 int i;
08811 int actual_atts;
08812
08813
08814 selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
08815
08816
08817 if (fout->remoteVersion >= 90100)
08818 {
08819
08820
08821
08822
08823
08824
08825
08826 appendPQExpBuffer(query, "SELECT a.attname, "
08827 "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
08828 "a.attlen, a.attalign, a.attisdropped, "
08829 "CASE WHEN a.attcollation <> at.typcollation "
08830 "THEN a.attcollation ELSE 0 END AS attcollation, "
08831 "ct.typrelid "
08832 "FROM pg_catalog.pg_type ct "
08833 "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
08834 "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
08835 "WHERE ct.oid = '%u'::pg_catalog.oid "
08836 "ORDER BY a.attnum ",
08837 tyinfo->dobj.catId.oid);
08838 }
08839 else
08840 {
08841
08842
08843
08844
08845
08846 appendPQExpBuffer(query, "SELECT a.attname, "
08847 "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
08848 "a.attlen, a.attalign, a.attisdropped, "
08849 "0 AS attcollation, "
08850 "ct.typrelid "
08851 "FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a "
08852 "WHERE ct.oid = '%u'::pg_catalog.oid "
08853 "AND a.attrelid = ct.typrelid "
08854 "ORDER BY a.attnum ",
08855 tyinfo->dobj.catId.oid);
08856 }
08857
08858 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
08859
08860 ntups = PQntuples(res);
08861
08862 i_attname = PQfnumber(res, "attname");
08863 i_atttypdefn = PQfnumber(res, "atttypdefn");
08864 i_attlen = PQfnumber(res, "attlen");
08865 i_attalign = PQfnumber(res, "attalign");
08866 i_attisdropped = PQfnumber(res, "attisdropped");
08867 i_attcollation = PQfnumber(res, "attcollation");
08868 i_typrelid = PQfnumber(res, "typrelid");
08869
08870 if (binary_upgrade)
08871 {
08872 Oid typrelid = atooid(PQgetvalue(res, 0, i_typrelid));
08873
08874 binary_upgrade_set_type_oids_by_type_oid(fout, q,
08875 tyinfo->dobj.catId.oid);
08876 binary_upgrade_set_pg_class_oids(fout, q, typrelid, false);
08877 }
08878
08879 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
08880
08881 appendPQExpBuffer(q, "CREATE TYPE %s AS (",
08882 qtypname);
08883
08884 actual_atts = 0;
08885 for (i = 0; i < ntups; i++)
08886 {
08887 char *attname;
08888 char *atttypdefn;
08889 char *attlen;
08890 char *attalign;
08891 bool attisdropped;
08892 Oid attcollation;
08893
08894 attname = PQgetvalue(res, i, i_attname);
08895 atttypdefn = PQgetvalue(res, i, i_atttypdefn);
08896 attlen = PQgetvalue(res, i, i_attlen);
08897 attalign = PQgetvalue(res, i, i_attalign);
08898 attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
08899 attcollation = atooid(PQgetvalue(res, i, i_attcollation));
08900
08901 if (attisdropped && !binary_upgrade)
08902 continue;
08903
08904
08905 if (actual_atts++ > 0)
08906 appendPQExpBuffer(q, ",");
08907 appendPQExpBuffer(q, "\n\t");
08908
08909 if (!attisdropped)
08910 {
08911 appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
08912
08913
08914 if (OidIsValid(attcollation))
08915 {
08916 CollInfo *coll;
08917
08918 coll = findCollationByOid(attcollation);
08919 if (coll)
08920 {
08921
08922 appendPQExpBuffer(q, " COLLATE %s.",
08923 fmtId(coll->dobj.namespace->dobj.name));
08924 appendPQExpBuffer(q, "%s",
08925 fmtId(coll->dobj.name));
08926 }
08927 }
08928 }
08929 else
08930 {
08931
08932
08933
08934
08935
08936
08937 appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
08938
08939
08940 appendPQExpBuffer(dropped,
08941 "\n-- For binary upgrade, recreate dropped column.\n");
08942 appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
08943 "SET attlen = %s, "
08944 "attalign = '%s', attbyval = false\n"
08945 "WHERE attname = ", attlen, attalign);
08946 appendStringLiteralAH(dropped, attname, fout);
08947 appendPQExpBuffer(dropped, "\n AND attrelid = ");
08948 appendStringLiteralAH(dropped, qtypname, fout);
08949 appendPQExpBuffer(dropped, "::pg_catalog.regclass;\n");
08950
08951 appendPQExpBuffer(dropped, "ALTER TYPE %s ",
08952 qtypname);
08953 appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
08954 fmtId(attname));
08955 }
08956 }
08957 appendPQExpBuffer(q, "\n);\n");
08958 appendPQExpBufferStr(q, dropped->data);
08959
08960
08961
08962
08963 appendPQExpBuffer(delq, "DROP TYPE %s.",
08964 fmtId(tyinfo->dobj.namespace->dobj.name));
08965 appendPQExpBuffer(delq, "%s;\n",
08966 qtypname);
08967
08968 appendPQExpBuffer(labelq, "TYPE %s", qtypname);
08969
08970 if (binary_upgrade)
08971 binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
08972
08973 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
08974 tyinfo->dobj.name,
08975 tyinfo->dobj.namespace->dobj.name,
08976 NULL,
08977 tyinfo->rolname, false,
08978 "TYPE", SECTION_PRE_DATA,
08979 q->data, delq->data, NULL,
08980 NULL, 0,
08981 NULL, NULL);
08982
08983
08984
08985 dumpComment(fout, labelq->data,
08986 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08987 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08988 dumpSecLabel(fout, labelq->data,
08989 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
08990 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
08991
08992 dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
08993 qtypname, NULL, tyinfo->dobj.name,
08994 tyinfo->dobj.namespace->dobj.name,
08995 tyinfo->rolname, tyinfo->typacl);
08996
08997 PQclear(res);
08998 destroyPQExpBuffer(q);
08999 destroyPQExpBuffer(dropped);
09000 destroyPQExpBuffer(delq);
09001 destroyPQExpBuffer(labelq);
09002 destroyPQExpBuffer(query);
09003
09004
09005 dumpCompositeTypeColComments(fout, tyinfo);
09006 }
09007
09008
09009
09010
09011
09012
09013 static void
09014 dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
09015 {
09016 CommentItem *comments;
09017 int ncomments;
09018 PGresult *res;
09019 PQExpBuffer query;
09020 PQExpBuffer target;
09021 Oid pgClassOid;
09022 int i;
09023 int ntups;
09024 int i_attname;
09025 int i_attnum;
09026
09027 query = createPQExpBuffer();
09028
09029
09030 appendPQExpBuffer(query,
09031 "SELECT c.tableoid, a.attname, a.attnum "
09032 "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
09033 "WHERE c.oid = '%u' AND c.oid = a.attrelid "
09034 " AND NOT a.attisdropped "
09035 "ORDER BY a.attnum ",
09036 tyinfo->typrelid);
09037
09038
09039 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
09040
09041 ntups = PQntuples(res);
09042 if (ntups < 1)
09043 {
09044 PQclear(res);
09045 destroyPQExpBuffer(query);
09046 return;
09047 }
09048
09049 pgClassOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "tableoid")));
09050
09051
09052 ncomments = findComments(fout,
09053 pgClassOid,
09054 tyinfo->typrelid,
09055 &comments);
09056
09057
09058 if (ncomments <= 0)
09059 {
09060 PQclear(res);
09061 destroyPQExpBuffer(query);
09062 return;
09063 }
09064
09065
09066 target = createPQExpBuffer();
09067
09068 i_attnum = PQfnumber(res, "attnum");
09069 i_attname = PQfnumber(res, "attname");
09070 while (ncomments > 0)
09071 {
09072 const char *attname;
09073
09074 attname = NULL;
09075 for (i = 0; i < ntups; i++)
09076 {
09077 if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid)
09078 {
09079 attname = PQgetvalue(res, i, i_attname);
09080 break;
09081 }
09082 }
09083 if (attname)
09084 {
09085 const char *descr = comments->descr;
09086
09087 resetPQExpBuffer(target);
09088 appendPQExpBuffer(target, "COLUMN %s.",
09089 fmtId(tyinfo->dobj.name));
09090 appendPQExpBuffer(target, "%s",
09091 fmtId(attname));
09092
09093 resetPQExpBuffer(query);
09094 appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
09095 appendStringLiteralAH(query, descr, fout);
09096 appendPQExpBuffer(query, ";\n");
09097
09098 ArchiveEntry(fout, nilCatalogId, createDumpId(),
09099 target->data,
09100 tyinfo->dobj.namespace->dobj.name,
09101 NULL, tyinfo->rolname,
09102 false, "COMMENT", SECTION_NONE,
09103 query->data, "", NULL,
09104 &(tyinfo->dobj.dumpId), 1,
09105 NULL, NULL);
09106 }
09107
09108 comments++;
09109 ncomments--;
09110 }
09111
09112 PQclear(res);
09113 destroyPQExpBuffer(query);
09114 destroyPQExpBuffer(target);
09115 }
09116
09117
09118
09119
09120
09121
09122
09123 static void
09124 dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
09125 {
09126 PQExpBuffer q;
09127
09128
09129 if (!stinfo->dobj.dump || dataOnly)
09130 return;
09131
09132 q = createPQExpBuffer();
09133
09134
09135
09136
09137
09138
09139
09140
09141
09142
09143 if (binary_upgrade)
09144 binary_upgrade_set_type_oids_by_type_oid(fout, q,
09145 stinfo->baseType->dobj.catId.oid);
09146
09147 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
09148 fmtId(stinfo->dobj.name));
09149
09150 ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
09151 stinfo->dobj.name,
09152 stinfo->dobj.namespace->dobj.name,
09153 NULL,
09154 stinfo->baseType->rolname, false,
09155 "SHELL TYPE", SECTION_PRE_DATA,
09156 q->data, "", NULL,
09157 NULL, 0,
09158 NULL, NULL);
09159
09160 destroyPQExpBuffer(q);
09161 }
09162
09163
09164
09165
09166
09167
09168
09169
09170
09171
09172
09173
09174
09175
09176
09177
09178 static bool
09179 shouldDumpProcLangs(void)
09180 {
09181 if (!include_everything)
09182 return false;
09183
09184 if (dataOnly)
09185 return false;
09186 return true;
09187 }
09188
09189
09190
09191
09192
09193
09194 static void
09195 dumpProcLang(Archive *fout, ProcLangInfo *plang)
09196 {
09197 PQExpBuffer defqry;
09198 PQExpBuffer delqry;
09199 PQExpBuffer labelq;
09200 bool useParams;
09201 char *qlanname;
09202 char *lanschema;
09203 FuncInfo *funcInfo;
09204 FuncInfo *inlineInfo = NULL;
09205 FuncInfo *validatorInfo = NULL;
09206
09207
09208 if (!plang->dobj.dump || dataOnly)
09209 return;
09210
09211
09212
09213
09214
09215
09216
09217
09218
09219 funcInfo = findFuncByOid(plang->lanplcallfoid);
09220 if (funcInfo != NULL && !funcInfo->dobj.dump)
09221 funcInfo = NULL;
09222
09223 if (OidIsValid(plang->laninline))
09224 {
09225 inlineInfo = findFuncByOid(plang->laninline);
09226 if (inlineInfo != NULL && !inlineInfo->dobj.dump)
09227 inlineInfo = NULL;
09228 }
09229
09230 if (OidIsValid(plang->lanvalidator))
09231 {
09232 validatorInfo = findFuncByOid(plang->lanvalidator);
09233 if (validatorInfo != NULL && !validatorInfo->dobj.dump)
09234 validatorInfo = NULL;
09235 }
09236
09237
09238
09239
09240
09241
09242
09243
09244
09245
09246
09247
09248 useParams = (funcInfo != NULL &&
09249 (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
09250 (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
09251
09252 if (!plang->dobj.ext_member)
09253 {
09254 if (!useParams && !shouldDumpProcLangs())
09255 return;
09256 }
09257
09258 defqry = createPQExpBuffer();
09259 delqry = createPQExpBuffer();
09260 labelq = createPQExpBuffer();
09261
09262 qlanname = pg_strdup(fmtId(plang->dobj.name));
09263
09264
09265
09266
09267
09268
09269 if (useParams)
09270 lanschema = funcInfo->dobj.namespace->dobj.name;
09271 else
09272 lanschema = NULL;
09273
09274 appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
09275 qlanname);
09276
09277 if (useParams)
09278 {
09279 appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
09280 plang->lanpltrusted ? "TRUSTED " : "",
09281 qlanname);
09282 appendPQExpBuffer(defqry, " HANDLER %s",
09283 fmtId(funcInfo->dobj.name));
09284 if (OidIsValid(plang->laninline))
09285 {
09286 appendPQExpBuffer(defqry, " INLINE ");
09287
09288 if (inlineInfo->dobj.namespace != funcInfo->dobj.namespace)
09289 appendPQExpBuffer(defqry, "%s.",
09290 fmtId(inlineInfo->dobj.namespace->dobj.name));
09291 appendPQExpBuffer(defqry, "%s",
09292 fmtId(inlineInfo->dobj.name));
09293 }
09294 if (OidIsValid(plang->lanvalidator))
09295 {
09296 appendPQExpBuffer(defqry, " VALIDATOR ");
09297
09298 if (validatorInfo->dobj.namespace != funcInfo->dobj.namespace)
09299 appendPQExpBuffer(defqry, "%s.",
09300 fmtId(validatorInfo->dobj.namespace->dobj.name));
09301 appendPQExpBuffer(defqry, "%s",
09302 fmtId(validatorInfo->dobj.name));
09303 }
09304 }
09305 else
09306 {
09307
09308
09309
09310
09311
09312
09313
09314
09315
09316 appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
09317 qlanname);
09318 }
09319 appendPQExpBuffer(defqry, ";\n");
09320
09321 appendPQExpBuffer(labelq, "LANGUAGE %s", qlanname);
09322
09323 if (binary_upgrade)
09324 binary_upgrade_extension_member(defqry, &plang->dobj, labelq->data);
09325
09326 ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
09327 plang->dobj.name,
09328 lanschema, NULL, plang->lanowner,
09329 false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
09330 defqry->data, delqry->data, NULL,
09331 NULL, 0,
09332 NULL, NULL);
09333
09334
09335 dumpComment(fout, labelq->data,
09336 NULL, "",
09337 plang->dobj.catId, 0, plang->dobj.dumpId);
09338 dumpSecLabel(fout, labelq->data,
09339 NULL, "",
09340 plang->dobj.catId, 0, plang->dobj.dumpId);
09341
09342 if (plang->lanpltrusted)
09343 dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE",
09344 qlanname, NULL, plang->dobj.name,
09345 lanschema,
09346 plang->lanowner, plang->lanacl);
09347
09348 free(qlanname);
09349
09350 destroyPQExpBuffer(defqry);
09351 destroyPQExpBuffer(delqry);
09352 destroyPQExpBuffer(labelq);
09353 }
09354
09355
09356
09357
09358
09359
09360
09361 static char *
09362 format_function_arguments(FuncInfo *finfo, char *funcargs)
09363 {
09364 PQExpBufferData fn;
09365
09366 initPQExpBuffer(&fn);
09367 appendPQExpBuffer(&fn, "%s(%s)", fmtId(finfo->dobj.name), funcargs);
09368 return fn.data;
09369 }
09370
09371
09372
09373
09374
09375
09376
09377
09378
09379
09380
09381
09382 static char *
09383 format_function_arguments_old(Archive *fout,
09384 FuncInfo *finfo, int nallargs,
09385 char **allargtypes,
09386 char **argmodes,
09387 char **argnames)
09388 {
09389 PQExpBufferData fn;
09390 int j;
09391
09392 initPQExpBuffer(&fn);
09393 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
09394 for (j = 0; j < nallargs; j++)
09395 {
09396 Oid typid;
09397 char *typname;
09398 const char *argmode;
09399 const char *argname;
09400
09401 typid = allargtypes ? atooid(allargtypes[j]) : finfo->argtypes[j];
09402 typname = getFormattedTypeName(fout, typid, zeroAsOpaque);
09403
09404 if (argmodes)
09405 {
09406 switch (argmodes[j][0])
09407 {
09408 case PROARGMODE_IN:
09409 argmode = "";
09410 break;
09411 case PROARGMODE_OUT:
09412 argmode = "OUT ";
09413 break;
09414 case PROARGMODE_INOUT:
09415 argmode = "INOUT ";
09416 break;
09417 default:
09418 write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
09419 argmode = "";
09420 break;
09421 }
09422 }
09423 else
09424 argmode = "";
09425
09426 argname = argnames ? argnames[j] : (char *) NULL;
09427 if (argname && argname[0] == '\0')
09428 argname = NULL;
09429
09430 appendPQExpBuffer(&fn, "%s%s%s%s%s",
09431 (j > 0) ? ", " : "",
09432 argmode,
09433 argname ? fmtId(argname) : "",
09434 argname ? " " : "",
09435 typname);
09436 free(typname);
09437 }
09438 appendPQExpBuffer(&fn, ")");
09439 return fn.data;
09440 }
09441
09442
09443
09444
09445
09446
09447
09448
09449
09450
09451
09452 static char *
09453 format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes)
09454 {
09455 PQExpBufferData fn;
09456 int j;
09457
09458 initPQExpBuffer(&fn);
09459 if (honor_quotes)
09460 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
09461 else
09462 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
09463 for (j = 0; j < finfo->nargs; j++)
09464 {
09465 char *typname;
09466
09467 typname = getFormattedTypeName(fout, finfo->argtypes[j],
09468 zeroAsOpaque);
09469
09470 appendPQExpBuffer(&fn, "%s%s",
09471 (j > 0) ? ", " : "",
09472 typname);
09473 free(typname);
09474 }
09475 appendPQExpBuffer(&fn, ")");
09476 return fn.data;
09477 }
09478
09479
09480
09481
09482
09483
09484 static void
09485 dumpFunc(Archive *fout, FuncInfo *finfo)
09486 {
09487 PQExpBuffer query;
09488 PQExpBuffer q;
09489 PQExpBuffer delqry;
09490 PQExpBuffer labelq;
09491 PQExpBuffer asPart;
09492 PGresult *res;
09493 char *funcsig;
09494 char *funcfullsig;
09495 char *funcsig_tag;
09496 char *proretset;
09497 char *prosrc;
09498 char *probin;
09499 char *funcargs;
09500 char *funciargs;
09501 char *funcresult;
09502 char *proallargtypes;
09503 char *proargmodes;
09504 char *proargnames;
09505 char *proiswindow;
09506 char *provolatile;
09507 char *proisstrict;
09508 char *prosecdef;
09509 char *proleakproof;
09510 char *proconfig;
09511 char *procost;
09512 char *prorows;
09513 char *lanname;
09514 char *rettypename;
09515 int nallargs;
09516 char **allargtypes = NULL;
09517 char **argmodes = NULL;
09518 char **argnames = NULL;
09519 char **configitems = NULL;
09520 int nconfigitems = 0;
09521 int i;
09522
09523
09524 if (!finfo->dobj.dump || dataOnly)
09525 return;
09526
09527 query = createPQExpBuffer();
09528 q = createPQExpBuffer();
09529 delqry = createPQExpBuffer();
09530 labelq = createPQExpBuffer();
09531 asPart = createPQExpBuffer();
09532
09533
09534 selectSourceSchema(fout, finfo->dobj.namespace->dobj.name);
09535
09536
09537 if (fout->remoteVersion >= 90200)
09538 {
09539
09540
09541
09542 appendPQExpBuffer(query,
09543 "SELECT proretset, prosrc, probin, "
09544 "pg_catalog.pg_get_function_arguments(oid) AS funcargs, "
09545 "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, "
09546 "pg_catalog.pg_get_function_result(oid) AS funcresult, "
09547 "proiswindow, provolatile, proisstrict, prosecdef, "
09548 "proleakproof, proconfig, procost, prorows, "
09549 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
09550 "FROM pg_catalog.pg_proc "
09551 "WHERE oid = '%u'::pg_catalog.oid",
09552 finfo->dobj.catId.oid);
09553 }
09554 else if (fout->remoteVersion >= 80400)
09555 {
09556
09557
09558
09559
09560 appendPQExpBuffer(query,
09561 "SELECT proretset, prosrc, probin, "
09562 "pg_catalog.pg_get_function_arguments(oid) AS funcargs, "
09563 "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, "
09564 "pg_catalog.pg_get_function_result(oid) AS funcresult, "
09565 "proiswindow, provolatile, proisstrict, prosecdef, "
09566 "false AS proleakproof, "
09567 " proconfig, procost, prorows, "
09568 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
09569 "FROM pg_catalog.pg_proc "
09570 "WHERE oid = '%u'::pg_catalog.oid",
09571 finfo->dobj.catId.oid);
09572 }
09573 else if (fout->remoteVersion >= 80300)
09574 {
09575 appendPQExpBuffer(query,
09576 "SELECT proretset, prosrc, probin, "
09577 "proallargtypes, proargmodes, proargnames, "
09578 "false AS proiswindow, "
09579 "provolatile, proisstrict, prosecdef, "
09580 "false AS proleakproof, "
09581 "proconfig, procost, prorows, "
09582 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
09583 "FROM pg_catalog.pg_proc "
09584 "WHERE oid = '%u'::pg_catalog.oid",
09585 finfo->dobj.catId.oid);
09586 }
09587 else if (fout->remoteVersion >= 80100)
09588 {
09589 appendPQExpBuffer(query,
09590 "SELECT proretset, prosrc, probin, "
09591 "proallargtypes, proargmodes, proargnames, "
09592 "false AS proiswindow, "
09593 "provolatile, proisstrict, prosecdef, "
09594 "false AS proleakproof, "
09595 "null AS proconfig, 0 AS procost, 0 AS prorows, "
09596 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
09597 "FROM pg_catalog.pg_proc "
09598 "WHERE oid = '%u'::pg_catalog.oid",
09599 finfo->dobj.catId.oid);
09600 }
09601 else if (fout->remoteVersion >= 80000)
09602 {
09603 appendPQExpBuffer(query,
09604 "SELECT proretset, prosrc, probin, "
09605 "null AS proallargtypes, "
09606 "null AS proargmodes, "
09607 "proargnames, "
09608 "false AS proiswindow, "
09609 "provolatile, proisstrict, prosecdef, "
09610 "false AS proleakproof, "
09611 "null AS proconfig, 0 AS procost, 0 AS prorows, "
09612 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
09613 "FROM pg_catalog.pg_proc "
09614 "WHERE oid = '%u'::pg_catalog.oid",
09615 finfo->dobj.catId.oid);
09616 }
09617 else if (fout->remoteVersion >= 70300)
09618 {
09619 appendPQExpBuffer(query,
09620 "SELECT proretset, prosrc, probin, "
09621 "null AS proallargtypes, "
09622 "null AS proargmodes, "
09623 "null AS proargnames, "
09624 "false AS proiswindow, "
09625 "provolatile, proisstrict, prosecdef, "
09626 "false AS proleakproof, "
09627 "null AS proconfig, 0 AS procost, 0 AS prorows, "
09628 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
09629 "FROM pg_catalog.pg_proc "
09630 "WHERE oid = '%u'::pg_catalog.oid",
09631 finfo->dobj.catId.oid);
09632 }
09633 else if (fout->remoteVersion >= 70100)
09634 {
09635 appendPQExpBuffer(query,
09636 "SELECT proretset, prosrc, probin, "
09637 "null AS proallargtypes, "
09638 "null AS proargmodes, "
09639 "null AS proargnames, "
09640 "false AS proiswindow, "
09641 "case when proiscachable then 'i' else 'v' end AS provolatile, "
09642 "proisstrict, "
09643 "false AS prosecdef, "
09644 "false AS proleakproof, "
09645 "null AS proconfig, 0 AS procost, 0 AS prorows, "
09646 "(SELECT lanname FROM pg_language WHERE oid = prolang) AS lanname "
09647 "FROM pg_proc "
09648 "WHERE oid = '%u'::oid",
09649 finfo->dobj.catId.oid);
09650 }
09651 else
09652 {
09653 appendPQExpBuffer(query,
09654 "SELECT proretset, prosrc, probin, "
09655 "null AS proallargtypes, "
09656 "null AS proargmodes, "
09657 "null AS proargnames, "
09658 "false AS proiswindow, "
09659 "CASE WHEN proiscachable THEN 'i' ELSE 'v' END AS provolatile, "
09660 "false AS proisstrict, "
09661 "false AS prosecdef, "
09662 "false AS proleakproof, "
09663 "NULL AS proconfig, 0 AS procost, 0 AS prorows, "
09664 "(SELECT lanname FROM pg_language WHERE oid = prolang) AS lanname "
09665 "FROM pg_proc "
09666 "WHERE oid = '%u'::oid",
09667 finfo->dobj.catId.oid);
09668 }
09669
09670 res = ExecuteSqlQueryForSingleRow(fout, query->data);
09671
09672 proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
09673 prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
09674 probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
09675 if (fout->remoteVersion >= 80400)
09676 {
09677 funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
09678 funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
09679 funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
09680 proallargtypes = proargmodes = proargnames = NULL;
09681 }
09682 else
09683 {
09684 proallargtypes = PQgetvalue(res, 0, PQfnumber(res, "proallargtypes"));
09685 proargmodes = PQgetvalue(res, 0, PQfnumber(res, "proargmodes"));
09686 proargnames = PQgetvalue(res, 0, PQfnumber(res, "proargnames"));
09687 funcargs = funciargs = funcresult = NULL;
09688 }
09689 proiswindow = PQgetvalue(res, 0, PQfnumber(res, "proiswindow"));
09690 provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
09691 proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
09692 prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
09693 proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
09694 proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
09695 procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
09696 prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
09697 lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
09698
09699
09700
09701
09702
09703
09704
09705 if (probin[0] != '\0' && strcmp(probin, "-") != 0)
09706 {
09707 appendPQExpBuffer(asPart, "AS ");
09708 appendStringLiteralAH(asPart, probin, fout);
09709 if (strcmp(prosrc, "-") != 0)
09710 {
09711 appendPQExpBuffer(asPart, ", ");
09712
09713
09714
09715
09716
09717 if (disable_dollar_quoting ||
09718 (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
09719 appendStringLiteralAH(asPart, prosrc, fout);
09720 else
09721 appendStringLiteralDQ(asPart, prosrc, NULL);
09722 }
09723 }
09724 else
09725 {
09726 if (strcmp(prosrc, "-") != 0)
09727 {
09728 appendPQExpBuffer(asPart, "AS ");
09729
09730 if (disable_dollar_quoting)
09731 appendStringLiteralAH(asPart, prosrc, fout);
09732 else
09733 appendStringLiteralDQ(asPart, prosrc, NULL);
09734 }
09735 }
09736
09737 nallargs = finfo->nargs;
09738
09739 if (proallargtypes && *proallargtypes)
09740 {
09741 int nitems = 0;
09742
09743 if (!parsePGArray(proallargtypes, &allargtypes, &nitems) ||
09744 nitems < finfo->nargs)
09745 {
09746 write_msg(NULL, "WARNING: could not parse proallargtypes array\n");
09747 if (allargtypes)
09748 free(allargtypes);
09749 allargtypes = NULL;
09750 }
09751 else
09752 nallargs = nitems;
09753 }
09754
09755 if (proargmodes && *proargmodes)
09756 {
09757 int nitems = 0;
09758
09759 if (!parsePGArray(proargmodes, &argmodes, &nitems) ||
09760 nitems != nallargs)
09761 {
09762 write_msg(NULL, "WARNING: could not parse proargmodes array\n");
09763 if (argmodes)
09764 free(argmodes);
09765 argmodes = NULL;
09766 }
09767 }
09768
09769 if (proargnames && *proargnames)
09770 {
09771 int nitems = 0;
09772
09773 if (!parsePGArray(proargnames, &argnames, &nitems) ||
09774 nitems != nallargs)
09775 {
09776 write_msg(NULL, "WARNING: could not parse proargnames array\n");
09777 if (argnames)
09778 free(argnames);
09779 argnames = NULL;
09780 }
09781 }
09782
09783 if (proconfig && *proconfig)
09784 {
09785 if (!parsePGArray(proconfig, &configitems, &nconfigitems))
09786 {
09787 write_msg(NULL, "WARNING: could not parse proconfig array\n");
09788 if (configitems)
09789 free(configitems);
09790 configitems = NULL;
09791 nconfigitems = 0;
09792 }
09793 }
09794
09795 if (funcargs)
09796 {
09797
09798 funcfullsig = format_function_arguments(finfo, funcargs);
09799 funcsig = format_function_arguments(finfo, funciargs);
09800 }
09801 else
09802 {
09803
09804 funcsig = format_function_arguments_old(fout,
09805 finfo, nallargs, allargtypes,
09806 argmodes, argnames);
09807 funcfullsig = funcsig;
09808 }
09809
09810 funcsig_tag = format_function_signature(fout, finfo, false);
09811
09812
09813
09814
09815 appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
09816 fmtId(finfo->dobj.namespace->dobj.name),
09817 funcsig);
09818
09819 appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig);
09820 if (funcresult)
09821 appendPQExpBuffer(q, "RETURNS %s", funcresult);
09822 else
09823 {
09824 rettypename = getFormattedTypeName(fout, finfo->prorettype,
09825 zeroAsOpaque);
09826 appendPQExpBuffer(q, "RETURNS %s%s",
09827 (proretset[0] == 't') ? "SETOF " : "",
09828 rettypename);
09829 free(rettypename);
09830 }
09831
09832 appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
09833
09834 if (proiswindow[0] == 't')
09835 appendPQExpBuffer(q, " WINDOW");
09836
09837 if (provolatile[0] != PROVOLATILE_VOLATILE)
09838 {
09839 if (provolatile[0] == PROVOLATILE_IMMUTABLE)
09840 appendPQExpBuffer(q, " IMMUTABLE");
09841 else if (provolatile[0] == PROVOLATILE_STABLE)
09842 appendPQExpBuffer(q, " STABLE");
09843 else if (provolatile[0] != PROVOLATILE_VOLATILE)
09844 exit_horribly(NULL, "unrecognized provolatile value for function \"%s\"\n",
09845 finfo->dobj.name);
09846 }
09847
09848 if (proisstrict[0] == 't')
09849 appendPQExpBuffer(q, " STRICT");
09850
09851 if (prosecdef[0] == 't')
09852 appendPQExpBuffer(q, " SECURITY DEFINER");
09853
09854 if (proleakproof[0] == 't')
09855 appendPQExpBuffer(q, " LEAKPROOF");
09856
09857
09858
09859
09860
09861
09862 if (strcmp(procost, "0") != 0)
09863 {
09864 if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
09865 {
09866
09867 if (strcmp(procost, "1") != 0)
09868 appendPQExpBuffer(q, " COST %s", procost);
09869 }
09870 else
09871 {
09872
09873 if (strcmp(procost, "100") != 0)
09874 appendPQExpBuffer(q, " COST %s", procost);
09875 }
09876 }
09877 if (proretset[0] == 't' &&
09878 strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
09879 appendPQExpBuffer(q, " ROWS %s", prorows);
09880
09881 for (i = 0; i < nconfigitems; i++)
09882 {
09883
09884 char *configitem = configitems[i];
09885 char *pos;
09886
09887 pos = strchr(configitem, '=');
09888 if (pos == NULL)
09889 continue;
09890 *pos++ = '\0';
09891 appendPQExpBuffer(q, "\n SET %s TO ", fmtId(configitem));
09892
09893
09894
09895
09896
09897 if (pg_strcasecmp(configitem, "DateStyle") == 0
09898 || pg_strcasecmp(configitem, "search_path") == 0)
09899 appendPQExpBuffer(q, "%s", pos);
09900 else
09901 appendStringLiteralAH(q, pos, fout);
09902 }
09903
09904 appendPQExpBuffer(q, "\n %s;\n", asPart->data);
09905
09906 appendPQExpBuffer(labelq, "FUNCTION %s", funcsig);
09907
09908 if (binary_upgrade)
09909 binary_upgrade_extension_member(q, &finfo->dobj, labelq->data);
09910
09911 ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
09912 funcsig_tag,
09913 finfo->dobj.namespace->dobj.name,
09914 NULL,
09915 finfo->rolname, false,
09916 "FUNCTION", SECTION_PRE_DATA,
09917 q->data, delqry->data, NULL,
09918 NULL, 0,
09919 NULL, NULL);
09920
09921
09922 dumpComment(fout, labelq->data,
09923 finfo->dobj.namespace->dobj.name, finfo->rolname,
09924 finfo->dobj.catId, 0, finfo->dobj.dumpId);
09925 dumpSecLabel(fout, labelq->data,
09926 finfo->dobj.namespace->dobj.name, finfo->rolname,
09927 finfo->dobj.catId, 0, finfo->dobj.dumpId);
09928
09929 dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId, "FUNCTION",
09930 funcsig, NULL, funcsig_tag,
09931 finfo->dobj.namespace->dobj.name,
09932 finfo->rolname, finfo->proacl);
09933
09934 PQclear(res);
09935
09936 destroyPQExpBuffer(query);
09937 destroyPQExpBuffer(q);
09938 destroyPQExpBuffer(delqry);
09939 destroyPQExpBuffer(labelq);
09940 destroyPQExpBuffer(asPart);
09941 free(funcsig);
09942 free(funcsig_tag);
09943 if (allargtypes)
09944 free(allargtypes);
09945 if (argmodes)
09946 free(argmodes);
09947 if (argnames)
09948 free(argnames);
09949 if (configitems)
09950 free(configitems);
09951 }
09952
09953
09954
09955
09956
09957 static void
09958 dumpCast(Archive *fout, CastInfo *cast)
09959 {
09960 PQExpBuffer defqry;
09961 PQExpBuffer delqry;
09962 PQExpBuffer labelq;
09963 FuncInfo *funcInfo = NULL;
09964
09965
09966 if (!cast->dobj.dump || dataOnly)
09967 return;
09968
09969
09970 if (OidIsValid(cast->castfunc))
09971 {
09972 funcInfo = findFuncByOid(cast->castfunc);
09973 if (funcInfo == NULL)
09974 return;
09975 }
09976
09977
09978
09979
09980
09981
09982
09983
09984
09985
09986 if (!cast->dobj.ext_member)
09987 {
09988 TypeInfo *sourceInfo = findTypeByOid(cast->castsource);
09989 TypeInfo *targetInfo = findTypeByOid(cast->casttarget);
09990
09991 if (sourceInfo == NULL || targetInfo == NULL)
09992 return;
09993
09994
09995
09996
09997 if ((funcInfo == NULL ||
09998 strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
09999 strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 &&
10000 strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0)
10001 return;
10002
10003
10004
10005
10006 if (funcInfo &&
10007 strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
10008 !funcInfo->dobj.dump)
10009 return;
10010
10011
10012
10013
10014 if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
10015 !sourceInfo->dobj.dump)
10016 return;
10017
10018
10019
10020
10021 if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
10022 !targetInfo->dobj.dump)
10023 return;
10024 }
10025
10026
10027 selectSourceSchema(fout, "pg_catalog");
10028
10029 defqry = createPQExpBuffer();
10030 delqry = createPQExpBuffer();
10031 labelq = createPQExpBuffer();
10032
10033 appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
10034 getFormattedTypeName(fout, cast->castsource, zeroAsNone),
10035 getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
10036
10037 appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
10038 getFormattedTypeName(fout, cast->castsource, zeroAsNone),
10039 getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
10040
10041 switch (cast->castmethod)
10042 {
10043 case COERCION_METHOD_BINARY:
10044 appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
10045 break;
10046 case COERCION_METHOD_INOUT:
10047 appendPQExpBuffer(defqry, "WITH INOUT");
10048 break;
10049 case COERCION_METHOD_FUNCTION:
10050 if (funcInfo)
10051 {
10052 char *fsig = format_function_signature(fout, funcInfo, true);
10053
10054
10055
10056
10057
10058
10059 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
10060 fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
10061 free(fsig);
10062 }
10063 else
10064 write_msg(NULL, "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n");
10065 break;
10066 default:
10067 write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n");
10068 }
10069
10070 if (cast->castcontext == 'a')
10071 appendPQExpBuffer(defqry, " AS ASSIGNMENT");
10072 else if (cast->castcontext == 'i')
10073 appendPQExpBuffer(defqry, " AS IMPLICIT");
10074 appendPQExpBuffer(defqry, ";\n");
10075
10076 appendPQExpBuffer(labelq, "CAST (%s AS %s)",
10077 getFormattedTypeName(fout, cast->castsource, zeroAsNone),
10078 getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
10079
10080 if (binary_upgrade)
10081 binary_upgrade_extension_member(defqry, &cast->dobj, labelq->data);
10082
10083 ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
10084 labelq->data,
10085 "pg_catalog", NULL, "",
10086 false, "CAST", SECTION_PRE_DATA,
10087 defqry->data, delqry->data, NULL,
10088 NULL, 0,
10089 NULL, NULL);
10090
10091
10092 dumpComment(fout, labelq->data,
10093 NULL, "",
10094 cast->dobj.catId, 0, cast->dobj.dumpId);
10095
10096 destroyPQExpBuffer(defqry);
10097 destroyPQExpBuffer(delqry);
10098 destroyPQExpBuffer(labelq);
10099 }
10100
10101
10102
10103
10104
10105 static void
10106 dumpOpr(Archive *fout, OprInfo *oprinfo)
10107 {
10108 PQExpBuffer query;
10109 PQExpBuffer q;
10110 PQExpBuffer delq;
10111 PQExpBuffer labelq;
10112 PQExpBuffer oprid;
10113 PQExpBuffer details;
10114 const char *name;
10115 PGresult *res;
10116 int i_oprkind;
10117 int i_oprcode;
10118 int i_oprleft;
10119 int i_oprright;
10120 int i_oprcom;
10121 int i_oprnegate;
10122 int i_oprrest;
10123 int i_oprjoin;
10124 int i_oprcanmerge;
10125 int i_oprcanhash;
10126 char *oprkind;
10127 char *oprcode;
10128 char *oprleft;
10129 char *oprright;
10130 char *oprcom;
10131 char *oprnegate;
10132 char *oprrest;
10133 char *oprjoin;
10134 char *oprcanmerge;
10135 char *oprcanhash;
10136
10137
10138 if (!oprinfo->dobj.dump || dataOnly)
10139 return;
10140
10141
10142
10143
10144
10145 if (!OidIsValid(oprinfo->oprcode))
10146 return;
10147
10148 query = createPQExpBuffer();
10149 q = createPQExpBuffer();
10150 delq = createPQExpBuffer();
10151 labelq = createPQExpBuffer();
10152 oprid = createPQExpBuffer();
10153 details = createPQExpBuffer();
10154
10155
10156 selectSourceSchema(fout, oprinfo->dobj.namespace->dobj.name);
10157
10158 if (fout->remoteVersion >= 80300)
10159 {
10160 appendPQExpBuffer(query, "SELECT oprkind, "
10161 "oprcode::pg_catalog.regprocedure, "
10162 "oprleft::pg_catalog.regtype, "
10163 "oprright::pg_catalog.regtype, "
10164 "oprcom::pg_catalog.regoperator, "
10165 "oprnegate::pg_catalog.regoperator, "
10166 "oprrest::pg_catalog.regprocedure, "
10167 "oprjoin::pg_catalog.regprocedure, "
10168 "oprcanmerge, oprcanhash "
10169 "FROM pg_catalog.pg_operator "
10170 "WHERE oid = '%u'::pg_catalog.oid",
10171 oprinfo->dobj.catId.oid);
10172 }
10173 else if (fout->remoteVersion >= 70300)
10174 {
10175 appendPQExpBuffer(query, "SELECT oprkind, "
10176 "oprcode::pg_catalog.regprocedure, "
10177 "oprleft::pg_catalog.regtype, "
10178 "oprright::pg_catalog.regtype, "
10179 "oprcom::pg_catalog.regoperator, "
10180 "oprnegate::pg_catalog.regoperator, "
10181 "oprrest::pg_catalog.regprocedure, "
10182 "oprjoin::pg_catalog.regprocedure, "
10183 "(oprlsortop != 0) AS oprcanmerge, "
10184 "oprcanhash "
10185 "FROM pg_catalog.pg_operator "
10186 "WHERE oid = '%u'::pg_catalog.oid",
10187 oprinfo->dobj.catId.oid);
10188 }
10189 else if (fout->remoteVersion >= 70100)
10190 {
10191 appendPQExpBuffer(query, "SELECT oprkind, oprcode, "
10192 "CASE WHEN oprleft = 0 THEN '-' "
10193 "ELSE format_type(oprleft, NULL) END AS oprleft, "
10194 "CASE WHEN oprright = 0 THEN '-' "
10195 "ELSE format_type(oprright, NULL) END AS oprright, "
10196 "oprcom, oprnegate, oprrest, oprjoin, "
10197 "(oprlsortop != 0) AS oprcanmerge, "
10198 "oprcanhash "
10199 "FROM pg_operator "
10200 "WHERE oid = '%u'::oid",
10201 oprinfo->dobj.catId.oid);
10202 }
10203 else
10204 {
10205 appendPQExpBuffer(query, "SELECT oprkind, oprcode, "
10206 "CASE WHEN oprleft = 0 THEN '-'::name "
10207 "ELSE (SELECT typname FROM pg_type WHERE oid = oprleft) END AS oprleft, "
10208 "CASE WHEN oprright = 0 THEN '-'::name "
10209 "ELSE (SELECT typname FROM pg_type WHERE oid = oprright) END AS oprright, "
10210 "oprcom, oprnegate, oprrest, oprjoin, "
10211 "(oprlsortop != 0) AS oprcanmerge, "
10212 "oprcanhash "
10213 "FROM pg_operator "
10214 "WHERE oid = '%u'::oid",
10215 oprinfo->dobj.catId.oid);
10216 }
10217
10218 res = ExecuteSqlQueryForSingleRow(fout, query->data);
10219
10220 i_oprkind = PQfnumber(res, "oprkind");
10221 i_oprcode = PQfnumber(res, "oprcode");
10222 i_oprleft = PQfnumber(res, "oprleft");
10223 i_oprright = PQfnumber(res, "oprright");
10224 i_oprcom = PQfnumber(res, "oprcom");
10225 i_oprnegate = PQfnumber(res, "oprnegate");
10226 i_oprrest = PQfnumber(res, "oprrest");
10227 i_oprjoin = PQfnumber(res, "oprjoin");
10228 i_oprcanmerge = PQfnumber(res, "oprcanmerge");
10229 i_oprcanhash = PQfnumber(res, "oprcanhash");
10230
10231 oprkind = PQgetvalue(res, 0, i_oprkind);
10232 oprcode = PQgetvalue(res, 0, i_oprcode);
10233 oprleft = PQgetvalue(res, 0, i_oprleft);
10234 oprright = PQgetvalue(res, 0, i_oprright);
10235 oprcom = PQgetvalue(res, 0, i_oprcom);
10236 oprnegate = PQgetvalue(res, 0, i_oprnegate);
10237 oprrest = PQgetvalue(res, 0, i_oprrest);
10238 oprjoin = PQgetvalue(res, 0, i_oprjoin);
10239 oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
10240 oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
10241
10242 appendPQExpBuffer(details, " PROCEDURE = %s",
10243 convertRegProcReference(fout, oprcode));
10244
10245 appendPQExpBuffer(oprid, "%s (",
10246 oprinfo->dobj.name);
10247
10248
10249
10250
10251
10252 if (strcmp(oprkind, "r") == 0 ||
10253 strcmp(oprkind, "b") == 0)
10254 {
10255 if (fout->remoteVersion >= 70100)
10256 name = oprleft;
10257 else
10258 name = fmtId(oprleft);
10259 appendPQExpBuffer(details, ",\n LEFTARG = %s", name);
10260 appendPQExpBuffer(oprid, "%s", name);
10261 }
10262 else
10263 appendPQExpBuffer(oprid, "NONE");
10264
10265 if (strcmp(oprkind, "l") == 0 ||
10266 strcmp(oprkind, "b") == 0)
10267 {
10268 if (fout->remoteVersion >= 70100)
10269 name = oprright;
10270 else
10271 name = fmtId(oprright);
10272 appendPQExpBuffer(details, ",\n RIGHTARG = %s", name);
10273 appendPQExpBuffer(oprid, ", %s)", name);
10274 }
10275 else
10276 appendPQExpBuffer(oprid, ", NONE)");
10277
10278 name = convertOperatorReference(fout, oprcom);
10279 if (name)
10280 appendPQExpBuffer(details, ",\n COMMUTATOR = %s", name);
10281
10282 name = convertOperatorReference(fout, oprnegate);
10283 if (name)
10284 appendPQExpBuffer(details, ",\n NEGATOR = %s", name);
10285
10286 if (strcmp(oprcanmerge, "t") == 0)
10287 appendPQExpBuffer(details, ",\n MERGES");
10288
10289 if (strcmp(oprcanhash, "t") == 0)
10290 appendPQExpBuffer(details, ",\n HASHES");
10291
10292 name = convertRegProcReference(fout, oprrest);
10293 if (name)
10294 appendPQExpBuffer(details, ",\n RESTRICT = %s", name);
10295
10296 name = convertRegProcReference(fout, oprjoin);
10297 if (name)
10298 appendPQExpBuffer(details, ",\n JOIN = %s", name);
10299
10300
10301
10302
10303 appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
10304 fmtId(oprinfo->dobj.namespace->dobj.name),
10305 oprid->data);
10306
10307 appendPQExpBuffer(q, "CREATE OPERATOR %s (\n%s\n);\n",
10308 oprinfo->dobj.name, details->data);
10309
10310 appendPQExpBuffer(labelq, "OPERATOR %s", oprid->data);
10311
10312 if (binary_upgrade)
10313 binary_upgrade_extension_member(q, &oprinfo->dobj, labelq->data);
10314
10315 ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
10316 oprinfo->dobj.name,
10317 oprinfo->dobj.namespace->dobj.name,
10318 NULL,
10319 oprinfo->rolname,
10320 false, "OPERATOR", SECTION_PRE_DATA,
10321 q->data, delq->data, NULL,
10322 NULL, 0,
10323 NULL, NULL);
10324
10325
10326 dumpComment(fout, labelq->data,
10327 oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
10328 oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
10329
10330 PQclear(res);
10331
10332 destroyPQExpBuffer(query);
10333 destroyPQExpBuffer(q);
10334 destroyPQExpBuffer(delq);
10335 destroyPQExpBuffer(labelq);
10336 destroyPQExpBuffer(oprid);
10337 destroyPQExpBuffer(details);
10338 }
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348 static const char *
10349 convertRegProcReference(Archive *fout, const char *proc)
10350 {
10351
10352 if (strcmp(proc, "-") == 0)
10353 return NULL;
10354
10355 if (fout->remoteVersion >= 70300)
10356 {
10357 char *name;
10358 char *paren;
10359 bool inquote;
10360
10361 name = pg_strdup(proc);
10362
10363 inquote = false;
10364 for (paren = name; *paren; paren++)
10365 {
10366 if (*paren == '(' && !inquote)
10367 {
10368 *paren = '\0';
10369 break;
10370 }
10371 if (*paren == '"')
10372 inquote = !inquote;
10373 }
10374 return name;
10375 }
10376
10377
10378 return fmtId(proc);
10379 }
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391 static const char *
10392 convertOperatorReference(Archive *fout, const char *opr)
10393 {
10394 OprInfo *oprInfo;
10395
10396
10397 if (strcmp(opr, "0") == 0)
10398 return NULL;
10399
10400 if (fout->remoteVersion >= 70300)
10401 {
10402 char *name;
10403 char *oname;
10404 char *ptr;
10405 bool inquote;
10406 bool sawdot;
10407
10408 name = pg_strdup(opr);
10409
10410 inquote = false;
10411 sawdot = false;
10412 for (ptr = name; *ptr; ptr++)
10413 {
10414 if (*ptr == '"')
10415 inquote = !inquote;
10416 else if (*ptr == '.' && !inquote)
10417 sawdot = true;
10418 else if (*ptr == '(' && !inquote)
10419 {
10420 *ptr = '\0';
10421 break;
10422 }
10423 }
10424
10425 if (!sawdot)
10426 return name;
10427 oname = pg_malloc(strlen(name) + 11);
10428 sprintf(oname, "OPERATOR(%s)", name);
10429 free(name);
10430 return oname;
10431 }
10432
10433 oprInfo = findOprByOid(atooid(opr));
10434 if (oprInfo == NULL)
10435 {
10436 write_msg(NULL, "WARNING: could not find operator with OID %s\n",
10437 opr);
10438 return NULL;
10439 }
10440 return oprInfo->dobj.name;
10441 }
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451 static const char *
10452 convertTSFunction(Archive *fout, Oid funcOid)
10453 {
10454 char *result;
10455 char query[128];
10456 PGresult *res;
10457
10458 snprintf(query, sizeof(query),
10459 "SELECT '%u'::pg_catalog.regproc", funcOid);
10460 res = ExecuteSqlQueryForSingleRow(fout, query);
10461
10462 result = pg_strdup(PQgetvalue(res, 0, 0));
10463
10464 PQclear(res);
10465
10466 return result;
10467 }
10468
10469
10470
10471
10472
10473
10474 static void
10475 dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
10476 {
10477 PQExpBuffer query;
10478 PQExpBuffer q;
10479 PQExpBuffer delq;
10480 PQExpBuffer labelq;
10481 PGresult *res;
10482 int ntups;
10483 int i_opcintype;
10484 int i_opckeytype;
10485 int i_opcdefault;
10486 int i_opcfamily;
10487 int i_opcfamilyname;
10488 int i_opcfamilynsp;
10489 int i_amname;
10490 int i_amopstrategy;
10491 int i_amopreqcheck;
10492 int i_amopopr;
10493 int i_sortfamily;
10494 int i_sortfamilynsp;
10495 int i_amprocnum;
10496 int i_amproc;
10497 int i_amproclefttype;
10498 int i_amprocrighttype;
10499 char *opcintype;
10500 char *opckeytype;
10501 char *opcdefault;
10502 char *opcfamily;
10503 char *opcfamilyname;
10504 char *opcfamilynsp;
10505 char *amname;
10506 char *amopstrategy;
10507 char *amopreqcheck;
10508 char *amopopr;
10509 char *sortfamily;
10510 char *sortfamilynsp;
10511 char *amprocnum;
10512 char *amproc;
10513 char *amproclefttype;
10514 char *amprocrighttype;
10515 bool needComma;
10516 int i;
10517
10518
10519 if (!opcinfo->dobj.dump || dataOnly)
10520 return;
10521
10522
10523
10524
10525
10526
10527 if (fout->remoteVersion < 70300)
10528 return;
10529
10530 query = createPQExpBuffer();
10531 q = createPQExpBuffer();
10532 delq = createPQExpBuffer();
10533 labelq = createPQExpBuffer();
10534
10535
10536 selectSourceSchema(fout, opcinfo->dobj.namespace->dobj.name);
10537
10538
10539 if (fout->remoteVersion >= 80300)
10540 {
10541 appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
10542 "opckeytype::pg_catalog.regtype, "
10543 "opcdefault, opcfamily, "
10544 "opfname AS opcfamilyname, "
10545 "nspname AS opcfamilynsp, "
10546 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
10547 "FROM pg_catalog.pg_opclass c "
10548 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
10549 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
10550 "WHERE c.oid = '%u'::pg_catalog.oid",
10551 opcinfo->dobj.catId.oid);
10552 }
10553 else
10554 {
10555 appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
10556 "opckeytype::pg_catalog.regtype, "
10557 "opcdefault, NULL AS opcfamily, "
10558 "NULL AS opcfamilyname, "
10559 "NULL AS opcfamilynsp, "
10560 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
10561 "FROM pg_catalog.pg_opclass "
10562 "WHERE oid = '%u'::pg_catalog.oid",
10563 opcinfo->dobj.catId.oid);
10564 }
10565
10566 res = ExecuteSqlQueryForSingleRow(fout, query->data);
10567
10568 i_opcintype = PQfnumber(res, "opcintype");
10569 i_opckeytype = PQfnumber(res, "opckeytype");
10570 i_opcdefault = PQfnumber(res, "opcdefault");
10571 i_opcfamily = PQfnumber(res, "opcfamily");
10572 i_opcfamilyname = PQfnumber(res, "opcfamilyname");
10573 i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
10574 i_amname = PQfnumber(res, "amname");
10575
10576 opcintype = PQgetvalue(res, 0, i_opcintype);
10577 opckeytype = PQgetvalue(res, 0, i_opckeytype);
10578 opcdefault = PQgetvalue(res, 0, i_opcdefault);
10579
10580 opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
10581 opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
10582 opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
10583
10584 amname = pg_strdup(PQgetvalue(res, 0, i_amname));
10585
10586
10587
10588
10589 appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
10590 fmtId(opcinfo->dobj.namespace->dobj.name));
10591 appendPQExpBuffer(delq, ".%s",
10592 fmtId(opcinfo->dobj.name));
10593 appendPQExpBuffer(delq, " USING %s;\n",
10594 fmtId(amname));
10595
10596
10597 appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n ",
10598 fmtId(opcinfo->dobj.name));
10599 if (strcmp(opcdefault, "t") == 0)
10600 appendPQExpBuffer(q, "DEFAULT ");
10601 appendPQExpBuffer(q, "FOR TYPE %s USING %s",
10602 opcintype,
10603 fmtId(amname));
10604 if (strlen(opcfamilyname) > 0 &&
10605 (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 ||
10606 strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0))
10607 {
10608 appendPQExpBuffer(q, " FAMILY ");
10609 if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
10610 appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
10611 appendPQExpBuffer(q, "%s", fmtId(opcfamilyname));
10612 }
10613 appendPQExpBuffer(q, " AS\n ");
10614
10615 needComma = false;
10616
10617 if (strcmp(opckeytype, "-") != 0)
10618 {
10619 appendPQExpBuffer(q, "STORAGE %s",
10620 opckeytype);
10621 needComma = true;
10622 }
10623
10624 PQclear(res);
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638 resetPQExpBuffer(query);
10639
10640 if (fout->remoteVersion >= 90100)
10641 {
10642 appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
10643 "amopopr::pg_catalog.regoperator, "
10644 "opfname AS sortfamily, "
10645 "nspname AS sortfamilynsp "
10646 "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
10647 "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
10648 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
10649 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
10650 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
10651 "AND refobjid = '%u'::pg_catalog.oid "
10652 "AND amopfamily = '%s'::pg_catalog.oid "
10653 "ORDER BY amopstrategy",
10654 opcinfo->dobj.catId.oid,
10655 opcfamily);
10656 }
10657 else if (fout->remoteVersion >= 80400)
10658 {
10659 appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
10660 "amopopr::pg_catalog.regoperator, "
10661 "NULL AS sortfamily, "
10662 "NULL AS sortfamilynsp "
10663 "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
10664 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
10665 "AND refobjid = '%u'::pg_catalog.oid "
10666 "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
10667 "AND objid = ao.oid "
10668 "ORDER BY amopstrategy",
10669 opcinfo->dobj.catId.oid);
10670 }
10671 else if (fout->remoteVersion >= 80300)
10672 {
10673 appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
10674 "amopopr::pg_catalog.regoperator, "
10675 "NULL AS sortfamily, "
10676 "NULL AS sortfamilynsp "
10677 "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
10678 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
10679 "AND refobjid = '%u'::pg_catalog.oid "
10680 "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
10681 "AND objid = ao.oid "
10682 "ORDER BY amopstrategy",
10683 opcinfo->dobj.catId.oid);
10684 }
10685 else
10686 {
10687
10688
10689
10690
10691 appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
10692 "amopopr::pg_catalog.regoperator, "
10693 "NULL AS sortfamily, "
10694 "NULL AS sortfamilynsp "
10695 "FROM pg_catalog.pg_amop "
10696 "WHERE amopclaid = '%u'::pg_catalog.oid "
10697 "ORDER BY amopstrategy",
10698 opcinfo->dobj.catId.oid);
10699 }
10700
10701 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10702
10703 ntups = PQntuples(res);
10704
10705 i_amopstrategy = PQfnumber(res, "amopstrategy");
10706 i_amopreqcheck = PQfnumber(res, "amopreqcheck");
10707 i_amopopr = PQfnumber(res, "amopopr");
10708 i_sortfamily = PQfnumber(res, "sortfamily");
10709 i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
10710
10711 for (i = 0; i < ntups; i++)
10712 {
10713 amopstrategy = PQgetvalue(res, i, i_amopstrategy);
10714 amopreqcheck = PQgetvalue(res, i, i_amopreqcheck);
10715 amopopr = PQgetvalue(res, i, i_amopopr);
10716 sortfamily = PQgetvalue(res, i, i_sortfamily);
10717 sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
10718
10719 if (needComma)
10720 appendPQExpBuffer(q, " ,\n ");
10721
10722 appendPQExpBuffer(q, "OPERATOR %s %s",
10723 amopstrategy, amopopr);
10724
10725 if (strlen(sortfamily) > 0)
10726 {
10727 appendPQExpBuffer(q, " FOR ORDER BY ");
10728 if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
10729 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
10730 appendPQExpBuffer(q, "%s", fmtId(sortfamily));
10731 }
10732
10733 if (strcmp(amopreqcheck, "t") == 0)
10734 appendPQExpBuffer(q, " RECHECK");
10735
10736 needComma = true;
10737 }
10738
10739 PQclear(res);
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753 resetPQExpBuffer(query);
10754
10755 if (fout->remoteVersion >= 80300)
10756 {
10757 appendPQExpBuffer(query, "SELECT amprocnum, "
10758 "amproc::pg_catalog.regprocedure, "
10759 "amproclefttype::pg_catalog.regtype, "
10760 "amprocrighttype::pg_catalog.regtype "
10761 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
10762 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
10763 "AND refobjid = '%u'::pg_catalog.oid "
10764 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
10765 "AND objid = ap.oid "
10766 "ORDER BY amprocnum",
10767 opcinfo->dobj.catId.oid);
10768 }
10769 else
10770 {
10771 appendPQExpBuffer(query, "SELECT amprocnum, "
10772 "amproc::pg_catalog.regprocedure, "
10773 "'' AS amproclefttype, "
10774 "'' AS amprocrighttype "
10775 "FROM pg_catalog.pg_amproc "
10776 "WHERE amopclaid = '%u'::pg_catalog.oid "
10777 "ORDER BY amprocnum",
10778 opcinfo->dobj.catId.oid);
10779 }
10780
10781 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10782
10783 ntups = PQntuples(res);
10784
10785 i_amprocnum = PQfnumber(res, "amprocnum");
10786 i_amproc = PQfnumber(res, "amproc");
10787 i_amproclefttype = PQfnumber(res, "amproclefttype");
10788 i_amprocrighttype = PQfnumber(res, "amprocrighttype");
10789
10790 for (i = 0; i < ntups; i++)
10791 {
10792 amprocnum = PQgetvalue(res, i, i_amprocnum);
10793 amproc = PQgetvalue(res, i, i_amproc);
10794 amproclefttype = PQgetvalue(res, i, i_amproclefttype);
10795 amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
10796
10797 if (needComma)
10798 appendPQExpBuffer(q, " ,\n ");
10799
10800 appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
10801
10802 if (*amproclefttype && *amprocrighttype)
10803 appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
10804
10805 appendPQExpBuffer(q, " %s", amproc);
10806
10807 needComma = true;
10808 }
10809
10810 PQclear(res);
10811
10812 appendPQExpBuffer(q, ";\n");
10813
10814 appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
10815 fmtId(opcinfo->dobj.name));
10816 appendPQExpBuffer(labelq, " USING %s",
10817 fmtId(amname));
10818
10819 if (binary_upgrade)
10820 binary_upgrade_extension_member(q, &opcinfo->dobj, labelq->data);
10821
10822 ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
10823 opcinfo->dobj.name,
10824 opcinfo->dobj.namespace->dobj.name,
10825 NULL,
10826 opcinfo->rolname,
10827 false, "OPERATOR CLASS", SECTION_PRE_DATA,
10828 q->data, delq->data, NULL,
10829 NULL, 0,
10830 NULL, NULL);
10831
10832
10833 dumpComment(fout, labelq->data,
10834 NULL, opcinfo->rolname,
10835 opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
10836
10837 free(amname);
10838 destroyPQExpBuffer(query);
10839 destroyPQExpBuffer(q);
10840 destroyPQExpBuffer(delq);
10841 destroyPQExpBuffer(labelq);
10842 }
10843
10844
10845
10846
10847
10848
10849
10850
10851 static void
10852 dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
10853 {
10854 PQExpBuffer query;
10855 PQExpBuffer q;
10856 PQExpBuffer delq;
10857 PQExpBuffer labelq;
10858 PGresult *res;
10859 PGresult *res_ops;
10860 PGresult *res_procs;
10861 int ntups;
10862 int i_amname;
10863 int i_amopstrategy;
10864 int i_amopreqcheck;
10865 int i_amopopr;
10866 int i_sortfamily;
10867 int i_sortfamilynsp;
10868 int i_amprocnum;
10869 int i_amproc;
10870 int i_amproclefttype;
10871 int i_amprocrighttype;
10872 char *amname;
10873 char *amopstrategy;
10874 char *amopreqcheck;
10875 char *amopopr;
10876 char *sortfamily;
10877 char *sortfamilynsp;
10878 char *amprocnum;
10879 char *amproc;
10880 char *amproclefttype;
10881 char *amprocrighttype;
10882 bool needComma;
10883 int i;
10884
10885
10886 if (!opfinfo->dobj.dump || dataOnly)
10887 return;
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898 query = createPQExpBuffer();
10899 q = createPQExpBuffer();
10900 delq = createPQExpBuffer();
10901 labelq = createPQExpBuffer();
10902
10903
10904 selectSourceSchema(fout, opfinfo->dobj.namespace->dobj.name);
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916 if (fout->remoteVersion >= 90100)
10917 {
10918 appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
10919 "amopopr::pg_catalog.regoperator, "
10920 "opfname AS sortfamily, "
10921 "nspname AS sortfamilynsp "
10922 "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
10923 "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
10924 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
10925 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
10926 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
10927 "AND refobjid = '%u'::pg_catalog.oid "
10928 "AND amopfamily = '%u'::pg_catalog.oid "
10929 "ORDER BY amopstrategy",
10930 opfinfo->dobj.catId.oid,
10931 opfinfo->dobj.catId.oid);
10932 }
10933 else if (fout->remoteVersion >= 80400)
10934 {
10935 appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
10936 "amopopr::pg_catalog.regoperator, "
10937 "NULL AS sortfamily, "
10938 "NULL AS sortfamilynsp "
10939 "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
10940 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
10941 "AND refobjid = '%u'::pg_catalog.oid "
10942 "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
10943 "AND objid = ao.oid "
10944 "ORDER BY amopstrategy",
10945 opfinfo->dobj.catId.oid);
10946 }
10947 else
10948 {
10949 appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
10950 "amopopr::pg_catalog.regoperator, "
10951 "NULL AS sortfamily, "
10952 "NULL AS sortfamilynsp "
10953 "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
10954 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
10955 "AND refobjid = '%u'::pg_catalog.oid "
10956 "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
10957 "AND objid = ao.oid "
10958 "ORDER BY amopstrategy",
10959 opfinfo->dobj.catId.oid);
10960 }
10961
10962 res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10963
10964 resetPQExpBuffer(query);
10965
10966 appendPQExpBuffer(query, "SELECT amprocnum, "
10967 "amproc::pg_catalog.regprocedure, "
10968 "amproclefttype::pg_catalog.regtype, "
10969 "amprocrighttype::pg_catalog.regtype "
10970 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
10971 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
10972 "AND refobjid = '%u'::pg_catalog.oid "
10973 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
10974 "AND objid = ap.oid "
10975 "ORDER BY amprocnum",
10976 opfinfo->dobj.catId.oid);
10977
10978 res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10979
10980 if (PQntuples(res_ops) == 0 && PQntuples(res_procs) == 0)
10981 {
10982
10983 resetPQExpBuffer(query);
10984
10985 appendPQExpBuffer(query, "SELECT 1 "
10986 "FROM pg_catalog.pg_opclass c, pg_catalog.pg_opfamily f, pg_catalog.pg_depend "
10987 "WHERE f.oid = '%u'::pg_catalog.oid "
10988 "AND refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
10989 "AND refobjid = f.oid "
10990 "AND classid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
10991 "AND objid = c.oid "
10992 "AND (opcname != opfname OR opcnamespace != opfnamespace OR opcowner != opfowner) "
10993 "LIMIT 1",
10994 opfinfo->dobj.catId.oid);
10995
10996 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10997
10998 if (PQntuples(res) == 0)
10999 {
11000
11001 PQclear(res);
11002 PQclear(res_ops);
11003 PQclear(res_procs);
11004 destroyPQExpBuffer(query);
11005 destroyPQExpBuffer(q);
11006 destroyPQExpBuffer(delq);
11007 destroyPQExpBuffer(labelq);
11008 return;
11009 }
11010
11011 PQclear(res);
11012 }
11013
11014
11015 resetPQExpBuffer(query);
11016
11017 appendPQExpBuffer(query, "SELECT "
11018 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
11019 "FROM pg_catalog.pg_opfamily "
11020 "WHERE oid = '%u'::pg_catalog.oid",
11021 opfinfo->dobj.catId.oid);
11022
11023 res = ExecuteSqlQueryForSingleRow(fout, query->data);
11024
11025 i_amname = PQfnumber(res, "amname");
11026
11027
11028 amname = pg_strdup(PQgetvalue(res, 0, i_amname));
11029
11030
11031
11032
11033 appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
11034 fmtId(opfinfo->dobj.namespace->dobj.name));
11035 appendPQExpBuffer(delq, ".%s",
11036 fmtId(opfinfo->dobj.name));
11037 appendPQExpBuffer(delq, " USING %s;\n",
11038 fmtId(amname));
11039
11040
11041 appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
11042 fmtId(opfinfo->dobj.name));
11043 appendPQExpBuffer(q, " USING %s;\n",
11044 fmtId(amname));
11045
11046 PQclear(res);
11047
11048
11049 if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
11050 {
11051 appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
11052 fmtId(opfinfo->dobj.name));
11053 appendPQExpBuffer(q, " USING %s ADD\n ",
11054 fmtId(amname));
11055
11056 needComma = false;
11057
11058
11059
11060
11061 ntups = PQntuples(res_ops);
11062
11063 i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
11064 i_amopreqcheck = PQfnumber(res_ops, "amopreqcheck");
11065 i_amopopr = PQfnumber(res_ops, "amopopr");
11066 i_sortfamily = PQfnumber(res_ops, "sortfamily");
11067 i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
11068
11069 for (i = 0; i < ntups; i++)
11070 {
11071 amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
11072 amopreqcheck = PQgetvalue(res_ops, i, i_amopreqcheck);
11073 amopopr = PQgetvalue(res_ops, i, i_amopopr);
11074 sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
11075 sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
11076
11077 if (needComma)
11078 appendPQExpBuffer(q, " ,\n ");
11079
11080 appendPQExpBuffer(q, "OPERATOR %s %s",
11081 amopstrategy, amopopr);
11082
11083 if (strlen(sortfamily) > 0)
11084 {
11085 appendPQExpBuffer(q, " FOR ORDER BY ");
11086 if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0)
11087 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
11088 appendPQExpBuffer(q, "%s", fmtId(sortfamily));
11089 }
11090
11091 if (strcmp(amopreqcheck, "t") == 0)
11092 appendPQExpBuffer(q, " RECHECK");
11093
11094 needComma = true;
11095 }
11096
11097
11098
11099
11100 ntups = PQntuples(res_procs);
11101
11102 i_amprocnum = PQfnumber(res_procs, "amprocnum");
11103 i_amproc = PQfnumber(res_procs, "amproc");
11104 i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
11105 i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
11106
11107 for (i = 0; i < ntups; i++)
11108 {
11109 amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
11110 amproc = PQgetvalue(res_procs, i, i_amproc);
11111 amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
11112 amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
11113
11114 if (needComma)
11115 appendPQExpBuffer(q, " ,\n ");
11116
11117 appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
11118 amprocnum, amproclefttype, amprocrighttype,
11119 amproc);
11120
11121 needComma = true;
11122 }
11123
11124 appendPQExpBuffer(q, ";\n");
11125 }
11126
11127 appendPQExpBuffer(labelq, "OPERATOR FAMILY %s",
11128 fmtId(opfinfo->dobj.name));
11129 appendPQExpBuffer(labelq, " USING %s",
11130 fmtId(amname));
11131
11132 if (binary_upgrade)
11133 binary_upgrade_extension_member(q, &opfinfo->dobj, labelq->data);
11134
11135 ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
11136 opfinfo->dobj.name,
11137 opfinfo->dobj.namespace->dobj.name,
11138 NULL,
11139 opfinfo->rolname,
11140 false, "OPERATOR FAMILY", SECTION_PRE_DATA,
11141 q->data, delq->data, NULL,
11142 NULL, 0,
11143 NULL, NULL);
11144
11145
11146 dumpComment(fout, labelq->data,
11147 NULL, opfinfo->rolname,
11148 opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
11149
11150 free(amname);
11151 PQclear(res_ops);
11152 PQclear(res_procs);
11153 destroyPQExpBuffer(query);
11154 destroyPQExpBuffer(q);
11155 destroyPQExpBuffer(delq);
11156 destroyPQExpBuffer(labelq);
11157 }
11158
11159
11160
11161
11162
11163 static void
11164 dumpCollation(Archive *fout, CollInfo *collinfo)
11165 {
11166 PQExpBuffer query;
11167 PQExpBuffer q;
11168 PQExpBuffer delq;
11169 PQExpBuffer labelq;
11170 PGresult *res;
11171 int i_collcollate;
11172 int i_collctype;
11173 const char *collcollate;
11174 const char *collctype;
11175
11176
11177 if (!collinfo->dobj.dump || dataOnly)
11178 return;
11179
11180 query = createPQExpBuffer();
11181 q = createPQExpBuffer();
11182 delq = createPQExpBuffer();
11183 labelq = createPQExpBuffer();
11184
11185
11186 selectSourceSchema(fout, collinfo->dobj.namespace->dobj.name);
11187
11188
11189 appendPQExpBuffer(query, "SELECT "
11190 "collcollate, "
11191 "collctype "
11192 "FROM pg_catalog.pg_collation c "
11193 "WHERE c.oid = '%u'::pg_catalog.oid",
11194 collinfo->dobj.catId.oid);
11195
11196 res = ExecuteSqlQueryForSingleRow(fout, query->data);
11197
11198 i_collcollate = PQfnumber(res, "collcollate");
11199 i_collctype = PQfnumber(res, "collctype");
11200
11201 collcollate = PQgetvalue(res, 0, i_collcollate);
11202 collctype = PQgetvalue(res, 0, i_collctype);
11203
11204
11205
11206
11207 appendPQExpBuffer(delq, "DROP COLLATION %s",
11208 fmtId(collinfo->dobj.namespace->dobj.name));
11209 appendPQExpBuffer(delq, ".%s;\n",
11210 fmtId(collinfo->dobj.name));
11211
11212 appendPQExpBuffer(q, "CREATE COLLATION %s (lc_collate = ",
11213 fmtId(collinfo->dobj.name));
11214 appendStringLiteralAH(q, collcollate, fout);
11215 appendPQExpBuffer(q, ", lc_ctype = ");
11216 appendStringLiteralAH(q, collctype, fout);
11217 appendPQExpBuffer(q, ");\n");
11218
11219 appendPQExpBuffer(labelq, "COLLATION %s", fmtId(collinfo->dobj.name));
11220
11221 if (binary_upgrade)
11222 binary_upgrade_extension_member(q, &collinfo->dobj, labelq->data);
11223
11224 ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
11225 collinfo->dobj.name,
11226 collinfo->dobj.namespace->dobj.name,
11227 NULL,
11228 collinfo->rolname,
11229 false, "COLLATION", SECTION_PRE_DATA,
11230 q->data, delq->data, NULL,
11231 NULL, 0,
11232 NULL, NULL);
11233
11234
11235 dumpComment(fout, labelq->data,
11236 collinfo->dobj.namespace->dobj.name, collinfo->rolname,
11237 collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
11238
11239 PQclear(res);
11240
11241 destroyPQExpBuffer(query);
11242 destroyPQExpBuffer(q);
11243 destroyPQExpBuffer(delq);
11244 destroyPQExpBuffer(labelq);
11245 }
11246
11247
11248
11249
11250
11251 static void
11252 dumpConversion(Archive *fout, ConvInfo *convinfo)
11253 {
11254 PQExpBuffer query;
11255 PQExpBuffer q;
11256 PQExpBuffer delq;
11257 PQExpBuffer labelq;
11258 PGresult *res;
11259 int i_conforencoding;
11260 int i_contoencoding;
11261 int i_conproc;
11262 int i_condefault;
11263 const char *conforencoding;
11264 const char *contoencoding;
11265 const char *conproc;
11266 bool condefault;
11267
11268
11269 if (!convinfo->dobj.dump || dataOnly)
11270 return;
11271
11272 query = createPQExpBuffer();
11273 q = createPQExpBuffer();
11274 delq = createPQExpBuffer();
11275 labelq = createPQExpBuffer();
11276
11277
11278 selectSourceSchema(fout, convinfo->dobj.namespace->dobj.name);
11279
11280
11281 appendPQExpBuffer(query, "SELECT "
11282 "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
11283 "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
11284 "conproc, condefault "
11285 "FROM pg_catalog.pg_conversion c "
11286 "WHERE c.oid = '%u'::pg_catalog.oid",
11287 convinfo->dobj.catId.oid);
11288
11289 res = ExecuteSqlQueryForSingleRow(fout, query->data);
11290
11291 i_conforencoding = PQfnumber(res, "conforencoding");
11292 i_contoencoding = PQfnumber(res, "contoencoding");
11293 i_conproc = PQfnumber(res, "conproc");
11294 i_condefault = PQfnumber(res, "condefault");
11295
11296 conforencoding = PQgetvalue(res, 0, i_conforencoding);
11297 contoencoding = PQgetvalue(res, 0, i_contoencoding);
11298 conproc = PQgetvalue(res, 0, i_conproc);
11299 condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
11300
11301
11302
11303
11304 appendPQExpBuffer(delq, "DROP CONVERSION %s",
11305 fmtId(convinfo->dobj.namespace->dobj.name));
11306 appendPQExpBuffer(delq, ".%s;\n",
11307 fmtId(convinfo->dobj.name));
11308
11309 appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
11310 (condefault) ? "DEFAULT " : "",
11311 fmtId(convinfo->dobj.name));
11312 appendStringLiteralAH(q, conforencoding, fout);
11313 appendPQExpBuffer(q, " TO ");
11314 appendStringLiteralAH(q, contoencoding, fout);
11315
11316 appendPQExpBuffer(q, " FROM %s;\n", conproc);
11317
11318 appendPQExpBuffer(labelq, "CONVERSION %s", fmtId(convinfo->dobj.name));
11319
11320 if (binary_upgrade)
11321 binary_upgrade_extension_member(q, &convinfo->dobj, labelq->data);
11322
11323 ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
11324 convinfo->dobj.name,
11325 convinfo->dobj.namespace->dobj.name,
11326 NULL,
11327 convinfo->rolname,
11328 false, "CONVERSION", SECTION_PRE_DATA,
11329 q->data, delq->data, NULL,
11330 NULL, 0,
11331 NULL, NULL);
11332
11333
11334 dumpComment(fout, labelq->data,
11335 convinfo->dobj.namespace->dobj.name, convinfo->rolname,
11336 convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
11337
11338 PQclear(res);
11339
11340 destroyPQExpBuffer(query);
11341 destroyPQExpBuffer(q);
11342 destroyPQExpBuffer(delq);
11343 destroyPQExpBuffer(labelq);
11344 }
11345
11346
11347
11348
11349
11350
11351
11352 static char *
11353 format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
11354 {
11355 PQExpBufferData buf;
11356 int j;
11357
11358 initPQExpBuffer(&buf);
11359 if (honor_quotes)
11360 appendPQExpBuffer(&buf, "%s",
11361 fmtId(agginfo->aggfn.dobj.name));
11362 else
11363 appendPQExpBuffer(&buf, "%s", agginfo->aggfn.dobj.name);
11364
11365 if (agginfo->aggfn.nargs == 0)
11366 appendPQExpBuffer(&buf, "(*)");
11367 else
11368 {
11369 appendPQExpBuffer(&buf, "(");
11370 for (j = 0; j < agginfo->aggfn.nargs; j++)
11371 {
11372 char *typname;
11373
11374 typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
11375 zeroAsOpaque);
11376
11377 appendPQExpBuffer(&buf, "%s%s",
11378 (j > 0) ? ", " : "",
11379 typname);
11380 free(typname);
11381 }
11382 appendPQExpBuffer(&buf, ")");
11383 }
11384 return buf.data;
11385 }
11386
11387
11388
11389
11390
11391 static void
11392 dumpAgg(Archive *fout, AggInfo *agginfo)
11393 {
11394 PQExpBuffer query;
11395 PQExpBuffer q;
11396 PQExpBuffer delq;
11397 PQExpBuffer labelq;
11398 PQExpBuffer details;
11399 char *aggsig;
11400 char *aggsig_tag;
11401 PGresult *res;
11402 int i_aggtransfn;
11403 int i_aggfinalfn;
11404 int i_aggsortop;
11405 int i_aggtranstype;
11406 int i_agginitval;
11407 int i_convertok;
11408 const char *aggtransfn;
11409 const char *aggfinalfn;
11410 const char *aggsortop;
11411 const char *aggtranstype;
11412 const char *agginitval;
11413 bool convertok;
11414
11415
11416 if (!agginfo->aggfn.dobj.dump || dataOnly)
11417 return;
11418
11419 query = createPQExpBuffer();
11420 q = createPQExpBuffer();
11421 delq = createPQExpBuffer();
11422 labelq = createPQExpBuffer();
11423 details = createPQExpBuffer();
11424
11425
11426 selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);
11427
11428
11429 if (fout->remoteVersion >= 80100)
11430 {
11431 appendPQExpBuffer(query, "SELECT aggtransfn, "
11432 "aggfinalfn, aggtranstype::pg_catalog.regtype, "
11433 "aggsortop::pg_catalog.regoperator, "
11434 "agginitval, "
11435 "'t'::boolean AS convertok "
11436 "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
11437 "WHERE a.aggfnoid = p.oid "
11438 "AND p.oid = '%u'::pg_catalog.oid",
11439 agginfo->aggfn.dobj.catId.oid);
11440 }
11441 else if (fout->remoteVersion >= 70300)
11442 {
11443 appendPQExpBuffer(query, "SELECT aggtransfn, "
11444 "aggfinalfn, aggtranstype::pg_catalog.regtype, "
11445 "0 AS aggsortop, "
11446 "agginitval, "
11447 "'t'::boolean AS convertok "
11448 "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
11449 "WHERE a.aggfnoid = p.oid "
11450 "AND p.oid = '%u'::pg_catalog.oid",
11451 agginfo->aggfn.dobj.catId.oid);
11452 }
11453 else if (fout->remoteVersion >= 70100)
11454 {
11455 appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
11456 "format_type(aggtranstype, NULL) AS aggtranstype, "
11457 "0 AS aggsortop, "
11458 "agginitval, "
11459 "'t'::boolean AS convertok "
11460 "FROM pg_aggregate "
11461 "WHERE oid = '%u'::oid",
11462 agginfo->aggfn.dobj.catId.oid);
11463 }
11464 else
11465 {
11466 appendPQExpBuffer(query, "SELECT aggtransfn1 AS aggtransfn, "
11467 "aggfinalfn, "
11468 "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, "
11469 "0 AS aggsortop, "
11470 "agginitval1 AS agginitval, "
11471 "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok "
11472 "FROM pg_aggregate "
11473 "WHERE oid = '%u'::oid",
11474 agginfo->aggfn.dobj.catId.oid);
11475 }
11476
11477 res = ExecuteSqlQueryForSingleRow(fout, query->data);
11478
11479 i_aggtransfn = PQfnumber(res, "aggtransfn");
11480 i_aggfinalfn = PQfnumber(res, "aggfinalfn");
11481 i_aggsortop = PQfnumber(res, "aggsortop");
11482 i_aggtranstype = PQfnumber(res, "aggtranstype");
11483 i_agginitval = PQfnumber(res, "agginitval");
11484 i_convertok = PQfnumber(res, "convertok");
11485
11486 aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
11487 aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
11488 aggsortop = PQgetvalue(res, 0, i_aggsortop);
11489 aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
11490 agginitval = PQgetvalue(res, 0, i_agginitval);
11491 convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
11492
11493 aggsig = format_aggregate_signature(agginfo, fout, true);
11494 aggsig_tag = format_aggregate_signature(agginfo, fout, false);
11495
11496 if (!convertok)
11497 {
11498 write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
11499 aggsig);
11500 return;
11501 }
11502
11503 if (fout->remoteVersion >= 70300)
11504 {
11505
11506 appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
11507 aggtransfn,
11508 aggtranstype);
11509 }
11510 else if (fout->remoteVersion >= 70100)
11511 {
11512
11513 appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
11514 fmtId(aggtransfn),
11515 aggtranstype);
11516 }
11517 else
11518 {
11519
11520 appendPQExpBuffer(details, " SFUNC = %s,\n",
11521 fmtId(aggtransfn));
11522 appendPQExpBuffer(details, " STYPE = %s",
11523 fmtId(aggtranstype));
11524 }
11525
11526 if (!PQgetisnull(res, 0, i_agginitval))
11527 {
11528 appendPQExpBuffer(details, ",\n INITCOND = ");
11529 appendStringLiteralAH(details, agginitval, fout);
11530 }
11531
11532 if (strcmp(aggfinalfn, "-") != 0)
11533 {
11534 appendPQExpBuffer(details, ",\n FINALFUNC = %s",
11535 aggfinalfn);
11536 }
11537
11538 aggsortop = convertOperatorReference(fout, aggsortop);
11539 if (aggsortop)
11540 {
11541 appendPQExpBuffer(details, ",\n SORTOP = %s",
11542 aggsortop);
11543 }
11544
11545
11546
11547
11548 appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
11549 fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
11550 aggsig);
11551
11552 appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
11553 aggsig, details->data);
11554
11555 appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig);
11556
11557 if (binary_upgrade)
11558 binary_upgrade_extension_member(q, &agginfo->aggfn.dobj, labelq->data);
11559
11560 ArchiveEntry(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
11561 aggsig_tag,
11562 agginfo->aggfn.dobj.namespace->dobj.name,
11563 NULL,
11564 agginfo->aggfn.rolname,
11565 false, "AGGREGATE", SECTION_PRE_DATA,
11566 q->data, delq->data, NULL,
11567 NULL, 0,
11568 NULL, NULL);
11569
11570
11571 dumpComment(fout, labelq->data,
11572 agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
11573 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
11574 dumpSecLabel(fout, labelq->data,
11575 agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
11576 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
11577
11578
11579
11580
11581
11582
11583 free(aggsig);
11584 free(aggsig_tag);
11585
11586 aggsig = format_function_signature(fout, &agginfo->aggfn, true);
11587 aggsig_tag = format_function_signature(fout, &agginfo->aggfn, false);
11588
11589 dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
11590 "FUNCTION",
11591 aggsig, NULL, aggsig_tag,
11592 agginfo->aggfn.dobj.namespace->dobj.name,
11593 agginfo->aggfn.rolname, agginfo->aggfn.proacl);
11594
11595 free(aggsig);
11596 free(aggsig_tag);
11597
11598 PQclear(res);
11599
11600 destroyPQExpBuffer(query);
11601 destroyPQExpBuffer(q);
11602 destroyPQExpBuffer(delq);
11603 destroyPQExpBuffer(labelq);
11604 destroyPQExpBuffer(details);
11605 }
11606
11607
11608
11609
11610
11611 static void
11612 dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
11613 {
11614 PQExpBuffer q;
11615 PQExpBuffer delq;
11616 PQExpBuffer labelq;
11617
11618
11619 if (!prsinfo->dobj.dump || dataOnly)
11620 return;
11621
11622 q = createPQExpBuffer();
11623 delq = createPQExpBuffer();
11624 labelq = createPQExpBuffer();
11625
11626
11627 selectSourceSchema(fout, prsinfo->dobj.namespace->dobj.name);
11628
11629 appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
11630 fmtId(prsinfo->dobj.name));
11631
11632 appendPQExpBuffer(q, " START = %s,\n",
11633 convertTSFunction(fout, prsinfo->prsstart));
11634 appendPQExpBuffer(q, " GETTOKEN = %s,\n",
11635 convertTSFunction(fout, prsinfo->prstoken));
11636 appendPQExpBuffer(q, " END = %s,\n",
11637 convertTSFunction(fout, prsinfo->prsend));
11638 if (prsinfo->prsheadline != InvalidOid)
11639 appendPQExpBuffer(q, " HEADLINE = %s,\n",
11640 convertTSFunction(fout, prsinfo->prsheadline));
11641 appendPQExpBuffer(q, " LEXTYPES = %s );\n",
11642 convertTSFunction(fout, prsinfo->prslextype));
11643
11644
11645
11646
11647 appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s",
11648 fmtId(prsinfo->dobj.namespace->dobj.name));
11649 appendPQExpBuffer(delq, ".%s;\n",
11650 fmtId(prsinfo->dobj.name));
11651
11652 appendPQExpBuffer(labelq, "TEXT SEARCH PARSER %s",
11653 fmtId(prsinfo->dobj.name));
11654
11655 if (binary_upgrade)
11656 binary_upgrade_extension_member(q, &prsinfo->dobj, labelq->data);
11657
11658 ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
11659 prsinfo->dobj.name,
11660 prsinfo->dobj.namespace->dobj.name,
11661 NULL,
11662 "",
11663 false, "TEXT SEARCH PARSER", SECTION_PRE_DATA,
11664 q->data, delq->data, NULL,
11665 NULL, 0,
11666 NULL, NULL);
11667
11668
11669 dumpComment(fout, labelq->data,
11670 NULL, "",
11671 prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
11672
11673 destroyPQExpBuffer(q);
11674 destroyPQExpBuffer(delq);
11675 destroyPQExpBuffer(labelq);
11676 }
11677
11678
11679
11680
11681
11682 static void
11683 dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
11684 {
11685 PQExpBuffer q;
11686 PQExpBuffer delq;
11687 PQExpBuffer labelq;
11688 PQExpBuffer query;
11689 PGresult *res;
11690 char *nspname;
11691 char *tmplname;
11692
11693
11694 if (!dictinfo->dobj.dump || dataOnly)
11695 return;
11696
11697 q = createPQExpBuffer();
11698 delq = createPQExpBuffer();
11699 labelq = createPQExpBuffer();
11700 query = createPQExpBuffer();
11701
11702
11703 selectSourceSchema(fout, "pg_catalog");
11704 appendPQExpBuffer(query, "SELECT nspname, tmplname "
11705 "FROM pg_ts_template p, pg_namespace n "
11706 "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
11707 dictinfo->dicttemplate);
11708 res = ExecuteSqlQueryForSingleRow(fout, query->data);
11709 nspname = PQgetvalue(res, 0, 0);
11710 tmplname = PQgetvalue(res, 0, 1);
11711
11712
11713 selectSourceSchema(fout, dictinfo->dobj.namespace->dobj.name);
11714
11715 appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
11716 fmtId(dictinfo->dobj.name));
11717
11718 appendPQExpBuffer(q, " TEMPLATE = ");
11719 if (strcmp(nspname, dictinfo->dobj.namespace->dobj.name) != 0)
11720 appendPQExpBuffer(q, "%s.", fmtId(nspname));
11721 appendPQExpBuffer(q, "%s", fmtId(tmplname));
11722
11723 PQclear(res);
11724
11725
11726 if (dictinfo->dictinitoption)
11727 appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
11728
11729 appendPQExpBuffer(q, " );\n");
11730
11731
11732
11733
11734 appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s",
11735 fmtId(dictinfo->dobj.namespace->dobj.name));
11736 appendPQExpBuffer(delq, ".%s;\n",
11737 fmtId(dictinfo->dobj.name));
11738
11739 appendPQExpBuffer(labelq, "TEXT SEARCH DICTIONARY %s",
11740 fmtId(dictinfo->dobj.name));
11741
11742 if (binary_upgrade)
11743 binary_upgrade_extension_member(q, &dictinfo->dobj, labelq->data);
11744
11745 ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
11746 dictinfo->dobj.name,
11747 dictinfo->dobj.namespace->dobj.name,
11748 NULL,
11749 dictinfo->rolname,
11750 false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
11751 q->data, delq->data, NULL,
11752 NULL, 0,
11753 NULL, NULL);
11754
11755
11756 dumpComment(fout, labelq->data,
11757 NULL, dictinfo->rolname,
11758 dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
11759
11760 destroyPQExpBuffer(q);
11761 destroyPQExpBuffer(delq);
11762 destroyPQExpBuffer(labelq);
11763 destroyPQExpBuffer(query);
11764 }
11765
11766
11767
11768
11769
11770 static void
11771 dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
11772 {
11773 PQExpBuffer q;
11774 PQExpBuffer delq;
11775 PQExpBuffer labelq;
11776
11777
11778 if (!tmplinfo->dobj.dump || dataOnly)
11779 return;
11780
11781 q = createPQExpBuffer();
11782 delq = createPQExpBuffer();
11783 labelq = createPQExpBuffer();
11784
11785
11786 selectSourceSchema(fout, tmplinfo->dobj.namespace->dobj.name);
11787
11788 appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
11789 fmtId(tmplinfo->dobj.name));
11790
11791 if (tmplinfo->tmplinit != InvalidOid)
11792 appendPQExpBuffer(q, " INIT = %s,\n",
11793 convertTSFunction(fout, tmplinfo->tmplinit));
11794 appendPQExpBuffer(q, " LEXIZE = %s );\n",
11795 convertTSFunction(fout, tmplinfo->tmpllexize));
11796
11797
11798
11799
11800 appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s",
11801 fmtId(tmplinfo->dobj.namespace->dobj.name));
11802 appendPQExpBuffer(delq, ".%s;\n",
11803 fmtId(tmplinfo->dobj.name));
11804
11805 appendPQExpBuffer(labelq, "TEXT SEARCH TEMPLATE %s",
11806 fmtId(tmplinfo->dobj.name));
11807
11808 if (binary_upgrade)
11809 binary_upgrade_extension_member(q, &tmplinfo->dobj, labelq->data);
11810
11811 ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
11812 tmplinfo->dobj.name,
11813 tmplinfo->dobj.namespace->dobj.name,
11814 NULL,
11815 "",
11816 false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
11817 q->data, delq->data, NULL,
11818 NULL, 0,
11819 NULL, NULL);
11820
11821
11822 dumpComment(fout, labelq->data,
11823 NULL, "",
11824 tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
11825
11826 destroyPQExpBuffer(q);
11827 destroyPQExpBuffer(delq);
11828 destroyPQExpBuffer(labelq);
11829 }
11830
11831
11832
11833
11834
11835 static void
11836 dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
11837 {
11838 PQExpBuffer q;
11839 PQExpBuffer delq;
11840 PQExpBuffer labelq;
11841 PQExpBuffer query;
11842 PGresult *res;
11843 char *nspname;
11844 char *prsname;
11845 int ntups,
11846 i;
11847 int i_tokenname;
11848 int i_dictname;
11849
11850
11851 if (!cfginfo->dobj.dump || dataOnly)
11852 return;
11853
11854 q = createPQExpBuffer();
11855 delq = createPQExpBuffer();
11856 labelq = createPQExpBuffer();
11857 query = createPQExpBuffer();
11858
11859
11860 selectSourceSchema(fout, "pg_catalog");
11861 appendPQExpBuffer(query, "SELECT nspname, prsname "
11862 "FROM pg_ts_parser p, pg_namespace n "
11863 "WHERE p.oid = '%u' AND n.oid = prsnamespace",
11864 cfginfo->cfgparser);
11865 res = ExecuteSqlQueryForSingleRow(fout, query->data);
11866 nspname = PQgetvalue(res, 0, 0);
11867 prsname = PQgetvalue(res, 0, 1);
11868
11869
11870 selectSourceSchema(fout, cfginfo->dobj.namespace->dobj.name);
11871
11872 appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
11873 fmtId(cfginfo->dobj.name));
11874
11875 appendPQExpBuffer(q, " PARSER = ");
11876 if (strcmp(nspname, cfginfo->dobj.namespace->dobj.name) != 0)
11877 appendPQExpBuffer(q, "%s.", fmtId(nspname));
11878 appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
11879
11880 PQclear(res);
11881
11882 resetPQExpBuffer(query);
11883 appendPQExpBuffer(query,
11884 "SELECT \n"
11885 " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t \n"
11886 " WHERE t.tokid = m.maptokentype ) AS tokenname, \n"
11887 " m.mapdict::pg_catalog.regdictionary AS dictname \n"
11888 "FROM pg_catalog.pg_ts_config_map AS m \n"
11889 "WHERE m.mapcfg = '%u' \n"
11890 "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
11891 cfginfo->cfgparser, cfginfo->dobj.catId.oid);
11892
11893 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11894 ntups = PQntuples(res);
11895
11896 i_tokenname = PQfnumber(res, "tokenname");
11897 i_dictname = PQfnumber(res, "dictname");
11898
11899 for (i = 0; i < ntups; i++)
11900 {
11901 char *tokenname = PQgetvalue(res, i, i_tokenname);
11902 char *dictname = PQgetvalue(res, i, i_dictname);
11903
11904 if (i == 0 ||
11905 strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
11906 {
11907
11908 if (i > 0)
11909 appendPQExpBuffer(q, ";\n");
11910 appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
11911 fmtId(cfginfo->dobj.name));
11912
11913 appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
11914 fmtId(tokenname), dictname);
11915 }
11916 else
11917 appendPQExpBuffer(q, ", %s", dictname);
11918 }
11919
11920 if (ntups > 0)
11921 appendPQExpBuffer(q, ";\n");
11922
11923 PQclear(res);
11924
11925
11926
11927
11928 appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s",
11929 fmtId(cfginfo->dobj.namespace->dobj.name));
11930 appendPQExpBuffer(delq, ".%s;\n",
11931 fmtId(cfginfo->dobj.name));
11932
11933 appendPQExpBuffer(labelq, "TEXT SEARCH CONFIGURATION %s",
11934 fmtId(cfginfo->dobj.name));
11935
11936 if (binary_upgrade)
11937 binary_upgrade_extension_member(q, &cfginfo->dobj, labelq->data);
11938
11939 ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
11940 cfginfo->dobj.name,
11941 cfginfo->dobj.namespace->dobj.name,
11942 NULL,
11943 cfginfo->rolname,
11944 false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
11945 q->data, delq->data, NULL,
11946 NULL, 0,
11947 NULL, NULL);
11948
11949
11950 dumpComment(fout, labelq->data,
11951 NULL, cfginfo->rolname,
11952 cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
11953
11954 destroyPQExpBuffer(q);
11955 destroyPQExpBuffer(delq);
11956 destroyPQExpBuffer(labelq);
11957 destroyPQExpBuffer(query);
11958 }
11959
11960
11961
11962
11963
11964 static void
11965 dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
11966 {
11967 PQExpBuffer q;
11968 PQExpBuffer delq;
11969 PQExpBuffer labelq;
11970 char *qfdwname;
11971
11972
11973 if (!fdwinfo->dobj.dump || dataOnly)
11974 return;
11975
11976
11977
11978
11979
11980 if (!fdwinfo->dobj.ext_member)
11981 if (!include_everything)
11982 return;
11983
11984 q = createPQExpBuffer();
11985 delq = createPQExpBuffer();
11986 labelq = createPQExpBuffer();
11987
11988 qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
11989
11990 appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
11991 qfdwname);
11992
11993 if (strcmp(fdwinfo->fdwhandler, "-") != 0)
11994 appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
11995
11996 if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
11997 appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
11998
11999 if (strlen(fdwinfo->fdwoptions) > 0)
12000 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
12001
12002 appendPQExpBuffer(q, ";\n");
12003
12004 appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
12005 qfdwname);
12006
12007 appendPQExpBuffer(labelq, "FOREIGN DATA WRAPPER %s",
12008 qfdwname);
12009
12010 if (binary_upgrade)
12011 binary_upgrade_extension_member(q, &fdwinfo->dobj, labelq->data);
12012
12013 ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
12014 fdwinfo->dobj.name,
12015 NULL,
12016 NULL,
12017 fdwinfo->rolname,
12018 false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
12019 q->data, delq->data, NULL,
12020 NULL, 0,
12021 NULL, NULL);
12022
12023
12024 dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
12025 "FOREIGN DATA WRAPPER",
12026 qfdwname, NULL, fdwinfo->dobj.name,
12027 NULL, fdwinfo->rolname,
12028 fdwinfo->fdwacl);
12029
12030
12031 dumpComment(fout, labelq->data,
12032 NULL, fdwinfo->rolname,
12033 fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
12034
12035 free(qfdwname);
12036
12037 destroyPQExpBuffer(q);
12038 destroyPQExpBuffer(delq);
12039 destroyPQExpBuffer(labelq);
12040 }
12041
12042
12043
12044
12045
12046 static void
12047 dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
12048 {
12049 PQExpBuffer q;
12050 PQExpBuffer delq;
12051 PQExpBuffer labelq;
12052 PQExpBuffer query;
12053 PGresult *res;
12054 char *qsrvname;
12055 char *fdwname;
12056
12057
12058 if (!srvinfo->dobj.dump || dataOnly || !include_everything)
12059 return;
12060
12061 q = createPQExpBuffer();
12062 delq = createPQExpBuffer();
12063 labelq = createPQExpBuffer();
12064 query = createPQExpBuffer();
12065
12066 qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
12067
12068
12069 selectSourceSchema(fout, "pg_catalog");
12070 appendPQExpBuffer(query, "SELECT fdwname "
12071 "FROM pg_foreign_data_wrapper w "
12072 "WHERE w.oid = '%u'",
12073 srvinfo->srvfdw);
12074 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12075 fdwname = PQgetvalue(res, 0, 0);
12076
12077 appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
12078 if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
12079 {
12080 appendPQExpBuffer(q, " TYPE ");
12081 appendStringLiteralAH(q, srvinfo->srvtype, fout);
12082 }
12083 if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
12084 {
12085 appendPQExpBuffer(q, " VERSION ");
12086 appendStringLiteralAH(q, srvinfo->srvversion, fout);
12087 }
12088
12089 appendPQExpBuffer(q, " FOREIGN DATA WRAPPER ");
12090 appendPQExpBuffer(q, "%s", fmtId(fdwname));
12091
12092 if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
12093 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
12094
12095 appendPQExpBuffer(q, ";\n");
12096
12097 appendPQExpBuffer(delq, "DROP SERVER %s;\n",
12098 qsrvname);
12099
12100 appendPQExpBuffer(labelq, "SERVER %s", qsrvname);
12101
12102 if (binary_upgrade)
12103 binary_upgrade_extension_member(q, &srvinfo->dobj, labelq->data);
12104
12105 ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
12106 srvinfo->dobj.name,
12107 NULL,
12108 NULL,
12109 srvinfo->rolname,
12110 false, "SERVER", SECTION_PRE_DATA,
12111 q->data, delq->data, NULL,
12112 NULL, 0,
12113 NULL, NULL);
12114
12115
12116 dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
12117 "FOREIGN SERVER",
12118 qsrvname, NULL, srvinfo->dobj.name,
12119 NULL, srvinfo->rolname,
12120 srvinfo->srvacl);
12121
12122
12123 dumpUserMappings(fout,
12124 srvinfo->dobj.name, NULL,
12125 srvinfo->rolname,
12126 srvinfo->dobj.catId, srvinfo->dobj.dumpId);
12127
12128
12129 dumpComment(fout, labelq->data,
12130 NULL, srvinfo->rolname,
12131 srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
12132
12133 free(qsrvname);
12134
12135 destroyPQExpBuffer(q);
12136 destroyPQExpBuffer(delq);
12137 destroyPQExpBuffer(labelq);
12138 }
12139
12140
12141
12142
12143
12144
12145
12146
12147 static void
12148 dumpUserMappings(Archive *fout,
12149 const char *servername, const char *namespace,
12150 const char *owner,
12151 CatalogId catalogId, DumpId dumpId)
12152 {
12153 PQExpBuffer q;
12154 PQExpBuffer delq;
12155 PQExpBuffer query;
12156 PQExpBuffer tag;
12157 PGresult *res;
12158 int ntups;
12159 int i_usename;
12160 int i_umoptions;
12161 int i;
12162
12163 q = createPQExpBuffer();
12164 tag = createPQExpBuffer();
12165 delq = createPQExpBuffer();
12166 query = createPQExpBuffer();
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176 selectSourceSchema(fout, "pg_catalog");
12177
12178 appendPQExpBuffer(query,
12179 "SELECT usename, "
12180 "array_to_string(ARRAY("
12181 "SELECT quote_ident(option_name) || ' ' || "
12182 "quote_literal(option_value) "
12183 "FROM pg_options_to_table(umoptions) "
12184 "ORDER BY option_name"
12185 "), E',\n ') AS umoptions "
12186 "FROM pg_user_mappings "
12187 "WHERE srvid = '%u' "
12188 "ORDER BY usename",
12189 catalogId.oid);
12190
12191 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12192
12193 ntups = PQntuples(res);
12194 i_usename = PQfnumber(res, "usename");
12195 i_umoptions = PQfnumber(res, "umoptions");
12196
12197 for (i = 0; i < ntups; i++)
12198 {
12199 char *usename;
12200 char *umoptions;
12201
12202 usename = PQgetvalue(res, i, i_usename);
12203 umoptions = PQgetvalue(res, i, i_umoptions);
12204
12205 resetPQExpBuffer(q);
12206 appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
12207 appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
12208
12209 if (umoptions && strlen(umoptions) > 0)
12210 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions);
12211
12212 appendPQExpBuffer(q, ";\n");
12213
12214 resetPQExpBuffer(delq);
12215 appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
12216 appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
12217
12218 resetPQExpBuffer(tag);
12219 appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
12220 usename, servername);
12221
12222 ArchiveEntry(fout, nilCatalogId, createDumpId(),
12223 tag->data,
12224 namespace,
12225 NULL,
12226 owner, false,
12227 "USER MAPPING", SECTION_PRE_DATA,
12228 q->data, delq->data, NULL,
12229 &dumpId, 1,
12230 NULL, NULL);
12231 }
12232
12233 PQclear(res);
12234
12235 destroyPQExpBuffer(query);
12236 destroyPQExpBuffer(delq);
12237 destroyPQExpBuffer(q);
12238 }
12239
12240
12241
12242
12243 static void
12244 dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
12245 {
12246 PQExpBuffer q;
12247 PQExpBuffer tag;
12248 const char *type;
12249
12250
12251 if (!daclinfo->dobj.dump || dataOnly || aclsSkip)
12252 return;
12253
12254 q = createPQExpBuffer();
12255 tag = createPQExpBuffer();
12256
12257 switch (daclinfo->defaclobjtype)
12258 {
12259 case DEFACLOBJ_RELATION:
12260 type = "TABLES";
12261 break;
12262 case DEFACLOBJ_SEQUENCE:
12263 type = "SEQUENCES";
12264 break;
12265 case DEFACLOBJ_FUNCTION:
12266 type = "FUNCTIONS";
12267 break;
12268 case DEFACLOBJ_TYPE:
12269 type = "TYPES";
12270 break;
12271 default:
12272
12273 exit_horribly(NULL,
12274 "unrecognized object type in default privileges: %d\n",
12275 (int) daclinfo->defaclobjtype);
12276 type = "";
12277 }
12278
12279 appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
12280
12281
12282 if (!buildDefaultACLCommands(type,
12283 daclinfo->dobj.namespace != NULL ?
12284 daclinfo->dobj.namespace->dobj.name : NULL,
12285 daclinfo->defaclacl,
12286 daclinfo->defaclrole,
12287 fout->remoteVersion,
12288 q))
12289 exit_horribly(NULL, "could not parse default ACL list (%s)\n",
12290 daclinfo->defaclacl);
12291
12292 ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
12293 tag->data,
12294 daclinfo->dobj.namespace ? daclinfo->dobj.namespace->dobj.name : NULL,
12295 NULL,
12296 daclinfo->defaclrole,
12297 false, "DEFAULT ACL", SECTION_POST_DATA,
12298 q->data, "", NULL,
12299 NULL, 0,
12300 NULL, NULL);
12301
12302 destroyPQExpBuffer(tag);
12303 destroyPQExpBuffer(q);
12304 }
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323 static void
12324 dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
12325 const char *type, const char *name, const char *subname,
12326 const char *tag, const char *nspname, const char *owner,
12327 const char *acls)
12328 {
12329 PQExpBuffer sql;
12330
12331
12332 if (aclsSkip)
12333 return;
12334
12335
12336 if (dataOnly && strcmp(type, "LARGE OBJECT") != 0)
12337 return;
12338
12339 sql = createPQExpBuffer();
12340
12341 if (!buildACLCommands(name, subname, type, acls, owner,
12342 "", fout->remoteVersion, sql))
12343 exit_horribly(NULL,
12344 "could not parse ACL list (%s) for object \"%s\" (%s)\n",
12345 acls, name, type);
12346
12347 if (sql->len > 0)
12348 ArchiveEntry(fout, nilCatalogId, createDumpId(),
12349 tag, nspname,
12350 NULL,
12351 owner ? owner : "",
12352 false, "ACL", SECTION_NONE,
12353 sql->data, "", NULL,
12354 &(objDumpId), 1,
12355 NULL, NULL);
12356
12357 destroyPQExpBuffer(sql);
12358 }
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378 static void
12379 dumpSecLabel(Archive *fout, const char *target,
12380 const char *namespace, const char *owner,
12381 CatalogId catalogId, int subid, DumpId dumpId)
12382 {
12383 SecLabelItem *labels;
12384 int nlabels;
12385 int i;
12386 PQExpBuffer query;
12387
12388
12389 if (no_security_labels)
12390 return;
12391
12392
12393 if (strncmp(target, "LARGE OBJECT ", 13) != 0)
12394 {
12395 if (dataOnly)
12396 return;
12397 }
12398 else
12399 {
12400 if (schemaOnly)
12401 return;
12402 }
12403
12404
12405 nlabels = findSecLabels(fout, catalogId.tableoid, catalogId.oid, &labels);
12406
12407 query = createPQExpBuffer();
12408
12409 for (i = 0; i < nlabels; i++)
12410 {
12411
12412
12413
12414 if (labels[i].objsubid != subid)
12415 continue;
12416
12417 appendPQExpBuffer(query,
12418 "SECURITY LABEL FOR %s ON %s IS ",
12419 fmtId(labels[i].provider), target);
12420 appendStringLiteralAH(query, labels[i].label, fout);
12421 appendPQExpBuffer(query, ";\n");
12422 }
12423
12424 if (query->len > 0)
12425 {
12426 ArchiveEntry(fout, nilCatalogId, createDumpId(),
12427 target, namespace, NULL, owner,
12428 false, "SECURITY LABEL", SECTION_NONE,
12429 query->data, "", NULL,
12430 &(dumpId), 1,
12431 NULL, NULL);
12432 }
12433 destroyPQExpBuffer(query);
12434 }
12435
12436
12437
12438
12439
12440
12441
12442 static void
12443 dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename)
12444 {
12445 SecLabelItem *labels;
12446 int nlabels;
12447 int i;
12448 PQExpBuffer query;
12449 PQExpBuffer target;
12450
12451
12452 if (no_security_labels)
12453 return;
12454
12455
12456 if (dataOnly)
12457 return;
12458
12459
12460 nlabels = findSecLabels(fout,
12461 tbinfo->dobj.catId.tableoid,
12462 tbinfo->dobj.catId.oid,
12463 &labels);
12464
12465
12466 if (nlabels <= 0)
12467 return;
12468
12469 query = createPQExpBuffer();
12470 target = createPQExpBuffer();
12471
12472 for (i = 0; i < nlabels; i++)
12473 {
12474 const char *colname;
12475 const char *provider = labels[i].provider;
12476 const char *label = labels[i].label;
12477 int objsubid = labels[i].objsubid;
12478
12479 resetPQExpBuffer(target);
12480 if (objsubid == 0)
12481 {
12482 appendPQExpBuffer(target, "%s %s", reltypename,
12483 fmtId(tbinfo->dobj.name));
12484 }
12485 else
12486 {
12487 colname = getAttrName(objsubid, tbinfo);
12488
12489 appendPQExpBuffer(target, "COLUMN %s", fmtId(tbinfo->dobj.name));
12490 appendPQExpBuffer(target, ".%s", fmtId(colname));
12491 }
12492 appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
12493 fmtId(provider), target->data);
12494 appendStringLiteralAH(query, label, fout);
12495 appendPQExpBuffer(query, ";\n");
12496 }
12497 if (query->len > 0)
12498 {
12499 resetPQExpBuffer(target);
12500 appendPQExpBuffer(target, "%s %s", reltypename,
12501 fmtId(tbinfo->dobj.name));
12502 ArchiveEntry(fout, nilCatalogId, createDumpId(),
12503 target->data,
12504 tbinfo->dobj.namespace->dobj.name,
12505 NULL, tbinfo->rolname,
12506 false, "SECURITY LABEL", SECTION_NONE,
12507 query->data, "", NULL,
12508 &(tbinfo->dobj.dumpId), 1,
12509 NULL, NULL);
12510 }
12511 destroyPQExpBuffer(query);
12512 destroyPQExpBuffer(target);
12513 }
12514
12515
12516
12517
12518
12519
12520
12521
12522 static int
12523 findSecLabels(Archive *fout, Oid classoid, Oid objoid, SecLabelItem **items)
12524 {
12525
12526 static SecLabelItem *labels = NULL;
12527 static int nlabels = -1;
12528
12529 SecLabelItem *middle = NULL;
12530 SecLabelItem *low;
12531 SecLabelItem *high;
12532 int nmatch;
12533
12534
12535 if (nlabels < 0)
12536 nlabels = collectSecLabels(fout, &labels);
12537
12538 if (nlabels <= 0)
12539 {
12540 *items = NULL;
12541 return 0;
12542 }
12543
12544
12545
12546
12547 low = &labels[0];
12548 high = &labels[nlabels - 1];
12549 while (low <= high)
12550 {
12551 middle = low + (high - low) / 2;
12552
12553 if (classoid < middle->classoid)
12554 high = middle - 1;
12555 else if (classoid > middle->classoid)
12556 low = middle + 1;
12557 else if (objoid < middle->objoid)
12558 high = middle - 1;
12559 else if (objoid > middle->objoid)
12560 low = middle + 1;
12561 else
12562 break;
12563 }
12564
12565 if (low > high)
12566 {
12567 *items = NULL;
12568 return 0;
12569 }
12570
12571
12572
12573
12574
12575
12576 nmatch = 1;
12577 while (middle > low)
12578 {
12579 if (classoid != middle[-1].classoid ||
12580 objoid != middle[-1].objoid)
12581 break;
12582 middle--;
12583 nmatch++;
12584 }
12585
12586 *items = middle;
12587
12588 middle += nmatch;
12589 while (middle <= high)
12590 {
12591 if (classoid != middle->classoid ||
12592 objoid != middle->objoid)
12593 break;
12594 middle++;
12595 nmatch++;
12596 }
12597
12598 return nmatch;
12599 }
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609 static int
12610 collectSecLabels(Archive *fout, SecLabelItem **items)
12611 {
12612 PGresult *res;
12613 PQExpBuffer query;
12614 int i_label;
12615 int i_provider;
12616 int i_classoid;
12617 int i_objoid;
12618 int i_objsubid;
12619 int ntups;
12620 int i;
12621 SecLabelItem *labels;
12622
12623 query = createPQExpBuffer();
12624
12625 appendPQExpBuffer(query,
12626 "SELECT label, provider, classoid, objoid, objsubid "
12627 "FROM pg_catalog.pg_seclabel "
12628 "ORDER BY classoid, objoid, objsubid");
12629
12630 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12631
12632
12633 i_label = PQfnumber(res, "label");
12634 i_provider = PQfnumber(res, "provider");
12635 i_classoid = PQfnumber(res, "classoid");
12636 i_objoid = PQfnumber(res, "objoid");
12637 i_objsubid = PQfnumber(res, "objsubid");
12638
12639 ntups = PQntuples(res);
12640
12641 labels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
12642
12643 for (i = 0; i < ntups; i++)
12644 {
12645 labels[i].label = PQgetvalue(res, i, i_label);
12646 labels[i].provider = PQgetvalue(res, i, i_provider);
12647 labels[i].classoid = atooid(PQgetvalue(res, i, i_classoid));
12648 labels[i].objoid = atooid(PQgetvalue(res, i, i_objoid));
12649 labels[i].objsubid = atoi(PQgetvalue(res, i, i_objsubid));
12650 }
12651
12652
12653 destroyPQExpBuffer(query);
12654
12655 *items = labels;
12656 return ntups;
12657 }
12658
12659
12660
12661
12662
12663 static void
12664 dumpTable(Archive *fout, TableInfo *tbinfo)
12665 {
12666 if (tbinfo->dobj.dump && !dataOnly)
12667 {
12668 char *namecopy;
12669
12670 if (tbinfo->relkind == RELKIND_SEQUENCE)
12671 dumpSequence(fout, tbinfo);
12672 else
12673 dumpTableSchema(fout, tbinfo);
12674
12675
12676 namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
12677 dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
12678 (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" :
12679 "TABLE",
12680 namecopy, NULL, tbinfo->dobj.name,
12681 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
12682 tbinfo->relacl);
12683
12684
12685
12686
12687
12688
12689 if (fout->remoteVersion >= 80400)
12690 {
12691 PQExpBuffer query = createPQExpBuffer();
12692 PGresult *res;
12693 int i;
12694
12695 appendPQExpBuffer(query,
12696 "SELECT attname, attacl FROM pg_catalog.pg_attribute "
12697 "WHERE attrelid = '%u' AND NOT attisdropped AND attacl IS NOT NULL "
12698 "ORDER BY attnum",
12699 tbinfo->dobj.catId.oid);
12700 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12701
12702 for (i = 0; i < PQntuples(res); i++)
12703 {
12704 char *attname = PQgetvalue(res, i, 0);
12705 char *attacl = PQgetvalue(res, i, 1);
12706 char *attnamecopy;
12707 char *acltag;
12708
12709 attnamecopy = pg_strdup(fmtId(attname));
12710 acltag = pg_malloc(strlen(tbinfo->dobj.name) + strlen(attname) + 2);
12711 sprintf(acltag, "%s.%s", tbinfo->dobj.name, attname);
12712
12713 dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
12714 namecopy, attnamecopy, acltag,
12715 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
12716 attacl);
12717 free(attnamecopy);
12718 free(acltag);
12719 }
12720 PQclear(res);
12721 destroyPQExpBuffer(query);
12722 }
12723
12724 free(namecopy);
12725 }
12726 }
12727
12728
12729
12730
12731
12732
12733
12734 static PQExpBuffer
12735 createViewAsClause(Archive *fout, TableInfo *tbinfo)
12736 {
12737 PQExpBuffer query = createPQExpBuffer();
12738 PQExpBuffer result = createPQExpBuffer();
12739 PGresult *res;
12740 int len;
12741
12742
12743 if (fout->remoteVersion >= 70300)
12744 {
12745
12746 appendPQExpBuffer(query,
12747 "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
12748 tbinfo->dobj.catId.oid);
12749 }
12750 else
12751 {
12752 appendPQExpBuffer(query, "SELECT definition AS viewdef "
12753 "FROM pg_views WHERE viewname = ");
12754 appendStringLiteralAH(query, tbinfo->dobj.name, fout);
12755 appendPQExpBuffer(query, ";");
12756 }
12757
12758 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12759
12760 if (PQntuples(res) != 1)
12761 {
12762 if (PQntuples(res) < 1)
12763 exit_horribly(NULL, "query to obtain definition of view \"%s\" returned no data\n",
12764 tbinfo->dobj.name);
12765 else
12766 exit_horribly(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n",
12767 tbinfo->dobj.name);
12768 }
12769
12770 len = PQgetlength(res, 0, 0);
12771
12772 if (len == 0)
12773 exit_horribly(NULL, "definition of view \"%s\" appears to be empty (length zero)\n",
12774 tbinfo->dobj.name);
12775
12776
12777 Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
12778 appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
12779
12780 PQclear(res);
12781 destroyPQExpBuffer(query);
12782
12783 return result;
12784 }
12785
12786
12787
12788
12789
12790 static void
12791 dumpTableSchema(Archive *fout, TableInfo *tbinfo)
12792 {
12793 PQExpBuffer q = createPQExpBuffer();
12794 PQExpBuffer delq = createPQExpBuffer();
12795 PQExpBuffer labelq = createPQExpBuffer();
12796 int numParents;
12797 TableInfo **parents;
12798 int actual_atts;
12799 const char *reltypename;
12800 char *storage;
12801 char *srvname;
12802 char *ftoptions;
12803 int j,
12804 k;
12805
12806
12807 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
12808
12809 if (binary_upgrade)
12810 binary_upgrade_set_type_oids_by_rel_oid(fout, q,
12811 tbinfo->dobj.catId.oid);
12812
12813
12814 if (tbinfo->relkind == RELKIND_VIEW)
12815 {
12816 PQExpBuffer result;
12817
12818 reltypename = "VIEW";
12819
12820
12821
12822
12823
12824 appendPQExpBuffer(delq, "DROP VIEW %s.",
12825 fmtId(tbinfo->dobj.namespace->dobj.name));
12826 appendPQExpBuffer(delq, "%s;\n",
12827 fmtId(tbinfo->dobj.name));
12828
12829 if (binary_upgrade)
12830 binary_upgrade_set_pg_class_oids(fout, q,
12831 tbinfo->dobj.catId.oid, false);
12832
12833 appendPQExpBuffer(q, "CREATE VIEW %s", fmtId(tbinfo->dobj.name));
12834 if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
12835 appendPQExpBuffer(q, " WITH (%s)", tbinfo->reloptions);
12836 result = createViewAsClause(fout, tbinfo);
12837 appendPQExpBuffer(q, " AS\n%s;\n", result->data);
12838 destroyPQExpBuffer(result);
12839
12840 appendPQExpBuffer(labelq, "VIEW %s",
12841 fmtId(tbinfo->dobj.name));
12842 }
12843 else
12844 {
12845 switch (tbinfo->relkind)
12846 {
12847 case (RELKIND_FOREIGN_TABLE):
12848 {
12849 PQExpBuffer query = createPQExpBuffer();
12850 PGresult *res;
12851 int i_srvname;
12852 int i_ftoptions;
12853
12854 reltypename = "FOREIGN TABLE";
12855
12856
12857 appendPQExpBuffer(query,
12858 "SELECT fs.srvname, "
12859 "pg_catalog.array_to_string(ARRAY("
12860 "SELECT pg_catalog.quote_ident(option_name) || "
12861 "' ' || pg_catalog.quote_literal(option_value) "
12862 "FROM pg_catalog.pg_options_to_table(ftoptions) "
12863 "ORDER BY option_name"
12864 "), E',\n ') AS ftoptions "
12865 "FROM pg_catalog.pg_foreign_table ft "
12866 "JOIN pg_catalog.pg_foreign_server fs "
12867 "ON (fs.oid = ft.ftserver) "
12868 "WHERE ft.ftrelid = '%u'",
12869 tbinfo->dobj.catId.oid);
12870 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12871 i_srvname = PQfnumber(res, "srvname");
12872 i_ftoptions = PQfnumber(res, "ftoptions");
12873 srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
12874 ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
12875 PQclear(res);
12876 destroyPQExpBuffer(query);
12877 break;
12878 }
12879 case (RELKIND_MATVIEW):
12880 reltypename = "MATERIALIZED VIEW";
12881 srvname = NULL;
12882 ftoptions = NULL;
12883 break;
12884 default:
12885 reltypename = "TABLE";
12886 srvname = NULL;
12887 ftoptions = NULL;
12888 }
12889
12890 numParents = tbinfo->numParents;
12891 parents = tbinfo->parents;
12892
12893
12894
12895
12896
12897 appendPQExpBuffer(delq, "DROP %s %s.", reltypename,
12898 fmtId(tbinfo->dobj.namespace->dobj.name));
12899 appendPQExpBuffer(delq, "%s;\n",
12900 fmtId(tbinfo->dobj.name));
12901
12902 appendPQExpBuffer(labelq, "%s %s", reltypename,
12903 fmtId(tbinfo->dobj.name));
12904
12905 if (binary_upgrade)
12906 binary_upgrade_set_pg_class_oids(fout, q,
12907 tbinfo->dobj.catId.oid, false);
12908
12909 appendPQExpBuffer(q, "CREATE %s%s %s",
12910 tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
12911 "UNLOGGED " : "",
12912 reltypename,
12913 fmtId(tbinfo->dobj.name));
12914
12915
12916
12917
12918
12919 if (tbinfo->reloftype && !binary_upgrade)
12920 appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
12921
12922 if (tbinfo->relkind != RELKIND_MATVIEW)
12923 {
12924
12925 actual_atts = 0;
12926 for (j = 0; j < tbinfo->numatts; j++)
12927 {
12928
12929
12930
12931
12932
12933
12934 if (shouldPrintColumn(tbinfo, j))
12935 {
12936
12937
12938
12939 bool has_default = (tbinfo->attrdefs[j] != NULL &&
12940 !tbinfo->attrdefs[j]->separate);
12941
12942
12943
12944
12945
12946 bool has_notnull = (tbinfo->notnull[j] &&
12947 (!tbinfo->inhNotNull[j] ||
12948 binary_upgrade));
12949
12950
12951 if (tbinfo->reloftype &&
12952 !has_default && !has_notnull && !binary_upgrade)
12953 continue;
12954
12955
12956 if (actual_atts == 0)
12957 appendPQExpBuffer(q, " (");
12958 else
12959 appendPQExpBuffer(q, ",");
12960 appendPQExpBuffer(q, "\n ");
12961 actual_atts++;
12962
12963
12964 appendPQExpBuffer(q, "%s",
12965 fmtId(tbinfo->attnames[j]));
12966
12967 if (tbinfo->attisdropped[j])
12968 {
12969
12970
12971
12972
12973
12974
12975 appendPQExpBuffer(q, " INTEGER /* dummy */");
12976
12977 continue;
12978 }
12979
12980
12981 if (tbinfo->reloftype && !binary_upgrade)
12982 {
12983 appendPQExpBuffer(q, " WITH OPTIONS");
12984 }
12985 else if (fout->remoteVersion >= 70100)
12986 {
12987 appendPQExpBuffer(q, " %s",
12988 tbinfo->atttypnames[j]);
12989 }
12990 else
12991 {
12992
12993 appendPQExpBuffer(q, " %s",
12994 myFormatType(tbinfo->atttypnames[j],
12995 tbinfo->atttypmod[j]));
12996 }
12997
12998
12999 if (OidIsValid(tbinfo->attcollation[j]))
13000 {
13001 CollInfo *coll;
13002
13003 coll = findCollationByOid(tbinfo->attcollation[j]);
13004 if (coll)
13005 {
13006
13007 appendPQExpBuffer(q, " COLLATE %s.",
13008 fmtId(coll->dobj.namespace->dobj.name));
13009 appendPQExpBuffer(q, "%s",
13010 fmtId(coll->dobj.name));
13011 }
13012 }
13013
13014 if (has_default)
13015 appendPQExpBuffer(q, " DEFAULT %s",
13016 tbinfo->attrdefs[j]->adef_expr);
13017
13018 if (has_notnull)
13019 appendPQExpBuffer(q, " NOT NULL");
13020 }
13021 }
13022
13023
13024
13025
13026 for (j = 0; j < tbinfo->ncheck; j++)
13027 {
13028 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
13029
13030 if (constr->separate || !constr->conislocal)
13031 continue;
13032
13033 if (actual_atts == 0)
13034 appendPQExpBuffer(q, " (\n ");
13035 else
13036 appendPQExpBuffer(q, ",\n ");
13037
13038 appendPQExpBuffer(q, "CONSTRAINT %s ",
13039 fmtId(constr->dobj.name));
13040 appendPQExpBuffer(q, "%s", constr->condef);
13041
13042 actual_atts++;
13043 }
13044
13045 if (actual_atts)
13046 appendPQExpBuffer(q, "\n)");
13047 else if (!(tbinfo->reloftype && !binary_upgrade))
13048 {
13049
13050
13051
13052
13053 appendPQExpBuffer(q, " (\n)");
13054 }
13055
13056 if (numParents > 0 && !binary_upgrade)
13057 {
13058 appendPQExpBuffer(q, "\nINHERITS (");
13059 for (k = 0; k < numParents; k++)
13060 {
13061 TableInfo *parentRel = parents[k];
13062
13063 if (k > 0)
13064 appendPQExpBuffer(q, ", ");
13065 if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
13066 appendPQExpBuffer(q, "%s.",
13067 fmtId(parentRel->dobj.namespace->dobj.name));
13068 appendPQExpBuffer(q, "%s",
13069 fmtId(parentRel->dobj.name));
13070 }
13071 appendPQExpBuffer(q, ")");
13072 }
13073
13074 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
13075 appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
13076 }
13077
13078 if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) ||
13079 (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0))
13080 {
13081 bool addcomma = false;
13082
13083 appendPQExpBuffer(q, "\nWITH (");
13084 if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
13085 {
13086 addcomma = true;
13087 appendPQExpBuffer(q, "%s", tbinfo->reloptions);
13088 }
13089 if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)
13090 {
13091 appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "",
13092 tbinfo->toast_reloptions);
13093 }
13094 appendPQExpBuffer(q, ")");
13095 }
13096
13097
13098 if (ftoptions && ftoptions[0])
13099 appendPQExpBuffer(q, "\nOPTIONS (\n %s\n)", ftoptions);
13100
13101
13102
13103
13104 if (tbinfo->relkind == RELKIND_MATVIEW)
13105 {
13106 PQExpBuffer result;
13107
13108 result = createViewAsClause(fout, tbinfo);
13109 appendPQExpBuffer(q, " AS\n%s\n WITH NO DATA;\n",
13110 result->data);
13111 destroyPQExpBuffer(result);
13112 }
13113 else
13114 appendPQExpBuffer(q, ";\n");
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129 if (binary_upgrade && tbinfo->relkind == RELKIND_RELATION)
13130 {
13131 for (j = 0; j < tbinfo->numatts; j++)
13132 {
13133 if (tbinfo->attisdropped[j])
13134 {
13135 appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column.\n");
13136 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
13137 "SET attlen = %d, "
13138 "attalign = '%c', attbyval = false\n"
13139 "WHERE attname = ",
13140 tbinfo->attlen[j],
13141 tbinfo->attalign[j]);
13142 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
13143 appendPQExpBuffer(q, "\n AND attrelid = ");
13144 appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
13145 appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
13146
13147 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13148 fmtId(tbinfo->dobj.name));
13149 appendPQExpBuffer(q, "DROP COLUMN %s;\n",
13150 fmtId(tbinfo->attnames[j]));
13151 }
13152 else if (!tbinfo->attislocal[j])
13153 {
13154 appendPQExpBuffer(q, "\n-- For binary upgrade, recreate inherited column.\n");
13155 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
13156 "SET attislocal = false\n"
13157 "WHERE attname = ");
13158 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
13159 appendPQExpBuffer(q, "\n AND attrelid = ");
13160 appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
13161 appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
13162 }
13163 }
13164
13165 for (k = 0; k < tbinfo->ncheck; k++)
13166 {
13167 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
13168
13169 if (constr->separate || constr->conislocal)
13170 continue;
13171
13172 appendPQExpBuffer(q, "\n-- For binary upgrade, set up inherited constraint.\n");
13173 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13174 fmtId(tbinfo->dobj.name));
13175 appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
13176 fmtId(constr->dobj.name));
13177 appendPQExpBuffer(q, "%s;\n", constr->condef);
13178 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_constraint\n"
13179 "SET conislocal = false\n"
13180 "WHERE contype = 'c' AND conname = ");
13181 appendStringLiteralAH(q, constr->dobj.name, fout);
13182 appendPQExpBuffer(q, "\n AND conrelid = ");
13183 appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
13184 appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
13185 }
13186
13187 if (numParents > 0)
13188 {
13189 appendPQExpBuffer(q, "\n-- For binary upgrade, set up inheritance this way.\n");
13190 for (k = 0; k < numParents; k++)
13191 {
13192 TableInfo *parentRel = parents[k];
13193
13194 appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
13195 fmtId(tbinfo->dobj.name));
13196 if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
13197 appendPQExpBuffer(q, "%s.",
13198 fmtId(parentRel->dobj.namespace->dobj.name));
13199 appendPQExpBuffer(q, "%s;\n",
13200 fmtId(parentRel->dobj.name));
13201 }
13202 }
13203
13204 if (tbinfo->reloftype)
13205 {
13206 appendPQExpBuffer(q, "\n-- For binary upgrade, set up typed tables this way.\n");
13207 appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
13208 fmtId(tbinfo->dobj.name),
13209 tbinfo->reloftype);
13210 }
13211
13212 appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
13213 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
13214 "SET relfrozenxid = '%u'\n"
13215 "WHERE oid = ",
13216 tbinfo->frozenxid);
13217 appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
13218 appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
13219
13220 if (tbinfo->toast_oid)
13221 {
13222
13223 appendPQExpBuffer(q, "\n-- For binary upgrade, set toast's relfrozenxid\n");
13224 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
13225 "SET relfrozenxid = '%u'\n"
13226 "WHERE oid = '%u';\n",
13227 tbinfo->toast_frozenxid, tbinfo->toast_oid);
13228 }
13229 }
13230
13231
13232
13233
13234
13235 for (j = 0; j < tbinfo->numatts; j++)
13236 {
13237
13238 if (tbinfo->attisdropped[j])
13239 continue;
13240
13241
13242
13243
13244
13245
13246 if (!shouldPrintColumn(tbinfo, j) &&
13247 tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
13248 {
13249 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13250 fmtId(tbinfo->dobj.name));
13251 appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
13252 fmtId(tbinfo->attnames[j]));
13253 }
13254
13255
13256
13257
13258
13259
13260 if (tbinfo->attstattarget[j] >= 0)
13261 {
13262 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13263 fmtId(tbinfo->dobj.name));
13264 appendPQExpBuffer(q, "ALTER COLUMN %s ",
13265 fmtId(tbinfo->attnames[j]));
13266 appendPQExpBuffer(q, "SET STATISTICS %d;\n",
13267 tbinfo->attstattarget[j]);
13268 }
13269
13270
13271
13272
13273
13274 if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
13275 {
13276 switch (tbinfo->attstorage[j])
13277 {
13278 case 'p':
13279 storage = "PLAIN";
13280 break;
13281 case 'e':
13282 storage = "EXTERNAL";
13283 break;
13284 case 'm':
13285 storage = "MAIN";
13286 break;
13287 case 'x':
13288 storage = "EXTENDED";
13289 break;
13290 default:
13291 storage = NULL;
13292 }
13293
13294
13295
13296
13297 if (storage != NULL)
13298 {
13299 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13300 fmtId(tbinfo->dobj.name));
13301 appendPQExpBuffer(q, "ALTER COLUMN %s ",
13302 fmtId(tbinfo->attnames[j]));
13303 appendPQExpBuffer(q, "SET STORAGE %s;\n",
13304 storage);
13305 }
13306 }
13307
13308
13309
13310
13311 if (tbinfo->attoptions[j] && tbinfo->attoptions[j][0] != '\0')
13312 {
13313 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13314 fmtId(tbinfo->dobj.name));
13315 appendPQExpBuffer(q, "ALTER COLUMN %s ",
13316 fmtId(tbinfo->attnames[j]));
13317 appendPQExpBuffer(q, "SET (%s);\n",
13318 tbinfo->attoptions[j]);
13319 }
13320
13321
13322
13323
13324 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
13325 tbinfo->attfdwoptions[j] &&
13326 tbinfo->attfdwoptions[j][0] != '\0')
13327 {
13328 appendPQExpBuffer(q, "ALTER FOREIGN TABLE %s ",
13329 fmtId(tbinfo->dobj.name));
13330 appendPQExpBuffer(q, "ALTER COLUMN %s ",
13331 fmtId(tbinfo->attnames[j]));
13332 appendPQExpBuffer(q, "OPTIONS (\n %s\n);\n",
13333 tbinfo->attfdwoptions[j]);
13334 }
13335 }
13336 }
13337
13338 if (binary_upgrade)
13339 binary_upgrade_extension_member(q, &tbinfo->dobj, labelq->data);
13340
13341 ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
13342 tbinfo->dobj.name,
13343 tbinfo->dobj.namespace->dobj.name,
13344 (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
13345 tbinfo->rolname,
13346 (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
13347 reltypename, SECTION_PRE_DATA,
13348 q->data, delq->data, NULL,
13349 NULL, 0,
13350 NULL, NULL);
13351
13352
13353
13354 dumpTableComment(fout, tbinfo, reltypename);
13355
13356
13357 dumpTableSecLabel(fout, tbinfo, reltypename);
13358
13359
13360 for (j = 0; j < tbinfo->ncheck; j++)
13361 {
13362 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
13363
13364 if (constr->separate || !constr->conislocal)
13365 continue;
13366
13367 dumpTableConstraintComment(fout, constr);
13368 }
13369
13370 destroyPQExpBuffer(q);
13371 destroyPQExpBuffer(delq);
13372 destroyPQExpBuffer(labelq);
13373 }
13374
13375
13376
13377
13378 static void
13379 dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
13380 {
13381 TableInfo *tbinfo = adinfo->adtable;
13382 int adnum = adinfo->adnum;
13383 PQExpBuffer q;
13384 PQExpBuffer delq;
13385
13386
13387 if (!tbinfo->dobj.dump || dataOnly)
13388 return;
13389
13390
13391 if (!adinfo->separate)
13392 return;
13393
13394 q = createPQExpBuffer();
13395 delq = createPQExpBuffer();
13396
13397 appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
13398 fmtId(tbinfo->dobj.name));
13399 appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
13400 fmtId(tbinfo->attnames[adnum - 1]),
13401 adinfo->adef_expr);
13402
13403
13404
13405
13406 appendPQExpBuffer(delq, "ALTER TABLE %s.",
13407 fmtId(tbinfo->dobj.namespace->dobj.name));
13408 appendPQExpBuffer(delq, "%s ",
13409 fmtId(tbinfo->dobj.name));
13410 appendPQExpBuffer(delq, "ALTER COLUMN %s DROP DEFAULT;\n",
13411 fmtId(tbinfo->attnames[adnum - 1]));
13412
13413 ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
13414 tbinfo->attnames[adnum - 1],
13415 tbinfo->dobj.namespace->dobj.name,
13416 NULL,
13417 tbinfo->rolname,
13418 false, "DEFAULT", SECTION_PRE_DATA,
13419 q->data, delq->data, NULL,
13420 NULL, 0,
13421 NULL, NULL);
13422
13423 destroyPQExpBuffer(q);
13424 destroyPQExpBuffer(delq);
13425 }
13426
13427
13428
13429
13430
13431
13432
13433
13434 static const char *
13435 getAttrName(int attrnum, TableInfo *tblInfo)
13436 {
13437 if (attrnum > 0 && attrnum <= tblInfo->numatts)
13438 return tblInfo->attnames[attrnum - 1];
13439 switch (attrnum)
13440 {
13441 case SelfItemPointerAttributeNumber:
13442 return "ctid";
13443 case ObjectIdAttributeNumber:
13444 return "oid";
13445 case MinTransactionIdAttributeNumber:
13446 return "xmin";
13447 case MinCommandIdAttributeNumber:
13448 return "cmin";
13449 case MaxTransactionIdAttributeNumber:
13450 return "xmax";
13451 case MaxCommandIdAttributeNumber:
13452 return "cmax";
13453 case TableOidAttributeNumber:
13454 return "tableoid";
13455 }
13456 exit_horribly(NULL, "invalid column number %d for table \"%s\"\n",
13457 attrnum, tblInfo->dobj.name);
13458 return NULL;
13459 }
13460
13461
13462
13463
13464
13465 static void
13466 dumpIndex(Archive *fout, IndxInfo *indxinfo)
13467 {
13468 TableInfo *tbinfo = indxinfo->indextable;
13469 PQExpBuffer q;
13470 PQExpBuffer delq;
13471 PQExpBuffer labelq;
13472
13473 if (dataOnly)
13474 return;
13475
13476 q = createPQExpBuffer();
13477 delq = createPQExpBuffer();
13478 labelq = createPQExpBuffer();
13479
13480 appendPQExpBuffer(labelq, "INDEX %s",
13481 fmtId(indxinfo->dobj.name));
13482
13483
13484
13485
13486
13487
13488 if (indxinfo->indexconstraint == 0)
13489 {
13490 if (binary_upgrade)
13491 binary_upgrade_set_pg_class_oids(fout, q,
13492 indxinfo->dobj.catId.oid, true);
13493
13494
13495 appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
13496
13497
13498 if (indxinfo->indisclustered)
13499 {
13500 appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
13501 fmtId(tbinfo->dobj.name));
13502 appendPQExpBuffer(q, " ON %s;\n",
13503 fmtId(indxinfo->dobj.name));
13504 }
13505
13506
13507
13508
13509
13510 appendPQExpBuffer(delq, "DROP INDEX %s.",
13511 fmtId(tbinfo->dobj.namespace->dobj.name));
13512 appendPQExpBuffer(delq, "%s;\n",
13513 fmtId(indxinfo->dobj.name));
13514
13515 ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
13516 indxinfo->dobj.name,
13517 tbinfo->dobj.namespace->dobj.name,
13518 indxinfo->tablespace,
13519 tbinfo->rolname, false,
13520 "INDEX", SECTION_POST_DATA,
13521 q->data, delq->data, NULL,
13522 NULL, 0,
13523 NULL, NULL);
13524 }
13525
13526
13527 dumpComment(fout, labelq->data,
13528 tbinfo->dobj.namespace->dobj.name,
13529 tbinfo->rolname,
13530 indxinfo->dobj.catId, 0, indxinfo->dobj.dumpId);
13531
13532 destroyPQExpBuffer(q);
13533 destroyPQExpBuffer(delq);
13534 destroyPQExpBuffer(labelq);
13535 }
13536
13537
13538
13539
13540
13541 static void
13542 dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
13543 {
13544 TableInfo *tbinfo = coninfo->contable;
13545 PQExpBuffer q;
13546 PQExpBuffer delq;
13547
13548
13549 if (!coninfo->dobj.dump || dataOnly)
13550 return;
13551
13552 q = createPQExpBuffer();
13553 delq = createPQExpBuffer();
13554
13555 if (coninfo->contype == 'p' ||
13556 coninfo->contype == 'u' ||
13557 coninfo->contype == 'x')
13558 {
13559
13560 IndxInfo *indxinfo;
13561 int k;
13562
13563 indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
13564
13565 if (indxinfo == NULL)
13566 exit_horribly(NULL, "missing index for constraint \"%s\"\n",
13567 coninfo->dobj.name);
13568
13569 if (binary_upgrade)
13570 binary_upgrade_set_pg_class_oids(fout, q,
13571 indxinfo->dobj.catId.oid, true);
13572
13573 appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
13574 fmtId(tbinfo->dobj.name));
13575 appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
13576 fmtId(coninfo->dobj.name));
13577
13578 if (coninfo->condef)
13579 {
13580
13581 appendPQExpBuffer(q, "%s;\n", coninfo->condef);
13582 }
13583 else
13584 {
13585 appendPQExpBuffer(q, "%s (",
13586 coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
13587 for (k = 0; k < indxinfo->indnkeys; k++)
13588 {
13589 int indkey = (int) indxinfo->indkeys[k];
13590 const char *attname;
13591
13592 if (indkey == InvalidAttrNumber)
13593 break;
13594 attname = getAttrName(indkey, tbinfo);
13595
13596 appendPQExpBuffer(q, "%s%s",
13597 (k == 0) ? "" : ", ",
13598 fmtId(attname));
13599 }
13600
13601 appendPQExpBuffer(q, ")");
13602
13603 if (indxinfo->options && strlen(indxinfo->options) > 0)
13604 appendPQExpBuffer(q, " WITH (%s)", indxinfo->options);
13605
13606 if (coninfo->condeferrable)
13607 {
13608 appendPQExpBuffer(q, " DEFERRABLE");
13609 if (coninfo->condeferred)
13610 appendPQExpBuffer(q, " INITIALLY DEFERRED");
13611 }
13612
13613 appendPQExpBuffer(q, ";\n");
13614 }
13615
13616
13617 if (indxinfo->indisclustered)
13618 {
13619 appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
13620 fmtId(tbinfo->dobj.name));
13621 appendPQExpBuffer(q, " ON %s;\n",
13622 fmtId(indxinfo->dobj.name));
13623 }
13624
13625
13626
13627
13628
13629 appendPQExpBuffer(delq, "ALTER TABLE ONLY %s.",
13630 fmtId(tbinfo->dobj.namespace->dobj.name));
13631 appendPQExpBuffer(delq, "%s ",
13632 fmtId(tbinfo->dobj.name));
13633 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
13634 fmtId(coninfo->dobj.name));
13635
13636 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
13637 coninfo->dobj.name,
13638 tbinfo->dobj.namespace->dobj.name,
13639 indxinfo->tablespace,
13640 tbinfo->rolname, false,
13641 "CONSTRAINT", SECTION_POST_DATA,
13642 q->data, delq->data, NULL,
13643 NULL, 0,
13644 NULL, NULL);
13645 }
13646 else if (coninfo->contype == 'f')
13647 {
13648
13649
13650
13651
13652 appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
13653 fmtId(tbinfo->dobj.name));
13654 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
13655 fmtId(coninfo->dobj.name),
13656 coninfo->condef);
13657
13658
13659
13660
13661
13662 appendPQExpBuffer(delq, "ALTER TABLE ONLY %s.",
13663 fmtId(tbinfo->dobj.namespace->dobj.name));
13664 appendPQExpBuffer(delq, "%s ",
13665 fmtId(tbinfo->dobj.name));
13666 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
13667 fmtId(coninfo->dobj.name));
13668
13669 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
13670 coninfo->dobj.name,
13671 tbinfo->dobj.namespace->dobj.name,
13672 NULL,
13673 tbinfo->rolname, false,
13674 "FK CONSTRAINT", SECTION_POST_DATA,
13675 q->data, delq->data, NULL,
13676 NULL, 0,
13677 NULL, NULL);
13678 }
13679 else if (coninfo->contype == 'c' && tbinfo)
13680 {
13681
13682
13683
13684 if (coninfo->separate)
13685 {
13686
13687 appendPQExpBuffer(q, "ALTER TABLE %s\n",
13688 fmtId(tbinfo->dobj.name));
13689 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
13690 fmtId(coninfo->dobj.name),
13691 coninfo->condef);
13692
13693
13694
13695
13696
13697 appendPQExpBuffer(delq, "ALTER TABLE %s.",
13698 fmtId(tbinfo->dobj.namespace->dobj.name));
13699 appendPQExpBuffer(delq, "%s ",
13700 fmtId(tbinfo->dobj.name));
13701 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
13702 fmtId(coninfo->dobj.name));
13703
13704 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
13705 coninfo->dobj.name,
13706 tbinfo->dobj.namespace->dobj.name,
13707 NULL,
13708 tbinfo->rolname, false,
13709 "CHECK CONSTRAINT", SECTION_POST_DATA,
13710 q->data, delq->data, NULL,
13711 NULL, 0,
13712 NULL, NULL);
13713 }
13714 }
13715 else if (coninfo->contype == 'c' && tbinfo == NULL)
13716 {
13717
13718 TypeInfo *tyinfo = coninfo->condomain;
13719
13720
13721 if (coninfo->separate)
13722 {
13723 appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
13724 fmtId(tyinfo->dobj.name));
13725 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
13726 fmtId(coninfo->dobj.name),
13727 coninfo->condef);
13728
13729
13730
13731
13732
13733 appendPQExpBuffer(delq, "ALTER DOMAIN %s.",
13734 fmtId(tyinfo->dobj.namespace->dobj.name));
13735 appendPQExpBuffer(delq, "%s ",
13736 fmtId(tyinfo->dobj.name));
13737 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
13738 fmtId(coninfo->dobj.name));
13739
13740 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
13741 coninfo->dobj.name,
13742 tyinfo->dobj.namespace->dobj.name,
13743 NULL,
13744 tyinfo->rolname, false,
13745 "CHECK CONSTRAINT", SECTION_POST_DATA,
13746 q->data, delq->data, NULL,
13747 NULL, 0,
13748 NULL, NULL);
13749 }
13750 }
13751 else
13752 {
13753 exit_horribly(NULL, "unrecognized constraint type: %c\n",
13754 coninfo->contype);
13755 }
13756
13757
13758 if (tbinfo && coninfo->separate)
13759 dumpTableConstraintComment(fout, coninfo);
13760
13761 destroyPQExpBuffer(q);
13762 destroyPQExpBuffer(delq);
13763 }
13764
13765
13766
13767
13768
13769
13770
13771
13772 static void
13773 dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo)
13774 {
13775 TableInfo *tbinfo = coninfo->contable;
13776 PQExpBuffer labelq = createPQExpBuffer();
13777
13778 appendPQExpBuffer(labelq, "CONSTRAINT %s ",
13779 fmtId(coninfo->dobj.name));
13780 appendPQExpBuffer(labelq, "ON %s",
13781 fmtId(tbinfo->dobj.name));
13782 dumpComment(fout, labelq->data,
13783 tbinfo->dobj.namespace->dobj.name,
13784 tbinfo->rolname,
13785 coninfo->dobj.catId, 0,
13786 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
13787
13788 destroyPQExpBuffer(labelq);
13789 }
13790
13791
13792
13793
13794
13795
13796
13797
13798 static Oid
13799 findLastBuiltinOid_V71(Archive *fout, const char *dbname)
13800 {
13801 PGresult *res;
13802 Oid last_oid;
13803 PQExpBuffer query = createPQExpBuffer();
13804
13805 resetPQExpBuffer(query);
13806 appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
13807 appendStringLiteralAH(query, dbname, fout);
13808
13809 res = ExecuteSqlQueryForSingleRow(fout, query->data);
13810 last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid")));
13811 PQclear(res);
13812 destroyPQExpBuffer(query);
13813 return last_oid;
13814 }
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824 static Oid
13825 findLastBuiltinOid_V70(Archive *fout)
13826 {
13827 PGresult *res;
13828 int last_oid;
13829
13830 res = ExecuteSqlQueryForSingleRow(fout,
13831 "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'");
13832 last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
13833 PQclear(res);
13834 return last_oid;
13835 }
13836
13837
13838
13839
13840
13841 static void
13842 dumpSequence(Archive *fout, TableInfo *tbinfo)
13843 {
13844 PGresult *res;
13845 char *startv,
13846 *incby,
13847 *maxv = NULL,
13848 *minv = NULL,
13849 *cache;
13850 char bufm[100],
13851 bufx[100];
13852 bool cycled;
13853 PQExpBuffer query = createPQExpBuffer();
13854 PQExpBuffer delqry = createPQExpBuffer();
13855 PQExpBuffer labelq = createPQExpBuffer();
13856
13857
13858 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
13859
13860 snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
13861 snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
13862
13863 if (fout->remoteVersion >= 80400)
13864 {
13865 appendPQExpBuffer(query,
13866 "SELECT sequence_name, "
13867 "start_value, increment_by, "
13868 "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
13869 " WHEN increment_by < 0 AND max_value = -1 THEN NULL "
13870 " ELSE max_value "
13871 "END AS max_value, "
13872 "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
13873 " WHEN increment_by < 0 AND min_value = %s THEN NULL "
13874 " ELSE min_value "
13875 "END AS min_value, "
13876 "cache_value, is_cycled FROM %s",
13877 bufx, bufm,
13878 fmtId(tbinfo->dobj.name));
13879 }
13880 else
13881 {
13882 appendPQExpBuffer(query,
13883 "SELECT sequence_name, "
13884 "0 AS start_value, increment_by, "
13885 "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
13886 " WHEN increment_by < 0 AND max_value = -1 THEN NULL "
13887 " ELSE max_value "
13888 "END AS max_value, "
13889 "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
13890 " WHEN increment_by < 0 AND min_value = %s THEN NULL "
13891 " ELSE min_value "
13892 "END AS min_value, "
13893 "cache_value, is_cycled FROM %s",
13894 bufx, bufm,
13895 fmtId(tbinfo->dobj.name));
13896 }
13897
13898 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13899
13900 if (PQntuples(res) != 1)
13901 {
13902 write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
13903 "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
13904 PQntuples(res)),
13905 tbinfo->dobj.name, PQntuples(res));
13906 exit_nicely(1);
13907 }
13908
13909
13910 #ifdef NOT_USED
13911 if (strcmp(PQgetvalue(res, 0, 0), tbinfo->dobj.name) != 0)
13912 {
13913 write_msg(NULL, "query to get data of sequence \"%s\" returned name \"%s\"\n",
13914 tbinfo->dobj.name, PQgetvalue(res, 0, 0));
13915 exit_nicely(1);
13916 }
13917 #endif
13918
13919 startv = PQgetvalue(res, 0, 1);
13920 incby = PQgetvalue(res, 0, 2);
13921 if (!PQgetisnull(res, 0, 3))
13922 maxv = PQgetvalue(res, 0, 3);
13923 if (!PQgetisnull(res, 0, 4))
13924 minv = PQgetvalue(res, 0, 4);
13925 cache = PQgetvalue(res, 0, 5);
13926 cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
13927
13928
13929
13930
13931 appendPQExpBuffer(delqry, "DROP SEQUENCE %s.",
13932 fmtId(tbinfo->dobj.namespace->dobj.name));
13933 appendPQExpBuffer(delqry, "%s;\n",
13934 fmtId(tbinfo->dobj.name));
13935
13936 resetPQExpBuffer(query);
13937
13938 if (binary_upgrade)
13939 {
13940 binary_upgrade_set_pg_class_oids(fout, query,
13941 tbinfo->dobj.catId.oid, false);
13942 binary_upgrade_set_type_oids_by_rel_oid(fout, query,
13943 tbinfo->dobj.catId.oid);
13944 }
13945
13946 appendPQExpBuffer(query,
13947 "CREATE SEQUENCE %s\n",
13948 fmtId(tbinfo->dobj.name));
13949
13950 if (fout->remoteVersion >= 80400)
13951 appendPQExpBuffer(query, " START WITH %s\n", startv);
13952
13953 appendPQExpBuffer(query, " INCREMENT BY %s\n", incby);
13954
13955 if (minv)
13956 appendPQExpBuffer(query, " MINVALUE %s\n", minv);
13957 else
13958 appendPQExpBuffer(query, " NO MINVALUE\n");
13959
13960 if (maxv)
13961 appendPQExpBuffer(query, " MAXVALUE %s\n", maxv);
13962 else
13963 appendPQExpBuffer(query, " NO MAXVALUE\n");
13964
13965 appendPQExpBuffer(query,
13966 " CACHE %s%s",
13967 cache, (cycled ? "\n CYCLE" : ""));
13968
13969 appendPQExpBuffer(query, ";\n");
13970
13971 appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
13972
13973
13974
13975 if (binary_upgrade)
13976 binary_upgrade_extension_member(query, &tbinfo->dobj,
13977 labelq->data);
13978
13979 ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
13980 tbinfo->dobj.name,
13981 tbinfo->dobj.namespace->dobj.name,
13982 NULL,
13983 tbinfo->rolname,
13984 false, "SEQUENCE", SECTION_PRE_DATA,
13985 query->data, delqry->data, NULL,
13986 NULL, 0,
13987 NULL, NULL);
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001 if (OidIsValid(tbinfo->owning_tab))
14002 {
14003 TableInfo *owning_tab = findTableByOid(tbinfo->owning_tab);
14004
14005 if (owning_tab && owning_tab->dobj.dump)
14006 {
14007 resetPQExpBuffer(query);
14008 appendPQExpBuffer(query, "ALTER SEQUENCE %s",
14009 fmtId(tbinfo->dobj.name));
14010 appendPQExpBuffer(query, " OWNED BY %s",
14011 fmtId(owning_tab->dobj.name));
14012 appendPQExpBuffer(query, ".%s;\n",
14013 fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
14014
14015 ArchiveEntry(fout, nilCatalogId, createDumpId(),
14016 tbinfo->dobj.name,
14017 tbinfo->dobj.namespace->dobj.name,
14018 NULL,
14019 tbinfo->rolname,
14020 false, "SEQUENCE OWNED BY", SECTION_PRE_DATA,
14021 query->data, "", NULL,
14022 &(tbinfo->dobj.dumpId), 1,
14023 NULL, NULL);
14024 }
14025 }
14026
14027
14028 dumpComment(fout, labelq->data,
14029 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
14030 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
14031 dumpSecLabel(fout, labelq->data,
14032 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
14033 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
14034
14035 PQclear(res);
14036
14037 destroyPQExpBuffer(query);
14038 destroyPQExpBuffer(delqry);
14039 destroyPQExpBuffer(labelq);
14040 }
14041
14042
14043
14044
14045
14046 static void
14047 dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
14048 {
14049 TableInfo *tbinfo = tdinfo->tdtable;
14050 PGresult *res;
14051 char *last;
14052 bool called;
14053 PQExpBuffer query = createPQExpBuffer();
14054
14055
14056 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
14057
14058 appendPQExpBuffer(query,
14059 "SELECT last_value, is_called FROM %s",
14060 fmtId(tbinfo->dobj.name));
14061
14062 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14063
14064 if (PQntuples(res) != 1)
14065 {
14066 write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
14067 "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
14068 PQntuples(res)),
14069 tbinfo->dobj.name, PQntuples(res));
14070 exit_nicely(1);
14071 }
14072
14073 last = PQgetvalue(res, 0, 0);
14074 called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
14075
14076 resetPQExpBuffer(query);
14077 appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
14078 appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
14079 appendPQExpBuffer(query, ", %s, %s);\n",
14080 last, (called ? "true" : "false"));
14081
14082 ArchiveEntry(fout, nilCatalogId, createDumpId(),
14083 tbinfo->dobj.name,
14084 tbinfo->dobj.namespace->dobj.name,
14085 NULL,
14086 tbinfo->rolname,
14087 false, "SEQUENCE SET", SECTION_DATA,
14088 query->data, "", NULL,
14089 &(tbinfo->dobj.dumpId), 1,
14090 NULL, NULL);
14091
14092 PQclear(res);
14093
14094 destroyPQExpBuffer(query);
14095 }
14096
14097 static void
14098 dumpTrigger(Archive *fout, TriggerInfo *tginfo)
14099 {
14100 TableInfo *tbinfo = tginfo->tgtable;
14101 PQExpBuffer query;
14102 PQExpBuffer delqry;
14103 PQExpBuffer labelq;
14104 char *tgargs;
14105 size_t lentgargs;
14106 const char *p;
14107 int findx;
14108
14109 if (dataOnly)
14110 return;
14111
14112 query = createPQExpBuffer();
14113 delqry = createPQExpBuffer();
14114 labelq = createPQExpBuffer();
14115
14116
14117
14118
14119 appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
14120 fmtId(tginfo->dobj.name));
14121 appendPQExpBuffer(delqry, "ON %s.",
14122 fmtId(tbinfo->dobj.namespace->dobj.name));
14123 appendPQExpBuffer(delqry, "%s;\n",
14124 fmtId(tbinfo->dobj.name));
14125
14126 if (tginfo->tgdef)
14127 {
14128 appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
14129 }
14130 else
14131 {
14132 if (tginfo->tgisconstraint)
14133 {
14134 appendPQExpBuffer(query, "CREATE CONSTRAINT TRIGGER ");
14135 appendPQExpBufferStr(query, fmtId(tginfo->tgconstrname));
14136 }
14137 else
14138 {
14139 appendPQExpBuffer(query, "CREATE TRIGGER ");
14140 appendPQExpBufferStr(query, fmtId(tginfo->dobj.name));
14141 }
14142 appendPQExpBuffer(query, "\n ");
14143
14144
14145 if (TRIGGER_FOR_BEFORE(tginfo->tgtype))
14146 appendPQExpBuffer(query, "BEFORE");
14147 else if (TRIGGER_FOR_AFTER(tginfo->tgtype))
14148 appendPQExpBuffer(query, "AFTER");
14149 else if (TRIGGER_FOR_INSTEAD(tginfo->tgtype))
14150 appendPQExpBuffer(query, "INSTEAD OF");
14151 else
14152 {
14153 write_msg(NULL, "unexpected tgtype value: %d\n", tginfo->tgtype);
14154 exit_nicely(1);
14155 }
14156
14157 findx = 0;
14158 if (TRIGGER_FOR_INSERT(tginfo->tgtype))
14159 {
14160 appendPQExpBuffer(query, " INSERT");
14161 findx++;
14162 }
14163 if (TRIGGER_FOR_DELETE(tginfo->tgtype))
14164 {
14165 if (findx > 0)
14166 appendPQExpBuffer(query, " OR DELETE");
14167 else
14168 appendPQExpBuffer(query, " DELETE");
14169 findx++;
14170 }
14171 if (TRIGGER_FOR_UPDATE(tginfo->tgtype))
14172 {
14173 if (findx > 0)
14174 appendPQExpBuffer(query, " OR UPDATE");
14175 else
14176 appendPQExpBuffer(query, " UPDATE");
14177 findx++;
14178 }
14179 if (TRIGGER_FOR_TRUNCATE(tginfo->tgtype))
14180 {
14181 if (findx > 0)
14182 appendPQExpBuffer(query, " OR TRUNCATE");
14183 else
14184 appendPQExpBuffer(query, " TRUNCATE");
14185 findx++;
14186 }
14187 appendPQExpBuffer(query, " ON %s\n",
14188 fmtId(tbinfo->dobj.name));
14189
14190 if (tginfo->tgisconstraint)
14191 {
14192 if (OidIsValid(tginfo->tgconstrrelid))
14193 {
14194
14195 if (fout->remoteVersion >= 70300)
14196 appendPQExpBuffer(query, " FROM %s\n ",
14197 tginfo->tgconstrrelname);
14198 else
14199 appendPQExpBuffer(query, " FROM %s\n ",
14200 fmtId(tginfo->tgconstrrelname));
14201 }
14202 if (!tginfo->tgdeferrable)
14203 appendPQExpBuffer(query, "NOT ");
14204 appendPQExpBuffer(query, "DEFERRABLE INITIALLY ");
14205 if (tginfo->tginitdeferred)
14206 appendPQExpBuffer(query, "DEFERRED\n");
14207 else
14208 appendPQExpBuffer(query, "IMMEDIATE\n");
14209 }
14210
14211 if (TRIGGER_FOR_ROW(tginfo->tgtype))
14212 appendPQExpBuffer(query, " FOR EACH ROW\n ");
14213 else
14214 appendPQExpBuffer(query, " FOR EACH STATEMENT\n ");
14215
14216
14217 if (fout->remoteVersion >= 70300)
14218 appendPQExpBuffer(query, "EXECUTE PROCEDURE %s(",
14219 tginfo->tgfname);
14220 else
14221 appendPQExpBuffer(query, "EXECUTE PROCEDURE %s(",
14222 fmtId(tginfo->tgfname));
14223
14224 tgargs = (char *) PQunescapeBytea((unsigned char *) tginfo->tgargs,
14225 &lentgargs);
14226 p = tgargs;
14227 for (findx = 0; findx < tginfo->tgnargs; findx++)
14228 {
14229
14230 size_t tlen = strlen(p);
14231
14232 if (p + tlen >= tgargs + lentgargs)
14233 {
14234
14235 write_msg(NULL, "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n",
14236 tginfo->tgargs,
14237 tginfo->dobj.name,
14238 tbinfo->dobj.name);
14239 exit_nicely(1);
14240 }
14241
14242 if (findx > 0)
14243 appendPQExpBuffer(query, ", ");
14244 appendStringLiteralAH(query, p, fout);
14245 p += tlen + 1;
14246 }
14247 free(tgargs);
14248 appendPQExpBuffer(query, ");\n");
14249 }
14250
14251 if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
14252 {
14253 appendPQExpBuffer(query, "\nALTER TABLE %s ",
14254 fmtId(tbinfo->dobj.name));
14255 switch (tginfo->tgenabled)
14256 {
14257 case 'D':
14258 case 'f':
14259 appendPQExpBuffer(query, "DISABLE");
14260 break;
14261 case 'A':
14262 appendPQExpBuffer(query, "ENABLE ALWAYS");
14263 break;
14264 case 'R':
14265 appendPQExpBuffer(query, "ENABLE REPLICA");
14266 break;
14267 default:
14268 appendPQExpBuffer(query, "ENABLE");
14269 break;
14270 }
14271 appendPQExpBuffer(query, " TRIGGER %s;\n",
14272 fmtId(tginfo->dobj.name));
14273 }
14274
14275 appendPQExpBuffer(labelq, "TRIGGER %s ",
14276 fmtId(tginfo->dobj.name));
14277 appendPQExpBuffer(labelq, "ON %s",
14278 fmtId(tbinfo->dobj.name));
14279
14280 ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
14281 tginfo->dobj.name,
14282 tbinfo->dobj.namespace->dobj.name,
14283 NULL,
14284 tbinfo->rolname, false,
14285 "TRIGGER", SECTION_POST_DATA,
14286 query->data, delqry->data, NULL,
14287 NULL, 0,
14288 NULL, NULL);
14289
14290 dumpComment(fout, labelq->data,
14291 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
14292 tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
14293
14294 destroyPQExpBuffer(query);
14295 destroyPQExpBuffer(delqry);
14296 destroyPQExpBuffer(labelq);
14297 }
14298
14299 static void
14300 dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo)
14301 {
14302 PQExpBuffer query;
14303 PQExpBuffer labelq;
14304
14305 query = createPQExpBuffer();
14306 labelq = createPQExpBuffer();
14307
14308 appendPQExpBuffer(query, "CREATE EVENT TRIGGER ");
14309 appendPQExpBufferStr(query, fmtId(evtinfo->dobj.name));
14310 appendPQExpBuffer(query, " ON ");
14311 appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
14312 appendPQExpBufferStr(query, " ");
14313
14314 if (strcmp("", evtinfo->evttags) != 0)
14315 {
14316 appendPQExpBufferStr(query, "\n WHEN TAG IN (");
14317 appendPQExpBufferStr(query, evtinfo->evttags);
14318 appendPQExpBufferStr(query, ") ");
14319 }
14320
14321 appendPQExpBuffer(query, "\n EXECUTE PROCEDURE ");
14322 appendPQExpBufferStr(query, evtinfo->evtfname);
14323 appendPQExpBuffer(query, "();\n");
14324
14325 if (evtinfo->evtenabled != 'O')
14326 {
14327 appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
14328 fmtId(evtinfo->dobj.name));
14329 switch (evtinfo->evtenabled)
14330 {
14331 case 'D':
14332 appendPQExpBuffer(query, "DISABLE");
14333 break;
14334 case 'A':
14335 appendPQExpBuffer(query, "ENABLE ALWAYS");
14336 break;
14337 case 'R':
14338 appendPQExpBuffer(query, "ENABLE REPLICA");
14339 break;
14340 default:
14341 appendPQExpBuffer(query, "ENABLE");
14342 break;
14343 }
14344 appendPQExpBuffer(query, ";\n");
14345 }
14346 appendPQExpBuffer(labelq, "EVENT TRIGGER %s ",
14347 fmtId(evtinfo->dobj.name));
14348
14349 ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
14350 evtinfo->dobj.name, NULL, NULL, evtinfo->evtowner, false,
14351 "EVENT TRIGGER", SECTION_POST_DATA,
14352 query->data, "", NULL, NULL, 0, NULL, NULL);
14353
14354 dumpComment(fout, labelq->data,
14355 NULL, NULL,
14356 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
14357
14358 destroyPQExpBuffer(query);
14359 destroyPQExpBuffer(labelq);
14360 }
14361
14362
14363
14364
14365
14366 static void
14367 dumpRule(Archive *fout, RuleInfo *rinfo)
14368 {
14369 TableInfo *tbinfo = rinfo->ruletable;
14370 PQExpBuffer query;
14371 PQExpBuffer cmd;
14372 PQExpBuffer delcmd;
14373 PQExpBuffer labelq;
14374 PGresult *res;
14375
14376
14377 if (!rinfo->dobj.dump || dataOnly)
14378 return;
14379
14380
14381
14382
14383
14384 if (!rinfo->separate)
14385 return;
14386
14387
14388
14389
14390 selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
14391
14392 query = createPQExpBuffer();
14393 cmd = createPQExpBuffer();
14394 delcmd = createPQExpBuffer();
14395 labelq = createPQExpBuffer();
14396
14397 if (fout->remoteVersion >= 70300)
14398 {
14399 appendPQExpBuffer(query,
14400 "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid) AS definition",
14401 rinfo->dobj.catId.oid);
14402 }
14403 else
14404 {
14405
14406 appendPQExpBuffer(query,
14407 "SELECT pg_get_ruledef('%s') AS definition",
14408 rinfo->dobj.name);
14409 }
14410
14411 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14412
14413 if (PQntuples(res) != 1)
14414 {
14415 write_msg(NULL, "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n",
14416 rinfo->dobj.name, tbinfo->dobj.name);
14417 exit_nicely(1);
14418 }
14419
14420 printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
14421
14422
14423
14424
14425
14426 if (rinfo->ev_enabled != 'O')
14427 {
14428 appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtId(tbinfo->dobj.name));
14429 switch (rinfo->ev_enabled)
14430 {
14431 case 'A':
14432 appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
14433 fmtId(rinfo->dobj.name));
14434 break;
14435 case 'R':
14436 appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
14437 fmtId(rinfo->dobj.name));
14438 break;
14439 case 'D':
14440 appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
14441 fmtId(rinfo->dobj.name));
14442 break;
14443 }
14444 }
14445
14446
14447
14448
14449 if (rinfo->reloptions && strlen(rinfo->reloptions) > 0)
14450 {
14451 appendPQExpBuffer(cmd, "ALTER VIEW %s SET (%s);\n",
14452 fmtId(tbinfo->dobj.name),
14453 rinfo->reloptions);
14454 }
14455
14456
14457
14458
14459 appendPQExpBuffer(delcmd, "DROP RULE %s ",
14460 fmtId(rinfo->dobj.name));
14461 appendPQExpBuffer(delcmd, "ON %s.",
14462 fmtId(tbinfo->dobj.namespace->dobj.name));
14463 appendPQExpBuffer(delcmd, "%s;\n",
14464 fmtId(tbinfo->dobj.name));
14465
14466 appendPQExpBuffer(labelq, "RULE %s",
14467 fmtId(rinfo->dobj.name));
14468 appendPQExpBuffer(labelq, " ON %s",
14469 fmtId(tbinfo->dobj.name));
14470
14471 ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
14472 rinfo->dobj.name,
14473 tbinfo->dobj.namespace->dobj.name,
14474 NULL,
14475 tbinfo->rolname, false,
14476 "RULE", SECTION_POST_DATA,
14477 cmd->data, delcmd->data, NULL,
14478 NULL, 0,
14479 NULL, NULL);
14480
14481
14482 dumpComment(fout, labelq->data,
14483 tbinfo->dobj.namespace->dobj.name,
14484 tbinfo->rolname,
14485 rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
14486
14487 PQclear(res);
14488
14489 destroyPQExpBuffer(query);
14490 destroyPQExpBuffer(cmd);
14491 destroyPQExpBuffer(delcmd);
14492 destroyPQExpBuffer(labelq);
14493 }
14494
14495
14496
14497
14498 void
14499 getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
14500 int numExtensions)
14501 {
14502 PQExpBuffer query;
14503 PGresult *res;
14504 int ntups,
14505 i;
14506 int i_classid,
14507 i_objid,
14508 i_refclassid,
14509 i_refobjid;
14510 DumpableObject *dobj,
14511 *refdobj;
14512
14513
14514 if (numExtensions == 0)
14515 return;
14516
14517
14518 selectSourceSchema(fout, "pg_catalog");
14519
14520 query = createPQExpBuffer();
14521
14522
14523 appendPQExpBuffer(query, "SELECT "
14524 "classid, objid, refclassid, refobjid "
14525 "FROM pg_depend "
14526 "WHERE refclassid = 'pg_extension'::regclass "
14527 "AND deptype = 'e' "
14528 "ORDER BY 3,4");
14529
14530 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14531
14532 ntups = PQntuples(res);
14533
14534 i_classid = PQfnumber(res, "classid");
14535 i_objid = PQfnumber(res, "objid");
14536 i_refclassid = PQfnumber(res, "refclassid");
14537 i_refobjid = PQfnumber(res, "refobjid");
14538
14539
14540
14541
14542
14543
14544 refdobj = NULL;
14545
14546 for (i = 0; i < ntups; i++)
14547 {
14548 CatalogId objId;
14549 CatalogId refobjId;
14550
14551 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
14552 objId.oid = atooid(PQgetvalue(res, i, i_objid));
14553 refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
14554 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
14555
14556 if (refdobj == NULL ||
14557 refdobj->catId.tableoid != refobjId.tableoid ||
14558 refdobj->catId.oid != refobjId.oid)
14559 refdobj = findObjectByCatalogId(refobjId);
14560
14561
14562
14563
14564
14565 if (refdobj == NULL)
14566 {
14567 #ifdef NOT_USED
14568 fprintf(stderr, "no referenced object %u %u\n",
14569 refobjId.tableoid, refobjId.oid);
14570 #endif
14571 continue;
14572 }
14573
14574 dobj = findObjectByCatalogId(objId);
14575
14576 if (dobj == NULL)
14577 {
14578 #ifdef NOT_USED
14579 fprintf(stderr, "no referencing object %u %u\n",
14580 objId.tableoid, objId.oid);
14581 #endif
14582 continue;
14583 }
14584
14585
14586 addObjectDependency(dobj, refdobj->dumpId);
14587
14588 dobj->ext_member = true;
14589
14590
14591
14592
14593
14594
14595
14596 if (!binary_upgrade)
14597 dobj->dump = false;
14598 else
14599 dobj->dump = refdobj->dump;
14600 }
14601
14602 PQclear(res);
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614 for (i = 0; i < numExtensions; i++)
14615 {
14616 ExtensionInfo *curext = &(extinfo[i]);
14617 char *extconfig = curext->extconfig;
14618 char *extcondition = curext->extcondition;
14619 char **extconfigarray = NULL;
14620 char **extconditionarray = NULL;
14621 int nconfigitems;
14622 int nconditionitems;
14623
14624 if (parsePGArray(extconfig, &extconfigarray, &nconfigitems) &&
14625 parsePGArray(extcondition, &extconditionarray, &nconditionitems) &&
14626 nconfigitems == nconditionitems)
14627 {
14628 int j;
14629
14630 for (j = 0; j < nconfigitems; j++)
14631 {
14632 TableInfo *configtbl;
14633 Oid configtbloid = atooid(extconfigarray[j]);
14634 bool dumpobj = curext->dobj.dump;
14635
14636 configtbl = findTableByOid(configtbloid);
14637 if (configtbl == NULL)
14638 continue;
14639
14640
14641
14642
14643
14644 if (!curext->dobj.dump)
14645 {
14646
14647 if (table_include_oids.head != NULL &&
14648 simple_oid_list_member(&table_include_oids,
14649 configtbloid))
14650 dumpobj = true;
14651
14652
14653 if (configtbl->dobj.namespace->dobj.dump)
14654 dumpobj = true;
14655 }
14656
14657
14658 if (table_exclude_oids.head != NULL &&
14659 simple_oid_list_member(&table_exclude_oids,
14660 configtbloid))
14661 dumpobj = false;
14662
14663
14664 if (simple_oid_list_member(&schema_exclude_oids,
14665 configtbl->dobj.namespace->dobj.catId.oid))
14666 dumpobj = false;
14667
14668 if (dumpobj)
14669 {
14670
14671
14672
14673
14674
14675 makeTableDataInfo(configtbl, false);
14676 if (configtbl->dataObj != NULL)
14677 {
14678 if (strlen(extconditionarray[j]) > 0)
14679 configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
14680 }
14681 }
14682 }
14683 }
14684 if (extconfigarray)
14685 free(extconfigarray);
14686 if (extconditionarray)
14687 free(extconditionarray);
14688 }
14689
14690 destroyPQExpBuffer(query);
14691 }
14692
14693
14694
14695
14696 static void
14697 getDependencies(Archive *fout)
14698 {
14699 PQExpBuffer query;
14700 PGresult *res;
14701 int ntups,
14702 i;
14703 int i_classid,
14704 i_objid,
14705 i_refclassid,
14706 i_refobjid,
14707 i_deptype;
14708 DumpableObject *dobj,
14709 *refdobj;
14710
14711
14712 if (fout->remoteVersion < 70300)
14713 return;
14714
14715 if (g_verbose)
14716 write_msg(NULL, "reading dependency data\n");
14717
14718
14719 selectSourceSchema(fout, "pg_catalog");
14720
14721 query = createPQExpBuffer();
14722
14723
14724
14725
14726
14727 appendPQExpBuffer(query, "SELECT "
14728 "classid, objid, refclassid, refobjid, deptype "
14729 "FROM pg_depend "
14730 "WHERE deptype != 'p' AND deptype != 'e' "
14731 "ORDER BY 1,2");
14732
14733 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14734
14735 ntups = PQntuples(res);
14736
14737 i_classid = PQfnumber(res, "classid");
14738 i_objid = PQfnumber(res, "objid");
14739 i_refclassid = PQfnumber(res, "refclassid");
14740 i_refobjid = PQfnumber(res, "refobjid");
14741 i_deptype = PQfnumber(res, "deptype");
14742
14743
14744
14745
14746
14747
14748 dobj = NULL;
14749
14750 for (i = 0; i < ntups; i++)
14751 {
14752 CatalogId objId;
14753 CatalogId refobjId;
14754 char deptype;
14755
14756 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
14757 objId.oid = atooid(PQgetvalue(res, i, i_objid));
14758 refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
14759 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
14760 deptype = *(PQgetvalue(res, i, i_deptype));
14761
14762 if (dobj == NULL ||
14763 dobj->catId.tableoid != objId.tableoid ||
14764 dobj->catId.oid != objId.oid)
14765 dobj = findObjectByCatalogId(objId);
14766
14767
14768
14769
14770
14771 if (dobj == NULL)
14772 {
14773 #ifdef NOT_USED
14774 fprintf(stderr, "no referencing object %u %u\n",
14775 objId.tableoid, objId.oid);
14776 #endif
14777 continue;
14778 }
14779
14780 refdobj = findObjectByCatalogId(refobjId);
14781
14782 if (refdobj == NULL)
14783 {
14784 #ifdef NOT_USED
14785 fprintf(stderr, "no referenced object %u %u\n",
14786 refobjId.tableoid, refobjId.oid);
14787 #endif
14788 continue;
14789 }
14790
14791
14792
14793
14794
14795
14796
14797
14798 if (deptype == 'i' &&
14799 dobj->objType == DO_TABLE &&
14800 refdobj->objType == DO_TYPE)
14801 addObjectDependency(refdobj, dobj->dumpId);
14802 else
14803
14804 addObjectDependency(dobj, refdobj->dumpId);
14805 }
14806
14807 PQclear(res);
14808
14809 destroyPQExpBuffer(query);
14810 }
14811
14812
14813
14814
14815
14816
14817 static DumpableObject *
14818 createBoundaryObjects(void)
14819 {
14820 DumpableObject *dobjs;
14821
14822 dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
14823
14824 dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
14825 dobjs[0].catId = nilCatalogId;
14826 AssignDumpId(dobjs + 0);
14827 dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
14828
14829 dobjs[1].objType = DO_POST_DATA_BOUNDARY;
14830 dobjs[1].catId = nilCatalogId;
14831 AssignDumpId(dobjs + 1);
14832 dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
14833
14834 return dobjs;
14835 }
14836
14837
14838
14839
14840
14841 static void
14842 addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
14843 DumpableObject *boundaryObjs)
14844 {
14845 DumpableObject *preDataBound = boundaryObjs + 0;
14846 DumpableObject *postDataBound = boundaryObjs + 1;
14847 int i;
14848
14849 for (i = 0; i < numObjs; i++)
14850 {
14851 DumpableObject *dobj = dobjs[i];
14852
14853
14854
14855
14856
14857 switch (dobj->objType)
14858 {
14859 case DO_NAMESPACE:
14860 case DO_EXTENSION:
14861 case DO_TYPE:
14862 case DO_SHELL_TYPE:
14863 case DO_FUNC:
14864 case DO_AGG:
14865 case DO_OPERATOR:
14866 case DO_OPCLASS:
14867 case DO_OPFAMILY:
14868 case DO_COLLATION:
14869 case DO_CONVERSION:
14870 case DO_TABLE:
14871 case DO_ATTRDEF:
14872 case DO_PROCLANG:
14873 case DO_CAST:
14874 case DO_DUMMY_TYPE:
14875 case DO_TSPARSER:
14876 case DO_TSDICT:
14877 case DO_TSTEMPLATE:
14878 case DO_TSCONFIG:
14879 case DO_FDW:
14880 case DO_FOREIGN_SERVER:
14881 case DO_BLOB:
14882
14883 addObjectDependency(preDataBound, dobj->dumpId);
14884 break;
14885 case DO_TABLE_DATA:
14886 case DO_BLOB_DATA:
14887
14888 addObjectDependency(dobj, preDataBound->dumpId);
14889 addObjectDependency(postDataBound, dobj->dumpId);
14890 break;
14891 case DO_INDEX:
14892 case DO_REFRESH_MATVIEW:
14893 case DO_TRIGGER:
14894 case DO_EVENT_TRIGGER:
14895 case DO_DEFAULT_ACL:
14896
14897 addObjectDependency(dobj, postDataBound->dumpId);
14898 break;
14899 case DO_RULE:
14900
14901 if (((RuleInfo *) dobj)->separate)
14902 addObjectDependency(dobj, postDataBound->dumpId);
14903 break;
14904 case DO_CONSTRAINT:
14905 case DO_FK_CONSTRAINT:
14906
14907 if (((ConstraintInfo *) dobj)->separate)
14908 addObjectDependency(dobj, postDataBound->dumpId);
14909 break;
14910 case DO_PRE_DATA_BOUNDARY:
14911
14912 break;
14913 case DO_POST_DATA_BOUNDARY:
14914
14915 addObjectDependency(dobj, preDataBound->dumpId);
14916 break;
14917 }
14918 }
14919 }
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945 static void
14946 BuildArchiveDependencies(Archive *fout)
14947 {
14948 ArchiveHandle *AH = (ArchiveHandle *) fout;
14949 TocEntry *te;
14950
14951
14952 for (te = AH->toc->next; te != AH->toc; te = te->next)
14953 {
14954 DumpableObject *dobj;
14955 DumpId *dependencies;
14956 int nDeps;
14957 int allocDeps;
14958
14959
14960 if (te->reqs == 0)
14961 continue;
14962
14963 if (te->nDeps > 0)
14964 continue;
14965
14966 dobj = findObjectByDumpId(te->dumpId);
14967 if (dobj == NULL)
14968 continue;
14969
14970 if (dobj->nDeps <= 0)
14971 continue;
14972
14973 allocDeps = 64;
14974 dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
14975 nDeps = 0;
14976
14977 findDumpableDependencies(AH, dobj,
14978 &dependencies, &nDeps, &allocDeps);
14979
14980 if (nDeps > 0)
14981 {
14982 dependencies = (DumpId *) pg_realloc(dependencies,
14983 nDeps * sizeof(DumpId));
14984 te->dependencies = dependencies;
14985 te->nDeps = nDeps;
14986 }
14987 else
14988 free(dependencies);
14989 }
14990 }
14991
14992
14993 static void
14994 findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
14995 DumpId **dependencies, int *nDeps, int *allocDeps)
14996 {
14997 int i;
14998
14999
15000
15001
15002
15003 if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
15004 dobj->objType == DO_POST_DATA_BOUNDARY)
15005 return;
15006
15007 for (i = 0; i < dobj->nDeps; i++)
15008 {
15009 DumpId depid = dobj->dependencies[i];
15010
15011 if (TocIDRequired(AH, depid) != 0)
15012 {
15013
15014 if (*nDeps >= *allocDeps)
15015 {
15016 *allocDeps *= 2;
15017 *dependencies = (DumpId *) pg_realloc(*dependencies,
15018 *allocDeps * sizeof(DumpId));
15019 }
15020 (*dependencies)[*nDeps] = depid;
15021 (*nDeps)++;
15022 }
15023 else
15024 {
15025
15026
15027
15028
15029
15030 DumpableObject *otherdobj = findObjectByDumpId(depid);
15031
15032 if (otherdobj)
15033 findDumpableDependencies(AH, otherdobj,
15034 dependencies, nDeps, allocDeps);
15035 }
15036 }
15037 }
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055 static void
15056 selectSourceSchema(Archive *fout, const char *schemaName)
15057 {
15058 PQExpBuffer query;
15059
15060
15061 Assert(schemaName != NULL && *schemaName != '\0');
15062
15063
15064 if (fout->remoteVersion < 70300)
15065 return;
15066
15067 query = createPQExpBuffer();
15068 appendPQExpBuffer(query, "SET search_path = %s",
15069 fmtId(schemaName));
15070 if (strcmp(schemaName, "pg_catalog") != 0)
15071 appendPQExpBuffer(query, ", pg_catalog");
15072
15073 ExecuteSqlStatement(fout, query->data);
15074
15075 destroyPQExpBuffer(query);
15076 }
15077
15078
15079
15080
15081
15082
15083
15084
15085 static char *
15086 getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
15087 {
15088 char *result;
15089 PQExpBuffer query;
15090 PGresult *res;
15091
15092 if (oid == 0)
15093 {
15094 if ((opts & zeroAsOpaque) != 0)
15095 return pg_strdup(g_opaque_type);
15096 else if ((opts & zeroAsAny) != 0)
15097 return pg_strdup("'any'");
15098 else if ((opts & zeroAsStar) != 0)
15099 return pg_strdup("*");
15100 else if ((opts & zeroAsNone) != 0)
15101 return pg_strdup("NONE");
15102 }
15103
15104 query = createPQExpBuffer();
15105 if (fout->remoteVersion >= 70300)
15106 {
15107 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
15108 oid);
15109 }
15110 else if (fout->remoteVersion >= 70100)
15111 {
15112 appendPQExpBuffer(query, "SELECT format_type('%u'::oid, NULL)",
15113 oid);
15114 }
15115 else
15116 {
15117 appendPQExpBuffer(query, "SELECT typname "
15118 "FROM pg_type "
15119 "WHERE oid = '%u'::oid",
15120 oid);
15121 }
15122
15123 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15124
15125 if (fout->remoteVersion >= 70100)
15126 {
15127
15128 result = pg_strdup(PQgetvalue(res, 0, 0));
15129 }
15130 else
15131 {
15132
15133 result = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
15134 }
15135
15136 PQclear(res);
15137 destroyPQExpBuffer(query);
15138
15139 return result;
15140 }
15141
15142
15143
15144
15145 static char *
15146 myFormatType(const char *typname, int32 typmod)
15147 {
15148 char *result;
15149 bool isarray = false;
15150 PQExpBuffer buf = createPQExpBuffer();
15151
15152
15153 if (typname[0] == '_')
15154 {
15155 isarray = true;
15156 typname++;
15157 }
15158
15159
15160 if (strcmp(typname, "bpchar") == 0)
15161 {
15162 int len = (typmod - VARHDRSZ);
15163
15164 appendPQExpBuffer(buf, "character");
15165 if (len > 1)
15166 appendPQExpBuffer(buf, "(%d)",
15167 typmod - VARHDRSZ);
15168 }
15169 else if (strcmp(typname, "varchar") == 0)
15170 {
15171 appendPQExpBuffer(buf, "character varying");
15172 if (typmod != -1)
15173 appendPQExpBuffer(buf, "(%d)",
15174 typmod - VARHDRSZ);
15175 }
15176 else if (strcmp(typname, "numeric") == 0)
15177 {
15178 appendPQExpBuffer(buf, "numeric");
15179 if (typmod != -1)
15180 {
15181 int32 tmp_typmod;
15182 int precision;
15183 int scale;
15184
15185 tmp_typmod = typmod - VARHDRSZ;
15186 precision = (tmp_typmod >> 16) & 0xffff;
15187 scale = tmp_typmod & 0xffff;
15188 appendPQExpBuffer(buf, "(%d,%d)",
15189 precision, scale);
15190 }
15191 }
15192
15193
15194
15195
15196
15197 else if (strcmp(typname, "char") == 0)
15198 appendPQExpBuffer(buf, "\"char\"");
15199 else
15200 appendPQExpBuffer(buf, "%s", fmtId(typname));
15201
15202
15203 if (isarray)
15204 appendPQExpBuffer(buf, "[]");
15205
15206 result = pg_strdup(buf->data);
15207 destroyPQExpBuffer(buf);
15208
15209 return result;
15210 }
15211
15212
15213
15214
15215
15216
15217
15218 static const char *
15219 fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
15220 {
15221 int numatts = ti->numatts;
15222 char **attnames = ti->attnames;
15223 bool *attisdropped = ti->attisdropped;
15224 bool needComma;
15225 int i;
15226
15227 appendPQExpBuffer(buffer, "(");
15228 needComma = false;
15229 for (i = 0; i < numatts; i++)
15230 {
15231 if (attisdropped[i])
15232 continue;
15233 if (needComma)
15234 appendPQExpBuffer(buffer, ", ");
15235 appendPQExpBuffer(buffer, "%s", fmtId(attnames[i]));
15236 needComma = true;
15237 }
15238
15239 if (!needComma)
15240 return "";
15241
15242 appendPQExpBuffer(buffer, ")");
15243 return buffer->data;
15244 }
15245
15246
15247
15248
15249 static PGresult *
15250 ExecuteSqlQueryForSingleRow(Archive *fout, char *query)
15251 {
15252 PGresult *res;
15253 int ntups;
15254
15255 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
15256
15257
15258 ntups = PQntuples(res);
15259 if (ntups != 1)
15260 exit_horribly(NULL,
15261 ngettext("query returned %d row instead of one: %s\n",
15262 "query returned %d rows instead of one: %s\n",
15263 ntups),
15264 ntups, query);
15265
15266 return res;
15267 }