PostgreSQL Source Code  git master
pg_dump.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_aggregate_d.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_attribute_d.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_cast_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_default_acl_d.h"
#include "catalog/pg_largeobject_d.h"
#include "catalog/pg_largeobject_metadata_d.h"
#include "catalog/pg_proc_d.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_trigger_d.h"
#include "catalog/pg_type_d.h"
#include "common/connect.h"
#include "common/int.h"
#include "common/relpath.h"
#include "compress_io.h"
#include "dumputils.h"
#include "fe_utils/option_utils.h"
#include "fe_utils/string_utils.h"
#include "filter.h"
#include "getopt_long.h"
#include "libpq/libpq-fs.h"
#include "parallel.h"
#include "pg_backup_db.h"
#include "pg_backup_utils.h"
#include "pg_dump.h"
#include "storage/block.h"
Include dependency graph for pg_dump.c:

Go to the source code of this file.

Data Structures

struct  RoleNameItem
 
struct  CommentItem
 
struct  SecLabelItem
 
struct  BinaryUpgradeClassOidItem
 
struct  SequenceItem
 

Macros

#define DUMP_DEFAULT_ROWS_PER_INSERT   1
 
#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000
 
#define fmtQualifiedDumpable(obj)
 

Typedefs

typedef enum SeqType SeqType
 
typedef enum OidOptions OidOptions
 

Enumerations

enum  SeqType { SEQTYPE_SMALLINT , SEQTYPE_INTEGER , SEQTYPE_BIGINT }
 
enum  OidOptions { zeroIsError = 1 , zeroAsStar = 2 , zeroAsNone = 4 }
 

Functions

 StaticAssertDecl (lengthof(SeqTypeNames)==(SEQTYPE_BIGINT+1), "array length mismatch")
 
static void help (const char *progname)
 
static void setup_connection (Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role)
 
static ArchiveFormat parseArchiveFormat (const char *format, ArchiveMode *mode)
 
static void expand_schema_name_patterns (Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
 
static void expand_extension_name_patterns (Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
 
static void expand_foreign_server_name_patterns (Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
 
static void expand_table_name_patterns (Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names, bool with_child_tables)
 
static void prohibit_crossdb_refs (PGconn *conn, const char *dbname, const char *pattern)
 
static NamespaceInfofindNamespace (Oid nsoid)
 
static void dumpTableData (Archive *fout, const TableDataInfo *tdinfo)
 
static void refreshMatViewData (Archive *fout, const TableDataInfo *tdinfo)
 
static const char * getRoleName (const char *roleoid_str)
 
static void collectRoleNames (Archive *fout)
 
static void getAdditionalACLs (Archive *fout)
 
static void dumpCommentExtended (Archive *fout, const char *type, const char *name, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId, const char *initdb_comment)
 
static void dumpComment (Archive *fout, const char *type, const char *name, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId)
 
static int findComments (Oid classoid, Oid objoid, CommentItem **items)
 
static void collectComments (Archive *fout)
 
static void dumpSecLabel (Archive *fout, const char *type, const char *name, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId)
 
static int findSecLabels (Oid classoid, Oid objoid, SecLabelItem **items)
 
static void collectSecLabels (Archive *fout)
 
static void dumpDumpableObject (Archive *fout, DumpableObject *dobj)
 
static void dumpNamespace (Archive *fout, const NamespaceInfo *nspinfo)
 
static void dumpExtension (Archive *fout, const ExtensionInfo *extinfo)
 
static void dumpType (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpBaseType (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpEnumType (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpRangeType (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpUndefinedType (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpDomain (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpCompositeType (Archive *fout, const TypeInfo *tyinfo)
 
static void dumpCompositeTypeColComments (Archive *fout, const TypeInfo *tyinfo, PGresult *res)
 
static void dumpShellType (Archive *fout, const ShellTypeInfo *stinfo)
 
static void dumpProcLang (Archive *fout, const ProcLangInfo *plang)
 
static void dumpFunc (Archive *fout, const FuncInfo *finfo)
 
static void dumpCast (Archive *fout, const CastInfo *cast)
 
static void dumpTransform (Archive *fout, const TransformInfo *transform)
 
static void dumpOpr (Archive *fout, const OprInfo *oprinfo)
 
static void dumpAccessMethod (Archive *fout, const AccessMethodInfo *aminfo)
 
static void dumpOpclass (Archive *fout, const OpclassInfo *opcinfo)
 
static void dumpOpfamily (Archive *fout, const OpfamilyInfo *opfinfo)
 
static void dumpCollation (Archive *fout, const CollInfo *collinfo)
 
static void dumpConversion (Archive *fout, const ConvInfo *convinfo)
 
static void dumpRule (Archive *fout, const RuleInfo *rinfo)
 
static void dumpAgg (Archive *fout, const AggInfo *agginfo)
 
static void dumpTrigger (Archive *fout, const TriggerInfo *tginfo)
 
static void dumpEventTrigger (Archive *fout, const EventTriggerInfo *evtinfo)
 
static void dumpTable (Archive *fout, const TableInfo *tbinfo)
 
static void dumpTableSchema (Archive *fout, const TableInfo *tbinfo)
 
static void dumpTableAttach (Archive *fout, const TableAttachInfo *attachinfo)
 
static void dumpAttrDef (Archive *fout, const AttrDefInfo *adinfo)
 
static void collectSequences (Archive *fout)
 
static void dumpSequence (Archive *fout, const TableInfo *tbinfo)
 
static void dumpSequenceData (Archive *fout, const TableDataInfo *tdinfo)
 
static void dumpIndex (Archive *fout, const IndxInfo *indxinfo)
 
static void dumpIndexAttach (Archive *fout, const IndexAttachInfo *attachinfo)
 
static void dumpStatisticsExt (Archive *fout, const StatsExtInfo *statsextinfo)
 
static void dumpConstraint (Archive *fout, const ConstraintInfo *coninfo)
 
static void dumpTableConstraintComment (Archive *fout, const ConstraintInfo *coninfo)
 
static void dumpTSParser (Archive *fout, const TSParserInfo *prsinfo)
 
static void dumpTSDictionary (Archive *fout, const TSDictInfo *dictinfo)
 
static void dumpTSTemplate (Archive *fout, const TSTemplateInfo *tmplinfo)
 
static void dumpTSConfig (Archive *fout, const TSConfigInfo *cfginfo)
 
static void dumpForeignDataWrapper (Archive *fout, const FdwInfo *fdwinfo)
 
static void dumpForeignServer (Archive *fout, const ForeignServerInfo *srvinfo)
 
static void dumpUserMappings (Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
 
static void dumpDefaultACL (Archive *fout, const DefaultACLInfo *daclinfo)
 
static DumpId dumpACL (Archive *fout, DumpId objDumpId, DumpId altDumpId, const char *type, const char *name, const char *subname, const char *nspname, const char *tag, const char *owner, const DumpableAcl *dacl)
 
static void getDependencies (Archive *fout)
 
static void BuildArchiveDependencies (Archive *fout)
 
static void findDumpableDependencies (ArchiveHandle *AH, const DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
 
static DumpableObjectcreateBoundaryObjects (void)
 
static void addBoundaryDependencies (DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
 
static void addConstrChildIdxDeps (DumpableObject *dobj, const IndxInfo *refidx)
 
static void getDomainConstraints (Archive *fout, TypeInfo *tyinfo)
 
static void getTableData (DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
 
static void makeTableDataInfo (DumpOptions *dopt, TableInfo *tbinfo)
 
static void buildMatViewRefreshDependencies (Archive *fout)
 
static void getTableDataFKConstraints (void)
 
static char * format_function_arguments (const FuncInfo *finfo, const char *funcargs, bool is_agg)
 
static char * format_function_signature (Archive *fout, const FuncInfo *finfo, bool honor_quotes)
 
static char * convertRegProcReference (const char *proc)
 
static char * getFormattedOperatorName (const char *oproid)
 
static char * convertTSFunction (Archive *fout, Oid funcOid)
 
static const char * getFormattedTypeName (Archive *fout, Oid oid, OidOptions opts)
 
static void getLOs (Archive *fout)
 
static void dumpLO (Archive *fout, const LoInfo *loinfo)
 
static int dumpLOs (Archive *fout, const void *arg)
 
static void dumpPolicy (Archive *fout, const PolicyInfo *polinfo)
 
static void dumpPublication (Archive *fout, const PublicationInfo *pubinfo)
 
static void dumpPublicationTable (Archive *fout, const PublicationRelInfo *pubrinfo)
 
static void dumpSubscription (Archive *fout, const SubscriptionInfo *subinfo)
 
static void dumpSubscriptionTable (Archive *fout, const SubRelInfo *subrinfo)
 
static void dumpDatabase (Archive *fout)
 
static void dumpDatabaseConfig (Archive *AH, PQExpBuffer outbuf, const char *dbname, Oid dboid)
 
static void dumpEncoding (Archive *AH)
 
static void dumpStdStrings (Archive *AH)
 
static void dumpSearchPath (Archive *AH)
 
static void binary_upgrade_set_type_oids_by_type_oid (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_type_oid, bool force_array_type, bool include_multirange_type)
 
static void binary_upgrade_set_type_oids_by_rel (Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tbinfo)
 
static void collectBinaryUpgradeClassOids (Archive *fout)
 
static void binary_upgrade_set_pg_class_oids (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid)
 
static void binary_upgrade_extension_member (PQExpBuffer upgrade_buffer, const DumpableObject *dobj, const char *objtype, const char *objname, const char *objnamespace)
 
static const char * getAttrName (int attrnum, const TableInfo *tblInfo)
 
static const char * fmtCopyColumnList (const TableInfo *ti, PQExpBuffer buffer)
 
static bool nonemptyReloptions (const char *reloptions)
 
static void appendReloptionsArrayAH (PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
 
static char * get_synchronized_snapshot (Archive *fout)
 
static void set_restrict_relation_kind (Archive *AH, const char *value)
 
static void setupDumpWorker (Archive *AH)
 
static TableInfogetRootTableInfo (const TableInfo *tbinfo)
 
static bool forcePartitionRootLoad (const TableInfo *tbinfo)
 
static void read_dump_filters (const char *filename, DumpOptions *dopt)
 
int main (int argc, char **argv)
 
static bool checkExtensionMembership (DumpableObject *dobj, Archive *fout)
 
static void selectDumpableNamespace (NamespaceInfo *nsinfo, Archive *fout)
 
static void selectDumpableTable (TableInfo *tbinfo, Archive *fout)
 
static void selectDumpableType (TypeInfo *tyinfo, Archive *fout)
 
static void selectDumpableDefaultACL (DefaultACLInfo *dinfo, DumpOptions *dopt)
 
static void selectDumpableCast (CastInfo *cast, Archive *fout)
 
static void selectDumpableProcLang (ProcLangInfo *plang, Archive *fout)
 
static void selectDumpableAccessMethod (AccessMethodInfo *method, Archive *fout)
 
static void selectDumpableExtension (ExtensionInfo *extinfo, DumpOptions *dopt)
 
static void selectDumpablePublicationObject (DumpableObject *dobj, Archive *fout)
 
static void selectDumpableStatisticsObject (StatsExtInfo *sobj, Archive *fout)
 
static void selectDumpableObject (DumpableObject *dobj, Archive *fout)
 
static int dumpTableData_copy (Archive *fout, const void *dcontext)
 
static int dumpTableData_insert (Archive *fout, const void *dcontext)
 
void getPolicies (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getPublications (Archive *fout)
 
void getPublicationNamespaces (Archive *fout)
 
void getPublicationTables (Archive *fout, TableInfo tblinfo[], int numTables)
 
static void dumpPublicationNamespace (Archive *fout, const PublicationSchemaInfo *pubsinfo)
 
static bool is_superuser (Archive *fout)
 
void getSubscriptions (Archive *fout)
 
void getSubscriptionTables (Archive *fout)
 
static void append_depends_on_extension (Archive *fout, PQExpBuffer create, const DumpableObject *dobj, const char *catalog, const char *keyword, const char *objname)
 
static Oid get_next_possible_free_pg_type_oid (Archive *fout, PQExpBuffer upgrade_query)
 
static int BinaryUpgradeClassOidItemCmp (const void *p1, const void *p2)
 
void getNamespaces (Archive *fout)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
void getTypes (Archive *fout)
 
void getOperators (Archive *fout)
 
void getCollations (Archive *fout)
 
void getConversions (Archive *fout)
 
void getAccessMethods (Archive *fout)
 
void getOpclasses (Archive *fout)
 
void getOpfamilies (Archive *fout)
 
void getAggregates (Archive *fout)
 
void getFuncs (Archive *fout)
 
TableInfogetTables (Archive *fout, int *numTables)
 
void getOwnedSeqs (Archive *fout, TableInfo tblinfo[], int numTables)
 
InhInfogetInherits (Archive *fout, int *numInherits)
 
void getPartitioningInfo (Archive *fout)
 
void getIndexes (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getExtendedStatistics (Archive *fout)
 
void getConstraints (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getRules (Archive *fout)
 
void getTriggers (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getEventTriggers (Archive *fout)
 
void getProcLangs (Archive *fout)
 
void getCasts (Archive *fout)
 
static char * get_language_name (Archive *fout, Oid langid)
 
void getTransforms (Archive *fout)
 
void getTableAttrs (Archive *fout, TableInfo *tblinfo, int numTables)
 
bool shouldPrintColumn (const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
 
void getTSParsers (Archive *fout)
 
void getTSDictionaries (Archive *fout)
 
void getTSTemplates (Archive *fout)
 
void getTSConfigurations (Archive *fout)
 
void getForeignDataWrappers (Archive *fout)
 
void getForeignServers (Archive *fout)
 
void getDefaultACLs (Archive *fout)
 
static void dumpTableComment (Archive *fout, const TableInfo *tbinfo, const char *reltypename)
 
static char * format_aggregate_signature (const AggInfo *agginfo, Archive *fout, bool honor_quotes)
 
static void dumpTableSecLabel (Archive *fout, const TableInfo *tbinfo, const char *reltypename)
 
static PQExpBuffer createViewAsClause (Archive *fout, const TableInfo *tbinfo)
 
static PQExpBuffer createDummyViewAsClause (Archive *fout, const TableInfo *tbinfo)
 
static SeqType parse_sequence_type (const char *name)
 
static int SequenceItemCmp (const void *p1, const void *p2)
 
void getExtensionMembership (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void processExtensionTables (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 

Variables

static const char *const SeqTypeNames []
 
static bool dosync = true
 
static Oid g_last_builtin_oid
 
static int strict_names = 0
 
static pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE
 
static SimpleStringList schema_include_patterns = {NULL, NULL}
 
static SimpleOidList schema_include_oids = {NULL, NULL}
 
static SimpleStringList schema_exclude_patterns = {NULL, NULL}
 
static SimpleOidList schema_exclude_oids = {NULL, NULL}
 
static SimpleStringList table_include_patterns = {NULL, NULL}
 
static SimpleStringList table_include_patterns_and_children = {NULL, NULL}
 
static SimpleOidList table_include_oids = {NULL, NULL}
 
static SimpleStringList table_exclude_patterns = {NULL, NULL}
 
static SimpleStringList table_exclude_patterns_and_children = {NULL, NULL}
 
static SimpleOidList table_exclude_oids = {NULL, NULL}
 
static SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
 
static SimpleStringList tabledata_exclude_patterns_and_children = {NULL, NULL}
 
static SimpleOidList tabledata_exclude_oids = {NULL, NULL}
 
static SimpleStringList foreign_servers_include_patterns = {NULL, NULL}
 
static SimpleOidList foreign_servers_include_oids = {NULL, NULL}
 
static SimpleStringList extension_include_patterns = {NULL, NULL}
 
static SimpleOidList extension_include_oids = {NULL, NULL}
 
static SimpleStringList extension_exclude_patterns = {NULL, NULL}
 
static SimpleOidList extension_exclude_oids = {NULL, NULL}
 
static const CatalogId nilCatalogId = {0, 0}
 
static bool have_extra_float_digits = false
 
static int extra_float_digits
 
static RoleNameItemrolenames = NULL
 
static int nrolenames = 0
 
static CommentItemcomments = NULL
 
static int ncomments = 0
 
static SecLabelItemseclabels = NULL
 
static int nseclabels = 0
 
static BinaryUpgradeClassOidItembinaryUpgradeClassOids = NULL
 
static int nbinaryUpgradeClassOids = 0
 
static SequenceItemsequences = NULL
 
static int nsequences = 0
 

Macro Definition Documentation

◆ DUMP_DEFAULT_ROWS_PER_INSERT

#define DUMP_DEFAULT_ROWS_PER_INSERT   1

Definition at line 216 of file pg_dump.c.

◆ fmtQualifiedDumpable

#define fmtQualifiedDumpable (   obj)
Value:
fmtQualifiedId((obj)->dobj.namespace->dobj.name, \
(obj)->dobj.name)
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145

Definition at line 228 of file pg_dump.c.

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

Definition at line 223 of file pg_dump.c.

Typedef Documentation

◆ OidOptions

typedef enum OidOptions OidOptions

◆ SeqType

typedef enum SeqType SeqType

Enumeration Type Documentation

◆ OidOptions

enum OidOptions
Enumerator
zeroIsError 
zeroAsStar 
zeroAsNone 

Definition at line 139 of file pg_dump.c.

140 {
141  zeroIsError = 1,
142  zeroAsStar = 2,
143  zeroAsNone = 4,
144 } OidOptions;
OidOptions
Definition: pg_dump.c:140
@ zeroIsError
Definition: pg_dump.c:141
@ zeroAsStar
Definition: pg_dump.c:142
@ zeroAsNone
Definition: pg_dump.c:143

◆ SeqType

enum SeqType
Enumerator
SEQTYPE_SMALLINT 
SEQTYPE_INTEGER 
SEQTYPE_BIGINT 

Definition at line 108 of file pg_dump.c.

109 {
113 } SeqType;
SeqType
Definition: pg_dump.c:109
@ SEQTYPE_BIGINT
Definition: pg_dump.c:112
@ SEQTYPE_INTEGER
Definition: pg_dump.c:111
@ SEQTYPE_SMALLINT
Definition: pg_dump.c:110

Function Documentation

◆ addBoundaryDependencies()

static void addBoundaryDependencies ( DumpableObject **  dobjs,
int  numObjs,
DumpableObject boundaryObjs 
)
static

Definition at line 18616 of file pg_dump.c.

18618 {
18619  DumpableObject *preDataBound = boundaryObjs + 0;
18620  DumpableObject *postDataBound = boundaryObjs + 1;
18621  int i;
18622 
18623  for (i = 0; i < numObjs; i++)
18624  {
18625  DumpableObject *dobj = dobjs[i];
18626 
18627  /*
18628  * The classification of object types here must match the SECTION_xxx
18629  * values assigned during subsequent ArchiveEntry calls!
18630  */
18631  switch (dobj->objType)
18632  {
18633  case DO_NAMESPACE:
18634  case DO_EXTENSION:
18635  case DO_TYPE:
18636  case DO_SHELL_TYPE:
18637  case DO_FUNC:
18638  case DO_AGG:
18639  case DO_OPERATOR:
18640  case DO_ACCESS_METHOD:
18641  case DO_OPCLASS:
18642  case DO_OPFAMILY:
18643  case DO_COLLATION:
18644  case DO_CONVERSION:
18645  case DO_TABLE:
18646  case DO_TABLE_ATTACH:
18647  case DO_ATTRDEF:
18648  case DO_PROCLANG:
18649  case DO_CAST:
18650  case DO_DUMMY_TYPE:
18651  case DO_TSPARSER:
18652  case DO_TSDICT:
18653  case DO_TSTEMPLATE:
18654  case DO_TSCONFIG:
18655  case DO_FDW:
18656  case DO_FOREIGN_SERVER:
18657  case DO_TRANSFORM:
18658  /* Pre-data objects: must come before the pre-data boundary */
18659  addObjectDependency(preDataBound, dobj->dumpId);
18660  break;
18661  case DO_TABLE_DATA:
18662  case DO_SEQUENCE_SET:
18663  case DO_LARGE_OBJECT:
18664  case DO_LARGE_OBJECT_DATA:
18665  /* Data objects: must come between the boundaries */
18666  addObjectDependency(dobj, preDataBound->dumpId);
18667  addObjectDependency(postDataBound, dobj->dumpId);
18668  break;
18669  case DO_INDEX:
18670  case DO_INDEX_ATTACH:
18671  case DO_STATSEXT:
18672  case DO_REFRESH_MATVIEW:
18673  case DO_TRIGGER:
18674  case DO_EVENT_TRIGGER:
18675  case DO_DEFAULT_ACL:
18676  case DO_POLICY:
18677  case DO_PUBLICATION:
18678  case DO_PUBLICATION_REL:
18680  case DO_SUBSCRIPTION:
18681  case DO_SUBSCRIPTION_REL:
18682  /* Post-data objects: must come after the post-data boundary */
18683  addObjectDependency(dobj, postDataBound->dumpId);
18684  break;
18685  case DO_RULE:
18686  /* Rules are post-data, but only if dumped separately */
18687  if (((RuleInfo *) dobj)->separate)
18688  addObjectDependency(dobj, postDataBound->dumpId);
18689  break;
18690  case DO_CONSTRAINT:
18691  case DO_FK_CONSTRAINT:
18692  /* Constraints are post-data, but only if dumped separately */
18693  if (((ConstraintInfo *) dobj)->separate)
18694  addObjectDependency(dobj, postDataBound->dumpId);
18695  break;
18696  case DO_PRE_DATA_BOUNDARY:
18697  /* nothing to do */
18698  break;
18699  case DO_POST_DATA_BOUNDARY:
18700  /* must come after the pre-data boundary */
18701  addObjectDependency(dobj, preDataBound->dumpId);
18702  break;
18703  }
18704  }
18705 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:783
int i
Definition: isn.c:73
@ DO_EVENT_TRIGGER
Definition: pg_dump.h:79
@ DO_REFRESH_MATVIEW
Definition: pg_dump.h:80
@ DO_POLICY
Definition: pg_dump.h:81
@ DO_CAST
Definition: pg_dump.h:63
@ DO_FOREIGN_SERVER
Definition: pg_dump.h:72
@ DO_PRE_DATA_BOUNDARY
Definition: pg_dump.h:77
@ DO_PROCLANG
Definition: pg_dump.h:62
@ DO_TYPE
Definition: pg_dump.h:42
@ DO_INDEX
Definition: pg_dump.h:55
@ DO_COLLATION
Definition: pg_dump.h:50
@ DO_LARGE_OBJECT
Definition: pg_dump.h:75
@ DO_TSCONFIG
Definition: pg_dump.h:70
@ DO_OPERATOR
Definition: pg_dump.h:46
@ DO_FK_CONSTRAINT
Definition: pg_dump.h:61
@ DO_CONSTRAINT
Definition: pg_dump.h:60
@ DO_SUBSCRIPTION
Definition: pg_dump.h:85
@ DO_DEFAULT_ACL
Definition: pg_dump.h:73
@ DO_FDW
Definition: pg_dump.h:71
@ DO_SUBSCRIPTION_REL
Definition: pg_dump.h:86
@ DO_SEQUENCE_SET
Definition: pg_dump.h:65
@ DO_ATTRDEF
Definition: pg_dump.h:54
@ DO_PUBLICATION_REL
Definition: pg_dump.h:83
@ DO_TABLE_ATTACH
Definition: pg_dump.h:53
@ DO_OPCLASS
Definition: pg_dump.h:48
@ DO_INDEX_ATTACH
Definition: pg_dump.h:56
@ DO_TSTEMPLATE
Definition: pg_dump.h:69
@ DO_STATSEXT
Definition: pg_dump.h:57
@ DO_FUNC
Definition: pg_dump.h:44
@ DO_POST_DATA_BOUNDARY
Definition: pg_dump.h:78
@ DO_LARGE_OBJECT_DATA
Definition: pg_dump.h:76
@ DO_OPFAMILY
Definition: pg_dump.h:49
@ DO_TRANSFORM
Definition: pg_dump.h:74
@ DO_ACCESS_METHOD
Definition: pg_dump.h:47
@ DO_PUBLICATION_TABLE_IN_SCHEMA
Definition: pg_dump.h:84
@ DO_CONVERSION
Definition: pg_dump.h:51
@ DO_TRIGGER
Definition: pg_dump.h:59
@ DO_RULE
Definition: pg_dump.h:58
@ DO_DUMMY_TYPE
Definition: pg_dump.h:66
@ DO_TSDICT
Definition: pg_dump.h:68
@ DO_TSPARSER
Definition: pg_dump.h:67
@ DO_EXTENSION
Definition: pg_dump.h:41
@ DO_TABLE_DATA
Definition: pg_dump.h:64
@ DO_PUBLICATION
Definition: pg_dump.h:82
@ DO_TABLE
Definition: pg_dump.h:52
@ DO_NAMESPACE
Definition: pg_dump.h:40
@ DO_AGG
Definition: pg_dump.h:45
@ DO_SHELL_TYPE
Definition: pg_dump.h:43
DumpId dumpId
Definition: pg_dump.h:137
DumpableObjectType objType
Definition: pg_dump.h:135

References addObjectDependency(), DO_ACCESS_METHOD, DO_AGG, DO_ATTRDEF, DO_CAST, DO_COLLATION, DO_CONSTRAINT, DO_CONVERSION, DO_DEFAULT_ACL, DO_DUMMY_TYPE, DO_EVENT_TRIGGER, DO_EXTENSION, DO_FDW, DO_FK_CONSTRAINT, DO_FOREIGN_SERVER, DO_FUNC, DO_INDEX, DO_INDEX_ATTACH, DO_LARGE_OBJECT, DO_LARGE_OBJECT_DATA, DO_NAMESPACE, DO_OPCLASS, DO_OPERATOR, DO_OPFAMILY, DO_POLICY, DO_POST_DATA_BOUNDARY, DO_PRE_DATA_BOUNDARY, DO_PROCLANG, DO_PUBLICATION, DO_PUBLICATION_REL, DO_PUBLICATION_TABLE_IN_SCHEMA, DO_REFRESH_MATVIEW, DO_RULE, DO_SEQUENCE_SET, DO_SHELL_TYPE, DO_STATSEXT, DO_SUBSCRIPTION, DO_SUBSCRIPTION_REL, DO_TABLE, DO_TABLE_ATTACH, DO_TABLE_DATA, DO_TRANSFORM, DO_TRIGGER, DO_TSCONFIG, DO_TSDICT, DO_TSPARSER, DO_TSTEMPLATE, DO_TYPE, _dumpableObject::dumpId, i, and _dumpableObject::objType.

Referenced by main().

◆ addConstrChildIdxDeps()

static void addConstrChildIdxDeps ( DumpableObject dobj,
const IndxInfo refidx 
)
static

Definition at line 7961 of file pg_dump.c.

7962 {
7963  SimplePtrListCell *cell;
7964 
7965  Assert(dobj->objType == DO_FK_CONSTRAINT);
7966 
7967  for (cell = refidx->partattaches.head; cell; cell = cell->next)
7968  {
7969  IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
7970 
7971  addObjectDependency(dobj, attach->dobj.dumpId);
7972 
7973  if (attach->partitionIdx->partattaches.head != NULL)
7974  addConstrChildIdxDeps(dobj, attach->partitionIdx);
7975  }
7976 }
#define Assert(condition)
Definition: c.h:861
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:7961
struct SimplePtrListCell * next
Definition: simple_list.h:48
SimplePtrListCell * head
Definition: simple_list.h:54
IndxInfo * partitionIdx
Definition: pg_dump.h:417
DumpableObject dobj
Definition: pg_dump.h:415
SimplePtrList partattaches
Definition: pg_dump.h:407

References addObjectDependency(), Assert, DO_FK_CONSTRAINT, _indexAttachInfo::dobj, _dumpableObject::dumpId, SimplePtrList::head, SimplePtrListCell::next, _dumpableObject::objType, _indxInfo::partattaches, _indexAttachInfo::partitionIdx, and SimplePtrListCell::ptr.

Referenced by getConstraints().

◆ append_depends_on_extension()

static void append_depends_on_extension ( Archive fout,
PQExpBuffer  create,
const DumpableObject dobj,
const char *  catalog,
const char *  keyword,
const char *  objname 
)
static

Definition at line 5331 of file pg_dump.c.

5337 {
5338  if (dobj->depends_on_ext)
5339  {
5340  char *nm;
5341  PGresult *res;
5342  PQExpBuffer query;
5343  int ntups;
5344  int i_extname;
5345  int i;
5346 
5347  /* dodge fmtId() non-reentrancy */
5348  nm = pg_strdup(objname);
5349 
5350  query = createPQExpBuffer();
5351  appendPQExpBuffer(query,
5352  "SELECT e.extname "
5353  "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5354  "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5355  "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5356  "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5357  catalog,
5358  dobj->catId.oid);
5359  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5360  ntups = PQntuples(res);
5361  i_extname = PQfnumber(res, "extname");
5362  for (i = 0; i < ntups; i++)
5363  {
5364  appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5365  keyword, nm,
5366  fmtId(PQgetvalue(res, i, i_extname)));
5367  }
5368 
5369  PQclear(res);
5370  destroyPQExpBuffer(query);
5371  pg_free(nm);
5372  }
5373 }
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3589
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:123
PGresult * ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
Definition: pg_backup_db.c:290
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
CatalogId catId
Definition: pg_dump.h:136
bool depends_on_ext
Definition: pg_dump.h:144

References appendPQExpBuffer(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpableObject::depends_on_ext, destroyPQExpBuffer(), ExecuteSqlQuery(), fmtId(), i, CatalogId::oid, pg_free(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), and res.

Referenced by dumpConstraint(), dumpFunc(), dumpIndex(), dumpTableSchema(), and dumpTrigger().

◆ appendReloptionsArrayAH()

static void appendReloptionsArrayAH ( PQExpBuffer  buffer,
const char *  reloptions,
const char *  prefix,
Archive fout 
)
static

Definition at line 18933 of file pg_dump.c.

18935 {
18936  bool res;
18937 
18938  res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
18939  fout->std_strings);
18940  if (!res)
18941  pg_log_warning("could not parse %s array", "reloptions");
18942 }
#define pg_log_warning(...)
Definition: pgfnames.c:24
bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, const char *prefix, int encoding, bool std_strings)
Definition: string_utils.c:804
bool std_strings
Definition: pg_backup.h:231
int encoding
Definition: pg_backup.h:230

References appendReloptionsArray(), Archive::encoding, pg_log_warning, res, and Archive::std_strings.

Referenced by dumpConstraint(), dumpRule(), and dumpTableSchema().

◆ binary_upgrade_extension_member()

static void binary_upgrade_extension_member ( PQExpBuffer  upgrade_buffer,
const DumpableObject dobj,
const char *  objtype,
const char *  objname,
const char *  objnamespace 
)
static

Definition at line 5642 of file pg_dump.c.

5647 {
5648  DumpableObject *extobj = NULL;
5649  int i;
5650 
5651  if (!dobj->ext_member)
5652  return;
5653 
5654  /*
5655  * Find the parent extension. We could avoid this search if we wanted to
5656  * add a link field to DumpableObject, but the space costs of that would
5657  * be considerable. We assume that member objects could only have a
5658  * direct dependency on their own extension, not any others.
5659  */
5660  for (i = 0; i < dobj->nDeps; i++)
5661  {
5662  extobj = findObjectByDumpId(dobj->dependencies[i]);
5663  if (extobj && extobj->objType == DO_EXTENSION)
5664  break;
5665  extobj = NULL;
5666  }
5667  if (extobj == NULL)
5668  pg_fatal("could not find parent extension for %s %s",
5669  objtype, objname);
5670 
5671  appendPQExpBufferStr(upgrade_buffer,
5672  "\n-- For binary upgrade, handle extension membership the hard way\n");
5673  appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5674  fmtId(extobj->name),
5675  objtype);
5676  if (objnamespace && *objnamespace)
5677  appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5678  appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5679 }
DumpableObject * findObjectByDumpId(DumpId dumpId)
Definition: common.c:730
#define pg_fatal(...)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
char * name
Definition: pg_dump.h:138
DumpId * dependencies
Definition: pg_dump.h:145
bool ext_member
Definition: pg_dump.h:143

References appendPQExpBuffer(), appendPQExpBufferStr(), _dumpableObject::dependencies, DO_EXTENSION, _dumpableObject::ext_member, findObjectByDumpId(), fmtId(), i, _dumpableObject::name, _dumpableObject::nDeps, _dumpableObject::objType, and pg_fatal.

Referenced by dumpAccessMethod(), dumpAgg(), dumpBaseType(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpConversion(), dumpDomain(), dumpEnumType(), dumpEventTrigger(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRangeType(), dumpSequence(), dumpTableSchema(), dumpTransform(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), and dumpUndefinedType().

◆ binary_upgrade_set_pg_class_oids()

static void binary_upgrade_set_pg_class_oids ( Archive fout,
PQExpBuffer  upgrade_buffer,
Oid  pg_class_oid 
)
static

Definition at line 5552 of file pg_dump.c.

5554 {
5557 
5559 
5560  /*
5561  * Preserve the OID and relfilenumber of the table, table's index, table's
5562  * toast table and toast table's index if any.
5563  *
5564  * One complexity is that the current table definition might not require
5565  * the creation of a TOAST table, but the old database might have a TOAST
5566  * table that was created earlier, before some wide columns were dropped.
5567  * By setting the TOAST oid we force creation of the TOAST heap and index
5568  * by the new backend, so we can copy the files during binary upgrade
5569  * without worrying about this case.
5570  */
5571  key.oid = pg_class_oid;
5573  sizeof(BinaryUpgradeClassOidItem),
5575 
5576  appendPQExpBufferStr(upgrade_buffer,
5577  "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5578 
5579  if (entry->relkind != RELKIND_INDEX &&
5580  entry->relkind != RELKIND_PARTITIONED_INDEX)
5581  {
5582  appendPQExpBuffer(upgrade_buffer,
5583  "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5584  pg_class_oid);
5585 
5586  /*
5587  * Not every relation has storage. Also, in a pre-v12 database,
5588  * partitioned tables have a relfilenumber, which should not be
5589  * preserved when upgrading.
5590  */
5591  if (RelFileNumberIsValid(entry->relfilenumber) &&
5592  entry->relkind != RELKIND_PARTITIONED_TABLE)
5593  appendPQExpBuffer(upgrade_buffer,
5594  "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5595  entry->relfilenumber);
5596 
5597  /*
5598  * In a pre-v12 database, partitioned tables might be marked as having
5599  * toast tables, but we should ignore them if so.
5600  */
5601  if (OidIsValid(entry->toast_oid) &&
5602  entry->relkind != RELKIND_PARTITIONED_TABLE)
5603  {
5604  appendPQExpBuffer(upgrade_buffer,
5605  "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5606  entry->toast_oid);
5607  appendPQExpBuffer(upgrade_buffer,
5608  "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5609  entry->toast_relfilenumber);
5610 
5611  /* every toast table has an index */
5612  appendPQExpBuffer(upgrade_buffer,
5613  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5614  entry->toast_index_oid);
5615  appendPQExpBuffer(upgrade_buffer,
5616  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5617  entry->toast_index_relfilenumber);
5618  }
5619  }
5620  else
5621  {
5622  /* Preserve the OID and relfilenumber of the index */
5623  appendPQExpBuffer(upgrade_buffer,
5624  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5625  pg_class_oid);
5626  appendPQExpBuffer(upgrade_buffer,
5627  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5628  entry->relfilenumber);
5629  }
5630 
5631  appendPQExpBufferChar(upgrade_buffer, '\n');
5632 }
#define OidIsValid(objectId)
Definition: c.h:778
static int nbinaryUpgradeClassOids
Definition: pg_dump.c:206
static BinaryUpgradeClassOidItem * binaryUpgradeClassOids
Definition: pg_dump.c:205
static int BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:5502
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
#define RelFileNumberIsValid(relnumber)
Definition: relpath.h:27
RelFileNumber toast_index_relfilenumber
Definition: pg_dump.c:104
RelFileNumber toast_relfilenumber
Definition: pg_dump.c:102
RelFileNumber relfilenumber
Definition: pg_dump.c:100

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), Assert, BinaryUpgradeClassOidItemCmp(), binaryUpgradeClassOids, sort-test::key, nbinaryUpgradeClassOids, OidIsValid, BinaryUpgradeClassOidItem::relfilenumber, RelFileNumberIsValid, BinaryUpgradeClassOidItem::relkind, BinaryUpgradeClassOidItem::toast_index_oid, BinaryUpgradeClassOidItem::toast_index_relfilenumber, BinaryUpgradeClassOidItem::toast_oid, and BinaryUpgradeClassOidItem::toast_relfilenumber.

Referenced by dumpCompositeType(), dumpConstraint(), dumpIndex(), dumpSequence(), and dumpTableSchema().

◆ binary_upgrade_set_type_oids_by_rel()

static void binary_upgrade_set_type_oids_by_rel ( Archive fout,
PQExpBuffer  upgrade_buffer,
const TableInfo tbinfo 
)
static

Definition at line 5487 of file pg_dump.c.

5490 {
5491  Oid pg_type_oid = tbinfo->reltype;
5492 
5493  if (OidIsValid(pg_type_oid))
5494  binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5495  pg_type_oid, false, false);
5496 }
static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_type_oid, bool force_array_type, bool include_multirange_type)
Definition: pg_dump.c:5407
unsigned int Oid
Definition: postgres_ext.h:31
Oid reltype
Definition: pg_dump.h:310

References binary_upgrade_set_type_oids_by_type_oid(), OidIsValid, and _tableInfo::reltype.

Referenced by dumpTableSchema().

◆ binary_upgrade_set_type_oids_by_type_oid()

static void binary_upgrade_set_type_oids_by_type_oid ( Archive fout,
PQExpBuffer  upgrade_buffer,
Oid  pg_type_oid,
bool  force_array_type,
bool  include_multirange_type 
)
static

Definition at line 5407 of file pg_dump.c.

5412 {
5413  PQExpBuffer upgrade_query = createPQExpBuffer();
5414  PGresult *res;
5415  Oid pg_type_array_oid;
5416  Oid pg_type_multirange_oid;
5417  Oid pg_type_multirange_array_oid;
5418  TypeInfo *tinfo;
5419 
5420  appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5421  appendPQExpBuffer(upgrade_buffer,
5422  "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5423  pg_type_oid);
5424 
5425  tinfo = findTypeByOid(pg_type_oid);
5426  if (tinfo)
5427  pg_type_array_oid = tinfo->typarray;
5428  else
5429  pg_type_array_oid = InvalidOid;
5430 
5431  if (!OidIsValid(pg_type_array_oid) && force_array_type)
5432  pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5433 
5434  if (OidIsValid(pg_type_array_oid))
5435  {
5436  appendPQExpBufferStr(upgrade_buffer,
5437  "\n-- For binary upgrade, must preserve pg_type array oid\n");
5438  appendPQExpBuffer(upgrade_buffer,
5439  "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5440  pg_type_array_oid);
5441  }
5442 
5443  /*
5444  * Pre-set the multirange type oid and its own array type oid.
5445  */
5446  if (include_multirange_type)
5447  {
5448  if (fout->remoteVersion >= 140000)
5449  {
5450  printfPQExpBuffer(upgrade_query,
5451  "SELECT t.oid, t.typarray "
5452  "FROM pg_catalog.pg_type t "
5453  "JOIN pg_catalog.pg_range r "
5454  "ON t.oid = r.rngmultitypid "
5455  "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5456  pg_type_oid);
5457 
5458  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5459 
5460  pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5461  pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5462 
5463  PQclear(res);
5464  }
5465  else
5466  {
5467  pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5468  pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5469  }
5470 
5471  appendPQExpBufferStr(upgrade_buffer,
5472  "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5473  appendPQExpBuffer(upgrade_buffer,
5474  "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5475  pg_type_multirange_oid);
5476  appendPQExpBufferStr(upgrade_buffer,
5477  "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5478  appendPQExpBuffer(upgrade_buffer,
5479  "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5480  pg_type_multirange_array_oid);
5481  }
5482 
5483  destroyPQExpBuffer(upgrade_query);
5484 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:864
static const gbtree_vinfo tinfo
Definition: btree_bit.c:109
PGresult * ExecuteSqlQueryForSingleRow(Archive *fout, const char *query)
Definition: pg_backup_db.c:305
static Oid get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
Definition: pg_dump.c:5376
#define InvalidOid
Definition: postgres_ext.h:36
#define atooid(x)
Definition: postgres_ext.h:42
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
int remoteVersion
Definition: pg_backup.h:220

References appendPQExpBuffer(), appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), findTypeByOid(), get_next_possible_free_pg_type_oid(), InvalidOid, OidIsValid, PQclear(), PQfnumber(), PQgetvalue(), printfPQExpBuffer(), Archive::remoteVersion, res, and tinfo.

Referenced by binary_upgrade_set_type_oids_by_rel(), dumpBaseType(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpRangeType(), dumpShellType(), and dumpUndefinedType().

◆ BinaryUpgradeClassOidItemCmp()

static int BinaryUpgradeClassOidItemCmp ( const void *  p1,
const void *  p2 
)
static

Definition at line 5502 of file pg_dump.c.

5503 {
5506 
5507  return pg_cmp_u32(v1.oid, v2.oid);
5508 }
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:604

References BinaryUpgradeClassOidItem::oid, p2, and pg_cmp_u32().

Referenced by binary_upgrade_set_pg_class_oids().

◆ BuildArchiveDependencies()

static void BuildArchiveDependencies ( Archive fout)
static

Definition at line 18732 of file pg_dump.c.

18733 {
18734  ArchiveHandle *AH = (ArchiveHandle *) fout;
18735  TocEntry *te;
18736 
18737  /* Scan all TOC entries in the archive */
18738  for (te = AH->toc->next; te != AH->toc; te = te->next)
18739  {
18740  DumpableObject *dobj;
18741  DumpId *dependencies;
18742  int nDeps;
18743  int allocDeps;
18744 
18745  /* No need to process entries that will not be dumped */
18746  if (te->reqs == 0)
18747  continue;
18748  /* Ignore entries that already have "special" dependencies */
18749  if (te->nDeps > 0)
18750  continue;
18751  /* Otherwise, look up the item's original DumpableObject, if any */
18752  dobj = findObjectByDumpId(te->dumpId);
18753  if (dobj == NULL)
18754  continue;
18755  /* No work if it has no dependencies */
18756  if (dobj->nDeps <= 0)
18757  continue;
18758  /* Set up work array */
18759  allocDeps = 64;
18760  dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
18761  nDeps = 0;
18762  /* Recursively find all dumpable dependencies */
18763  findDumpableDependencies(AH, dobj,
18764  &dependencies, &nDeps, &allocDeps);
18765  /* And save 'em ... */
18766  if (nDeps > 0)
18767  {
18768  dependencies = (DumpId *) pg_realloc(dependencies,
18769  nDeps * sizeof(DumpId));
18770  te->dependencies = dependencies;
18771  te->nDeps = nDeps;
18772  }
18773  else
18774  free(dependencies);
18775  }
18776 }
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define free(a)
Definition: header.h:65
int DumpId
Definition: pg_backup.h:271
static void findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
Definition: pg_dump.c:18780
struct _tocEntry * toc
struct _tocEntry * next
DumpId * dependencies

References _tocEntry::dependencies, _tocEntry::dumpId, findDumpableDependencies(), findObjectByDumpId(), free, _tocEntry::nDeps, _dumpableObject::nDeps, _tocEntry::next, pg_malloc(), pg_realloc(), _tocEntry::reqs, and _archiveHandle::toc.

Referenced by main().

◆ buildMatViewRefreshDependencies()

static void buildMatViewRefreshDependencies ( Archive fout)
static

Definition at line 2927 of file pg_dump.c.

2928 {
2929  PQExpBuffer query;
2930  PGresult *res;
2931  int ntups,
2932  i;
2933  int i_classid,
2934  i_objid,
2935  i_refobjid;
2936 
2937  /* No Mat Views before 9.3. */
2938  if (fout->remoteVersion < 90300)
2939  return;
2940 
2941  query = createPQExpBuffer();
2942 
2943  appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
2944  "( "
2945  "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
2946  "FROM pg_depend d1 "
2947  "JOIN pg_class c1 ON c1.oid = d1.objid "
2948  "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
2949  " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
2950  "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
2951  "AND d2.objid = r1.oid "
2952  "AND d2.refobjid <> d1.objid "
2953  "JOIN pg_class c2 ON c2.oid = d2.refobjid "
2954  "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
2955  CppAsString2(RELKIND_VIEW) ") "
2956  "WHERE d1.classid = 'pg_class'::regclass "
2957  "UNION "
2958  "SELECT w.objid, d3.refobjid, c3.relkind "
2959  "FROM w "
2960  "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
2961  "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
2962  "AND d3.objid = r3.oid "
2963  "AND d3.refobjid <> w.refobjid "
2964  "JOIN pg_class c3 ON c3.oid = d3.refobjid "
2965  "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
2966  CppAsString2(RELKIND_VIEW) ") "
2967  ") "
2968  "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
2969  "FROM w "
2970  "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
2971 
2972  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
2973 
2974  ntups = PQntuples(res);
2975 
2976  i_classid = PQfnumber(res, "classid");
2977  i_objid = PQfnumber(res, "objid");
2978  i_refobjid = PQfnumber(res, "refobjid");
2979 
2980  for (i = 0; i < ntups; i++)
2981  {
2982  CatalogId objId;
2983  CatalogId refobjId;
2984  DumpableObject *dobj;
2985  DumpableObject *refdobj;
2986  TableInfo *tbinfo;
2987  TableInfo *reftbinfo;
2988 
2989  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
2990  objId.oid = atooid(PQgetvalue(res, i, i_objid));
2991  refobjId.tableoid = objId.tableoid;
2992  refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
2993 
2994  dobj = findObjectByCatalogId(objId);
2995  if (dobj == NULL)
2996  continue;
2997 
2998  Assert(dobj->objType == DO_TABLE);
2999  tbinfo = (TableInfo *) dobj;
3000  Assert(tbinfo->relkind == RELKIND_MATVIEW);
3001  dobj = (DumpableObject *) tbinfo->dataObj;
3002  if (dobj == NULL)
3003  continue;
3004  Assert(dobj->objType == DO_REFRESH_MATVIEW);
3005 
3006  refdobj = findObjectByCatalogId(refobjId);
3007  if (refdobj == NULL)
3008  continue;
3009 
3010  Assert(refdobj->objType == DO_TABLE);
3011  reftbinfo = (TableInfo *) refdobj;
3012  Assert(reftbinfo->relkind == RELKIND_MATVIEW);
3013  refdobj = (DumpableObject *) reftbinfo->dataObj;
3014  if (refdobj == NULL)
3015  continue;
3016  Assert(refdobj->objType == DO_REFRESH_MATVIEW);
3017 
3018  addObjectDependency(dobj, refdobj->dumpId);
3019 
3020  if (!reftbinfo->relispopulated)
3021  tbinfo->relispopulated = false;
3022  }
3023 
3024  PQclear(res);
3025 
3026  destroyPQExpBuffer(query);
3027 }
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:743
#define CppAsString2(x)
Definition: c.h:330
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Oid tableoid
Definition: pg_backup.h:267
bool relispopulated
Definition: pg_dump.h:291
struct _tableDataInfo * dataObj
Definition: pg_dump.h:362
char relkind
Definition: pg_dump.h:289

References addObjectDependency(), appendPQExpBufferStr(), Assert, atooid, CppAsString2, createPQExpBuffer(), PQExpBufferData::data, _tableInfo::dataObj, destroyPQExpBuffer(), DO_REFRESH_MATVIEW, DO_TABLE, _dumpableObject::dumpId, ExecuteSqlQuery(), findObjectByCatalogId(), i, if(), _dumpableObject::objType, CatalogId::oid, PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _tableInfo::relispopulated, _tableInfo::relkind, Archive::remoteVersion, res, and CatalogId::tableoid.

Referenced by main().

◆ checkExtensionMembership()

static bool checkExtensionMembership ( DumpableObject dobj,
Archive fout 
)
static

Definition at line 1772 of file pg_dump.c.

1773 {
1774  ExtensionInfo *ext = findOwningExtension(dobj->catId);
1775 
1776  if (ext == NULL)
1777  return false;
1778 
1779  dobj->ext_member = true;
1780 
1781  /* Record dependency so that getDependencies needn't deal with that */
1782  addObjectDependency(dobj, ext->dobj.dumpId);
1783 
1784  /*
1785  * In 9.6 and above, mark the member object to have any non-initial ACLs
1786  * dumped. (Any initial ACLs will be removed later, using data from
1787  * pg_init_privs, so that we'll dump only the delta from the extension's
1788  * initial setup.)
1789  *
1790  * Prior to 9.6, we do not include any extension member components.
1791  *
1792  * In binary upgrades, we still dump all components of the members
1793  * individually, since the idea is to exactly reproduce the database
1794  * contents rather than replace the extension contents with something
1795  * different.
1796  *
1797  * Note: it might be interesting someday to implement storage and delta
1798  * dumping of extension members' RLS policies and/or security labels.
1799  * However there is a pitfall for RLS policies: trying to dump them
1800  * requires getting a lock on their tables, and the calling user might not
1801  * have privileges for that. We need no lock to examine a table's ACLs,
1802  * so the current feature doesn't have a problem of that sort.
1803  */
1804  if (fout->dopt->binary_upgrade)
1805  dobj->dump = ext->dobj.dump;
1806  else
1807  {
1808  if (fout->remoteVersion < 90600)
1809  dobj->dump = DUMP_COMPONENT_NONE;
1810  else
1811  dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
1812  }
1813 
1814  return true;
1815 }
ExtensionInfo * findOwningExtension(CatalogId catalogId)
Definition: common.c:1034
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:101
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:96
DumpOptions * dopt
Definition: pg_backup.h:215
int binary_upgrade
Definition: pg_backup.h:167
DumpComponents dump
Definition: pg_dump.h:139
DumpComponents dump_contains
Definition: pg_dump.h:141
DumpableObject dobj
Definition: pg_dump.h:181

References addObjectDependency(), _dumpOptions::binary_upgrade, _dumpableObject::catId, _extensionInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, _dumpableObject::dumpId, _dumpableObject::ext_member, findOwningExtension(), and Archive::remoteVersion.

Referenced by selectDumpableAccessMethod(), selectDumpableCast(), selectDumpableNamespace(), selectDumpableObject(), selectDumpableProcLang(), selectDumpablePublicationObject(), selectDumpableStatisticsObject(), selectDumpableTable(), and selectDumpableType().

◆ collectBinaryUpgradeClassOids()

static void collectBinaryUpgradeClassOids ( Archive fout)
static

Definition at line 5518 of file pg_dump.c.

5519 {
5520  PGresult *res;
5521  const char *query;
5522 
5523  query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5524  "ct.relfilenode, i.indexrelid, cti.relfilenode "
5525  "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5526  "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5527  "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5528  "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5529  "ORDER BY c.oid;";
5530 
5531  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5532 
5536 
5537  for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5538  {
5546  }
5547 
5548  PQclear(res);
5549 }

References atooid, binaryUpgradeClassOids, ExecuteSqlQuery(), i, nbinaryUpgradeClassOids, BinaryUpgradeClassOidItem::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), BinaryUpgradeClassOidItem::relfilenumber, BinaryUpgradeClassOidItem::relkind, res, BinaryUpgradeClassOidItem::toast_index_oid, BinaryUpgradeClassOidItem::toast_index_relfilenumber, BinaryUpgradeClassOidItem::toast_oid, and BinaryUpgradeClassOidItem::toast_relfilenumber.

Referenced by main().

◆ collectComments()

static void collectComments ( Archive fout)
static

Definition at line 10313 of file pg_dump.c.

10314 {
10315  PGresult *res;
10316  PQExpBuffer query;
10317  int i_description;
10318  int i_classoid;
10319  int i_objoid;
10320  int i_objsubid;
10321  int ntups;
10322  int i;
10323  DumpableObject *dobj;
10324 
10325  query = createPQExpBuffer();
10326 
10327  appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
10328  "FROM pg_catalog.pg_description "
10329  "ORDER BY classoid, objoid, objsubid");
10330 
10331  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10332 
10333  /* Construct lookup table containing OIDs in numeric form */
10334 
10335  i_description = PQfnumber(res, "description");
10336  i_classoid = PQfnumber(res, "classoid");
10337  i_objoid = PQfnumber(res, "objoid");
10338  i_objsubid = PQfnumber(res, "objsubid");
10339 
10340  ntups = PQntuples(res);
10341 
10342  comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
10343  ncomments = 0;
10344  dobj = NULL;
10345 
10346  for (i = 0; i < ntups; i++)
10347  {
10348  CatalogId objId;
10349  int subid;
10350 
10351  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
10352  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
10353  subid = atoi(PQgetvalue(res, i, i_objsubid));
10354 
10355  /* We needn't remember comments that don't match any dumpable object */
10356  if (dobj == NULL ||
10357  dobj->catId.tableoid != objId.tableoid ||
10358  dobj->catId.oid != objId.oid)
10359  dobj = findObjectByCatalogId(objId);
10360  if (dobj == NULL)
10361  continue;
10362 
10363  /*
10364  * Comments on columns of composite types are linked to the type's
10365  * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
10366  * in the type's own DumpableObject.
10367  */
10368  if (subid != 0 && dobj->objType == DO_TABLE &&
10369  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
10370  {
10371  TypeInfo *cTypeInfo;
10372 
10373  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
10374  if (cTypeInfo)
10375  cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
10376  }
10377  else
10378  dobj->components |= DUMP_COMPONENT_COMMENT;
10379 
10380  comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
10382  comments[ncomments].objoid = objId.oid;
10383  comments[ncomments].objsubid = subid;
10384  ncomments++;
10385  }
10386 
10387  PQclear(res);
10388  destroyPQExpBuffer(query);
10389 }
static int ncomments
Definition: pg_dump.c:198
static CommentItem * comments
Definition: pg_dump.c:197
#define DUMP_COMPONENT_COMMENT
Definition: pg_dump.h:99
Oid classoid
Definition: pg_dump.c:82
Oid objoid
Definition: pg_dump.c:83
int objsubid
Definition: pg_dump.c:84
const char * descr
Definition: pg_dump.c:81
DumpComponents components
Definition: pg_dump.h:142
DumpableObject dobj
Definition: pg_dump.h:191

References appendPQExpBufferStr(), atooid, _dumpableObject::catId, CommentItem::classoid, comments, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, CommentItem::descr, destroyPQExpBuffer(), DO_TABLE, _typeInfo::dobj, DUMP_COMPONENT_COMMENT, ExecuteSqlQuery(), findObjectByCatalogId(), findTypeByOid(), i, ncomments, CommentItem::objoid, CommentItem::objsubid, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, and CatalogId::tableoid.

Referenced by main().

◆ collectRoleNames()

static void collectRoleNames ( Archive fout)
static

Definition at line 9858 of file pg_dump.c.

9859 {
9860  PGresult *res;
9861  const char *query;
9862  int i;
9863 
9864  query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
9865 
9866  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
9867 
9869 
9871 
9872  for (i = 0; i < nrolenames; i++)
9873  {
9876  }
9877 
9878  PQclear(res);
9879 }
static RoleNameItem * rolenames
Definition: pg_dump.c:193
static int nrolenames
Definition: pg_dump.c:194
const char * rolename
Definition: pg_dump.c:76
Oid roleoid
Definition: pg_dump.c:75

References atooid, ExecuteSqlQuery(), i, nrolenames, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), res, RoleNameItem::rolename, rolenames, and RoleNameItem::roleoid.

Referenced by main().

◆ collectSecLabels()

static void collectSecLabels ( Archive fout)
static

Definition at line 15455 of file pg_dump.c.

15456 {
15457  PGresult *res;
15458  PQExpBuffer query;
15459  int i_label;
15460  int i_provider;
15461  int i_classoid;
15462  int i_objoid;
15463  int i_objsubid;
15464  int ntups;
15465  int i;
15466  DumpableObject *dobj;
15467 
15468  query = createPQExpBuffer();
15469 
15470  appendPQExpBufferStr(query,
15471  "SELECT label, provider, classoid, objoid, objsubid "
15472  "FROM pg_catalog.pg_seclabel "
15473  "ORDER BY classoid, objoid, objsubid");
15474 
15475  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15476 
15477  /* Construct lookup table containing OIDs in numeric form */
15478  i_label = PQfnumber(res, "label");
15479  i_provider = PQfnumber(res, "provider");
15480  i_classoid = PQfnumber(res, "classoid");
15481  i_objoid = PQfnumber(res, "objoid");
15482  i_objsubid = PQfnumber(res, "objsubid");
15483 
15484  ntups = PQntuples(res);
15485 
15486  seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
15487  nseclabels = 0;
15488  dobj = NULL;
15489 
15490  for (i = 0; i < ntups; i++)
15491  {
15492  CatalogId objId;
15493  int subid;
15494 
15495  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
15496  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
15497  subid = atoi(PQgetvalue(res, i, i_objsubid));
15498 
15499  /* We needn't remember labels that don't match any dumpable object */
15500  if (dobj == NULL ||
15501  dobj->catId.tableoid != objId.tableoid ||
15502  dobj->catId.oid != objId.oid)
15503  dobj = findObjectByCatalogId(objId);
15504  if (dobj == NULL)
15505  continue;
15506 
15507  /*
15508  * Labels on columns of composite types are linked to the type's
15509  * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
15510  * in the type's own DumpableObject.
15511  */
15512  if (subid != 0 && dobj->objType == DO_TABLE &&
15513  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
15514  {
15515  TypeInfo *cTypeInfo;
15516 
15517  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
15518  if (cTypeInfo)
15519  cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
15520  }
15521  else
15522  dobj->components |= DUMP_COMPONENT_SECLABEL;
15523 
15527  seclabels[nseclabels].objoid = objId.oid;
15528  seclabels[nseclabels].objsubid = subid;
15529  nseclabels++;
15530  }
15531 
15532  PQclear(res);
15533  destroyPQExpBuffer(query);
15534 }
static int nseclabels
Definition: pg_dump.c:202
static SecLabelItem * seclabels
Definition: pg_dump.c:201
#define DUMP_COMPONENT_SECLABEL
Definition: pg_dump.h:100
const char * provider
Definition: pg_dump.c:89
Oid classoid
Definition: pg_dump.c:91
int objsubid
Definition: pg_dump.c:93
const char * label
Definition: pg_dump.c:90
Oid objoid
Definition: pg_dump.c:92

References appendPQExpBufferStr(), atooid, _dumpableObject::catId, SecLabelItem::classoid, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TABLE, _typeInfo::dobj, DUMP_COMPONENT_SECLABEL, ExecuteSqlQuery(), findObjectByCatalogId(), findTypeByOid(), i, SecLabelItem::label, nseclabels, SecLabelItem::objoid, SecLabelItem::objsubid, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), SecLabelItem::provider, res, seclabels, and CatalogId::tableoid.

Referenced by main().

◆ collectSequences()

static void collectSequences ( Archive fout)
static

Definition at line 17395 of file pg_dump.c.

17396 {
17397  PGresult *res;
17398  const char *query;
17399 
17400  /*
17401  * Before Postgres 10, sequence metadata is in the sequence itself. With
17402  * some extra effort, we might be able to use the sorted table for those
17403  * versions, but for now it seems unlikely to be worth it.
17404  *
17405  * Since version 18, we can gather the sequence data in this query with
17406  * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
17407  */
17408  if (fout->remoteVersion < 100000)
17409  return;
17410  else if (fout->remoteVersion < 180000 ||
17411  (fout->dopt->schemaOnly && !fout->dopt->sequence_data))
17412  query = "SELECT seqrelid, format_type(seqtypid, NULL), "
17413  "seqstart, seqincrement, "
17414  "seqmax, seqmin, "
17415  "seqcache, seqcycle, "
17416  "NULL, 'f' "
17417  "FROM pg_catalog.pg_sequence "
17418  "ORDER BY seqrelid";
17419  else
17420  query = "SELECT seqrelid, format_type(seqtypid, NULL), "
17421  "seqstart, seqincrement, "
17422  "seqmax, seqmin, "
17423  "seqcache, seqcycle, "
17424  "last_value, is_called "
17425  "FROM pg_catalog.pg_sequence, "
17426  "pg_get_sequence_data(seqrelid) "
17427  "ORDER BY seqrelid;";
17428 
17429  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
17430 
17433 
17434  for (int i = 0; i < nsequences; i++)
17435  {
17436  sequences[i].oid = atooid(PQgetvalue(res, i, 0));
17438  sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
17439  sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
17440  sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
17441  sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
17442  sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
17443  sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
17444  sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
17445  sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
17446  }
17447 
17448  PQclear(res);
17449 }
#define strtoi64(str, endptr, base)
Definition: c.h:1300
static int nsequences
Definition: pg_dump.c:210
static SeqType parse_sequence_type(const char *name)
Definition: pg_dump.c:17364
static SequenceItem * sequences
Definition: pg_dump.c:209
int64 minv
Definition: pg_dump.c:130
int64 cache
Definition: pg_dump.c:134
int64 startv
Definition: pg_dump.c:132
int64 maxv
Definition: pg_dump.c:131
bool is_called
Definition: pg_dump.c:136
int64 incby
Definition: pg_dump.c:133
int64 last_value
Definition: pg_dump.c:135
SeqType seqtype
Definition: pg_dump.c:128
bool cycled
Definition: pg_dump.c:129
int sequence_data
Definition: pg_backup.h:205
bool schemaOnly
Definition: pg_backup.h:170

References atooid, SequenceItem::cache, SequenceItem::cycled, Archive::dopt, ExecuteSqlQuery(), i, SequenceItem::incby, SequenceItem::is_called, SequenceItem::last_value, SequenceItem::maxv, SequenceItem::minv, nsequences, SequenceItem::oid, parse_sequence_type(), pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _dumpOptions::schemaOnly, SequenceItem::seqtype, _dumpOptions::sequence_data, sequences, SequenceItem::startv, and strtoi64.

Referenced by main().

◆ convertRegProcReference()

static char * convertRegProcReference ( const char *  proc)
static

Definition at line 13005 of file pg_dump.c.

13006 {
13007  char *name;
13008  char *paren;
13009  bool inquote;
13010 
13011  /* In all cases "-" means a null reference */
13012  if (strcmp(proc, "-") == 0)
13013  return NULL;
13014 
13015  name = pg_strdup(proc);
13016  /* find non-double-quoted left paren */
13017  inquote = false;
13018  for (paren = name; *paren; paren++)
13019  {
13020  if (*paren == '(' && !inquote)
13021  {
13022  *paren = '\0';
13023  break;
13024  }
13025  if (*paren == '"')
13026  inquote = !inquote;
13027  }
13028  return name;
13029 }
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

static char * convertTSFunction ( Archive fout,
Oid  funcOid 
)
static

Definition at line 13076 of file pg_dump.c.

13077 {
13078  char *result;
13079  char query[128];
13080  PGresult *res;
13081 
13082  snprintf(query, sizeof(query),
13083  "SELECT '%u'::pg_catalog.regproc", funcOid);
13084  res = ExecuteSqlQueryForSingleRow(fout, query);
13085 
13086  result = pg_strdup(PQgetvalue(res, 0, 0));
13087 
13088  PQclear(res);
13089 
13090  return result;
13091 }
#define snprintf
Definition: port.h:238

References ExecuteSqlQueryForSingleRow(), pg_strdup(), PQclear(), PQgetvalue(), res, and snprintf.

Referenced by dumpTSParser(), and dumpTSTemplate().

◆ createBoundaryObjects()

static DumpableObject * createBoundaryObjects ( void  )
static

Definition at line 18592 of file pg_dump.c.

18593 {
18594  DumpableObject *dobjs;
18595 
18596  dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
18597 
18598  dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
18599  dobjs[0].catId = nilCatalogId;
18600  AssignDumpId(dobjs + 0);
18601  dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
18602 
18603  dobjs[1].objType = DO_POST_DATA_BOUNDARY;
18604  dobjs[1].catId = nilCatalogId;
18605  AssignDumpId(dobjs + 1);
18606  dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
18607 
18608  return dobjs;
18609 }
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:622
static const CatalogId nilCatalogId
Definition: pg_dump.c:186

References AssignDumpId(), _dumpableObject::catId, DO_POST_DATA_BOUNDARY, DO_PRE_DATA_BOUNDARY, _dumpableObject::name, nilCatalogId, _dumpableObject::objType, pg_malloc(), and pg_strdup().

Referenced by main().

◆ createDummyViewAsClause()

static PQExpBuffer createDummyViewAsClause ( Archive fout,
const TableInfo tbinfo 
)
static

Definition at line 15730 of file pg_dump.c.

15731 {
15732  PQExpBuffer result = createPQExpBuffer();
15733  int j;
15734 
15735  appendPQExpBufferStr(result, "SELECT");
15736 
15737  for (j = 0; j < tbinfo->numatts; j++)
15738  {
15739  if (j > 0)
15740  appendPQExpBufferChar(result, ',');
15741  appendPQExpBufferStr(result, "\n ");
15742 
15743  appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
15744 
15745  /*
15746  * Must add collation if not default for the type, because CREATE OR
15747  * REPLACE VIEW won't change it
15748  */
15749  if (OidIsValid(tbinfo->attcollation[j]))
15750  {
15751  CollInfo *coll;
15752 
15753  coll = findCollationByOid(tbinfo->attcollation[j]);
15754  if (coll)
15755  appendPQExpBuffer(result, " COLLATE %s",
15756  fmtQualifiedDumpable(coll));
15757  }
15758 
15759  appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
15760  }
15761 
15762  return result;
15763 }
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:919
int j
Definition: isn.c:74
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:228
int numatts
Definition: pg_dump.h:333
Oid * attcollation
Definition: pg_dump.h:346
char ** atttypnames
Definition: pg_dump.h:335
char ** attnames
Definition: pg_dump.h:334

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), _tableInfo::attcollation, _tableInfo::attnames, _tableInfo::atttypnames, createPQExpBuffer(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, j, _tableInfo::numatts, and OidIsValid.

Referenced by dumpRule(), and dumpTableSchema().

◆ createViewAsClause()

static PQExpBuffer createViewAsClause ( Archive fout,
const TableInfo tbinfo 
)
static

Definition at line 15681 of file pg_dump.c.

15682 {
15683  PQExpBuffer query = createPQExpBuffer();
15684  PQExpBuffer result = createPQExpBuffer();
15685  PGresult *res;
15686  int len;
15687 
15688  /* Fetch the view definition */
15689  appendPQExpBuffer(query,
15690  "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
15691  tbinfo->dobj.catId.oid);
15692 
15693  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15694 
15695  if (PQntuples(res) != 1)
15696  {
15697  if (PQntuples(res) < 1)
15698  pg_fatal("query to obtain definition of view \"%s\" returned no data",
15699  tbinfo->dobj.name);
15700  else
15701  pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
15702  tbinfo->dobj.name);
15703  }
15704 
15705  len = PQgetlength(res, 0, 0);
15706 
15707  if (len == 0)
15708  pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
15709  tbinfo->dobj.name);
15710 
15711  /* Strip off the trailing semicolon so that other things may follow. */
15712  Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
15713  appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
15714 
15715  PQclear(res);
15716  destroyPQExpBuffer(query);
15717 
15718  return result;
15719 }
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3887
const void size_t len
void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
Definition: pqexpbuffer.c:397
DumpableObject dobj
Definition: pg_dump.h:286

References appendBinaryPQExpBuffer(), appendPQExpBuffer(), Assert, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, ExecuteSqlQuery(), len, _dumpableObject::name, CatalogId::oid, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetlength(), PQgetvalue(), PQntuples(), and res.

Referenced by dumpRule(), and dumpTableSchema().

◆ dumpAccessMethod()

static void dumpAccessMethod ( Archive fout,
const AccessMethodInfo aminfo 
)
static

Definition at line 13098 of file pg_dump.c.

13099 {
13100  DumpOptions *dopt = fout->dopt;
13101  PQExpBuffer q;
13102  PQExpBuffer delq;
13103  char *qamname;
13104 
13105  /* Do nothing in data-only dump */
13106  if (dopt->dataOnly)
13107  return;
13108 
13109  q = createPQExpBuffer();
13110  delq = createPQExpBuffer();
13111 
13112  qamname = pg_strdup(fmtId(aminfo->dobj.name));
13113 
13114  appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
13115 
13116  switch (aminfo->amtype)
13117  {
13118  case AMTYPE_INDEX:
13119  appendPQExpBufferStr(q, "TYPE INDEX ");
13120  break;
13121  case AMTYPE_TABLE:
13122  appendPQExpBufferStr(q, "TYPE TABLE ");
13123  break;
13124  default:
13125  pg_log_warning("invalid type \"%c\" of access method \"%s\"",
13126  aminfo->amtype, qamname);
13127  destroyPQExpBuffer(q);
13128  destroyPQExpBuffer(delq);
13129  free(qamname);
13130  return;
13131  }
13132 
13133  appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
13134 
13135  appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
13136  qamname);
13137 
13138  if (dopt->binary_upgrade)
13140  "ACCESS METHOD", qamname, NULL);
13141 
13142  if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13143  ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
13144  ARCHIVE_OPTS(.tag = aminfo->dobj.name,
13145  .description = "ACCESS METHOD",
13146  .section = SECTION_PRE_DATA,
13147  .createStmt = q->data,
13148  .dropStmt = delq->data));
13149 
13150  /* Dump Access Method Comments */
13151  if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13152  dumpComment(fout, "ACCESS METHOD", qamname,
13153  NULL, "",
13154  aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
13155 
13156  destroyPQExpBuffer(q);
13157  destroyPQExpBuffer(delq);
13158  free(qamname);
13159 }
@ SECTION_PRE_DATA
Definition: pg_backup.h:58
TocEntry * ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId, ArchiveOpts *opts)
#define ARCHIVE_OPTS(...)
static void dumpComment(Archive *fout, const char *type, const char *name, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId)
Definition: pg_dump.c:10122
static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer, const DumpableObject *dobj, const char *objtype, const char *objname, const char *objnamespace)
Definition: pg_dump.c:5642
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:97
char * amhandler
Definition: pg_dump.h:254
DumpableObject dobj
Definition: pg_dump.h:252
bool dataOnly
Definition: pg_backup.h:171

References _accessMethodInfo::amhandler, _accessMethodInfo::amtype, appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _accessMethodInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, fmtId(), free, _dumpableObject::name, pg_log_warning, pg_strdup(), and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpACL()

static DumpId dumpACL ( Archive fout,
DumpId  objDumpId,
DumpId  altDumpId,
const char *  type,
const char *  name,
const char *  subname,
const char *  nspname,
const char *  tag,
const char *  owner,
const DumpableAcl dacl 
)
static

Definition at line 15086 of file pg_dump.c.

15090 {
15091  DumpId aclDumpId = InvalidDumpId;
15092  DumpOptions *dopt = fout->dopt;
15093  const char *acls = dacl->acl;
15094  const char *acldefault = dacl->acldefault;
15095  char privtype = dacl->privtype;
15096  const char *initprivs = dacl->initprivs;
15097  const char *baseacls;
15098  PQExpBuffer sql;
15099 
15100  /* Do nothing if ACL dump is not enabled */
15101  if (dopt->aclsSkip)
15102  return InvalidDumpId;
15103 
15104  /* --data-only skips ACLs *except* large object ACLs */
15105  if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15106  return InvalidDumpId;
15107 
15108  sql = createPQExpBuffer();
15109 
15110  /*
15111  * In binary upgrade mode, we don't run an extension's script but instead
15112  * dump out the objects independently and then recreate them. To preserve
15113  * any initial privileges which were set on extension objects, we need to
15114  * compute the set of GRANT and REVOKE commands necessary to get from the
15115  * default privileges of an object to its initial privileges as recorded
15116  * in pg_init_privs.
15117  *
15118  * At restore time, we apply these commands after having called
15119  * binary_upgrade_set_record_init_privs(true). That tells the backend to
15120  * copy the results into pg_init_privs. This is how we preserve the
15121  * contents of that catalog across binary upgrades.
15122  */
15123  if (dopt->binary_upgrade && privtype == 'e' &&
15124  initprivs && *initprivs != '\0')
15125  {
15126  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
15127  if (!buildACLCommands(name, subname, nspname, type,
15128  initprivs, acldefault, owner,
15129  "", fout->remoteVersion, sql))
15130  pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
15131  initprivs, acldefault, name, type);
15132  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
15133  }
15134 
15135  /*
15136  * Now figure the GRANT and REVOKE commands needed to get to the object's
15137  * actual current ACL, starting from the initprivs if given, else from the
15138  * object-type-specific default. Also, while buildACLCommands will assume
15139  * that a NULL/empty acls string means it needn't do anything, what that
15140  * actually represents is the object-type-specific default; so we need to
15141  * substitute the acldefault string to get the right results in that case.
15142  */
15143  if (initprivs && *initprivs != '\0')
15144  {
15145  baseacls = initprivs;
15146  if (acls == NULL || *acls == '\0')
15147  acls = acldefault;
15148  }
15149  else
15150  baseacls = acldefault;
15151 
15152  if (!buildACLCommands(name, subname, nspname, type,
15153  acls, baseacls, owner,
15154  "", fout->remoteVersion, sql))
15155  pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
15156  acls, baseacls, name, type);
15157 
15158  if (sql->len > 0)
15159  {
15160  PQExpBuffer tagbuf = createPQExpBuffer();
15161  DumpId aclDeps[2];
15162  int nDeps = 0;
15163 
15164  if (tag)
15165  appendPQExpBufferStr(tagbuf, tag);
15166  else if (subname)
15167  appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
15168  else
15169  appendPQExpBuffer(tagbuf, "%s %s", type, name);
15170 
15171  aclDeps[nDeps++] = objDumpId;
15172  if (altDumpId != InvalidDumpId)
15173  aclDeps[nDeps++] = altDumpId;
15174 
15175  aclDumpId = createDumpId();
15176 
15177  ArchiveEntry(fout, nilCatalogId, aclDumpId,
15178  ARCHIVE_OPTS(.tag = tagbuf->data,
15179  .namespace = nspname,
15180  .owner = owner,
15181  .description = "ACL",
15182  .section = SECTION_NONE,
15183  .createStmt = sql->data,
15184  .deps = aclDeps,
15185  .nDeps = nDeps));
15186 
15187  destroyPQExpBuffer(tagbuf);
15188  }
15189 
15190  destroyPQExpBuffer(sql);
15191 
15192  return aclDumpId;
15193 }
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:787
DumpId createDumpId(void)
Definition: common.c:710
bool buildACLCommands(const char *name, const char *subname, const char *nspname, const char *type, const char *acls, const char *baseacls, const char *owner, const char *prefix, int remoteVersion, PQExpBuffer sql)
Definition: dumputils.c:64
@ SECTION_NONE
Definition: pg_backup.h:57
#define InvalidDumpId
Definition: pg_backup.h:273
NameData subname
bool aclsSkip
Definition: pg_backup.h:173
char privtype
Definition: pg_dump.h:159
char * acldefault
Definition: pg_dump.h:157
char * acl
Definition: pg_dump.h:156
char * initprivs
Definition: pg_dump.h:160
const char * type

References _dumpableAcl::acl, acldefault(), _dumpableAcl::acldefault, _dumpOptions::aclsSkip, appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, buildACLCommands(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), Archive::dopt, _dumpableAcl::initprivs, InvalidDumpId, PQExpBufferData::len, name, nilCatalogId, pg_fatal, _dumpableAcl::privtype, Archive::remoteVersion, SECTION_NONE, subname, and type.

Referenced by dumpAgg(), dumpBaseType(), dumpCompositeType(), dumpDatabase(), dumpDomain(), dumpEnumType(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpLO(), dumpNamespace(), dumpProcLang(), dumpRangeType(), dumpTable(), and dumpUndefinedType().

◆ dumpAgg()

static void dumpAgg ( Archive fout,
const AggInfo agginfo 
)
static

Definition at line 14051 of file pg_dump.c.

14052 {
14053  DumpOptions *dopt = fout->dopt;
14054  PQExpBuffer query;
14055  PQExpBuffer q;
14056  PQExpBuffer delq;
14057  PQExpBuffer details;
14058  char *aggsig; /* identity signature */
14059  char *aggfullsig = NULL; /* full signature */
14060  char *aggsig_tag;
14061  PGresult *res;
14062  int i_agginitval;
14063  int i_aggminitval;
14064  const char *aggtransfn;
14065  const char *aggfinalfn;
14066  const char *aggcombinefn;
14067  const char *aggserialfn;
14068  const char *aggdeserialfn;
14069  const char *aggmtransfn;
14070  const char *aggminvtransfn;
14071  const char *aggmfinalfn;
14072  bool aggfinalextra;
14073  bool aggmfinalextra;
14074  char aggfinalmodify;
14075  char aggmfinalmodify;
14076  const char *aggsortop;
14077  char *aggsortconvop;
14078  char aggkind;
14079  const char *aggtranstype;
14080  const char *aggtransspace;
14081  const char *aggmtranstype;
14082  const char *aggmtransspace;
14083  const char *agginitval;
14084  const char *aggminitval;
14085  const char *proparallel;
14086  char defaultfinalmodify;
14087 
14088  /* Do nothing in data-only dump */
14089  if (dopt->dataOnly)
14090  return;
14091 
14092  query = createPQExpBuffer();
14093  q = createPQExpBuffer();
14094  delq = createPQExpBuffer();
14095  details = createPQExpBuffer();
14096 
14097  if (!fout->is_prepared[PREPQUERY_DUMPAGG])
14098  {
14099  /* Set up query for aggregate-specific details */
14100  appendPQExpBufferStr(query,
14101  "PREPARE dumpAgg(pg_catalog.oid) AS\n");
14102 
14103  appendPQExpBufferStr(query,
14104  "SELECT "
14105  "aggtransfn,\n"
14106  "aggfinalfn,\n"
14107  "aggtranstype::pg_catalog.regtype,\n"
14108  "agginitval,\n"
14109  "aggsortop,\n"
14110  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
14111  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
14112 
14113  if (fout->remoteVersion >= 90400)
14114  appendPQExpBufferStr(query,
14115  "aggkind,\n"
14116  "aggmtransfn,\n"
14117  "aggminvtransfn,\n"
14118  "aggmfinalfn,\n"
14119  "aggmtranstype::pg_catalog.regtype,\n"
14120  "aggfinalextra,\n"
14121  "aggmfinalextra,\n"
14122  "aggtransspace,\n"
14123  "aggmtransspace,\n"
14124  "aggminitval,\n");
14125  else
14126  appendPQExpBufferStr(query,
14127  "'n' AS aggkind,\n"
14128  "'-' AS aggmtransfn,\n"
14129  "'-' AS aggminvtransfn,\n"
14130  "'-' AS aggmfinalfn,\n"
14131  "0 AS aggmtranstype,\n"
14132  "false AS aggfinalextra,\n"
14133  "false AS aggmfinalextra,\n"
14134  "0 AS aggtransspace,\n"
14135  "0 AS aggmtransspace,\n"
14136  "NULL AS aggminitval,\n");
14137 
14138  if (fout->remoteVersion >= 90600)
14139  appendPQExpBufferStr(query,
14140  "aggcombinefn,\n"
14141  "aggserialfn,\n"
14142  "aggdeserialfn,\n"
14143  "proparallel,\n");
14144  else
14145  appendPQExpBufferStr(query,
14146  "'-' AS aggcombinefn,\n"
14147  "'-' AS aggserialfn,\n"
14148  "'-' AS aggdeserialfn,\n"
14149  "'u' AS proparallel,\n");
14150 
14151  if (fout->remoteVersion >= 110000)
14152  appendPQExpBufferStr(query,
14153  "aggfinalmodify,\n"
14154  "aggmfinalmodify\n");
14155  else
14156  appendPQExpBufferStr(query,
14157  "'0' AS aggfinalmodify,\n"
14158  "'0' AS aggmfinalmodify\n");
14159 
14160  appendPQExpBufferStr(query,
14161  "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
14162  "WHERE a.aggfnoid = p.oid "
14163  "AND p.oid = $1");
14164 
14165  ExecuteSqlStatement(fout, query->data);
14166 
14167  fout->is_prepared[PREPQUERY_DUMPAGG] = true;
14168  }
14169 
14170  printfPQExpBuffer(query,
14171  "EXECUTE dumpAgg('%u')",
14172  agginfo->aggfn.dobj.catId.oid);
14173 
14174  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14175 
14176  i_agginitval = PQfnumber(res, "agginitval");
14177  i_aggminitval = PQfnumber(res, "aggminitval");
14178 
14179  aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
14180  aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
14181  aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
14182  aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
14183  aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
14184  aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
14185  aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
14186  aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
14187  aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
14188  aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
14189  aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
14190  aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
14191  aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
14192  aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
14193  aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
14194  aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
14195  aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
14196  aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
14197  agginitval = PQgetvalue(res, 0, i_agginitval);
14198  aggminitval = PQgetvalue(res, 0, i_aggminitval);
14199  proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
14200 
14201  {
14202  char *funcargs;
14203  char *funciargs;
14204 
14205  funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
14206  funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
14207  aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
14208  aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
14209  }
14210 
14211  aggsig_tag = format_aggregate_signature(agginfo, fout, false);
14212 
14213  /* identify default modify flag for aggkind (must match DefineAggregate) */
14214  defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
14215  /* replace omitted flags for old versions */
14216  if (aggfinalmodify == '0')
14217  aggfinalmodify = defaultfinalmodify;
14218  if (aggmfinalmodify == '0')
14219  aggmfinalmodify = defaultfinalmodify;
14220 
14221  /* regproc and regtype output is already sufficiently quoted */
14222  appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
14223  aggtransfn, aggtranstype);
14224 
14225  if (strcmp(aggtransspace, "0") != 0)
14226  {
14227  appendPQExpBuffer(details, ",\n SSPACE = %s",
14228  aggtransspace);
14229  }
14230 
14231  if (!PQgetisnull(res, 0, i_agginitval))
14232  {
14233  appendPQExpBufferStr(details, ",\n INITCOND = ");
14234  appendStringLiteralAH(details, agginitval, fout);
14235  }
14236 
14237  if (strcmp(aggfinalfn, "-") != 0)
14238  {
14239  appendPQExpBuffer(details, ",\n FINALFUNC = %s",
14240  aggfinalfn);
14241  if (aggfinalextra)
14242  appendPQExpBufferStr(details, ",\n FINALFUNC_EXTRA");
14243  if (aggfinalmodify != defaultfinalmodify)
14244  {
14245  switch (aggfinalmodify)
14246  {
14247  case AGGMODIFY_READ_ONLY:
14248  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_ONLY");
14249  break;
14250  case AGGMODIFY_SHAREABLE:
14251  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHAREABLE");
14252  break;
14253  case AGGMODIFY_READ_WRITE:
14254  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_WRITE");
14255  break;
14256  default:
14257  pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
14258  agginfo->aggfn.dobj.name);
14259  break;
14260  }
14261  }
14262  }
14263 
14264  if (strcmp(aggcombinefn, "-") != 0)
14265  appendPQExpBuffer(details, ",\n COMBINEFUNC = %s", aggcombinefn);
14266 
14267  if (strcmp(aggserialfn, "-") != 0)
14268  appendPQExpBuffer(details, ",\n SERIALFUNC = %s", aggserialfn);
14269 
14270  if (strcmp(aggdeserialfn, "-") != 0)
14271  appendPQExpBuffer(details, ",\n DESERIALFUNC = %s", aggdeserialfn);
14272 
14273  if (strcmp(aggmtransfn, "-") != 0)
14274  {
14275  appendPQExpBuffer(details, ",\n MSFUNC = %s,\n MINVFUNC = %s,\n MSTYPE = %s",
14276  aggmtransfn,
14277  aggminvtransfn,
14278  aggmtranstype);
14279  }
14280 
14281  if (strcmp(aggmtransspace, "0") != 0)
14282  {
14283  appendPQExpBuffer(details, ",\n MSSPACE = %s",
14284  aggmtransspace);
14285  }
14286 
14287  if (!PQgetisnull(res, 0, i_aggminitval))
14288  {
14289  appendPQExpBufferStr(details, ",\n MINITCOND = ");
14290  appendStringLiteralAH(details, aggminitval, fout);
14291  }
14292 
14293  if (strcmp(aggmfinalfn, "-") != 0)
14294  {
14295  appendPQExpBuffer(details, ",\n MFINALFUNC = %s",
14296  aggmfinalfn);
14297  if (aggmfinalextra)
14298  appendPQExpBufferStr(details, ",\n MFINALFUNC_EXTRA");
14299  if (aggmfinalmodify != defaultfinalmodify)
14300  {
14301  switch (aggmfinalmodify)
14302  {
14303  case AGGMODIFY_READ_ONLY:
14304  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_ONLY");
14305  break;
14306  case AGGMODIFY_SHAREABLE:
14307  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHAREABLE");
14308  break;
14309  case AGGMODIFY_READ_WRITE:
14310  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_WRITE");
14311  break;
14312  default:
14313  pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
14314  agginfo->aggfn.dobj.name);
14315  break;
14316  }
14317  }
14318  }
14319 
14320  aggsortconvop = getFormattedOperatorName(aggsortop);
14321  if (aggsortconvop)
14322  {
14323  appendPQExpBuffer(details, ",\n SORTOP = %s",
14324  aggsortconvop);
14325  free(aggsortconvop);
14326  }
14327 
14328  if (aggkind == AGGKIND_HYPOTHETICAL)
14329  appendPQExpBufferStr(details, ",\n HYPOTHETICAL");
14330 
14331  if (proparallel[0] != PROPARALLEL_UNSAFE)
14332  {
14333  if (proparallel[0] == PROPARALLEL_SAFE)
14334  appendPQExpBufferStr(details, ",\n PARALLEL = safe");
14335  else if (proparallel[0] == PROPARALLEL_RESTRICTED)
14336  appendPQExpBufferStr(details, ",\n PARALLEL = restricted");
14337  else if (proparallel[0] != PROPARALLEL_UNSAFE)
14338  pg_fatal("unrecognized proparallel value for function \"%s\"",
14339  agginfo->aggfn.dobj.name);
14340  }
14341 
14342  appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
14343  fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
14344  aggsig);
14345 
14346  appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
14347  fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
14348  aggfullsig ? aggfullsig : aggsig, details->data);
14349 
14350  if (dopt->binary_upgrade)
14351  binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
14352  "AGGREGATE", aggsig,
14353  agginfo->aggfn.dobj.namespace->dobj.name);
14354 
14355  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
14356  ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
14357  agginfo->aggfn.dobj.dumpId,
14358  ARCHIVE_OPTS(.tag = aggsig_tag,
14359  .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
14360  .owner = agginfo->aggfn.rolname,
14361  .description = "AGGREGATE",
14362  .section = SECTION_PRE_DATA,
14363  .createStmt = q->data,
14364  .dropStmt = delq->data));
14365 
14366  /* Dump Aggregate Comments */
14367  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
14368  dumpComment(fout, "AGGREGATE", aggsig,
14369  agginfo->aggfn.dobj.namespace->dobj.name,
14370  agginfo->aggfn.rolname,
14371  agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
14372 
14373  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
14374  dumpSecLabel(fout, "AGGREGATE", aggsig,
14375  agginfo->aggfn.dobj.namespace->dobj.name,
14376  agginfo->aggfn.rolname,
14377  agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
14378 
14379  /*
14380  * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
14381  * command look like a function's GRANT; in particular this affects the
14382  * syntax for zero-argument aggregates and ordered-set aggregates.
14383  */
14384  free(aggsig);
14385 
14386  aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14387 
14388  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14389  dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
14390  "FUNCTION", aggsig, NULL,
14391  agginfo->aggfn.dobj.namespace->dobj.name,
14392  NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
14393 
14394  free(aggsig);
14395  free(aggfullsig);
14396  free(aggsig_tag);
14397 
14398  PQclear(res);
14399 
14400  destroyPQExpBuffer(query);
14401  destroyPQExpBuffer(q);
14402  destroyPQExpBuffer(delq);
14403  destroyPQExpBuffer(details);
14404 }
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
#define appendStringLiteralAH(buf, str, AH)
Definition: pg_backup.h:333
@ PREPQUERY_DUMPAGG
Definition: pg_backup.h:66
void ExecuteSqlStatement(Archive *AHX, const char *query)
Definition: pg_backup_db.c:278
static DumpId dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId, const char *type, const char *name, const char *subname, const char *nspname, const char *tag, const char *owner, const DumpableAcl *dacl)
Definition: pg_dump.c:15086
static char * getFormattedOperatorName(const char *oproid)
Definition: pg_dump.c:13046
static char * format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
Definition: pg_dump.c:12107
static char * format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
Definition: pg_dump.c:14019
static char * format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
Definition: pg_dump.c:12084
static void dumpSecLabel(Archive *fout, const char *type, const char *name, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId)
Definition: pg_dump.c:15214
bool * is_prepared
Definition: pg_backup.h:242

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), Archive::dopt, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), dumpSecLabel(), ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), fmtId(), format_aggregate_signature(), format_function_arguments(), format_function_signature(), free, getFormattedOperatorName(), InvalidDumpId, Archive::is_prepared, pg_fatal, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PREPQUERY_DUMPAGG, printfPQExpBuffer(), Archive::remoteVersion, res, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpAttrDef()

static void dumpAttrDef ( Archive fout,
const AttrDefInfo adinfo 
)
static

Definition at line 16705 of file pg_dump.c.

16706 {
16707  DumpOptions *dopt = fout->dopt;
16708  TableInfo *tbinfo = adinfo->adtable;
16709  int adnum = adinfo->adnum;
16710  PQExpBuffer q;
16711  PQExpBuffer delq;
16712  char *qualrelname;
16713  char *tag;
16714  char *foreign;
16715 
16716  /* Do nothing in data-only dump */
16717  if (dopt->dataOnly)
16718  return;
16719 
16720  /* Skip if not "separate"; it was dumped in the table's definition */
16721  if (!adinfo->separate)
16722  return;
16723 
16724  q = createPQExpBuffer();
16725  delq = createPQExpBuffer();
16726 
16727  qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
16728 
16729  foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
16730 
16732  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
16733  foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
16734  adinfo->adef_expr);
16735 
16736  appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
16737  foreign, qualrelname,
16738  fmtId(tbinfo->attnames[adnum - 1]));
16739 
16740  tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
16741 
16742  if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16743  ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
16744  ARCHIVE_OPTS(.tag = tag,
16745  .namespace = tbinfo->dobj.namespace->dobj.name,
16746  .owner = tbinfo->rolname,
16747  .description = "DEFAULT",
16748  .section = SECTION_PRE_DATA,
16749  .createStmt = q->data,
16750  .dropStmt = delq->data));
16751 
16752  free(tag);
16753  destroyPQExpBuffer(q);
16754  destroyPQExpBuffer(delq);
16755  free(qualrelname);
16756 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
DumpableObject dobj
Definition: pg_dump.h:376
char * adef_expr
Definition: pg_dump.h:379
TableInfo * adtable
Definition: pg_dump.h:377
bool separate
Definition: pg_dump.h:380
const char * rolname
Definition: pg_dump.h:288

References _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _tableInfo::attnames, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _attrDefInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, pg_strdup(), psprintf(), _tableInfo::relkind, _tableInfo::rolname, SECTION_PRE_DATA, and _attrDefInfo::separate.

Referenced by dumpDumpableObject().

◆ dumpBaseType()

static void dumpBaseType ( Archive fout,
const TypeInfo tyinfo 
)
static

Definition at line 11189 of file pg_dump.c.

11190 {
11191  DumpOptions *dopt = fout->dopt;
11193  PQExpBuffer delq = createPQExpBuffer();
11194  PQExpBuffer query = createPQExpBuffer();
11195  PGresult *res;
11196  char *qtypname;
11197  char *qualtypname;
11198  char *typlen;
11199  char *typinput;
11200  char *typoutput;
11201  char *typreceive;
11202  char *typsend;
11203  char *typmodin;
11204  char *typmodout;
11205  char *typanalyze;
11206  char *typsubscript;
11207  Oid typreceiveoid;
11208  Oid typsendoid;
11209  Oid typmodinoid;
11210  Oid typmodoutoid;
11211  Oid typanalyzeoid;
11212  Oid typsubscriptoid;
11213  char *typcategory;
11214  char *typispreferred;
11215  char *typdelim;
11216  char *typbyval;
11217  char *typalign;
11218  char *typstorage;
11219  char *typcollatable;
11220  char *typdefault;
11221  bool typdefault_is_literal = false;
11222 
11223  if (!fout->is_prepared[PREPQUERY_DUMPBASETYPE])
11224  {
11225  /* Set up query for type-specific details */
11226  appendPQExpBufferStr(query,
11227  "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
11228  "SELECT typlen, "
11229  "typinput, typoutput, typreceive, typsend, "
11230  "typreceive::pg_catalog.oid AS typreceiveoid, "
11231  "typsend::pg_catalog.oid AS typsendoid, "
11232  "typanalyze, "
11233  "typanalyze::pg_catalog.oid AS typanalyzeoid, "
11234  "typdelim, typbyval, typalign, typstorage, "
11235  "typmodin, typmodout, "
11236  "typmodin::pg_catalog.oid AS typmodinoid, "
11237  "typmodout::pg_catalog.oid AS typmodoutoid, "
11238  "typcategory, typispreferred, "
11239  "(typcollation <> 0) AS typcollatable, "
11240  "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
11241 
11242  if (fout->remoteVersion >= 140000)
11243  appendPQExpBufferStr(query,
11244  "typsubscript, "
11245  "typsubscript::pg_catalog.oid AS typsubscriptoid ");
11246  else
11247  appendPQExpBufferStr(query,
11248  "'-' AS typsubscript, 0 AS typsubscriptoid ");
11249 
11250  appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
11251  "WHERE oid = $1");
11252 
11253  ExecuteSqlStatement(fout, query->data);
11254 
11255  fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
11256  }
11257 
11258  printfPQExpBuffer(query,
11259  "EXECUTE dumpBaseType('%u')",
11260  tyinfo->dobj.catId.oid);
11261 
11262  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11263 
11264  typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
11265  typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
11266  typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
11267  typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
11268  typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
11269  typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
11270  typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
11271  typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
11272  typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
11273  typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
11274  typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
11275  typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
11276  typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
11277  typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
11278  typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
11279  typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
11280  typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
11281  typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
11282  typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
11283  typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
11284  typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
11285  typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
11286  if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
11287  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
11288  else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
11289  {
11290  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
11291  typdefault_is_literal = true; /* it needs quotes */
11292  }
11293  else
11294  typdefault = NULL;
11295 
11296  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11297  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11298 
11299  /*
11300  * The reason we include CASCADE is that the circular dependency between
11301  * the type and its I/O functions makes it impossible to drop the type any
11302  * other way.
11303  */
11304  appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
11305 
11306  /*
11307  * We might already have a shell type, but setting pg_type_oid is
11308  * harmless, and in any case we'd better set the array type OID.
11309  */
11310  if (dopt->binary_upgrade)
11312  tyinfo->dobj.catId.oid,
11313  false, false);
11314 
11316  "CREATE TYPE %s (\n"
11317  " INTERNALLENGTH = %s",
11318  qualtypname,
11319  (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
11320 
11321  /* regproc result is sufficiently quoted already */
11322  appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
11323  appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
11324  if (OidIsValid(typreceiveoid))
11325  appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
11326  if (OidIsValid(typsendoid))
11327  appendPQExpBuffer(q, ",\n SEND = %s", typsend);
11328  if (OidIsValid(typmodinoid))
11329  appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
11330  if (OidIsValid(typmodoutoid))
11331  appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
11332  if (OidIsValid(typanalyzeoid))
11333  appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
11334 
11335  if (strcmp(typcollatable, "t") == 0)
11336  appendPQExpBufferStr(q, ",\n COLLATABLE = true");
11337 
11338  if (typdefault != NULL)
11339  {
11340  appendPQExpBufferStr(q, ",\n DEFAULT = ");
11341  if (typdefault_is_literal)
11342  appendStringLiteralAH(q, typdefault, fout);
11343  else
11344  appendPQExpBufferStr(q, typdefault);
11345  }
11346 
11347  if (OidIsValid(typsubscriptoid))
11348  appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
11349 
11350  if (OidIsValid(tyinfo->typelem))
11351  appendPQExpBuffer(q, ",\n ELEMENT = %s",
11352  getFormattedTypeName(fout, tyinfo->typelem,
11353  zeroIsError));
11354 
11355  if (strcmp(typcategory, "U") != 0)
11356  {
11357  appendPQExpBufferStr(q, ",\n CATEGORY = ");
11358  appendStringLiteralAH(q, typcategory, fout);
11359  }
11360 
11361  if (strcmp(typispreferred, "t") == 0)
11362  appendPQExpBufferStr(q, ",\n PREFERRED = true");
11363 
11364  if (typdelim && strcmp(typdelim, ",") != 0)
11365  {
11366  appendPQExpBufferStr(q, ",\n DELIMITER = ");
11367  appendStringLiteralAH(q, typdelim, fout);
11368  }
11369 
11370  if (*typalign == TYPALIGN_CHAR)
11371  appendPQExpBufferStr(q, ",\n ALIGNMENT = char");
11372  else if (*typalign == TYPALIGN_SHORT)
11373  appendPQExpBufferStr(q, ",\n ALIGNMENT = int2");
11374  else if (*typalign == TYPALIGN_INT)
11375  appendPQExpBufferStr(q, ",\n ALIGNMENT = int4");
11376  else if (*typalign == TYPALIGN_DOUBLE)
11377  appendPQExpBufferStr(q, ",\n ALIGNMENT = double");
11378 
11379  if (*typstorage == TYPSTORAGE_PLAIN)
11380  appendPQExpBufferStr(q, ",\n STORAGE = plain");
11381  else if (*typstorage == TYPSTORAGE_EXTERNAL)
11382  appendPQExpBufferStr(q, ",\n STORAGE = external");
11383  else if (*typstorage == TYPSTORAGE_EXTENDED)
11384  appendPQExpBufferStr(q, ",\n STORAGE = extended");
11385  else if (*typstorage == TYPSTORAGE_MAIN)
11386  appendPQExpBufferStr(q, ",\n STORAGE = main");
11387 
11388  if (strcmp(typbyval, "t") == 0)
11389  appendPQExpBufferStr(q, ",\n PASSEDBYVALUE");
11390 
11391  appendPQExpBufferStr(q, "\n);\n");
11392 
11393  if (dopt->binary_upgrade)
11395  "TYPE", qtypname,
11396  tyinfo->dobj.namespace->dobj.name);
11397 
11398  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11399  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11400  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11401  .namespace = tyinfo->dobj.namespace->dobj.name,
11402  .owner = tyinfo->rolname,
11403  .description = "TYPE",
11404  .section = SECTION_PRE_DATA,
11405  .createStmt = q->data,
11406  .dropStmt = delq->data));
11407 
11408  /* Dump Type Comments and Security Labels */
11409  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11410  dumpComment(fout, "TYPE", qtypname,
11411  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11412  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11413 
11414  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11415  dumpSecLabel(fout, "TYPE", qtypname,
11416  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11417  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11418 
11419  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11420  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11421  qtypname, NULL,
11422  tyinfo->dobj.namespace->dobj.name,
11423  NULL, tyinfo->rolname, &tyinfo->dacl);
11424 
11425  PQclear(res);
11426  destroyPQExpBuffer(q);
11427  destroyPQExpBuffer(delq);
11428  destroyPQExpBuffer(query);
11429  free(qtypname);
11430  free(qualtypname);
11431 }
@ PREPQUERY_DUMPBASETYPE
Definition: pg_backup.h:67
static const char * getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
Definition: pg_dump.c:18836
char typalign
Definition: pg_type.h:176
DumpableAcl dacl
Definition: pg_dump.h:192
Oid typelem
Definition: pg_dump.h:201
const char * rolname
Definition: pg_dump.h:200

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), atooid, _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_type_oids_by_type_oid(), _dumpableObject::catId, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _typeInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), fmtId(), fmtQualifiedDumpable, free, getFormattedTypeName(), InvalidDumpId, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PREPQUERY_DUMPBASETYPE, printfPQExpBuffer(), Archive::remoteVersion, res, _typeInfo::rolname, SECTION_PRE_DATA, typalign, _typeInfo::typelem, and zeroIsError.

Referenced by dumpType().

◆ dumpCast()

static void dumpCast ( Archive fout,
const CastInfo cast 
)
static

Definition at line 12552 of file pg_dump.c.

12553 {
12554  DumpOptions *dopt = fout->dopt;
12555  PQExpBuffer defqry;
12556  PQExpBuffer delqry;
12557  PQExpBuffer labelq;
12558  PQExpBuffer castargs;
12559  FuncInfo *funcInfo = NULL;
12560  const char *sourceType;
12561  const char *targetType;
12562 
12563  /* Do nothing in data-only dump */
12564  if (dopt->dataOnly)
12565  return;
12566 
12567  /* Cannot dump if we don't have the cast function's info */
12568  if (OidIsValid(cast->castfunc))
12569  {
12570  funcInfo = findFuncByOid(cast->castfunc);
12571  if (funcInfo == NULL)
12572  pg_fatal("could not find function definition for function with OID %u",
12573  cast->castfunc);
12574  }
12575 
12576  defqry = createPQExpBuffer();
12577  delqry = createPQExpBuffer();
12578  labelq = createPQExpBuffer();
12579  castargs = createPQExpBuffer();
12580 
12581  sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
12582  targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
12583  appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
12584  sourceType, targetType);
12585 
12586  appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
12587  sourceType, targetType);
12588 
12589  switch (cast->castmethod)
12590  {
12591  case COERCION_METHOD_BINARY:
12592  appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
12593  break;
12594  case COERCION_METHOD_INOUT:
12595  appendPQExpBufferStr(defqry, "WITH INOUT");
12596  break;
12597  case COERCION_METHOD_FUNCTION:
12598  if (funcInfo)
12599  {
12600  char *fsig = format_function_signature(fout, funcInfo, true);
12601 
12602  /*
12603  * Always qualify the function name (format_function_signature
12604  * won't qualify it).
12605  */
12606  appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
12607  fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
12608  free(fsig);
12609  }
12610  else
12611  pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
12612  break;
12613  default:
12614  pg_log_warning("bogus value in pg_cast.castmethod field");
12615  }
12616 
12617  if (cast->castcontext == 'a')
12618  appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
12619  else if (cast->castcontext == 'i')
12620  appendPQExpBufferStr(defqry, " AS IMPLICIT");
12621  appendPQExpBufferStr(defqry, ";\n");
12622 
12623  appendPQExpBuffer(labelq, "CAST (%s AS %s)",
12624  sourceType, targetType);
12625 
12626  appendPQExpBuffer(castargs, "(%s AS %s)",
12627  sourceType, targetType);
12628 
12629  if (dopt->binary_upgrade)
12630  binary_upgrade_extension_member(defqry, &cast->dobj,
12631  "CAST", castargs->data, NULL);
12632 
12633  if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
12634  ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
12635  ARCHIVE_OPTS(.tag = labelq->data,
12636  .description = "CAST",
12637  .section = SECTION_PRE_DATA,
12638  .createStmt = defqry->data,
12639  .dropStmt = delqry->data));
12640 
12641  /* Dump Cast Comments */
12642  if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
12643  dumpComment(fout, "CAST", castargs->data,
12644  NULL, "",
12645  cast->dobj.catId, 0, cast->dobj.dumpId);
12646 
12647  destroyPQExpBuffer(defqry);
12648  destroyPQExpBuffer(delqry);
12649  destroyPQExpBuffer(labelq);
12650  destroyPQExpBuffer(castargs);
12651 }
FuncInfo * findFuncByOid(Oid oid)
Definition: common.c:883
char castmethod
Definition: pg_dump.h:501
Oid casttarget
Definition: pg_dump.h:498
char castcontext
Definition: pg_dump.h:500
DumpableObject dobj
Definition: pg_dump.h:496
Oid castsource
Definition: pg_dump.h:497
Oid castfunc
Definition: pg_dump.h:499
DumpableObject dobj
Definition: pg_dump.h:225

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _castInfo::castcontext, _castInfo::castfunc, _castInfo::castmethod, _castInfo::castsource, _castInfo::casttarget, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _funcInfo::dobj, _castInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, findFuncByOid(), fmtId(), format_function_signature(), free, getFormattedTypeName(), _dumpableObject::name, OidIsValid, pg_fatal, pg_log_warning, SECTION_PRE_DATA, and zeroAsNone.

Referenced by dumpDumpableObject().

◆ dumpCollation()

static void dumpCollation ( Archive fout,
const CollInfo collinfo 
)
static

Definition at line 13666 of file pg_dump.c.

13667 {
13668  DumpOptions *dopt = fout->dopt;
13669  PQExpBuffer query;
13670  PQExpBuffer q;
13671  PQExpBuffer delq;
13672  char *qcollname;
13673  PGresult *res;
13674  int i_collprovider;
13675  int i_collisdeterministic;
13676  int i_collcollate;
13677  int i_collctype;
13678  int i_colllocale;
13679  int i_collicurules;
13680  const char *collprovider;
13681  const char *collcollate;
13682  const char *collctype;
13683  const char *colllocale;
13684  const char *collicurules;
13685 
13686  /* Do nothing in data-only dump */
13687  if (dopt->dataOnly)
13688  return;
13689 
13690  query = createPQExpBuffer();
13691  q = createPQExpBuffer();
13692  delq = createPQExpBuffer();
13693 
13694  qcollname = pg_strdup(fmtId(collinfo->dobj.name));
13695 
13696  /* Get collation-specific details */
13697  appendPQExpBufferStr(query, "SELECT ");
13698 
13699  if (fout->remoteVersion >= 100000)
13700  appendPQExpBufferStr(query,
13701  "collprovider, "
13702  "collversion, ");
13703  else
13704  appendPQExpBufferStr(query,
13705  "'c' AS collprovider, "
13706  "NULL AS collversion, ");
13707 
13708  if (fout->remoteVersion >= 120000)
13709  appendPQExpBufferStr(query,
13710  "collisdeterministic, ");
13711  else
13712  appendPQExpBufferStr(query,
13713  "true AS collisdeterministic, ");
13714 
13715  if (fout->remoteVersion >= 170000)
13716  appendPQExpBufferStr(query,
13717  "colllocale, ");
13718  else if (fout->remoteVersion >= 150000)
13719  appendPQExpBufferStr(query,
13720  "colliculocale AS colllocale, ");
13721  else
13722  appendPQExpBufferStr(query,
13723  "NULL AS colllocale, ");
13724 
13725  if (fout->remoteVersion >= 160000)
13726  appendPQExpBufferStr(query,
13727  "collicurules, ");
13728  else
13729  appendPQExpBufferStr(query,
13730  "NULL AS collicurules, ");
13731 
13732  appendPQExpBuffer(query,
13733  "collcollate, "
13734  "collctype "
13735  "FROM pg_catalog.pg_collation c "
13736  "WHERE c.oid = '%u'::pg_catalog.oid",
13737  collinfo->dobj.catId.oid);
13738 
13739  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13740 
13741  i_collprovider = PQfnumber(res, "collprovider");
13742  i_collisdeterministic = PQfnumber(res, "collisdeterministic");
13743  i_collcollate = PQfnumber(res, "collcollate");
13744  i_collctype = PQfnumber(res, "collctype");
13745  i_colllocale = PQfnumber(res, "colllocale");
13746  i_collicurules = PQfnumber(res, "collicurules");
13747 
13748  collprovider = PQgetvalue(res, 0, i_collprovider);
13749 
13750  if (!PQgetisnull(res, 0, i_collcollate))
13751  collcollate = PQgetvalue(res, 0, i_collcollate);
13752  else
13753  collcollate = NULL;
13754 
13755  if (!PQgetisnull(res, 0, i_collctype))
13756  collctype = PQgetvalue(res, 0, i_collctype);
13757  else
13758  collctype = NULL;
13759 
13760  /*
13761  * Before version 15, collcollate and collctype were of type NAME and
13762  * non-nullable. Treat empty strings as NULL for consistency.
13763  */
13764  if (fout->remoteVersion < 150000)
13765  {
13766  if (collcollate[0] == '\0')
13767  collcollate = NULL;
13768  if (collctype[0] == '\0')
13769  collctype = NULL;
13770  }
13771 
13772  if (!PQgetisnull(res, 0, i_colllocale))
13773  colllocale = PQgetvalue(res, 0, i_colllocale);
13774  else
13775  colllocale = NULL;
13776 
13777  if (!PQgetisnull(res, 0, i_collicurules))
13778  collicurules = PQgetvalue(res, 0, i_collicurules);
13779  else
13780  collicurules = NULL;
13781 
13782  appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
13783  fmtQualifiedDumpable(collinfo));
13784 
13785  appendPQExpBuffer(q, "CREATE COLLATION %s (",
13786  fmtQualifiedDumpable(collinfo));
13787 
13788  appendPQExpBufferStr(q, "provider = ");
13789  if (collprovider[0] == 'b')
13790  appendPQExpBufferStr(q, "builtin");
13791  else if (collprovider[0] == 'c')
13792  appendPQExpBufferStr(q, "libc");
13793  else if (collprovider[0] == 'i')
13794  appendPQExpBufferStr(q, "icu");
13795  else if (collprovider[0] == 'd')
13796  /* to allow dumping pg_catalog; not accepted on input */
13797  appendPQExpBufferStr(q, "default");
13798  else
13799  pg_fatal("unrecognized collation provider: %s",
13800  collprovider);
13801 
13802  if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
13803  appendPQExpBufferStr(q, ", deterministic = false");
13804 
13805  if (collprovider[0] == 'd')
13806  {
13807  if (collcollate || collctype || colllocale || collicurules)
13808  pg_log_warning("invalid collation \"%s\"", qcollname);
13809 
13810  /* no locale -- the default collation cannot be reloaded anyway */
13811  }
13812  else if (collprovider[0] == 'b')
13813  {
13814  if (collcollate || collctype || !colllocale || collicurules)
13815  pg_log_warning("invalid collation \"%s\"", qcollname);
13816 
13817  appendPQExpBufferStr(q, ", locale = ");
13818  appendStringLiteralAH(q, colllocale ? colllocale : "",
13819  fout);
13820  }
13821  else if (collprovider[0] == 'i')
13822  {
13823  if (fout->remoteVersion >= 150000)
13824  {
13825  if (collcollate || collctype || !colllocale)
13826  pg_log_warning("invalid collation \"%s\"", qcollname);
13827 
13828  appendPQExpBufferStr(q, ", locale = ");
13829  appendStringLiteralAH(q, colllocale ? colllocale : "",
13830  fout);
13831  }
13832  else
13833  {
13834  if (!collcollate || !collctype || colllocale ||
13835  strcmp(collcollate, collctype) != 0)
13836  pg_log_warning("invalid collation \"%s\"", qcollname);
13837 
13838  appendPQExpBufferStr(q, ", locale = ");
13839  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
13840  }
13841 
13842  if (collicurules)
13843  {
13844  appendPQExpBufferStr(q, ", rules = ");
13845  appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
13846  }
13847  }
13848  else if (collprovider[0] == 'c')
13849  {
13850  if (colllocale || collicurules || !collcollate || !collctype)
13851  pg_log_warning("invalid collation \"%s\"", qcollname);
13852 
13853  if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
13854  {
13855  appendPQExpBufferStr(q, ", locale = ");
13856  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
13857  }
13858  else
13859  {
13860  appendPQExpBufferStr(q, ", lc_collate = ");
13861  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
13862  appendPQExpBufferStr(q, ", lc_ctype = ");
13863  appendStringLiteralAH(q, collctype ? collctype : "", fout);
13864  }
13865  }
13866  else
13867  pg_fatal("unrecognized collation provider: %s", collprovider);
13868 
13869  /*
13870  * For binary upgrade, carry over the collation version. For normal
13871  * dump/restore, omit the version, so that it is computed upon restore.
13872  */
13873  if (dopt->binary_upgrade)
13874  {
13875  int i_collversion;
13876 
13877  i_collversion = PQfnumber(res, "collversion");
13878  if (!PQgetisnull(res, 0, i_collversion))
13879  {
13880  appendPQExpBufferStr(q, ", version = ");
13882  PQgetvalue(res, 0, i_collversion),
13883  fout);
13884  }
13885  }
13886 
13887  appendPQExpBufferStr(q, ");\n");
13888 
13889  if (dopt->binary_upgrade)
13890  binary_upgrade_extension_member(q, &collinfo->dobj,
13891  "COLLATION", qcollname,
13892  collinfo->dobj.namespace->dobj.name);
13893 
13894  if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13895  ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
13896  ARCHIVE_OPTS(.tag = collinfo->dobj.name,
13897  .namespace = collinfo->dobj.namespace->dobj.name,
13898  .owner = collinfo->rolname,
13899  .description = "COLLATION",
13900  .section = SECTION_PRE_DATA,
13901  .createStmt = q->data,
13902  .dropStmt = delq->data));
13903 
13904  /* Dump Collation Comments */
13905  if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13906  dumpComment(fout, "COLLATION", qcollname,
13907  collinfo->dobj.namespace->dobj.name, collinfo->rolname,
13908  collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
13909 
13910  PQclear(res);
13911 
13912  destroyPQExpBuffer(query);
13913  destroyPQExpBuffer(q);
13914  destroyPQExpBuffer(delq);
13915  free(qcollname);
13916 }
const char * rolname
Definition: pg_dump.h:272
DumpableObject dobj
Definition: pg_dump.h:271

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _collInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, CatalogId::oid, pg_fatal, pg_log_warning, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), Archive::remoteVersion, res, _collInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpComment()

static void dumpComment ( Archive fout,
const char *  type,
const char *  name,
const char *  namespace,
const char *  owner,
CatalogId  catalogId,
int  subid,
DumpId  dumpId 
)
inlinestatic

Definition at line 10122 of file pg_dump.c.

10126 {
10127  dumpCommentExtended(fout, type, name, namespace, owner,
10128  catalogId, subid, dumpId, NULL);
10129 }
static void dumpCommentExtended(Archive *fout, const char *type, const char *name, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId, const char *initdb_comment)
Definition: pg_dump.c:10022

References dumpCommentExtended(), name, and type.

Referenced by dumpAccessMethod(), dumpAgg(), dumpBaseType(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpConversion(), dumpDomain(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpLO(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpPolicy(), dumpProcLang(), dumpPublication(), dumpRangeType(), dumpRule(), dumpSequence(), dumpStatisticsExt(), dumpSubscription(), dumpTableConstraintComment(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), and dumpUndefinedType().

◆ dumpCommentExtended()

static void dumpCommentExtended ( Archive fout,
const char *  type,
const char *  name,
const char *  namespace,
const char *  owner,
CatalogId  catalogId,
int  subid,
DumpId  dumpId,
const char *  initdb_comment 
)
static

Definition at line 10022 of file pg_dump.c.

10027 {
10028  DumpOptions *dopt = fout->dopt;
10030  int ncomments;
10031 
10032  /* do nothing, if --no-comments is supplied */
10033  if (dopt->no_comments)
10034  return;
10035 
10036  /* Comments are schema not data ... except LO comments are data */
10037  if (strcmp(type, "LARGE OBJECT") != 0)
10038  {
10039  if (dopt->dataOnly)
10040  return;
10041  }
10042  else
10043  {
10044  /* We do dump LO comments in binary-upgrade mode */
10045  if (dopt->schemaOnly && !dopt->binary_upgrade)
10046  return;
10047  }
10048 
10049  /* Search for comments associated with catalogId, using table */
10050  ncomments = findComments(catalogId.tableoid, catalogId.oid,
10051  &comments);
10052 
10053  /* Is there one matching the subid? */
10054  while (ncomments > 0)
10055  {
10056  if (comments->objsubid == subid)
10057  break;
10058  comments++;
10059  ncomments--;
10060  }
10061 
10062  if (initdb_comment != NULL)
10063  {
10064  static CommentItem empty_comment = {.descr = ""};
10065 
10066  /*
10067  * initdb creates this object with a comment. Skip dumping the
10068  * initdb-provided comment, which would complicate matters for
10069  * non-superuser use of pg_dump. When the DBA has removed initdb's
10070  * comment, replicate that.
10071  */
10072  if (ncomments == 0)
10073  {
10074  comments = &empty_comment;
10075  ncomments = 1;
10076  }
10077  else if (strcmp(comments->descr, initdb_comment) == 0)
10078  ncomments = 0;
10079  }
10080 
10081  /* If a comment exists, build COMMENT ON statement */
10082  if (ncomments > 0)
10083  {
10084  PQExpBuffer query = createPQExpBuffer();
10086 
10087  appendPQExpBuffer(query, "COMMENT ON %s ", type);
10088  if (namespace && *namespace)
10089  appendPQExpBuffer(query, "%s.", fmtId(namespace));
10090  appendPQExpBuffer(query, "%s IS ", name);
10091  appendStringLiteralAH(query, comments->descr, fout);
10092  appendPQExpBufferStr(query, ";\n");
10093 
10094  appendPQExpBuffer(tag, "%s %s", type, name);
10095 
10096  /*
10097  * We mark comments as SECTION_NONE because they really belong in the
10098  * same section as their parent, whether that is pre-data or
10099  * post-data.
10100  */
10102  ARCHIVE_OPTS(.tag = tag->data,
10103  .namespace = namespace,
10104  .owner = owner,
10105  .description = "COMMENT",
10106  .section = SECTION_NONE,
10107  .createStmt = query->data,
10108  .deps = &dumpId,
10109  .nDeps = 1));
10110 
10111  destroyPQExpBuffer(query);
10112  destroyPQExpBuffer(tag);
10113  }
10114 }
static int findComments(Oid classoid, Oid objoid, CommentItem **items)
Definition: pg_dump.c:10236
int no_comments
Definition: pg_backup.h:181

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, comments, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, CommentItem::descr, destroyPQExpBuffer(), Archive::dopt, findComments(), fmtId(), name, ncomments, nilCatalogId, _dumpOptions::no_comments, CommentItem::objsubid, CatalogId::oid, _dumpOptions::schemaOnly, SECTION_NONE, CatalogId::tableoid, and type.

Referenced by dumpComment(), and dumpNamespace().

◆ dumpCompositeType()

static void dumpCompositeType ( Archive fout,
const TypeInfo tyinfo 
)
static

Definition at line 11611 of file pg_dump.c.

11612 {
11613  DumpOptions *dopt = fout->dopt;
11615  PQExpBuffer dropped = createPQExpBuffer();
11616  PQExpBuffer delq = createPQExpBuffer();
11617  PQExpBuffer query = createPQExpBuffer();
11618  PGresult *res;
11619  char *qtypname;
11620  char *qualtypname;
11621  int ntups;
11622  int i_attname;
11623  int i_atttypdefn;
11624  int i_attlen;
11625  int i_attalign;
11626  int i_attisdropped;
11627  int i_attcollation;
11628  int i;
11629  int actual_atts;
11630 
11632  {
11633  /*
11634  * Set up query for type-specific details.
11635  *
11636  * Since we only want to dump COLLATE clauses for attributes whose
11637  * collation is different from their type's default, we use a CASE
11638  * here to suppress uninteresting attcollations cheaply. atttypid
11639  * will be 0 for dropped columns; collation does not matter for those.
11640  */
11641  appendPQExpBufferStr(query,
11642  "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
11643  "SELECT a.attname, a.attnum, "
11644  "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
11645  "a.attlen, a.attalign, a.attisdropped, "
11646  "CASE WHEN a.attcollation <> at.typcollation "
11647  "THEN a.attcollation ELSE 0 END AS attcollation "
11648  "FROM pg_catalog.pg_type ct "
11649  "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
11650  "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
11651  "WHERE ct.oid = $1 "
11652  "ORDER BY a.attnum");
11653 
11654  ExecuteSqlStatement(fout, query->data);
11655 
11657  }
11658 
11659  printfPQExpBuffer(query,
11660  "EXECUTE dumpCompositeType('%u')",
11661  tyinfo->dobj.catId.oid);
11662 
11663  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11664 
11665  ntups = PQntuples(res);
11666 
11667  i_attname = PQfnumber(res, "attname");
11668  i_atttypdefn = PQfnumber(res, "atttypdefn");
11669  i_attlen = PQfnumber(res, "attlen");
11670  i_attalign = PQfnumber(res, "attalign");
11671  i_attisdropped = PQfnumber(res, "attisdropped");
11672  i_attcollation = PQfnumber(res, "attcollation");
11673 
11674  if (dopt->binary_upgrade)
11675  {
11677  tyinfo->dobj.catId.oid,
11678  false, false);
11679  binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid);
11680  }
11681 
11682  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11683  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11684 
11685  appendPQExpBuffer(q, "CREATE TYPE %s AS (",
11686  qualtypname);
11687 
11688  actual_atts = 0;
11689  for (i = 0; i < ntups; i++)
11690  {
11691  char *attname;
11692  char *atttypdefn;
11693  char *attlen;
11694  char *attalign;
11695  bool attisdropped;
11696  Oid attcollation;
11697 
11698  attname = PQgetvalue(res, i, i_attname);
11699  atttypdefn = PQgetvalue(res, i, i_atttypdefn);
11700  attlen = PQgetvalue(res, i, i_attlen);
11701  attalign = PQgetvalue(res, i, i_attalign);
11702  attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
11703  attcollation = atooid(PQgetvalue(res, i, i_attcollation));
11704 
11705  if (attisdropped && !dopt->binary_upgrade)
11706  continue;
11707 
11708  /* Format properly if not first attr */
11709  if (actual_atts++ > 0)
11710  appendPQExpBufferChar(q, ',');
11711  appendPQExpBufferStr(q, "\n\t");
11712 
11713  if (!attisdropped)
11714  {
11715  appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
11716 
11717  /* Add collation if not default for the column type */
11718  if (OidIsValid(attcollation))
11719  {
11720  CollInfo *coll;
11721 
11722  coll = findCollationByOid(attcollation);
11723  if (coll)
11724  appendPQExpBuffer(q, " COLLATE %s",
11725  fmtQualifiedDumpable(coll));
11726  }
11727  }
11728  else
11729  {
11730  /*
11731  * This is a dropped attribute and we're in binary_upgrade mode.
11732  * Insert a placeholder for it in the CREATE TYPE command, and set
11733  * length and alignment with direct UPDATE to the catalogs
11734  * afterwards. See similar code in dumpTableSchema().
11735  */
11736  appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
11737 
11738  /* stash separately for insertion after the CREATE TYPE */
11739  appendPQExpBufferStr(dropped,
11740  "\n-- For binary upgrade, recreate dropped column.\n");
11741  appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
11742  "SET attlen = %s, "
11743  "attalign = '%s', attbyval = false\n"
11744  "WHERE attname = ", attlen, attalign);
11745  appendStringLiteralAH(dropped, attname, fout);
11746  appendPQExpBufferStr(dropped, "\n AND attrelid = ");
11747  appendStringLiteralAH(dropped, qualtypname, fout);
11748  appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
11749 
11750  appendPQExpBuffer(dropped, "ALTER TYPE %s ",
11751  qualtypname);
11752  appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
11753  fmtId(attname));
11754  }
11755  }
11756  appendPQExpBufferStr(q, "\n);\n");
11757  appendPQExpBufferStr(q, dropped->data);
11758 
11759  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11760 
11761  if (dopt->binary_upgrade)
11763  "TYPE", qtypname,
11764  tyinfo->dobj.namespace->dobj.name);
11765 
11766  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11767  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11768  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11769  .namespace = tyinfo->dobj.namespace->dobj.name,
11770  .owner = tyinfo->rolname,
11771  .description = "TYPE",
11772  .section = SECTION_PRE_DATA,
11773  .createStmt = q->data,
11774  .dropStmt = delq->data));
11775 
11776 
11777  /* Dump Type Comments and Security Labels */
11778  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11779  dumpComment(fout, "TYPE", qtypname,
11780  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11781  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11782 
11783  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11784  dumpSecLabel(fout, "TYPE", qtypname,
11785  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11786  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11787 
11788  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11789  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11790  qtypname, NULL,
11791  tyinfo->dobj.namespace->dobj.name,
11792  NULL, tyinfo->rolname, &tyinfo->dacl);
11793 
11794  /* Dump any per-column comments */
11795  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11796  dumpCompositeTypeColComments(fout, tyinfo, res);
11797 
11798  PQclear(res);
11799  destroyPQExpBuffer(q);
11800  destroyPQExpBuffer(dropped);
11801  destroyPQExpBuffer(delq);
11802  destroyPQExpBuffer(query);
11803  free(qtypname);
11804  free(qualtypname);
11805 }
NameData attname
Definition: pg_attribute.h:41
char attalign
Definition: pg_attribute.h:109
int16 attlen
Definition: pg_attribute.h:59
@ PREPQUERY_DUMPCOMPOSITETYPE
Definition: pg_backup.h:68
static void binary_upgrade_set_pg_class_oids(Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid)
Definition: pg_dump.c:5552
static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo, PGresult *res)
Definition: pg_dump.c:11817
Oid typrelid
Definition: pg_dump.h:202

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), atooid, attalign, attlen, attname, _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_type_oid(), _dumpableObject::catId, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _typeInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), dumpCompositeTypeColComments(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQuery(), ExecuteSqlStatement(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, free, i, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, OidIsValid, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), PREPQUERY_DUMPCOMPOSITETYPE, printfPQExpBuffer(), res, _typeInfo::rolname, SECTION_PRE_DATA, and _typeInfo::typrelid.

Referenced by dumpType().

◆ dumpCompositeTypeColComments()

static void dumpCompositeTypeColComments ( Archive fout,
const TypeInfo tyinfo,
PGresult res 
)
static

Definition at line 11817 of file pg_dump.c.

11819 {
11821  int ncomments;
11822  PQExpBuffer query;
11823  PQExpBuffer target;
11824  int i;
11825  int ntups;
11826  int i_attname;
11827  int i_attnum;
11828  int i_attisdropped;
11829 
11830  /* do nothing, if --no-comments is supplied */
11831  if (fout->dopt->no_comments)
11832  return;
11833 
11834  /* Search for comments associated with type's pg_class OID */
11835  ncomments = findComments(RelationRelationId, tyinfo->typrelid,
11836  &comments);
11837 
11838  /* If no comments exist, we're done */
11839  if (ncomments <= 0)
11840  return;
11841 
11842  /* Build COMMENT ON statements */
11843  query = createPQExpBuffer();
11844  target = createPQExpBuffer();
11845 
11846  ntups = PQntuples(res);
11847  i_attnum = PQfnumber(res, "attnum");
11848  i_attname = PQfnumber(res, "attname");
11849  i_attisdropped = PQfnumber(res, "attisdropped");
11850  while (ncomments > 0)
11851  {
11852  const char *attname;
11853 
11854  attname = NULL;
11855  for (i = 0; i < ntups; i++)
11856  {
11857  if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
11858  PQgetvalue(res, i, i_attisdropped)[0] != 't')
11859  {
11860  attname = PQgetvalue(res, i, i_attname);
11861  break;
11862  }
11863  }
11864  if (attname) /* just in case we don't find it */
11865  {
11866  const char *descr = comments->descr;
11867 
11868  resetPQExpBuffer(target);
11869  appendPQExpBuffer(target, "COLUMN %s.",
11870  fmtId(tyinfo->dobj.name));
11872 
11873  resetPQExpBuffer(query);
11874  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
11875  fmtQualifiedDumpable(tyinfo));
11876  appendPQExpBuffer(query, "%s IS ", fmtId(attname));
11877  appendStringLiteralAH(query, descr, fout);
11878  appendPQExpBufferStr(query, ";\n");
11879 
11881  ARCHIVE_OPTS(.tag = target->data,
11882  .namespace = tyinfo->dobj.namespace->dobj.name,
11883  .owner = tyinfo->rolname,
11884  .description = "COMMENT",
11885  .section = SECTION_NONE,
11886  .createStmt = query->data,
11887  .deps = &(tyinfo->dobj.dumpId),
11888  .nDeps = 1));
11889  }
11890 
11891  comments++;
11892  ncomments--;
11893  }
11894 
11895  destroyPQExpBuffer(query);
11896  destroyPQExpBuffer(target);
11897 }
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), attname, comments, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, CommentItem::descr, destroyPQExpBuffer(), _typeInfo::dobj, Archive::dopt, _dumpableObject::dumpId, findComments(), fmtId(), fmtQualifiedDumpable, i, _dumpableObject::name, ncomments, nilCatalogId, _dumpOptions::no_comments, CommentItem::objsubid, PQfnumber(), PQgetvalue(), PQntuples(), res, resetPQExpBuffer(), _typeInfo::rolname, SECTION_NONE, and _typeInfo::typrelid.

Referenced by dumpCompositeType().

◆ dumpConstraint()

static void dumpConstraint ( Archive fout,
const ConstraintInfo coninfo 
)
static

Definition at line 17052 of file pg_dump.c.

17053 {
17054  DumpOptions *dopt = fout->dopt;
17055  TableInfo *tbinfo = coninfo->contable;
17056  PQExpBuffer q;
17057  PQExpBuffer delq;
17058  char *tag = NULL;
17059  char *foreign;
17060 
17061  /* Do nothing in data-only dump */
17062  if (dopt->dataOnly)
17063  return;
17064 
17065  q = createPQExpBuffer();
17066  delq = createPQExpBuffer();
17067 
17068  foreign = tbinfo &&
17069  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
17070 
17071  if (coninfo->contype == 'p' ||
17072  coninfo->contype == 'u' ||
17073  coninfo->contype == 'x')
17074  {
17075  /* Index-related constraint */
17076  IndxInfo *indxinfo;
17077  int k;
17078 
17079  indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
17080 
17081  if (indxinfo == NULL)
17082  pg_fatal("missing index for constraint \"%s\"",
17083  coninfo->dobj.name);
17084 
17085  if (dopt->binary_upgrade)
17087  indxinfo->dobj.catId.oid);
17088 
17089  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
17090  fmtQualifiedDumpable(tbinfo));
17091  appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
17092  fmtId(coninfo->dobj.name));
17093 
17094  if (coninfo->condef)
17095  {
17096  /* pg_get_constraintdef should have provided everything */
17097  appendPQExpBuffer(q, "%s;\n", coninfo->condef);
17098  }
17099  else
17100  {
17102  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
17103 
17104  /*
17105  * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
17106  * indexes. Being able to create this was fixed, but we need to
17107  * make the index distinct in order to be able to restore the
17108  * dump.
17109  */
17110  if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
17111  appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
17112  appendPQExpBufferStr(q, " (");
17113  for (k = 0; k < indxinfo->indnkeyattrs; k++)
17114  {
17115  int indkey = (int) indxinfo->indkeys[k];
17116  const char *attname;
17117 
17118  if (indkey == InvalidAttrNumber)
17119  break;
17120  attname = getAttrName(indkey, tbinfo);
17121 
17122  appendPQExpBuffer(q, "%s%s",
17123  (k == 0) ? "" : ", ",
17124  fmtId(attname));
17125  }
17126  if (coninfo->conperiod)
17127  appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
17128 
17129  if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
17130  appendPQExpBufferStr(q, ") INCLUDE (");
17131 
17132  for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
17133  {
17134  int indkey = (int) indxinfo->indkeys[k];
17135  const char *attname;
17136 
17137  if (indkey == InvalidAttrNumber)
17138  break;
17139  attname = getAttrName(indkey, tbinfo);
17140 
17141  appendPQExpBuffer(q, "%s%s",
17142  (k == indxinfo->indnkeyattrs) ? "" : ", ",
17143  fmtId(attname));
17144  }
17145 
17146  appendPQExpBufferChar(q, ')');
17147 
17148  if (nonemptyReloptions(indxinfo->indreloptions))
17149  {
17150  appendPQExpBufferStr(q, " WITH (");
17151  appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
17152  appendPQExpBufferChar(q, ')');
17153  }
17154 
17155  if (coninfo->condeferrable)
17156  {
17157  appendPQExpBufferStr(q, " DEFERRABLE");
17158  if (coninfo->condeferred)
17159  appendPQExpBufferStr(q, " INITIALLY DEFERRED");
17160  }
17161 
17162  appendPQExpBufferStr(q, ";\n");
17163  }
17164 
17165  /*
17166  * Append ALTER TABLE commands as needed to set properties that we
17167  * only have ALTER TABLE syntax for. Keep this in sync with the
17168  * similar code in dumpIndex!
17169  */
17170 
17171  /* If the index is clustered, we need to record that. */
17172  if (indxinfo->indisclustered)
17173  {
17174  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17175  fmtQualifiedDumpable(tbinfo));
17176  /* index name is not qualified in this syntax */
17177  appendPQExpBuffer(q, " ON %s;\n",
17178  fmtId(indxinfo->dobj.name));
17179  }
17180 
17181  /* If the index defines identity, we need to record that. */
17182  if (indxinfo->indisreplident)
17183  {
17184  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17185  fmtQualifiedDumpable(tbinfo));
17186  /* index name is not qualified in this syntax */
17187  appendPQExpBuffer(q, " INDEX %s;\n",
17188  fmtId(indxinfo->dobj.name));
17189  }
17190 
17191  /* Indexes can depend on extensions */
17192  append_depends_on_extension(fout, q, &indxinfo->dobj,
17193  "pg_catalog.pg_class", "INDEX",
17194  fmtQualifiedDumpable(indxinfo));
17195 
17196  appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
17197  fmtQualifiedDumpable(tbinfo));
17198  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17199  fmtId(coninfo->dobj.name));
17200 
17201  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17202 
17203  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17204  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17205  ARCHIVE_OPTS(.tag = tag,
17206  .namespace = tbinfo->dobj.namespace->dobj.name,
17207  .tablespace = indxinfo->tablespace,
17208  .owner = tbinfo->rolname,
17209  .description = "CONSTRAINT",
17210  .section = SECTION_POST_DATA,
17211  .createStmt = q->data,
17212  .dropStmt = delq->data));
17213  }
17214  else if (coninfo->contype == 'f')
17215  {
17216  char *only;
17217 
17218  /*
17219  * Foreign keys on partitioned tables are always declared as
17220  * inheriting to partitions; for all other cases, emit them as
17221  * applying ONLY directly to the named table, because that's how they
17222  * work for regular inherited tables.
17223  */
17224  only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
17225 
17226  /*
17227  * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
17228  * current table data is not processed
17229  */
17230  appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
17231  only, fmtQualifiedDumpable(tbinfo));
17232  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17233  fmtId(coninfo->dobj.name),
17234  coninfo->condef);
17235 
17236  appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
17237  only, fmtQualifiedDumpable(tbinfo));
17238  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17239  fmtId(coninfo->dobj.name));
17240 
17241  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17242 
17243  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17244  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17245  ARCHIVE_OPTS(.tag = tag,
17246  .namespace = tbinfo->dobj.namespace->dobj.name,
17247  .owner = tbinfo->rolname,
17248  .description = "FK CONSTRAINT",
17249  .section = SECTION_POST_DATA,
17250  .createStmt = q->data,
17251  .dropStmt = delq->data));
17252  }
17253  else if (coninfo->contype == 'c' && tbinfo)
17254  {
17255  /* CHECK constraint on a table */
17256 
17257  /* Ignore if not to be dumped separately, or if it was inherited */
17258  if (coninfo->separate && coninfo->conislocal)
17259  {
17260  /* not ONLY since we want it to propagate to children */
17261  appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
17262  fmtQualifiedDumpable(tbinfo));
17263  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17264  fmtId(coninfo->dobj.name),
17265  coninfo->condef);
17266 
17267  appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
17268  fmtQualifiedDumpable(tbinfo));
17269  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17270  fmtId(coninfo->dobj.name));
17271 
17272  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17273 
17274  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17275  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17276  ARCHIVE_OPTS(.tag = tag,
17277  .namespace = tbinfo->dobj.namespace->dobj.name,
17278  .owner = tbinfo->rolname,
17279  .description = "CHECK CONSTRAINT",
17280  .section = SECTION_POST_DATA,
17281  .createStmt = q->data,
17282  .dropStmt = delq->data));
17283  }
17284  }
17285  else if (coninfo->contype == 'c' && tbinfo == NULL)
17286  {
17287  /* CHECK constraint on a domain */
17288  TypeInfo *tyinfo = coninfo->condomain;
17289 
17290  /* Ignore if not to be dumped separately */
17291  if (coninfo->separate)
17292  {
17293  appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
17294  fmtQualifiedDumpable(tyinfo));
17295  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17296  fmtId(coninfo->dobj.name),
17297  coninfo->condef);
17298 
17299  appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
17300  fmtQualifiedDumpable(tyinfo));
17301  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17302  fmtId(coninfo->dobj.name));
17303 
17304  tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
17305 
17306  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17307  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17308  ARCHIVE_OPTS(.tag = tag,
17309  .namespace = tyinfo->dobj.namespace->dobj.name,
17310  .owner = tyinfo->rolname,
17311  .description = "CHECK CONSTRAINT",
17312  .section = SECTION_POST_DATA,
17313  .createStmt = q->data,
17314  .dropStmt = delq->data));
17315  }
17316  }
17317  else
17318  {
17319  pg_fatal("unrecognized constraint type: %c",
17320  coninfo->contype);
17321  }
17322 
17323  /* Dump Constraint Comments --- only works for table constraints */
17324  if (tbinfo && coninfo->separate &&
17325  coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17326  dumpTableConstraintComment(fout, coninfo);
17327 
17328  free(tag);
17329  destroyPQExpBuffer(q);
17330  destroyPQExpBuffer(delq);
17331 }
#define InvalidAttrNumber
Definition: attnum.h:23
@ SECTION_POST_DATA
Definition: pg_backup.h:60
static void append_depends_on_extension(Archive *fout, PQExpBuffer create, const DumpableObject *dobj, const char *catalog, const char *keyword, const char *objname)
Definition: pg_dump.c:5331
static const char * getAttrName(int attrnum, const TableInfo *tblInfo)
Definition: pg_dump.c:16766
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
Definition: pg_dump.c:18933
static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:17341
static bool nonemptyReloptions(const char *reloptions)
Definition: pg_dump.c:18921
TypeInfo * condomain
Definition: pg_dump.h:471
TableInfo * contable
Definition: pg_dump.h:470
bool condeferred
Definition: pg_dump.h:477
bool conperiod
Definition: pg_dump.h:478
bool conislocal
Definition: pg_dump.h:479
DumpableObject dobj
Definition: pg_dump.h:469
DumpId conindex
Definition: pg_dump.h:475
bool condeferrable
Definition: pg_dump.h:476
char * condef
Definition: pg_dump.h:473
bool indisreplident
Definition: pg_dump.h:404
int indnkeyattrs
Definition: pg_dump.h:399
int indnattrs
Definition: pg_dump.h:400
Oid * indkeys
Definition: pg_dump.h:401
char * indreloptions
Definition: pg_dump.h:396
bool indisclustered
Definition: pg_dump.h:403
char * tablespace
Definition: pg_dump.h:395
bool indnullsnotdistinct
Definition: pg_dump.h:405
DumpableObject dobj
Definition: pg_dump.h:392

References append_depends_on_extension(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArrayAH(), ARCHIVE_OPTS, ArchiveEntry(), attname, _dumpOptions::binary_upgrade, binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::conperiod, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _typeInfo::dobj, _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, dumpTableConstraintComment(), findObjectByDumpId(), fmtId(), fmtQualifiedDumpable, free, getAttrName(), if(), _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indkeys, _indxInfo::indnattrs, _indxInfo::indnkeyattrs, _indxInfo::indnullsnotdistinct, _indxInfo::indreloptions, InvalidAttrNumber, _dumpableObject::name, nonemptyReloptions(), CatalogId::oid, pg_fatal, psprintf(), _tableInfo::relkind, _typeInfo::rolname, _tableInfo::rolname, SECTION_POST_DATA, _constraintInfo::separate, and _indxInfo::tablespace.

Referenced by dumpDumpableObject().

◆ dumpConversion()

static void dumpConversion ( Archive fout,
const ConvInfo convinfo 
)
static

Definition at line 13923 of file pg_dump.c.

13924 {
13925  DumpOptions *dopt = fout->dopt;
13926  PQExpBuffer query;
13927  PQExpBuffer q;
13928  PQExpBuffer delq;
13929  char *qconvname;
13930  PGresult *res;
13931  int i_conforencoding;
13932  int i_contoencoding;
13933  int i_conproc;
13934  int i_condefault;
13935  const char *conforencoding;
13936  const char *contoencoding;
13937  const char *conproc;
13938  bool condefault;
13939 
13940  /* Do nothing in data-only dump */
13941  if (dopt->dataOnly)
13942  return;
13943 
13944  query = createPQExpBuffer();
13945  q = createPQExpBuffer();
13946  delq = createPQExpBuffer();
13947 
13948  qconvname = pg_strdup(fmtId(convinfo->dobj.name));
13949 
13950  /* Get conversion-specific details */
13951  appendPQExpBuffer(query, "SELECT "
13952  "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
13953  "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
13954  "conproc, condefault "
13955  "FROM pg_catalog.pg_conversion c "
13956  "WHERE c.oid = '%u'::pg_catalog.oid",
13957  convinfo->dobj.catId.oid);
13958 
13959  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13960 
13961  i_conforencoding = PQfnumber(res, "conforencoding");
13962  i_contoencoding = PQfnumber(res, "contoencoding");
13963  i_conproc = PQfnumber(res, "conproc");
13964  i_condefault = PQfnumber(res, "condefault");
13965 
13966  conforencoding = PQgetvalue(res, 0, i_conforencoding);
13967  contoencoding = PQgetvalue(res, 0, i_contoencoding);
13968  conproc = PQgetvalue(res, 0, i_conproc);
13969  condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
13970 
13971  appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
13972  fmtQualifiedDumpable(convinfo));
13973 
13974  appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
13975  (condefault) ? "DEFAULT " : "",
13976  fmtQualifiedDumpable(convinfo));
13977  appendStringLiteralAH(q, conforencoding, fout);
13978  appendPQExpBufferStr(q, " TO ");
13979  appendStringLiteralAH(q, contoencoding, fout);
13980  /* regproc output is already sufficiently quoted */
13981  appendPQExpBuffer(q, " FROM %s;\n", conproc);
13982 
13983  if (dopt->binary_upgrade)
13984  binary_upgrade_extension_member(q, &convinfo->dobj,
13985  "CONVERSION", qconvname,
13986  convinfo->dobj.namespace->dobj.name);
13987 
13988  if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13989  ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
13990  ARCHIVE_OPTS(.tag = convinfo->dobj.name,
13991  .namespace = convinfo->dobj.namespace->dobj.name,
13992  .owner = convinfo->rolname,
13993  .description = "CONVERSION",
13994  .section = SECTION_PRE_DATA,
13995  .createStmt = q->data,
13996  .dropStmt = delq->data));
13997 
13998  /* Dump Conversion Comments */
13999  if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14000  dumpComment(fout, "CONVERSION", qconvname,
14001  convinfo->dobj.namespace->dobj.name, convinfo->rolname,
14002  convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
14003 
14004  PQclear(res);
14005 
14006  destroyPQExpBuffer(query);
14007  destroyPQExpBuffer(q);
14008  destroyPQExpBuffer(delq);
14009  free(qconvname);
14010 }
DumpableObject dobj
Definition: pg_dump.h:277
const char * rolname
Definition: pg_dump.h:278

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _convInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, CatalogId::oid, pg_strdup(), PQclear(), PQfnumber(), PQgetvalue(), res, _convInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpDatabase()

static void dumpDatabase ( Archive fout)
static

Definition at line 3083 of file pg_dump.c.

3084 {
3085  DumpOptions *dopt = fout->dopt;
3086  PQExpBuffer dbQry = createPQExpBuffer();
3087  PQExpBuffer delQry = createPQExpBuffer();
3088  PQExpBuffer creaQry = createPQExpBuffer();
3089  PQExpBuffer labelq = createPQExpBuffer();
3090  PGconn *conn = GetConnection(fout);
3091  PGresult *res;
3092  int i_tableoid,
3093  i_oid,
3094  i_datname,
3095  i_datdba,
3096  i_encoding,
3097  i_datlocprovider,
3098  i_collate,
3099  i_ctype,
3100  i_datlocale,
3101  i_daticurules,
3102  i_frozenxid,
3103  i_minmxid,
3104  i_datacl,
3105  i_acldefault,
3106  i_datistemplate,
3107  i_datconnlimit,
3108  i_datcollversion,
3109  i_tablespace;
3110  CatalogId dbCatId;
3111  DumpId dbDumpId;
3112  DumpableAcl dbdacl;
3113  const char *datname,
3114  *dba,
3115  *encoding,
3116  *datlocprovider,
3117  *collate,
3118  *ctype,
3119  *locale,
3120  *icurules,
3121  *datistemplate,
3122  *datconnlimit,
3123  *tablespace;
3124  uint32 frozenxid,
3125  minmxid;
3126  char *qdatname;
3127 
3128  pg_log_info("saving database definition");
3129 
3130  /*
3131  * Fetch the database-level properties for this database.
3132  */
3133  appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
3134  "datdba, "
3135  "pg_encoding_to_char(encoding) AS encoding, "
3136  "datcollate, datctype, datfrozenxid, "
3137  "datacl, acldefault('d', datdba) AS acldefault, "
3138  "datistemplate, datconnlimit, ");
3139  if (fout->remoteVersion >= 90300)
3140  appendPQExpBufferStr(dbQry, "datminmxid, ");
3141  else
3142  appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
3143  if (fout->remoteVersion >= 170000)
3144  appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
3145  else if (fout->remoteVersion >= 150000)
3146  appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
3147  else
3148  appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
3149  if (fout->remoteVersion >= 160000)
3150  appendPQExpBufferStr(dbQry, "daticurules, ");
3151  else
3152  appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
3153  appendPQExpBufferStr(dbQry,
3154  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
3155  "shobj_description(oid, 'pg_database') AS description "
3156  "FROM pg_database "
3157  "WHERE datname = current_database()");
3158 
3159  res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
3160 
3161  i_tableoid = PQfnumber(res, "tableoid");
3162  i_oid = PQfnumber(res, "oid");
3163  i_datname = PQfnumber(res, "datname");
3164  i_datdba = PQfnumber(res, "datdba");
3165  i_encoding = PQfnumber(res, "encoding");
3166  i_datlocprovider = PQfnumber(res, "datlocprovider");
3167  i_collate = PQfnumber(res, "datcollate");
3168  i_ctype = PQfnumber(res, "datctype");
3169  i_datlocale = PQfnumber(res, "datlocale");
3170  i_daticurules = PQfnumber(res, "daticurules");
3171  i_frozenxid = PQfnumber(res, "datfrozenxid");
3172  i_minmxid = PQfnumber(res, "datminmxid");
3173  i_datacl = PQfnumber(res, "datacl");
3174  i_acldefault = PQfnumber(res, "acldefault");
3175  i_datistemplate = PQfnumber(res, "datistemplate");
3176  i_datconnlimit = PQfnumber(res, "datconnlimit");
3177  i_datcollversion = PQfnumber(res, "datcollversion");
3178  i_tablespace = PQfnumber(res, "tablespace");
3179 
3180  dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
3181  dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
3182  datname = PQgetvalue(res, 0, i_datname);
3183  dba = getRoleName(PQgetvalue(res, 0, i_datdba));
3184  encoding = PQgetvalue(res, 0, i_encoding);
3185  datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
3186  collate = PQgetvalue(res, 0, i_collate);
3187  ctype = PQgetvalue(res, 0, i_ctype);
3188  if (!PQgetisnull(res, 0, i_datlocale))
3189  locale = PQgetvalue(res, 0, i_datlocale);
3190  else
3191  locale = NULL;
3192  if (!PQgetisnull(res, 0, i_daticurules))
3193  icurules = PQgetvalue(res, 0, i_daticurules);
3194  else
3195  icurules = NULL;
3196  frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
3197  minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
3198  dbdacl.acl = PQgetvalue(res, 0, i_datacl);
3199  dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
3200  datistemplate = PQgetvalue(res, 0, i_datistemplate);
3201  datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
3202  tablespace = PQgetvalue(res, 0, i_tablespace);
3203 
3204  qdatname = pg_strdup(fmtId(datname));
3205 
3206  /*
3207  * Prepare the CREATE DATABASE command. We must specify OID (if we want
3208  * to preserve that), as well as the encoding, locale, and tablespace
3209  * since those can't be altered later. Other DB properties are left to
3210  * the DATABASE PROPERTIES entry, so that they can be applied after
3211  * reconnecting to the target DB.
3212  *
3213  * For binary upgrade, we use the FILE_COPY strategy because testing has
3214  * shown it to be faster. When the server is in binary upgrade mode, it
3215  * will also skip the checkpoints this strategy ordinarily performs.
3216  */
3217  if (dopt->binary_upgrade)
3218  {
3219  appendPQExpBuffer(creaQry,
3220  "CREATE DATABASE %s WITH TEMPLATE = template0 "
3221  "OID = %u STRATEGY = FILE_COPY",
3222  qdatname, dbCatId.oid);
3223  }
3224  else
3225  {
3226  appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
3227  qdatname);
3228  }
3229  if (strlen(encoding) > 0)
3230  {
3231  appendPQExpBufferStr(creaQry, " ENCODING = ");
3232  appendStringLiteralAH(creaQry, encoding, fout);
3233  }
3234 
3235  appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
3236  if (datlocprovider[0] == 'b')
3237  appendPQExpBufferStr(creaQry, "builtin");
3238  else if (datlocprovider[0] == 'c')
3239  appendPQExpBufferStr(creaQry, "libc");
3240  else if (datlocprovider[0] == 'i')
3241  appendPQExpBufferStr(creaQry, "icu");
3242  else
3243  pg_fatal("unrecognized locale provider: %s",
3244  datlocprovider);
3245 
3246  if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
3247  {
3248  appendPQExpBufferStr(creaQry, " LOCALE = ");
3249  appendStringLiteralAH(creaQry, collate, fout);
3250  }
3251  else
3252  {
3253  if (strlen(collate) > 0)
3254  {
3255  appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
3256  appendStringLiteralAH(creaQry, collate, fout);
3257  }
3258  if (strlen(ctype) > 0)
3259  {
3260  appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
3261  appendStringLiteralAH(creaQry, ctype, fout);
3262  }
3263  }
3264  if (locale)
3265  {
3266  if (datlocprovider[0] == 'b')
3267  appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
3268  else
3269  appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
3270 
3271  appendStringLiteralAH(creaQry, locale, fout);
3272  }
3273 
3274  if (icurules)
3275  {
3276  appendPQExpBufferStr(creaQry, " ICU_RULES = ");
3277  appendStringLiteralAH(creaQry, icurules, fout);
3278  }
3279 
3280  /*
3281  * For binary upgrade, carry over the collation version. For normal
3282  * dump/restore, omit the version, so that it is computed upon restore.
3283  */
3284  if (dopt->binary_upgrade)
3285  {
3286  if (!PQgetisnull(res, 0, i_datcollversion))
3287  {
3288  appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
3289  appendStringLiteralAH(creaQry,
3290  PQgetvalue(res, 0, i_datcollversion),
3291  fout);
3292  }
3293  }
3294 
3295  /*
3296  * Note: looking at dopt->outputNoTablespaces here is completely the wrong
3297  * thing; the decision whether to specify a tablespace should be left till
3298  * pg_restore, so that pg_restore --no-tablespaces applies. Ideally we'd
3299  * label the DATABASE entry with the tablespace and let the normal
3300  * tablespace selection logic work ... but CREATE DATABASE doesn't pay
3301  * attention to default_tablespace, so that won't work.
3302  */
3303  if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
3304  !dopt->outputNoTablespaces)
3305  appendPQExpBuffer(creaQry, " TABLESPACE = %s",
3306  fmtId(tablespace));
3307  appendPQExpBufferStr(creaQry, ";\n");
3308 
3309  appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
3310  qdatname);
3311 
3312  dbDumpId = createDumpId();
3313 
3314  ArchiveEntry(fout,
3315  dbCatId, /* catalog ID */
3316  dbDumpId, /* dump ID */
3317  ARCHIVE_OPTS(.tag = datname,
3318  .owner = dba,
3319  .description = "DATABASE",
3320  .section = SECTION_PRE_DATA,
3321  .createStmt = creaQry->data,
3322  .dropStmt = delQry->data));
3323 
3324  /* Compute correct tag for archive entry */
3325  appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
3326 
3327  /* Dump DB comment if any */
3328  {
3329  /*
3330  * 8.2 and up keep comments on shared objects in a shared table, so we
3331  * cannot use the dumpComment() code used for other database objects.
3332  * Be careful that the ArchiveEntry parameters match that function.
3333  */
3334  char *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
3335 
3336  if (comment && *comment && !dopt->no_comments)
3337  {
3338  resetPQExpBuffer(dbQry);
3339 
3340  /*
3341  * Generates warning when loaded into a differently-named
3342  * database.
3343  */
3344  appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
3345  appendStringLiteralAH(dbQry, comment, fout);
3346  appendPQExpBufferStr(dbQry, ";\n");
3347 
3349  ARCHIVE_OPTS(.tag = labelq->data,
3350  .owner = dba,
3351  .description = "COMMENT",
3352  .section = SECTION_NONE,
3353  .createStmt = dbQry->data,
3354  .deps = &dbDumpId,
3355  .nDeps = 1));
3356  }
3357  }
3358 
3359  /* Dump DB security label, if enabled */
3360  if (!dopt->no_security_labels)
3361  {
3362  PGresult *shres;
3363  PQExpBuffer seclabelQry;
3364 
3365  seclabelQry = createPQExpBuffer();
3366 
3367  buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
3368  shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
3369  resetPQExpBuffer(seclabelQry);
3370  emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
3371  if (seclabelQry->len > 0)
3373  ARCHIVE_OPTS(.tag = labelq->data,
3374  .owner = dba,
3375  .description = "SECURITY LABEL",
3376  .section = SECTION_NONE,
3377  .createStmt = seclabelQry->data,
3378  .deps = &dbDumpId,
3379  .nDeps = 1));
3380  destroyPQExpBuffer(seclabelQry);
3381  PQclear(shres);
3382  }
3383 
3384  /*
3385  * Dump ACL if any. Note that we do not support initial privileges
3386  * (pg_init_privs) on databases.
3387  */
3388  dbdacl.privtype = 0;
3389  dbdacl.initprivs = NULL;
3390 
3391  dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
3392  qdatname, NULL, NULL,
3393  NULL, dba, &dbdacl);
3394 
3395  /*
3396  * Now construct a DATABASE PROPERTIES archive entry to restore any
3397  * non-default database-level properties. (The reason this must be
3398  * separate is that we cannot put any additional commands into the TOC
3399  * entry that has CREATE DATABASE. pg_restore would execute such a group
3400  * in an implicit transaction block, and the backend won't allow CREATE
3401  * DATABASE in that context.)
3402  */
3403  resetPQExpBuffer(creaQry);
3404  resetPQExpBuffer(delQry);
3405 
3406  if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
3407  appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
3408  qdatname, datconnlimit);
3409 
3410  if (strcmp(datistemplate, "t") == 0)
3411  {
3412  appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
3413  qdatname);
3414 
3415  /*
3416  * The backend won't accept DROP DATABASE on a template database. We
3417  * can deal with that by removing the template marking before the DROP
3418  * gets issued. We'd prefer to use ALTER DATABASE IF EXISTS here, but
3419  * since no such command is currently supported, fake it with a direct
3420  * UPDATE on pg_database.
3421  */
3422  appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
3423  "SET datistemplate = false WHERE datname = ");
3424  appendStringLiteralAH(delQry, datname, fout);
3425  appendPQExpBufferStr(delQry, ";\n");
3426  }
3427 
3428  /*
3429  * We do not restore pg_database.dathasloginevt because it is set
3430  * automatically on login event trigger creation.
3431  */
3432 
3433  /* Add database-specific SET options */
3434  dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
3435 
3436  /*
3437  * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
3438  * entry, too, for lack of a better place.
3439  */
3440  if (dopt->binary_upgrade)
3441  {
3442  appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
3443  appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
3444  "SET datfrozenxid = '%u', datminmxid = '%u'\n"
3445  "WHERE datname = ",
3446  frozenxid, minmxid);
3447  appendStringLiteralAH(creaQry, datname, fout);
3448  appendPQExpBufferStr(creaQry, ";\n");
3449  }
3450 
3451  if (creaQry->len > 0)
3453  ARCHIVE_OP