PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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_proc_d.h"
#include "catalog/pg_subscription.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 void determineNotNullFlags (Archive *fout, PGresult *res, int r, TableInfo *tbinfo, int j, int i_notnull_name, int i_notnull_noinherit, int i_notnull_islocal)
 
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 214 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 226 of file pg_dump.c.

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

Definition at line 221 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 137 of file pg_dump.c.

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

◆ SeqType

enum SeqType
Enumerator
SEQTYPE_SMALLINT 
SEQTYPE_INTEGER 
SEQTYPE_BIGINT 

Definition at line 106 of file pg_dump.c.

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

Function Documentation

◆ addBoundaryDependencies()

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

Definition at line 18870 of file pg_dump.c.

18872 {
18873  DumpableObject *preDataBound = boundaryObjs + 0;
18874  DumpableObject *postDataBound = boundaryObjs + 1;
18875  int i;
18876 
18877  for (i = 0; i < numObjs; i++)
18878  {
18879  DumpableObject *dobj = dobjs[i];
18880 
18881  /*
18882  * The classification of object types here must match the SECTION_xxx
18883  * values assigned during subsequent ArchiveEntry calls!
18884  */
18885  switch (dobj->objType)
18886  {
18887  case DO_NAMESPACE:
18888  case DO_EXTENSION:
18889  case DO_TYPE:
18890  case DO_SHELL_TYPE:
18891  case DO_FUNC:
18892  case DO_AGG:
18893  case DO_OPERATOR:
18894  case DO_ACCESS_METHOD:
18895  case DO_OPCLASS:
18896  case DO_OPFAMILY:
18897  case DO_COLLATION:
18898  case DO_CONVERSION:
18899  case DO_TABLE:
18900  case DO_TABLE_ATTACH:
18901  case DO_ATTRDEF:
18902  case DO_PROCLANG:
18903  case DO_CAST:
18904  case DO_DUMMY_TYPE:
18905  case DO_TSPARSER:
18906  case DO_TSDICT:
18907  case DO_TSTEMPLATE:
18908  case DO_TSCONFIG:
18909  case DO_FDW:
18910  case DO_FOREIGN_SERVER:
18911  case DO_TRANSFORM:
18912  /* Pre-data objects: must come before the pre-data boundary */
18913  addObjectDependency(preDataBound, dobj->dumpId);
18914  break;
18915  case DO_TABLE_DATA:
18916  case DO_SEQUENCE_SET:
18917  case DO_LARGE_OBJECT:
18918  case DO_LARGE_OBJECT_DATA:
18919  /* Data objects: must come between the boundaries */
18920  addObjectDependency(dobj, preDataBound->dumpId);
18921  addObjectDependency(postDataBound, dobj->dumpId);
18922  break;
18923  case DO_INDEX:
18924  case DO_INDEX_ATTACH:
18925  case DO_STATSEXT:
18926  case DO_REFRESH_MATVIEW:
18927  case DO_TRIGGER:
18928  case DO_EVENT_TRIGGER:
18929  case DO_DEFAULT_ACL:
18930  case DO_POLICY:
18931  case DO_PUBLICATION:
18932  case DO_PUBLICATION_REL:
18934  case DO_SUBSCRIPTION:
18935  case DO_SUBSCRIPTION_REL:
18936  /* Post-data objects: must come after the post-data boundary */
18937  addObjectDependency(dobj, postDataBound->dumpId);
18938  break;
18939  case DO_RULE:
18940  /* Rules are post-data, but only if dumped separately */
18941  if (((RuleInfo *) dobj)->separate)
18942  addObjectDependency(dobj, postDataBound->dumpId);
18943  break;
18944  case DO_CONSTRAINT:
18945  case DO_FK_CONSTRAINT:
18946  /* Constraints are post-data, but only if dumped separately */
18947  if (((ConstraintInfo *) dobj)->separate)
18948  addObjectDependency(dobj, postDataBound->dumpId);
18949  break;
18950  case DO_PRE_DATA_BOUNDARY:
18951  /* nothing to do */
18952  break;
18953  case DO_POST_DATA_BOUNDARY:
18954  /* must come after the pre-data boundary */
18955  addObjectDependency(dobj, preDataBound->dumpId);
18956  break;
18957  }
18958  }
18959 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:795
int i
Definition: isn.c:72
@ 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 7974 of file pg_dump.c.

7975 {
7976  SimplePtrListCell *cell;
7977 
7978  Assert(dobj->objType == DO_FK_CONSTRAINT);
7979 
7980  for (cell = refidx->partattaches.head; cell; cell = cell->next)
7981  {
7982  IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
7983 
7984  addObjectDependency(dobj, attach->dobj.dumpId);
7985 
7986  if (attach->partitionIdx->partattaches.head != NULL)
7987  addConstrChildIdxDeps(dobj, attach->partitionIdx);
7988  }
7989 }
#define Assert(condition)
Definition: c.h:863
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:7974
struct SimplePtrListCell * next
Definition: simple_list.h:48
SimplePtrListCell * head
Definition: simple_list.h:54
IndxInfo * partitionIdx
Definition: pg_dump.h:421
DumpableObject dobj
Definition: pg_dump.h:419
SimplePtrList partattaches
Definition: pg_dump.h:411

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 5344 of file pg_dump.c.

5350 {
5351  if (dobj->depends_on_ext)
5352  {
5353  char *nm;
5354  PGresult *res;
5355  PQExpBuffer query;
5356  int ntups;
5357  int i_extname;
5358  int i;
5359 
5360  /* dodge fmtId() non-reentrancy */
5361  nm = pg_strdup(objname);
5362 
5363  query = createPQExpBuffer();
5364  appendPQExpBuffer(query,
5365  "SELECT e.extname "
5366  "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5367  "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5368  "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5369  "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5370  catalog,
5371  dobj->catId.oid);
5372  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5373  ntups = PQntuples(res);
5374  i_extname = PQfnumber(res, "extname");
5375  for (i = 0; i < ntups; i++)
5376  {
5377  appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5378  keyword, nm,
5379  fmtId(PQgetvalue(res, i, i_extname)));
5380  }
5381 
5382  PQclear(res);
5383  destroyPQExpBuffer(query);
5384  pg_free(nm);
5385  }
5386 }
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:288
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 19187 of file pg_dump.c.

19189 {
19190  bool res;
19191 
19192  res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
19193  fout->std_strings);
19194  if (!res)
19195  pg_log_warning("could not parse %s array", "reloptions");
19196 }
#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 5655 of file pg_dump.c.

5660 {
5661  DumpableObject *extobj = NULL;
5662  int i;
5663 
5664  if (!dobj->ext_member)
5665  return;
5666 
5667  /*
5668  * Find the parent extension. We could avoid this search if we wanted to
5669  * add a link field to DumpableObject, but the space costs of that would
5670  * be considerable. We assume that member objects could only have a
5671  * direct dependency on their own extension, not any others.
5672  */
5673  for (i = 0; i < dobj->nDeps; i++)
5674  {
5675  extobj = findObjectByDumpId(dobj->dependencies[i]);
5676  if (extobj && extobj->objType == DO_EXTENSION)
5677  break;
5678  extobj = NULL;
5679  }
5680  if (extobj == NULL)
5681  pg_fatal("could not find parent extension for %s %s",
5682  objtype, objname);
5683 
5684  appendPQExpBufferStr(upgrade_buffer,
5685  "\n-- For binary upgrade, handle extension membership the hard way\n");
5686  appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5687  fmtId(extobj->name),
5688  objtype);
5689  if (objnamespace && *objnamespace)
5690  appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5691  appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5692 }
DumpableObject * findObjectByDumpId(DumpId dumpId)
Definition: common.c:742
#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 5565 of file pg_dump.c.

5567 {
5570 
5572 
5573  /*
5574  * Preserve the OID and relfilenumber of the table, table's index, table's
5575  * toast table and toast table's index if any.
5576  *
5577  * One complexity is that the current table definition might not require
5578  * the creation of a TOAST table, but the old database might have a TOAST
5579  * table that was created earlier, before some wide columns were dropped.
5580  * By setting the TOAST oid we force creation of the TOAST heap and index
5581  * by the new backend, so we can copy the files during binary upgrade
5582  * without worrying about this case.
5583  */
5584  key.oid = pg_class_oid;
5586  sizeof(BinaryUpgradeClassOidItem),
5588 
5589  appendPQExpBufferStr(upgrade_buffer,
5590  "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5591 
5592  if (entry->relkind != RELKIND_INDEX &&
5593  entry->relkind != RELKIND_PARTITIONED_INDEX)
5594  {
5595  appendPQExpBuffer(upgrade_buffer,
5596  "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5597  pg_class_oid);
5598 
5599  /*
5600  * Not every relation has storage. Also, in a pre-v12 database,
5601  * partitioned tables have a relfilenumber, which should not be
5602  * preserved when upgrading.
5603  */
5604  if (RelFileNumberIsValid(entry->relfilenumber) &&
5605  entry->relkind != RELKIND_PARTITIONED_TABLE)
5606  appendPQExpBuffer(upgrade_buffer,
5607  "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5608  entry->relfilenumber);
5609 
5610  /*
5611  * In a pre-v12 database, partitioned tables might be marked as having
5612  * toast tables, but we should ignore them if so.
5613  */
5614  if (OidIsValid(entry->toast_oid) &&
5615  entry->relkind != RELKIND_PARTITIONED_TABLE)
5616  {
5617  appendPQExpBuffer(upgrade_buffer,
5618  "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5619  entry->toast_oid);
5620  appendPQExpBuffer(upgrade_buffer,
5621  "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5622  entry->toast_relfilenumber);
5623 
5624  /* every toast table has an index */
5625  appendPQExpBuffer(upgrade_buffer,
5626  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5627  entry->toast_index_oid);
5628  appendPQExpBuffer(upgrade_buffer,
5629  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5630  entry->toast_index_relfilenumber);
5631  }
5632  }
5633  else
5634  {
5635  /* Preserve the OID and relfilenumber of the index */
5636  appendPQExpBuffer(upgrade_buffer,
5637  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5638  pg_class_oid);
5639  appendPQExpBuffer(upgrade_buffer,
5640  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5641  entry->relfilenumber);
5642  }
5643 
5644  appendPQExpBufferChar(upgrade_buffer, '\n');
5645 }
#define OidIsValid(objectId)
Definition: c.h:780
static int nbinaryUpgradeClassOids
Definition: pg_dump.c:204
static BinaryUpgradeClassOidItem * binaryUpgradeClassOids
Definition: pg_dump.c:203
static int BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:5515
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:102
RelFileNumber toast_relfilenumber
Definition: pg_dump.c:100
RelFileNumber relfilenumber
Definition: pg_dump.c:98

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 5500 of file pg_dump.c.

5503 {
5504  Oid pg_type_oid = tbinfo->reltype;
5505 
5506  if (OidIsValid(pg_type_oid))
5507  binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5508  pg_type_oid, false, false);
5509 }
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:5420
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 5420 of file pg_dump.c.

5425 {
5426  PQExpBuffer upgrade_query = createPQExpBuffer();
5427  PGresult *res;
5428  Oid pg_type_array_oid;
5429  Oid pg_type_multirange_oid;
5430  Oid pg_type_multirange_array_oid;
5431  TypeInfo *tinfo;
5432 
5433  appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5434  appendPQExpBuffer(upgrade_buffer,
5435  "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5436  pg_type_oid);
5437 
5438  tinfo = findTypeByOid(pg_type_oid);
5439  if (tinfo)
5440  pg_type_array_oid = tinfo->typarray;
5441  else
5442  pg_type_array_oid = InvalidOid;
5443 
5444  if (!OidIsValid(pg_type_array_oid) && force_array_type)
5445  pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5446 
5447  if (OidIsValid(pg_type_array_oid))
5448  {
5449  appendPQExpBufferStr(upgrade_buffer,
5450  "\n-- For binary upgrade, must preserve pg_type array oid\n");
5451  appendPQExpBuffer(upgrade_buffer,
5452  "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5453  pg_type_array_oid);
5454  }
5455 
5456  /*
5457  * Pre-set the multirange type oid and its own array type oid.
5458  */
5459  if (include_multirange_type)
5460  {
5461  if (fout->remoteVersion >= 140000)
5462  {
5463  printfPQExpBuffer(upgrade_query,
5464  "SELECT t.oid, t.typarray "
5465  "FROM pg_catalog.pg_type t "
5466  "JOIN pg_catalog.pg_range r "
5467  "ON t.oid = r.rngmultitypid "
5468  "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5469  pg_type_oid);
5470 
5471  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5472 
5473  pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5474  pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5475 
5476  PQclear(res);
5477  }
5478  else
5479  {
5480  pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5481  pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5482  }
5483 
5484  appendPQExpBufferStr(upgrade_buffer,
5485  "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5486  appendPQExpBuffer(upgrade_buffer,
5487  "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5488  pg_type_multirange_oid);
5489  appendPQExpBufferStr(upgrade_buffer,
5490  "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5491  appendPQExpBuffer(upgrade_buffer,
5492  "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5493  pg_type_multirange_array_oid);
5494  }
5495 
5496  destroyPQExpBuffer(upgrade_query);
5497 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:876
static const gbtree_vinfo tinfo
Definition: btree_bit.c:108
PGresult * ExecuteSqlQueryForSingleRow(Archive *fout, const char *query)
Definition: pg_backup_db.c:303
static Oid get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
Definition: pg_dump.c:5389
#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 5515 of file pg_dump.c.

5516 {
5519 
5520  return pg_cmp_u32(v1.oid, v2.oid);
5521 }
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 18986 of file pg_dump.c.

18987 {
18988  ArchiveHandle *AH = (ArchiveHandle *) fout;
18989  TocEntry *te;
18990 
18991  /* Scan all TOC entries in the archive */
18992  for (te = AH->toc->next; te != AH->toc; te = te->next)
18993  {
18994  DumpableObject *dobj;
18995  DumpId *dependencies;
18996  int nDeps;
18997  int allocDeps;
18998 
18999  /* No need to process entries that will not be dumped */
19000  if (te->reqs == 0)
19001  continue;
19002  /* Ignore entries that already have "special" dependencies */
19003  if (te->nDeps > 0)
19004  continue;
19005  /* Otherwise, look up the item's original DumpableObject, if any */
19006  dobj = findObjectByDumpId(te->dumpId);
19007  if (dobj == NULL)
19008  continue;
19009  /* No work if it has no dependencies */
19010  if (dobj->nDeps <= 0)
19011  continue;
19012  /* Set up work array */
19013  allocDeps = 64;
19014  dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
19015  nDeps = 0;
19016  /* Recursively find all dumpable dependencies */
19017  findDumpableDependencies(AH, dobj,
19018  &dependencies, &nDeps, &allocDeps);
19019  /* And save 'em ... */
19020  if (nDeps > 0)
19021  {
19022  dependencies = (DumpId *) pg_realloc(dependencies,
19023  nDeps * sizeof(DumpId));
19024  te->dependencies = dependencies;
19025  te->nDeps = nDeps;
19026  }
19027  else
19028  free(dependencies);
19029  }
19030 }
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:19034
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 2929 of file pg_dump.c.

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

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

5532 {
5533  PGresult *res;
5534  const char *query;
5535 
5536  query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5537  "ct.relfilenode, i.indexrelid, cti.relfilenode "
5538  "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5539  "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5540  "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5541  "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5542  "ORDER BY c.oid;";
5543 
5544  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5545 
5549 
5550  for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5551  {
5559  }
5560 
5561  PQclear(res);
5562 }

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 10476 of file pg_dump.c.

10477 {
10478  PGresult *res;
10479  PQExpBuffer query;
10480  int i_description;
10481  int i_classoid;
10482  int i_objoid;
10483  int i_objsubid;
10484  int ntups;
10485  int i;
10486  DumpableObject *dobj;
10487 
10488  query = createPQExpBuffer();
10489 
10490  appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
10491  "FROM pg_catalog.pg_description "
10492  "ORDER BY classoid, objoid, objsubid");
10493 
10494  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10495 
10496  /* Construct lookup table containing OIDs in numeric form */
10497 
10498  i_description = PQfnumber(res, "description");
10499  i_classoid = PQfnumber(res, "classoid");
10500  i_objoid = PQfnumber(res, "objoid");
10501  i_objsubid = PQfnumber(res, "objsubid");
10502 
10503  ntups = PQntuples(res);
10504 
10505  comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
10506  ncomments = 0;
10507  dobj = NULL;
10508 
10509  for (i = 0; i < ntups; i++)
10510  {
10511  CatalogId objId;
10512  int subid;
10513 
10514  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
10515  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
10516  subid = atoi(PQgetvalue(res, i, i_objsubid));
10517 
10518  /* We needn't remember comments that don't match any dumpable object */
10519  if (dobj == NULL ||
10520  dobj->catId.tableoid != objId.tableoid ||
10521  dobj->catId.oid != objId.oid)
10522  dobj = findObjectByCatalogId(objId);
10523  if (dobj == NULL)
10524  continue;
10525 
10526  /*
10527  * Comments on columns of composite types are linked to the type's
10528  * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
10529  * in the type's own DumpableObject.
10530  */
10531  if (subid != 0 && dobj->objType == DO_TABLE &&
10532  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
10533  {
10534  TypeInfo *cTypeInfo;
10535 
10536  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
10537  if (cTypeInfo)
10538  cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
10539  }
10540  else
10541  dobj->components |= DUMP_COMPONENT_COMMENT;
10542 
10543  comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
10545  comments[ncomments].objoid = objId.oid;
10546  comments[ncomments].objsubid = subid;
10547  ncomments++;
10548  }
10549 
10550  PQclear(res);
10551  destroyPQExpBuffer(query);
10552 }
static int ncomments
Definition: pg_dump.c:196
static CommentItem * comments
Definition: pg_dump.c:195
#define DUMP_COMPONENT_COMMENT
Definition: pg_dump.h:99
Oid classoid
Definition: pg_dump.c:80
Oid objoid
Definition: pg_dump.c:81
int objsubid
Definition: pg_dump.c:82
const char * descr
Definition: pg_dump.c:79
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 10021 of file pg_dump.c.

10022 {
10023  PGresult *res;
10024  const char *query;
10025  int i;
10026 
10027  query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
10028 
10029  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
10030 
10032 
10034 
10035  for (i = 0; i < nrolenames; i++)
10036  {
10039  }
10040 
10041  PQclear(res);
10042 }
static RoleNameItem * rolenames
Definition: pg_dump.c:191
static int nrolenames
Definition: pg_dump.c:192
const char * rolename
Definition: pg_dump.c:74
Oid roleoid
Definition: pg_dump.c:73

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 15618 of file pg_dump.c.

15619 {
15620  PGresult *res;
15621  PQExpBuffer query;
15622  int i_label;
15623  int i_provider;
15624  int i_classoid;
15625  int i_objoid;
15626  int i_objsubid;
15627  int ntups;
15628  int i;
15629  DumpableObject *dobj;
15630 
15631  query = createPQExpBuffer();
15632 
15633  appendPQExpBufferStr(query,
15634  "SELECT label, provider, classoid, objoid, objsubid "
15635  "FROM pg_catalog.pg_seclabel "
15636  "ORDER BY classoid, objoid, objsubid");
15637 
15638  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15639 
15640  /* Construct lookup table containing OIDs in numeric form */
15641  i_label = PQfnumber(res, "label");
15642  i_provider = PQfnumber(res, "provider");
15643  i_classoid = PQfnumber(res, "classoid");
15644  i_objoid = PQfnumber(res, "objoid");
15645  i_objsubid = PQfnumber(res, "objsubid");
15646 
15647  ntups = PQntuples(res);
15648 
15649  seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
15650  nseclabels = 0;
15651  dobj = NULL;
15652 
15653  for (i = 0; i < ntups; i++)
15654  {
15655  CatalogId objId;
15656  int subid;
15657 
15658  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
15659  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
15660  subid = atoi(PQgetvalue(res, i, i_objsubid));
15661 
15662  /* We needn't remember labels that don't match any dumpable object */
15663  if (dobj == NULL ||
15664  dobj->catId.tableoid != objId.tableoid ||
15665  dobj->catId.oid != objId.oid)
15666  dobj = findObjectByCatalogId(objId);
15667  if (dobj == NULL)
15668  continue;
15669 
15670  /*
15671  * Labels on columns of composite types are linked to the type's
15672  * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
15673  * in the type's own DumpableObject.
15674  */
15675  if (subid != 0 && dobj->objType == DO_TABLE &&
15676  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
15677  {
15678  TypeInfo *cTypeInfo;
15679 
15680  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
15681  if (cTypeInfo)
15682  cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
15683  }
15684  else
15685  dobj->components |= DUMP_COMPONENT_SECLABEL;
15686 
15690  seclabels[nseclabels].objoid = objId.oid;
15691  seclabels[nseclabels].objsubid = subid;
15692  nseclabels++;
15693  }
15694 
15695  PQclear(res);
15696  destroyPQExpBuffer(query);
15697 }
static int nseclabels
Definition: pg_dump.c:200
static SecLabelItem * seclabels
Definition: pg_dump.c:199
#define DUMP_COMPONENT_SECLABEL
Definition: pg_dump.h:100
const char * provider
Definition: pg_dump.c:87
Oid classoid
Definition: pg_dump.c:89
int objsubid
Definition: pg_dump.c:91
const char * label
Definition: pg_dump.c:88
Oid objoid
Definition: pg_dump.c:90

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 17649 of file pg_dump.c.

17650 {
17651  PGresult *res;
17652  const char *query;
17653 
17654  /*
17655  * Before Postgres 10, sequence metadata is in the sequence itself. With
17656  * some extra effort, we might be able to use the sorted table for those
17657  * versions, but for now it seems unlikely to be worth it.
17658  *
17659  * Since version 18, we can gather the sequence data in this query with
17660  * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
17661  */
17662  if (fout->remoteVersion < 100000)
17663  return;
17664  else if (fout->remoteVersion < 180000 ||
17665  (fout->dopt->schemaOnly && !fout->dopt->sequence_data))
17666  query = "SELECT seqrelid, format_type(seqtypid, NULL), "
17667  "seqstart, seqincrement, "
17668  "seqmax, seqmin, "
17669  "seqcache, seqcycle, "
17670  "NULL, 'f' "
17671  "FROM pg_catalog.pg_sequence "
17672  "ORDER BY seqrelid";
17673  else
17674  query = "SELECT seqrelid, format_type(seqtypid, NULL), "
17675  "seqstart, seqincrement, "
17676  "seqmax, seqmin, "
17677  "seqcache, seqcycle, "
17678  "last_value, is_called "
17679  "FROM pg_catalog.pg_sequence, "
17680  "pg_get_sequence_data(seqrelid) "
17681  "ORDER BY seqrelid;";
17682 
17683  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
17684 
17687 
17688  for (int i = 0; i < nsequences; i++)
17689  {
17690  sequences[i].oid = atooid(PQgetvalue(res, i, 0));
17692  sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
17693  sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
17694  sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
17695  sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
17696  sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
17697  sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
17698  sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
17699  sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
17700  }
17701 
17702  PQclear(res);
17703 }
#define strtoi64(str, endptr, base)
Definition: c.h:1302
static int nsequences
Definition: pg_dump.c:208
static SeqType parse_sequence_type(const char *name)
Definition: pg_dump.c:17618
static SequenceItem * sequences
Definition: pg_dump.c:207
int64 minv
Definition: pg_dump.c:128
int64 cache
Definition: pg_dump.c:132
int64 startv
Definition: pg_dump.c:130
int64 maxv
Definition: pg_dump.c:129
bool is_called
Definition: pg_dump.c:134
int64 incby
Definition: pg_dump.c:131
int64 last_value
Definition: pg_dump.c:133
SeqType seqtype
Definition: pg_dump.c:126
bool cycled
Definition: pg_dump.c:127
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 13168 of file pg_dump.c.

13169 {
13170  char *name;
13171  char *paren;
13172  bool inquote;
13173 
13174  /* In all cases "-" means a null reference */
13175  if (strcmp(proc, "-") == 0)
13176  return NULL;
13177 
13178  name = pg_strdup(proc);
13179  /* find non-double-quoted left paren */
13180  inquote = false;
13181  for (paren = name; *paren; paren++)
13182  {
13183  if (*paren == '(' && !inquote)
13184  {
13185  *paren = '\0';
13186  break;
13187  }
13188  if (*paren == '"')
13189  inquote = !inquote;
13190  }
13191  return name;
13192 }
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 13239 of file pg_dump.c.

13240 {
13241  char *result;
13242  char query[128];
13243  PGresult *res;
13244 
13245  snprintf(query, sizeof(query),
13246  "SELECT '%u'::pg_catalog.regproc", funcOid);
13247  res = ExecuteSqlQueryForSingleRow(fout, query);
13248 
13249  result = pg_strdup(PQgetvalue(res, 0, 0));
13250 
13251  PQclear(res);
13252 
13253  return result;
13254 }
#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 18846 of file pg_dump.c.

18847 {
18848  DumpableObject *dobjs;
18849 
18850  dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
18851 
18852  dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
18853  dobjs[0].catId = nilCatalogId;
18854  AssignDumpId(dobjs + 0);
18855  dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
18856 
18857  dobjs[1].objType = DO_POST_DATA_BOUNDARY;
18858  dobjs[1].catId = nilCatalogId;
18859  AssignDumpId(dobjs + 1);
18860  dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
18861 
18862  return dobjs;
18863 }
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:634
static const CatalogId nilCatalogId
Definition: pg_dump.c:184

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 15893 of file pg_dump.c.

15894 {
15895  PQExpBuffer result = createPQExpBuffer();
15896  int j;
15897 
15898  appendPQExpBufferStr(result, "SELECT");
15899 
15900  for (j = 0; j < tbinfo->numatts; j++)
15901  {
15902  if (j > 0)
15903  appendPQExpBufferChar(result, ',');
15904  appendPQExpBufferStr(result, "\n ");
15905 
15906  appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
15907 
15908  /*
15909  * Must add collation if not default for the type, because CREATE OR
15910  * REPLACE VIEW won't change it
15911  */
15912  if (OidIsValid(tbinfo->attcollation[j]))
15913  {
15914  CollInfo *coll;
15915 
15916  coll = findCollationByOid(tbinfo->attcollation[j]);
15917  if (coll)
15918  appendPQExpBuffer(result, " COLLATE %s",
15919  fmtQualifiedDumpable(coll));
15920  }
15921 
15922  appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
15923  }
15924 
15925  return result;
15926 }
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:931
int j
Definition: isn.c:73
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:226
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 15844 of file pg_dump.c.

15845 {
15846  PQExpBuffer query = createPQExpBuffer();
15847  PQExpBuffer result = createPQExpBuffer();
15848  PGresult *res;
15849  int len;
15850 
15851  /* Fetch the view definition */
15852  appendPQExpBuffer(query,
15853  "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
15854  tbinfo->dobj.catId.oid);
15855 
15856  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15857 
15858  if (PQntuples(res) != 1)
15859  {
15860  if (PQntuples(res) < 1)
15861  pg_fatal("query to obtain definition of view \"%s\" returned no data",
15862  tbinfo->dobj.name);
15863  else
15864  pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
15865  tbinfo->dobj.name);
15866  }
15867 
15868  len = PQgetlength(res, 0, 0);
15869 
15870  if (len == 0)
15871  pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
15872  tbinfo->dobj.name);
15873 
15874  /* Strip off the trailing semicolon so that other things may follow. */
15875  Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
15876  appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
15877 
15878  PQclear(res);
15879  destroyPQExpBuffer(query);
15880 
15881  return result;
15882 }
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().

◆ determineNotNullFlags()

static void determineNotNullFlags ( Archive fout,
PGresult res,
int  r,
TableInfo tbinfo,
int  j,
int  i_notnull_name,
int  i_notnull_noinherit,
int  i_notnull_islocal 
)
static

Definition at line 9357 of file pg_dump.c.

9361 {
9362  DumpOptions *dopt = fout->dopt;
9363 
9364  /*
9365  * notnull_noinh is straight from the query result. notnull_islocal also,
9366  * though flagInhAttrs may change that one later in versions < 18.
9367  */
9368  tbinfo->notnull_noinh[j] = PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
9369  tbinfo->notnull_islocal[j] = PQgetvalue(res, r, i_notnull_islocal)[0] == 't';
9370 
9371  /*
9372  * Determine a constraint name to use. If the column is not marked not-
9373  * null, we set NULL which cues ... to do nothing. An empty string says
9374  * to print an unnamed NOT NULL, and anything else is a constraint name to
9375  * use.
9376  */
9377  if (fout->remoteVersion < 180000)
9378  {
9379  /*
9380  * < 18 doesn't have not-null names, so an unnamed constraint is
9381  * sufficient.
9382  */
9383  if (PQgetisnull(res, r, i_notnull_name))
9384  tbinfo->notnull_constrs[j] = NULL;
9385  else
9386  tbinfo->notnull_constrs[j] = "";
9387  }
9388  else
9389  {
9390  if (PQgetisnull(res, r, i_notnull_name))
9391  tbinfo->notnull_constrs[j] = NULL;
9392  else
9393  {
9394  /*
9395  * In binary upgrade of inheritance child tables, must have a
9396  * constraint name that we can UPDATE later.
9397  */
9398  if (dopt->binary_upgrade &&
9399  !tbinfo->ispartition &&
9400  !tbinfo->notnull_islocal)
9401  {
9402  tbinfo->notnull_constrs[j] =
9403  pstrdup(PQgetvalue(res, r, i_notnull_name));
9404  }
9405  else
9406  {
9407  char *default_name;
9408 
9409  /* XXX should match ChooseConstraintName better */
9410  default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
9411  tbinfo->attnames[j]);
9412  if (strcmp(default_name,
9413  PQgetvalue(res, r, i_notnull_name)) == 0)
9414  tbinfo->notnull_constrs[j] = "";
9415  else
9416  {
9417  tbinfo->notnull_constrs[j] =
9418  pstrdup(PQgetvalue(res, r, i_notnull_name));
9419  }
9420  }
9421  }
9422  }
9423 }
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
char * pstrdup(const char *in)
Definition: mcxt.c:1696
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
char ** notnull_constrs
Definition: pg_dump.h:350
bool ispartition
Definition: pg_dump.h:323
bool * notnull_islocal
Definition: pg_dump.h:355
bool * notnull_noinh
Definition: pg_dump.h:354

References _tableInfo::attnames, _dumpOptions::binary_upgrade, _tableInfo::dobj, Archive::dopt, _tableInfo::ispartition, j, _dumpableObject::name, _tableInfo::notnull_constrs, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, PQgetisnull(), PQgetvalue(), psprintf(), pstrdup(), Archive::remoteVersion, and res.

Referenced by getTableAttrs().

◆ dumpAccessMethod()

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

Definition at line 13261 of file pg_dump.c.

13262 {
13263  DumpOptions *dopt = fout->dopt;
13264  PQExpBuffer q;
13265  PQExpBuffer delq;
13266  char *qamname;
13267 
13268  /* Do nothing in data-only dump */
13269  if (dopt->dataOnly)
13270  return;
13271 
13272  q = createPQExpBuffer();
13273  delq = createPQExpBuffer();
13274 
13275  qamname = pg_strdup(fmtId(aminfo->dobj.name));
13276 
13277  appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
13278 
13279  switch (aminfo->amtype)
13280  {
13281  case AMTYPE_INDEX:
13282  appendPQExpBufferStr(q, "TYPE INDEX ");
13283  break;
13284  case AMTYPE_TABLE:
13285  appendPQExpBufferStr(q, "TYPE TABLE ");
13286  break;
13287  default:
13288  pg_log_warning("invalid type \"%c\" of access method \"%s\"",
13289  aminfo->amtype, qamname);
13290  destroyPQExpBuffer(q);
13291  destroyPQExpBuffer(delq);
13292  free(qamname);
13293  return;
13294  }
13295 
13296  appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
13297 
13298  appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
13299  qamname);
13300 
13301  if (dopt->binary_upgrade)
13303  "ACCESS METHOD", qamname, NULL);
13304 
13305  if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13306  ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
13307  ARCHIVE_OPTS(.tag = aminfo->dobj.name,
13308  .description = "ACCESS METHOD",
13309  .section = SECTION_PRE_DATA,
13310  .createStmt = q->data,
13311  .dropStmt = delq->data));
13312 
13313  /* Dump Access Method Comments */
13314  if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13315  dumpComment(fout, "ACCESS METHOD", qamname,
13316  NULL, "",
13317  aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
13318 
13319  destroyPQExpBuffer(q);
13320  destroyPQExpBuffer(delq);
13321  free(qamname);
13322 }
@ 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:10285
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:5655
#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 15249 of file pg_dump.c.

15253 {
15254  DumpId aclDumpId = InvalidDumpId;
15255  DumpOptions *dopt = fout->dopt;
15256  const char *acls = dacl->acl;
15257  const char *acldefault = dacl->acldefault;
15258  char privtype = dacl->privtype;
15259  const char *initprivs = dacl->initprivs;
15260  const char *baseacls;
15261  PQExpBuffer sql;
15262 
15263  /* Do nothing if ACL dump is not enabled */
15264  if (dopt->aclsSkip)
15265  return InvalidDumpId;
15266 
15267  /* --data-only skips ACLs *except* large object ACLs */
15268  if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15269  return InvalidDumpId;
15270 
15271  sql = createPQExpBuffer();
15272 
15273  /*
15274  * In binary upgrade mode, we don't run an extension's script but instead
15275  * dump out the objects independently and then recreate them. To preserve
15276  * any initial privileges which were set on extension objects, we need to
15277  * compute the set of GRANT and REVOKE commands necessary to get from the
15278  * default privileges of an object to its initial privileges as recorded
15279  * in pg_init_privs.
15280  *
15281  * At restore time, we apply these commands after having called
15282  * binary_upgrade_set_record_init_privs(true). That tells the backend to
15283  * copy the results into pg_init_privs. This is how we preserve the
15284  * contents of that catalog across binary upgrades.
15285  */
15286  if (dopt->binary_upgrade && privtype == 'e' &&
15287  initprivs && *initprivs != '\0')
15288  {
15289  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
15290  if (!buildACLCommands(name, subname, nspname, type,
15291  initprivs, acldefault, owner,
15292  "", fout->remoteVersion, sql))
15293  pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
15294  initprivs, acldefault, name, type);
15295  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
15296  }
15297 
15298  /*
15299  * Now figure the GRANT and REVOKE commands needed to get to the object's
15300  * actual current ACL, starting from the initprivs if given, else from the
15301  * object-type-specific default. Also, while buildACLCommands will assume
15302  * that a NULL/empty acls string means it needn't do anything, what that
15303  * actually represents is the object-type-specific default; so we need to
15304  * substitute the acldefault string to get the right results in that case.
15305  */
15306  if (initprivs && *initprivs != '\0')
15307  {
15308  baseacls = initprivs;
15309  if (acls == NULL || *acls == '\0')
15310  acls = acldefault;
15311  }
15312  else
15313  baseacls = acldefault;
15314 
15315  if (!buildACLCommands(name, subname, nspname, type,
15316  acls, baseacls, owner,
15317  "", fout->remoteVersion, sql))
15318  pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
15319  acls, baseacls, name, type);
15320 
15321  if (sql->len > 0)
15322  {
15323  PQExpBuffer tagbuf = createPQExpBuffer();
15324  DumpId aclDeps[2];
15325  int nDeps = 0;
15326 
15327  if (tag)
15328  appendPQExpBufferStr(tagbuf, tag);
15329  else if (subname)
15330  appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
15331  else
15332  appendPQExpBuffer(tagbuf, "%s %s", type, name);
15333 
15334  aclDeps[nDeps++] = objDumpId;
15335  if (altDumpId != InvalidDumpId)
15336  aclDeps[nDeps++] = altDumpId;
15337 
15338  aclDumpId = createDumpId();
15339 
15340  ArchiveEntry(fout, nilCatalogId, aclDumpId,
15341  ARCHIVE_OPTS(.tag = tagbuf->data,
15342  .namespace = nspname,
15343  .owner = owner,
15344  .description = "ACL",
15345  .section = SECTION_NONE,
15346  .createStmt = sql->data,
15347  .deps = aclDeps,
15348  .nDeps = nDeps));
15349 
15350  destroyPQExpBuffer(tagbuf);
15351  }
15352 
15353  destroyPQExpBuffer(sql);
15354 
15355  return aclDumpId;
15356 }
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:787
DumpId createDumpId(void)
Definition: common.c:722
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 14214 of file pg_dump.c.

14215 {
14216  DumpOptions *dopt = fout->dopt;
14217  PQExpBuffer query;
14218  PQExpBuffer q;
14219  PQExpBuffer delq;
14220  PQExpBuffer details;
14221  char *aggsig; /* identity signature */
14222  char *aggfullsig = NULL; /* full signature */
14223  char *aggsig_tag;
14224  PGresult *res;
14225  int i_agginitval;
14226  int i_aggminitval;
14227  const char *aggtransfn;
14228  const char *aggfinalfn;
14229  const char *aggcombinefn;
14230  const char *aggserialfn;
14231  const char *aggdeserialfn;
14232  const char *aggmtransfn;
14233  const char *aggminvtransfn;
14234  const char *aggmfinalfn;
14235  bool aggfinalextra;
14236  bool aggmfinalextra;
14237  char aggfinalmodify;
14238  char aggmfinalmodify;
14239  const char *aggsortop;
14240  char *aggsortconvop;
14241  char aggkind;
14242  const char *aggtranstype;
14243  const char *aggtransspace;
14244  const char *aggmtranstype;
14245  const char *aggmtransspace;
14246  const char *agginitval;
14247  const char *aggminitval;
14248  const char *proparallel;
14249  char defaultfinalmodify;
14250 
14251  /* Do nothing in data-only dump */
14252  if (dopt->dataOnly)
14253  return;
14254 
14255  query = createPQExpBuffer();
14256  q = createPQExpBuffer();
14257  delq = createPQExpBuffer();
14258  details = createPQExpBuffer();
14259 
14260  if (!fout->is_prepared[PREPQUERY_DUMPAGG])
14261  {
14262  /* Set up query for aggregate-specific details */
14263  appendPQExpBufferStr(query,
14264  "PREPARE dumpAgg(pg_catalog.oid) AS\n");
14265 
14266  appendPQExpBufferStr(query,
14267  "SELECT "
14268  "aggtransfn,\n"
14269  "aggfinalfn,\n"
14270  "aggtranstype::pg_catalog.regtype,\n"
14271  "agginitval,\n"
14272  "aggsortop,\n"
14273  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
14274  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
14275 
14276  if (fout->remoteVersion >= 90400)
14277  appendPQExpBufferStr(query,
14278  "aggkind,\n"
14279  "aggmtransfn,\n"
14280  "aggminvtransfn,\n"
14281  "aggmfinalfn,\n"
14282  "aggmtranstype::pg_catalog.regtype,\n"
14283  "aggfinalextra,\n"
14284  "aggmfinalextra,\n"
14285  "aggtransspace,\n"
14286  "aggmtransspace,\n"
14287  "aggminitval,\n");
14288  else
14289  appendPQExpBufferStr(query,
14290  "'n' AS aggkind,\n"
14291  "'-' AS aggmtransfn,\n"
14292  "'-' AS aggminvtransfn,\n"
14293  "'-' AS aggmfinalfn,\n"
14294  "0 AS aggmtranstype,\n"
14295  "false AS aggfinalextra,\n"
14296  "false AS aggmfinalextra,\n"
14297  "0 AS aggtransspace,\n"
14298  "0 AS aggmtransspace,\n"
14299  "NULL AS aggminitval,\n");
14300 
14301  if (fout->remoteVersion >= 90600)
14302  appendPQExpBufferStr(query,
14303  "aggcombinefn,\n"
14304  "aggserialfn,\n"
14305  "aggdeserialfn,\n"
14306  "proparallel,\n");
14307  else
14308  appendPQExpBufferStr(query,
14309  "'-' AS aggcombinefn,\n"
14310  "'-' AS aggserialfn,\n"
14311  "'-' AS aggdeserialfn,\n"
14312  "'u' AS proparallel,\n");
14313 
14314  if (fout->remoteVersion >= 110000)
14315  appendPQExpBufferStr(query,
14316  "aggfinalmodify,\n"
14317  "aggmfinalmodify\n");
14318  else
14319  appendPQExpBufferStr(query,
14320  "'0' AS aggfinalmodify,\n"
14321  "'0' AS aggmfinalmodify\n");
14322 
14323  appendPQExpBufferStr(query,
14324  "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
14325  "WHERE a.aggfnoid = p.oid "
14326  "AND p.oid = $1");
14327 
14328  ExecuteSqlStatement(fout, query->data);
14329 
14330  fout->is_prepared[PREPQUERY_DUMPAGG] = true;
14331  }
14332 
14333  printfPQExpBuffer(query,
14334  "EXECUTE dumpAgg('%u')",
14335  agginfo->aggfn.dobj.catId.oid);
14336 
14337  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14338 
14339  i_agginitval = PQfnumber(res, "agginitval");
14340  i_aggminitval = PQfnumber(res, "aggminitval");
14341 
14342  aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
14343  aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
14344  aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
14345  aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
14346  aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
14347  aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
14348  aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
14349  aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
14350  aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
14351  aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
14352  aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
14353  aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
14354  aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
14355  aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
14356  aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
14357  aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
14358  aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
14359  aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
14360  agginitval = PQgetvalue(res, 0, i_agginitval);
14361  aggminitval = PQgetvalue(res, 0, i_aggminitval);
14362  proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
14363 
14364  {
14365  char *funcargs;
14366  char *funciargs;
14367 
14368  funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
14369  funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
14370  aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
14371  aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
14372  }
14373 
14374  aggsig_tag = format_aggregate_signature(agginfo, fout, false);
14375 
14376  /* identify default modify flag for aggkind (must match DefineAggregate) */
14377  defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
14378  /* replace omitted flags for old versions */
14379  if (aggfinalmodify == '0')
14380  aggfinalmodify = defaultfinalmodify;
14381  if (aggmfinalmodify == '0')
14382  aggmfinalmodify = defaultfinalmodify;
14383 
14384  /* regproc and regtype output is already sufficiently quoted */
14385  appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
14386  aggtransfn, aggtranstype);
14387 
14388  if (strcmp(aggtransspace, "0") != 0)
14389  {
14390  appendPQExpBuffer(details, ",\n SSPACE = %s",
14391  aggtransspace);
14392  }
14393 
14394  if (!PQgetisnull(res, 0, i_agginitval))
14395  {
14396  appendPQExpBufferStr(details, ",\n INITCOND = ");
14397  appendStringLiteralAH(details, agginitval, fout);
14398  }
14399 
14400  if (strcmp(aggfinalfn, "-") != 0)
14401  {
14402  appendPQExpBuffer(details, ",\n FINALFUNC = %s",
14403  aggfinalfn);
14404  if (aggfinalextra)
14405  appendPQExpBufferStr(details, ",\n FINALFUNC_EXTRA");
14406  if (aggfinalmodify != defaultfinalmodify)
14407  {
14408  switch (aggfinalmodify)
14409  {
14410  case AGGMODIFY_READ_ONLY:
14411  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_ONLY");
14412  break;
14413  case AGGMODIFY_SHAREABLE:
14414  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHAREABLE");
14415  break;
14416  case AGGMODIFY_READ_WRITE:
14417  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_WRITE");
14418  break;
14419  default:
14420  pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
14421  agginfo->aggfn.dobj.name);
14422  break;
14423  }
14424  }
14425  }
14426 
14427  if (strcmp(aggcombinefn, "-") != 0)
14428  appendPQExpBuffer(details, ",\n COMBINEFUNC = %s", aggcombinefn);
14429 
14430  if (strcmp(aggserialfn, "-") != 0)
14431  appendPQExpBuffer(details, ",\n SERIALFUNC = %s", aggserialfn);
14432 
14433  if (strcmp(aggdeserialfn, "-") != 0)
14434  appendPQExpBuffer(details, ",\n DESERIALFUNC = %s", aggdeserialfn);
14435 
14436  if (strcmp(aggmtransfn, "-") != 0)
14437  {
14438  appendPQExpBuffer(details, ",\n MSFUNC = %s,\n MINVFUNC = %s,\n MSTYPE = %s",
14439  aggmtransfn,
14440  aggminvtransfn,
14441  aggmtranstype);
14442  }
14443 
14444  if (strcmp(aggmtransspace, "0") != 0)
14445  {
14446  appendPQExpBuffer(details, ",\n MSSPACE = %s",
14447  aggmtransspace);
14448  }
14449 
14450  if (!PQgetisnull(res, 0, i_aggminitval))
14451  {
14452  appendPQExpBufferStr(details, ",\n MINITCOND = ");
14453  appendStringLiteralAH(details, aggminitval, fout);
14454  }
14455 
14456  if (strcmp(aggmfinalfn, "-") != 0)
14457  {
14458  appendPQExpBuffer(details, ",\n MFINALFUNC = %s",
14459  aggmfinalfn);
14460  if (aggmfinalextra)
14461  appendPQExpBufferStr(details, ",\n MFINALFUNC_EXTRA");
14462  if (aggmfinalmodify != defaultfinalmodify)
14463  {
14464  switch (aggmfinalmodify)
14465  {
14466  case AGGMODIFY_READ_ONLY:
14467  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_ONLY");
14468  break;
14469  case AGGMODIFY_SHAREABLE:
14470  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHAREABLE");
14471  break;
14472  case AGGMODIFY_READ_WRITE:
14473  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_WRITE");
14474  break;
14475  default:
14476  pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
14477  agginfo->aggfn.dobj.name);
14478  break;
14479  }
14480  }
14481  }
14482 
14483  aggsortconvop = getFormattedOperatorName(aggsortop);
14484  if (aggsortconvop)
14485  {
14486  appendPQExpBuffer(details, ",\n SORTOP = %s",
14487  aggsortconvop);
14488  free(aggsortconvop);
14489  }
14490 
14491  if (aggkind == AGGKIND_HYPOTHETICAL)
14492  appendPQExpBufferStr(details, ",\n HYPOTHETICAL");
14493 
14494  if (proparallel[0] != PROPARALLEL_UNSAFE)
14495  {
14496  if (proparallel[0] == PROPARALLEL_SAFE)
14497  appendPQExpBufferStr(details, ",\n PARALLEL = safe");
14498  else if (proparallel[0] == PROPARALLEL_RESTRICTED)
14499  appendPQExpBufferStr(details, ",\n PARALLEL = restricted");
14500  else if (proparallel[0] != PROPARALLEL_UNSAFE)
14501  pg_fatal("unrecognized proparallel value for function \"%s\"",
14502  agginfo->aggfn.dobj.name);
14503  }
14504 
14505  appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
14506  fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
14507  aggsig);
14508 
14509  appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
14510  fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
14511  aggfullsig ? aggfullsig : aggsig, details->data);
14512 
14513  if (dopt->binary_upgrade)
14514  binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
14515  "AGGREGATE", aggsig,
14516  agginfo->aggfn.dobj.namespace->dobj.name);
14517 
14518  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
14519  ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
14520  agginfo->aggfn.dobj.dumpId,
14521  ARCHIVE_OPTS(.tag = aggsig_tag,
14522  .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
14523  .owner = agginfo->aggfn.rolname,
14524  .description = "AGGREGATE",
14525  .section = SECTION_PRE_DATA,
14526  .createStmt = q->data,
14527  .dropStmt = delq->data));
14528 
14529  /* Dump Aggregate Comments */
14530  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
14531  dumpComment(fout, "AGGREGATE", aggsig,
14532  agginfo->aggfn.dobj.namespace->dobj.name,
14533  agginfo->aggfn.rolname,
14534  agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
14535 
14536  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
14537  dumpSecLabel(fout, "AGGREGATE", aggsig,
14538  agginfo->aggfn.dobj.namespace->dobj.name,
14539  agginfo->aggfn.rolname,
14540  agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
14541 
14542  /*
14543  * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
14544  * command look like a function's GRANT; in particular this affects the
14545  * syntax for zero-argument aggregates and ordered-set aggregates.
14546  */
14547  free(aggsig);
14548 
14549  aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14550 
14551  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14552  dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
14553  "FUNCTION", aggsig, NULL,
14554  agginfo->aggfn.dobj.namespace->dobj.name,
14555  NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
14556 
14557  free(aggsig);
14558  free(aggfullsig);
14559  free(aggsig_tag);
14560 
14561  PQclear(res);
14562 
14563  destroyPQExpBuffer(query);
14564  destroyPQExpBuffer(q);
14565  destroyPQExpBuffer(delq);
14566  destroyPQExpBuffer(details);
14567 }
#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:276
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:15249
static char * getFormattedOperatorName(const char *oproid)
Definition: pg_dump.c:13209
static char * format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
Definition: pg_dump.c:12270
static char * format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
Definition: pg_dump.c:14182
static char * format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
Definition: pg_dump.c:12247
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:15377
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 16959 of file pg_dump.c.

16960 {
16961  DumpOptions *dopt = fout->dopt;
16962  TableInfo *tbinfo = adinfo->adtable;
16963  int adnum = adinfo->adnum;
16964  PQExpBuffer q;
16965  PQExpBuffer delq;
16966  char *qualrelname;
16967  char *tag;
16968  char *foreign;
16969 
16970  /* Do nothing in data-only dump */
16971  if (dopt->dataOnly)
16972  return;
16973 
16974  /* Skip if not "separate"; it was dumped in the table's definition */
16975  if (!adinfo->separate)
16976  return;
16977 
16978  q = createPQExpBuffer();
16979  delq = createPQExpBuffer();
16980 
16981  qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
16982 
16983  foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
16984 
16986  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
16987  foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
16988  adinfo->adef_expr);
16989 
16990  appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
16991  foreign, qualrelname,
16992  fmtId(tbinfo->attnames[adnum - 1]));
16993 
16994  tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
16995 
16996  if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16997  ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
16998  ARCHIVE_OPTS(.tag = tag,
16999  .namespace = tbinfo->dobj.namespace->dobj.name,
17000  .owner = tbinfo->rolname,
17001  .description = "DEFAULT",
17002  .section = SECTION_PRE_DATA,
17003  .createStmt = q->data,
17004  .dropStmt = delq->data));
17005 
17006  free(tag);
17007  destroyPQExpBuffer(q);
17008  destroyPQExpBuffer(delq);
17009  free(qualrelname);
17010 }
DumpableObject dobj
Definition: pg_dump.h:380
char * adef_expr
Definition: pg_dump.h:383
TableInfo * adtable
Definition: pg_dump.h:381
bool separate
Definition: pg_dump.h:384
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 11352 of file pg_dump.c.

11353 {
11354  DumpOptions *dopt = fout->dopt;
11356  PQExpBuffer delq = createPQExpBuffer();
11357  PQExpBuffer query = createPQExpBuffer();
11358  PGresult *res;
11359  char *qtypname;
11360  char *qualtypname;
11361  char *typlen;
11362  char *typinput;
11363  char *typoutput;
11364  char *typreceive;
11365  char *typsend;
11366  char *typmodin;
11367  char *typmodout;
11368  char *typanalyze;
11369  char *typsubscript;
11370  Oid typreceiveoid;
11371  Oid typsendoid;
11372  Oid typmodinoid;
11373  Oid typmodoutoid;
11374  Oid typanalyzeoid;
11375  Oid typsubscriptoid;
11376  char *typcategory;
11377  char *typispreferred;
11378  char *typdelim;
11379  char *typbyval;
11380  char *typalign;
11381  char *typstorage;
11382  char *typcollatable;
11383  char *typdefault;
11384  bool typdefault_is_literal = false;
11385 
11386  if (!fout->is_prepared[PREPQUERY_DUMPBASETYPE])
11387  {
11388  /* Set up query for type-specific details */
11389  appendPQExpBufferStr(query,
11390  "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
11391  "SELECT typlen, "
11392  "typinput, typoutput, typreceive, typsend, "
11393  "typreceive::pg_catalog.oid AS typreceiveoid, "
11394  "typsend::pg_catalog.oid AS typsendoid, "
11395  "typanalyze, "
11396  "typanalyze::pg_catalog.oid AS typanalyzeoid, "
11397  "typdelim, typbyval, typalign, typstorage, "
11398  "typmodin, typmodout, "
11399  "typmodin::pg_catalog.oid AS typmodinoid, "
11400  "typmodout::pg_catalog.oid AS typmodoutoid, "
11401  "typcategory, typispreferred, "
11402  "(typcollation <> 0) AS typcollatable, "
11403  "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
11404 
11405  if (fout->remoteVersion >= 140000)
11406  appendPQExpBufferStr(query,
11407  "typsubscript, "
11408  "typsubscript::pg_catalog.oid AS typsubscriptoid ");
11409  else
11410  appendPQExpBufferStr(query,
11411  "'-' AS typsubscript, 0 AS typsubscriptoid ");
11412 
11413  appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
11414  "WHERE oid = $1");
11415 
11416  ExecuteSqlStatement(fout, query->data);
11417 
11418  fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
11419  }
11420 
11421  printfPQExpBuffer(query,
11422  "EXECUTE dumpBaseType('%u')",
11423  tyinfo->dobj.catId.oid);
11424 
11425  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11426 
11427  typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
11428  typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
11429  typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
11430  typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
11431  typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
11432  typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
11433  typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
11434  typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
11435  typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
11436  typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
11437  typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
11438  typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
11439  typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
11440  typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
11441  typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
11442  typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
11443  typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
11444  typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
11445  typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
11446  typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
11447  typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
11448  typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
11449  if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
11450  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
11451  else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
11452  {
11453  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
11454  typdefault_is_literal = true; /* it needs quotes */
11455  }
11456  else
11457  typdefault = NULL;
11458 
11459  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11460  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11461 
11462  /*
11463  * The reason we include CASCADE is that the circular dependency between
11464  * the type and its I/O functions makes it impossible to drop the type any
11465  * other way.
11466  */
11467  appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
11468 
11469  /*
11470  * We might already have a shell type, but setting pg_type_oid is
11471  * harmless, and in any case we'd better set the array type OID.
11472  */
11473  if (dopt->binary_upgrade)
11475  tyinfo->dobj.catId.oid,
11476  false, false);
11477 
11479  "CREATE TYPE %s (\n"
11480  " INTERNALLENGTH = %s",
11481  qualtypname,
11482  (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
11483 
11484  /* regproc result is sufficiently quoted already */
11485  appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
11486  appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
11487  if (OidIsValid(typreceiveoid))
11488  appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
11489  if (OidIsValid(typsendoid))
11490  appendPQExpBuffer(q, ",\n SEND = %s", typsend);
11491  if (OidIsValid(typmodinoid))
11492  appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
11493  if (OidIsValid(typmodoutoid))
11494  appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
11495  if (OidIsValid(typanalyzeoid))
11496  appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
11497 
11498  if (strcmp(typcollatable, "t") == 0)
11499  appendPQExpBufferStr(q, ",\n COLLATABLE = true");
11500 
11501  if (typdefault != NULL)
11502  {
11503  appendPQExpBufferStr(q, ",\n DEFAULT = ");
11504  if (typdefault_is_literal)
11505  appendStringLiteralAH(q, typdefault, fout);
11506  else
11507  appendPQExpBufferStr(q, typdefault);
11508  }
11509 
11510  if (OidIsValid(typsubscriptoid))
11511  appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
11512 
11513  if (OidIsValid(tyinfo->typelem))
11514  appendPQExpBuffer(q, ",\n ELEMENT = %s",
11515  getFormattedTypeName(fout, tyinfo->typelem,
11516  zeroIsError));
11517 
11518  if (strcmp(typcategory, "U") != 0)
11519  {
11520  appendPQExpBufferStr(q, ",\n CATEGORY = ");
11521  appendStringLiteralAH(q, typcategory, fout);
11522  }
11523 
11524  if (strcmp(typispreferred, "t") == 0)
11525  appendPQExpBufferStr(q, ",\n PREFERRED = true");
11526 
11527  if (typdelim && strcmp(typdelim, ",") != 0)
11528  {
11529  appendPQExpBufferStr(q, ",\n DELIMITER = ");
11530  appendStringLiteralAH(q, typdelim, fout);
11531  }
11532 
11533  if (*typalign == TYPALIGN_CHAR)
11534  appendPQExpBufferStr(q, ",\n ALIGNMENT = char");
11535  else if (*typalign == TYPALIGN_SHORT)
11536  appendPQExpBufferStr(q, ",\n ALIGNMENT = int2");
11537  else if (*typalign == TYPALIGN_INT)
11538  appendPQExpBufferStr(q, ",\n ALIGNMENT = int4");
11539  else if (*typalign == TYPALIGN_DOUBLE)
11540  appendPQExpBufferStr(q, ",\n ALIGNMENT = double");
11541 
11542  if (*typstorage == TYPSTORAGE_PLAIN)
11543  appendPQExpBufferStr(q, ",\n STORAGE = plain");
11544  else if (*typstorage == TYPSTORAGE_EXTERNAL)
11545  appendPQExpBufferStr(q, ",\n STORAGE = external");
11546  else if (*typstorage == TYPSTORAGE_EXTENDED)
11547  appendPQExpBufferStr(q, ",\n STORAGE = extended");
11548  else if (*typstorage == TYPSTORAGE_MAIN)
11549  appendPQExpBufferStr(q, ",\n STORAGE = main");
11550 
11551  if (strcmp(typbyval, "t") == 0)
11552  appendPQExpBufferStr(q, ",\n PASSEDBYVALUE");
11553 
11554  appendPQExpBufferStr(q, "\n);\n");
11555 
11556  if (dopt->binary_upgrade)
11558  "TYPE", qtypname,
11559  tyinfo->dobj.namespace->dobj.name);
11560 
11561  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11562  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11563  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11564  .namespace = tyinfo->dobj.namespace->dobj.name,
11565  .owner = tyinfo->rolname,
11566  .description = "TYPE",
11567  .section = SECTION_PRE_DATA,
11568  .createStmt = q->data,
11569  .dropStmt = delq->data));
11570 
11571  /* Dump Type Comments and Security Labels */
11572  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11573  dumpComment(fout, "TYPE", qtypname,
11574  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11575  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11576 
11577  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11578  dumpSecLabel(fout, "TYPE", qtypname,
11579  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11580  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11581 
11582  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11583  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11584  qtypname, NULL,
11585  tyinfo->dobj.namespace->dobj.name,
11586  NULL, tyinfo->rolname, &tyinfo->dacl);
11587 
11588  PQclear(res);
11589  destroyPQExpBuffer(q);
11590  destroyPQExpBuffer(delq);
11591  destroyPQExpBuffer(query);
11592  free(qtypname);
11593  free(qualtypname);
11594 }
@ PREPQUERY_DUMPBASETYPE
Definition: pg_backup.h:67
static const char * getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
Definition: pg_dump.c:19090
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 12715 of file pg_dump.c.

12716 {
12717  DumpOptions *dopt = fout->dopt;
12718  PQExpBuffer defqry;
12719  PQExpBuffer delqry;
12720  PQExpBuffer labelq;
12721  PQExpBuffer castargs;
12722  FuncInfo *funcInfo = NULL;
12723  const char *sourceType;
12724  const char *targetType;
12725 
12726  /* Do nothing in data-only dump */
12727  if (dopt->dataOnly)
12728  return;
12729 
12730  /* Cannot dump if we don't have the cast function's info */
12731  if (OidIsValid(cast->castfunc))
12732  {
12733  funcInfo = findFuncByOid(cast->castfunc);
12734  if (funcInfo == NULL)
12735  pg_fatal("could not find function definition for function with OID %u",
12736  cast->castfunc);
12737  }
12738 
12739  defqry = createPQExpBuffer();
12740  delqry = createPQExpBuffer();
12741  labelq = createPQExpBuffer();
12742  castargs = createPQExpBuffer();
12743 
12744  sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
12745  targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
12746  appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
12747  sourceType, targetType);
12748 
12749  appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
12750  sourceType, targetType);
12751 
12752  switch (cast->castmethod)
12753  {
12754  case COERCION_METHOD_BINARY:
12755  appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
12756  break;
12757  case COERCION_METHOD_INOUT:
12758  appendPQExpBufferStr(defqry, "WITH INOUT");
12759  break;
12760  case COERCION_METHOD_FUNCTION:
12761  if (funcInfo)
12762  {
12763  char *fsig = format_function_signature(fout, funcInfo, true);
12764 
12765  /*
12766  * Always qualify the function name (format_function_signature
12767  * won't qualify it).
12768  */
12769  appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
12770  fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
12771  free(fsig);
12772  }
12773  else
12774  pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
12775  break;
12776  default:
12777  pg_log_warning("bogus value in pg_cast.castmethod field");
12778  }
12779 
12780  if (cast->castcontext == 'a')
12781  appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
12782  else if (cast->castcontext == 'i')
12783  appendPQExpBufferStr(defqry, " AS IMPLICIT");
12784  appendPQExpBufferStr(defqry, ";\n");
12785 
12786  appendPQExpBuffer(labelq, "CAST (%s AS %s)",
12787  sourceType, targetType);
12788 
12789  appendPQExpBuffer(castargs, "(%s AS %s)",
12790  sourceType, targetType);
12791 
12792  if (dopt->binary_upgrade)
12793  binary_upgrade_extension_member(defqry, &cast->dobj,
12794  "CAST", castargs->data, NULL);
12795 
12796  if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
12797  ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
12798  ARCHIVE_OPTS(.tag = labelq->data,
12799  .description = "CAST",
12800  .section = SECTION_PRE_DATA,
12801  .createStmt = defqry->data,
12802  .dropStmt = delqry->data));
12803 
12804  /* Dump Cast Comments */
12805  if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
12806  dumpComment(fout, "CAST", castargs->data,
12807  NULL, "",
12808  cast->dobj.catId, 0, cast->dobj.dumpId);
12809 
12810  destroyPQExpBuffer(defqry);
12811  destroyPQExpBuffer(delqry);
12812  destroyPQExpBuffer(labelq);
12813  destroyPQExpBuffer(castargs);
12814 }
FuncInfo * findFuncByOid(Oid oid)
Definition: common.c:895
char castmethod
Definition: pg_dump.h:505
Oid casttarget
Definition: pg_dump.h:502
char castcontext
Definition: pg_dump.h:504
DumpableObject dobj
Definition: pg_dump.h:500
Oid castsource
Definition: pg_dump.h:501
Oid castfunc
Definition: pg_dump.h:503
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 13829 of file pg_dump.c.

13830 {
13831  DumpOptions *dopt = fout->dopt;
13832  PQExpBuffer query;
13833  PQExpBuffer q;
13834  PQExpBuffer delq;
13835  char *qcollname;
13836  PGresult *res;
13837  int i_collprovider;
13838  int i_collisdeterministic;
13839  int i_collcollate;
13840  int i_collctype;
13841  int i_colllocale;
13842  int i_collicurules;
13843  const char *collprovider;
13844  const char *collcollate;
13845  const char *collctype;
13846  const char *colllocale;
13847  const char *collicurules;
13848 
13849  /* Do nothing in data-only dump */
13850  if (dopt->dataOnly)
13851  return;
13852 
13853  query = createPQExpBuffer();
13854  q = createPQExpBuffer();
13855  delq = createPQExpBuffer();
13856 
13857  qcollname = pg_strdup(fmtId(collinfo->dobj.name));
13858 
13859  /* Get collation-specific details */
13860  appendPQExpBufferStr(query, "SELECT ");
13861 
13862  if (fout->remoteVersion >= 100000)
13863  appendPQExpBufferStr(query,
13864  "collprovider, "
13865  "collversion, ");
13866  else
13867  appendPQExpBufferStr(query,
13868  "'c' AS collprovider, "
13869  "NULL AS collversion, ");
13870 
13871  if (fout->remoteVersion >= 120000)
13872  appendPQExpBufferStr(query,
13873  "collisdeterministic, ");
13874  else
13875  appendPQExpBufferStr(query,
13876  "true AS collisdeterministic, ");
13877 
13878  if (fout->remoteVersion >= 170000)
13879  appendPQExpBufferStr(query,
13880  "colllocale, ");
13881  else if (fout->remoteVersion >= 150000)
13882  appendPQExpBufferStr(query,
13883  "colliculocale AS colllocale, ");
13884  else
13885  appendPQExpBufferStr(query,
13886  "NULL AS colllocale, ");
13887 
13888  if (fout->remoteVersion >= 160000)
13889  appendPQExpBufferStr(query,
13890  "collicurules, ");
13891  else
13892  appendPQExpBufferStr(query,
13893  "NULL AS collicurules, ");
13894 
13895  appendPQExpBuffer(query,
13896  "collcollate, "
13897  "collctype "
13898  "FROM pg_catalog.pg_collation c "
13899  "WHERE c.oid = '%u'::pg_catalog.oid",
13900  collinfo->dobj.catId.oid);
13901 
13902  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13903 
13904  i_collprovider = PQfnumber(res, "collprovider");
13905  i_collisdeterministic = PQfnumber(res, "collisdeterministic");
13906  i_collcollate = PQfnumber(res, "collcollate");
13907  i_collctype = PQfnumber(res, "collctype");
13908  i_colllocale = PQfnumber(res, "colllocale");
13909  i_collicurules = PQfnumber(res, "collicurules");
13910 
13911  collprovider = PQgetvalue(res, 0, i_collprovider);
13912 
13913  if (!PQgetisnull(res, 0, i_collcollate))
13914  collcollate = PQgetvalue(res, 0, i_collcollate);
13915  else
13916  collcollate = NULL;
13917 
13918  if (!PQgetisnull(res, 0, i_collctype))
13919  collctype = PQgetvalue(res, 0, i_collctype);
13920  else
13921  collctype = NULL;
13922 
13923  /*
13924  * Before version 15, collcollate and collctype were of type NAME and
13925  * non-nullable. Treat empty strings as NULL for consistency.
13926  */
13927  if (fout->remoteVersion < 150000)
13928  {
13929  if (collcollate[0] == '\0')
13930  collcollate = NULL;
13931  if (collctype[0] == '\0')
13932  collctype = NULL;
13933  }
13934 
13935  if (!PQgetisnull(res, 0, i_colllocale))
13936  colllocale = PQgetvalue(res, 0, i_colllocale);
13937  else
13938  colllocale = NULL;
13939 
13940  if (!PQgetisnull(res, 0, i_collicurules))
13941  collicurules = PQgetvalue(res, 0, i_collicurules);
13942  else
13943  collicurules = NULL;
13944 
13945  appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
13946  fmtQualifiedDumpable(collinfo));
13947 
13948  appendPQExpBuffer(q, "CREATE COLLATION %s (",
13949  fmtQualifiedDumpable(collinfo));
13950 
13951  appendPQExpBufferStr(q, "provider = ");
13952  if (collprovider[0] == 'b')
13953  appendPQExpBufferStr(q, "builtin");
13954  else if (collprovider[0] == 'c')
13955  appendPQExpBufferStr(q, "libc");
13956  else if (collprovider[0] == 'i')
13957  appendPQExpBufferStr(q, "icu");
13958  else if (collprovider[0] == 'd')
13959  /* to allow dumping pg_catalog; not accepted on input */
13960  appendPQExpBufferStr(q, "default");
13961  else
13962  pg_fatal("unrecognized collation provider: %s",
13963  collprovider);
13964 
13965  if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
13966  appendPQExpBufferStr(q, ", deterministic = false");
13967 
13968  if (collprovider[0] == 'd')
13969  {
13970  if (collcollate || collctype || colllocale || collicurules)
13971  pg_log_warning("invalid collation \"%s\"", qcollname);
13972 
13973  /* no locale -- the default collation cannot be reloaded anyway */
13974  }
13975  else if (collprovider[0] == 'b')
13976  {
13977  if (collcollate || collctype || !colllocale || collicurules)
13978  pg_log_warning("invalid collation \"%s\"", qcollname);
13979 
13980  appendPQExpBufferStr(q, ", locale = ");
13981  appendStringLiteralAH(q, colllocale ? colllocale : "",
13982  fout);
13983  }
13984  else if (collprovider[0] == 'i')
13985  {
13986  if (fout->remoteVersion >= 150000)
13987  {
13988  if (collcollate || collctype || !colllocale)
13989  pg_log_warning("invalid collation \"%s\"", qcollname);
13990 
13991  appendPQExpBufferStr(q, ", locale = ");
13992  appendStringLiteralAH(q, colllocale ? colllocale : "",
13993  fout);
13994  }
13995  else
13996  {
13997  if (!collcollate || !collctype || colllocale ||
13998  strcmp(collcollate, collctype) != 0)
13999  pg_log_warning("invalid collation \"%s\"", qcollname);
14000 
14001  appendPQExpBufferStr(q, ", locale = ");
14002  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
14003  }
14004 
14005  if (collicurules)
14006  {
14007  appendPQExpBufferStr(q, ", rules = ");
14008  appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
14009  }
14010  }
14011  else if (collprovider[0] == 'c')
14012  {
14013  if (colllocale || collicurules || !collcollate || !collctype)
14014  pg_log_warning("invalid collation \"%s\"", qcollname);
14015 
14016  if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
14017  {
14018  appendPQExpBufferStr(q, ", locale = ");
14019  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
14020  }
14021  else
14022  {
14023  appendPQExpBufferStr(q, ", lc_collate = ");
14024  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
14025  appendPQExpBufferStr(q, ", lc_ctype = ");
14026  appendStringLiteralAH(q, collctype ? collctype : "", fout);
14027  }
14028  }
14029  else
14030  pg_fatal("unrecognized collation provider: %s", collprovider);
14031 
14032  /*
14033  * For binary upgrade, carry over the collation version. For normal
14034  * dump/restore, omit the version, so that it is computed upon restore.
14035  */
14036  if (dopt->binary_upgrade)
14037  {
14038  int i_collversion;
14039 
14040  i_collversion = PQfnumber(res, "collversion");
14041  if (!PQgetisnull(res, 0, i_collversion))
14042  {
14043  appendPQExpBufferStr(q, ", version = ");
14045  PQgetvalue(res, 0, i_collversion),
14046  fout);
14047  }
14048  }
14049 
14050  appendPQExpBufferStr(q, ");\n");
14051 
14052  if (dopt->binary_upgrade)
14053  binary_upgrade_extension_member(q, &collinfo->dobj,
14054  "COLLATION", qcollname,
14055  collinfo->dobj.namespace->dobj.name);
14056 
14057  if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14058  ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
14059  ARCHIVE_OPTS(.tag = collinfo->dobj.name,
14060  .namespace = collinfo->dobj.namespace->dobj.name,
14061  .owner = collinfo->rolname,
14062  .description = "COLLATION",
14063  .section = SECTION_PRE_DATA,
14064  .createStmt = q->data,
14065  .dropStmt = delq->data));
14066 
14067  /* Dump Collation Comments */
14068  if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14069  dumpComment(fout, "COLLATION", qcollname,
14070  collinfo->dobj.namespace->dobj.name, collinfo->rolname,
14071  collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
14072 
14073  PQclear(res);
14074 
14075  destroyPQExpBuffer(query);
14076  destroyPQExpBuffer(q);
14077  destroyPQExpBuffer(delq);
14078  free(qcollname);
14079 }
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 10285 of file pg_dump.c.

10289 {
10290  dumpCommentExtended(fout, type, name, namespace, owner,
10291  catalogId, subid, dumpId, NULL);
10292 }
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:10185

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 10185 of file pg_dump.c.

10190 {
10191  DumpOptions *dopt = fout->dopt;
10193  int ncomments;
10194 
10195  /* do nothing, if --no-comments is supplied */
10196  if (dopt->no_comments)
10197  return;
10198 
10199  /* Comments are schema not data ... except LO comments are data */
10200  if (strcmp(type, "LARGE OBJECT") != 0)
10201  {
10202  if (dopt->dataOnly)
10203  return;
10204  }
10205  else
10206  {
10207  /* We do dump LO comments in binary-upgrade mode */
10208  if (dopt->schemaOnly && !dopt->binary_upgrade)
10209  return;
10210  }
10211 
10212  /* Search for comments associated with catalogId, using table */
10213  ncomments = findComments(catalogId.tableoid, catalogId.oid,
10214  &comments);
10215 
10216  /* Is there one matching the subid? */
10217  while (ncomments > 0)
10218  {
10219  if (comments->objsubid == subid)
10220  break;
10221  comments++;
10222  ncomments--;
10223  }
10224 
10225  if (initdb_comment != NULL)
10226  {
10227  static CommentItem empty_comment = {.descr = ""};
10228 
10229  /*
10230  * initdb creates this object with a comment. Skip dumping the
10231  * initdb-provided comment, which would complicate matters for
10232  * non-superuser use of pg_dump. When the DBA has removed initdb's
10233  * comment, replicate that.
10234  */
10235  if (ncomments == 0)
10236  {
10237  comments = &empty_comment;
10238  ncomments = 1;
10239  }
10240  else if (strcmp(comments->descr, initdb_comment) == 0)
10241  ncomments = 0;
10242  }
10243 
10244  /* If a comment exists, build COMMENT ON statement */
10245  if (ncomments > 0)
10246  {
10247  PQExpBuffer query = createPQExpBuffer();
10249 
10250  appendPQExpBuffer(query, "COMMENT ON %s ", type);
10251  if (namespace && *namespace)
10252  appendPQExpBuffer(query, "%s.", fmtId(namespace));
10253  appendPQExpBuffer(query, "%s IS ", name);
10254  appendStringLiteralAH(query, comments->descr, fout);
10255  appendPQExpBufferStr(query, ";\n");
10256 
10257  appendPQExpBuffer(tag, "%s %s", type, name);
10258 
10259  /*
10260  * We mark comments as SECTION_NONE because they really belong in the
10261  * same section as their parent, whether that is pre-data or
10262  * post-data.
10263  */
10265  ARCHIVE_OPTS(.tag = tag->data,
10266  .namespace = namespace,
10267  .owner = owner,
10268  .description = "COMMENT",
10269  .section = SECTION_NONE,
10270  .createStmt = query->data,
10271  .deps = &dumpId,
10272  .nDeps = 1));
10273 
10274  destroyPQExpBuffer(query);
10275  destroyPQExpBuffer(tag);
10276  }
10277 }
static int findComments(Oid classoid, Oid objoid, CommentItem **items)
Definition: pg_dump.c:10399
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 11774 of file pg_dump.c.

11775 {
11776  DumpOptions *dopt = fout->dopt;
11778  PQExpBuffer dropped = createPQExpBuffer();
11779  PQExpBuffer delq = createPQExpBuffer();
11780  PQExpBuffer query = createPQExpBuffer();
11781  PGresult *res;
11782  char *qtypname;
11783  char *qualtypname;
11784  int ntups;
11785  int i_attname;
11786  int i_atttypdefn;
11787  int i_attlen;
11788  int i_attalign;
11789  int i_attisdropped;
11790  int i_attcollation;
11791  int i;
11792  int actual_atts;
11793 
11795  {
11796  /*
11797  * Set up query for type-specific details.
11798  *
11799  * Since we only want to dump COLLATE clauses for attributes whose
11800  * collation is different from their type's default, we use a CASE
11801  * here to suppress uninteresting attcollations cheaply. atttypid
11802  * will be 0 for dropped columns; collation does not matter for those.
11803  */
11804  appendPQExpBufferStr(query,
11805  "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
11806  "SELECT a.attname, a.attnum, "
11807  "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
11808  "a.attlen, a.attalign, a.attisdropped, "
11809  "CASE WHEN a.attcollation <> at.typcollation "
11810  "THEN a.attcollation ELSE 0 END AS attcollation "
11811  "FROM pg_catalog.pg_type ct "
11812  "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
11813  "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
11814  "WHERE ct.oid = $1 "
11815  "ORDER BY a.attnum");
11816 
11817  ExecuteSqlStatement(fout, query->data);
11818 
11820  }
11821 
11822  printfPQExpBuffer(query,
11823  "EXECUTE dumpCompositeType('%u')",
11824  tyinfo->dobj.catId.oid);
11825 
11826  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11827 
11828  ntups = PQntuples(res);
11829 
11830  i_attname = PQfnumber(res, "attname");
11831  i_atttypdefn = PQfnumber(res, "atttypdefn");
11832  i_attlen = PQfnumber(res, "attlen");
11833  i_attalign = PQfnumber(res, "attalign");
11834  i_attisdropped = PQfnumber(res, "attisdropped");
11835  i_attcollation = PQfnumber(res, "attcollation");
11836 
11837  if (dopt->binary_upgrade)
11838  {
11840  tyinfo->dobj.catId.oid,
11841  false, false);
11842  binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid);
11843  }
11844 
11845  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11846  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11847 
11848  appendPQExpBuffer(q, "CREATE TYPE %s AS (",
11849  qualtypname);
11850 
11851  actual_atts = 0;
11852  for (i = 0; i < ntups; i++)
11853  {
11854  char *attname;
11855  char *atttypdefn;
11856  char *attlen;
11857  char *attalign;
11858  bool attisdropped;
11859  Oid attcollation;
11860 
11861  attname = PQgetvalue(res, i, i_attname);
11862  atttypdefn = PQgetvalue(res, i, i_atttypdefn);
11863  attlen = PQgetvalue(res, i, i_attlen);
11864  attalign = PQgetvalue(res, i, i_attalign);
11865  attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
11866  attcollation = atooid(PQgetvalue(res, i, i_attcollation));
11867 
11868  if (attisdropped && !dopt->binary_upgrade)
11869  continue;
11870 
11871  /* Format properly if not first attr */
11872  if (actual_atts++ > 0)
11873  appendPQExpBufferChar(q, ',');
11874  appendPQExpBufferStr(q, "\n\t");
11875 
11876  if (!attisdropped)
11877  {
11878  appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
11879 
11880  /* Add collation if not default for the column type */
11881  if (OidIsValid(attcollation))
11882  {
11883  CollInfo *coll;
11884 
11885  coll = findCollationByOid(attcollation);
11886  if (coll)
11887  appendPQExpBuffer(q, " COLLATE %s",
11888  fmtQualifiedDumpable(coll));
11889  }
11890  }
11891  else
11892  {
11893  /*
11894  * This is a dropped attribute and we're in binary_upgrade mode.
11895  * Insert a placeholder for it in the CREATE TYPE command, and set
11896  * length and alignment with direct UPDATE to the catalogs
11897  * afterwards. See similar code in dumpTableSchema().
11898  */
11899  appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
11900 
11901  /* stash separately for insertion after the CREATE TYPE */
11902  appendPQExpBufferStr(dropped,
11903  "\n-- For binary upgrade, recreate dropped column.\n");
11904  appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
11905  "SET attlen = %s, "
11906  "attalign = '%s', attbyval = false\n"
11907  "WHERE attname = ", attlen, attalign);
11908  appendStringLiteralAH(dropped, attname, fout);
11909  appendPQExpBufferStr(dropped, "\n AND attrelid = ");
11910  appendStringLiteralAH(dropped, qualtypname, fout);
11911  appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
11912 
11913  appendPQExpBuffer(dropped, "ALTER TYPE %s ",
11914  qualtypname);
11915  appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
11916  fmtId(attname));
11917  }
11918  }
11919  appendPQExpBufferStr(q, "\n);\n");
11920  appendPQExpBufferStr(q, dropped->data);
11921 
11922  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11923 
11924  if (dopt->binary_upgrade)
11926  "TYPE", qtypname,
11927  tyinfo->dobj.namespace->dobj.name);
11928 
11929  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11930  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11931  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11932  .namespace = tyinfo->dobj.namespace->dobj.name,
11933  .owner = tyinfo->rolname,
11934  .description = "TYPE",
11935  .section = SECTION_PRE_DATA,
11936  .createStmt = q->data,
11937  .dropStmt = delq->data));
11938 
11939 
11940  /* Dump Type Comments and Security Labels */
11941  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11942  dumpComment(fout, "TYPE", qtypname,
11943  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11944  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11945 
11946  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11947  dumpSecLabel(fout, "TYPE", qtypname,
11948  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11949  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11950 
11951  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11952  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11953  qtypname, NULL,
11954  tyinfo->dobj.namespace->dobj.name,
11955  NULL, tyinfo->rolname, &tyinfo->dacl);
11956 
11957  /* Dump any per-column comments */
11958  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11959  dumpCompositeTypeColComments(fout, tyinfo, res);
11960 
11961  PQclear(res);
11962  destroyPQExpBuffer(q);
11963  destroyPQExpBuffer(dropped);
11964  destroyPQExpBuffer(delq);
11965  destroyPQExpBuffer(query);
11966  free(qtypname);
11967  free(qualtypname);
11968 }
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:5565
static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo, PGresult *res)
Definition: pg_dump.c:11980
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 11980 of file pg_dump.c.

11982 {
11984  int ncomments;
11985  PQExpBuffer query;
11986  PQExpBuffer target;
11987  int i;
11988  int ntups;
11989  int i_attname;
11990  int i_attnum;
11991  int i_attisdropped;
11992 
11993  /* do nothing, if --no-comments is supplied */
11994  if (fout->dopt->no_comments)
11995  return;
11996 
11997  /* Search for comments associated with type's pg_class OID */
11998  ncomments = findComments(RelationRelationId, tyinfo->typrelid,
11999  &comments);
12000 
12001  /* If no comments exist, we're done */
12002  if (ncomments <= 0)
12003  return;
12004 
12005  /* Build COMMENT ON statements */
12006  query = createPQExpBuffer();
12007  target = createPQExpBuffer();
12008 
12009  ntups = PQntuples(res);
12010  i_attnum = PQfnumber(res, "attnum");
12011  i_attname = PQfnumber(res, "attname");
12012  i_attisdropped = PQfnumber(res, "attisdropped");
12013  while (ncomments > 0)
12014  {
12015  const char *attname;
12016 
12017  attname = NULL;
12018  for (i = 0; i < ntups; i++)
12019  {
12020  if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
12021  PQgetvalue(res, i, i_attisdropped)[0] != 't')
12022  {
12023  attname = PQgetvalue(res, i, i_attname);
12024  break;
12025  }
12026  }
12027  if (attname) /* just in case we don't find it */
12028  {
12029  const char *descr = comments->descr;
12030 
12031  resetPQExpBuffer(target);
12032  appendPQExpBuffer(target, "COLUMN %s.",
12033  fmtId(tyinfo->dobj.name));
12035 
12036  resetPQExpBuffer(query);
12037  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
12038  fmtQualifiedDumpable(tyinfo));
12039  appendPQExpBuffer(query, "%s IS ", fmtId(attname));
12040  appendStringLiteralAH(query, descr, fout);
12041  appendPQExpBufferStr(query, ";\n");
12042 
12044  ARCHIVE_OPTS(.tag = target->data,
12045  .namespace = tyinfo->dobj.namespace->dobj.name,
12046  .owner = tyinfo->rolname,
12047  .description = "COMMENT",
12048  .section = SECTION_NONE,
12049  .createStmt = query->data,
12050  .deps = &(tyinfo->dobj.dumpId),
12051  .nDeps = 1));
12052  }
12053 
12054  comments++;
12055  ncomments--;
12056  }
12057 
12058  destroyPQExpBuffer(query);
12059  destroyPQExpBuffer(target);
12060 }
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 17306 of file pg_dump.c.

17307 {
17308  DumpOptions *dopt = fout->dopt;
17309  TableInfo *tbinfo = coninfo->contable;
17310  PQExpBuffer q;
17311  PQExpBuffer delq;
17312  char *tag = NULL;
17313  char *foreign;
17314 
17315  /* Do nothing in data-only dump */
17316  if (dopt->dataOnly)
17317  return;
17318 
17319  q = createPQExpBuffer();
17320  delq = createPQExpBuffer();
17321 
17322  foreign = tbinfo &&
17323  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
17324 
17325  if (coninfo->contype == 'p' ||
17326  coninfo->contype == 'u' ||
17327  coninfo->contype == 'x')
17328  {
17329  /* Index-related constraint */
17330  IndxInfo *indxinfo;
17331  int k;
17332 
17333  indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
17334 
17335  if (indxinfo == NULL)
17336  pg_fatal("missing index for constraint \"%s\"",
17337  coninfo->dobj.name);
17338 
17339  if (dopt->binary_upgrade)
17341  indxinfo->dobj.catId.oid);
17342 
17343  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
17344  fmtQualifiedDumpable(tbinfo));
17345  appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
17346  fmtId(coninfo->dobj.name));
17347 
17348  if (coninfo->condef)
17349  {
17350  /* pg_get_constraintdef should have provided everything */
17351  appendPQExpBuffer(q, "%s;\n", coninfo->condef);
17352  }
17353  else
17354  {
17356  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
17357 
17358  /*
17359  * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
17360  * indexes. Being able to create this was fixed, but we need to
17361  * make the index distinct in order to be able to restore the
17362  * dump.
17363  */
17364  if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
17365  appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
17366  appendPQExpBufferStr(q, " (");
17367  for (k = 0; k < indxinfo->indnkeyattrs; k++)
17368  {
17369  int indkey = (int) indxinfo->indkeys[k];
17370  const char *attname;
17371 
17372  if (indkey == InvalidAttrNumber)
17373  break;
17374  attname = getAttrName(indkey, tbinfo);
17375 
17376  appendPQExpBuffer(q, "%s%s",
17377  (k == 0) ? "" : ", ",
17378  fmtId(attname));
17379  }
17380  if (coninfo->conperiod)
17381  appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
17382 
17383  if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
17384  appendPQExpBufferStr(q, ") INCLUDE (");
17385 
17386  for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
17387  {
17388  int indkey = (int) indxinfo->indkeys[k];
17389  const char *attname;
17390 
17391  if (indkey == InvalidAttrNumber)
17392  break;
17393  attname = getAttrName(indkey, tbinfo);
17394 
17395  appendPQExpBuffer(q, "%s%s",
17396  (k == indxinfo->indnkeyattrs) ? "" : ", ",
17397  fmtId(attname));
17398  }
17399 
17400  appendPQExpBufferChar(q, ')');
17401 
17402  if (nonemptyReloptions(indxinfo->indreloptions))
17403  {
17404  appendPQExpBufferStr(q, " WITH (");
17405  appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
17406  appendPQExpBufferChar(q, ')');
17407  }
17408 
17409  if (coninfo->condeferrable)
17410  {
17411  appendPQExpBufferStr(q, " DEFERRABLE");
17412  if (coninfo->condeferred)
17413  appendPQExpBufferStr(q, " INITIALLY DEFERRED");
17414  }
17415 
17416  appendPQExpBufferStr(q, ";\n");
17417  }
17418 
17419  /*
17420  * Append ALTER TABLE commands as needed to set properties that we
17421  * only have ALTER TABLE syntax for. Keep this in sync with the
17422  * similar code in dumpIndex!
17423  */
17424 
17425  /* If the index is clustered, we need to record that. */
17426  if (indxinfo->indisclustered)
17427  {
17428  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17429  fmtQualifiedDumpable(tbinfo));
17430  /* index name is not qualified in this syntax */
17431  appendPQExpBuffer(q, " ON %s;\n",
17432  fmtId(indxinfo->dobj.name));
17433  }
17434 
17435  /* If the index defines identity, we need to record that. */
17436  if (indxinfo->indisreplident)
17437  {
17438  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17439  fmtQualifiedDumpable(tbinfo));
17440  /* index name is not qualified in this syntax */
17441  appendPQExpBuffer(q, " INDEX %s;\n",
17442  fmtId(indxinfo->dobj.name));
17443  }
17444 
17445  /* Indexes can depend on extensions */
17446  append_depends_on_extension(fout, q, &indxinfo->dobj,
17447  "pg_catalog.pg_class", "INDEX",
17448  fmtQualifiedDumpable(indxinfo));
17449 
17450  appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
17451  fmtQualifiedDumpable(tbinfo));
17452  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17453  fmtId(coninfo->dobj.name));
17454 
17455  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17456 
17457  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17458  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17459  ARCHIVE_OPTS(.tag = tag,
17460  .namespace = tbinfo->dobj.namespace->dobj.name,
17461  .tablespace = indxinfo->tablespace,
17462  .owner = tbinfo->rolname,
17463  .description = "CONSTRAINT",
17464  .section = SECTION_POST_DATA,
17465  .createStmt = q->data,
17466  .dropStmt = delq->data));
17467  }
17468  else if (coninfo->contype == 'f')
17469  {
17470  char *only;
17471 
17472  /*
17473  * Foreign keys on partitioned tables are always declared as
17474  * inheriting to partitions; for all other cases, emit them as
17475  * applying ONLY directly to the named table, because that's how they
17476  * work for regular inherited tables.
17477  */
17478  only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
17479 
17480  /*
17481  * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
17482  * current table data is not processed
17483  */
17484  appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
17485  only, fmtQualifiedDumpable(tbinfo));
17486  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17487  fmtId(coninfo->dobj.name),
17488  coninfo->condef);
17489 
17490  appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
17491  only, fmtQualifiedDumpable(tbinfo));
17492  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17493  fmtId(coninfo->dobj.name));
17494 
17495  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17496 
17497  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17498  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17499  ARCHIVE_OPTS(.tag = tag,
17500  .namespace = tbinfo->dobj.namespace->dobj.name,
17501  .owner = tbinfo->rolname,
17502  .description = "FK CONSTRAINT",
17503  .section = SECTION_POST_DATA,
17504  .createStmt = q->data,
17505  .dropStmt = delq->data));
17506  }
17507  else if (coninfo->contype == 'c' && tbinfo)
17508  {
17509  /* CHECK constraint on a table */
17510 
17511  /* Ignore if not to be dumped separately, or if it was inherited */
17512  if (coninfo->separate && coninfo->conislocal)
17513  {
17514  /* not ONLY since we want it to propagate to children */
17515  appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
17516  fmtQualifiedDumpable(tbinfo));
17517  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17518  fmtId(coninfo->dobj.name),
17519  coninfo->condef);
17520 
17521  appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
17522  fmtQualifiedDumpable(tbinfo));
17523  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17524  fmtId(coninfo->dobj.name));
17525 
17526  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17527 
17528  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17529  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17530  ARCHIVE_OPTS(.tag = tag,
17531  .namespace = tbinfo->dobj.namespace->dobj.name,
17532  .owner = tbinfo->rolname,
17533  .description = "CHECK CONSTRAINT",
17534  .section = SECTION_POST_DATA,
17535  .createStmt = q->data,
17536  .dropStmt = delq->data));
17537  }
17538  }
17539  else if (coninfo->contype == 'c' && tbinfo == NULL)
17540  {
17541  /* CHECK constraint on a domain */
17542  TypeInfo *tyinfo = coninfo->condomain;
17543 
17544  /* Ignore if not to be dumped separately */
17545  if (coninfo->separate)
17546  {
17547  appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
17548  fmtQualifiedDumpable(tyinfo));
17549  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17550  fmtId(coninfo->dobj.name),
17551  coninfo->condef);
17552 
17553  appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
17554  fmtQualifiedDumpable(tyinfo));
17555  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17556  fmtId(coninfo->dobj.name));
17557 
17558  tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
17559 
17560  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17561  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17562  ARCHIVE_OPTS(.tag = tag,
17563  .namespace = tyinfo->dobj.namespace->dobj.name,
17564  .owner = tyinfo->rolname,
17565  .description = "CHECK CONSTRAINT",
17566  .section = SECTION_POST_DATA,
17567  .createStmt = q->data,
17568  .dropStmt = delq->data));
17569  }
17570  }
17571  else
17572  {
17573  pg_fatal("unrecognized constraint type: %c",
17574  coninfo->contype);
17575  }
17576 
17577  /* Dump Constraint Comments --- only works for table constraints */
17578  if (tbinfo && coninfo->separate &&
17579  coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17580  dumpTableConstraintComment(fout, coninfo);
17581 
17582  free(tag);
17583  destroyPQExpBuffer(q);
17584  destroyPQExpBuffer(delq);
17585 }
#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:5344
static const char * getAttrName(int attrnum, const TableInfo *tblInfo)
Definition: pg_dump.c:17020
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
Definition: pg_dump.c:19187
static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:17595
static bool nonemptyReloptions(const char *reloptions)
Definition: pg_dump.c:19175
TypeInfo * condomain
Definition: pg_dump.h:475
TableInfo * contable
Definition: pg_dump.h:474
bool condeferred
Definition: pg_dump.h:481
bool conperiod
Definition: pg_dump.h:482
bool conislocal
Definition: pg_dump.h:483
DumpableObject dobj
Definition: pg_dump.h:473
DumpId conindex
Definition: pg_dump.h:479
bool condeferrable
Definition: pg_dump.h:480
char * condef
Definition: pg_dump.h:477
bool indisreplident
Definition: pg_dump.h:408
int indnkeyattrs
Definition: pg_dump.h:403
int indnattrs
Definition: pg_dump.h:404
Oid * indkeys
Definition: pg_dump.h:405
char * indreloptions
Definition: pg_dump.h:400
bool indisclustered
Definition: pg_dump.h:407
char * tablespace
Definition: pg_dump.h:399
bool indnullsnotdistinct
Definition: pg_dump.h:409
DumpableObject dobj
Definition: pg_dump.h:396

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 14086 of file pg_dump.c.

14087 {
14088  DumpOptions *dopt = fout->dopt;
14089  PQExpBuffer query;
14090  PQExpBuffer q;
14091  PQExpBuffer delq;
14092  char *qconvname;
14093  PGresult *res;
14094  int i_conforencoding;
14095  int i_contoencoding;
14096  int i_conproc;
14097  int i_condefault;
14098  const char *conforencoding;
14099  const char *contoencoding;
14100  const char *conproc;
14101  bool condefault;
14102 
14103  /* Do nothing in data-only dump */
14104  if (dopt->dataOnly)
14105  return;
14106 
14107  query = createPQExpBuffer();
14108  q = createPQExpBuffer();
14109  delq = createPQExpBuffer();
14110 
14111  qconvname = pg_strdup(fmtId(convinfo->dobj.name));
14112 
14113  /* Get conversion-specific details */
14114  appendPQExpBuffer(query, "SELECT "
14115  "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
14116  "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
14117  "conproc, condefault "
14118  "FROM pg_catalog.pg_conversion c "
14119  "WHERE c.oid = '%u'::pg_catalog.oid",
14120  convinfo->dobj.catId.oid);
14121 
14122  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14123 
14124  i_conforencoding = PQfnumber(res, "conforencoding");
14125  i_contoencoding = PQfnumber(res, "contoencoding");
14126  i_conproc = PQfnumber(res, "conproc");
14127  i_condefault = PQfnumber(res, "condefault");
14128 
14129  conforencoding = PQgetvalue(res, 0, i_conforencoding);
14130  contoencoding = PQgetvalue(res, 0, i_contoencoding);
14131  conproc = PQgetvalue(res, 0, i_conproc);
14132  condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
14133 
14134  appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
14135  fmtQualifiedDumpable(convinfo));
14136 
14137  appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
14138  (condefault) ? "DEFAULT " : "",
14139  fmtQualifiedDumpable(convinfo));
14140  appendStringLiteralAH(q, conforencoding, fout);
14141  appendPQExpBufferStr(q, " TO ");
14142  appendStringLiteralAH(q, contoencoding, fout);
14143  /* regproc output is already sufficiently quoted */
14144  appendPQExpBuffer(q, " FROM %s;\n", conproc);
14145 
14146  if (dopt->binary_upgrade)
14147  binary_upgrade_extension_member(q, &convinfo->dobj,
14148  "CONVERSION", qconvname,
14149  convinfo->dobj.namespace->dobj.name);
14150 
14151  if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14152  ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
14153  ARCHIVE_OPTS(.tag = convinfo->dobj.name,
14154  .namespace = convinfo->dobj.namespace->dobj.name,
14155  .owner = convinfo->rolname,
14156  .description = "CONVERSION",
14157  .section = SECTION_PRE_DATA,
14158  .createStmt = q->data,
14159  .dropStmt = delq->data));
14160 
14161  /* Dump Conversion Comments */
14162  if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14163  dumpComment(fout, "CONVERSION", qconvname,
14164  convinfo->dobj.namespace->dobj.name, convinfo->rolname,
14165  convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
14166 
14167  PQclear(res);
14168 
14169  destroyPQExpBuffer(query);
14170  destroyPQExpBuffer(q);
14171  destroyPQExpBuffer(delq);
14172  free(qconvname);
14173 }
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 3085 of file pg_dump.c.

3086 {
3087  DumpOptions *dopt = fout->dopt;
3088  PQExpBuffer dbQry = createPQExpBuffer();
3089  PQExpBuffer delQry = createPQExpBuffer();
3090  PQExpBuffer creaQry = createPQExpBuffer();
3091  PQExpBuffer labelq = createPQExpBuffer();
3092  PGconn *conn = GetConnection(fout);
3093  PGresult *res;
3094  int i_tableoid,
3095  i_oid,
3096  i_datname,
3097  i_datdba,
3098  i_encoding,
3099  i_datlocprovider,
3100  i_collate,
3101  i_ctype,
3102  i_datlocale,
3103  i_daticurules,
3104  i_frozenxid,
3105  i_minmxid,
3106  i_datacl,
3107  i_acldefault,
3108  i_datistemplate,
3109  i_datconnlimit,
3110  i_datcollversion,
3111  i_tablespace;
3112  CatalogId dbCatId;
3113  DumpId dbDumpId;
3114  DumpableAcl dbdacl;
3115  const char *datname,
3116  *dba,
3117  *encoding,
3118  *datlocprovider,
3119  *collate,
3120  *ctype,
3121  *locale,
3122  *icurules,
3123  *datistemplate,
3124  *datconnlimit,
3125  *tablespace;
3126  uint32 frozenxid,
3127  minmxid;
3128  char *qdatname;
3129 
3130  pg_log_info("saving database definition");
3131 
3132  /*
3133  * Fetch the database-level properties for this database.
3134  */
3135  appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
3136  "datdba, "
3137  "pg_encoding_to_char(encoding) AS encoding, "
3138  "datcollate, datctype, datfrozenxid, "
3139  "datacl, acldefault('d', datdba) AS acldefault, "
3140  "datistemplate, datconnlimit, ");
3141  if (fout->remoteVersion >= 90300)
3142  appendPQExpBufferStr(dbQry, "datminmxid, ");
3143  else
3144  appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
3145  if (fout->remoteVersion >= 170000)
3146  appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
3147  else if (fout->remoteVersion >= 150000)
3148  appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
3149  else
3150  appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
3151  if (fout->remoteVersion >= 160000)
3152  appendPQExpBufferStr(dbQry, "daticurules, ");
3153  else
3154  appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
3155  appendPQExpBufferStr(dbQry,
3156  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
3157  "shobj_description(oid, 'pg_database') AS description "
3158  "FROM pg_database "
3159  "WHERE datname = current_database()");
3160 
3161  res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
3162 
3163  i_tableoid = PQfnumber(res, "tableoid");
3164  i_oid = PQfnumber(res, "oid");
3165  i_datname = PQfnumber(res, "datname");
3166  i_datdba = PQfnumber(res, "datdba");
3167  i_encoding = PQfnumber(res, "encoding");
3168  i_datlocprovider = PQfnumber(res, "datlocprovider");
3169  i_collate = PQfnumber(res, "datcollate");
3170  i_ctype = PQfnumber(res, "datctype");
3171  i_datlocale = PQfnumber(res, "datlocale");
3172  i_daticurules = PQfnumber(res, "daticurules");
3173  i_frozenxid = PQfnumber(res, "datfrozenxid");
3174  i_minmxid = PQfnumber(res, "datminmxid");
3175  i_datacl = PQfnumber(res, "datacl");
3176  i_acldefault = PQfnumber(res, "acldefault");
3177  i_datistemplate = PQfnumber(res, "datistemplate");
3178  i_datconnlimit = PQfnumber(res, "datconnlimit");
3179  i_datcollversion = PQfnumber(res, "datcollversion");
3180  i_tablespace = PQfnumber(res, "tablespace");
3181 
3182  dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
3183  dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
3184  datname = PQgetvalue(res, 0, i_datname);
3185  dba = getRoleName(PQgetvalue(res, 0, i_datdba));
3186  encoding = PQgetvalue(res, 0, i_encoding);
3187  datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
3188  collate = PQgetvalue(res, 0, i_collate);
3189  ctype = PQgetvalue(res, 0, i_ctype);
3190  if (!PQgetisnull(res, 0, i_datlocale))
3191  locale = PQgetvalue(res, 0, i_datlocale);
3192  else
3193  locale = NULL;
3194  if (!PQgetisnull(res, 0, i_daticurules))
3195  icurules = PQgetvalue(res, 0, i_daticurules);
3196  else
3197  icurules = NULL;
3198  frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
3199  minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
3200  dbdacl.acl = PQgetvalue(res, 0, i_datacl);
3201  dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
3202  datistemplate = PQgetvalue(res, 0, i_datistemplate);
3203  datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
3204  tablespace = PQgetvalue(res, 0, i_tablespace);
3205 
3206  qdatname = pg_strdup(fmtId(datname));
3207 
3208  /*
3209  * Prepare the CREATE DATABASE command. We must specify OID (if we want
3210  * to preserve that), as well as the encoding, locale, and tablespace
3211  * since those can't be altered later. Other DB properties are left to
3212  * the DATABASE PROPERTIES entry, so that they can be applied after
3213  * reconnecting to the target DB.
3214  *
3215  * For binary upgrade, we use the FILE_COPY strategy because testing has
3216  * shown it to be faster. When the server is in binary upgrade mode, it
3217  * will also skip the checkpoints this strategy ordinarily performs.
3218  */
3219  if (dopt->binary_upgrade)
3220  {
3221  appendPQExpBuffer(creaQry,
3222  "CREATE DATABASE %s WITH TEMPLATE = template0 "
3223  "OID = %u STRATEGY = FILE_COPY",
3224  qdatname, dbCatId.oid);
3225  }
3226  else
3227  {
3228  appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
3229  qdatname);
3230  }
3231  if (strlen(encoding) > 0)
3232  {
3233  appendPQExpBufferStr(creaQry, " ENCODING = ");
3234  appendStringLiteralAH(creaQry, encoding, fout);
3235  }
3236 
3237  appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
3238  if (datlocprovider[0] == 'b')
3239  appendPQExpBufferStr(creaQry, "builtin");
3240  else if (datlocprovider[0] == 'c')
3241  appendPQExpBufferStr(creaQry, "libc");
3242  else if (datlocprovider[0] == 'i')
3243  appendPQExpBufferStr(creaQry, "icu");
3244  else
3245  pg_fatal("unrecognized locale provider: %s",
3246  datlocprovider);
3247 
3248  if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
3249  {
3250  appendPQExpBufferStr(creaQry, " LOCALE = ");
3251  appendStringLiteralAH(creaQry, collate, fout);
3252  }
3253  else
3254  {
3255  if (strlen(collate) > 0)
3256  {
3257  appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
3258  appendStringLiteralAH(creaQry, collate, fout);
3259  }
3260  if (strlen(ctype) > 0)
3261  {
3262  appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
3263  appendStringLiteralAH(creaQry, ctype, fout);
3264  }
3265  }
3266  if (locale)
3267  {
3268  if (datlocprovider[0] == 'b')
3269  appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
3270  else
3271  appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
3272 
3273  appendStringLiteralAH(creaQry, locale, fout);
3274  }
3275 
3276  if (icurules)
3277  {
3278  appendPQExpBufferStr(creaQry, " ICU_RULES = ");
3279  appendStringLiteralAH(creaQry, icurules, fout);
3280  }
3281 
3282  /*
3283  * For binary upgrade, carry over the collation version. For normal
3284  * dump/restore, omit the version, so that it is computed upon restore.
3285  */
3286  if (dopt->binary_upgrade)
3287  {
3288  if (!PQgetisnull(res, 0, i_datcollversion))
3289  {
3290  appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
3291  appendStringLiteralAH(creaQry,
3292  PQgetvalue(res, 0, i_datcollversion),
3293  fout);
3294  }
3295  }
3296 
3297  /*
3298  * Note: looking at dopt->outputNoTablespaces here is completely the wrong
3299  * thing; the decision whether to specify a tablespace should be left till
3300  * pg_restore, so that pg_restore --no-tablespaces applies. Ideally we'd
3301  * label the DATABASE entry with the tablespace and let the normal
3302  * tablespace selection logic work ... but CREATE DATABASE doesn't pay
3303  * attention to default_tablespace, so that won't work.
3304  */
3305  if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
3306  !dopt->outputNoTablespaces)
3307  appendPQExpBuffer(creaQry, " TABLESPACE = %s",
3308  fmtId(tablespace));
3309  appendPQExpBufferStr(creaQry, ";\n");
3310 
3311  appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
3312  qdatname);
3313 
3314  dbDumpId = createDumpId();
3315 
3316  ArchiveEntry(fout,
3317  dbCatId, /* catalog ID */
3318  dbDumpId, /* dump ID */
3319  ARCHIVE_OPTS(.tag = datname,
3320  .owner = dba,
3321  .description = "DATABASE",
3322  .section = SECTION_PRE_DATA,
3323  .createStmt = creaQry->data,
3324  .dropStmt = delQry->data));
3325 
3326  /* Compute correct tag for archive entry */
3327  appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
3328 
3329  /* Dump DB comment if any */
3330  {
3331  /*
3332  * 8.2 and up keep comments on shared objects in a shared table, so we
3333  * cannot use the dumpComment() code used for other database objects.
3334  * Be careful that the ArchiveEntry parameters match that function.
3335  */
3336  char *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
3337 
3338  if (comment && *comment && !dopt->no_comments)
3339  {
3340  resetPQExpBuffer(dbQry);
3341 
3342  /*
3343  * Generates warning when loaded into a differently-named
3344  * database.
3345  */
3346  appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
3347  appendStringLiteralAH(dbQry, comment, fout);
3348  appendPQExpBufferStr(dbQry, ";\n");
3349 
3351  ARCHIVE_OPTS(.tag = labelq->data,
3352  .owner = dba,
3353  .description = "COMMENT",
3354  .section = SECTION_NONE,
3355  .createStmt = dbQry->data,
3356  .deps = &dbDumpId,
3357  .nDeps = 1));
3358  }
3359  }
3360 
3361  /* Dump DB security label, if enabled */
3362  if (!dopt->no_security_labels)
3363  {
3364  PGresult *shres;
3365  PQExpBuffer seclabelQry;
3366 
3367  seclabelQry = createPQExpBuffer();
3368 
3369  buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
3370  shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
3371  resetPQExpBuffer(seclabelQry);
3372  emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
3373  if (seclabelQry->len > 0)
3375  ARCHIVE_OPTS(.tag = labelq->data,
3376  .owner = dba,
3377  .description = "SECURITY LABEL",
3378  .section = SECTION_NONE,
3379  .createStmt = seclabelQry->data,
3380  .deps = &dbDumpId,
3381  .nDeps = 1));
3382  destroyPQExpBuffer(seclabelQry);
3383  PQclear(shres);
3384  }
3385 
3386  /*
3387  * Dump ACL if any. Note that we do not support initial privileges
3388  * (pg_init_privs) on databases.
3389  */
3390  dbdacl.privtype = 0;
3391  dbdacl.initprivs = NULL;
3392 
3393  dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
3394  qdatname, NULL, NULL,
3395  NULL, dba, &dbdacl);
3396 
3397  /*
3398  * Now construct a DATABASE PROPERTIES archive entry to restore any
3399  * non-default database-level properties. (The reason this must be
3400  * separate is that we cannot put any additional commands into the TOC
3401  * entry that has CREATE DATABASE. pg_restore would execute such a group
3402  * in an implicit transaction block, and the backend won't allow CREATE
3403  * DATABASE in that context.)
3404  */
3405  resetPQExpBuffer(creaQry);
3406  resetPQExpBuffer(delQry);
3407 
3408  if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
3409  appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
3410  qdatname, datconnlimit);
3411 
3412  if (strcmp(datistemplate, "t") == 0)
3413  {
3414  appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
3415  qdatname);
3416 
3417  /*
3418  * The backend won't accept DROP DATABASE on a template database. We
3419  * can deal with that by removing the template marking before the DROP
3420  * gets issued. We'd prefer to use ALTER DATABASE IF EXISTS here, but
3421  * since no such command is currently supported, fake it with a direct
3422  * UPDATE on pg_database.
3423  */
3424  appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
3425  "SET datistemplate = false WHERE datname = ");
3426  appendStringLiteralAH(delQry, datname, fout);
3427  appendPQExpBufferStr(delQry, ";\n");
3428  }
3429 
3430  /*
3431  * We do not restore pg_database.dathasloginevt because it is set
3432  * automatically on login event trigger creation.
3433  */
3434 
3435  /* Add database-specific SET options */
3436  dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
3437 
3438  /*
3439  * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
3440  * entry, too, for lack of a better place.
3441  */
3442  if (dopt->binary_upgrade)
3443  {
3444  appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
3445  appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
3446  "SET datfrozenxid = '%u', datminmxid = '%u'\n"
3447  "WHERE datname = ",
3448  frozenxid, minmxid);
3449  appendStringLiteralAH(creaQry, datname, fout);
3450  appendPQExpBufferStr(creaQry, ";\n");
3451  }
3452 
3453  if (creaQry->len > 0)
3455  ARCHIVE_OPTS(.tag = datname,
3456  .owner = dba,
3457  .description = "DATABASE PROPERTIES",
3458  .section = SECTION_PRE_DATA,
3459  .createStmt = creaQry->data,
3460  .dropStmt = delQry->data,
3461  .deps = &dbDumpId));
3462 
3463  /*
3464  * pg_largeobject comes from the old system intact, so set its
3465  * relfrozenxids, relminmxids and relfilenode.
3466  */
3467  if (dopt->binary_upgrade)
3468  {
3469  PGresult *lo_res;
3470  PQExpBuffer loFrozenQry = createPQExpBuffer();
3471  PQExpBuffer loOutQry = createPQExpBuffer();
3472  PQExpBuffer loHorizonQry = createPQExpBuffer();
3473  int ii_relfrozenxid,
3474  ii_relfilenode,
3475  ii_oid,
3476  ii_relminmxid;
3477 
3478  /*
3479  * pg_largeobject
3480  */
3481  if (fout->remoteVersion >= 90300)
3482  appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
3483  "FROM pg_catalog.pg_class\n"
3484  "WHERE oid IN (%u, %u);\n",
3485  LargeObjectRelationId, LargeObjectLOidPNIndexId);
3486  else
3487  appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
3488  "FROM pg_catalog.pg_class\n"
3489  "WHERE oid IN (%u, %u);\n",
3490  LargeObjectRelationId, LargeObjectLOidPNIndexId);
3491 
3492  lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
3493 
3494  ii_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
3495  ii_relminmxid = PQfnumber(lo_res, "relminmxid");
3496  ii_relfilenode = PQfnumber(lo_res, "relfilenode");
3497  ii_oid = PQfnumber(lo_res, "oid");
3498 
3499  appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
3500  appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
3501  for (int i = 0; i < PQntuples(lo_res); ++i)
3502  {
3503  Oid oid;
3504  RelFileNumber relfilenumber;
3505 
3506  appendPQExpBuffer(loHorizonQry, "UPDATE pg_catalog.pg_class\n"
3507  "SET relfrozenxid = '%u', relminmxid = '%u'\n"
3508  "WHERE oid = %u;\n",
3509  atooid(PQgetvalue(lo_res, i, ii_relfrozenxid)),
3510  atooid(PQgetvalue(lo_res, i, ii_relminmxid)),
3511  atooid(PQgetvalue(lo_res, i, ii_oid)));
3512 
3513  oid = atooid(PQgetvalue(lo_res, i, ii_oid));
3514  relfilenumber = atooid(PQgetvalue(lo_res, i, ii_relfilenode));
3515 
3516  if (oid == LargeObjectRelationId)
3517  appendPQExpBuffer(loOutQry,
3518  "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
3519  relfilenumber);
3520  else if (oid == LargeObjectLOidPNIndexId)
3521  appendPQExpBuffer(loOutQry,
3522  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
3523  relfilenumber);
3524  }
3525 
3526  appendPQExpBufferStr(loOutQry,
3527  "TRUNCATE pg_catalog.pg_largeobject;\n");
3528  appendPQExpBufferStr(loOutQry, loHorizonQry->data);
3529 
3531  ARCHIVE_OPTS(.tag = "pg_largeobject",
3532  .description = "pg_largeobject",
3533  .section = SECTION_PRE_DATA,
3534  .createStmt = loOutQry->data));
3535 
3536  PQclear(lo_res);
3537 
3538  destroyPQExpBuffer(loFrozenQry);
3539  destroyPQExpBuffer(loHorizonQry);
3540  destroyPQExpBuffer(loOutQry);
3541  }
3542 
3543  PQclear(res);
3544 
3545  free(qdatname);
3546  destroyPQExpBuffer(dbQry);
3547  destroyPQExpBuffer(delQry);
3548  destroyPQExpBuffer(creaQry);
3549  destroyPQExpBuffer(labelq);
3550 }
unsigned int uint32
Definition: c.h:518
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
Definition: connection.c:191
void buildShSecLabelQuery(const char *catalog_name, Oid objectId, PQExpBuffer sql)
Definition: dumputils.c:637
void emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *objtype, const char *objname)
Definition: dumputils.c:655
#define comment
Definition: indent_codes.h:49
static char * locale
Definition: initdb.c:140
#define pg_log_info(...)
Definition: logging.h:124
char datlocprovider
Definition: pg_database.h:44
NameData datname
Definition: pg_database.h:35
int32 encoding
Definition: pg_database.h:41
bool datistemplate
Definition: pg_database.h:47
int32 datconnlimit
Definition: pg_database.h:59
static const char * getRoleName(const char *roleoid_str)
Definition: pg_dump.c:9985
static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf, const char *dbname, Oid dboid)
Definition: pg_dump.c:3557
static char * tablespace
Definition: pgbench.c:216
Oid RelFileNumber
Definition: relpath.h:25
PGconn * conn
Definition: streamutil.c:53
int no_security_labels
Definition: pg_backup.h:182
int outputNoTablespaces
Definition: pg_backup.h:190
const char * description

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), atooid, _dumpOptions::binary_upgrade, buildShSecLabelQuery(), comment, conn, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, datconnlimit, datistemplate, datlocprovider, datname, description, destroyPQExpBuffer(), Archive::dopt, dumpACL(), dumpDatabaseConfig(), emitShSecLabels(), encoding, ExecuteSqlQuery(), ExecuteSqlQueryForSingleRow(), fmtId(), free, GetConnection(), getRoleName(), i, _dumpableAcl::initprivs, InvalidDumpId, PQExpBufferData::len, locale, nilCatalogId, _dumpOptions::no_comments, _dumpOptions::no_security_labels, CatalogId::oid, _dumpOptions::outputNoTablespaces, pg_fatal, pg_log_info, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, Archive::remoteVersion, res, resetPQExpBuffer(), SECTION_NONE, SECTION_PRE_DATA, CatalogId::tableoid, and tablespace.

Referenced by main().

◆ dumpDatabaseConfig()

static void dumpDatabaseConfig ( Archive AH,
PQExpBuffer  outbuf,
const char *  dbname,
Oid  dboid 
)
static

Definition at line 3557 of file pg_dump.c.

3559 {
3560  PGconn *conn = GetConnection(AH);
3562  PGresult *res;
3563 
3564  /* First collect database-specific options */
3565  printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
3566  "WHERE setrole = 0 AND setdatabase = '%u'::oid",
3567  dboid);
3568 
3569  res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3570 
3571  for (int i = 0; i < PQntuples(res); i++)
3573  "DATABASE", dbname, NULL, NULL,
3574  outbuf);
3575 
3576  PQclear(res);
3577 
3578  /* Now look for role-and-database-specific options */
3579  printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
3580  "FROM pg_db_role_setting s, pg_roles r "
3581  "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
3582  dboid);
3583 
3584  res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3585 
3586  for (int i = 0; i < PQntuples(res); i++)
3588  "ROLE", PQgetvalue(res, i, 0),
3589  "DATABASE", dbname,
3590  outbuf);
3591 
3592  PQclear(res);
3593 
3595 }
void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, PQExpBuffer buf)
Definition: dumputils.c:823
static char * buf
Definition: pg_test_fsync.c:72
char * dbname
Definition: streamutil.c:50

References buf, conn, createPQExpBuffer(), dbname, destroyPQExpBuffer(), ExecuteSqlQuery(), GetConnection(), i, makeAlterConfigCommand(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), and res.

Referenced by dumpDatabase().

◆ dumpDefaultACL()

static void dumpDefaultACL ( Archive fout,
const DefaultACLInfo daclinfo 
)
static

Definition at line 15160 of file pg_dump.c.

15161 {
15162  DumpOptions *dopt = fout->dopt;
15163  PQExpBuffer q;
15164  PQExpBuffer tag;
15165  const char *type;
15166 
15167  /* Do nothing in data-only dump, or if we're skipping ACLs */
15168  if (dopt->dataOnly || dopt->aclsSkip)
15169  return;
15170 
15171  q = createPQExpBuffer();
15172  tag = createPQExpBuffer();
15173 
15174  switch (daclinfo->defaclobjtype)
15175  {
15176  case DEFACLOBJ_RELATION:
15177  type = "TABLES";
15178  break;
15179  case DEFACLOBJ_SEQUENCE:
15180  type = "SEQUENCES";
15181  break;
15182  case DEFACLOBJ_FUNCTION:
15183  type = "FUNCTIONS";
15184  break;
15185  case DEFACLOBJ_TYPE:
15186  type = "TYPES";
15187  break;
15188  case DEFACLOBJ_NAMESPACE:
15189  type = "SCHEMAS";
15190  break;
15191  default:
15192  /* shouldn't get here */
15193  pg_fatal("unrecognized object type in default privileges: %d",
15194  (int) daclinfo->defaclobjtype);
15195  type = ""; /* keep compiler quiet */
15196  }
15197 
15198  appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
15199 
15200  /* build the actual command(s) for this tuple */
15202  daclinfo->dobj.namespace != NULL ?
15203  daclinfo->dobj.namespace->dobj.name : NULL,
15204  daclinfo->dacl.acl,
15205  daclinfo->dacl.acldefault,
15206  daclinfo->defaclrole,
15207  fout->remoteVersion,
15208  q))
15209  pg_fatal("could not parse default ACL list (%s)",
15210  daclinfo->dacl.acl);
15211 
15212  if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
15213  ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
15214  ARCHIVE_OPTS(.tag = tag->data,
15215  .namespace = daclinfo->dobj.namespace ?
15216  daclinfo->dobj.namespace->dobj.name : NULL,
15217  .owner = daclinfo->defaclrole,
15218  .description = "DEFAULT ACL",
15219  .section = SECTION_POST_DATA,
15220  .createStmt = q->data));
15221 
15222  destroyPQExpBuffer(tag);
15223  destroyPQExpBuffer(q);
15224 }
bool buildDefaultACLCommands(const char *type, const char *nspname, const char *acls, const char *acldefault, const char *owner, int remoteVersion, PQExpBuffer sql)
Definition: dumputils.c:326
DumpableObject dobj
Definition: pg_dump.h:579
DumpableAcl dacl
Definition: pg_dump.h:580
const char * defaclrole
Definition: pg_dump.h:581
char defaclobjtype
Definition: pg_dump.h:582

References _dumpableAcl::acl, _dumpableAcl::acldefault, _dumpOptions::aclsSkip, appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), buildDefaultACLCommands(), _dumpableObject::catId, createPQExpBuffer(), _defaultACLInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, _defaultACLInfo::defaclobjtype, _defaultACLInfo::defaclrole, destroyPQExpBuffer(), _defaultACLInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, _dumpableObject::dumpId, _dumpableObject::name, pg_fatal, Archive::remoteVersion, SECTION_POST_DATA, and type.

Referenced by dumpDumpableObject().

◆ dumpDomain()

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

Definition at line 11601 of file pg_dump.c.

11602 {
11603  DumpOptions *dopt = fout->dopt;
11605  PQExpBuffer delq = createPQExpBuffer();
11606  PQExpBuffer query = createPQExpBuffer();
11607  PGresult *res;
11608  int i;
11609  char *qtypname;
11610  char *qualtypname;
11611  char *typnotnull;
11612  char *typdefn;
11613  char *typdefault;
11614  Oid typcollation;
11615  bool typdefault_is_literal = false;
11616 
11617  if (!fout->is_prepared[PREPQUERY_DUMPDOMAIN])
11618  {
11619  /* Set up query for domain-specific details */
11620  appendPQExpBufferStr(query,
11621  "PREPARE dumpDomain(pg_catalog.oid) AS\n");
11622 
11623  appendPQExpBufferStr(query, "SELECT t.typnotnull, "
11624  "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
11625  "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
11626  "t.typdefault, "
11627  "CASE WHEN t.typcollation <> u.typcollation "
11628  "THEN t.typcollation ELSE 0 END AS typcollation "
11629  "FROM pg_catalog.pg_type t "
11630  "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
11631  "WHERE t.oid = $1");
11632 
11633  ExecuteSqlStatement(fout, query->data);
11634 
11635  fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
11636  }
11637 
11638  printfPQExpBuffer(query,
11639  "EXECUTE dumpDomain('%u')",
11640  tyinfo->dobj.catId.oid);
11641 
11642  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11643 
11644  typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
11645  typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
11646  if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
11647  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
11648  else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
11649  {
11650  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
11651  typdefault_is_literal = true; /* it needs quotes */
11652  }
11653  else
11654  typdefault = NULL;
11655  typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
11656 
11657  if (dopt->binary_upgrade)
11659  tyinfo->dobj.catId.oid,
11660  true, /* force array type */
11661  false); /* force multirange type */
11662 
11663  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11664  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11665 
11667  "CREATE DOMAIN %s AS %s",
11668  qualtypname,
11669  typdefn);
11670 
11671  /* Print collation only if different from base type's collation */
11672  if (OidIsValid(typcollation))
11673  {
11674  CollInfo *coll;
11675 
11676  coll = findCollationByOid(typcollation);
11677  if (coll)
11678  appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
11679  }
11680 
11681  if (typnotnull[0] == 't')
11682  appendPQExpBufferStr(q, " NOT NULL");
11683 
11684  if (typdefault != NULL)
11685  {
11686  appendPQExpBufferStr(q, " DEFAULT ");
11687  if (typdefault_is_literal)
11688  appendStringLiteralAH(q, typdefault, fout);
11689  else
11690  appendPQExpBufferStr(q, typdefault);
11691  }
11692 
11693  PQclear(res);
11694 
11695  /*
11696  * Add any CHECK constraints for the domain
11697  */
11698  for (i = 0; i < tyinfo->nDomChecks; i++)
11699  {
11700  ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
11701 
11702  if (!domcheck->separate)
11703  appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
11704  fmtId(domcheck->dobj.name), domcheck->condef);
11705  }
11706 
11707  appendPQExpBufferStr(q, ";\n");
11708 
11709  appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
11710 
11711  if (dopt->binary_upgrade)
11713  "DOMAIN", qtypname,
11714  tyinfo->dobj.namespace->dobj.name);
11715 
11716  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11717  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11718  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11719  .namespace = tyinfo->dobj.namespace->dobj.name,
11720  .owner = tyinfo->rolname,
11721  .description = "DOMAIN",
11722  .section = SECTION_PRE_DATA,
11723  .createStmt = q->data,
11724  .dropStmt = delq->data));
11725 
11726  /* Dump Domain Comments and Security Labels */
11727  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11728  dumpComment(fout, "DOMAIN", qtypname,
11729  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11730  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11731 
11732  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11733  dumpSecLabel(fout, "DOMAIN", qtypname,
11734  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11735  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11736 
11737  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11738  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11739  qtypname, NULL,
11740  tyinfo->dobj.namespace->dobj.name,
11741  NULL, tyinfo->rolname, &tyinfo->dacl);
11742 
11743  /* Dump any per-constraint comments */
11744  for (i = 0; i < tyinfo->nDomChecks; i++)
11745  {
11746  ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
11747  PQExpBuffer conprefix = createPQExpBuffer();
11748 
11749  appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
11750  fmtId(domcheck->dobj.name));
11751 
11752  if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
11753  dumpComment(fout, conprefix->data, qtypname,
11754  tyinfo->dobj.namespace->dobj.name,
11755  tyinfo->rolname,
11756  domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
11757 
11758  destroyPQExpBuffer(conprefix);
11759  }
11760 
11761  destroyPQExpBuffer(q);
11762  destroyPQExpBuffer(delq);
11763  destroyPQExpBuffer(query);
11764  free(qtypname);
11765  free(qualtypname);
11766 }
@ PREPQUERY_DUMPDOMAIN
Definition: pg_backup.h:69
struct _constraintInfo * domChecks
Definition: pg_dump.h:213
int nDomChecks
Definition: pg_dump.h:212

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, _constraintInfo::condef, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _typeInfo::dobj, _constraintInfo::dobj, _typeInfo::domChecks, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, free, i, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, _typeInfo::nDomChecks, CatalogId::oid, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PREPQUERY_DUMPDOMAIN, printfPQExpBuffer(), res, _typeInfo::rolname, SECTION_PRE_DATA, and _constraintInfo::separate.

Referenced by dumpType().

◆ dumpDumpableObject()

static void dumpDumpableObject ( Archive fout,
DumpableObject dobj 
)
static

Definition at line 10561 of file pg_dump.c.

10562 {
10563  /*
10564  * Clear any dump-request bits for components that don't exist for this
10565  * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
10566  * request for every kind of object.)
10567  */
10568  dobj->dump &= dobj->components;
10569 
10570  /* Now, short-circuit if there's nothing to be done here. */
10571  if (dobj->dump == 0)
10572  return;
10573 
10574  switch (dobj->objType)
10575  {
10576  case DO_NAMESPACE:
10577  dumpNamespace(fout, (const NamespaceInfo *) dobj);
10578  break;
10579  case DO_EXTENSION:
10580  dumpExtension(fout, (const ExtensionInfo *) dobj);
10581  break;
10582  case DO_TYPE:
10583  dumpType(fout, (const TypeInfo *) dobj);
10584  break;
10585  case DO_SHELL_TYPE:
10586  dumpShellType(fout, (const ShellTypeInfo *) dobj);
10587  break;
10588  case DO_FUNC:
10589  dumpFunc(fout, (const FuncInfo *) dobj);
10590  break;
10591  case DO_AGG:
10592  dumpAgg(fout, (const AggInfo *) dobj);
10593  break;
10594  case DO_OPERATOR:
10595  dumpOpr(fout, (const OprInfo *) dobj);
10596  break;
10597  case DO_ACCESS_METHOD:
10598  dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
10599  break;
10600  case DO_OPCLASS:
10601  dumpOpclass(fout, (const OpclassInfo *) dobj);
10602  break;
10603  case DO_OPFAMILY:
10604  dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
10605  break;
10606  case DO_COLLATION:
10607  dumpCollation(fout, (const CollInfo *) dobj);
10608  break;
10609  case DO_CONVERSION:
10610  dumpConversion(fout, (const ConvInfo *) dobj);
10611  break;
10612  case DO_TABLE:
10613  dumpTable(fout, (const TableInfo *) dobj);
10614  break;
10615  case DO_TABLE_ATTACH:
10616  dumpTableAttach(fout, (const TableAttachInfo *) dobj);
10617  break;
10618  case DO_ATTRDEF:
10619  dumpAttrDef(fout, (const AttrDefInfo *) dobj);
10620  break;
10621  case DO_INDEX:
10622  dumpIndex(fout, (const IndxInfo *) dobj);
10623  break;
10624  case DO_INDEX_ATTACH:
10625  dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
10626  break;
10627  case DO_STATSEXT:
10628  dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
10629  break;
10630  case DO_REFRESH_MATVIEW:
10631  refreshMatViewData(fout, (const TableDataInfo *) dobj);
10632  break;
10633  case DO_RULE:
10634  dumpRule(fout, (const RuleInfo *) dobj);
10635  break;
10636  case DO_TRIGGER:
10637  dumpTrigger(fout, (const TriggerInfo *) dobj);
10638  break;
10639  case DO_EVENT_TRIGGER:
10640  dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
10641  break;
10642  case DO_CONSTRAINT:
10643  dumpConstraint(fout, (const ConstraintInfo *) dobj);
10644  break;
10645  case DO_FK_CONSTRAINT:
10646  dumpConstraint(fout, (const ConstraintInfo *) dobj);
10647  break;
10648  case DO_PROCLANG:
10649  dumpProcLang(fout, (const ProcLangInfo *) dobj);
10650  break;
10651  case DO_CAST:
10652  dumpCast(fout, (const CastInfo *) dobj);
10653  break;
10654  case DO_TRANSFORM:
10655  dumpTransform(fout, (const TransformInfo *) dobj);
10656  break;
10657  case DO_SEQUENCE_SET:
10658  dumpSequenceData(fout, (const TableDataInfo *) dobj);
10659  break;
10660  case DO_TABLE_DATA:
10661  dumpTableData(fout, (const TableDataInfo *) dobj);
10662  break;
10663  case DO_DUMMY_TYPE:
10664  /* table rowtypes and array types are never dumped separately */
10665  break;
10666  case DO_TSPARSER:
10667  dumpTSParser(fout, (const TSParserInfo *) dobj);
10668  break;
10669  case DO_TSDICT:
10670  dumpTSDictionary(fout, (const TSDictInfo *) dobj);
10671  break;
10672  case DO_TSTEMPLATE:
10673  dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
10674  break;
10675  case DO_TSCONFIG:
10676  dumpTSConfig(fout, (const TSConfigInfo *) dobj);
10677  break;
10678  case DO_FDW:
10679  dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
10680  break;
10681  case DO_FOREIGN_SERVER:
10682  dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
10683  break;
10684  case DO_DEFAULT_ACL:
10685  dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
10686  break;
10687  case DO_LARGE_OBJECT:
10688  dumpLO(fout, (const LoInfo *) dobj);
10689  break;
10690  case DO_LARGE_OBJECT_DATA:
10691  if (dobj->dump & DUMP_COMPONENT_DATA)
10692  {
10693  LoInfo *loinfo;
10694  TocEntry *te;
10695 
10696  loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
10697  if (loinfo == NULL)
10698  pg_fatal("missing metadata for large objects \"%s\"",
10699  dobj->name);
10700 
10701  te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
10702  ARCHIVE_OPTS(.tag = dobj->name,
10703  .owner = loinfo->rolname,
10704  .description = "BLOBS",
10705  .section = SECTION_DATA,
10706  .deps = dobj->dependencies,
10707  .nDeps = dobj->nDeps,
10708  .dumpFn = dumpLOs,
10709  .dumpArg = loinfo));
10710 
10711  /*
10712  * Set the TocEntry's dataLength in case we are doing a
10713  * parallel dump and want to order dump jobs by table size.
10714  * (We need some size estimate for every TocEntry with a
10715  * DataDumper function.) We don't currently have any cheap
10716  * way to estimate the size of LOs, but fortunately it doesn't
10717  * matter too much as long as we get large batches of LOs
10718  * processed reasonably early. Assume 8K per blob.
10719  */
10720  te->dataLength = loinfo->numlos * (pgoff_t) 8192;
10721  }
10722  break;
10723  case DO_POLICY:
10724  dumpPolicy(fout, (const PolicyInfo *) dobj);
10725  break;
10726  case DO_PUBLICATION:
10727  dumpPublication(fout, (const PublicationInfo *) dobj);
10728  break;
10729  case DO_PUBLICATION_REL:
10730  dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
10731  break;
10734  (const PublicationSchemaInfo *) dobj);
10735  break;
10736  case DO_SUBSCRIPTION:
10737  dumpSubscription(fout, (const SubscriptionInfo *) dobj);
10738  break;
10739  case DO_SUBSCRIPTION_REL:
10740  dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
10741  break;
10742  case DO_PRE_DATA_BOUNDARY:
10743  case DO_POST_DATA_BOUNDARY:
10744  /* never dumped, nothing to do */
10745  break;
10746  }
10747 }
@ SECTION_DATA
Definition: pg_backup.h:59
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:16959
static void dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
Definition: pg_dump.c:4696
static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
Definition: pg_dump.c:10754
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:12715
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:17049
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:14638
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:14214
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:18041
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15704
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:17229
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:17306
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:10959
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:16891
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:13261
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:12949
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:17964
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:12299
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:14966
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2689
static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
Definition: pg_dump.c:12069
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2801
static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
Definition: pg_dump.c:4378
static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
Definition: pg_dump.c:4153
static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
Definition: pg_dump.c:13610
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:15160
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:14718
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:17190
static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
Definition: pg_dump.c:5126
static void dumpTransform(Archive *fout, const TransformInfo *transform)
Definition: pg_dump.c:12820
static void dumpLO(Archive *fout, const LoInfo *loinfo)
Definition: pg_dump.c:3850
static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
Definition: pg_dump.c:4739
static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
Definition: pg_dump.c:14574
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:18252
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:10831
static int dumpLOs(Archive *fout, const void *arg)
Definition: pg_dump.c:3940
static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
Definition: pg_dump.c:5195
static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
Definition: pg_dump.c:18167
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:14086
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:14896
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:12115
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:14776
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:13829
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:13329
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:98
const char * rolname
Definition: pg_dump.h:597
int numlos
Definition: pg_dump.h:598
pgoff_t dataLength
#define pgoff_t
Definition: win32_port.h:207

References ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::components, _tocEntry::dataLength, 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::dump, DUMP_COMPONENT_DATA, dumpAccessMethod(), dumpAgg(), dumpAttrDef(), dumpCast(), dumpCollation(), dumpConstraint(), dumpConversion(), dumpDefaultACL(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpIndexAttach(), dumpLO(), dumpLOs(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpPolicy(), dumpProcLang(), dumpPublication(), dumpPublicationNamespace(), dumpPublicationTable(), dumpRule(), dumpSequenceData(), dumpShellType(), dumpStatisticsExt(), dumpSubscription(), dumpSubscriptionTable(), dumpTable(), dumpTableAttach(), dumpTableData(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpType(), findObjectByDumpId(), _loInfo::numlos, _dumpableObject::objType, pg_fatal, pgoff_t, refreshMatViewData(), _loInfo::rolname, and SECTION_DATA.

Referenced by main().

◆ dumpEncoding()

static void dumpEncoding ( Archive AH)
static

Definition at line 3601 of file pg_dump.c.

3602 {
3603  const char *encname = pg_encoding_to_char(AH->encoding);
3605 
3606  pg_log_info("saving encoding = %s", encname);
3607 
3608  appendPQExpBufferStr(qry, "SET client_encoding = ");
3609  appendStringLiteralAH(qry, encname, AH);
3610  appendPQExpBufferStr(qry, ";\n");
3611 
3613  ARCHIVE_OPTS(.tag = "ENCODING",
3614  .description = "ENCODING",
3615  .section = SECTION_PRE_DATA,
3616  .createStmt = qry->data));
3617 
3618  destroyPQExpBuffer(qry);
3619 }
#define pg_encoding_to_char
Definition: pg_wchar.h:630

References appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, description, destroyPQExpBuffer(), Archive::encoding, nilCatalogId, pg_encoding_to_char, pg_log_info, and SECTION_PRE_DATA.

Referenced by main().

◆ dumpEnumType()

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

Definition at line 10990 of file pg_dump.c.

10991 {
10992  DumpOptions *dopt = fout->dopt;
10994  PQExpBuffer delq = createPQExpBuffer();
10995  PQExpBuffer query = createPQExpBuffer();
10996  PGresult *res;
10997  int num,
10998  i;
10999  Oid enum_oid;
11000  char *qtypname;
11001  char *qualtypname;
11002  char *label;
11003  int i_enumlabel;
11004  int i_oid;
11005 
11006  if (!fout->is_prepared[PREPQUERY_DUMPENUMTYPE])
11007  {
11008  /* Set up query for enum-specific details */
11009  appendPQExpBufferStr(query,
11010  "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
11011  "SELECT oid, enumlabel "
11012  "FROM pg_catalog.pg_enum "
11013  "WHERE enumtypid = $1 "
11014  "ORDER BY enumsortorder");
11015 
11016  ExecuteSqlStatement(fout, query->data);
11017 
11018  fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
11019  }
11020 
11021  printfPQExpBuffer(query,
11022  "EXECUTE dumpEnumType('%u')",
11023  tyinfo->dobj.catId.oid);
11024 
11025  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11026 
11027  num = PQntuples(res);
11028 
11029  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11030  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11031 
11032  /*
11033  * CASCADE shouldn't be required here as for normal types since the I/O
11034  * functions are generic and do not get dropped.
11035  */
11036  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11037 
11038  if (dopt->binary_upgrade)
11040  tyinfo->dobj.catId.oid,
11041  false, false);
11042 
11043  appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
11044  qualtypname);
11045 
11046  if (!dopt->binary_upgrade)
11047  {
11048  i_enumlabel = PQfnumber(res, "enumlabel");
11049 
11050  /* Labels with server-assigned oids */
11051  for (i = 0; i < num; i++)
11052  {
11053  label = PQgetvalue(res, i, i_enumlabel);
11054  if (i > 0)
11055  appendPQExpBufferChar(q, ',');
11056  appendPQExpBufferStr(q, "\n ");
11057  appendStringLiteralAH(q, label, fout);
11058  }
11059  }
11060 
11061  appendPQExpBufferStr(q, "\n);\n");
11062 
11063  if (dopt->binary_upgrade)
11064  {
11065  i_oid = PQfnumber(res, "oid");
11066  i_enumlabel = PQfnumber(res, "enumlabel");
11067 
11068  /* Labels with dump-assigned (preserved) oids */
11069  for (i = 0; i < num; i++)
11070  {
11071  enum_oid = atooid(PQgetvalue(res, i, i_oid));
11072  label = PQgetvalue(res, i, i_enumlabel);
11073 
11074  if (i == 0)
11075  appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
11077  "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
11078  enum_oid);
11079  appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
11080  appendStringLiteralAH(q, label, fout);
11081  appendPQExpBufferStr(q, ";\n\n");
11082  }
11083  }
11084 
11085  if (dopt->binary_upgrade)
11087  "TYPE", qtypname,
11088  tyinfo->dobj.namespace->dobj.name);
11089 
11090  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11091  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11092  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11093  .namespace = tyinfo->dobj.namespace->dobj.name,
11094  .owner = tyinfo->rolname,
11095  .description = "TYPE",
11096  .section = SECTION_PRE_DATA,
11097  .createStmt = q->data,
11098  .dropStmt = delq->data));
11099 
11100  /* Dump Type Comments and Security Labels */
11101  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11102  dumpComment(fout, "TYPE", qtypname,
11103  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11104  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11105 
11106  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11107  dumpSecLabel(fout, "TYPE", qtypname,
11108  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11109  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11110 
11111  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11112  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11113  qtypname, NULL,
11114  tyinfo->dobj.namespace->dobj.name,
11115  NULL, tyinfo->rolname, &tyinfo->dacl);
11116 
11117  PQclear(res);
11118  destroyPQExpBuffer(q);
11119  destroyPQExpBuffer(delq);
11120  destroyPQExpBuffer(query);
11121  free(qtypname);
11122  free(qualtypname);
11123 }
@ PREPQUERY_DUMPENUMTYPE
Definition: pg_backup.h:70
static char * label

References appendPQExpBuffer(), appendPQExpBufferChar(), 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(), ExecuteSqlQuery(), ExecuteSqlStatement(), fmtId(), fmtQualifiedDumpable, free, i, InvalidDumpId, Archive::is_prepared, label, _dumpableObject::name, CatalogId::oid, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), PREPQUERY_DUMPENUMTYPE, printfPQExpBuffer(), res, _typeInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpType().

◆ dumpEventTrigger()

static void dumpEventTrigger ( Archive fout,
const EventTriggerInfo evtinfo 
)
static

Definition at line 18167 of file pg_dump.c.

18168 {
18169  DumpOptions *dopt = fout->dopt;
18170  PQExpBuffer query;
18171  PQExpBuffer delqry;
18172  char *qevtname;
18173 
18174  /* Do nothing in data-only dump */
18175  if (dopt->dataOnly)
18176  return;
18177 
18178  query = createPQExpBuffer();
18179  delqry = createPQExpBuffer();
18180 
18181  qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
18182 
18183  appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
18184  appendPQExpBufferStr(query, qevtname);
18185  appendPQExpBufferStr(query, " ON ");
18186  appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
18187 
18188  if (strcmp("", evtinfo->evttags) != 0)
18189  {
18190  appendPQExpBufferStr(query, "\n WHEN TAG IN (");
18191  appendPQExpBufferStr(query, evtinfo->evttags);
18192  appendPQExpBufferChar(query, ')');
18193  }
18194 
18195  appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
18196  appendPQExpBufferStr(query, evtinfo->evtfname);
18197  appendPQExpBufferStr(query, "();\n");
18198 
18199  if (evtinfo->evtenabled != 'O')
18200  {
18201  appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
18202  qevtname);
18203  switch (evtinfo->evtenabled)
18204  {
18205  case 'D':
18206  appendPQExpBufferStr(query, "DISABLE");
18207  break;
18208  case 'A':
18209  appendPQExpBufferStr(query, "ENABLE ALWAYS");
18210  break;
18211  case 'R':
18212  appendPQExpBufferStr(query, "ENABLE REPLICA");
18213  break;
18214  default:
18215  appendPQExpBufferStr(query, "ENABLE");
18216  break;
18217  }
18218  appendPQExpBufferStr(query, ";\n");
18219  }
18220 
18221  appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
18222  qevtname);
18223 
18224  if (dopt->binary_upgrade)
18225  binary_upgrade_extension_member(query, &evtinfo->dobj,
18226  "EVENT TRIGGER", qevtname, NULL);
18227 
18228  if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18229  ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
18230  ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
18231  .owner = evtinfo->evtowner,
18232  .description = "EVENT TRIGGER",
18233  .section = SECTION_POST_DATA,
18234  .createStmt = query->data,
18235  .dropStmt = delqry->data));
18236 
18237  if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18238  dumpComment(fout, "EVENT TRIGGER", qevtname,
18239  NULL, evtinfo->evtowner,
18240  evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
18241 
18242  destroyPQExpBuffer(query);
18243  destroyPQExpBuffer(delqry);
18244  free(qevtname);
18245 }
char * evtevent
Definition: pg_dump.h:456
char * evtfname
Definition: pg_dump.h:459
char evtenabled
Definition: pg_dump.h:460
const char * evtowner
Definition: pg_dump.h:457
char * evttags
Definition: pg_dump.h:458
DumpableObject dobj
Definition: pg_dump.h:454

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _evttriggerInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _evttriggerInfo::evtenabled, _evttriggerInfo::evtevent, _evttriggerInfo::evtfname, _evttriggerInfo::evtowner, _evttriggerInfo::evttags, fmtId(), free, _dumpableObject::name, pg_strdup(), and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

◆ dumpExtension()

static void dumpExtension ( Archive fout,
const ExtensionInfo extinfo 
)
static

Definition at line 10831 of file pg_dump.c.

10832 {
10833  DumpOptions *dopt = fout->dopt;
10834  PQExpBuffer q;
10835  PQExpBuffer delq;
10836  char *qextname;
10837 
10838  /* Do nothing in data-only dump */
10839  if (dopt->dataOnly)
10840  return;
10841 
10842  q = createPQExpBuffer();
10843  delq = createPQExpBuffer();
10844 
10845  qextname = pg_strdup(fmtId(extinfo->dobj.name));
10846 
10847  appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
10848 
10849  if (!dopt->binary_upgrade)
10850  {
10851  /*
10852  * In a regular dump, we simply create the extension, intentionally
10853  * not specifying a version, so that the destination installation's
10854  * default version is used.
10855  *
10856  * Use of IF NOT EXISTS here is unlike our behavior for other object
10857  * types; but there are various scenarios in which it's convenient to
10858  * manually create the desired extension before restoring, so we
10859  * prefer to allow it to exist already.
10860  */
10861  appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
10862  qextname, fmtId(extinfo->namespace));
10863  }
10864  else
10865  {
10866  /*
10867  * In binary-upgrade mode, it's critical to reproduce the state of the
10868  * database exactly, so our procedure is to create an empty extension,
10869  * restore all the contained objects normally, and add them to the
10870  * extension one by one. This function performs just the first of
10871  * those steps. binary_upgrade_extension_member() takes care of
10872  * adding member objects as they're created.
10873  */
10874  int i;
10875  int n;
10876 
10877  appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
10878 
10879  /*
10880  * We unconditionally create the extension, so we must drop it if it
10881  * exists. This could happen if the user deleted 'plpgsql' and then
10882  * readded it, causing its oid to be greater than g_last_builtin_oid.
10883  */
10884  appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
10885 
10887  "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
10888  appendStringLiteralAH(q, extinfo->dobj.name, fout);
10889  appendPQExpBufferStr(q, ", ");
10890  appendStringLiteralAH(q, extinfo->namespace, fout);
10891  appendPQExpBufferStr(q, ", ");
10892  appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
10893  appendStringLiteralAH(q, extinfo->extversion, fout);
10894  appendPQExpBufferStr(q, ", ");
10895 
10896  /*
10897  * Note that we're pushing extconfig (an OID array) back into
10898  * pg_extension exactly as-is. This is OK because pg_class OIDs are
10899  * preserved in binary upgrade.
10900  */
10901  if (strlen(extinfo->extconfig) > 2)
10902  appendStringLiteralAH(q, extinfo->extconfig, fout);
10903  else
10904  appendPQExpBufferStr(q, "NULL");
10905  appendPQExpBufferStr(q, ", ");
10906  if (strlen(extinfo->extcondition) > 2)
10907  appendStringLiteralAH(q, extinfo->extcondition, fout);
10908  else
10909  appendPQExpBufferStr(q, "NULL");
10910  appendPQExpBufferStr(q, ", ");
10911  appendPQExpBufferStr(q, "ARRAY[");
10912  n = 0;
10913  for (i = 0; i < extinfo->dobj.nDeps; i++)
10914  {
10915  DumpableObject *extobj;
10916 
10917  extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
10918  if (extobj && extobj->objType == DO_EXTENSION)
10919  {
10920  if (n++ > 0)
10921  appendPQExpBufferChar(q, ',');
10922  appendStringLiteralAH(q, extobj->name, fout);
10923  }
10924  }
10925  appendPQExpBufferStr(q, "]::pg_catalog.text[]");
10926  appendPQExpBufferStr(q, ");\n");
10927  }
10928 
10929  if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10930  ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
10931  ARCHIVE_OPTS(.tag = extinfo->dobj.name,
10932  .description = "EXTENSION",
10933  .section = SECTION_PRE_DATA,
10934  .createStmt = q->data,
10935  .dropStmt = delq->data));
10936 
10937  /* Dump Extension Comments and Security Labels */
10938  if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10939  dumpComment(fout, "EXTENSION", qextname,
10940  NULL, "",
10941  extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
10942 
10943  if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10944  dumpSecLabel(fout, "EXTENSION", qextname,
10945  NULL, "",
10946  extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
10947 
10948  free(qextname);
10949 
10950  destroyPQExpBuffer(q);
10951  destroyPQExpBuffer(delq);
10952 }
bool relocatable
Definition: pg_dump.h:182
char * extversion
Definition: pg_dump.h:184
char * extcondition
Definition: pg_dump.h:186
char * extconfig
Definition: pg_dump.h:185

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, _dumpableObject::dependencies, destroyPQExpBuffer(), DO_EXTENSION, _extensionInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), _extensionInfo::extcondition, _extensionInfo::extconfig, _extensionInfo::extversion, findObjectByDumpId(), fmtId(), free, i, _dumpableObject::name, _dumpableObject::nDeps, _dumpableObject::objType, pg_strdup(), _extensionInfo::relocatable, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpForeignDataWrapper()

static void dumpForeignDataWrapper ( Archive fout,
const FdwInfo fdwinfo 
)
static

Definition at line 14896 of file pg_dump.c.

14897 {
14898  DumpOptions *dopt = fout->dopt;
14899  PQExpBuffer q;
14900  PQExpBuffer delq;
14901  char *qfdwname;
14902 
14903  /* Do nothing in data-only dump */
14904  if (dopt->dataOnly)
14905  return;
14906 
14907  q = createPQExpBuffer();
14908  delq = createPQExpBuffer();
14909 
14910  qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
14911 
14912  appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
14913  qfdwname);
14914 
14915  if (strcmp(fdwinfo->fdwhandler, "-") != 0)
14916  appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
14917 
14918  if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
14919  appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
14920 
14921  if (strlen(fdwinfo->fdwoptions) > 0)
14922  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
14923 
14924  appendPQExpBufferStr(q, ";\n");
14925 
14926  appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
14927  qfdwname);
14928 
14929  if (dopt->binary_upgrade)
14931  "FOREIGN DATA WRAPPER", qfdwname,
14932  NULL);
14933 
14934  if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14935  ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
14936  ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
14937  .owner = fdwinfo->rolname,
14938  .description = "FOREIGN DATA WRAPPER",
14939  .section = SECTION_PRE_DATA,
14940  .createStmt = q->data,
14941  .dropStmt = delq->data));
14942 
14943  /* Dump Foreign Data Wrapper Comments */
14944  if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14945  dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
14946  NULL, fdwinfo->rolname,
14947  fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
14948 
14949  /* Handle the ACL */
14950  if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14951  dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
14952  "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
14953  NULL, fdwinfo->rolname, &fdwinfo->dacl);
14954 
14955  free(qfdwname);
14956 
14957  destroyPQExpBuffer(q);
14958  destroyPQExpBuffer(delq);
14959 }
char * fdwhandler
Definition: pg_dump.h:561
const char * rolname
Definition: pg_dump.h:560
char * fdwvalidator
Definition: pg_dump.h:562
char * fdwoptions
Definition: pg_dump.h:563
DumpableAcl dacl
Definition: pg_dump.h:559
DumpableObject dobj
Definition: pg_dump.h:558

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _fdwInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _fdwInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpACL(), dumpComment(), _dumpableObject::dumpId, _fdwInfo::fdwhandler, _fdwInfo::fdwoptions, _fdwInfo::fdwvalidator, fmtId(), free, InvalidDumpId, _dumpableObject::name, pg_strdup(), _fdwInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpForeignServer()

static void dumpForeignServer ( Archive fout,
const ForeignServerInfo srvinfo 
)
static

Definition at line 14966 of file pg_dump.c.

14967 {
14968  DumpOptions *dopt = fout->dopt;
14969  PQExpBuffer q;
14970  PQExpBuffer delq;
14971  PQExpBuffer query;
14972  PGresult *res;
14973  char *qsrvname;
14974  char *fdwname;
14975 
14976  /* Do nothing in data-only dump */
14977  if (dopt->dataOnly)
14978  return;
14979 
14980  q = createPQExpBuffer();
14981  delq = createPQExpBuffer();
14982  query = createPQExpBuffer();
14983 
14984  qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
14985 
14986  /* look up the foreign-data wrapper */
14987  appendPQExpBuffer(query, "SELECT fdwname "
14988  "FROM pg_foreign_data_wrapper w "
14989  "WHERE w.oid = '%u'",
14990  srvinfo->srvfdw);
14991  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14992  fdwname = PQgetvalue(res, 0, 0);
14993 
14994  appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
14995  if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
14996  {
14997  appendPQExpBufferStr(q, " TYPE ");
14998  appendStringLiteralAH(q, srvinfo->srvtype, fout);
14999  }
15000  if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
15001  {
15002  appendPQExpBufferStr(q, " VERSION ");
15003  appendStringLiteralAH(q, srvinfo->srvversion, fout);
15004  }
15005 
15006  appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
15007  appendPQExpBufferStr(q, fmtId(fdwname));
15008 
15009  if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
15010  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
15011 
15012  appendPQExpBufferStr(q, ";\n");
15013 
15014  appendPQExpBuffer(delq, "DROP SERVER %s;\n",
15015  qsrvname);
15016 
15017  if (dopt->binary_upgrade)
15019  "SERVER", qsrvname, NULL);
15020 
15021  if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15022  ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
15023  ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
15024  .owner = srvinfo->rolname,
15025  .description = "SERVER",
15026  .section = SECTION_PRE_DATA,
15027  .createStmt = q->data,
15028  .dropStmt = delq->data));
15029 
15030  /* Dump Foreign Server Comments */
15031  if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15032  dumpComment(fout, "SERVER", qsrvname,
15033  NULL, srvinfo->rolname,
15034  srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
15035 
15036  /* Handle the ACL */
15037  if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
15038  dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
15039  "FOREIGN SERVER", qsrvname, NULL, NULL,
15040  NULL, srvinfo->rolname, &srvinfo->dacl);
15041 
15042  /* Dump user mappings */
15043  if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
15044  dumpUserMappings(fout,
15045  srvinfo->dobj.name, NULL,
15046  srvinfo->rolname,
15047  srvinfo->dobj.catId, srvinfo->dobj.dumpId);
15048 
15049  PQclear(res);
15050 
15051  free(qsrvname);
15052 
15053  destroyPQExpBuffer(q);
15054  destroyPQExpBuffer(delq);
15055  destroyPQExpBuffer(query);
15056 }
static void dumpUserMappings(Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
Definition: pg_dump.c:15066
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:103
DumpableAcl dacl
Definition: pg_dump.h:569
char * srvoptions
Definition: pg_dump.h:574
DumpableObject dobj
Definition: pg_dump.h:568
const char * rolname
Definition: pg_dump.h:570
char * srvversion
Definition: pg_dump.h:573

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _foreignServerInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _foreignServerInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_USERMAP, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpUserMappings(), ExecuteSqlQueryForSingleRow(), fmtId(), free, InvalidDumpId, _dumpableObject::name, pg_strdup(), PQclear(), PQgetvalue(), res, _foreignServerInfo::rolname, SECTION_PRE_DATA, _foreignServerInfo::srvfdw, _foreignServerInfo::srvoptions, _foreignServerInfo::srvtype, and _foreignServerInfo::srvversion.

Referenced by dumpDumpableObject().

◆ dumpFunc()

static void dumpFunc ( Archive fout,
const FuncInfo finfo 
)
static

Definition at line 12299 of file pg_dump.c.

12300 {
12301  DumpOptions *dopt = fout->dopt;
12302  PQExpBuffer query;
12303  PQExpBuffer q;
12304  PQExpBuffer delqry;
12305  PQExpBuffer asPart;
12306  PGresult *res;
12307  char *funcsig; /* identity signature */
12308  char *funcfullsig = NULL; /* full signature */
12309  char *funcsig_tag;
12310  char *qual_funcsig;
12311  char *proretset;
12312  char *prosrc;
12313  char *probin;
12314  char *prosqlbody;
12315  char *funcargs;
12316  char *funciargs;
12317  char *funcresult;
12318  char *protrftypes;
12319  char *prokind;
12320  char *provolatile;
12321  char *proisstrict;
12322  char *prosecdef;
12323  char *proleakproof;
12324  char *proconfig;
12325  char *procost;
12326  char *prorows;
12327  char *prosupport;
12328  char *proparallel;
12329  char *lanname;
12330  char **configitems = NULL;
12331  int nconfigitems = 0;
12332  const char *keyword;
12333 
12334  /* Do nothing in data-only dump */
12335  if (dopt->dataOnly)
12336  return;
12337 
12338  query = createPQExpBuffer();
12339  q = createPQExpBuffer();
12340  delqry = createPQExpBuffer();
12341  asPart = createPQExpBuffer();
12342 
12343  if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
12344  {
12345  /* Set up query for function-specific details */
12346  appendPQExpBufferStr(query,
12347  "PREPARE dumpFunc(pg_catalog.oid) AS\n");
12348 
12349  appendPQExpBufferStr(query,
12350  "SELECT\n"
12351  "proretset,\n"
12352  "prosrc,\n"
12353  "probin,\n"
12354  "provolatile,\n"
12355  "proisstrict,\n"
12356  "prosecdef,\n"
12357  "lanname,\n"
12358  "proconfig,\n"
12359  "procost,\n"
12360  "prorows,\n"
12361  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
12362  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
12363  "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
12364  "proleakproof,\n");
12365 
12366  if (fout->remoteVersion >= 90500)
12367  appendPQExpBufferStr(query,
12368  "array_to_string(protrftypes, ' ') AS protrftypes,\n");
12369  else
12370  appendPQExpBufferStr(query,
12371  "NULL AS protrftypes,\n");
12372 
12373  if (fout->remoteVersion >= 90600)
12374  appendPQExpBufferStr(query,
12375  "proparallel,\n");
12376  else
12377  appendPQExpBufferStr(query,
12378  "'u' AS proparallel,\n");
12379 
12380  if (fout->remoteVersion >= 110000)
12381  appendPQExpBufferStr(query,
12382  "prokind,\n");
12383  else
12384  appendPQExpBufferStr(query,
12385  "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
12386 
12387  if (fout->remoteVersion >= 120000)
12388  appendPQExpBufferStr(query,
12389  "prosupport,\n");
12390  else
12391  appendPQExpBufferStr(query,
12392  "'-' AS prosupport,\n");
12393 
12394  if (fout->remoteVersion >= 140000)
12395  appendPQExpBufferStr(query,
12396  "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
12397  else
12398  appendPQExpBufferStr(query,
12399  "NULL AS prosqlbody\n");
12400 
12401  appendPQExpBufferStr(query,
12402  "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
12403  "WHERE p.oid = $1 "
12404  "AND l.oid = p.prolang");
12405 
12406  ExecuteSqlStatement(fout, query->data);
12407 
12408  fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
12409  }
12410 
12411  printfPQExpBuffer(query,
12412  "EXECUTE dumpFunc('%u')",
12413  finfo->dobj.catId.oid);
12414 
12415  res = ExecuteSqlQueryForSingleRow(fout, query->data);
12416 
12417  proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
12418  if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
12419  {
12420  prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
12421  probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
12422  prosqlbody = NULL;
12423  }
12424  else
12425  {
12426  prosrc = NULL;
12427  probin = NULL;
12428  prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
12429  }
12430  funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
12431  funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
12432  funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
12433  protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
12434  prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
12435  provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
12436  proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
12437  prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
12438  proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
12439  proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
12440  procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
12441  prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
12442  prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
12443  proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
12444  lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
12445 
12446  /*
12447  * See backend/commands/functioncmds.c for details of how the 'AS' clause
12448  * is used.
12449  */
12450  if (prosqlbody)
12451  {
12452  appendPQExpBufferStr(asPart, prosqlbody);
12453  }
12454  else if (probin[0] != '\0')
12455  {
12456  appendPQExpBufferStr(asPart, "AS ");
12457  appendStringLiteralAH(asPart, probin, fout);
12458  if (prosrc[0] != '\0')
12459  {
12460  appendPQExpBufferStr(asPart, ", ");
12461 
12462  /*
12463  * where we have bin, use dollar quoting if allowed and src
12464  * contains quote or backslash; else use regular quoting.
12465  */
12466  if (dopt->disable_dollar_quoting ||
12467  (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
12468  appendStringLiteralAH(asPart, prosrc, fout);
12469  else
12470  appendStringLiteralDQ(asPart, prosrc, NULL);
12471  }
12472  }
12473  else
12474  {
12475  appendPQExpBufferStr(asPart, "AS ");
12476  /* with no bin, dollar quote src unconditionally if allowed */
12477  if (dopt->disable_dollar_quoting)
12478  appendStringLiteralAH(asPart, prosrc, fout);
12479  else
12480  appendStringLiteralDQ(asPart, prosrc, NULL);
12481  }
12482 
12483  if (*proconfig)
12484  {
12485  if (!parsePGArray(proconfig, &configitems, &nconfigitems))
12486  pg_fatal("could not parse %s array", "proconfig");
12487  }
12488  else
12489  {
12490  configitems = NULL;
12491  nconfigitems = 0;
12492  }
12493 
12494  funcfullsig = format_function_arguments(finfo, funcargs, false);
12495  funcsig = format_function_arguments(finfo, funciargs, false);
12496 
12497  funcsig_tag = format_function_signature(fout, finfo, false);
12498 
12499  qual_funcsig = psprintf("%s.%s",
12500  fmtId(finfo->dobj.namespace->dobj.name),
12501  funcsig);
12502 
12503  if (prokind[0] == PROKIND_PROCEDURE)
12504  keyword = "PROCEDURE";
12505  else
12506  keyword = "FUNCTION"; /* works for window functions too */
12507 
12508  appendPQExpBuffer(delqry, "DROP %s %s;\n",
12509  keyword, qual_funcsig);
12510 
12511  appendPQExpBuffer(q, "CREATE %s %s.%s",
12512  keyword,
12513  fmtId(finfo->dobj.namespace->dobj.name),
12514  funcfullsig ? funcfullsig :
12515  funcsig);
12516 
12517  if (prokind[0] == PROKIND_PROCEDURE)
12518  /* no result type to output */ ;
12519  else if (funcresult)
12520  appendPQExpBuffer(q, " RETURNS %s", funcresult);
12521  else
12522  appendPQExpBuffer(q, " RETURNS %s%s",
12523  (proretset[0] == 't') ? "SETOF " : "",
12524  getFormattedTypeName(fout, finfo->prorettype,
12525  zeroIsError));
12526 
12527  appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
12528 
12529  if (*protrftypes)
12530  {
12531  Oid *typeids = palloc(FUNC_MAX_ARGS * sizeof(Oid));
12532  int i;
12533 
12534  appendPQExpBufferStr(q, " TRANSFORM ");
12535  parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
12536  for (i = 0; typeids[i]; i++)
12537  {
12538  if (i != 0)
12539  appendPQExpBufferStr(q, ", ");
12540  appendPQExpBuffer(q, "FOR TYPE %s",
12541  getFormattedTypeName(fout, typeids[i], zeroAsNone));
12542  }
12543  }
12544 
12545  if (prokind[0] == PROKIND_WINDOW)
12546  appendPQExpBufferStr(q, " WINDOW");
12547 
12548  if (provolatile[0] != PROVOLATILE_VOLATILE)
12549  {
12550  if (provolatile[0] == PROVOLATILE_IMMUTABLE)
12551  appendPQExpBufferStr(q, " IMMUTABLE");
12552  else if (provolatile[0] == PROVOLATILE_STABLE)
12553  appendPQExpBufferStr(q, " STABLE");
12554  else if (provolatile[0] != PROVOLATILE_VOLATILE)
12555  pg_fatal("unrecognized provolatile value for function \"%s\"",
12556  finfo->dobj.name);
12557  }
12558 
12559  if (proisstrict[0] == 't')
12560  appendPQExpBufferStr(q, " STRICT");
12561 
12562  if (prosecdef[0] == 't')
12563  appendPQExpBufferStr(q, " SECURITY DEFINER");
12564 
12565  if (proleakproof[0] == 't')
12566  appendPQExpBufferStr(q, " LEAKPROOF");
12567 
12568  /*
12569  * COST and ROWS are emitted only if present and not default, so as not to
12570  * break backwards-compatibility of the dump without need. Keep this code
12571  * in sync with the defaults in functioncmds.c.
12572  */
12573  if (strcmp(procost, "0") != 0)
12574  {
12575  if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
12576  {
12577  /* default cost is 1 */
12578  if (strcmp(procost, "1") != 0)
12579  appendPQExpBuffer(q, " COST %s", procost);
12580  }
12581  else
12582  {
12583  /* default cost is 100 */
12584  if (strcmp(procost, "100") != 0)
12585  appendPQExpBuffer(q, " COST %s", procost);
12586  }
12587  }
12588  if (proretset[0] == 't' &&
12589  strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
12590  appendPQExpBuffer(q, " ROWS %s", prorows);
12591 
12592  if (strcmp(prosupport, "-") != 0)
12593  {
12594  /* We rely on regprocout to provide quoting and qualification */
12595  appendPQExpBuffer(q, " SUPPORT %s", prosupport);
12596  }
12597 
12598  if (proparallel[0] != PROPARALLEL_UNSAFE)
12599  {
12600  if (proparallel[0] == PROPARALLEL_SAFE)
12601  appendPQExpBufferStr(q, " PARALLEL SAFE");
12602  else if (proparallel[0] == PROPARALLEL_RESTRICTED)
12603  appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
12604  else if (proparallel[0] != PROPARALLEL_UNSAFE)
12605  pg_fatal("unrecognized proparallel value for function \"%s\"",
12606  finfo->dobj.name);
12607  }
12608 
12609  for (int i = 0; i < nconfigitems; i++)
12610  {
12611  /* we feel free to scribble on configitems[] here */
12612  char *configitem = configitems[i];
12613  char *pos;
12614 
12615  pos = strchr(configitem, '=');
12616  if (pos == NULL)
12617  continue;
12618  *pos++ = '\0';
12619  appendPQExpBuffer(q, "\n SET %s TO ", fmtId(configitem));
12620 
12621  /*
12622  * Variables that are marked GUC_LIST_QUOTE were already fully quoted
12623  * by flatten_set_variable_args() before they were put into the
12624  * proconfig array. However, because the quoting rules used there
12625  * aren't exactly like SQL's, we have to break the list value apart
12626  * and then quote the elements as string literals. (The elements may
12627  * be double-quoted as-is, but we can't just feed them to the SQL
12628  * parser; it would do the wrong thing with elements that are
12629  * zero-length or longer than NAMEDATALEN.)
12630  *
12631  * Variables that are not so marked should just be emitted as simple
12632  * string literals. If the variable is not known to
12633  * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
12634  * to use GUC_LIST_QUOTE for extension variables.
12635  */
12636  if (variable_is_guc_list_quote(configitem))
12637  {
12638  char **namelist;
12639  char **nameptr;
12640 
12641  /* Parse string into list of identifiers */
12642  /* this shouldn't fail really */
12643  if (SplitGUCList(pos, ',', &namelist))
12644  {
12645  for (nameptr = namelist; *nameptr; nameptr++)
12646  {
12647  if (nameptr != namelist)
12648  appendPQExpBufferStr(q, ", ");
12649  appendStringLiteralAH(q, *nameptr, fout);
12650  }
12651  }
12652  pg_free(namelist);
12653  }
12654  else
12655  appendStringLiteralAH(q, pos, fout);
12656  }
12657 
12658  appendPQExpBuffer(q, "\n %s;\n", asPart->data);
12659 
12660  append_depends_on_extension(fout, q, &finfo->dobj,
12661  "pg_catalog.pg_proc", keyword,
12662  qual_funcsig);
12663 
12664  if (dopt->binary_upgrade)
12666  keyword, funcsig,
12667  finfo->dobj.namespace->dobj.name);
12668 
12669  if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12670  ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
12671  ARCHIVE_OPTS(.tag = funcsig_tag,
12672  .namespace = finfo->dobj.namespace->dobj.name,
12673  .owner = finfo->rolname,
12674  .description = keyword,
12675  .section = finfo->postponed_def ?
12677  .createStmt = q->data,
12678  .dropStmt = delqry->data));
12679 
12680  /* Dump Function Comments and Security Labels */
12681  if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12682  dumpComment(fout, keyword, funcsig,
12683  finfo->dobj.namespace->dobj.name, finfo->rolname,
12684  finfo->dobj.catId, 0, finfo->dobj.dumpId);
12685 
12686  if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12687  dumpSecLabel(fout, keyword, funcsig,
12688  finfo->dobj.namespace->dobj.name, finfo->rolname,
12689  finfo->dobj.catId, 0, finfo->dobj.dumpId);
12690 
12691  if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
12692  dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
12693  funcsig, NULL,
12694  finfo->dobj.namespace->dobj.name,
12695  NULL, finfo->rolname, &finfo->dacl);
12696 
12697  PQclear(res);
12698 
12699  destroyPQExpBuffer(query);
12700  destroyPQExpBuffer(q);
12701  destroyPQExpBuffer(delqry);
12702  destroyPQExpBuffer(asPart);
12703  free(funcsig);
12704  free(funcfullsig);
12705  free(funcsig_tag);
12706  free(qual_funcsig);
12707  free(configitems);
12708 }
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1070
bool variable_is_guc_list_quote(const char *name)
Definition: dumputils.c:689
void * palloc(Size size)
Definition: mcxt.c:1317
@ PREPQUERY_DUMPFUNC
Definition: pg_backup.h:71
#define FUNC_MAX_ARGS
bool parsePGArray(const char *atext, char ***itemarray, int *nitems)
Definition: string_utils.c:657
void appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
Definition: string_utils.c:331
int disable_dollar_quoting
Definition: pg_backup.h:178
bool postponed_def
Definition: pg_dump.h:232
const char * rolname
Definition: pg_dump.h:227
Oid prorettype
Definition: pg_dump.h:231
DumpableAcl dacl
Definition: pg_dump.h:226
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3680

References append_depends_on_extension(), appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, appendStringLiteralDQ(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _funcInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _dumpOptions::disable_dollar_quoting, _funcInfo::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(), format_function_arguments(), format_function_signature(), free, FUNC_MAX_ARGS, getFormattedTypeName(), i, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, palloc(), parseOidArray(), parsePGArray(), pg_fatal, pg_free(), _funcInfo::postponed_def, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PREPQUERY_DUMPFUNC, printfPQExpBuffer(), _funcInfo::prorettype, psprintf(), Archive::remoteVersion, res, _funcInfo::rolname, SECTION_POST_DATA, SECTION_PRE_DATA, SplitGUCList(), variable_is_guc_list_quote(), zeroAsNone, and zeroIsError.

Referenced by dumpDumpableObject().

◆ dumpIndex()

static void dumpIndex ( Archive fout,
const IndxInfo indxinfo 
)
static

Definition at line 17049 of file pg_dump.c.

17050 {
17051  DumpOptions *dopt = fout->dopt;
17052  TableInfo *tbinfo = indxinfo->indextable;
17053  bool is_constraint = (indxinfo->indexconstraint != 0);
17054  PQExpBuffer q;
17055  PQExpBuffer delq;
17056  char *qindxname;
17057  char *qqindxname;
17058 
17059  /* Do nothing in data-only dump */
17060  if (dopt->dataOnly)
17061  return;
17062 
17063  q = createPQExpBuffer();
17064  delq = createPQExpBuffer();
17065 
17066  qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
17067  qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
17068 
17069  /*
17070  * If there's an associated constraint, don't dump the index per se, but
17071  * do dump any comment for it. (This is safe because dependency ordering
17072  * will have ensured the constraint is emitted first.) Note that the
17073  * emitted comment has to be shown as depending on the constraint, not the
17074  * index, in such cases.
17075  */
17076  if (!is_constraint)
17077  {
17078  char *indstatcols = indxinfo->indstatcols;
17079  char *indstatvals = indxinfo->indstatvals;
17080  char **indstatcolsarray = NULL;
17081  char **indstatvalsarray = NULL;
17082  int nstatcols = 0;
17083  int nstatvals = 0;
17084 
17085  if (dopt->binary_upgrade)
17087  indxinfo->dobj.catId.oid);
17088 
17089  /* Plain secondary index */
17090  appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
17091 
17092  /*
17093  * Append ALTER TABLE commands as needed to set properties that we
17094  * only have ALTER TABLE syntax for. Keep this in sync with the
17095  * similar code in dumpConstraint!
17096  */
17097 
17098  /* If the index is clustered, we need to record that. */
17099  if (indxinfo->indisclustered)
17100  {
17101  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17102  fmtQualifiedDumpable(tbinfo));
17103  /* index name is not qualified in this syntax */
17104  appendPQExpBuffer(q, " ON %s;\n",
17105  qindxname);
17106  }
17107 
17108  /*
17109  * If the index has any statistics on some of its columns, generate
17110  * the associated ALTER INDEX queries.
17111  */
17112  if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
17113  {
17114  int j;
17115 
17116  if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
17117  pg_fatal("could not parse index statistic columns");
17118  if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
17119  pg_fatal("could not parse index statistic values");
17120  if (nstatcols != nstatvals)
17121  pg_fatal("mismatched number of columns and values for index statistics");
17122 
17123  for (j = 0; j < nstatcols; j++)
17124  {
17125  appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
17126 
17127  /*
17128  * Note that this is a column number, so no quotes should be
17129  * used.
17130  */
17131  appendPQExpBuffer(q, "ALTER COLUMN %s ",
17132  indstatcolsarray[j]);
17133  appendPQExpBuffer(q, "SET STATISTICS %s;\n",
17134  indstatvalsarray[j]);
17135  }
17136  }
17137 
17138  /* Indexes can depend on extensions */
17139  append_depends_on_extension(fout, q, &indxinfo->dobj,
17140  "pg_catalog.pg_class",
17141  "INDEX", qqindxname);
17142 
17143  /* If the index defines identity, we need to record that. */
17144  if (indxinfo->indisreplident)
17145  {
17146  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17147  fmtQualifiedDumpable(tbinfo));
17148  /* index name is not qualified in this syntax */
17149  appendPQExpBuffer(q, " INDEX %s;\n",
17150  qindxname);
17151  }
17152 
17153  appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
17154 
17155  if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17156  ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
17157  ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
17158  .namespace = tbinfo->dobj.namespace->dobj.name,
17159  .tablespace = indxinfo->tablespace,
17160  .owner = tbinfo->rolname,
17161  .description = "INDEX",
17162  .section = SECTION_POST_DATA,
17163  .createStmt = q->data,
17164  .dropStmt = delq->data));
17165 
17166  free(indstatcolsarray);
17167  free(indstatvalsarray);
17168  }
17169 
17170  /* Dump Index Comments */
17171  if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17172  dumpComment(fout, "INDEX", qindxname,
17173  tbinfo->dobj.namespace->dobj.name,
17174  tbinfo->rolname,
17175  indxinfo->dobj.catId, 0,
17176  is_constraint ? indxinfo->indexconstraint :
17177  indxinfo->dobj.dumpId);
17178 
17179  destroyPQExpBuffer(q);
17180  destroyPQExpBuffer(delq);
17181  free(qindxname);
17182  free(qqindxname);
17183 }
char * indstatvals
Definition: pg_dump.h:402
char * indstatcols
Definition: pg_dump.h:401
TableInfo * indextable
Definition: pg_dump.h:397
DumpId indexconstraint
Definition: pg_dump.h:414
char * indexdef
Definition: pg_dump.h:398

References append_depends_on_extension(), appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _indxInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, fmtId(), fmtQualifiedDumpable, free, _indxInfo::indexconstraint, _indxInfo::indexdef, _indxInfo::indextable, _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indstatcols, _indxInfo::indstatvals, j, _dumpableObject::name, CatalogId::oid, parsePGArray(), pg_fatal, pg_strdup(), _tableInfo::rolname, SECTION_POST_DATA, and _indxInfo::tablespace.

Referenced by dumpDumpableObject().

◆ dumpIndexAttach()

static void dumpIndexAttach ( Archive fout,
const IndexAttachInfo attachinfo 
)
static

Definition at line 17190 of file pg_dump.c.

17191 {
17192  /* Do nothing in data-only dump */
17193  if (fout->dopt->dataOnly)
17194  return;
17195 
17196  if (attachinfo->partitionIdx->dobj.dump & DUMP_COMPONENT_DEFINITION)
17197  {
17199 
17200  appendPQExpBuffer(q, "ALTER INDEX %s ",
17201  fmtQualifiedDumpable(attachinfo->parentIdx));
17202  appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
17203  fmtQualifiedDumpable(attachinfo->partitionIdx));
17204 
17205  /*
17206  * There is no point in creating a drop query as the drop is done by
17207  * index drop. (If you think to change this, see also
17208  * _printTocEntry().) Although this object doesn't really have
17209  * ownership as such, set the owner field anyway to ensure that the
17210  * command is run by the correct role at restore time.
17211  */
17212  ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
17213  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
17214  .namespace = attachinfo->dobj.namespace->dobj.name,
17215  .owner = attachinfo->parentIdx->indextable->rolname,
17216  .description = "INDEX ATTACH",
17217  .section = SECTION_POST_DATA,
17218  .createStmt = q->data));
17219 
17220  destroyPQExpBuffer(q);
17221  }
17222 }
IndxInfo * parentIdx
Definition: pg_dump.h:420

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _indxInfo::dobj, _indexAttachInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, fmtQualifiedDumpable, _indxInfo::indextable, _dumpableObject::name, _indexAttachInfo::parentIdx, _indexAttachInfo::partitionIdx, _tableInfo::rolname, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

◆ dumpLO()

static void dumpLO ( Archive fout,
const LoInfo loinfo 
)
static

Definition at line 3850 of file pg_dump.c.

3851 {
3852  PQExpBuffer cquery = createPQExpBuffer();
3853 
3854  /*
3855  * The "definition" is just a newline-separated list of OIDs. We need to
3856  * put something into the dropStmt too, but it can just be a comment.
3857  */
3858  for (int i = 0; i < loinfo->numlos; i++)
3859  appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
3860 
3861  if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
3862  ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
3863  ARCHIVE_OPTS(.tag = loinfo->dobj.name,
3864  .owner = loinfo->rolname,
3865  .description = "BLOB METADATA",
3866  .section = SECTION_DATA,
3867  .createStmt = cquery->data,
3868  .dropStmt = "-- dummy"));
3869 
3870  /*
3871  * Dump per-blob comments and seclabels if any. We assume these are rare
3872  * enough that it's okay to generate retail TOC entries for them.
3873  */
3874  if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
3876  {
3877  for (int i = 0; i < loinfo->numlos; i++)
3878  {
3879  CatalogId catId;
3880  char namebuf[32];
3881 
3882  /* Build identifying info for this blob */
3883  catId.tableoid = loinfo->dobj.catId.tableoid;
3884  catId.oid = loinfo->looids[i];
3885  snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
3886 
3887  if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
3888  dumpComment(fout, "LARGE OBJECT", namebuf,
3889  NULL, loinfo->rolname,
3890  catId, 0, loinfo->dobj.dumpId);
3891 
3892  if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
3893  dumpSecLabel(fout, "LARGE OBJECT", namebuf,
3894  NULL, loinfo->rolname,
3895  catId, 0, loinfo->dobj.dumpId);
3896  }
3897  }
3898 
3899  /*
3900  * Dump the ACLs if any (remember that all blobs in the group will have
3901  * the same ACL). If there's just one blob, dump a simple ACL entry; if
3902  * there's more, make a "LARGE OBJECTS" entry that really contains only
3903  * the ACL for the first blob. _printTocEntry() will be cued by the tag
3904  * string to emit a mutated version for each blob.
3905  */
3906  if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
3907  {
3908  char namebuf[32];
3909 
3910  /* Build identifying info for the first blob */
3911  snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
3912 
3913  if (loinfo->numlos > 1)
3914  {
3915  char tagbuf[64];
3916 
3917  snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
3918  loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
3919 
3920  dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
3921  "LARGE OBJECT", namebuf, NULL, NULL,
3922  tagbuf, loinfo->rolname, &loinfo->dacl);
3923  }
3924  else
3925  {
3926  dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
3927  "LARGE OBJECT", namebuf, NULL, NULL,
3928  NULL, loinfo->rolname, &loinfo->dacl);
3929  }
3930  }
3931 
3932  destroyPQExpBuffer(cquery);
3933 }
DumpableObject dobj
Definition: pg_dump.h:595
DumpableAcl dacl
Definition: pg_dump.h:596
Oid looids[FLEXIBLE_ARRAY_MEMBER]
Definition: pg_dump.h:599

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), _loInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _loInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), i, InvalidDumpId, _loInfo::looids, _dumpableObject::name, _loInfo::numlos, CatalogId::oid, _loInfo::rolname, SECTION_DATA, snprintf, and CatalogId::tableoid.

Referenced by dumpDumpableObject().

◆ dumpLOs()

static int dumpLOs ( Archive fout,
const void *  arg 
)
static

Definition at line 3940 of file pg_dump.c.

3941 {
3942  const LoInfo *loinfo = (const LoInfo *) arg;
3943  PGconn *conn = GetConnection(fout);
3944  char buf[LOBBUFSIZE];
3945 
3946  pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
3947 
3948  for (int i = 0; i < loinfo->numlos; i++)
3949  {
3950  Oid loOid = loinfo->looids[i];
3951  int loFd;
3952  int cnt;
3953 
3954  /* Open the LO */
3955  loFd = lo_open(conn, loOid, INV_READ);
3956  if (loFd == -1)
3957  pg_fatal("could not open large object %u: %s",
3958  loOid, PQerrorMessage(conn));
3959 
3960  StartLO(fout, loOid);
3961 
3962  /* Now read it in chunks, sending data to archive */
3963  do
3964  {
3965  cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
3966  if (cnt < 0)
3967  pg_fatal("error reading large object %u: %s",
3968  loOid, PQerrorMessage(conn));
3969 
3970  WriteData(fout, buf, cnt);
3971  } while (cnt > 0);
3972 
3973  lo_close(conn, loFd);
3974 
3975  EndLO(fout, loOid);
3976  }
3977 
3978  return 1;
3979 }
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:154
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7200
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
#define INV_READ
Definition: libpq-fs.h:22
int EndLO(Archive *AHX, Oid oid)
int StartLO(Archive *AHX, Oid oid)
void WriteData(Archive *AHX, const void *data, size_t dLen)
#define LOBBUFSIZE
void * arg

References arg, buf, conn, _loInfo::dobj, EndLO(), GetConnection(), i, INV_READ, lo_close(), lo_open(), lo_read(), LOBBUFSIZE, _loInfo::looids, _dumpableObject::name, _loInfo::numlos, pg_fatal, pg_log_info, PQerrorMessage(), StartLO(), and WriteData().

Referenced by dumpDumpableObject().

◆ dumpNamespace()

static void dumpNamespace ( Archive fout,
const NamespaceInfo nspinfo 
)
static

Definition at line 10754 of file pg_dump.c.

10755 {
10756  DumpOptions *dopt = fout->dopt;
10757  PQExpBuffer q;
10758  PQExpBuffer delq;
10759  char *qnspname;
10760 
10761  /* Do nothing in data-only dump */
10762  if (dopt->dataOnly)
10763  return;
10764 
10765  q = createPQExpBuffer();
10766  delq = createPQExpBuffer();
10767 
10768  qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
10769 
10770  if (nspinfo->create)
10771  {
10772  appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
10773  appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
10774  }
10775  else
10776  {
10777  /* see selectDumpableNamespace() */
10778  appendPQExpBufferStr(delq,
10779  "-- *not* dropping schema, since initdb creates it\n");
10781  "-- *not* creating schema, since initdb creates it\n");
10782  }
10783 
10784  if (dopt->binary_upgrade)
10786  "SCHEMA", qnspname, NULL);
10787 
10788  if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10789  ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
10790  ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
10791  .owner = nspinfo->rolname,
10792  .description = "SCHEMA",
10793  .section = SECTION_PRE_DATA,
10794  .createStmt = q->data,
10795  .dropStmt = delq->data));
10796 
10797  /* Dump Schema Comments and Security Labels */
10798  if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10799  {
10800  const char *initdb_comment = NULL;
10801 
10802  if (!nspinfo->create && strcmp(qnspname, "public") == 0)
10803  initdb_comment = "standard public schema";
10804  dumpCommentExtended(fout, "SCHEMA", qnspname,
10805  NULL, nspinfo->rolname,
10806  nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
10807  initdb_comment);
10808  }
10809 
10810  if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10811  dumpSecLabel(fout, "SCHEMA", qnspname,
10812  NULL, nspinfo->rolname,
10813  nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10814 
10815  if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10816  dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
10817  qnspname, NULL, NULL,
10818  NULL, nspinfo->rolname, &nspinfo->dacl);
10819 
10820  free(qnspname);
10821 
10822  destroyPQExpBuffer(q);
10823  destroyPQExpBuffer(delq);
10824 }
DumpableObject dobj
Definition: pg_dump.h:172
DumpableAcl dacl
Definition: pg_dump.h:173
const char * rolname
Definition: pg_dump.h:176

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, _namespaceInfo::create, createPQExpBuffer(), _namespaceInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _namespaceInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpCommentExtended(), _dumpableObject::dumpId, dumpSecLabel(), fmtId(), free, InvalidDumpId, _dumpableObject::name, pg_strdup(), _namespaceInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpOpclass()

static void dumpOpclass ( Archive fout,
const OpclassInfo opcinfo 
)
static

Definition at line 13329 of file pg_dump.c.

13330 {
13331  DumpOptions *dopt = fout->dopt;
13332  PQExpBuffer query;
13333  PQExpBuffer q;
13334  PQExpBuffer delq;
13335  PQExpBuffer nameusing;
13336  PGresult *res;
13337  int ntups;
13338  int i_opcintype;
13339  int i_opckeytype;
13340  int i_opcdefault;
13341  int i_opcfamily;
13342  int i_opcfamilyname;
13343  int i_opcfamilynsp;
13344  int i_amname;
13345  int i_amopstrategy;
13346  int i_amopopr;
13347  int i_sortfamily;
13348  int i_sortfamilynsp;
13349  int i_amprocnum;
13350  int i_amproc;
13351  int i_amproclefttype;
13352  int i_amprocrighttype;
13353  char *opcintype;
13354  char *opckeytype;
13355  char *opcdefault;
13356  char *opcfamily;
13357  char *opcfamilyname;
13358  char *opcfamilynsp;
13359  char *amname;
13360  char *amopstrategy;
13361  char *amopopr;
13362  char *sortfamily;
13363  char *sortfamilynsp;
13364  char *amprocnum;
13365  char *amproc;
13366  char *amproclefttype;
13367  char *amprocrighttype;
13368  bool needComma;
13369  int i;
13370 
13371  /* Do nothing in data-only dump */
13372  if (dopt->dataOnly)
13373  return;
13374 
13375  query = createPQExpBuffer();
13376  q = createPQExpBuffer();
13377  delq = createPQExpBuffer();
13378  nameusing = createPQExpBuffer();
13379 
13380  /* Get additional fields from the pg_opclass row */
13381  appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
13382  "opckeytype::pg_catalog.regtype, "
13383  "opcdefault, opcfamily, "
13384  "opfname AS opcfamilyname, "
13385  "nspname AS opcfamilynsp, "
13386  "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
13387  "FROM pg_catalog.pg_opclass c "
13388  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
13389  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
13390  "WHERE c.oid = '%u'::pg_catalog.oid",
13391  opcinfo->dobj.catId.oid);
13392 
13393  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13394 
13395  i_opcintype = PQfnumber(res, "opcintype");
13396  i_opckeytype = PQfnumber(res, "opckeytype");
13397  i_opcdefault = PQfnumber(res, "opcdefault");
13398  i_opcfamily = PQfnumber(res, "opcfamily");
13399  i_opcfamilyname = PQfnumber(res, "opcfamilyname");
13400  i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
13401  i_amname = PQfnumber(res, "amname");
13402 
13403  /* opcintype may still be needed after we PQclear res */
13404  opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
13405  opckeytype = PQgetvalue(res, 0, i_opckeytype);
13406  opcdefault = PQgetvalue(res, 0, i_opcdefault);
13407  /* opcfamily will still be needed after we PQclear res */
13408  opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
13409  opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
13410  opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
13411  /* amname will still be needed after we PQclear res */
13412  amname = pg_strdup(PQgetvalue(res, 0, i_amname));
13413 
13414  appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
13415  fmtQualifiedDumpable(opcinfo));
13416  appendPQExpBuffer(delq, " USING %s;\n",
13417  fmtId(amname));
13418 
13419  /* Build the fixed portion of the CREATE command */
13420  appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n ",
13421  fmtQualifiedDumpable(opcinfo));
13422  if (strcmp(opcdefault, "t") == 0)
13423  appendPQExpBufferStr(q, "DEFAULT ");
13424  appendPQExpBuffer(q, "FOR TYPE %s USING %s",
13425  opcintype,
13426  fmtId(amname));
13427  if (strlen(opcfamilyname) > 0)
13428  {
13429  appendPQExpBufferStr(q, " FAMILY ");
13430  appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
13431  appendPQExpBufferStr(q, fmtId(opcfamilyname));
13432  }
13433  appendPQExpBufferStr(q, " AS\n ");
13434 
13435  needComma = false;
13436 
13437  if (strcmp(opckeytype, "-") != 0)
13438  {
13439  appendPQExpBuffer(q, "STORAGE %s",
13440  opckeytype);
13441  needComma = true;
13442  }
13443 
13444  PQclear(res);
13445 
13446  /*
13447  * Now fetch and print the OPERATOR entries (pg_amop rows).
13448  *
13449  * Print only those opfamily members that are tied to the opclass by
13450  * pg_depend entries.
13451  */
13452  resetPQExpBuffer(query);
13453  appendPQExpBuffer(query, "SELECT amopstrategy, "
13454  "amopopr::pg_catalog.regoperator, "
13455  "opfname AS sortfamily, "
13456  "nspname AS sortfamilynsp "
13457  "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
13458  "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
13459  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
13460  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
13461  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
13462  "AND refobjid = '%u'::pg_catalog.oid "
13463  "AND amopfamily = '%s'::pg_catalog.oid "
13464  "ORDER BY amopstrategy",
13465  opcinfo->dobj.catId.oid,
13466  opcfamily);
13467 
13468  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13469 
13470  ntups = PQntuples(res);
13471 
13472  i_amopstrategy = PQfnumber(res, "amopstrategy");
13473  i_amopopr = PQfnumber(res, "amopopr");
13474  i_sortfamily = PQfnumber(res, "sortfamily");
13475  i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
13476 
13477  for (i = 0; i < ntups; i++)
13478  {
13479  amopstrategy = PQgetvalue(res, i, i_amopstrategy);
13480  amopopr = PQgetvalue(res, i, i_amopopr);
13481  sortfamily = PQgetvalue(res, i, i_sortfamily);
13482  sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
13483 
13484  if (needComma)
13485  appendPQExpBufferStr(q, " ,\n ");
13486 
13487  appendPQExpBuffer(q, "OPERATOR %s %s",
13488  amopstrategy, amopopr);
13489 
13490  if (strlen(sortfamily) > 0)
13491  {
13492  appendPQExpBufferStr(q, " FOR ORDER BY ");
13493  appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
13494  appendPQExpBufferStr(q, fmtId(sortfamily));
13495  }
13496 
13497  needComma = true;
13498  }
13499 
13500  PQclear(res);
13501 
13502  /*
13503  * Now fetch and print the FUNCTION entries (pg_amproc rows).
13504  *
13505  * Print only those opfamily members that are tied to the opclass by
13506  * pg_depend entries.
13507  *
13508  * We print the amproclefttype/amprocrighttype even though in most cases
13509  * the backend could deduce the right values, because of the corner case
13510  * of a btree sort support function for a cross-type comparison.
13511  */
13512  resetPQExpBuffer(query);
13513 
13514  appendPQExpBuffer(query, "SELECT amprocnum, "
13515  "amproc::pg_catalog.regprocedure, "
13516  "amproclefttype::pg_catalog.regtype, "
13517  "amprocrighttype::pg_catalog.regtype "
13518  "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
13519  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
13520  "AND refobjid = '%u'::pg_catalog.oid "
13521  "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
13522  "AND objid = ap.oid "
13523  "ORDER BY amprocnum",
13524  opcinfo->dobj.catId.oid);
13525 
13526  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13527 
13528  ntups = PQntuples(res);
13529 
13530  i_amprocnum = PQfnumber(res, "amprocnum");
13531  i_amproc = PQfnumber(res, "amproc");
13532  i_amproclefttype = PQfnumber(res, "amproclefttype");
13533  i_amprocrighttype = PQfnumber(res, "amprocrighttype");
13534 
13535  for (i = 0; i < ntups; i++)
13536  {
13537  amprocnum = PQgetvalue(res, i, i_amprocnum);
13538  amproc = PQgetvalue(res, i, i_amproc);
13539  amproclefttype = PQgetvalue(res, i, i_amproclefttype);
13540  amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
13541 
13542  if (needComma)
13543  appendPQExpBufferStr(q, " ,\n ");
13544 
13545  appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
13546 
13547  if (*amproclefttype && *amprocrighttype)
13548  appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
13549 
13550  appendPQExpBuffer(q, " %s", amproc);
13551 
13552  needComma = true;
13553  }
13554 
13555  PQclear(res);
13556 
13557  /*
13558  * If needComma is still false it means we haven't added anything after
13559  * the AS keyword. To avoid printing broken SQL, append a dummy STORAGE
13560  * clause with the same datatype. This isn't sanctioned by the
13561  * documentation, but actually DefineOpClass will treat it as a no-op.
13562  */
13563  if (!needComma)
13564  appendPQExpBuffer(q, "STORAGE %s", opcintype);
13565 
13566  appendPQExpBufferStr(q, ";\n");
13567 
13568  appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
13569  appendPQExpBuffer(nameusing, " USING %s",
13570  fmtId(amname));
13571 
13572  if (dopt->binary_upgrade)
13574  "OPERATOR CLASS", nameusing->data,
13575  opcinfo->dobj.namespace->dobj.name);
13576 
13577  if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13578  ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
13579  ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
13580  .namespace = opcinfo->dobj.namespace->dobj.name,
13581  .owner = opcinfo->rolname,
13582  .description = "OPERATOR CLASS",
13583  .section = SECTION_PRE_DATA,
13584  .createStmt = q->data,
13585  .dropStmt = delq->data));
13586 
13587  /* Dump Operator Class Comments */
13588  if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13589  dumpComment(fout, "OPERATOR CLASS", nameusing->data,
13590  opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
13591  opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
13592 
13593  free(opcintype);
13594  free(opcfamily);
13595  free(amname);
13596  destroyPQExpBuffer(query);
13597  destroyPQExpBuffer(q);
13598  destroyPQExpBuffer(delq);
13599  destroyPQExpBuffer(nameusing);
13600 }
DumpableObject dobj
Definition: pg_dump.h:259
const char * rolname
Definition: pg_dump.h:260

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

Referenced by dumpDumpableObject().

◆ dumpOpfamily()

static void dumpOpfamily ( Archive fout,
const OpfamilyInfo opfinfo 
)
static

Definition at line 13610 of file pg_dump.c.

13611 {
13612  DumpOptions *dopt = fout->dopt;
13613  PQExpBuffer query;
13614  PQExpBuffer q;
13615  PQExpBuffer delq;
13616  PQExpBuffer nameusing;
13617  PGresult *res;
13618  PGresult *res_ops;
13619  PGresult *res_procs;
13620  int ntups;
13621  int i_amname;
13622  int i_amopstrategy;
13623  int i_amopopr;
13624  int i_sortfamily;
13625  int i_sortfamilynsp;
13626  int i_amprocnum;
13627  int i_amproc;
13628  int i_amproclefttype;
13629  int i_amprocrighttype;
13630  char *amname;
13631  char *amopstrategy;
13632  char *amopopr;
13633  char *sortfamily;
13634  char *sortfamilynsp;
13635  char *amprocnum;
13636  char *amproc;
13637  char *amproclefttype;
13638  char *amprocrighttype;
13639  bool needComma;
13640  int i;
13641 
13642  /* Do nothing in data-only dump */
13643  if (dopt->dataOnly)
13644  return;
13645 
13646  query = createPQExpBuffer();
13647  q = createPQExpBuffer();
13648  delq = createPQExpBuffer();
13649  nameusing = createPQExpBuffer();
13650 
13651  /*
13652  * Fetch only those opfamily members that are tied directly to the
13653  * opfamily by pg_depend entries.
13654  */
13655  appendPQExpBuffer(query, "SELECT amopstrategy, "
13656  "amopopr::pg_catalog.regoperator, "
13657  "opfname AS sortfamily, "
13658  "nspname AS sortfamilynsp "
13659  "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
13660  "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
13661  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
13662  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
13663  "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
13664  "AND refobjid = '%u'::pg_catalog.oid "
13665  "AND amopfamily = '%u'::pg_catalog.oid "
13666  "ORDER BY amopstrategy",
13667  opfinfo->dobj.catId.oid,
13668  opfinfo->dobj.catId.oid);
13669 
13670  res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13671 
13672  resetPQExpBuffer(query);
13673 
13674  appendPQExpBuffer(query, "SELECT amprocnum, "
13675  "amproc::pg_catalog.regprocedure, "
13676  "amproclefttype::pg_catalog.regtype, "
13677  "amprocrighttype::pg_catalog.regtype "
13678  "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
13679  "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
13680  "AND refobjid = '%u'::pg_catalog.oid "
13681  "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
13682  "AND objid = ap.oid "
13683  "ORDER BY amprocnum",
13684  opfinfo->dobj.catId.oid);
13685 
13686  res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13687 
13688  /* Get additional fields from the pg_opfamily row */
13689  resetPQExpBuffer(query);
13690 
13691  appendPQExpBuffer(query, "SELECT "
13692  "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
13693  "FROM pg_catalog.pg_opfamily "
13694  "WHERE oid = '%u'::pg_catalog.oid",
13695  opfinfo->dobj.catId.oid);
13696 
13697  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13698 
13699  i_amname = PQfnumber(res, "amname");
13700 
13701  /* amname will still be needed after we PQclear res */
13702  amname = pg_strdup(PQgetvalue(res, 0, i_amname));
13703 
13704  appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
13705  fmtQualifiedDumpable(opfinfo));
13706  appendPQExpBuffer(delq, " USING %s;\n",
13707  fmtId(amname));
13708 
13709  /* Build the fixed portion of the CREATE command */
13710  appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
13711  fmtQualifiedDumpable(opfinfo));
13712  appendPQExpBuffer(q, " USING %s;\n",
13713  fmtId(amname));
13714 
13715  PQclear(res);
13716 
13717  /* Do we need an ALTER to add loose members? */
13718  if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
13719  {
13720  appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
13721  fmtQualifiedDumpable(opfinfo));
13722  appendPQExpBuffer(q, " USING %s ADD\n ",
13723  fmtId(amname));
13724 
13725  needComma = false;
13726 
13727  /*
13728  * Now fetch and print the OPERATOR entries (pg_amop rows).
13729  */
13730  ntups = PQntuples(res_ops);
13731 
13732  i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
13733  i_amopopr = PQfnumber(res_ops, "amopopr");
13734  i_sortfamily = PQfnumber(res_ops, "sortfamily");
13735  i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
13736 
13737  for (i = 0; i < ntups; i++)
13738  {
13739  amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
13740  amopopr = PQgetvalue(res_ops, i, i_amopopr);
13741  sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
13742  sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
13743 
13744  if (needComma)
13745  appendPQExpBufferStr(q, " ,\n ");
13746 
13747  appendPQExpBuffer(q, "OPERATOR %s %s",
13748  amopstrategy, amopopr);
13749 
13750  if (strlen(sortfamily) > 0)
13751  {
13752  appendPQExpBufferStr(q, " FOR ORDER BY ");
13753  appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
13754  appendPQExpBufferStr(q, fmtId(sortfamily));
13755  }
13756 
13757  needComma = true;
13758  }
13759 
13760  /*
13761  * Now fetch and print the FUNCTION entries (pg_amproc rows).
13762  */
13763  ntups = PQntuples(res_procs);
13764 
13765  i_amprocnum = PQfnumber(res_procs, "amprocnum");
13766  i_amproc = PQfnumber(res_procs, "amproc");
13767  i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
13768  i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
13769 
13770  for (i = 0; i < ntups; i++)
13771  {
13772  amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
13773  amproc = PQgetvalue(res_procs, i, i_amproc);
13774  amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
13775  amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
13776 
13777  if (needComma)
13778  appendPQExpBufferStr(q, " ,\n ");
13779 
13780  appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
13781  amprocnum, amproclefttype, amprocrighttype,
13782  amproc);
13783 
13784  needComma = true;
13785  }
13786 
13787  appendPQExpBufferStr(q, ";\n");
13788  }
13789 
13790  appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
13791  appendPQExpBuffer(nameusing, " USING %s",
13792  fmtId(amname));
13793 
13794  if (dopt->binary_upgrade)
13796  "OPERATOR FAMILY", nameusing->data,
13797  opfinfo->dobj.namespace->dobj.name);
13798 
13799  if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13800  ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
13801  ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
13802  .namespace = opfinfo->dobj.namespace->dobj.name,
13803  .owner = opfinfo->rolname,
13804  .description = "OPERATOR FAMILY",
13805  .section = SECTION_PRE_DATA,
13806  .createStmt = q->data,
13807  .dropStmt = delq->data));
13808 
13809  /* Dump Operator Family Comments */
13810  if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13811  dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
13812  opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
13813  opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
13814 
13815  free(amname);
13816  PQclear(res_ops);
13817  PQclear(res_procs);
13818  destroyPQExpBuffer(query);
13819  destroyPQExpBuffer(q);
13820  destroyPQExpBuffer(delq);
13821  destroyPQExpBuffer(nameusing);
13822 }
const char * rolname
Definition: pg_dump.h:266
DumpableObject dobj
Definition: pg_dump.h:265

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

Referenced by dumpDumpableObject().

◆ dumpOpr()

static void dumpOpr ( Archive fout,
const OprInfo oprinfo 
)
static

Definition at line 12949 of file pg_dump.c.

12950 {
12951  DumpOptions *dopt = fout->dopt;
12952  PQExpBuffer query;
12953  PQExpBuffer q;
12954  PQExpBuffer delq;
12956  PQExpBuffer details;
12957  PGresult *res;
12958  int i_oprkind;
12959  int i_oprcode;
12960  int i_oprleft;
12961  int i_oprright;
12962  int i_oprcom;
12963  int i_oprnegate;
12964  int i_oprrest;
12965  int i_oprjoin;
12966  int i_oprcanmerge;
12967  int i_oprcanhash;
12968  char *oprkind;
12969  char *oprcode;
12970  char *oprleft;
12971  char *oprright;
12972  char *oprcom;
12973  char *oprnegate;
12974  char *oprrest;
12975  char *oprjoin;
12976  char *oprcanmerge;
12977  char *oprcanhash;
12978  char *oprregproc;
12979  char *oprref;
12980 
12981  /* Do nothing in data-only dump */
12982  if (dopt->dataOnly)
12983  return;
12984 
12985  /*
12986  * some operators are invalid because they were the result of user
12987  * defining operators before commutators exist
12988  */
12989  if (!OidIsValid(oprinfo->oprcode))
12990  return;
12991 
12992  query = createPQExpBuffer();
12993  q = createPQExpBuffer();
12994  delq = createPQExpBuffer();
12996  details = createPQExpBuffer();
12997 
12998  if (!fout->is_prepared[PREPQUERY_DUMPOPR])
12999  {
13000  /* Set up query for operator-specific details */
13001  appendPQExpBufferStr(query,
13002  "PREPARE dumpOpr(pg_catalog.oid) AS\n"
13003  "SELECT oprkind, "
13004  "oprcode::pg_catalog.regprocedure, "
13005  "oprleft::pg_catalog.regtype, "
13006  "oprright::pg_catalog.regtype, "
13007  "oprcom, "
13008  "oprnegate, "
13009  "oprrest::pg_catalog.regprocedure, "
13010  "oprjoin::pg_catalog.regprocedure, "
13011  "oprcanmerge, oprcanhash "
13012  "FROM pg_catalog.pg_operator "
13013  "WHERE oid = $1");
13014 
13015  ExecuteSqlStatement(fout, query->data);
13016 
13017  fout->is_prepared[PREPQUERY_DUMPOPR] = true;
13018  }
13019 
13020  printfPQExpBuffer(query,
13021  "EXECUTE dumpOpr('%u')",
13022  oprinfo->dobj.catId.oid);
13023 
13024  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13025 
13026  i_oprkind = PQfnumber(res, "oprkind");
13027  i_oprcode = PQfnumber(res, "oprcode");
13028  i_oprleft = PQfnumber(res, "oprleft");
13029  i_oprright = PQfnumber(res, "oprright");
13030  i_oprcom = PQfnumber(res, "oprcom");
13031  i_oprnegate = PQfnumber(res, "oprnegate");
13032  i_oprrest = PQfnumber(res, "oprrest");
13033  i_oprjoin = PQfnumber(res, "oprjoin");
13034  i_oprcanmerge = PQfnumber(res, "oprcanmerge");
13035  i_oprcanhash = PQfnumber(res, "oprcanhash");
13036 
13037  oprkind = PQgetvalue(res, 0, i_oprkind);
13038  oprcode = PQgetvalue(res, 0, i_oprcode);
13039  oprleft = PQgetvalue(res, 0, i_oprleft);
13040  oprright = PQgetvalue(res, 0, i_oprright);
13041  oprcom = PQgetvalue(res, 0, i_oprcom);
13042  oprnegate = PQgetvalue(res, 0, i_oprnegate);
13043  oprrest = PQgetvalue(res, 0, i_oprrest);
13044  oprjoin = PQgetvalue(res, 0, i_oprjoin);
13045  oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
13046  oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
13047 
13048  /* In PG14 upwards postfix operator support does not exist anymore. */
13049  if (strcmp(oprkind, "r") == 0)
13050  pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
13051  oprcode);
13052 
13053  oprregproc = convertRegProcReference(oprcode);
13054  if (oprregproc)
13055  {
13056  appendPQExpBuffer(details, " FUNCTION = %s", oprregproc);
13057  free(oprregproc);
13058  }
13059 
13060  appendPQExpBuffer(oprid, "%s (",
13061  oprinfo->dobj.name);
13062 
13063  /*
13064  * right unary means there's a left arg and left unary means there's a
13065  * right arg. (Although the "r" case is dead code for PG14 and later,
13066  * continue to support it in case we're dumping from an old server.)
13067  */
13068  if (strcmp(oprkind, "r") == 0 ||
13069  strcmp(oprkind, "b") == 0)
13070  {
13071  appendPQExpBuffer(details, ",\n LEFTARG = %s", oprleft);
13072  appendPQExpBufferStr(oprid, oprleft);
13073  }
13074  else
13075  appendPQExpBufferStr(oprid, "NONE");
13076 
13077  if (strcmp(oprkind, "l") == 0 ||
13078  strcmp(oprkind, "b") == 0)
13079  {
13080  appendPQExpBuffer(details, ",\n RIGHTARG = %s", oprright);
13081  appendPQExpBuffer(oprid, ", %s)", oprright);
13082  }
13083  else
13084  appendPQExpBufferStr(oprid, ", NONE)");
13085 
13086  oprref = getFormattedOperatorName(oprcom);
13087  if (oprref)
13088  {
13089  appendPQExpBuffer(details, ",\n COMMUTATOR = %s", oprref);
13090  free(oprref);
13091  }
13092 
13093  oprref = getFormattedOperatorName(oprnegate);
13094  if (oprref)
13095  {
13096  appendPQExpBuffer(details, ",\n NEGATOR = %s", oprref);
13097  free(oprref);
13098  }
13099 
13100  if (strcmp(oprcanmerge, "t") == 0)
13101  appendPQExpBufferStr(details, ",\n MERGES");
13102 
13103  if (strcmp(oprcanhash, "t") == 0)
13104  appendPQExpBufferStr(details, ",\n HASHES");
13105 
13106  oprregproc = convertRegProcReference(oprrest);
13107  if (oprregproc)
13108  {
13109  appendPQExpBuffer(details, ",\n RESTRICT = %s", oprregproc);
13110  free(oprregproc);
13111  }
13112 
13113  oprregproc = convertRegProcReference(oprjoin);
13114  if (oprregproc)
13115  {
13116  appendPQExpBuffer(details, ",\n JOIN = %s", oprregproc);
13117  free(oprregproc);
13118  }
13119 
13120  appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
13121  fmtId(oprinfo->dobj.namespace->dobj.name),
13122  oprid->data);
13123 
13124  appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
13125  fmtId(oprinfo->dobj.namespace->dobj.name),
13126  oprinfo->dobj.name, details->data);
13127 
13128  if (dopt->binary_upgrade)
13130  "OPERATOR", oprid->data,
13131  oprinfo->dobj.namespace->dobj.name);
13132 
13133  if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13134  ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
13135  ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
13136  .namespace = oprinfo->dobj.namespace->dobj.name,
13137  .owner = oprinfo->rolname,
13138  .description = "OPERATOR",
13139  .section = SECTION_PRE_DATA,
13140  .createStmt = q->data,
13141  .dropStmt = delq->data));
13142 
13143  /* Dump Operator Comments */
13144  if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13145  dumpComment(fout, "OPERATOR", oprid->data,
13146  oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
13147  oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
13148 
13149  PQclear(res);
13150 
13151  destroyPQExpBuffer(query);
13152  destroyPQExpBuffer(q);
13153  destroyPQExpBuffer(delq);
13155  destroyPQExpBuffer(details);
13156 }
Oid oprid(Operator op)
Definition: parse_oper.c:238
@ PREPQUERY_DUMPOPR
Definition: pg_backup.h:72
static char * convertRegProcReference(const char *proc)
Definition: pg_dump.c:13168
DumpableObject dobj
Definition: pg_dump.h:244
Oid oprcode
Definition: pg_dump.h:247
const char * rolname
Definition: pg_dump.h:245

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertRegProcReference(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _oprInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), fmtId(), free, getFormattedOperatorName(), Archive::is_prepared, _dumpableObject::name, CatalogId::oid, OidIsValid, _oprInfo::oprcode, oprid(), pg_log_warning, PQclear(), PQfnumber(), PQgetvalue(), PREPQUERY_DUMPOPR, printfPQExpBuffer(), res, _oprInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpPolicy()

static void dumpPolicy ( Archive fout,
const PolicyInfo polinfo 
)
static

Definition at line 4153 of file pg_dump.c.

4154 {
4155  DumpOptions *dopt = fout->dopt;
4156  TableInfo *tbinfo = polinfo->poltable;
4157  PQExpBuffer query;
4158  PQExpBuffer delqry;
4159  PQExpBuffer polprefix;
4160  char *qtabname;
4161  const char *cmd;
4162  char *tag;
4163 
4164  /* Do nothing in data-only dump */
4165  if (dopt->dataOnly)
4166  return;
4167 
4168  /*
4169  * If polname is NULL, then this record is just indicating that ROW LEVEL
4170  * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
4171  * ROW LEVEL SECURITY.
4172  */
4173  if (polinfo->polname == NULL)
4174  {
4175  query = createPQExpBuffer();
4176 
4177  appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
4178  fmtQualifiedDumpable(tbinfo));
4179 
4180  /*
4181  * We must emit the ROW SECURITY object's dependency on its table
4182  * explicitly, because it will not match anything in pg_depend (unlike
4183  * the case for other PolicyInfo objects).
4184  */
4185  if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4186  ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4187  ARCHIVE_OPTS(.tag = polinfo->dobj.name,
4188  .namespace = polinfo->dobj.namespace->dobj.name,
4189  .owner = tbinfo->rolname,
4190  .description = "ROW SECURITY",
4191  .section = SECTION_POST_DATA,
4192  .createStmt = query->data,
4193  .deps = &(tbinfo->dobj.dumpId),
4194  .nDeps = 1));
4195 
4196  destroyPQExpBuffer(query);
4197  return;
4198  }
4199 
4200  if (polinfo->polcmd == '*')
4201  cmd = "";
4202  else if (polinfo->polcmd == 'r')
4203  cmd = " FOR SELECT";
4204  else if (polinfo->polcmd == 'a')
4205  cmd = " FOR INSERT";
4206  else if (polinfo->polcmd == 'w')
4207  cmd = " FOR UPDATE";
4208  else if (polinfo->polcmd == 'd')
4209  cmd = " FOR DELETE";
4210  else
4211  pg_fatal("unexpected policy command type: %c",
4212  polinfo->polcmd);
4213 
4214  query = createPQExpBuffer();
4215  delqry = createPQExpBuffer();
4216  polprefix = createPQExpBuffer();
4217 
4218  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
4219 
4220  appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
4221 
4222  appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
4223  !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
4224 
4225  if (polinfo->polroles != NULL)
4226  appendPQExpBuffer(query, " TO %s", polinfo->polroles);
4227 
4228  if (polinfo->polqual != NULL)
4229  appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
4230 
4231  if (polinfo->polwithcheck != NULL)
4232  appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
4233 
4234  appendPQExpBufferStr(query, ";\n");
4235 
4236  appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
4237  appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
4238 
4239  appendPQExpBuffer(polprefix, "POLICY %s ON",
4240  fmtId(polinfo->polname));
4241 
4242  tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
4243 
4244  if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4245  ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4246  ARCHIVE_OPTS(.tag = tag,
4247  .namespace = polinfo->dobj.namespace->dobj.name,
4248  .owner = tbinfo->rolname,
4249  .description = "POLICY",
4250  .section = SECTION_POST_DATA,
4251  .createStmt = query->data,
4252  .dropStmt = delqry->data));
4253 
4254  if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4255  dumpComment(fout, polprefix->data, qtabname,
4256  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
4257  polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
4258 
4259  free(tag);
4260  destroyPQExpBuffer(query);
4261  destroyPQExpBuffer(delqry);
4262  destroyPQExpBuffer(polprefix);
4263  free(qtabname);
4264 }
TableInfo * poltable
Definition: pg_dump.h:611
char * polqual
Definition: pg_dump.h:616
char polcmd
Definition: pg_dump.h:613
char * polroles
Definition: pg_dump.h:615
char * polwithcheck
Definition: pg_dump.h:617
DumpableObject dobj
Definition: pg_dump.h:610
bool polpermissive
Definition: pg_dump.h:614
char * polname
Definition: pg_dump.h:612

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _policyInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, pg_fatal, pg_strdup(), _policyInfo::polcmd, _policyInfo::polname, _policyInfo::polpermissive, _policyInfo::polqual, _policyInfo::polroles, _policyInfo::poltable, _policyInfo::polwithcheck, psprintf(), _tableInfo::rolname, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

◆ dumpProcLang()

static void dumpProcLang ( Archive fout,
const ProcLangInfo plang 
)
static

Definition at line 12115 of file pg_dump.c.

12116 {
12117  DumpOptions *dopt = fout->dopt;
12118  PQExpBuffer defqry;
12119  PQExpBuffer delqry;
12120  bool useParams;
12121  char *qlanname;
12122  FuncInfo *funcInfo;
12123  FuncInfo *inlineInfo = NULL;
12124  FuncInfo *validatorInfo = NULL;
12125 
12126  /* Do nothing in data-only dump */
12127  if (dopt->dataOnly)
12128  return;
12129 
12130  /*
12131  * Try to find the support function(s). It is not an error if we don't
12132  * find them --- if the functions are in the pg_catalog schema, as is
12133  * standard in 8.1 and up, then we won't have loaded them. (In this case
12134  * we will emit a parameterless CREATE LANGUAGE command, which will
12135  * require PL template knowledge in the backend to reload.)
12136  */
12137 
12138  funcInfo = findFuncByOid(plang->lanplcallfoid);
12139  if (funcInfo != NULL && !funcInfo->dobj.dump)
12140  funcInfo = NULL; /* treat not-dumped same as not-found */
12141 
12142  if (OidIsValid(plang->laninline))
12143  {
12144  inlineInfo = findFuncByOid(plang->laninline);
12145  if (inlineInfo != NULL && !inlineInfo->dobj.dump)
12146  inlineInfo = NULL;
12147  }
12148 
12149  if (OidIsValid(plang->lanvalidator))
12150  {
12151  validatorInfo = findFuncByOid(plang->lanvalidator);
12152  if (validatorInfo != NULL && !validatorInfo->dobj.dump)
12153  validatorInfo = NULL;
12154  }
12155 
12156  /*
12157  * If the functions are dumpable then emit a complete CREATE LANGUAGE with
12158  * parameters. Otherwise, we'll write a parameterless command, which will
12159  * be interpreted as CREATE EXTENSION.
12160  */
12161  useParams = (funcInfo != NULL &&
12162  (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
12163  (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
12164 
12165  defqry = createPQExpBuffer();
12166  delqry = createPQExpBuffer();
12167 
12168  qlanname = pg_strdup(fmtId(plang->dobj.name));
12169 
12170  appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
12171  qlanname);
12172 
12173  if (useParams)
12174  {
12175  appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
12176  plang->lanpltrusted ? "TRUSTED " : "",
12177  qlanname);
12178  appendPQExpBuffer(defqry, " HANDLER %s",
12179  fmtQualifiedDumpable(funcInfo));
12180  if (OidIsValid(plang->laninline))
12181  appendPQExpBuffer(defqry, " INLINE %s",
12182  fmtQualifiedDumpable(inlineInfo));
12183  if (OidIsValid(plang->lanvalidator))
12184  appendPQExpBuffer(defqry, " VALIDATOR %s",
12185  fmtQualifiedDumpable(validatorInfo));
12186  }
12187  else
12188  {
12189  /*
12190  * If not dumping parameters, then use CREATE OR REPLACE so that the
12191  * command will not fail if the language is preinstalled in the target
12192  * database.
12193  *
12194  * Modern servers will interpret this as CREATE EXTENSION IF NOT
12195  * EXISTS; perhaps we should emit that instead? But it might just add
12196  * confusion.
12197  */
12198  appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
12199  qlanname);
12200  }
12201  appendPQExpBufferStr(defqry, ";\n");
12202 
12203  if (dopt->binary_upgrade)
12204  binary_upgrade_extension_member(defqry, &plang->dobj,
12205  "LANGUAGE", qlanname, NULL);
12206 
12207  if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
12208  ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
12209  ARCHIVE_OPTS(.tag = plang->dobj.name,
12210  .owner = plang->lanowner,
12211  .description = "PROCEDURAL LANGUAGE",
12212  .section = SECTION_PRE_DATA,
12213  .createStmt = defqry->data,
12214  .dropStmt = delqry->data,
12215  ));
12216 
12217  /* Dump Proc Lang Comments and Security Labels */
12218  if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
12219  dumpComment(fout, "LANGUAGE", qlanname,
12220  NULL, plang->lanowner,
12221  plang->dobj.catId, 0, plang->dobj.dumpId);
12222 
12223  if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
12224  dumpSecLabel(fout, "LANGUAGE", qlanname,
12225  NULL, plang->lanowner,
12226  plang->dobj.catId, 0, plang->dobj.dumpId);
12227 
12228  if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
12229  dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
12230  qlanname, NULL, NULL,
12231  NULL, plang->lanowner, &plang->dacl);
12232 
12233  free(qlanname);
12234 
12235  destroyPQExpBuffer(defqry);
12236  destroyPQExpBuffer(delqry);
12237 }
Oid lanvalidator
Definition: pg_dump.h:494
DumpableAcl dacl
Definition: pg_dump.h:490
DumpableObject dobj
Definition: pg_dump.h:489
Oid laninline
Definition: pg_dump.h:493
const char * lanowner
Definition: pg_dump.h:495
Oid lanplcallfoid
Definition: pg_dump.h:492
bool lanpltrusted
Definition: pg_dump.h:491

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _procLangInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _funcInfo::dobj, _procLangInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), findFuncByOid(), fmtId(), fmtQualifiedDumpable, free, InvalidDumpId, _procLangInfo::laninline, _procLangInfo::lanowner, _procLangInfo::lanplcallfoid, _procLangInfo::lanpltrusted, _procLangInfo::lanvalidator, _dumpableObject::name, OidIsValid, pg_strdup(), and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpPublication()

static void dumpPublication ( Archive fout,
const PublicationInfo pubinfo 
)
static

Definition at line 4378 of file pg_dump.c.

4379 {
4380  DumpOptions *dopt = fout->dopt;
4381  PQExpBuffer delq;
4382  PQExpBuffer query;
4383  char *qpubname;
4384  bool first = true;
4385 
4386  /* Do nothing in data-only dump */
4387  if (dopt->dataOnly)
4388  return;
4389 
4390  delq = createPQExpBuffer();
4391  query = createPQExpBuffer();
4392 
4393  qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
4394 
4395  appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
4396  qpubname);
4397 
4398  appendPQExpBuffer(query, "CREATE PUBLICATION %s",
4399  qpubname);
4400 
4401  if (pubinfo->puballtables)
4402  appendPQExpBufferStr(query, " FOR ALL TABLES");
4403 
4404  appendPQExpBufferStr(query, " WITH (publish = '");
4405  if (pubinfo->pubinsert)
4406  {
4407  appendPQExpBufferStr(query, "insert");
4408  first = false;
4409  }
4410 
4411  if (pubinfo->pubupdate)
4412  {
4413  if (!first)
4414  appendPQExpBufferStr(query, ", ");
4415 
4416  appendPQExpBufferStr(query, "update");
4417  first = false;
4418  }
4419 
4420  if (pubinfo->pubdelete)
4421  {
4422  if (!first)
4423  appendPQExpBufferStr(query, ", ");
4424 
4425  appendPQExpBufferStr(query, "delete");
4426  first = false;
4427  }
4428 
4429  if (pubinfo->pubtruncate)
4430  {
4431  if (!first)
4432  appendPQExpBufferStr(query, ", ");
4433 
4434  appendPQExpBufferStr(query, "truncate");
4435  first = false;
4436  }
4437 
4438  appendPQExpBufferChar(query, '\'');
4439 
4440  if (pubinfo->pubviaroot)
4441  appendPQExpBufferStr(query, ", publish_via_partition_root = true");
4442 
4443  if (pubinfo->pubgencols)
4444  appendPQExpBufferStr(query, ", publish_generated_columns = true");
4445 
4446  appendPQExpBufferStr(query, ");\n");
4447 
4448  if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4449  ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
4450  ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
4451  .owner = pubinfo->rolname,
4452  .description = "PUBLICATION",
4453  .section = SECTION_POST_DATA,
4454  .createStmt = query->data,
4455  .dropStmt = delq->data));
4456 
4457  if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4458  dumpComment(fout, "PUBLICATION", qpubname,
4459  NULL, pubinfo->rolname,
4460  pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4461 
4462  if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4463  dumpSecLabel(fout, "PUBLICATION", qpubname,
4464  NULL, pubinfo->rolname,
4465  pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4466 
4467  destroyPQExpBuffer(delq);
4468  destroyPQExpBuffer(query);
4469  free(qpubname);
4470 }
const char * rolname
Definition: pg_dump.h:626
bool puballtables
Definition: pg_dump.h:627
bool pubtruncate
Definition: pg_dump.h:631
DumpableObject dobj
Definition: pg_dump.h:625

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _PublicationInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), fmtId(), free, _dumpableObject::name, pg_strdup(), _PublicationInfo::puballtables, _PublicationInfo::pubdelete, _PublicationInfo::pubgencols, _PublicationInfo::pubinsert, _PublicationInfo::pubtruncate, _PublicationInfo::pubupdate, _PublicationInfo::pubviaroot, _PublicationInfo::rolname, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

◆ dumpPublicationNamespace()

static void dumpPublicationNamespace ( Archive fout,
const PublicationSchemaInfo pubsinfo 
)
static

Definition at line 4696 of file pg_dump.c.

4697 {
4698  DumpOptions *dopt = fout->dopt;
4699  NamespaceInfo *schemainfo = pubsinfo->pubschema;
4700  PublicationInfo *pubinfo = pubsinfo->publication;
4701  PQExpBuffer query;
4702  char *tag;
4703 
4704  /* Do nothing in data-only dump */
4705  if (dopt->dataOnly)
4706  return;
4707 
4708  tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
4709 
4710  query = createPQExpBuffer();
4711 
4712  appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
4713  appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
4714 
4715  /*
4716  * There is no point in creating drop query as the drop is done by schema
4717  * drop.
4718  */
4719  if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4720  ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
4721  ARCHIVE_OPTS(.tag = tag,
4722  .namespace = schemainfo->dobj.name,
4723  .owner = pubinfo->rolname,
4724  .description = "PUBLICATION TABLES IN SCHEMA",
4725  .section = SECTION_POST_DATA,
4726  .createStmt = query->data));
4727 
4728  /* These objects can't currently have comments or seclabels */
4729 
4730  free(tag);
4731  destroyPQExpBuffer(query);
4732 }
NamespaceInfo * pubschema
Definition: pg_dump.h:657
DumpableObject dobj
Definition: pg_dump.h:655
PublicationInfo * publication
Definition: pg_dump.h:656

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _namespaceInfo::dobj, _PublicationInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, fmtId(), free, _dumpableObject::name, psprintf(), _PublicationSchemaInfo::publication, _PublicationSchemaInfo::pubschema, _PublicationInfo::rolname, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

◆ dumpPublicationTable()

static void dumpPublicationTable ( Archive fout,
const PublicationRelInfo pubrinfo 
)
static

Definition at line 4739 of file pg_dump.c.

4740 {
4741  DumpOptions *dopt = fout->dopt;
4742  PublicationInfo *pubinfo = pubrinfo->publication;
4743  TableInfo *tbinfo = pubrinfo->pubtable;
4744  PQExpBuffer query;
4745  char *tag;
4746 
4747  /* Do nothing in data-only dump */
4748  if (dopt->dataOnly)
4749  return;
4750 
4751  tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
4752 
4753  query = createPQExpBuffer();
4754 
4755  appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
4756  fmtId(pubinfo->dobj.name));
4757  appendPQExpBuffer(query, " %s",
4758  fmtQualifiedDumpable(tbinfo));
4759 
4760  if (pubrinfo->pubrattrs)
4761  appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
4762 
4763  if (pubrinfo->pubrelqual)
4764  {
4765  /*
4766  * It's necessary to add parentheses around the expression because
4767  * pg_get_expr won't supply the parentheses for things like WHERE
4768  * TRUE.
4769  */
4770  appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
4771  }
4772  appendPQExpBufferStr(query, ";\n");
4773 
4774  /*
4775  * There is no point in creating a drop query as the drop is done by table
4776  * drop. (If you think to change this, see also _printTocEntry().)
4777  * Although this object doesn't really have ownership as such, set the
4778  * owner field anyway to ensure that the command is run by the correct
4779  * role at restore time.
4780  */
4781  if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4782  ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
4783  ARCHIVE_OPTS(.tag = tag,
4784  .namespace = tbinfo->dobj.namespace->dobj.name,
4785  .owner = pubinfo->rolname,
4786  .description = "PUBLICATION TABLE",
4787  .section = SECTION_POST_DATA,
4788  .createStmt = query->data));
4789 
4790  /* These objects can't currently have comments or seclabels */
4791 
4792  free(tag);
4793  destroyPQExpBuffer(query);
4794 }

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _PublicationInfo::dobj, Archive::dopt, DUMP_COMPONENT_DEFINITION, fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, psprintf(), _PublicationInfo::rolname, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

◆ dumpRangeType()

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

Definition at line 11130 of file pg_dump.c.

11131 {
11132  DumpOptions *dopt = fout->dopt;
11134  PQExpBuffer delq = createPQExpBuffer();
11135  PQExpBuffer query = createPQExpBuffer();
11136  PGresult *res;
11137  Oid collationOid;
11138  char *qtypname;
11139  char *qualtypname;
11140  char *procname;
11141 
11143  {
11144  /* Set up query for range-specific details */
11145  appendPQExpBufferStr(query,
11146  "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
11147 
11148  appendPQExpBufferStr(query,
11149  "SELECT ");
11150 
11151  if (fout->remoteVersion >= 140000)
11152  appendPQExpBufferStr(query,
11153  "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
11154  else
11155  appendPQExpBufferStr(query,
11156  "NULL AS rngmultitype, ");
11157 
11158  appendPQExpBufferStr(query,
11159  "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
11160  "opc.opcname AS opcname, "
11161  "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
11162  " WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
11163  "opc.opcdefault, "
11164  "CASE WHEN rngcollation = st.typcollation THEN 0 "
11165  " ELSE rngcollation END AS collation, "
11166  "rngcanonical, rngsubdiff "
11167  "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
11168  " pg_catalog.pg_opclass opc "
11169  "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
11170  "rngtypid = $1");
11171 
11172  ExecuteSqlStatement(fout, query->data);
11173 
11174  fout->is_prepared[PREPQUERY_DUMPRANGETYPE] = true;
11175  }
11176 
11177  printfPQExpBuffer(query,
11178  "EXECUTE dumpRangeType('%u')",
11179  tyinfo->dobj.catId.oid);
11180 
11181  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11182 
11183  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11184  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11185 
11186  /*
11187  * CASCADE shouldn't be required here as for normal types since the I/O
11188  * functions are generic and do not get dropped.
11189  */
11190  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11191 
11192  if (dopt->binary_upgrade)
11194  tyinfo->dobj.catId.oid,
11195  false, true);
11196 
11197  appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
11198  qualtypname);
11199 
11200  appendPQExpBuffer(q, "\n subtype = %s",
11201  PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
11202 
11203  if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
11204  appendPQExpBuffer(q, ",\n multirange_type_name = %s",
11205  PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
11206 
11207  /* print subtype_opclass only if not default for subtype */
11208  if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
11209  {
11210  char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
11211  char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
11212 
11213  appendPQExpBuffer(q, ",\n subtype_opclass = %s.",
11214  fmtId(nspname));
11215  appendPQExpBufferStr(q, fmtId(opcname));
11216  }
11217 
11218  collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
11219  if (OidIsValid(collationOid))
11220  {
11221  CollInfo *coll = findCollationByOid(collationOid);
11222 
11223  if (coll)
11224  appendPQExpBuffer(q, ",\n collation = %s",
11225  fmtQualifiedDumpable(coll));
11226  }
11227 
11228  procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
11229  if (strcmp(procname, "-") != 0)
11230  appendPQExpBuffer(q, ",\n canonical = %s", procname);
11231 
11232  procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
11233  if (strcmp(procname, "-") != 0)
11234  appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
11235 
11236  appendPQExpBufferStr(q, "\n);\n");
11237 
11238  if (dopt->binary_upgrade)
11240  "TYPE", qtypname,
11241  tyinfo->dobj.namespace->dobj.name);
11242 
11243  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11244  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11245  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11246  .namespace = tyinfo->dobj.namespace->dobj.name,
11247  .owner = tyinfo->rolname,
11248  .description = "TYPE",
11249  .section = SECTION_PRE_DATA,
11250  .createStmt = q->data,
11251  .dropStmt = delq->data));
11252 
11253  /* Dump Type Comments and Security Labels */
11254  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11255  dumpComment(fout, "TYPE", qtypname,
11256  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11257  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11258 
11259  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11260  dumpSecLabel(fout, "TYPE", qtypname,
11261  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11262  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11263 
11264  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11265  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11266  qtypname, NULL,
11267  tyinfo->dobj.namespace->dobj.name,
11268  NULL, tyinfo->rolname, &tyinfo->dacl);
11269 
11270  PQclear(res);
11271  destroyPQExpBuffer(q);
11272  destroyPQExpBuffer(delq);
11273  destroyPQExpBuffer(query);
11274  free(qtypname);
11275  free(qualtypname);
11276 }
@ PREPQUERY_DUMPRANGETYPE
Definition: pg_backup.h:73

References appendPQExpBuffer(), appendPQExpBufferStr(), 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(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, free, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PREPQUERY_DUMPRANGETYPE, printfPQExpBuffer(), Archive::remoteVersion, res, _typeInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpType().

◆ dumpRule()

static void dumpRule ( Archive fout,
const RuleInfo rinfo 
)
static

Definition at line 18252 of file pg_dump.c.

18253 {
18254  DumpOptions *dopt = fout->dopt;
18255  TableInfo *tbinfo = rinfo->ruletable;
18256  bool is_view;
18257  PQExpBuffer query;
18258  PQExpBuffer cmd;
18259  PQExpBuffer delcmd;
18260  PQExpBuffer ruleprefix;
18261  char *qtabname;
18262  PGresult *res;
18263  char *tag;
18264 
18265  /* Do nothing in data-only dump */
18266  if (dopt->dataOnly)
18267  return;
18268 
18269  /*
18270  * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
18271  * we do not want to dump it as a separate object.
18272  */
18273  if (!rinfo->separate)
18274  return;
18275 
18276  /*
18277  * If it's an ON SELECT rule, we want to print it as a view definition,
18278  * instead of a rule.
18279  */
18280  is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
18281 
18282  query = createPQExpBuffer();
18283  cmd = createPQExpBuffer();
18284  delcmd = createPQExpBuffer();
18285  ruleprefix = createPQExpBuffer();
18286 
18287  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18288 
18289  if (is_view)
18290  {
18291  PQExpBuffer result;
18292 
18293  /*
18294  * We need OR REPLACE here because we'll be replacing a dummy view.
18295  * Otherwise this should look largely like the regular view dump code.
18296  */
18297  appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
18298  fmtQualifiedDumpable(tbinfo));
18299  if (nonemptyReloptions(tbinfo->reloptions))
18300  {
18301  appendPQExpBufferStr(cmd, " WITH (");
18302  appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
18303  appendPQExpBufferChar(cmd, ')');
18304  }
18305  result = createViewAsClause(fout, tbinfo);
18306  appendPQExpBuffer(cmd, " AS\n%s", result->data);
18307  destroyPQExpBuffer(result);
18308  if (tbinfo->checkoption != NULL)
18309  appendPQExpBuffer(cmd, "\n WITH %s CHECK OPTION",
18310  tbinfo->checkoption);
18311  appendPQExpBufferStr(cmd, ";\n");
18312  }
18313  else
18314  {
18315  /* In the rule case, just print pg_get_ruledef's result verbatim */
18316  appendPQExpBuffer(query,
18317  "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
18318  rinfo->dobj.catId.oid);
18319 
18320  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18321 
18322  if (PQntuples(res) != 1)
18323  pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
18324  rinfo->dobj.name, tbinfo->dobj.name);
18325 
18326  printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
18327 
18328  PQclear(res);
18329  }
18330 
18331  /*
18332  * Add the command to alter the rules replication firing semantics if it
18333  * differs from the default.
18334  */
18335  if (rinfo->ev_enabled != 'O')
18336  {
18337  appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
18338  switch (rinfo->ev_enabled)
18339  {
18340  case 'A':
18341  appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
18342  fmtId(rinfo->dobj.name));
18343  break;
18344  case 'R':
18345  appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
18346  fmtId(rinfo->dobj.name));
18347  break;
18348  case 'D':
18349  appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
18350  fmtId(rinfo->dobj.name));
18351  break;
18352  }
18353  }
18354 
18355  if (is_view)
18356  {
18357  /*
18358  * We can't DROP a view's ON SELECT rule. Instead, use CREATE OR
18359  * REPLACE VIEW to replace the rule with something with minimal
18360  * dependencies.
18361  */
18362  PQExpBuffer result;
18363 
18364  appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
18365  fmtQualifiedDumpable(tbinfo));
18366  result = createDummyViewAsClause(fout, tbinfo);
18367  appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
18368  destroyPQExpBuffer(result);
18369  }
18370  else
18371  {
18372  appendPQExpBuffer(delcmd, "DROP RULE %s ",
18373  fmtId(rinfo->dobj.name));
18374  appendPQExpBuffer(delcmd, "ON %s;\n",
18375  fmtQualifiedDumpable(tbinfo));
18376  }
18377 
18378  appendPQExpBuffer(ruleprefix, "RULE %s ON",
18379  fmtId(rinfo->dobj.name));
18380 
18381  tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
18382 
18383  if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18384  ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
18385  ARCHIVE_OPTS(.tag = tag,
18386  .namespace = tbinfo->dobj.namespace->dobj.name,
18387  .owner = tbinfo->rolname,
18388  .description = "RULE",
18389  .section = SECTION_POST_DATA,
18390  .createStmt = cmd->data,
18391  .dropStmt = delcmd->data));
18392 
18393  /* Dump rule comments */
18394  if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18395  dumpComment(fout, ruleprefix->data, qtabname,
18396  tbinfo->dobj.namespace->dobj.name,
18397  tbinfo->rolname,
18398  rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
18399 
18400  free(tag);
18401  destroyPQExpBuffer(query);
18402  destroyPQExpBuffer(cmd);
18403  destroyPQExpBuffer(delcmd);
18404  destroyPQExpBuffer(ruleprefix);
18405  free(qtabname);
18406 }
static PQExpBuffer createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15893
static PQExpBuffer createViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15844
DumpableObject dobj
Definition: pg_dump.h:434
bool separate
Definition: pg_dump.h:439
char ev_enabled
Definition: pg_dump.h:438
bool is_instead
Definition: pg_dump.h:437
TableInfo * ruletable
Definition: pg_dump.h:435
char ev_type
Definition: pg_dump.h:436
char * checkoption
Definition: pg_dump.h:295
char * reloptions
Definition: pg_dump.h:294

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArrayAH(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, _tableInfo::checkoption, createDummyViewAsClause(), createPQExpBuffer(), createViewAsClause(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _ruleInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _ruleInfo::ev_enabled, _ruleInfo::ev_type, ExecuteSqlQuery(), fmtId(), fmtQualifiedDumpable, free, _ruleInfo::is_instead, _dumpableObject::name, nonemptyReloptions(), CatalogId::oid, pg_fatal, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), psprintf(), _tableInfo::reloptions, res, _tableInfo::rolname, _ruleInfo::ruletable, SECTION_POST_DATA, and _ruleInfo::separate.

Referenced by dumpDumpableObject().

◆ dumpSearchPath()

static void dumpSearchPath ( Archive AH)
static

Definition at line 3650 of file pg_dump.c.

3651 {
3653  PQExpBuffer path = createPQExpBuffer();
3654  PGresult *res;
3655  char **schemanames = NULL;
3656  int nschemanames = 0;
3657  int i;
3658 
3659  /*
3660  * We use the result of current_schemas(), not the search_path GUC,
3661  * because that might contain wildcards such as "$user", which won't
3662  * necessarily have the same value during restore. Also, this way avoids
3663  * listing schemas that may appear in search_path but not actually exist,
3664  * which seems like a prudent exclusion.
3665  */
3667  "SELECT pg_catalog.current_schemas(false)");
3668 
3669  if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
3670  pg_fatal("could not parse result of current_schemas()");
3671 
3672  /*
3673  * We use set_config(), not a simple "SET search_path" command, because
3674  * the latter has less-clean behavior if the search path is empty. While
3675  * that's likely to get fixed at some point, it seems like a good idea to
3676  * be as backwards-compatible as possible in what we put into archives.
3677  */
3678  for (i = 0; i < nschemanames; i++)
3679  {
3680  if (i > 0)
3681  appendPQExpBufferStr(path, ", ");
3682  appendPQExpBufferStr(path, fmtId(schemanames[i]));
3683  }
3684 
3685  appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
3686  appendStringLiteralAH(qry, path->data, AH);
3687  appendPQExpBufferStr(qry, ", false);\n");
3688 
3689  pg_log_info("saving \"search_path = %s\"", path->data);
3690 
3692  ARCHIVE_OPTS(.tag = "SEARCHPATH",
3693  .description = "SEARCHPATH",
3694  .section = SECTION_PRE_DATA,
3695  .createStmt = qry->data));
3696 
3697  /* Also save it in AH->searchpath, in case we're doing plain text dump */
3698  AH->searchpath = pg_strdup(qry->data);
3699 
3700  free(schemanames);
3701  PQclear(res);
3702  destroyPQExpBuffer(qry);
3703  destroyPQExpBuffer(path);
3704 }
char * searchpath
Definition: pg_backup.h:234

References appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, description, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), fmtId(), free, i, nilCatalogId, parsePGArray(), pg_fatal, pg_log_info, pg_strdup(), PQclear(), PQgetvalue(), res, Archive::searchpath, and SECTION_PRE_DATA.

Referenced by main().

◆ dumpSecLabel()

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

Definition at line 15377 of file pg_dump.c.

15380 {
15381  DumpOptions *dopt = fout->dopt;
15382  SecLabelItem *labels;
15383  int nlabels;
15384  int i;
15385  PQExpBuffer query;
15386 
15387  /* do nothing, if --no-security-labels is supplied */
15388  if (dopt->no_security_labels)
15389  return;
15390 
15391  /*
15392  * Security labels are schema not data ... except large object labels are
15393  * data
15394  */
15395  if (strcmp(type, "LARGE OBJECT") != 0)
15396  {
15397  if (dopt->dataOnly)
15398  return;
15399  }
15400  else
15401  {
15402  /* We do dump large object security labels in binary-upgrade mode */
15403  if (dopt->schemaOnly && !dopt->binary_upgrade)
15404  return;
15405  }
15406 
15407  /* Search for security labels associated with catalogId, using table */
15408  nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
15409 
15410  query = createPQExpBuffer();
15411 
15412  for (i = 0; i < nlabels; i++)
15413  {
15414  /*
15415  * Ignore label entries for which the subid doesn't match.
15416  */
15417  if (labels[i].objsubid != subid)
15418  continue;
15419 
15420  appendPQExpBuffer(query,
15421  "SECURITY LABEL FOR %s ON %s ",
15422  fmtId(labels[i].provider), type);
15423  if (namespace && *namespace)
15424  appendPQExpBuffer(query, "%s.", fmtId(namespace));
15425  appendPQExpBuffer(query, "%s IS ", name);
15426  appendStringLiteralAH(query, labels[i].label, fout);
15427  appendPQExpBufferStr(query, ";\n");
15428  }
15429 
15430  if (query->len > 0)
15431  {
15433 
15434  appendPQExpBuffer(tag, "%s %s", type, name);
15436  ARCHIVE_OPTS(.tag = tag->data,
15437  .namespace = namespace,
15438  .owner = owner,
15439  .description = "SECURITY LABEL",
15440  .section = SECTION_NONE,
15441  .createStmt = query->data,
15442  .deps = &dumpId,
15443  .nDeps = 1));
15444  destroyPQExpBuffer(tag);
15445  }
15446 
15447  destroyPQExpBuffer(query);
15448 }
static JitProviderCallbacks provider
Definition: jit.c:43
static int findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
Definition: pg_dump.c:15539

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), Archive::dopt, findSecLabels(), fmtId(), i, label, PQExpBufferData::len, name, nilCatalogId, _dumpOptions::no_security_labels, CatalogId::oid, provider, _dumpOptions::schemaOnly, SECTION_NONE, CatalogId::tableoid, and type.

Referenced by dumpAgg(), dumpBaseType(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpExtension(), dumpFunc(), dumpLO(), dumpNamespace(), dumpProcLang(), dumpPublication(), dumpRangeType(), dumpSequence(), dumpSubscription(), and dumpUndefinedType().

◆ dumpSequence()

static void dumpSequence ( Archive fout,
const TableInfo tbinfo 
)
static

Definition at line 17710 of file pg_dump.c.

17711 {
17712  DumpOptions *dopt = fout->dopt;
17713  SequenceItem *seq;
17714  bool is_ascending;
17715  int64 default_minv,
17716  default_maxv;
17717  PQExpBuffer query = createPQExpBuffer();
17718  PQExpBuffer delqry = createPQExpBuffer();
17719  char *qseqname;
17720  TableInfo *owning_tab = NULL;
17721 
17722  qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
17723 
17724  /*
17725  * For versions >= 10, the sequence information is gathered in a sorted
17726  * table before any calls to dumpSequence(). See collectSequences() for
17727  * more information.
17728  */
17729  if (fout->remoteVersion >= 100000)
17730  {
17731  SequenceItem key = {0};
17732 
17733  Assert(sequences);
17734 
17735  key.oid = tbinfo->dobj.catId.oid;
17736  seq = bsearch(&key, sequences, nsequences,
17737  sizeof(SequenceItem), SequenceItemCmp);
17738  }
17739  else
17740  {
17741  PGresult *res;
17742 
17743  /*
17744  * Before PostgreSQL 10, sequence metadata is in the sequence itself.
17745  *
17746  * Note: it might seem that 'bigint' potentially needs to be
17747  * schema-qualified, but actually that's a keyword.
17748  */
17749  appendPQExpBuffer(query,
17750  "SELECT 'bigint' AS sequence_type, "
17751  "start_value, increment_by, max_value, min_value, "
17752  "cache_value, is_cycled FROM %s",
17753  fmtQualifiedDumpable(tbinfo));
17754 
17755  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17756 
17757  if (PQntuples(res) != 1)
17758  pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
17759  "query to get data of sequence \"%s\" returned %d rows (expected 1)",
17760  PQntuples(res)),
17761  tbinfo->dobj.name, PQntuples(res));
17762 
17763  seq = pg_malloc0(sizeof(SequenceItem));
17764  seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0));
17765  seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10);
17766  seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10);
17767  seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10);
17768  seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10);
17769  seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10);
17770  seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
17771 
17772  PQclear(res);
17773  }
17774 
17775  /* Calculate default limits for a sequence of this type */
17776  is_ascending = (seq->incby >= 0);
17777  if (seq->seqtype == SEQTYPE_SMALLINT)
17778  {
17779  default_minv = is_ascending ? 1 : PG_INT16_MIN;
17780  default_maxv = is_ascending ? PG_INT16_MAX : -1;
17781  }
17782  else if (seq->seqtype == SEQTYPE_INTEGER)
17783  {
17784  default_minv = is_ascending ? 1 : PG_INT32_MIN;
17785  default_maxv = is_ascending ? PG_INT32_MAX : -1;
17786  }
17787  else if (seq->seqtype == SEQTYPE_BIGINT)
17788  {
17789  default_minv = is_ascending ? 1 : PG_INT64_MIN;
17790  default_maxv = is_ascending ? PG_INT64_MAX : -1;
17791  }
17792  else
17793  {
17794  pg_fatal("unrecognized sequence type: %d", seq->seqtype);
17795  default_minv = default_maxv = 0; /* keep compiler quiet */
17796  }
17797 
17798  /*
17799  * Identity sequences are not to be dropped separately.
17800  */
17801  if (!tbinfo->is_identity_sequence)
17802  {
17803  appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
17804  fmtQualifiedDumpable(tbinfo));
17805  }
17806 
17807  resetPQExpBuffer(query);
17808 
17809  if (dopt->binary_upgrade)
17810  {
17812  tbinfo->dobj.catId.oid);
17813 
17814  /*
17815  * In older PG versions a sequence will have a pg_type entry, but v14
17816  * and up don't use that, so don't attempt to preserve the type OID.
17817  */
17818  }
17819 
17820  if (tbinfo->is_identity_sequence)
17821  {
17822  owning_tab = findTableByOid(tbinfo->owning_tab);
17823 
17824  appendPQExpBuffer(query,
17825  "ALTER TABLE %s ",
17826  fmtQualifiedDumpable(owning_tab));
17827  appendPQExpBuffer(query,
17828  "ALTER COLUMN %s ADD GENERATED ",
17829  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
17830  if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
17831  appendPQExpBufferStr(query, "ALWAYS");
17832  else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
17833  appendPQExpBufferStr(query, "BY DEFAULT");
17834  appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n",
17835  fmtQualifiedDumpable(tbinfo));
17836 
17837  /*
17838  * Emit persistence option only if it's different from the owning
17839  * table's. This avoids using this new syntax unnecessarily.
17840  */
17841  if (tbinfo->relpersistence != owning_tab->relpersistence)
17842  appendPQExpBuffer(query, " %s\n",
17843  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
17844  "UNLOGGED" : "LOGGED");
17845  }
17846  else
17847  {
17848  appendPQExpBuffer(query,
17849  "CREATE %sSEQUENCE %s\n",
17850  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
17851  "UNLOGGED " : "",
17852  fmtQualifiedDumpable(tbinfo));
17853 
17854  if (seq->seqtype != SEQTYPE_BIGINT)
17855  appendPQExpBuffer(query, " AS %s\n", SeqTypeNames[seq->seqtype]);
17856  }
17857 
17858  appendPQExpBuffer(query, " START WITH " INT64_FORMAT "\n", seq->startv);
17859 
17860  appendPQExpBuffer(query, " INCREMENT BY " INT64_FORMAT "\n", seq->incby);
17861 
17862  if (seq->minv != default_minv)
17863  appendPQExpBuffer(query, " MINVALUE " INT64_FORMAT "\n", seq->minv);
17864  else
17865  appendPQExpBufferStr(query, " NO MINVALUE\n");
17866 
17867  if (seq->maxv != default_maxv)
17868  appendPQExpBuffer(query, " MAXVALUE " INT64_FORMAT "\n", seq->maxv);
17869  else
17870  appendPQExpBufferStr(query, " NO MAXVALUE\n");
17871 
17872  appendPQExpBuffer(query,
17873  " CACHE " INT64_FORMAT "%s",
17874  seq->cache, (seq->cycled ? "\n CYCLE" : ""));
17875 
17876  if (tbinfo->is_identity_sequence)
17877  appendPQExpBufferStr(query, "\n);\n");
17878  else
17879  appendPQExpBufferStr(query, ";\n");
17880 
17881  /* binary_upgrade: no need to clear TOAST table oid */
17882 
17883  if (dopt->binary_upgrade)
17884  binary_upgrade_extension_member(query, &tbinfo->dobj,
17885  "SEQUENCE", qseqname,
17886  tbinfo->dobj.namespace->dobj.name);
17887 
17888  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17889  ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
17890  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17891  .namespace = tbinfo->dobj.namespace->dobj.name,
17892  .owner = tbinfo->rolname,
17893  .description = "SEQUENCE",
17894  .section = SECTION_PRE_DATA,
17895  .createStmt = query->data,
17896  .dropStmt = delqry->data));
17897 
17898  /*
17899  * If the sequence is owned by a table column, emit the ALTER for it as a
17900  * separate TOC entry immediately following the sequence's own entry. It's
17901  * OK to do this rather than using full sorting logic, because the
17902  * dependency that tells us it's owned will have forced the table to be
17903  * created first. We can't just include the ALTER in the TOC entry
17904  * because it will fail if we haven't reassigned the sequence owner to
17905  * match the table's owner.
17906  *
17907  * We need not schema-qualify the table reference because both sequence
17908  * and table must be in the same schema.
17909  */
17910  if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
17911  {
17912  owning_tab = findTableByOid(tbinfo->owning_tab);
17913 
17914  if (owning_tab == NULL)
17915  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
17916  tbinfo->owning_tab, tbinfo->dobj.catId.oid);
17917 
17918  if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
17919  {
17920  resetPQExpBuffer(query);
17921  appendPQExpBuffer(query, "ALTER SEQUENCE %s",
17922  fmtQualifiedDumpable(tbinfo));
17923  appendPQExpBuffer(query, " OWNED BY %s",
17924  fmtQualifiedDumpable(owning_tab));
17925  appendPQExpBuffer(query, ".%s;\n",
17926  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
17927 
17928  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17930  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17931  .namespace = tbinfo->dobj.namespace->dobj.name,
17932  .owner = tbinfo->rolname,
17933  .description = "SEQUENCE OWNED BY",
17934  .section = SECTION_PRE_DATA,
17935  .createStmt = query->data,
17936  .deps = &(tbinfo->dobj.dumpId),
17937  .nDeps = 1));
17938  }
17939  }
17940 
17941  /* Dump Sequence Comments and Security Labels */
17942  if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17943  dumpComment(fout, "SEQUENCE", qseqname,
17944  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17945  tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
17946 
17947  if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
17948  dumpSecLabel(fout, "SEQUENCE", qseqname,
17949  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17950  tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
17951 
17952  if (fout->remoteVersion < 100000)
17953  pg_free(seq);
17954  destroyPQExpBuffer(query);
17955  destroyPQExpBuffer(delqry);
17956  free(qseqname);
17957 }
TableInfo * findTableByOid(Oid oid)
Definition: common.c:840
#define PG_INT32_MAX
Definition: c.h:594
#define ngettext(s, p, n)
Definition: c.h:1186
#define INT64_FORMAT
Definition: c.h:551
#define PG_INT16_MIN
Definition: c.h:590
#define PG_INT64_MAX
Definition: c.h:597
#define PG_INT64_MIN
Definition: c.h:596
#define PG_INT32_MIN
Definition: c.h:593
#define PG_INT16_MAX
Definition: c.h:591
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static int SequenceItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:17634
static const char *const SeqTypeNames[]
Definition: pg_dump.c:113
char * attidentity
Definition: pg_dump.h:340
bool is_identity_sequence
Definition: pg_dump.h:316
int owning_col
Definition: pg_dump.h:315
Oid owning_tab
Definition: pg_dump.h:314
char relpersistence
Definition: pg_dump.h:290

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), Assert, _tableInfo::attidentity, _tableInfo::attnames, _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), SequenceItem::cache, _dumpableObject::catId, createDumpId(), createPQExpBuffer(), SequenceItem::cycled, PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQuery(), findTableByOid(), fmtId(), fmtQualifiedDumpable, free, SequenceItem::incby, INT64_FORMAT, _tableInfo::is_identity_sequence, sort-test::key, SequenceItem::maxv, SequenceItem::minv, _dumpableObject::name, ngettext, nilCatalogId, nsequences, CatalogId::oid, OidIsValid, _tableInfo::owning_col, _tableInfo::owning_tab, parse_sequence_type(), pg_fatal, pg_free(), PG_INT16_MAX, PG_INT16_MIN, PG_INT32_MAX, PG_INT32_MIN, PG_INT64_MAX, PG_INT64_MIN, pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), _tableInfo::relpersistence, Archive::remoteVersion, res, resetPQExpBuffer(), _tableInfo::rolname, SECTION_PRE_DATA, SequenceItem::seqtype, SEQTYPE_BIGINT, SEQTYPE_INTEGER, SEQTYPE_SMALLINT, SeqTypeNames, SequenceItemCmp(), sequences, SequenceItem::startv, and strtoi64.

Referenced by dumpTable().

◆ dumpSequenceData()

static void dumpSequenceData ( Archive fout,
const TableDataInfo tdinfo 
)
static

Definition at line 17964 of file pg_dump.c.

17965 {
17966  TableInfo *tbinfo = tdinfo->tdtable;
17967  int64 last;
17968  bool called;
17969  PQExpBuffer query = createPQExpBuffer();
17970 
17971  /*
17972  * For versions >= 18, the sequence information is gathered in the sorted
17973  * array before any calls to dumpSequenceData(). See collectSequences()
17974  * for more information.
17975  *
17976  * For older versions, we have to query the sequence relations
17977  * individually.
17978  */
17979  if (fout->remoteVersion < 180000)
17980  {
17981  PGresult *res;
17982 
17983  appendPQExpBuffer(query,
17984  "SELECT last_value, is_called FROM %s",
17985  fmtQualifiedDumpable(tbinfo));
17986 
17987  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17988 
17989  if (PQntuples(res) != 1)
17990  pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
17991  "query to get data of sequence \"%s\" returned %d rows (expected 1)",
17992  PQntuples(res)),
17993  tbinfo->dobj.name, PQntuples(res));
17994 
17995  last = strtoi64(PQgetvalue(res, 0, 0), NULL, 10);
17996  called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
17997 
17998  PQclear(res);
17999  }
18000  else
18001  {
18002  SequenceItem key = {0};
18003  SequenceItem *entry;
18004 
18005  Assert(sequences);
18006  Assert(tbinfo->dobj.catId.oid);
18007 
18008  key.oid = tbinfo->dobj.catId.oid;
18009  entry = bsearch(&key, sequences, nsequences,
18010  sizeof(SequenceItem), SequenceItemCmp);
18011 
18012  last = entry->last_value;
18013  called = entry->is_called;
18014  }
18015 
18016  resetPQExpBuffer(query);
18017  appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
18018  appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
18019  appendPQExpBuffer(query, ", " INT64_FORMAT ", %s);\n",
18020  last, (called ? "true" : "false"));
18021 
18022  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
18024  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
18025  .namespace = tbinfo->dobj.namespace->dobj.name,
18026  .owner = tbinfo->rolname,
18027  .description = "SEQUENCE SET",
18028  .section = SECTION_DATA,
18029  .createStmt = query->data,
18030  .deps = &(tbinfo->dobj.dumpId),
18031  .nDeps = 1));
18032 
18033  destroyPQExpBuffer(query);
18034 }
TableInfo * tdtable
Definition: pg_dump.h:390
DumpableObject dobj
Definition: pg_dump.h:389

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), Assert, _dumpableObject::catId, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _tableDataInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_DATA, _dumpableObject::dumpId, ExecuteSqlQuery(), fmtQualifiedDumpable, INT64_FORMAT, SequenceItem::is_called, sort-test::key, SequenceItem::last_value, _dumpableObject::name, ngettext, nilCatalogId, nsequences, CatalogId::oid, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, resetPQExpBuffer(), _tableInfo::rolname, SECTION_DATA, SequenceItemCmp(), sequences, strtoi64, and _tableDataInfo::tdtable.

Referenced by dumpDumpableObject().

◆ dumpShellType()

static void dumpShellType ( Archive fout,
const ShellTypeInfo stinfo 
)
static

Definition at line 12069 of file pg_dump.c.

12070 {
12071  DumpOptions *dopt = fout->dopt;
12072  PQExpBuffer q;
12073 
12074  /* Do nothing in data-only dump */
12075  if (dopt->dataOnly)
12076  return;
12077 
12078  q = createPQExpBuffer();
12079 
12080  /*
12081  * Note the lack of a DROP command for the shell type; any required DROP
12082  * is driven off the base type entry, instead. This interacts with
12083  * _printTocEntry()'s use of the presence of a DROP command to decide
12084  * whether an entry needs an ALTER OWNER command. We don't want to alter
12085  * the shell type's owner immediately on creation; that should happen only
12086  * after it's filled in, otherwise the backend complains.
12087  */
12088 
12089  if (dopt->binary_upgrade)
12091  stinfo->baseType->dobj.catId.oid,
12092  false, false);
12093 
12094  appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12095  fmtQualifiedDumpable(stinfo));
12096 
12097  if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12098  ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
12099  ARCHIVE_OPTS(.tag = stinfo->dobj.name,
12100  .namespace = stinfo->dobj.namespace->dobj.name,
12101  .owner = stinfo->baseType->rolname,
12102  .description = "SHELL TYPE",
12103  .section = SECTION_PRE_DATA,
12104  .createStmt = q->data));
12105 
12106  destroyPQExpBuffer(q);
12107 }
TypeInfo * baseType
Definition: pg_dump.h:220
DumpableObject dobj
Definition: pg_dump.h:218

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _shellTypeInfo::baseType, _dumpOptions::binary_upgrade, binary_upgrade_set_type_oids_by_type_oid(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _typeInfo::dobj, _shellTypeInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, fmtQualifiedDumpable, _dumpableObject::name, CatalogId::oid, _typeInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpStatisticsExt()

static void dumpStatisticsExt ( Archive fout,
const StatsExtInfo statsextinfo 
)
static

Definition at line 17229 of file pg_dump.c.

17230 {
17231  DumpOptions *dopt = fout->dopt;
17232  PQExpBuffer q;
17233  PQExpBuffer delq;
17234  PQExpBuffer query;
17235  char *qstatsextname;
17236  PGresult *res;
17237  char *stxdef;
17238 
17239  /* Do nothing in data-only dump */
17240  if (dopt->dataOnly)
17241  return;
17242 
17243  q = createPQExpBuffer();
17244  delq = createPQExpBuffer();
17245  query = createPQExpBuffer();
17246 
17247  qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
17248 
17249  appendPQExpBuffer(query, "SELECT "
17250  "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
17251  statsextinfo->dobj.catId.oid);
17252 
17253  res = ExecuteSqlQueryForSingleRow(fout, query->data);
17254 
17255  stxdef = PQgetvalue(res, 0, 0);
17256 
17257  /* Result of pg_get_statisticsobjdef is complete except for semicolon */
17258  appendPQExpBuffer(q, "%s;\n", stxdef);
17259 
17260  /*
17261  * We only issue an ALTER STATISTICS statement if the stxstattarget entry
17262  * for this statistics object is not the default value.
17263  */
17264  if (statsextinfo->stattarget >= 0)
17265  {
17266  appendPQExpBuffer(q, "ALTER STATISTICS %s ",
17267  fmtQualifiedDumpable(statsextinfo));
17268  appendPQExpBuffer(q, "SET STATISTICS %d;\n",
17269  statsextinfo->stattarget);
17270  }
17271 
17272  appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
17273  fmtQualifiedDumpable(statsextinfo));
17274 
17275  if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17276  ArchiveEntry(fout, statsextinfo->dobj.catId,
17277  statsextinfo->dobj.dumpId,
17278  ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
17279  .namespace = statsextinfo->dobj.namespace->dobj.name,
17280  .owner = statsextinfo->rolname,
17281  .description = "STATISTICS",
17282  .section = SECTION_POST_DATA,
17283  .createStmt = q->data,
17284  .dropStmt = delq->data));
17285 
17286  /* Dump Statistics Comments */
17287  if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17288  dumpComment(fout, "STATISTICS", qstatsextname,
17289  statsextinfo->dobj.namespace->dobj.name,
17290  statsextinfo->rolname,
17291  statsextinfo->dobj.catId, 0,
17292  statsextinfo->dobj.dumpId);
17293 
17294  PQclear(res);
17295  destroyPQExpBuffer(q);
17296  destroyPQExpBuffer(delq);
17297  destroyPQExpBuffer(query);
17298  free(qstatsextname);
17299 }
int stattarget
Definition: pg_dump.h:429
const char * rolname
Definition: pg_dump.h:427
DumpableObject dobj
Definition: pg_dump.h:426

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _statsExtInfo::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(), PQgetvalue(), res, _statsExtInfo::rolname, SECTION_POST_DATA, and _statsExtInfo::stattarget.

Referenced by dumpDumpableObject().

◆ dumpStdStrings()

static void dumpStdStrings ( Archive AH)
static

Definition at line 3626 of file pg_dump.c.

3627 {
3628  const char *stdstrings = AH->std_strings ? "on" : "off";
3630 
3631  pg_log_info("saving \"standard_conforming_strings = %s\"",
3632  stdstrings);
3633 
3634  appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
3635  stdstrings);
3636 
3638  ARCHIVE_OPTS(.tag = "STDSTRINGS",
3639  .description = "STDSTRINGS",
3640  .section = SECTION_PRE_DATA,
3641  .createStmt = qry->data));
3642 
3643  destroyPQExpBuffer(qry);
3644 }

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, description, destroyPQExpBuffer(), nilCatalogId, pg_log_info, SECTION_PRE_DATA, and Archive::std_strings.

Referenced by main().

◆ dumpSubscription()

static void dumpSubscription ( Archive fout,
const SubscriptionInfo subinfo 
)
static

Definition at line 5195 of file pg_dump.c.

5196 {
5197  DumpOptions *dopt = fout->dopt;
5198  PQExpBuffer delq;
5199  PQExpBuffer query;
5200  PQExpBuffer publications;
5201  char *qsubname;
5202  char **pubnames = NULL;
5203  int npubnames = 0;
5204  int i;
5205  char two_phase_disabled[] = {LOGICALREP_TWOPHASE_STATE_DISABLED, '\0'};
5206 
5207  /* Do nothing in data-only dump */
5208  if (dopt->dataOnly)
5209  return;
5210 
5211  delq = createPQExpBuffer();
5212  query = createPQExpBuffer();
5213 
5214  qsubname = pg_strdup(fmtId(subinfo->dobj.name));
5215 
5216  appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
5217  qsubname);
5218 
5219  appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
5220  qsubname);
5221  appendStringLiteralAH(query, subinfo->subconninfo, fout);
5222 
5223  /* Build list of quoted publications and append them to query. */
5224  if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
5225  pg_fatal("could not parse %s array", "subpublications");
5226 
5227  publications = createPQExpBuffer();
5228  for (i = 0; i < npubnames; i++)
5229  {
5230  if (i > 0)
5231  appendPQExpBufferStr(publications, ", ");
5232 
5233  appendPQExpBufferStr(publications, fmtId(pubnames[i]));
5234  }
5235 
5236  appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
5237  if (subinfo->subslotname)
5238  appendStringLiteralAH(query, subinfo->subslotname, fout);
5239  else
5240  appendPQExpBufferStr(query, "NONE");
5241 
5242  if (strcmp(subinfo->subbinary, "t") == 0)
5243  appendPQExpBufferStr(query, ", binary = true");
5244 
5245  if (strcmp(subinfo->substream, "t") == 0)
5246  appendPQExpBufferStr(query, ", streaming = on");
5247  else if (strcmp(subinfo->substream, "p") == 0)
5248  appendPQExpBufferStr(query, ", streaming = parallel");
5249  else
5250  appendPQExpBufferStr(query, ", streaming = off");
5251 
5252  if (strcmp(subinfo->subtwophasestate, two_phase_disabled) != 0)
5253  appendPQExpBufferStr(query, ", two_phase = on");
5254 
5255  if (strcmp(subinfo->subdisableonerr, "t") == 0)
5256  appendPQExpBufferStr(query, ", disable_on_error = true");
5257 
5258  if (strcmp(subinfo->subpasswordrequired, "t") != 0)
5259  appendPQExpBuffer(query, ", password_required = false");
5260 
5261  if (strcmp(subinfo->subrunasowner, "t") == 0)
5262  appendPQExpBufferStr(query, ", run_as_owner = true");
5263 
5264  if (strcmp(subinfo->subfailover, "t") == 0)
5265  appendPQExpBufferStr(query, ", failover = true");
5266 
5267  if (strcmp(subinfo->subsynccommit, "off") != 0)
5268  appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
5269 
5270  if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
5271  appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
5272 
5273  appendPQExpBufferStr(query, ");\n");
5274 
5275  /*
5276  * In binary-upgrade mode, we allow the replication to continue after the
5277  * upgrade.
5278  */
5279  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5280  {
5281  if (subinfo->suboriginremotelsn)
5282  {
5283  /*
5284  * Preserve the remote_lsn for the subscriber's replication
5285  * origin. This value is required to start the replication from
5286  * the position before the upgrade. This value will be stale if
5287  * the publisher gets upgraded before the subscriber node.
5288  * However, this shouldn't be a problem as the upgrade of the
5289  * publisher ensures that all the transactions were replicated
5290  * before upgrading it.
5291  */
5292  appendPQExpBufferStr(query,
5293  "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
5294  appendPQExpBufferStr(query,
5295  "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
5296  appendStringLiteralAH(query, subinfo->dobj.name, fout);
5297  appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
5298  }
5299 
5300  if (strcmp(subinfo->subenabled, "t") == 0)
5301  {
5302  /*
5303  * Enable the subscription to allow the replication to continue
5304  * after the upgrade.
5305  */
5306  appendPQExpBufferStr(query,
5307  "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
5308  appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
5309  }
5310  }
5311 
5312  if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5313  ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
5314  ARCHIVE_OPTS(.tag = subinfo->dobj.name,
5315  .owner = subinfo->rolname,
5316  .description = "SUBSCRIPTION",
5317  .section = SECTION_POST_DATA,
5318  .createStmt = query->data,
5319  .dropStmt = delq->data));
5320 
5321  if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
5322  dumpComment(fout, "SUBSCRIPTION", qsubname,
5323  NULL, subinfo->rolname,
5324  subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5325 
5326  if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
5327  dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
5328  NULL, subinfo->rolname,
5329  subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5330 
5331  destroyPQExpBuffer(publications);
5332  free(pubnames);
5333 
5334  destroyPQExpBuffer(delq);
5335  destroyPQExpBuffer(query);
5336  free(qsubname);
5337 }
#define LOGICALREP_ORIGIN_ANY
#define LOGICALREP_TWOPHASE_STATE_DISABLED
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char * suboriginremotelsn
Definition: pg_dump.h:679
char * suborigin
Definition: pg_dump.h:678
char * subbinary
Definition: pg_dump.h:668
const char * rolname
Definition: pg_dump.h:666
char * subrunasowner
Definition: pg_dump.h:673
char * subsynccommit
Definition: pg_dump.h:676
char * subpublications
Definition: pg_dump.h:677
char * subtwophasestate
Definition: pg_dump.h:670
char * subfailover
Definition: pg_dump.h:680
char * subenabled
Definition: pg_dump.h:667
char * substream
Definition: pg_dump.h:669
char * subpasswordrequired
Definition: pg_dump.h:672
char * subslotname
Definition: pg_dump.h:675
char * subdisableonerr
Definition: pg_dump.h:671
char * subconninfo
Definition: pg_dump.h:674
DumpableObject dobj
Definition: pg_dump.h:665

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _SubscriptionInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), fmtId(), free, i, LOGICALREP_ORIGIN_ANY, LOGICALREP_TWOPHASE_STATE_DISABLED, _dumpableObject::name, parsePGArray(), pg_fatal, pg_strcasecmp(), pg_strdup(), Archive::remoteVersion, _SubscriptionInfo::rolname, SECTION_POST_DATA, _SubscriptionInfo::subbinary, _SubscriptionInfo::subconninfo, _SubscriptionInfo::subdisableonerr, _SubscriptionInfo::subenabled, _SubscriptionInfo::subfailover, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, and _SubscriptionInfo::subtwophasestate.

Referenced by dumpDumpableObject().

◆ dumpSubscriptionTable()

static void dumpSubscriptionTable ( Archive fout,
const SubRelInfo subrinfo 
)
static

Definition at line 5126 of file pg_dump.c.

5127 {
5128  DumpOptions *dopt = fout->dopt;
5129  SubscriptionInfo *subinfo = subrinfo->subinfo;
5130  PQExpBuffer query;
5131  char *tag;
5132 
5133  /* Do nothing in data-only dump */
5134  if (dopt->dataOnly)
5135  return;
5136 
5137  Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
5138 
5139  tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
5140 
5141  query = createPQExpBuffer();
5142 
5143  if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5144  {
5145  /*
5146  * binary_upgrade_add_sub_rel_state will add the subscription relation
5147  * to pg_subscription_rel table. This will be used only in
5148  * binary-upgrade mode.
5149  */
5150  appendPQExpBufferStr(query,
5151  "\n-- For binary upgrade, must preserve the subscriber table.\n");
5152  appendPQExpBufferStr(query,
5153  "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
5154  appendStringLiteralAH(query, subrinfo->dobj.name, fout);
5155  appendPQExpBuffer(query,
5156  ", %u, '%c'",
5157  subrinfo->tblinfo->dobj.catId.oid,
5158  subrinfo->srsubstate);
5159 
5160  if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
5161  appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
5162  else
5163  appendPQExpBuffer(query, ", NULL");
5164 
5165  appendPQExpBufferStr(query, ");\n");
5166  }
5167 
5168  /*
5169  * There is no point in creating a drop query as the drop is done by table
5170  * drop. (If you think to change this, see also _printTocEntry().)
5171  * Although this object doesn't really have ownership as such, set the
5172  * owner field anyway to ensure that the command is run by the correct
5173  * role at restore time.
5174  */
5175  if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5176  ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
5177  ARCHIVE_OPTS(.tag = tag,
5178  .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
5179  .owner = subinfo->rolname,
5180  .description = "SUBSCRIPTION TABLE",
5181  .section = SECTION_POST_DATA,
5182  .createStmt = query->data));
5183 
5184  /* These objects can't currently have comments or seclabels */
5185 
5186  free(tag);
5187  destroyPQExpBuffer(query);
5188 }
DumpableObject dobj
Definition: pg_dump.h:695
char * srsublsn
Definition: pg_dump.h:699
SubscriptionInfo * subinfo
Definition: pg_dump.h:696
TableInfo * tblinfo
Definition: pg_dump.h:697
char srsubstate
Definition: pg_dump.h:698

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), Assert, _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _SubscriptionInfo::dobj, _SubRelInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, free, _dumpableObject::name, CatalogId::oid, psprintf(), Archive::remoteVersion, _SubscriptionInfo::rolname, SECTION_POST_DATA, _SubRelInfo::srsublsn, _SubRelInfo::srsubstate, _SubRelInfo::subinfo, and _SubRelInfo::tblinfo.

Referenced by dumpDumpableObject().

◆ dumpTable()

static void dumpTable ( Archive fout,
const TableInfo tbinfo 
)
static

Definition at line 15704 of file pg_dump.c.

15705 {
15706  DumpOptions *dopt = fout->dopt;
15707  DumpId tableAclDumpId = InvalidDumpId;
15708  char *namecopy;
15709 
15710  /* Do nothing in data-only dump */
15711  if (dopt->dataOnly)
15712  return;
15713 
15714  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15715  {
15716  if (tbinfo->relkind == RELKIND_SEQUENCE)
15717  dumpSequence(fout, tbinfo);
15718  else
15719  dumpTableSchema(fout, tbinfo);
15720  }
15721 
15722  /* Handle the ACL here */
15723  namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
15724  if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
15725  {
15726  const char *objtype =
15727  (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
15728 
15729  tableAclDumpId =
15730  dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
15731  objtype, namecopy, NULL,
15732  tbinfo->dobj.namespace->dobj.name,
15733  NULL, tbinfo->rolname, &tbinfo->dacl);
15734  }
15735 
15736  /*
15737  * Handle column ACLs, if any. Note: we pull these with a separate query
15738  * rather than trying to fetch them during getTableAttrs, so that we won't
15739  * miss ACLs on system columns. Doing it this way also allows us to dump
15740  * ACLs for catalogs that we didn't mark "interesting" back in getTables.
15741  */
15742  if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
15743  {
15744  PQExpBuffer query = createPQExpBuffer();
15745  PGresult *res;
15746  int i;
15747 
15749  {
15750  /* Set up query for column ACLs */
15751  appendPQExpBufferStr(query,
15752  "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
15753 
15754  if (fout->remoteVersion >= 90600)
15755  {
15756  /*
15757  * In principle we should call acldefault('c', relowner) to
15758  * get the default ACL for a column. However, we don't
15759  * currently store the numeric OID of the relowner in
15760  * TableInfo. We could convert the owner name using regrole,
15761  * but that creates a risk of failure due to concurrent role
15762  * renames. Given that the default ACL for columns is empty
15763  * and is likely to stay that way, it's not worth extra cycles
15764  * and risk to avoid hard-wiring that knowledge here.
15765  */
15766  appendPQExpBufferStr(query,
15767  "SELECT at.attname, "
15768  "at.attacl, "
15769  "'{}' AS acldefault, "
15770  "pip.privtype, pip.initprivs "
15771  "FROM pg_catalog.pg_attribute at "
15772  "LEFT JOIN pg_catalog.pg_init_privs pip ON "
15773  "(at.attrelid = pip.objoid "
15774  "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
15775  "AND at.attnum = pip.objsubid) "
15776  "WHERE at.attrelid = $1 AND "
15777  "NOT at.attisdropped "
15778  "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
15779  "ORDER BY at.attnum");
15780  }
15781  else
15782  {
15783  appendPQExpBufferStr(query,
15784  "SELECT attname, attacl, '{}' AS acldefault, "
15785  "NULL AS privtype, NULL AS initprivs "
15786  "FROM pg_catalog.pg_attribute "
15787  "WHERE attrelid = $1 AND NOT attisdropped "
15788  "AND attacl IS NOT NULL "
15789  "ORDER BY attnum");
15790  }
15791 
15792  ExecuteSqlStatement(fout, query->data);
15793 
15794  fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
15795  }
15796 
15797  printfPQExpBuffer(query,
15798  "EXECUTE getColumnACLs('%u')",
15799  tbinfo->dobj.catId.oid);
15800 
15801  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15802 
15803  for (i = 0; i < PQntuples(res); i++)
15804  {
15805  char *attname = PQgetvalue(res, i, 0);
15806  char *attacl = PQgetvalue(res, i, 1);
15807  char *acldefault = PQgetvalue(res, i, 2);
15808  char privtype = *(PQgetvalue(res, i, 3));
15809  char *initprivs = PQgetvalue(res, i, 4);
15810  DumpableAcl coldacl;
15811  char *attnamecopy;
15812 
15813  coldacl.acl = attacl;
15814  coldacl.acldefault = acldefault;
15815  coldacl.privtype = privtype;
15816  coldacl.initprivs = initprivs;
15817  attnamecopy = pg_strdup(fmtId(attname));
15818 
15819  /*
15820  * Column's GRANT type is always TABLE. Each column ACL depends
15821  * on the table-level ACL, since we can restore column ACLs in
15822  * parallel but the table-level ACL has to be done first.
15823  */
15824  dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
15825  "TABLE", namecopy, attnamecopy,
15826  tbinfo->dobj.namespace->dobj.name,
15827  NULL, tbinfo->rolname, &coldacl);
15828  free(attnamecopy);
15829  }
15830  PQclear(res);
15831  destroyPQExpBuffer(query);
15832  }
15833 
15834  free(namecopy);
15835 }
@ PREPQUERY_GETCOLUMNACLS
Definition: pg_backup.h:75
static void dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15933
static void dumpSequence(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:17710
DumpableAcl dacl
Definition: pg_dump.h:287
bool hascolumnACLs
Definition: pg_dump.h:300

References _dumpableAcl::acl, acldefault(), _dumpableAcl::acldefault, appendPQExpBufferStr(), attname, _dumpableObject::catId, createPQExpBuffer(), _tableInfo::dacl, PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DEFINITION, dumpACL(), _dumpableObject::dumpId, dumpSequence(), dumpTableSchema(), ExecuteSqlQuery(), ExecuteSqlStatement(), fmtId(), free, _tableInfo::hascolumnACLs, i, _dumpableAcl::initprivs, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), PREPQUERY_GETCOLUMNACLS, printfPQExpBuffer(), _dumpableAcl::privtype, _tableInfo::relkind, Archive::remoteVersion, res, and _tableInfo::rolname.

Referenced by dumpDumpableObject().

◆ dumpTableAttach()

static void dumpTableAttach ( Archive fout,
const TableAttachInfo attachinfo 
)
static

Definition at line 16891 of file pg_dump.c.

16892 {
16893  DumpOptions *dopt = fout->dopt;
16894  PQExpBuffer q;
16895  PGresult *res;
16896  char *partbound;
16897 
16898  /* Do nothing in data-only dump */
16899  if (dopt->dataOnly)
16900  return;
16901 
16902  q = createPQExpBuffer();
16903 
16905  {
16906  /* Set up query for partbound details */
16908  "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
16909 
16911  "SELECT pg_get_expr(c.relpartbound, c.oid) "
16912  "FROM pg_class c "
16913  "WHERE c.oid = $1");
16914 
16915  ExecuteSqlStatement(fout, q->data);
16916 
16917  fout->is_prepared[PREPQUERY_DUMPTABLEATTACH] = true;
16918  }
16919 
16921  "EXECUTE dumpTableAttach('%u')",
16922  attachinfo->partitionTbl->dobj.catId.oid);
16923 
16924  res = ExecuteSqlQueryForSingleRow(fout, q->data);
16925  partbound = PQgetvalue(res, 0, 0);
16926 
16927  /* Perform ALTER TABLE on the parent */
16929  "ALTER TABLE ONLY %s ",
16930  fmtQualifiedDumpable(attachinfo->parentTbl));
16932  "ATTACH PARTITION %s %s;\n",
16933  fmtQualifiedDumpable(attachinfo->partitionTbl),
16934  partbound);
16935 
16936  /*
16937  * There is no point in creating a drop query as the drop is done by table
16938  * drop. (If you think to change this, see also _printTocEntry().)
16939  * Although this object doesn't really have ownership as such, set the
16940  * owner field anyway to ensure that the command is run by the correct
16941  * role at restore time.
16942  */
16943  ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
16944  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
16945  .namespace = attachinfo->dobj.namespace->dobj.name,
16946  .owner = attachinfo->partitionTbl->rolname,
16947  .description = "TABLE ATTACH",
16948  .section = SECTION_PRE_DATA,
16949  .createStmt = q->data));
16950 
16951  PQclear(res);
16952  destroyPQExpBuffer(q);
16953 }
@ PREPQUERY_DUMPTABLEATTACH
Definition: pg_backup.h:74
TableInfo * partitionTbl
Definition: pg_dump.h:375
DumpableObject dobj
Definition: pg_dump.h:373
TableInfo * parentTbl
Definition: pg_dump.h:374

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _tableAttachInfo::dobj, Archive::dopt, _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), fmtQualifiedDumpable, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, _tableAttachInfo::parentTbl, _tableAttachInfo::partitionTbl, PQclear(), PQgetvalue(), PREPQUERY_DUMPTABLEATTACH, printfPQExpBuffer(), res, _tableInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpTableComment()

static void dumpTableComment ( Archive fout,
const TableInfo tbinfo,
const char *  reltypename 
)
static

Definition at line 10301 of file pg_dump.c.

10303 {
10304  DumpOptions *dopt = fout->dopt;
10306  int ncomments;
10307  PQExpBuffer query;
10308  PQExpBuffer tag;
10309 
10310  /* do nothing, if --no-comments is supplied */
10311  if (dopt->no_comments)
10312  return;
10313 
10314  /* Comments are SCHEMA not data */
10315  if (dopt->dataOnly)
10316  return;
10317 
10318  /* Search for comments associated with relation, using table */
10320  tbinfo->dobj.catId.oid,
10321  &comments);
10322 
10323  /* If comments exist, build COMMENT ON statements */
10324  if (ncomments <= 0)
10325  return;
10326 
10327  query = createPQExpBuffer();
10328  tag = createPQExpBuffer();
10329 
10330  while (ncomments > 0)
10331  {
10332  const char *descr = comments->descr;
10333  int objsubid = comments->objsubid;
10334 
10335  if (objsubid == 0)
10336  {
10337  resetPQExpBuffer(tag);
10338  appendPQExpBuffer(tag, "%s %s", reltypename,
10339  fmtId(tbinfo->dobj.name));
10340 
10341  resetPQExpBuffer(query);
10342  appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
10343  fmtQualifiedDumpable(tbinfo));
10344  appendStringLiteralAH(query, descr, fout);
10345  appendPQExpBufferStr(query, ";\n");
10346 
10348  ARCHIVE_OPTS(.tag = tag->data,
10349  .namespace = tbinfo->dobj.namespace->dobj.name,
10350  .owner = tbinfo->rolname,
10351  .description = "COMMENT",
10352  .section = SECTION_NONE,
10353  .createStmt = query->data,
10354  .deps = &(tbinfo->dobj.dumpId),
10355  .nDeps = 1));
10356  }
10357  else if (objsubid > 0 && objsubid <= tbinfo->numatts)
10358  {
10359  resetPQExpBuffer(tag);
10360  appendPQExpBuffer(tag, "COLUMN %s.",
10361  fmtId(tbinfo->dobj.name));
10362  appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
10363 
10364  resetPQExpBuffer(query);
10365  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
10366  fmtQualifiedDumpable(tbinfo));
10367  appendPQExpBuffer(query, "%s IS ",
10368  fmtId(tbinfo->attnames[objsubid - 1]));
10369  appendStringLiteralAH(query, descr, fout);
10370  appendPQExpBufferStr(query, ";\n");
10371 
10373  ARCHIVE_OPTS(.tag = tag->data,
10374  .namespace = tbinfo->dobj.namespace->dobj.name,
10375  .owner = tbinfo->rolname,
10376  .description = "COMMENT",
10377  .section = SECTION_NONE,
10378  .createStmt = query->data,
10379  .deps = &(tbinfo->dobj.dumpId),
10380  .nDeps = 1));
10381  }
10382 
10383  comments++;
10384  ncomments--;
10385  }
10386 
10387  destroyPQExpBuffer(query);
10388  destroyPQExpBuffer(tag);
10389 }

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _tableInfo::attnames, _dumpableObject::catId, comments, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, CommentItem::descr, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dumpId, findComments(), fmtId(), fmtQualifiedDumpable, _dumpableObject::name, ncomments, nilCatalogId, _dumpOptions::no_comments, CommentItem::objsubid, CatalogId::oid, resetPQExpBuffer(), _tableInfo::rolname, SECTION_NONE, and CatalogId::tableoid.

Referenced by dumpTableSchema().

◆ dumpTableConstraintComment()

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

Definition at line 17595 of file pg_dump.c.

17596 {
17597  TableInfo *tbinfo = coninfo->contable;
17598  PQExpBuffer conprefix = createPQExpBuffer();
17599  char *qtabname;
17600 
17601  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17602 
17603  appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
17604  fmtId(coninfo->dobj.name));
17605 
17606  if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17607  dumpComment(fout, conprefix->data, qtabname,
17608  tbinfo->dobj.namespace->dobj.name,
17609  tbinfo->rolname,
17610  coninfo->dobj.catId, 0,
17611  coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
17612 
17613  destroyPQExpBuffer(conprefix);
17614  free(qtabname);
17615 }

References appendPQExpBuffer(), _dumpableObject::catId, _constraintInfo::contable, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _constraintInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, dumpComment(), _dumpableObject::dumpId, fmtId(), free, _dumpableObject::name, pg_strdup(), _tableInfo::rolname, and _constraintInfo::separate.

Referenced by dumpConstraint(), and dumpTableSchema().

◆ dumpTableData()

static void dumpTableData ( Archive fout,
const TableDataInfo tdinfo 
)
static

Definition at line 2689 of file pg_dump.c.

2690 {
2691  DumpOptions *dopt = fout->dopt;
2692  TableInfo *tbinfo = tdinfo->tdtable;
2693  PQExpBuffer copyBuf = createPQExpBuffer();
2694  PQExpBuffer clistBuf = createPQExpBuffer();
2695  DataDumperPtr dumpFn;
2696  char *tdDefn = NULL;
2697  char *copyStmt;
2698  const char *copyFrom;
2699 
2700  /* We had better have loaded per-column details about this table */
2701  Assert(tbinfo->interesting);
2702 
2703  /*
2704  * When load-via-partition-root is set or forced, get the root table name
2705  * for the partition table, so that we can reload data through the root
2706  * table. Then construct a comment to be inserted into the TOC entry's
2707  * defn field, so that such cases can be identified reliably.
2708  */
2709  if (tbinfo->ispartition &&
2710  (dopt->load_via_partition_root ||
2711  forcePartitionRootLoad(tbinfo)))
2712  {
2713  TableInfo *parentTbinfo;
2714 
2715  parentTbinfo = getRootTableInfo(tbinfo);
2716  copyFrom = fmtQualifiedDumpable(parentTbinfo);
2717  printfPQExpBuffer(copyBuf, "-- load via partition root %s",
2718  copyFrom);
2719  tdDefn = pg_strdup(copyBuf->data);
2720  }
2721  else
2722  copyFrom = fmtQualifiedDumpable(tbinfo);
2723 
2724  if (dopt->dump_inserts == 0)
2725  {
2726  /* Dump/restore using COPY */
2727  dumpFn = dumpTableData_copy;
2728  /* must use 2 steps here 'cause fmtId is nonreentrant */
2729  printfPQExpBuffer(copyBuf, "COPY %s ",
2730  copyFrom);
2731  appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
2732  fmtCopyColumnList(tbinfo, clistBuf));
2733  copyStmt = copyBuf->data;
2734  }
2735  else
2736  {
2737  /* Restore using INSERT */
2738  dumpFn = dumpTableData_insert;
2739  copyStmt = NULL;
2740  }
2741 
2742  /*
2743  * Note: although the TableDataInfo is a full DumpableObject, we treat its
2744  * dependency on its table as "special" and pass it to ArchiveEntry now.
2745  * See comments for BuildArchiveDependencies.
2746  */
2747  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2748  {
2749  TocEntry *te;
2750 
2751  te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
2752  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2753  .namespace = tbinfo->dobj.namespace->dobj.name,
2754  .owner = tbinfo->rolname,
2755  .description = "TABLE DATA",
2756  .section = SECTION_DATA,
2757  .createStmt = tdDefn,
2758  .copyStmt = copyStmt,
2759  .deps = &(tbinfo->dobj.dumpId),
2760  .nDeps = 1,
2761  .dumpFn = dumpFn,
2762  .dumpArg = tdinfo));
2763 
2764  /*
2765  * Set the TocEntry's dataLength in case we are doing a parallel dump
2766  * and want to order dump jobs by table size. We choose to measure
2767  * dataLength in table pages (including TOAST pages) during dump, so
2768  * no scaling is needed.
2769  *
2770  * However, relpages is declared as "integer" in pg_class, and hence
2771  * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
2772  * Cast so that we get the right interpretation of table sizes
2773  * exceeding INT_MAX pages.
2774  */
2775  te->dataLength = (BlockNumber) tbinfo->relpages;
2776  te->dataLength += (BlockNumber) tbinfo->toastpages;
2777 
2778  /*
2779  * If pgoff_t is only 32 bits wide, the above refinement is useless,
2780  * and instead we'd better worry about integer overflow. Clamp to
2781  * INT_MAX if the correct result exceeds that.
2782  */
2783  if (sizeof(te->dataLength) == 4 &&
2784  (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
2785  te->dataLength < 0))
2786  te->dataLength = INT_MAX;
2787  }
2788 
2789  destroyPQExpBuffer(copyBuf);
2790  destroyPQExpBuffer(clistBuf);
2791 }
uint32 BlockNumber
Definition: block.h:31
int(* DataDumperPtr)(Archive *AH, const void *userArg)
Definition: pg_backup.h:279
static bool forcePartitionRootLoad(const TableInfo *tbinfo)
Definition: pg_dump.c:2661
static int dumpTableData_copy(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2199
static const char * fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
Definition: pg_dump.c:19141
static int dumpTableData_insert(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2367
static TableInfo * getRootTableInfo(const TableInfo *tbinfo)
Definition: pg_dump.c:2636
int dump_inserts
Definition: pg_backup.h:175
int load_via_partition_root
Definition: pg_backup.h:193
bool interesting
Definition: pg_dump.h:320
int toastpages
Definition: pg_dump.h:318
int relpages
Definition: pg_dump.h:317

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), Assert, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _tocEntry::dataLength, destroyPQExpBuffer(), _tableInfo::dobj, _tableDataInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DATA, _dumpOptions::dump_inserts, _dumpableObject::dumpId, dumpTableData_copy(), dumpTableData_insert(), fmtCopyColumnList(), fmtQualifiedDumpable, forcePartitionRootLoad(), getRootTableInfo(), _tableInfo::interesting, _tableInfo::ispartition, _dumpOptions::load_via_partition_root, _dumpableObject::name, pg_strdup(), printfPQExpBuffer(), _tableInfo::relpages, _tableInfo::rolname, SECTION_DATA, _tableDataInfo::tdtable, and _tableInfo::toastpages.

Referenced by dumpDumpableObject().

◆ dumpTableData_copy()

static int dumpTableData_copy ( Archive fout,
const void *  dcontext 
)
static

Definition at line 2199 of file pg_dump.c.

2200 {
2201  TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2202  TableInfo *tbinfo = tdinfo->tdtable;
2203  const char *classname = tbinfo->dobj.name;
2205 
2206  /*
2207  * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
2208  * which uses it already.
2209  */
2210  PQExpBuffer clistBuf = createPQExpBuffer();
2211  PGconn *conn = GetConnection(fout);
2212  PGresult *res;
2213  int ret;
2214  char *copybuf;
2215  const char *column_list;
2216 
2217  pg_log_info("dumping contents of table \"%s.%s\"",
2218  tbinfo->dobj.namespace->dobj.name, classname);
2219 
2220  /*
2221  * Specify the column list explicitly so that we have no possibility of
2222  * retrieving data in the wrong column order. (The default column
2223  * ordering of COPY will not be what we want in certain corner cases
2224  * involving ADD COLUMN and inheritance.)
2225  */
2226  column_list = fmtCopyColumnList(tbinfo, clistBuf);
2227 
2228  /*
2229  * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
2230  * a filter condition was specified. For other cases a simple COPY
2231  * suffices.
2232  */
2233  if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2234  {
2235  /* Temporary allows to access to foreign tables to dump data */
2236  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2237  set_restrict_relation_kind(fout, "view");
2238 
2239  appendPQExpBufferStr(q, "COPY (SELECT ");
2240  /* klugery to get rid of parens in column list */
2241  if (strlen(column_list) > 2)
2242  {
2243  appendPQExpBufferStr(q, column_list + 1);
2244  q->data[q->len - 1] = ' ';
2245  }
2246  else
2247  appendPQExpBufferStr(q, "* ");
2248 
2249  appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
2250  fmtQualifiedDumpable(tbinfo),
2251  tdinfo->filtercond ? tdinfo->filtercond : "");
2252  }
2253  else
2254  {
2255  appendPQExpBuffer(q, "COPY %s %s TO stdout;",
2256  fmtQualifiedDumpable(tbinfo),
2257  column_list);
2258  }
2259  res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
2260  PQclear(res);
2261  destroyPQExpBuffer(clistBuf);
2262 
2263  for (;;)
2264  {
2265  ret = PQgetCopyData(conn, &copybuf, 0);
2266 
2267  if (ret < 0)
2268  break; /* done or error */
2269 
2270  if (copybuf)
2271  {
2272  WriteData(fout, copybuf, ret);
2273  PQfreemem(copybuf);
2274  }
2275 
2276  /* ----------
2277  * THROTTLE:
2278  *
2279  * There was considerable discussion in late July, 2000 regarding
2280  * slowing down pg_dump when backing up large tables. Users with both
2281  * slow & fast (multi-processor) machines experienced performance
2282  * degradation when doing a backup.
2283  *
2284  * Initial attempts based on sleeping for a number of ms for each ms
2285  * of work were deemed too complex, then a simple 'sleep in each loop'
2286  * implementation was suggested. The latter failed because the loop
2287  * was too tight. Finally, the following was implemented:
2288  *
2289  * If throttle is non-zero, then
2290  * See how long since the last sleep.
2291  * Work out how long to sleep (based on ratio).
2292  * If sleep is more than 100ms, then
2293  * sleep
2294  * reset timer
2295  * EndIf
2296  * EndIf
2297  *
2298  * where the throttle value was the number of ms to sleep per ms of
2299  * work. The calculation was done in each loop.
2300  *
2301  * Most of the hard work is done in the backend, and this solution
2302  * still did not work particularly well: on slow machines, the ratio
2303  * was 50:1, and on medium paced machines, 1:1, and on fast
2304  * multi-processor machines, it had little or no effect, for reasons
2305  * that were unclear.
2306  *
2307  * Further discussion ensued, and the proposal was dropped.
2308  *
2309  * For those people who want this feature, it can be implemented using
2310  * gettimeofday in each loop, calculating the time since last sleep,
2311  * multiplying that by the sleep ratio, then if the result is more
2312  * than a preset 'minimum sleep time' (say 100ms), call the 'select'
2313  * function to sleep for a subsecond period ie.
2314  *
2315  * select(0, NULL, NULL, NULL, &tvi);
2316  *
2317  * This will return after the interval specified in the structure tvi.
2318  * Finally, call gettimeofday again to save the 'last sleep time'.
2319  * ----------
2320  */
2321  }
2322  archprintf(fout, "\\.\n\n\n");
2323 
2324  if (ret == -2)
2325  {
2326  /* copy data transfer failed */
2327  pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
2328  pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2329  pg_log_error_detail("Command was: %s", q->data);
2330  exit_nicely(1);
2331  }
2332 
2333  /* Check command status and return to normal libpq state */
2334  res = PQgetResult(conn);
2336  {
2337  pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
2338  pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2339  pg_log_error_detail("Command was: %s", q->data);
2340  exit_nicely(1);
2341  }
2342  PQclear(res);
2343 
2344  /* Do this to ensure we've pumped libpq back to idle state */
2345  if (PQgetResult(conn) != NULL)
2346  pg_log_warning("unexpected extra results during COPY of table \"%s\"",
2347  classname);
2348 
2349  destroyPQExpBuffer(q);
2350 
2351  /* Revert back the setting */
2352  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2353  set_restrict_relation_kind(fout, "view, foreign-table");
2354 
2355  return 1;
2356 }
void PQfreemem(void *ptr)
Definition: fe-exec.c:4032
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2062
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2816
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:120
@ PGRES_COPY_OUT
Definition: libpq-fe.h:126
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_detail(...)
Definition: logging.h:109
int archprintf(Archive *AH, const char *fmt,...) pg_attribute_printf(2
static void set_restrict_relation_kind(Archive *AH, const char *value)
Definition: pg_dump.c:4819
#define exit_nicely(code)
Definition: pg_dumpall.c:124
char * filtercond
Definition: pg_dump.h:391
static StringInfo copybuf
Definition: tablesync.c:137

References appendPQExpBuffer(), appendPQExpBufferStr(), archprintf(), conn, copybuf, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, ExecuteSqlQuery(), exit_nicely, _tableDataInfo::filtercond, fmtCopyColumnList(), fmtQualifiedDumpable, GetConnection(), PQExpBufferData::len, _dumpableObject::name, pg_log_error, pg_log_error_detail, pg_log_info, pg_log_warning, PGRES_COMMAND_OK, PGRES_COPY_OUT, PQclear(), PQerrorMessage(), PQfreemem(), PQgetCopyData(), PQgetResult(), PQresultStatus(), _tableInfo::relkind, res, set_restrict_relation_kind(), _tableDataInfo::tdtable, and WriteData().

Referenced by dumpTableData().

◆ dumpTableData_insert()

static int dumpTableData_insert ( Archive fout,
const void *  dcontext 
)
static

Definition at line 2367 of file pg_dump.c.

2368 {
2369  TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2370  TableInfo *tbinfo = tdinfo->tdtable;
2371  DumpOptions *dopt = fout->dopt;
2373  PQExpBuffer insertStmt = NULL;
2374  char *attgenerated;
2375  PGresult *res;
2376  int nfields,
2377  i;
2378  int rows_per_statement = dopt->dump_inserts;
2379  int rows_this_statement = 0;
2380 
2381  /* Temporary allows to access to foreign tables to dump data */
2382  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2383  set_restrict_relation_kind(fout, "view");
2384 
2385  /*
2386  * If we're going to emit INSERTs with column names, the most efficient
2387  * way to deal with generated columns is to exclude them entirely. For
2388  * INSERTs without column names, we have to emit DEFAULT rather than the
2389  * actual column value --- but we can save a few cycles by fetching nulls
2390  * rather than the uninteresting-to-us value.
2391  */
2392  attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
2393  appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
2394  nfields = 0;
2395  for (i = 0; i < tbinfo->numatts; i++)
2396  {
2397  if (tbinfo->attisdropped[i])
2398  continue;
2399  if (tbinfo->attgenerated[i] && dopt->column_inserts)
2400  continue;
2401  if (nfields > 0)
2402  appendPQExpBufferStr(q, ", ");
2403  if (tbinfo->attgenerated[i])
2404  appendPQExpBufferStr(q, "NULL");
2405  else
2406  appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
2407  attgenerated[nfields] = tbinfo->attgenerated[i];
2408  nfields++;
2409  }
2410  /* Servers before 9.4 will complain about zero-column SELECT */
2411  if (nfields == 0)
2412  appendPQExpBufferStr(q, "NULL");
2413  appendPQExpBuffer(q, " FROM ONLY %s",
2414  fmtQualifiedDumpable(tbinfo));
2415  if (tdinfo->filtercond)
2416  appendPQExpBuffer(q, " %s", tdinfo->filtercond);
2417 
2418  ExecuteSqlStatement(fout, q->data);
2419 
2420  while (1)
2421  {
2422  res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
2423  PGRES_TUPLES_OK);
2424 
2425  /* cross-check field count, allowing for dummy NULL if any */
2426  if (nfields != PQnfields(res) &&
2427  !(nfields == 0 && PQnfields(res) == 1))
2428  pg_fatal("wrong number of fields retrieved from table \"%s\"",
2429  tbinfo->dobj.name);
2430 
2431  /*
2432  * First time through, we build as much of the INSERT statement as
2433  * possible in "insertStmt", which we can then just print for each
2434  * statement. If the table happens to have zero dumpable columns then
2435  * this will be a complete statement, otherwise it will end in
2436  * "VALUES" and be ready to have the row's column values printed.
2437  */
2438  if (insertStmt == NULL)
2439  {
2440  TableInfo *targettab;
2441 
2442  insertStmt = createPQExpBuffer();
2443 
2444  /*
2445  * When load-via-partition-root is set or forced, get the root
2446  * table name for the partition table, so that we can reload data
2447  * through the root table.
2448  */
2449  if (tbinfo->ispartition &&
2450  (dopt->load_via_partition_root ||
2451  forcePartitionRootLoad(tbinfo)))
2452  targettab = getRootTableInfo(tbinfo);
2453  else
2454  targettab = tbinfo;
2455 
2456  appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
2457  fmtQualifiedDumpable(targettab));
2458 
2459  /* corner case for zero-column table */
2460  if (nfields == 0)
2461  {
2462  appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
2463  }
2464  else
2465  {
2466  /* append the list of column names if required */
2467  if (dopt->column_inserts)
2468  {
2469  appendPQExpBufferChar(insertStmt, '(');
2470  for (int field = 0; field < nfields; field++)
2471  {
2472  if (field > 0)
2473  appendPQExpBufferStr(insertStmt, ", ");
2474  appendPQExpBufferStr(insertStmt,
2475  fmtId(PQfname(res, field)));
2476  }
2477  appendPQExpBufferStr(insertStmt, ") ");
2478  }
2479 
2480  if (tbinfo->needs_override)
2481  appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
2482 
2483  appendPQExpBufferStr(insertStmt, "VALUES");
2484  }
2485  }
2486 
2487  for (int tuple = 0; tuple < PQntuples(res); tuple++)
2488  {
2489  /* Write the INSERT if not in the middle of a multi-row INSERT. */
2490  if (rows_this_statement == 0)
2491  archputs(insertStmt->data, fout);
2492 
2493  /*
2494  * If it is zero-column table then we've already written the
2495  * complete statement, which will mean we've disobeyed
2496  * --rows-per-insert when it's set greater than 1. We do support
2497  * a way to make this multi-row with: SELECT UNION ALL SELECT
2498  * UNION ALL ... but that's non-standard so we should avoid it
2499  * given that using INSERTs is mostly only ever needed for
2500  * cross-database exports.
2501  */
2502  if (nfields == 0)
2503  continue;
2504 
2505  /* Emit a row heading */
2506  if (rows_per_statement == 1)
2507  archputs(" (", fout);
2508  else if (rows_this_statement > 0)
2509  archputs(",\n\t(", fout);
2510  else
2511  archputs("\n\t(", fout);
2512 
2513  for (int field = 0; field < nfields; field++)
2514  {
2515  if (field > 0)
2516  archputs(", ", fout);
2517  if (attgenerated[field])
2518  {
2519  archputs("DEFAULT", fout);
2520  continue;
2521  }
2522  if (PQgetisnull(res, tuple, field))
2523  {
2524  archputs("NULL", fout);
2525  continue;
2526  }
2527 
2528  /* XXX This code is partially duplicated in ruleutils.c */
2529  switch (PQftype(res, field))
2530  {
2531  case INT2OID:
2532  case INT4OID:
2533  case INT8OID:
2534  case OIDOID:
2535  case FLOAT4OID:
2536  case FLOAT8OID:
2537  case NUMERICOID:
2538  {
2539  /*
2540  * These types are printed without quotes unless
2541  * they contain values that aren't accepted by the
2542  * scanner unquoted (e.g., 'NaN'). Note that
2543  * strtod() and friends might accept NaN, so we
2544  * can't use that to test.
2545  *
2546  * In reality we only need to defend against
2547  * infinity and NaN, so we need not get too crazy
2548  * about pattern matching here.
2549  */
2550  const char *s = PQgetvalue(res, tuple, field);
2551 
2552  if (strspn(s, "0123456789 +-eE.") == strlen(s))
2553  archputs(s, fout);
2554  else
2555  archprintf(fout, "'%s'", s);
2556  }
2557  break;
2558 
2559  case BITOID:
2560  case VARBITOID:
2561  archprintf(fout, "B'%s'",
2562  PQgetvalue(res, tuple, field));
2563  break;
2564 
2565  case BOOLOID:
2566  if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
2567  archputs("true", fout);
2568  else
2569  archputs("false", fout);
2570  break;
2571 
2572  default:
2573  /* All other types are printed as string literals. */
2574  resetPQExpBuffer(q);
2576  PQgetvalue(res, tuple, field),
2577  fout);
2578  archputs(q->data, fout);
2579  break;
2580  }
2581  }
2582 
2583  /* Terminate the row ... */
2584  archputs(")", fout);
2585 
2586  /* ... and the statement, if the target no. of rows is reached */
2587  if (++rows_this_statement >= rows_per_statement)
2588  {
2589  if (dopt->do_nothing)
2590  archputs(" ON CONFLICT DO NOTHING;\n", fout);
2591  else
2592  archputs(";\n", fout);
2593  /* Reset the row counter */
2594  rows_this_statement = 0;
2595  }
2596  }
2597 
2598  if (PQntuples(res) <= 0)
2599  {
2600  PQclear(res);
2601  break;
2602  }
2603  PQclear(res);
2604  }
2605 
2606  /* Terminate any statements that didn't make the row count. */
2607  if (rows_this_statement > 0)
2608  {
2609  if (dopt->do_nothing)
2610  archputs(" ON CONFLICT DO NOTHING;\n", fout);
2611  else
2612  archputs(";\n", fout);
2613  }
2614 
2615  archputs("\n\n", fout);
2616 
2617  ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
2618 
2619  destroyPQExpBuffer(q);
2620  if (insertStmt != NULL)
2621  destroyPQExpBuffer(insertStmt);
2622  free(attgenerated);
2623 
2624  /* Revert back the setting */
2625  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2626  set_restrict_relation_kind(fout, "view, foreign-table");
2627 
2628  return 1;
2629 }
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3719
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3567
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3489
void archputs(const char *s, Archive *AH)
int column_inserts
Definition: pg_backup.h:179
int do_nothing
Definition: pg_backup.h:206
char * attgenerated
Definition: pg_dump.h:341
bool * attisdropped
Definition: pg_dump.h:339
bool needs_override
Definition: pg_dump.h:358

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAH, archprintf(), archputs(), _tableInfo::attgenerated, _tableInfo::attisdropped, _tableInfo::attnames, _dumpOptions::column_inserts, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _dumpOptions::do_nothing, _tableInfo::dobj, Archive::dopt, _dumpOptions::dump_inserts, ExecuteSqlQuery(), ExecuteSqlStatement(), _tableDataInfo::filtercond, fmtId(), fmtQualifiedDumpable, forcePartitionRootLoad(), free, getRootTableInfo(), i, _tableInfo::ispartition, _dumpOptions::load_via_partition_root, _dumpableObject::name, _tableInfo::needs_override, _tableInfo::numatts, pg_fatal, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQfname(), PQftype(), PQgetisnull(), PQgetvalue(), PQnfields(), PQntuples(), _tableInfo::relkind, res, resetPQExpBuffer(), set_restrict_relation_kind(), and _tableDataInfo::tdtable.

Referenced by dumpTableData().

◆ dumpTableSchema()

static void dumpTableSchema ( Archive fout,
const TableInfo tbinfo 
)
static

Definition at line 15933 of file pg_dump.c.

15934 {
15935  DumpOptions *dopt = fout->dopt;
15937  PQExpBuffer delq = createPQExpBuffer();
15938  PQExpBuffer extra = createPQExpBuffer();
15939  char *qrelname;
15940  char *qualrelname;
15941  int numParents;
15942  TableInfo **parents;
15943  int actual_atts; /* number of attrs in this CREATE statement */
15944  const char *reltypename;
15945  char *storage;
15946  int j,
15947  k;
15948 
15949  /* We had better have loaded per-column details about this table */
15950  Assert(tbinfo->interesting);
15951 
15952  qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
15953  qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
15954 
15955  if (tbinfo->hasoids)
15956  pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
15957  qrelname);
15958 
15959  if (dopt->binary_upgrade)
15960  binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
15961 
15962  /* Is it a table or a view? */
15963  if (tbinfo->relkind == RELKIND_VIEW)
15964  {
15965  PQExpBuffer result;
15966 
15967  /*
15968  * Note: keep this code in sync with the is_view case in dumpRule()
15969  */
15970 
15971  reltypename = "VIEW";
15972 
15973  appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
15974 
15975  if (dopt->binary_upgrade)
15977  tbinfo->dobj.catId.oid);
15978 
15979  appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
15980 
15981  if (tbinfo->dummy_view)
15982  result = createDummyViewAsClause(fout, tbinfo);
15983  else
15984  {
15985  if (nonemptyReloptions(tbinfo->reloptions))
15986  {
15987  appendPQExpBufferStr(q, " WITH (");
15988  appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
15989  appendPQExpBufferChar(q, ')');
15990  }
15991  result = createViewAsClause(fout, tbinfo);
15992  }
15993  appendPQExpBuffer(q, " AS\n%s", result->data);
15994  destroyPQExpBuffer(result);
15995 
15996  if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
15997  appendPQExpBuffer(q, "\n WITH %s CHECK OPTION", tbinfo->checkoption);
15998  appendPQExpBufferStr(q, ";\n");
15999  }
16000  else
16001  {
16002  char *partkeydef = NULL;
16003  char *ftoptions = NULL;
16004  char *srvname = NULL;
16005  const char *foreign = "";
16006 
16007  /*
16008  * Set reltypename, and collect any relkind-specific data that we
16009  * didn't fetch during getTables().
16010  */
16011  switch (tbinfo->relkind)
16012  {
16013  case RELKIND_PARTITIONED_TABLE:
16014  {
16015  PQExpBuffer query = createPQExpBuffer();
16016  PGresult *res;
16017 
16018  reltypename = "TABLE";
16019 
16020  /* retrieve partition key definition */
16021  appendPQExpBuffer(query,
16022  "SELECT pg_get_partkeydef('%u')",
16023  tbinfo->dobj.catId.oid);
16024  res = ExecuteSqlQueryForSingleRow(fout, query->data);
16025  partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
16026  PQclear(res);
16027  destroyPQExpBuffer(query);
16028  break;
16029  }
16030  case RELKIND_FOREIGN_TABLE:
16031  {
16032  PQExpBuffer query = createPQExpBuffer();
16033  PGresult *res;
16034  int i_srvname;
16035  int i_ftoptions;
16036 
16037  reltypename = "FOREIGN TABLE";
16038 
16039  /* retrieve name of foreign server and generic options */
16040  appendPQExpBuffer(query,
16041  "SELECT fs.srvname, "
16042  "pg_catalog.array_to_string(ARRAY("
16043  "SELECT pg_catalog.quote_ident(option_name) || "
16044  "' ' || pg_catalog.quote_literal(option_value) "
16045  "FROM pg_catalog.pg_options_to_table(ftoptions) "
16046  "ORDER BY option_name"
16047  "), E',\n ') AS ftoptions "
16048  "FROM pg_catalog.pg_foreign_table ft "
16049  "JOIN pg_catalog.pg_foreign_server fs "
16050  "ON (fs.oid = ft.ftserver) "
16051  "WHERE ft.ftrelid = '%u'",
16052  tbinfo->dobj.catId.oid);
16053  res = ExecuteSqlQueryForSingleRow(fout, query->data);
16054  i_srvname = PQfnumber(res, "srvname");
16055  i_ftoptions = PQfnumber(res, "ftoptions");
16056  srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
16057  ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
16058  PQclear(res);
16059  destroyPQExpBuffer(query);
16060 
16061  foreign = "FOREIGN ";
16062  break;
16063  }
16064  case RELKIND_MATVIEW:
16065  reltypename = "MATERIALIZED VIEW";
16066  break;
16067  default:
16068  reltypename = "TABLE";
16069  break;
16070  }
16071 
16072  numParents = tbinfo->numParents;
16073  parents = tbinfo->parents;
16074 
16075  appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
16076 
16077  if (dopt->binary_upgrade)
16079  tbinfo->dobj.catId.oid);
16080 
16081  /*
16082  * PostgreSQL 18 has disabled UNLOGGED for partitioned tables, so
16083  * ignore it when dumping if it was set in this case.
16084  */
16085  appendPQExpBuffer(q, "CREATE %s%s %s",
16086  (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
16087  tbinfo->relkind != RELKIND_PARTITIONED_TABLE) ?
16088  "UNLOGGED " : "",
16089  reltypename,
16090  qualrelname);
16091 
16092  /*
16093  * Attach to type, if reloftype; except in case of a binary upgrade,
16094  * we dump the table normally and attach it to the type afterward.
16095  */
16096  if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
16097  appendPQExpBuffer(q, " OF %s",
16098  getFormattedTypeName(fout, tbinfo->reloftype,
16099  zeroIsError));
16100 
16101  if (tbinfo->relkind != RELKIND_MATVIEW)
16102  {
16103  /* Dump the attributes */
16104  actual_atts = 0;
16105  for (j = 0; j < tbinfo->numatts; j++)
16106  {
16107  /*
16108  * Normally, dump if it's locally defined in this table, and
16109  * not dropped. But for binary upgrade, we'll dump all the
16110  * columns, and then fix up the dropped and nonlocal cases
16111  * below.
16112  */
16113  if (shouldPrintColumn(dopt, tbinfo, j))
16114  {
16115  bool print_default;
16116  bool print_notnull;
16117 
16118  /*
16119  * Default value --- suppress if to be printed separately
16120  * or not at all.
16121  */
16122  print_default = (tbinfo->attrdefs[j] != NULL &&
16123  tbinfo->attrdefs[j]->dobj.dump &&
16124  !tbinfo->attrdefs[j]->separate);
16125 
16126  /*
16127  * Not Null constraint --- print it if it is locally
16128  * defined, or if binary upgrade. (In the latter case, we
16129  * reset conislocal below.)
16130  */
16131  print_notnull = (tbinfo->notnull_constrs[j] != NULL &&
16132  (tbinfo->notnull_islocal[j] ||
16133  dopt->binary_upgrade ||
16134  tbinfo->ispartition));
16135 
16136  /*
16137  * Skip column if fully defined by reloftype, except in
16138  * binary upgrade
16139  */
16140  if (OidIsValid(tbinfo->reloftype) &&
16141  !print_default && !print_notnull &&
16142  !dopt->binary_upgrade)
16143  continue;
16144 
16145  /* Format properly if not first attr */
16146  if (actual_atts == 0)
16147  appendPQExpBufferStr(q, " (");
16148  else
16149  appendPQExpBufferChar(q, ',');
16150  appendPQExpBufferStr(q, "\n ");
16151  actual_atts++;
16152 
16153  /* Attribute name */
16154  appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
16155 
16156  if (tbinfo->attisdropped[j])
16157  {
16158  /*
16159  * ALTER TABLE DROP COLUMN clears
16160  * pg_attribute.atttypid, so we will not have gotten a
16161  * valid type name; insert INTEGER as a stopgap. We'll
16162  * clean things up later.
16163  */
16164  appendPQExpBufferStr(q, " INTEGER /* dummy */");
16165  /* and skip to the next column */
16166  continue;
16167  }
16168 
16169  /*
16170  * Attribute type; print it except when creating a typed
16171  * table ('OF type_name'), but in binary-upgrade mode,
16172  * print it in that case too.
16173  */
16174  if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
16175  {
16176  appendPQExpBuffer(q, " %s",
16177  tbinfo->atttypnames[j]);
16178  }
16179 
16180  if (print_default)
16181  {
16182  if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
16183  appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
16184  tbinfo->attrdefs[j]->adef_expr);
16185  else
16186  appendPQExpBuffer(q, " DEFAULT %s",
16187  tbinfo->attrdefs[j]->adef_expr);
16188  }
16189 
16190  print_notnull = (tbinfo->notnull_constrs[j] != NULL &&
16191  (tbinfo->notnull_islocal[j] ||
16192  dopt->binary_upgrade ||
16193  tbinfo->ispartition));
16194 
16195  if (print_notnull)
16196  {
16197  if (tbinfo->notnull_constrs[j][0] == '\0')
16198  appendPQExpBufferStr(q, " NOT NULL");
16199  else
16200  appendPQExpBuffer(q, " CONSTRAINT %s NOT NULL",
16201  fmtId(tbinfo->notnull_constrs[j]));
16202 
16203  if (tbinfo->notnull_noinh[j])
16204  appendPQExpBufferStr(q, " NO INHERIT");
16205  }
16206 
16207  /* Add collation if not default for the type */
16208  if (OidIsValid(tbinfo->attcollation[j]))
16209  {
16210  CollInfo *coll;
16211 
16212  coll = findCollationByOid(tbinfo->attcollation[j]);
16213  if (coll)
16214  appendPQExpBuffer(q, " COLLATE %s",
16215  fmtQualifiedDumpable(coll));
16216  }
16217  }
16218  }
16219 
16220  /*
16221  * Add non-inherited CHECK constraints, if any.
16222  *
16223  * For partitions, we need to include check constraints even if
16224  * they're not defined locally, because the ALTER TABLE ATTACH
16225  * PARTITION that we'll emit later expects the constraint to be
16226  * there. (No need to fix conislocal: ATTACH PARTITION does that)
16227  */
16228  for (j = 0; j < tbinfo->ncheck; j++)
16229  {
16230  ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
16231 
16232  if (constr->separate ||
16233  (!constr->conislocal && !tbinfo->ispartition))
16234  continue;
16235 
16236  if (actual_atts == 0)
16237  appendPQExpBufferStr(q, " (\n ");
16238  else
16239  appendPQExpBufferStr(q, ",\n ");
16240 
16241  appendPQExpBuffer(q, "CONSTRAINT %s ",
16242  fmtId(constr->dobj.name));
16243  appendPQExpBufferStr(q, constr->condef);
16244 
16245  actual_atts++;
16246  }
16247 
16248  if (actual_atts)
16249  appendPQExpBufferStr(q, "\n)");
16250  else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
16251  {
16252  /*
16253  * No attributes? we must have a parenthesized attribute list,
16254  * even though empty, when not using the OF TYPE syntax.
16255  */
16256  appendPQExpBufferStr(q, " (\n)");
16257  }
16258 
16259  /*
16260  * Emit the INHERITS clause (not for partitions), except in
16261  * binary-upgrade mode.
16262  */
16263  if (numParents > 0 && !tbinfo->ispartition &&
16264  !dopt->binary_upgrade)
16265  {
16266  appendPQExpBufferStr(q, "\nINHERITS (");
16267  for (k = 0; k < numParents; k++)
16268  {
16269  TableInfo *parentRel = parents[k];
16270 
16271  if (k > 0)
16272  appendPQExpBufferStr(q, ", ");
16274  }
16275  appendPQExpBufferChar(q, ')');
16276  }
16277 
16278  if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
16279  appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
16280 
16281  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
16282  appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
16283  }
16284 
16285  if (nonemptyReloptions(tbinfo->reloptions) ||
16287  {
16288  bool addcomma = false;
16289 
16290  appendPQExpBufferStr(q, "\nWITH (");
16291  if (nonemptyReloptions(tbinfo->reloptions))
16292  {
16293  addcomma = true;
16294  appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
16295  }
16296  if (nonemptyReloptions(tbinfo->toast_reloptions))
16297  {
16298  if (addcomma)
16299  appendPQExpBufferStr(q, ", ");
16300  appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
16301  fout);
16302  }
16303  appendPQExpBufferChar(q, ')');
16304  }
16305 
16306  /* Dump generic options if any */
16307  if (ftoptions && ftoptions[0])
16308  appendPQExpBuffer(q, "\nOPTIONS (\n %s\n)", ftoptions);
16309 
16310  /*
16311  * For materialized views, create the AS clause just like a view. At
16312  * this point, we always mark the view as not populated.
16313  */
16314  if (tbinfo->relkind == RELKIND_MATVIEW)
16315  {
16316  PQExpBuffer result;
16317 
16318  result = createViewAsClause(fout, tbinfo);
16319  appendPQExpBuffer(q, " AS\n%s\n WITH NO DATA;\n",
16320  result->data);
16321  destroyPQExpBuffer(result);
16322  }
16323  else
16324  appendPQExpBufferStr(q, ";\n");
16325 
16326  /* Materialized views can depend on extensions */
16327  if (tbinfo->relkind == RELKIND_MATVIEW)
16328  append_depends_on_extension(fout, q, &tbinfo->dobj,
16329  "pg_catalog.pg_class",
16330  "MATERIALIZED VIEW",
16331  qualrelname);
16332 
16333  /*
16334  * in binary upgrade mode, update the catalog with any missing values
16335  * that might be present.
16336  */
16337  if (dopt->binary_upgrade)
16338  {
16339  for (j = 0; j < tbinfo->numatts; j++)
16340  {
16341  if (tbinfo->attmissingval[j][0] != '\0')
16342  {
16343  appendPQExpBufferStr(q, "\n-- set missing value.\n");
16345  "SELECT pg_catalog.binary_upgrade_set_missing_value(");
16346  appendStringLiteralAH(q, qualrelname, fout);
16347  appendPQExpBufferStr(q, "::pg_catalog.regclass,");
16348  appendStringLiteralAH(q, tbinfo->attnames[j], fout);
16349  appendPQExpBufferChar(q, ',');
16350  appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
16351  appendPQExpBufferStr(q, ");\n\n");
16352  }
16353  }
16354  }
16355 
16356  /*
16357  * To create binary-compatible heap files, we have to ensure the same
16358  * physical column order, including dropped columns, as in the
16359  * original. Therefore, we create dropped columns above and drop them
16360  * here, also updating their attlen/attalign values so that the
16361  * dropped column can be skipped properly. (We do not bother with
16362  * restoring the original attbyval setting.) Also, inheritance
16363  * relationships are set up by doing ALTER TABLE INHERIT rather than
16364  * using an INHERITS clause --- the latter would possibly mess up the
16365  * column order. That also means we have to take care about setting
16366  * attislocal correctly, plus fix up any inherited CHECK constraints.
16367  * Analogously, we set up typed tables using ALTER TABLE / OF here.
16368  *
16369  * We process foreign and partitioned tables here, even though they
16370  * lack heap storage, because they can participate in inheritance
16371  * relationships and we want this stuff to be consistent across the
16372  * inheritance tree. We can exclude indexes, toast tables, sequences
16373  * and matviews, even though they have storage, because we don't
16374  * support altering or dropping columns in them, nor can they be part
16375  * of inheritance trees.
16376  */
16377  if (dopt->binary_upgrade &&
16378  (tbinfo->relkind == RELKIND_RELATION ||
16379  tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
16380  tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
16381  {
16382  bool firstitem;
16383  bool firstitem_extra;
16384 
16385  /*
16386  * Drop any dropped columns. Merge the pg_attribute manipulations
16387  * into a single SQL command, so that we don't cause repeated
16388  * relcache flushes on the target table. Otherwise we risk O(N^2)
16389  * relcache bloat while dropping N columns.
16390  */
16391  resetPQExpBuffer(extra);
16392  firstitem = true;
16393  for (j = 0; j < tbinfo->numatts; j++)
16394  {
16395  if (tbinfo->attisdropped[j])
16396  {
16397  if (firstitem)
16398  {
16399  appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped columns.\n"
16400  "UPDATE pg_catalog.pg_attribute\n"
16401  "SET attlen = v.dlen, "
16402  "attalign = v.dalign, "
16403  "attbyval = false\n"
16404  "FROM (VALUES ");
16405  firstitem = false;
16406  }
16407  else
16408  appendPQExpBufferStr(q, ",\n ");
16409  appendPQExpBufferChar(q, '(');
16410  appendStringLiteralAH(q, tbinfo->attnames[j], fout);
16411  appendPQExpBuffer(q, ", %d, '%c')",
16412  tbinfo->attlen[j],
16413  tbinfo->attalign[j]);
16414  /* The ALTER ... DROP COLUMN commands must come after */
16415  appendPQExpBuffer(extra, "ALTER %sTABLE ONLY %s ",
16416  foreign, qualrelname);
16417  appendPQExpBuffer(extra, "DROP COLUMN %s;\n",
16418  fmtId(tbinfo->attnames[j]));
16419  }
16420  }
16421  if (!firstitem)
16422  {
16423  appendPQExpBufferStr(q, ") v(dname, dlen, dalign)\n"
16424  "WHERE attrelid = ");
16425  appendStringLiteralAH(q, qualrelname, fout);
16426  appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
16427  " AND attname = v.dname;\n");
16428  /* Now we can issue the actual DROP COLUMN commands */
16429  appendBinaryPQExpBuffer(q, extra->data, extra->len);
16430  }
16431 
16432  /*
16433  * Fix up inherited columns. As above, do the pg_attribute
16434  * manipulations in a single SQL command.
16435  */
16436  firstitem = true;
16437  for (j = 0; j < tbinfo->numatts; j++)
16438  {
16439  if (!tbinfo->attisdropped[j] &&
16440  !tbinfo->attislocal[j])
16441  {
16442  if (firstitem)
16443  {
16444  appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited columns.\n");
16445  appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
16446  "SET attislocal = false\n"
16447  "WHERE attrelid = ");
16448  appendStringLiteralAH(q, qualrelname, fout);
16449  appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
16450  " AND attname IN (");
16451  firstitem = false;
16452  }
16453  else
16454  appendPQExpBufferStr(q, ", ");
16455  appendStringLiteralAH(q, tbinfo->attnames[j], fout);
16456  }
16457  }
16458  if (!firstitem)
16459  appendPQExpBufferStr(q, ");\n");
16460 
16461  /*
16462  * Fix up not-null constraints that come from inheritance. As
16463  * above, do the pg_constraint manipulations in a single SQL
16464  * command. (Actually, two in special cases, if we're doing an
16465  * upgrade from < 18).
16466  */
16467  firstitem = true;
16468  firstitem_extra = true;
16469  resetPQExpBuffer(extra);
16470  for (j = 0; j < tbinfo->numatts; j++)
16471  {
16472  /*
16473  * If a not-null constraint comes from inheritance, reset
16474  * conislocal. The inhcount is fixed by ALTER TABLE INHERIT,
16475  * below. Special hack: in versions < 18, columns with no
16476  * local definition need their constraint to be matched by
16477  * column number in conkeys instead of by contraint name,
16478  * because the latter is not available. (We distinguish the
16479  * case because the constraint name is the empty string.)
16480  */
16481  if (tbinfo->notnull_constrs[j] != NULL &&
16482  !tbinfo->notnull_islocal[j])
16483  {
16484  if (tbinfo->notnull_constrs[j][0] != '\0')
16485  {
16486  if (firstitem)
16487  {
16488  appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
16489  "SET conislocal = false\n"
16490  "WHERE contype = 'n' AND conrelid = ");
16491  appendStringLiteralAH(q, qualrelname, fout);
16492  appendPQExpBufferStr(q, "::pg_catalog.regclass AND\n"
16493  "conname IN (");
16494  firstitem = false;
16495  }
16496  else
16497  appendPQExpBufferStr(q, ", ");
16498  appendStringLiteralAH(q, tbinfo->notnull_constrs[j], fout);
16499  }
16500  else
16501  {
16502  if (firstitem_extra)
16503  {
16504  appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
16505  "SET conislocal = false\n"
16506  "WHERE contype = 'n' AND conrelid = ");
16507  appendStringLiteralAH(extra, qualrelname, fout);
16508  appendPQExpBufferStr(extra, "::pg_catalog.regclass AND\n"
16509  "conkey IN (");
16510  firstitem_extra = false;
16511  }
16512  else
16513  appendPQExpBufferStr(extra, ", ");
16514  appendPQExpBuffer(extra, "'{%d}'", j + 1);
16515  }
16516  }
16517  }
16518  if (!firstitem)
16519  appendPQExpBufferStr(q, ");\n");
16520  if (!firstitem_extra)
16521  appendPQExpBufferStr(extra, ");\n");
16522 
16523  if (extra->len > 0)
16524  appendBinaryPQExpBuffer(q, extra->data, extra->len);
16525 
16526  /*
16527  * Add inherited CHECK constraints, if any.
16528  *
16529  * For partitions, they were already dumped, and conislocal
16530  * doesn't need fixing.
16531  *
16532  * As above, issue only one direct manipulation of pg_constraint.
16533  * Although it is tempting to merge the ALTER ADD CONSTRAINT
16534  * commands into one as well, refrain for now due to concern about
16535  * possible backend memory bloat if there are many such
16536  * constraints.
16537  */
16538  resetPQExpBuffer(extra);
16539  firstitem = true;
16540  for (k = 0; k < tbinfo->ncheck; k++)
16541  {
16542  ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
16543 
16544  if (constr->separate || constr->conislocal || tbinfo->ispartition)
16545  continue;
16546 
16547  if (firstitem)
16548  appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraints.\n");
16549  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
16550  foreign, qualrelname,
16551  fmtId(constr->dobj.name),
16552  constr->condef);
16553  /* Update pg_constraint after all the ALTER TABLEs */
16554  if (firstitem)
16555  {
16556  appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
16557  "SET conislocal = false\n"
16558  "WHERE contype = 'c' AND conrelid = ");
16559  appendStringLiteralAH(extra, qualrelname, fout);
16560  appendPQExpBufferStr(extra, "::pg_catalog.regclass\n");
16561  appendPQExpBufferStr(extra, " AND conname IN (");
16562  firstitem = false;
16563  }
16564  else
16565  appendPQExpBufferStr(extra, ", ");
16566  appendStringLiteralAH(extra, constr->dobj.name, fout);
16567  }
16568  if (!firstitem)
16569  {
16570  appendPQExpBufferStr(extra, ");\n");
16571  appendBinaryPQExpBuffer(q, extra->data, extra->len);
16572  }
16573 
16574  if (numParents > 0 && !tbinfo->ispartition)
16575  {
16576  appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
16577  for (k = 0; k < numParents; k++)
16578  {
16579  TableInfo *parentRel = parents[k];
16580 
16581  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
16582  qualrelname,
16583  fmtQualifiedDumpable(parentRel));
16584  }
16585  }
16586 
16587  if (OidIsValid(tbinfo->reloftype))
16588  {
16589  appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
16590  appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
16591  qualrelname,
16592  getFormattedTypeName(fout, tbinfo->reloftype,
16593  zeroIsError));
16594  }
16595  }
16596 
16597  /*
16598  * In binary_upgrade mode, arrange to restore the old relfrozenxid and
16599  * relminmxid of all vacuumable relations. (While vacuum.c processes
16600  * TOAST tables semi-independently, here we see them only as children
16601  * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
16602  * child toast table is handled below.)
16603  */
16604  if (dopt->binary_upgrade &&
16605  (tbinfo->relkind == RELKIND_RELATION ||
16606  tbinfo->relkind == RELKIND_MATVIEW))
16607  {
16608  appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
16609  appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
16610  "SET relfrozenxid = '%u', relminmxid = '%u'\n"
16611  "WHERE oid = ",
16612  tbinfo->frozenxid, tbinfo->minmxid);
16613  appendStringLiteralAH(q, qualrelname, fout);
16614  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16615 
16616  if (tbinfo->toast_oid)
16617  {
16618  /*
16619  * The toast table will have the same OID at restore, so we
16620  * can safely target it by OID.
16621  */
16622  appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
16623  appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
16624  "SET relfrozenxid = '%u', relminmxid = '%u'\n"
16625  "WHERE oid = '%u';\n",
16626  tbinfo->toast_frozenxid,
16627  tbinfo->toast_minmxid, tbinfo->toast_oid);
16628  }
16629  }
16630 
16631  /*
16632  * In binary_upgrade mode, restore matviews' populated status by
16633  * poking pg_class directly. This is pretty ugly, but we can't use
16634  * REFRESH MATERIALIZED VIEW since it's possible that some underlying
16635  * matview is not populated even though this matview is; in any case,
16636  * we want to transfer the matview's heap storage, not run REFRESH.
16637  */
16638  if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
16639  tbinfo->relispopulated)
16640  {
16641  appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
16642  appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
16643  "SET relispopulated = 't'\n"
16644  "WHERE oid = ");
16645  appendStringLiteralAH(q, qualrelname, fout);
16646  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16647  }
16648 
16649  /*
16650  * Dump additional per-column properties that we can't handle in the
16651  * main CREATE TABLE command.
16652  */
16653  for (j = 0; j < tbinfo->numatts; j++)
16654  {
16655  /* None of this applies to dropped columns */
16656  if (tbinfo->attisdropped[j])
16657  continue;
16658 
16659  /*
16660  * If we didn't dump the column definition explicitly above, and
16661  * it is not-null and did not inherit that property from a parent,
16662  * we have to mark it separately.
16663  */
16664  if (!shouldPrintColumn(dopt, tbinfo, j) &&
16665  tbinfo->notnull_constrs[j] != NULL &&
16666  (tbinfo->notnull_islocal[j] && !tbinfo->ispartition && !dopt->binary_upgrade))
16667  {
16668  /* No constraint name desired? */
16669  if (tbinfo->notnull_constrs[j][0] == '\0')
16671  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET NOT NULL;\n",
16672  foreign, qualrelname,
16673  fmtId(tbinfo->attnames[j]));
16674  else
16676  "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s NOT NULL %s;\n",
16677  foreign, qualrelname,
16678  tbinfo->notnull_constrs[j],
16679  fmtId(tbinfo->attnames[j]));
16680  }
16681 
16682  /*
16683  * Dump per-column statistics information. We only issue an ALTER
16684  * TABLE statement if the attstattarget entry for this column is
16685  * not the default value.
16686  */
16687  if (tbinfo->attstattarget[j] >= 0)
16688  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
16689  foreign, qualrelname,
16690  fmtId(tbinfo->attnames[j]),
16691  tbinfo->attstattarget[j]);
16692 
16693  /*
16694  * Dump per-column storage information. The statement is only
16695  * dumped if the storage has been changed from the type's default.
16696  */
16697  if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
16698  {
16699  switch (tbinfo->attstorage[j])
16700  {
16701  case TYPSTORAGE_PLAIN:
16702  storage = "PLAIN";
16703  break;
16704  case TYPSTORAGE_EXTERNAL:
16705  storage = "EXTERNAL";
16706  break;
16707  case TYPSTORAGE_EXTENDED:
16708  storage = "EXTENDED";
16709  break;
16710  case TYPSTORAGE_MAIN:
16711  storage = "MAIN";
16712  break;
16713  default:
16714  storage = NULL;
16715  }
16716 
16717  /*
16718  * Only dump the statement if it's a storage type we recognize
16719  */
16720  if (storage != NULL)
16721  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
16722  foreign, qualrelname,
16723  fmtId(tbinfo->attnames[j]),
16724  storage);
16725  }
16726 
16727  /*
16728  * Dump per-column compression, if it's been set.
16729  */
16730  if (!dopt->no_toast_compression)
16731  {
16732  const char *cmname;
16733 
16734  switch (tbinfo->attcompression[j])
16735  {
16736  case 'p':
16737  cmname = "pglz";
16738  break;
16739  case 'l':
16740  cmname = "lz4";
16741  break;
16742  default:
16743  cmname = NULL;
16744  break;
16745  }
16746 
16747  if (cmname != NULL)
16748  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
16749  foreign, qualrelname,
16750  fmtId(tbinfo->attnames[j]),
16751  cmname);
16752  }
16753 
16754  /*
16755  * Dump per-column attributes.
16756  */
16757  if (tbinfo->attoptions[j][0] != '\0')
16758  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
16759  foreign, qualrelname,
16760  fmtId(tbinfo->attnames[j]),
16761  tbinfo->attoptions[j]);
16762 
16763  /*
16764  * Dump per-column fdw options.
16765  */
16766  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
16767  tbinfo->attfdwoptions[j][0] != '\0')
16769  "ALTER FOREIGN TABLE ONLY %s ALTER COLUMN %s OPTIONS (\n"
16770  " %s\n"
16771  ");\n",
16772  qualrelname,
16773  fmtId(tbinfo->attnames[j]),
16774  tbinfo->attfdwoptions[j]);
16775  } /* end loop over columns */
16776 
16777  free(partkeydef);
16778  free(ftoptions);
16779  free(srvname);
16780  }
16781 
16782  /*
16783  * dump properties we only have ALTER TABLE syntax for
16784  */
16785  if ((tbinfo->relkind == RELKIND_RELATION ||
16786  tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
16787  tbinfo->relkind == RELKIND_MATVIEW) &&
16788  tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
16789  {
16790  if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
16791  {
16792  /* nothing to do, will be set when the index is dumped */
16793  }
16794  else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
16795  {
16796  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
16797  qualrelname);
16798  }
16799  else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
16800  {
16801  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
16802  qualrelname);
16803  }
16804  }
16805 
16806  if (tbinfo->forcerowsec)
16807  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
16808  qualrelname);
16809 
16810  if (dopt->binary_upgrade)
16812  reltypename, qrelname,
16813  tbinfo->dobj.namespace->dobj.name);
16814 
16815  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16816  {
16817  char *tablespace = NULL;
16818  char *tableam = NULL;
16819 
16820  /*
16821  * _selectTablespace() relies on tablespace-enabled objects in the
16822  * default tablespace to have a tablespace of "" (empty string) versus
16823  * non-tablespace-enabled objects to have a tablespace of NULL.
16824  * getTables() sets tbinfo->reltablespace to "" for the default
16825  * tablespace (not NULL).
16826  */
16827  if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
16828  tablespace = tbinfo->reltablespace;
16829 
16830  if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
16831  tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
16832  tableam = tbinfo->amname;
16833 
16834  ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
16835  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
16836  .namespace = tbinfo->dobj.namespace->dobj.name,
16837  .tablespace = tablespace,
16838  .tableam = tableam,
16839  .relkind = tbinfo->relkind,
16840  .owner = tbinfo->rolname,
16841  .description = reltypename,
16842  .section = tbinfo->postponed_def ?
16844  .createStmt = q->data,
16845  .dropStmt = delq->data));
16846  }
16847 
16848  /* Dump Table Comments */
16849  if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16850  dumpTableComment(fout, tbinfo, reltypename);
16851 
16852  /* Dump Table Security Labels */
16853  if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
16854  dumpTableSecLabel(fout, tbinfo, reltypename);
16855 
16856  /* Dump comments on inlined table constraints */
16857  for (j = 0; j < tbinfo->ncheck; j++)
16858  {
16859  ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
16860 
16861  if (constr->separate || !constr->conislocal)
16862  continue;
16863 
16864  if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
16865  dumpTableConstraintComment(fout, constr);
16866  }
16867 
16868  destroyPQExpBuffer(q);
16869  destroyPQExpBuffer(delq);
16870  destroyPQExpBuffer(extra);
16871  free(qrelname);
16872  free(qualrelname);
16873 }
#define storage
Definition: indent_codes.h:68
static void dumpTableComment(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:10301
static void binary_upgrade_set_type_oids_by_rel(Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tbinfo)
Definition: pg_dump.c:5500
bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
Definition: pg_dump.c:9443
static void dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:15457
int no_toast_compression
Definition: pg_backup.h:185
char * reltablespace
Definition: pg_dump.h:293
int ncheck
Definition: pg_dump.h:309
bool * attislocal
Definition: pg_dump.h:344
Oid reloftype
Definition: pg_dump.h:311
int numParents
Definition: pg_dump.h:326
char * toast_reloptions
Definition: pg_dump.h:296
struct _tableInfo ** parents
Definition: pg_dump.h:327
int * attlen
Definition: pg_dump.h:342
char ** attfdwoptions
Definition: pg_dump.h:348
bool hasoids
Definition: pg_dump.h:303
Oid toast_oid
Definition: pg_dump.h:306
struct _constraintInfo * checkexprs
Definition: pg_dump.h:357
int * attstattarget
Definition: pg_dump.h:336
uint32 frozenxid
Definition: pg_dump.h:304
char * typstorage
Definition: pg_dump.h:338
struct _attrDefInfo ** attrdefs
Definition: pg_dump.h:356
char ** attoptions
Definition: pg_dump.h:345
char relreplident
Definition: pg_dump.h:292
uint32 minmxid
Definition: pg_dump.h:305
char * attstorage
Definition: pg_dump.h:337
char * amname
Definition: pg_dump.h:359
bool dummy_view
Definition: pg_dump.h:321
bool forcerowsec
Definition: pg_dump.h:302
char ** attmissingval
Definition: pg_dump.h:349
uint32 toast_frozenxid
Definition: pg_dump.h:307
uint32 toast_minmxid
Definition: pg_dump.h:308
char * attalign
Definition: pg_dump.h:343
char * attcompression
Definition: pg_dump.h:347
bool postponed_def
Definition: pg_dump.h:322

References _attrDefInfo::adef_expr, _tableInfo::amname, append_depends_on_extension(), appendBinaryPQExpBuffer(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArrayAH(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), Assert, _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attcompression, _tableInfo::attfdwoptions, _tableInfo::attgenerated, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attmissingval, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypnames, _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel(), _dumpableObject::catId, _tableInfo::checkexprs, _tableInfo::checkoption, _constraintInfo::condef, _constraintInfo::conislocal, createDummyViewAsClause(), createPQExpBuffer(), createViewAsClause(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _attrDefInfo::dobj, _constraintInfo::dobj, Archive::dopt, _tableInfo::dummy_view, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, _dumpableObject::dumpId, dumpTableComment(), dumpTableConstraintComment(), dumpTableSecLabel(), ExecuteSqlQueryForSingleRow(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, _tableInfo::forcerowsec, free, _tableInfo::frozenxid, getFormattedTypeName(), _tableInfo::hasoids, _tableInfo::interesting, _tableInfo::ispartition, j, PQExpBufferData::len, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, _dumpOptions::no_toast_compression, nonemptyReloptions(), _tableInfo::notnull_constrs, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, _tableInfo::numatts, _tableInfo::numParents, CatalogId::oid, OidIsValid, _tableInfo::parents, pg_log_warning, pg_strdup(), _tableInfo::postponed_def, PQclear(), PQfnumber(), PQgetvalue(), _tableInfo::relispopulated, _tableInfo::relkind, _tableInfo::reloftype, _tableInfo::reloptions, _tableInfo::relpersistence, _tableInfo::relreplident, _tableInfo::reltablespace, res, resetPQExpBuffer(), _tableInfo::rolname, SECTION_POST_DATA, SECTION_PRE_DATA, _attrDefInfo::separate, _constraintInfo::separate, shouldPrintColumn(), storage, tablespace, _tableInfo::toast_frozenxid, _tableInfo::toast_minmxid, _tableInfo::toast_oid, _tableInfo::toast_reloptions, _tableInfo::typstorage, and zeroIsError.

Referenced by dumpTable().

◆ dumpTableSecLabel()

static void dumpTableSecLabel ( Archive fout,
const TableInfo tbinfo,
const char *  reltypename 
)
static

Definition at line 15457 of file pg_dump.c.

15458 {
15459  DumpOptions *dopt = fout->dopt;
15460  SecLabelItem *labels;
15461  int nlabels;
15462  int i;
15463  PQExpBuffer query;
15464  PQExpBuffer target;
15465 
15466  /* do nothing, if --no-security-labels is supplied */
15467  if (dopt->no_security_labels)
15468  return;
15469 
15470  /* SecLabel are SCHEMA not data */
15471  if (dopt->dataOnly)
15472  return;
15473 
15474  /* Search for comments associated with relation, using table */
15475  nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
15476  tbinfo->dobj.catId.oid,
15477  &labels);
15478 
15479  /* If security labels exist, build SECURITY LABEL statements */
15480  if (nlabels <= 0)
15481  return;
15482 
15483  query = createPQExpBuffer();
15484  target = createPQExpBuffer();
15485 
15486  for (i = 0; i < nlabels; i++)
15487  {
15488  const char *colname;
15489  const char *provider = labels[i].provider;
15490  const char *label = labels[i].label;
15491  int objsubid = labels[i].objsubid;
15492 
15493  resetPQExpBuffer(target);
15494  if (objsubid == 0)
15495  {
15496  appendPQExpBuffer(target, "%s %s", reltypename,
15497  fmtQualifiedDumpable(tbinfo));
15498  }
15499  else
15500  {
15501  colname = getAttrName(objsubid, tbinfo);
15502  /* first fmtXXX result must be consumed before calling again */
15503  appendPQExpBuffer(target, "COLUMN %s",
15504  fmtQualifiedDumpable(tbinfo));
15505  appendPQExpBuffer(target, ".%s", fmtId(colname));
15506  }
15507  appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
15508  fmtId(provider), target->data);
15509  appendStringLiteralAH(query, label, fout);
15510  appendPQExpBufferStr(query, ";\n");
15511  }
15512  if (query->len > 0)
15513  {
15514  resetPQExpBuffer(target);
15515  appendPQExpBuffer(target, "%s %s", reltypename,
15516  fmtId(tbinfo->dobj.name));
15518  ARCHIVE_OPTS(.tag = target->data,
15519  .namespace = tbinfo->dobj.namespace->dobj.name,
15520  .owner = tbinfo->rolname,
15521  .description = "SECURITY LABEL",
15522  .section = SECTION_NONE,
15523  .createStmt = query->data,
15524  .deps = &(tbinfo->dobj.dumpId),
15525  .nDeps = 1));
15526  }
15527  destroyPQExpBuffer(query);
15528  destroyPQExpBuffer(target);
15529 }

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dumpId, findSecLabels(), fmtId(), fmtQualifiedDumpable, getAttrName(), i, label, SecLabelItem::label, PQExpBufferData::len, _dumpableObject::name, nilCatalogId, _dumpOptions::no_security_labels, SecLabelItem::objsubid, CatalogId::oid, provider, SecLabelItem::provider, resetPQExpBuffer(), _tableInfo::rolname, SECTION_NONE, and CatalogId::tableoid.

Referenced by dumpTableSchema().

◆ dumpTransform()

static void dumpTransform ( Archive fout,
const TransformInfo transform 
)
static

Definition at line 12820 of file pg_dump.c.

12821 {
12822  DumpOptions *dopt = fout->dopt;
12823  PQExpBuffer defqry;
12824  PQExpBuffer delqry;
12825  PQExpBuffer labelq;
12826  PQExpBuffer transformargs;
12827  FuncInfo *fromsqlFuncInfo = NULL;
12828  FuncInfo *tosqlFuncInfo = NULL;
12829  char *lanname;
12830  const char *transformType;
12831 
12832  /* Do nothing in data-only dump */
12833  if (dopt->dataOnly)
12834  return;
12835 
12836  /* Cannot dump if we don't have the transform functions' info */
12837  if (OidIsValid(transform->trffromsql))
12838  {
12839  fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
12840  if (fromsqlFuncInfo == NULL)
12841  pg_fatal("could not find function definition for function with OID %u",
12842  transform->trffromsql);
12843  }
12844  if (OidIsValid(transform->trftosql))
12845  {
12846  tosqlFuncInfo = findFuncByOid(transform->trftosql);
12847  if (tosqlFuncInfo == NULL)
12848  pg_fatal("could not find function definition for function with OID %u",
12849  transform->trftosql);
12850  }
12851 
12852  defqry = createPQExpBuffer();
12853  delqry = createPQExpBuffer();
12854  labelq = createPQExpBuffer();
12855  transformargs = createPQExpBuffer();
12856 
12857  lanname = get_language_name(fout, transform->trflang);
12858  transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
12859 
12860  appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
12861  transformType, lanname);
12862 
12863  appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
12864  transformType, lanname);
12865 
12866  if (!transform->trffromsql && !transform->trftosql)
12867  pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
12868 
12869  if (transform->trffromsql)
12870  {
12871  if (fromsqlFuncInfo)
12872  {
12873  char *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
12874 
12875  /*
12876  * Always qualify the function name (format_function_signature
12877  * won't qualify it).
12878  */
12879  appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
12880  fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
12881  free(fsig);
12882  }
12883  else
12884  pg_log_warning("bogus value in pg_transform.trffromsql field");
12885  }
12886 
12887  if (transform->trftosql)
12888  {
12889  if (transform->trffromsql)
12890  appendPQExpBufferStr(defqry, ", ");
12891 
12892  if (tosqlFuncInfo)
12893  {
12894  char *fsig = format_function_signature(fout, tosqlFuncInfo, true);
12895 
12896  /*
12897  * Always qualify the function name (format_function_signature
12898  * won't qualify it).
12899  */
12900  appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
12901  fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
12902  free(fsig);
12903  }
12904  else
12905  pg_log_warning("bogus value in pg_transform.trftosql field");
12906  }
12907 
12908  appendPQExpBufferStr(defqry, ");\n");
12909 
12910  appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
12911  transformType, lanname);
12912 
12913  appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
12914  transformType, lanname);
12915 
12916  if (dopt->binary_upgrade)
12917  binary_upgrade_extension_member(defqry, &transform->dobj,
12918  "TRANSFORM", transformargs->data, NULL);
12919 
12920  if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
12921  ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
12922  ARCHIVE_OPTS(.tag = labelq->data,
12923  .description = "TRANSFORM",
12924  .section = SECTION_PRE_DATA,
12925  .createStmt = defqry->data,
12926  .dropStmt = delqry->data,
12927  .deps = transform->dobj.dependencies,
12928  .nDeps = transform->dobj.nDeps));
12929 
12930  /* Dump Transform Comments */
12931  if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
12932  dumpComment(fout, "TRANSFORM", transformargs->data,
12933  NULL, "",
12934  transform->dobj.catId, 0, transform->dobj.dumpId);
12935 
12936  free(lanname);
12937  destroyPQExpBuffer(defqry);
12938  destroyPQExpBuffer(delqry);
12939  destroyPQExpBuffer(labelq);
12940  destroyPQExpBuffer(transformargs);
12941 }
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8631
DumpableObject dobj
Definition: pg_dump.h:510
Oid trffromsql
Definition: pg_dump.h:513

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, _dumpableObject::dependencies, destroyPQExpBuffer(), _funcInfo::dobj, _transformInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, findFuncByOid(), fmtId(), format_function_signature(), free, get_language_name(), getFormattedTypeName(), _dumpableObject::name, _dumpableObject::nDeps, OidIsValid, pg_fatal, pg_log_warning, SECTION_PRE_DATA, _transformInfo::trffromsql, _transformInfo::trflang, _transformInfo::trftosql, _transformInfo::trftype, and zeroAsNone.

Referenced by dumpDumpableObject().

◆ dumpTrigger()

static void dumpTrigger ( Archive fout,
const TriggerInfo tginfo 
)
static

Definition at line 18041 of file pg_dump.c.

18042 {
18043  DumpOptions *dopt = fout->dopt;
18044  TableInfo *tbinfo = tginfo->tgtable;
18045  PQExpBuffer query;
18046  PQExpBuffer delqry;
18047  PQExpBuffer trigprefix;
18048  PQExpBuffer trigidentity;
18049  char *qtabname;
18050  char *tag;
18051 
18052  /* Do nothing in data-only dump */
18053  if (dopt->dataOnly)
18054  return;
18055 
18056  query = createPQExpBuffer();
18057  delqry = createPQExpBuffer();
18058  trigprefix = createPQExpBuffer();
18059  trigidentity = createPQExpBuffer();
18060 
18061  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18062 
18063  appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
18064  appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
18065 
18066  appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
18067  appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
18068 
18069  /* Triggers can depend on extensions */
18070  append_depends_on_extension(fout, query, &tginfo->dobj,
18071  "pg_catalog.pg_trigger", "TRIGGER",
18072  trigidentity->data);
18073 
18074  if (tginfo->tgispartition)
18075  {
18076  Assert(tbinfo->ispartition);
18077 
18078  /*
18079  * Partition triggers only appear here because their 'tgenabled' flag
18080  * differs from its parent's. The trigger is created already, so
18081  * remove the CREATE and replace it with an ALTER. (Clear out the
18082  * DROP query too, so that pg_dump --create does not cause errors.)
18083  */
18084  resetPQExpBuffer(query);
18085  resetPQExpBuffer(delqry);
18086  appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
18087  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
18088  fmtQualifiedDumpable(tbinfo));
18089  switch (tginfo->tgenabled)
18090  {
18091  case 'f':
18092  case 'D':
18093  appendPQExpBufferStr(query, "DISABLE");
18094  break;
18095  case 't':
18096  case 'O':
18097  appendPQExpBufferStr(query, "ENABLE");
18098  break;
18099  case 'R':
18100  appendPQExpBufferStr(query, "ENABLE REPLICA");
18101  break;
18102  case 'A':
18103  appendPQExpBufferStr(query, "ENABLE ALWAYS");
18104  break;
18105  }
18106  appendPQExpBuffer(query, " TRIGGER %s;\n",
18107  fmtId(tginfo->dobj.name));
18108  }
18109  else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
18110  {
18111  appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
18112  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
18113  fmtQualifiedDumpable(tbinfo));
18114  switch (tginfo->tgenabled)
18115  {
18116  case 'D':
18117  case 'f':
18118  appendPQExpBufferStr(query, "DISABLE");
18119  break;
18120  case 'A':
18121  appendPQExpBufferStr(query, "ENABLE ALWAYS");
18122  break;
18123  case 'R':
18124  appendPQExpBufferStr(query, "ENABLE REPLICA");
18125  break;
18126  default:
18127  appendPQExpBufferStr(query, "ENABLE");
18128  break;
18129  }
18130  appendPQExpBuffer(query, " TRIGGER %s;\n",
18131  fmtId(tginfo->dobj.name));
18132  }
18133 
18134  appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
18135  fmtId(tginfo->dobj.name));
18136 
18137  tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
18138 
18139  if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18140  ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
18141  ARCHIVE_OPTS(.tag = tag,
18142  .namespace = tbinfo->dobj.namespace->dobj.name,
18143  .owner = tbinfo->rolname,
18144  .description = "TRIGGER",
18145  .section = SECTION_POST_DATA,
18146  .createStmt = query->data,
18147  .dropStmt = delqry->data));
18148 
18149  if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18150  dumpComment(fout, trigprefix->data, qtabname,
18151  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
18152  tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
18153 
18154  free(tag);
18155  destroyPQExpBuffer(query);
18156  destroyPQExpBuffer(delqry);
18157  destroyPQExpBuffer(trigprefix);
18158  destroyPQExpBuffer(trigidentity);
18159  free(qtabname);
18160 }
TableInfo * tgtable
Definition: pg_dump.h:446
DumpableObject dobj
Definition: pg_dump.h:445
char tgenabled
Definition: pg_dump.h:447
char * tgdef
Definition: pg_dump.h:449
bool tgispartition
Definition: pg_dump.h:448

References append_depends_on_extension(), appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), Assert, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _triggerInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, fmtId(), fmtQualifiedDumpable, free, _tableInfo::ispartition, _dumpableObject::name, pg_strdup(), psprintf(), _tableInfo::relkind, resetPQExpBuffer(), _tableInfo::rolname, SECTION_POST_DATA, _triggerInfo::tgdef, _triggerInfo::tgenabled, _triggerInfo::tgispartition, and _triggerInfo::tgtable.

Referenced by dumpDumpableObject().

◆ dumpTSConfig()

static void dumpTSConfig ( Archive fout,
const TSConfigInfo cfginfo 
)
static

Definition at line 14776 of file pg_dump.c.

14777 {
14778  DumpOptions *dopt = fout->dopt;
14779  PQExpBuffer q;
14780  PQExpBuffer delq;
14781  PQExpBuffer query;
14782  char *qcfgname;
14783  PGresult *res;
14784  char *nspname;
14785  char *prsname;
14786  int ntups,
14787  i;
14788  int i_tokenname;
14789  int i_dictname;
14790 
14791  /* Do nothing in data-only dump */
14792  if (dopt->dataOnly)
14793  return;
14794 
14795  q = createPQExpBuffer();
14796  delq = createPQExpBuffer();
14797  query = createPQExpBuffer();
14798 
14799  qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
14800 
14801  /* Fetch name and namespace of the config's parser */
14802  appendPQExpBuffer(query, "SELECT nspname, prsname "
14803  "FROM pg_ts_parser p, pg_namespace n "
14804  "WHERE p.oid = '%u' AND n.oid = prsnamespace",
14805  cfginfo->cfgparser);
14806  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14807  nspname = PQgetvalue(res, 0, 0);
14808  prsname = PQgetvalue(res, 0, 1);
14809 
14810  appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
14811  fmtQualifiedDumpable(cfginfo));
14812 
14813  appendPQExpBuffer(q, " PARSER = %s.", fmtId(nspname));
14814  appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
14815 
14816  PQclear(res);
14817 
14818  resetPQExpBuffer(query);
14819  appendPQExpBuffer(query,
14820  "SELECT\n"
14821  " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
14822  " WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
14823  " m.mapdict::pg_catalog.regdictionary AS dictname\n"
14824  "FROM pg_catalog.pg_ts_config_map AS m\n"
14825  "WHERE m.mapcfg = '%u'\n"
14826  "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
14827  cfginfo->cfgparser, cfginfo->dobj.catId.oid);
14828 
14829  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14830  ntups = PQntuples(res);
14831 
14832  i_tokenname = PQfnumber(res, "tokenname");
14833  i_dictname = PQfnumber(res, "dictname");
14834 
14835  for (i = 0; i < ntups; i++)
14836  {
14837  char *tokenname = PQgetvalue(res, i, i_tokenname);
14838  char *dictname = PQgetvalue(res, i, i_dictname);
14839 
14840  if (i == 0 ||
14841  strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
14842  {
14843  /* starting a new token type, so start a new command */
14844  if (i > 0)
14845  appendPQExpBufferStr(q, ";\n");
14846  appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
14847  fmtQualifiedDumpable(cfginfo));
14848  /* tokenname needs quoting, dictname does NOT */
14849  appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
14850  fmtId(tokenname), dictname);
14851  }
14852  else
14853  appendPQExpBuffer(q, ", %s", dictname);
14854  }
14855 
14856  if (ntups > 0)
14857  appendPQExpBufferStr(q, ";\n");
14858 
14859  PQclear(res);
14860 
14861  appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
14862  fmtQualifiedDumpable(cfginfo));
14863 
14864  if (dopt->binary_upgrade)
14866  "TEXT SEARCH CONFIGURATION", qcfgname,
14867  cfginfo->dobj.namespace->dobj.name);
14868 
14869  if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14870  ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
14871  ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
14872  .namespace = cfginfo->dobj.namespace->dobj.name,
14873  .owner = cfginfo->rolname,
14874  .description = "TEXT SEARCH CONFIGURATION",
14875  .section = SECTION_PRE_DATA,
14876  .createStmt = q->data,
14877  .dropStmt = delq->data));
14878 
14879  /* Dump Configuration Comments */
14880  if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14881  dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
14882  cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
14883  cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
14884 
14885  destroyPQExpBuffer(q);
14886  destroyPQExpBuffer(delq);
14887  destroyPQExpBuffer(query);
14888  free(qcfgname);
14889 }
Oid cfgparser
Definition: pg_dump.h:553
DumpableObject dobj
Definition: pg_dump.h:551
const char * rolname
Definition: pg_dump.h:552

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

Referenced by dumpDumpableObject().

◆ dumpTSDictionary()

static void dumpTSDictionary ( Archive fout,
const TSDictInfo dictinfo 
)
static

Definition at line 14638 of file pg_dump.c.

14639 {
14640  DumpOptions *dopt = fout->dopt;
14641  PQExpBuffer q;
14642  PQExpBuffer delq;
14643  PQExpBuffer query;
14644  char *qdictname;
14645  PGresult *res;
14646  char *nspname;
14647  char *tmplname;
14648 
14649  /* Do nothing in data-only dump */
14650  if (dopt->dataOnly)
14651  return;
14652 
14653  q = createPQExpBuffer();
14654  delq = createPQExpBuffer();
14655  query = createPQExpBuffer();
14656 
14657  qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
14658 
14659  /* Fetch name and namespace of the dictionary's template */
14660  appendPQExpBuffer(query, "SELECT nspname, tmplname "
14661  "FROM pg_ts_template p, pg_namespace n "
14662  "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
14663  dictinfo->dicttemplate);
14664  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14665  nspname = PQgetvalue(res, 0, 0);
14666  tmplname = PQgetvalue(res, 0, 1);
14667 
14668  appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
14669  fmtQualifiedDumpable(dictinfo));
14670 
14671  appendPQExpBufferStr(q, " TEMPLATE = ");
14672  appendPQExpBuffer(q, "%s.", fmtId(nspname));
14673  appendPQExpBufferStr(q, fmtId(tmplname));
14674 
14675  PQclear(res);
14676 
14677  /* the dictinitoption can be dumped straight into the command */
14678  if (dictinfo->dictinitoption)
14679  appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
14680 
14681  appendPQExpBufferStr(q, " );\n");
14682 
14683  appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
14684  fmtQualifiedDumpable(dictinfo));
14685 
14686  if (dopt->binary_upgrade)
14687  binary_upgrade_extension_member(q, &dictinfo->dobj,
14688  "TEXT SEARCH DICTIONARY", qdictname,
14689  dictinfo->dobj.namespace->dobj.name);
14690 
14691  if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14692  ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
14693  ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
14694  .namespace = dictinfo->dobj.namespace->dobj.name,
14695  .owner = dictinfo->rolname,
14696  .description = "TEXT SEARCH DICTIONARY",
14697  .section = SECTION_PRE_DATA,
14698  .createStmt = q->data,
14699  .dropStmt = delq->data));
14700 
14701  /* Dump Dictionary Comments */
14702  if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14703  dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
14704  dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
14705  dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
14706 
14707  destroyPQExpBuffer(q);
14708  destroyPQExpBuffer(delq);
14709  destroyPQExpBuffer(query);
14710  free(qdictname);
14711 }
char * dictinitoption
Definition: pg_dump.h:539
DumpableObject dobj
Definition: pg_dump.h:536
const char * rolname
Definition: pg_dump.h:537
Oid dicttemplate
Definition: pg_dump.h:538

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

Referenced by dumpDumpableObject().

◆ dumpTSParser()

static void dumpTSParser ( Archive fout,
const TSParserInfo prsinfo 
)
static

Definition at line 14574 of file pg_dump.c.

14575 {
14576  DumpOptions *dopt = fout->dopt;
14577  PQExpBuffer q;
14578  PQExpBuffer delq;
14579  char *qprsname;
14580 
14581  /* Do nothing in data-only dump */
14582  if (dopt->dataOnly)
14583  return;
14584 
14585  q = createPQExpBuffer();
14586  delq = createPQExpBuffer();
14587 
14588  qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
14589 
14590  appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
14591  fmtQualifiedDumpable(prsinfo));
14592 
14593  appendPQExpBuffer(q, " START = %s,\n",
14594  convertTSFunction(fout, prsinfo->prsstart));
14595  appendPQExpBuffer(q, " GETTOKEN = %s,\n",
14596  convertTSFunction(fout, prsinfo->prstoken));
14597  appendPQExpBuffer(q, " END = %s,\n",
14598  convertTSFunction(fout, prsinfo->prsend));
14599  if (prsinfo->prsheadline != InvalidOid)
14600  appendPQExpBuffer(q, " HEADLINE = %s,\n",
14601  convertTSFunction(fout, prsinfo->prsheadline));
14602  appendPQExpBuffer(q, " LEXTYPES = %s );\n",
14603  convertTSFunction(fout, prsinfo->prslextype));
14604 
14605  appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
14606  fmtQualifiedDumpable(prsinfo));
14607 
14608  if (dopt->binary_upgrade)
14610  "TEXT SEARCH PARSER", qprsname,
14611  prsinfo->dobj.namespace->dobj.name);
14612 
14613  if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14614  ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
14615  ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
14616  .namespace = prsinfo->dobj.namespace->dobj.name,
14617  .description = "TEXT SEARCH PARSER",
14618  .section = SECTION_PRE_DATA,
14619  .createStmt = q->data,
14620  .dropStmt = delq->data));
14621 
14622  /* Dump Parser Comments */
14623  if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14624  dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
14625  prsinfo->dobj.namespace->dobj.name, "",
14626  prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
14627 
14628  destroyPQExpBuffer(q);
14629  destroyPQExpBuffer(delq);
14630  free(qprsname);
14631 }
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:13239
DumpableObject dobj
Definition: pg_dump.h:526
Oid prstoken
Definition: pg_dump.h:528
Oid prslextype
Definition: pg_dump.h:531
Oid prsheadline
Definition: pg_dump.h:530
Oid prsstart
Definition: pg_dump.h:527
Oid prsend
Definition: pg_dump.h:529

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertTSFunction(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _prsInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, fmtId(), fmtQualifiedDumpable, free, InvalidOid, _dumpableObject::name, pg_strdup(), _prsInfo::prsend, _prsInfo::prsheadline, _prsInfo::prslextype, _prsInfo::prsstart, _prsInfo::prstoken, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpTSTemplate()

static void dumpTSTemplate ( Archive fout,
const TSTemplateInfo tmplinfo 
)
static

Definition at line 14718 of file pg_dump.c.

14719 {
14720  DumpOptions *dopt = fout->dopt;
14721  PQExpBuffer q;
14722  PQExpBuffer delq;
14723  char *qtmplname;
14724 
14725  /* Do nothing in data-only dump */
14726  if (dopt->dataOnly)
14727  return;
14728 
14729  q = createPQExpBuffer();
14730  delq = createPQExpBuffer();
14731 
14732  qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
14733 
14734  appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
14735  fmtQualifiedDumpable(tmplinfo));
14736 
14737  if (tmplinfo->tmplinit != InvalidOid)
14738  appendPQExpBuffer(q, " INIT = %s,\n",
14739  convertTSFunction(fout, tmplinfo->tmplinit));
14740  appendPQExpBuffer(q, " LEXIZE = %s );\n",
14741  convertTSFunction(fout, tmplinfo->tmpllexize));
14742 
14743  appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
14744  fmtQualifiedDumpable(tmplinfo));
14745 
14746  if (dopt->binary_upgrade)
14747  binary_upgrade_extension_member(q, &tmplinfo->dobj,
14748  "TEXT SEARCH TEMPLATE", qtmplname,
14749  tmplinfo->dobj.namespace->dobj.name);
14750 
14751  if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14752  ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
14753  ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
14754  .namespace = tmplinfo->dobj.namespace->dobj.name,
14755  .description = "TEXT SEARCH TEMPLATE",
14756  .section = SECTION_PRE_DATA,
14757  .createStmt = q->data,
14758  .dropStmt = delq->data));
14759 
14760  /* Dump Template Comments */
14761  if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14762  dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
14763  tmplinfo->dobj.namespace->dobj.name, "",
14764  tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
14765 
14766  destroyPQExpBuffer(q);
14767  destroyPQExpBuffer(delq);
14768  free(qtmplname);
14769 }
Oid tmpllexize
Definition: pg_dump.h:546
Oid tmplinit
Definition: pg_dump.h:545
DumpableObject dobj
Definition: pg_dump.h:544

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertTSFunction(), createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _tmplInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, fmtId(), fmtQualifiedDumpable, free, InvalidOid, _dumpableObject::name, pg_strdup(), SECTION_PRE_DATA, _tmplInfo::tmplinit, and _tmplInfo::tmpllexize.

Referenced by dumpDumpableObject().

◆ dumpType()

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

Definition at line 10959 of file pg_dump.c.

10960 {
10961  DumpOptions *dopt = fout->dopt;
10962 
10963  /* Do nothing in data-only dump */
10964  if (dopt->dataOnly)
10965  return;
10966 
10967  /* Dump out in proper style */
10968  if (tyinfo->typtype == TYPTYPE_BASE)
10969  dumpBaseType(fout, tyinfo);
10970  else if (tyinfo->typtype == TYPTYPE_DOMAIN)
10971  dumpDomain(fout, tyinfo);
10972  else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
10973  dumpCompositeType(fout, tyinfo);
10974  else if (tyinfo->typtype == TYPTYPE_ENUM)
10975  dumpEnumType(fout, tyinfo);
10976  else if (tyinfo->typtype == TYPTYPE_RANGE)
10977  dumpRangeType(fout, tyinfo);
10978  else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
10979  dumpUndefinedType(fout, tyinfo);
10980  else
10981  pg_log_warning("typtype of data type \"%s\" appears to be invalid",
10982  tyinfo->dobj.name);
10983 }
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11352
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11130
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11601
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11288
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11774
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:10990
bool isDefined
Definition: pg_dump.h:208
char typtype
Definition: pg_dump.h:205

References _dumpOptions::dataOnly, _typeInfo::dobj, Archive::dopt, dumpBaseType(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpRangeType(), dumpUndefinedType(), _typeInfo::isDefined, _dumpableObject::name, pg_log_warning, and _typeInfo::typtype.

Referenced by crashDumpHandler(), and dumpDumpableObject().

◆ dumpUndefinedType()

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

Definition at line 11288 of file pg_dump.c.

11289 {
11290  DumpOptions *dopt = fout->dopt;
11292  PQExpBuffer delq = createPQExpBuffer();
11293  char *qtypname;
11294  char *qualtypname;
11295 
11296  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11297  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11298 
11299  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11300 
11301  if (dopt->binary_upgrade)
11303  tyinfo->dobj.catId.oid,
11304  false, false);
11305 
11306  appendPQExpBuffer(q, "CREATE TYPE %s;\n",
11307  qualtypname);
11308 
11309  if (dopt->binary_upgrade)
11311  "TYPE", qtypname,
11312  tyinfo->dobj.namespace->dobj.name);
11313 
11314  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11315  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11316  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11317  .namespace = tyinfo->dobj.namespace->dobj.name,
11318  .owner = tyinfo->rolname,
11319  .description = "TYPE",
11320  .section = SECTION_PRE_DATA,
11321  .createStmt = q->data,
11322  .dropStmt = delq->data));
11323 
11324  /* Dump Type Comments and Security Labels */
11325  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11326  dumpComment(fout, "TYPE", qtypname,
11327  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11328  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11329 
11330  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11331  dumpSecLabel(fout, "TYPE", qtypname,
11332  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11333  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11334 
11335  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11336  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11337  qtypname, NULL,
11338  tyinfo->dobj.namespace->dobj.name,
11339  NULL, tyinfo->rolname, &tyinfo->dacl);
11340 
11341  destroyPQExpBuffer(q);
11342  destroyPQExpBuffer(delq);
11343  free(qtypname);
11344  free(qualtypname);
11345 }

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _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(), fmtId(), fmtQualifiedDumpable, free, InvalidDumpId, _dumpableObject::name, CatalogId::oid, pg_strdup(), _typeInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpType().

◆ dumpUserMappings()

static void dumpUserMappings ( Archive fout,
const char *  servername,
const char *  namespace,
const char *  owner,
CatalogId  catalogId,
DumpId  dumpId 
)
static

Definition at line 15066 of file pg_dump.c.

15070 {
15071  PQExpBuffer q;
15072  PQExpBuffer delq;
15073  PQExpBuffer query;
15074  PQExpBuffer tag;
15075  PGresult *res;
15076  int ntups;
15077  int i_usename;
15078  int i_umoptions;
15079  int i;
15080 
15081  q = createPQExpBuffer();
15082  tag = createPQExpBuffer();
15083  delq = createPQExpBuffer();
15084  query = createPQExpBuffer();
15085 
15086  /*
15087  * We read from the publicly accessible view pg_user_mappings, so as not
15088  * to fail if run by a non-superuser. Note that the view will show
15089  * umoptions as null if the user hasn't got privileges for the associated
15090  * server; this means that pg_dump will dump such a mapping, but with no
15091  * OPTIONS clause. A possible alternative is to skip such mappings
15092  * altogether, but it's not clear that that's an improvement.
15093  */
15094  appendPQExpBuffer(query,
15095  "SELECT usename, "
15096  "array_to_string(ARRAY("
15097  "SELECT quote_ident(option_name) || ' ' || "
15098  "quote_literal(option_value) "
15099  "FROM pg_options_to_table(umoptions) "
15100  "ORDER BY option_name"
15101  "), E',\n ') AS umoptions "
15102  "FROM pg_user_mappings "
15103  "WHERE srvid = '%u' "
15104  "ORDER BY usename",
15105  catalogId.oid);
15106 
15107  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15108 
15109  ntups = PQntuples(res);
15110  i_usename = PQfnumber(res, "usename");
15111  i_umoptions = PQfnumber(res, "umoptions");
15112 
15113  for (i = 0; i < ntups; i++)
15114  {
15115  char *usename;
15116  char *umoptions;
15117 
15118  usename = PQgetvalue(res, i, i_usename);
15119  umoptions = PQgetvalue(res, i, i_umoptions);
15120 
15121  resetPQExpBuffer(q);
15122  appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
15123  appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
15124 
15125  if (umoptions && strlen(umoptions) > 0)
15126  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions);
15127 
15128  appendPQExpBufferStr(q, ";\n");
15129 
15130  resetPQExpBuffer(delq);
15131  appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
15132  appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
15133 
15134  resetPQExpBuffer(tag);
15135  appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
15136  usename, servername);
15137 
15139  ARCHIVE_OPTS(.tag = tag->data,
15140  .namespace = namespace,
15141  .owner = owner,
15142  .description = "USER MAPPING",
15143  .section = SECTION_PRE_DATA,
15144  .createStmt = q->data,
15145  .dropStmt = delq->data));
15146  }
15147 
15148  PQclear(res);
15149 
15150  destroyPQExpBuffer(query);
15151  destroyPQExpBuffer(delq);
15152  destroyPQExpBuffer(tag);
15153  destroyPQExpBuffer(q);
15154 }

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), fmtId(), i, nilCatalogId, CatalogId::oid, PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, resetPQExpBuffer(), and SECTION_PRE_DATA.

Referenced by dumpForeignServer().

◆ expand_extension_name_patterns()

static void expand_extension_name_patterns ( Archive fout,
SimpleStringList patterns,
SimpleOidList oids,
bool  strict_names 
)
static

Definition at line 1548 of file pg_dump.c.

1552 {
1553  PQExpBuffer query;
1554  PGresult *res;
1555  SimpleStringListCell *cell;
1556  int i;
1557 
1558  if (patterns->head == NULL)
1559  return; /* nothing to do */
1560 
1561  query = createPQExpBuffer();
1562 
1563  /*
1564  * The loop below runs multiple SELECTs might sometimes result in
1565  * duplicate entries in the OID list, but we don't care.
1566  */
1567  for (cell = patterns->head; cell; cell = cell->next)
1568  {
1569  int dotcnt;
1570 
1571  appendPQExpBufferStr(query,
1572  "SELECT oid FROM pg_catalog.pg_extension e\n");
1573  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1574  false, NULL, "e.extname", NULL, NULL, NULL,
1575  &dotcnt);
1576  if (dotcnt > 0)
1577  pg_fatal("improper qualified name (too many dotted names): %s",
1578  cell->val);
1579 
1580  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1581  if (strict_names && PQntuples(res) == 0)
1582  pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
1583 
1584  for (i = 0; i < PQntuples(res); i++)
1585  {
1587  }
1588 
1589  PQclear(res);
1590  resetPQExpBuffer(query);
1591  }
1592 
1593  destroyPQExpBuffer(query);
1594 }
static int strict_names
Definition: pg_dump.c:150
void simple_oid_list_append(SimpleOidList *list, Oid val)
Definition: simple_list.c:26
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule, PQExpBuffer dbnamebuf, int *dotcnt)
Definition: string_utils.c:891
char val[FLEXIBLE_ARRAY_MEMBER]
Definition: simple_list.h:37
struct SimpleStringListCell * next
Definition: simple_list.h:34
SimpleStringListCell * head
Definition: simple_list.h:42

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), GetConnection(), SimpleStringList::head, i, SimpleStringListCell::next, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), processSQLNamePattern(), res, resetPQExpBuffer(), simple_oid_list_append(), strict_names, and SimpleStringListCell::val.

Referenced by main().

◆ expand_foreign_server_name_patterns()

static void expand_foreign_server_name_patterns ( Archive fout,
SimpleStringList patterns,
SimpleOidList oids 
)
static

Definition at line 1601 of file pg_dump.c.

1604 {
1605  PQExpBuffer query;
1606  PGresult *res;
1607  SimpleStringListCell *cell;
1608  int i;
1609 
1610  if (patterns->head == NULL)
1611  return; /* nothing to do */
1612 
1613  query = createPQExpBuffer();
1614 
1615  /*
1616  * The loop below runs multiple SELECTs might sometimes result in
1617  * duplicate entries in the OID list, but we don't care.
1618  */
1619 
1620  for (cell = patterns->head; cell; cell = cell->next)
1621  {
1622  int dotcnt;
1623 
1624  appendPQExpBufferStr(query,
1625  "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
1626  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1627  false, NULL, "s.srvname", NULL, NULL, NULL,
1628  &dotcnt);
1629  if (dotcnt > 0)
1630  pg_fatal("improper qualified name (too many dotted names): %s",
1631  cell->val);
1632 
1633  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1634  if (PQntuples(res) == 0)
1635  pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
1636 
1637  for (i = 0; i < PQntuples(res); i++)
1639 
1640  PQclear(res);
1641  resetPQExpBuffer(query);
1642  }
1643 
1644  destroyPQExpBuffer(query);
1645 }

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), GetConnection(), SimpleStringList::head, i, SimpleStringListCell::next, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), processSQLNamePattern(), res, resetPQExpBuffer(), simple_oid_list_append(), and SimpleStringListCell::val.

Referenced by main().

◆ expand_schema_name_patterns()

static void expand_schema_name_patterns ( Archive fout,
SimpleStringList patterns,
SimpleOidList oids,
bool  strict_names 
)
static

Definition at line 1489 of file pg_dump.c.

1493 {
1494  PQExpBuffer query;
1495  PGresult *res;
1496  SimpleStringListCell *cell;
1497  int i;
1498 
1499  if (patterns->head == NULL)
1500  return; /* nothing to do */
1501 
1502  query = createPQExpBuffer();
1503 
1504  /*
1505  * The loop below runs multiple SELECTs might sometimes result in
1506  * duplicate entries in the OID list, but we don't care.
1507  */
1508 
1509  for (cell = patterns->head; cell; cell = cell->next)
1510  {
1511  PQExpBufferData dbbuf;
1512  int dotcnt;
1513 
1514  appendPQExpBufferStr(query,
1515  "SELECT oid FROM pg_catalog.pg_namespace n\n");
1516  initPQExpBuffer(&dbbuf);
1517  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1518  false, NULL, "n.nspname", NULL, NULL, &dbbuf,
1519  &dotcnt);
1520  if (dotcnt > 1)
1521  pg_fatal("improper qualified name (too many dotted names): %s",
1522  cell->val);
1523  else if (dotcnt == 1)
1524  prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1525  termPQExpBuffer(&dbbuf);
1526 
1527  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1528  if (strict_names && PQntuples(res) == 0)
1529  pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
1530 
1531  for (i = 0; i < PQntuples(res); i++)
1532  {
1534  }
1535 
1536  PQclear(res);
1537  resetPQExpBuffer(query);
1538  }
1539 
1540  destroyPQExpBuffer(query);
1541 }
static void prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
Definition: pg_dump.c:1749
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), GetConnection(), SimpleStringList::head, i, initPQExpBuffer(), SimpleStringListCell::next, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), processSQLNamePattern(), prohibit_crossdb_refs(), res, resetPQExpBuffer(), simple_oid_list_append(), strict_names, termPQExpBuffer(), and SimpleStringListCell::val.

Referenced by main().

◆ expand_table_name_patterns()

static void expand_table_name_patterns ( Archive fout,
SimpleStringList patterns,
SimpleOidList oids,
bool  strict_names,
bool  with_child_tables 
)
static

Definition at line 1653 of file pg_dump.c.

1656 {
1657  PQExpBuffer query;
1658  PGresult *res;
1659  SimpleStringListCell *cell;
1660  int i;
1661 
1662  if (patterns->head == NULL)
1663  return; /* nothing to do */
1664 
1665  query = createPQExpBuffer();
1666 
1667  /*
1668  * this might sometimes result in duplicate entries in the OID list, but
1669  * we don't care.
1670  */
1671 
1672  for (cell = patterns->head; cell; cell = cell->next)
1673  {
1674  PQExpBufferData dbbuf;
1675  int dotcnt;
1676 
1677  /*
1678  * Query must remain ABSOLUTELY devoid of unqualified names. This
1679  * would be unnecessary given a pg_table_is_visible() variant taking a
1680  * search_path argument.
1681  *
1682  * For with_child_tables, we start with the basic query's results and
1683  * recursively search the inheritance tree to add child tables.
1684  */
1685  if (with_child_tables)
1686  {
1687  appendPQExpBuffer(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
1688  }
1689 
1690  appendPQExpBuffer(query,
1691  "SELECT c.oid"
1692  "\nFROM pg_catalog.pg_class c"
1693  "\n LEFT JOIN pg_catalog.pg_namespace n"
1694  "\n ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
1695  "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
1696  "\n (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
1697  RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
1698  RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
1699  RELKIND_PARTITIONED_TABLE);
1700  initPQExpBuffer(&dbbuf);
1701  processSQLNamePattern(GetConnection(fout), query, cell->val, true,
1702  false, "n.nspname", "c.relname", NULL,
1703  "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
1704  &dotcnt);
1705  if (dotcnt > 2)
1706  pg_fatal("improper relation name (too many dotted names): %s",
1707  cell->val);
1708  else if (dotcnt == 2)
1709  prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1710  termPQExpBuffer(&dbbuf);
1711 
1712  if (with_child_tables)
1713  {
1714  appendPQExpBuffer(query, "UNION"
1715  "\nSELECT i.inhrelid"
1716  "\nFROM partition_tree p"
1717  "\n JOIN pg_catalog.pg_inherits i"
1718  "\n ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
1719  "\n)"
1720  "\nSELECT relid FROM partition_tree");
1721  }
1722 
1723  ExecuteSqlStatement(fout, "RESET search_path");
1724  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1727  if (strict_names && PQntuples(res) == 0)
1728  pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
1729 
1730  for (i = 0; i < PQntuples(res); i++)
1731  {
1733  }
1734 
1735  PQclear(res);
1736  resetPQExpBuffer(query);
1737  }
1738 
1739  destroyPQExpBuffer(query);
1740 }
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25

References ALWAYS_SECURE_SEARCH_PATH_SQL, appendPQExpBuffer(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), GetConnection(), SimpleStringList::head, i, initPQExpBuffer(), SimpleStringListCell::next, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), processSQLNamePattern(), prohibit_crossdb_refs(), res, resetPQExpBuffer(), simple_oid_list_append(), strict_names, termPQExpBuffer(), and SimpleStringListCell::val.

Referenced by main().

◆ findComments()

static int findComments ( Oid  classoid,
Oid  objoid,
CommentItem **  items 
)
static

Definition at line 10399 of file pg_dump.c.

10400 {
10401  CommentItem *middle = NULL;
10402  CommentItem *low;
10403  CommentItem *high;
10404  int nmatch;
10405 
10406  /*
10407  * Do binary search to find some item matching the object.
10408  */
10409  low = &comments[0];
10410  high = &comments[ncomments - 1];
10411  while (low <= high)
10412  {
10413  middle = low + (high - low) / 2;
10414 
10415  if (classoid < middle->classoid)
10416  high = middle - 1;
10417  else if (classoid > middle->classoid)
10418  low = middle + 1;
10419  else if (objoid < middle->objoid)
10420  high = middle - 1;
10421  else if (objoid > middle->objoid)
10422  low = middle + 1;
10423  else
10424  break; /* found a match */
10425  }
10426 
10427  if (low > high) /* no matches */
10428  {
10429  *items = NULL;
10430  return 0;
10431  }
10432 
10433  /*
10434  * Now determine how many items match the object. The search loop
10435  * invariant still holds: only items between low and high inclusive could
10436  * match.
10437  */
10438  nmatch = 1;
10439  while (middle > low)
10440  {
10441  if (classoid != middle[-1].classoid ||
10442  objoid != middle[-1].objoid)
10443  break;
10444  middle--;
10445  nmatch++;
10446  }
10447 
10448  *items = middle;
10449 
10450  middle += nmatch;
10451  while (middle <= high)
10452  {
10453  if (classoid != middle->classoid ||
10454  objoid != middle->objoid)
10455  break;
10456  middle++;
10457  nmatch++;
10458  }
10459 
10460  return nmatch;
10461 }
static ItemArray items
Definition: test_tidstore.c:48

References CommentItem::classoid, comments, items, ncomments, and CommentItem::objoid.

Referenced by dumpCommentExtended(), dumpCompositeTypeColComments(), and dumpTableComment().

◆ findDumpableDependencies()

static void findDumpableDependencies ( ArchiveHandle AH,
const DumpableObject dobj,
DumpId **  dependencies,
int *  nDeps,
int *  allocDeps 
)
static

Definition at line 19034 of file pg_dump.c.

19036 {
19037  int i;
19038 
19039  /*
19040  * Ignore section boundary objects: if we search through them, we'll
19041  * report lots of bogus dependencies.
19042  */
19043  if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
19044  dobj->objType == DO_POST_DATA_BOUNDARY)
19045  return;
19046 
19047  for (i = 0; i < dobj->nDeps; i++)
19048  {
19049  DumpId depid = dobj->dependencies[i];
19050 
19051  if (TocIDRequired(AH, depid) != 0)
19052  {
19053  /* Object will be dumped, so just reference it as a dependency */
19054  if (*nDeps >= *allocDeps)
19055  {
19056  *allocDeps *= 2;
19057  *dependencies = (DumpId *) pg_realloc(*dependencies,
19058  *allocDeps * sizeof(DumpId));
19059  }
19060  (*dependencies)[*nDeps] = depid;
19061  (*nDeps)++;
19062  }
19063  else
19064  {
19065  /*
19066  * Object will not be dumped, so recursively consider its deps. We
19067  * rely on the assumption that sortDumpableObjects already broke
19068  * any dependency loops, else we might recurse infinitely.
19069  */
19070  DumpableObject *otherdobj = findObjectByDumpId(depid);
19071 
19072  if (otherdobj)
19073  findDumpableDependencies(AH, otherdobj,
19074  dependencies, nDeps, allocDeps);
19075  }
19076  }
19077 }
int TocIDRequired(ArchiveHandle *AH, DumpId id)

References _dumpableObject::dependencies, DO_POST_DATA_BOUNDARY, DO_PRE_DATA_BOUNDARY, findObjectByDumpId(), i, _dumpableObject::nDeps, _dumpableObject::objType, pg_realloc(), and TocIDRequired().

Referenced by BuildArchiveDependencies().

◆ findNamespace()

static NamespaceInfo * findNamespace ( Oid  nsoid)
static

Definition at line 5813 of file pg_dump.c.

5814 {
5815  NamespaceInfo *nsinfo;
5816 
5817  nsinfo = findNamespaceByOid(nsoid);
5818  if (nsinfo == NULL)
5819  pg_fatal("schema with OID %u does not exist", nsoid);
5820  return nsinfo;
5821 }
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:949

References findNamespaceByOid(), and pg_fatal.

Referenced by getAggregates(), getCollations(), getConversions(), getDefaultACLs(), getExtendedStatistics(), getFuncs(), getOpclasses(), getOperators(), getOpfamilies(), getTables(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), and getTypes().

◆ findSecLabels()

static int findSecLabels ( Oid  classoid,
Oid  objoid,
SecLabelItem **  items 
)
static

Definition at line 15539 of file pg_dump.c.

15540 {
15541  SecLabelItem *middle = NULL;
15542  SecLabelItem *low;
15543  SecLabelItem *high;
15544  int nmatch;
15545 
15546  if (nseclabels <= 0) /* no labels, so no match is possible */
15547  {
15548  *items = NULL;
15549  return 0;
15550  }
15551 
15552  /*
15553  * Do binary search to find some item matching the object.
15554  */
15555  low = &seclabels[0];
15556  high = &seclabels[nseclabels - 1];
15557  while (low <= high)
15558  {
15559  middle = low + (high - low) / 2;
15560 
15561  if (classoid < middle->classoid)
15562  high = middle - 1;
15563  else if (classoid > middle->classoid)
15564  low = middle + 1;
15565  else if (objoid < middle->objoid)
15566  high = middle - 1;
15567  else if (objoid > middle->objoid)
15568  low = middle + 1;
15569  else
15570  break; /* found a match */
15571  }
15572 
15573  if (low > high) /* no matches */
15574  {
15575  *items = NULL;
15576  return 0;
15577  }
15578 
15579  /*
15580  * Now determine how many items match the object. The search loop
15581  * invariant still holds: only items between low and high inclusive could
15582  * match.
15583  */
15584  nmatch = 1;
15585  while (middle > low)
15586  {
15587  if (classoid != middle[-1].classoid ||
15588  objoid != middle[-1].objoid)
15589  break;
15590  middle--;
15591  nmatch++;
15592  }
15593 
15594  *items = middle;
15595 
15596  middle += nmatch;
15597  while (middle <= high)
15598  {
15599  if (classoid != middle->classoid ||
15600  objoid != middle->objoid)
15601  break;
15602  middle++;
15603  nmatch++;
15604  }
15605 
15606  return nmatch;
15607 }

References SecLabelItem::classoid, items, nseclabels, SecLabelItem::objoid, and seclabels.

Referenced by dumpSecLabel(), and dumpTableSecLabel().

◆ fmtCopyColumnList()

static const char * fmtCopyColumnList ( const TableInfo ti,
PQExpBuffer  buffer 
)
static

Definition at line 19141 of file pg_dump.c.

19142 {
19143  int numatts = ti->numatts;
19144  char **attnames = ti->attnames;
19145  bool *attisdropped = ti->attisdropped;
19146  char *attgenerated = ti->attgenerated;
19147  bool needComma;
19148  int i;
19149 
19150  appendPQExpBufferChar(buffer, '(');
19151  needComma = false;
19152  for (i = 0; i < numatts; i++)
19153  {
19154  if (attisdropped[i])
19155  continue;
19156  if (attgenerated[i])
19157  continue;
19158  if (needComma)
19159  appendPQExpBufferStr(buffer, ", ");
19160  appendPQExpBufferStr(buffer, fmtId(attnames[i]));
19161  needComma = true;
19162  }
19163 
19164  if (!needComma)
19165  return ""; /* no undropped columns */
19166 
19167  appendPQExpBufferChar(buffer, ')');
19168  return buffer->data;
19169 }

References appendPQExpBufferChar(), appendPQExpBufferStr(), _tableInfo::attgenerated, _tableInfo::attisdropped, _tableInfo::attnames, PQExpBufferData::data, fmtId(), i, and _tableInfo::numatts.

Referenced by dumpTableData(), and dumpTableData_copy().

◆ forcePartitionRootLoad()

static bool forcePartitionRootLoad ( const TableInfo tbinfo)
static

Definition at line 2661 of file pg_dump.c.

2662 {
2663  TableInfo *parentTbinfo;
2664 
2665  Assert(tbinfo->ispartition);
2666  Assert(tbinfo->numParents == 1);
2667 
2668  parentTbinfo = tbinfo->parents[0];
2669  if (parentTbinfo->unsafe_partitions)
2670  return true;
2671  while (parentTbinfo->ispartition)
2672  {
2673  Assert(parentTbinfo->numParents == 1);
2674  parentTbinfo = parentTbinfo->parents[0];
2675  if (parentTbinfo->unsafe_partitions)
2676  return true;
2677  }
2678 
2679  return false;
2680 }
bool unsafe_partitions
Definition: pg_dump.h:324

References Assert, _tableInfo::ispartition, _tableInfo::numParents, _tableInfo::parents, and _tableInfo::unsafe_partitions.

Referenced by dumpTableData(), and dumpTableData_insert().

◆ format_aggregate_signature()

static char* format_aggregate_signature ( const AggInfo agginfo,
Archive fout,
bool  honor_quotes 
)
static

Definition at line 14182 of file pg_dump.c.

14183 {
14185  int j;
14186 
14187  initPQExpBuffer(&buf);
14188  if (honor_quotes)
14189  appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
14190  else
14191  appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
14192 
14193  if (agginfo->aggfn.nargs == 0)
14194  appendPQExpBufferStr(&buf, "(*)");
14195  else
14196  {
14197  appendPQExpBufferChar(&buf, '(');
14198  for (j = 0; j < agginfo->aggfn.nargs; j++)
14199  appendPQExpBuffer(&buf, "%s%s",
14200  (j > 0) ? ", " : "",
14201  getFormattedTypeName(fout,
14202  agginfo->aggfn.argtypes[j],
14203  zeroIsError));
14204  appendPQExpBufferChar(&buf, ')');
14205  }
14206  return buf.data;
14207 }

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), buf, fmtId(), getFormattedTypeName(), initPQExpBuffer(), j, and zeroIsError.

Referenced by dumpAgg().

◆ format_function_arguments()

static char * format_function_arguments ( const FuncInfo finfo,
const char *  funcargs,
bool  is_agg 
)
static

Definition at line 12247 of file pg_dump.c.

12248 {
12250 
12251  initPQExpBuffer(&fn);
12252  appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
12253  if (is_agg && finfo->nargs == 0)
12254  appendPQExpBufferStr(&fn, "(*)");
12255  else
12256  appendPQExpBuffer(&fn, "(%s)", funcargs);
12257  return fn.data;
12258 }
int nargs
Definition: pg_dump.h:229
static void * fn(void *arg)
Definition: thread-alloc.c:119

References appendPQExpBuffer(), appendPQExpBufferStr(), _funcInfo::dobj, fmtId(), fn(), initPQExpBuffer(), _dumpableObject::name, and _funcInfo::nargs.

Referenced by dumpAgg(), and dumpFunc().

◆ format_function_signature()

static char * format_function_signature ( Archive fout,
const FuncInfo finfo,
bool  honor_quotes 
)
static

Definition at line 12270 of file pg_dump.c.

12271 {
12273  int j;
12274 
12275  initPQExpBuffer(&fn);
12276  if (honor_quotes)
12277  appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
12278  else
12279  appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
12280  for (j = 0; j < finfo->nargs; j++)
12281  {
12282  if (j > 0)
12283  appendPQExpBufferStr(&fn, ", ");
12284 
12286  getFormattedTypeName(fout, finfo->argtypes[j],
12287  zeroIsError));
12288  }
12289  appendPQExpBufferChar(&fn, ')');
12290  return fn.data;
12291 }
Oid * argtypes
Definition: pg_dump.h:230

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), _funcInfo::argtypes, _funcInfo::dobj, fmtId(), fn(), getFormattedTypeName(), initPQExpBuffer(), j, _dumpableObject::name, _funcInfo::nargs, and zeroIsError.

Referenced by dumpAgg(), dumpCast(), dumpFunc(), and dumpTransform().

◆ get_language_name()

static char* get_language_name ( Archive fout,
Oid  langid 
)
static

Definition at line 8631 of file pg_dump.c.

8632 {
8633  PQExpBuffer query;
8634  PGresult *res;
8635  char *lanname;
8636 
8637  query = createPQExpBuffer();
8638  appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
8639  res = ExecuteSqlQueryForSingleRow(fout, query->data);
8640  lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
8641  destroyPQExpBuffer(query);
8642  PQclear(res);
8643 
8644  return lanname;
8645 }

References appendPQExpBuffer(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), fmtId(), pg_strdup(), PQclear(), PQgetvalue(), and res.

Referenced by dumpTransform(), and getTransforms().

◆ get_next_possible_free_pg_type_oid()

static Oid get_next_possible_free_pg_type_oid ( Archive fout,
PQExpBuffer  upgrade_query 
)
static

Definition at line 5389 of file pg_dump.c.

5390 {
5391  /*
5392  * If the old version didn't assign an array type, but the new version
5393  * does, we must select an unused type OID to assign. This currently only
5394  * happens for domains, when upgrading pre-v11 to v11 and up.
5395  *
5396  * Note: local state here is kind of ugly, but we must have some, since we
5397  * mustn't choose the same unused OID more than once.
5398  */
5399  static Oid next_possible_free_oid = FirstNormalObjectId;
5400  PGresult *res;
5401  bool is_dup;
5402 
5403  do
5404  {
5405  ++next_possible_free_oid;
5406  printfPQExpBuffer(upgrade_query,
5407  "SELECT EXISTS(SELECT 1 "
5408  "FROM pg_catalog.pg_type "
5409  "WHERE oid = '%u'::pg_catalog.oid);",
5410  next_possible_free_oid);
5411  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5412  is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
5413  PQclear(res);
5414  } while (is_dup);
5415 
5416  return next_possible_free_oid;
5417 }
#define FirstNormalObjectId
Definition: transam.h:197

References PQExpBufferData::data, ExecuteSqlQueryForSingleRow(), FirstNormalObjectId, PQclear(), PQgetvalue(), printfPQExpBuffer(), and res.

Referenced by binary_upgrade_set_type_oids_by_type_oid().

◆ get_synchronized_snapshot()

static char * get_synchronized_snapshot ( Archive fout)
static

Definition at line 1437 of file pg_dump.c.

1438 {
1439  char *query = "SELECT pg_catalog.pg_export_snapshot()";
1440  char *result;
1441  PGresult *res;
1442 
1443  res = ExecuteSqlQueryForSingleRow(fout, query);
1444  result = pg_strdup(PQgetvalue(res, 0, 0));
1445  PQclear(res);
1446 
1447  return result;
1448 }

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

Referenced by setup_connection().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6265 of file pg_dump.c.

6266 {
6267  PGresult *res;
6268  int ntups;
6269  int i;
6270  PQExpBuffer query;
6271  AccessMethodInfo *aminfo;
6272  int i_tableoid;
6273  int i_oid;
6274  int i_amname;
6275  int i_amhandler;
6276  int i_amtype;
6277 
6278  /* Before 9.6, there are no user-defined access methods */
6279  if (fout->remoteVersion < 90600)
6280  return;
6281 
6282  query = createPQExpBuffer();
6283 
6284  /* Select all access methods from pg_am table */
6285  appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6286  "amhandler::pg_catalog.regproc AS amhandler "
6287  "FROM pg_am");
6288 
6289  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6290 
6291  ntups = PQntuples(res);
6292 
6293  aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6294 
6295  i_tableoid = PQfnumber(res, "tableoid");
6296  i_oid = PQfnumber(res, "oid");
6297  i_amname = PQfnumber(res, "amname");
6298  i_amhandler = PQfnumber(res, "amhandler");
6299  i_amtype = PQfnumber(res, "amtype");
6300 
6301  for (i = 0; i < ntups; i++)
6302  {
6303  aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6304  aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6305  aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6306  AssignDumpId(&aminfo[i].dobj);
6307  aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6308  aminfo[i].dobj.namespace = NULL;
6309  aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6310  aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6311 
6312  /* Decide whether we want to dump it */
6313  selectDumpableAccessMethod(&(aminfo[i]), fout);
6314  }
6315 
6316  PQclear(res);
6317 
6318  destroyPQExpBuffer(query);
6319 }
static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
Definition: pg_dump.c:2074

References _accessMethodInfo::amhandler, _accessMethodInfo::amtype, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_ACCESS_METHOD, _accessMethodInfo::dobj, ExecuteSqlQuery(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, selectDumpableAccessMethod(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getAdditionalACLs()

static void getAdditionalACLs ( Archive fout)
static

Definition at line 10056 of file pg_dump.c.

10057 {
10058  PQExpBuffer query = createPQExpBuffer();
10059  PGresult *res;
10060  int ntups,
10061  i;
10062 
10063  /* Check for per-column ACLs */
10064  appendPQExpBufferStr(query,
10065  "SELECT DISTINCT attrelid FROM pg_attribute "
10066  "WHERE attacl IS NOT NULL");
10067 
10068  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10069 
10070  ntups = PQntuples(res);
10071  for (i = 0; i < ntups; i++)
10072  {
10073  Oid relid = atooid(PQgetvalue(res, i, 0));
10074  TableInfo *tblinfo;
10075 
10076  tblinfo = findTableByOid(relid);
10077  /* OK to ignore tables we haven't got a DumpableObject for */
10078  if (tblinfo)
10079  {
10080  tblinfo->dobj.components |= DUMP_COMPONENT_ACL;
10081  tblinfo->hascolumnACLs = true;
10082  }
10083  }
10084  PQclear(res);
10085 
10086  /* Fetch initial-privileges data */
10087  if (fout->remoteVersion >= 90600)
10088  {
10089  printfPQExpBuffer(query,
10090  "SELECT objoid, classoid, objsubid, privtype, initprivs "
10091  "FROM pg_init_privs");
10092 
10093  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10094 
10095  ntups = PQntuples(res);
10096  for (i = 0; i < ntups; i++)
10097  {
10098  Oid objoid = atooid(PQgetvalue(res, i, 0));
10099  Oid classoid = atooid(PQgetvalue(res, i, 1));
10100  int objsubid = atoi(PQgetvalue(res, i, 2));
10101  char privtype = *(PQgetvalue(res, i, 3));
10102  char *initprivs = PQgetvalue(res, i, 4);
10103  CatalogId objId;
10104  DumpableObject *dobj;
10105 
10106  objId.tableoid = classoid;
10107  objId.oid = objoid;
10108  dobj = findObjectByCatalogId(objId);
10109  /* OK to ignore entries we haven't got a DumpableObject for */
10110  if (dobj)
10111  {
10112  /* Cope with sub-object initprivs */
10113  if (objsubid != 0)
10114  {
10115  if (dobj->objType == DO_TABLE)
10116  {
10117  /* For a column initprivs, set the table's ACL flags */
10118  dobj->components |= DUMP_COMPONENT_ACL;
10119  ((TableInfo *) dobj)->hascolumnACLs = true;
10120  }
10121  else
10122  pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10123  classoid, objoid, objsubid);
10124  continue;
10125  }
10126 
10127  /*
10128  * We ignore any pg_init_privs.initprivs entry for the public
10129  * schema, as explained in getNamespaces().
10130  */
10131  if (dobj->objType == DO_NAMESPACE &&
10132  strcmp(dobj->name, "public") == 0)
10133  continue;
10134 
10135  /* Else it had better be of a type we think has ACLs */
10136  if (dobj->objType == DO_NAMESPACE ||
10137  dobj->objType == DO_TYPE ||
10138  dobj->objType == DO_FUNC ||
10139  dobj->objType == DO_AGG ||
10140  dobj->objType == DO_TABLE ||
10141  dobj->objType == DO_PROCLANG ||
10142  dobj->objType == DO_FDW ||
10143  dobj->objType == DO_FOREIGN_SERVER)
10144  {
10145  DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj;
10146 
10147  daobj->dacl.privtype = privtype;
10148  daobj->dacl.initprivs = pstrdup(initprivs);
10149  }
10150  else
10151  pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10152  classoid, objoid, objsubid);
10153  }
10154  }
10155  PQclear(res);
10156  }
10157 
10158  destroyPQExpBuffer(query);
10159 }
DumpableAcl dacl
Definition: pg_dump.h:167

References appendPQExpBufferStr(), atooid, _dumpableObject::components, createPQExpBuffer(), _dumpableObjectWithAcl::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_AGG, DO_FDW, DO_FOREIGN_SERVER, DO_FUNC, DO_NAMESPACE, DO_PROCLANG, DO_TABLE, DO_TYPE, _tableInfo::dobj, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findObjectByCatalogId(), findTableByOid(), _tableInfo::hascolumnACLs, i, _dumpableAcl::initprivs, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_log_warning, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _dumpableAcl::privtype, pstrdup(), Archive::remoteVersion, res, and CatalogId::tableoid.

Referenced by main().

◆ getAggregates()

void getAggregates ( Archive fout)

Definition at line 6449 of file pg_dump.c.

6450 {
6451  DumpOptions *dopt = fout->dopt;
6452  PGresult *res;
6453  int ntups;
6454  int i;
6455  PQExpBuffer query = createPQExpBuffer();
6456  AggInfo *agginfo;
6457  int i_tableoid;
6458  int i_oid;
6459  int i_aggname;
6460  int i_aggnamespace;
6461  int i_pronargs;
6462  int i_proargtypes;
6463  int i_proowner;
6464  int i_aggacl;
6465  int i_acldefault;
6466 
6467  /*
6468  * Find all interesting aggregates. See comment in getFuncs() for the
6469  * rationale behind the filtering logic.
6470  */
6471  if (fout->remoteVersion >= 90600)
6472  {
6473  const char *agg_check;
6474 
6475  agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
6476  : "p.proisagg");
6477 
6478  appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
6479  "p.proname AS aggname, "
6480  "p.pronamespace AS aggnamespace, "
6481  "p.pronargs, p.proargtypes, "
6482  "p.proowner, "
6483  "p.proacl AS aggacl, "
6484  "acldefault('f', p.proowner) AS acldefault "
6485  "FROM pg_proc p "
6486  "LEFT JOIN pg_init_privs pip ON "
6487  "(p.oid = pip.objoid "
6488  "AND pip.classoid = 'pg_proc'::regclass "
6489  "AND pip.objsubid = 0) "
6490  "WHERE %s AND ("
6491  "p.pronamespace != "
6492  "(SELECT oid FROM pg_namespace "
6493  "WHERE nspname = 'pg_catalog') OR "
6494  "p.proacl IS DISTINCT FROM pip.initprivs",
6495  agg_check);
6496  if (dopt->binary_upgrade)
6497  appendPQExpBufferStr(query,
6498  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6499  "classid = 'pg_proc'::regclass AND "
6500  "objid = p.oid AND "
6501  "refclassid = 'pg_extension'::regclass AND "
6502  "deptype = 'e')");
6503  appendPQExpBufferChar(query, ')');
6504  }
6505  else
6506  {
6507  appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
6508  "pronamespace AS aggnamespace, "
6509  "pronargs, proargtypes, "
6510  "proowner, "
6511  "proacl AS aggacl, "
6512  "acldefault('f', proowner) AS acldefault "
6513  "FROM pg_proc p "
6514  "WHERE proisagg AND ("
6515  "pronamespace != "
6516  "(SELECT oid FROM pg_namespace "
6517  "WHERE nspname = 'pg_catalog')");
6518  if (dopt->binary_upgrade)
6519  appendPQExpBufferStr(query,
6520  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6521  "classid = 'pg_proc'::regclass AND "
6522  "objid = p.oid AND "
6523  "refclassid = 'pg_extension'::regclass AND "
6524  "deptype = 'e')");
6525  appendPQExpBufferChar(query, ')');
6526  }
6527 
6528  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6529 
6530  ntups = PQntuples(res);
6531 
6532  agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
6533 
6534  i_tableoid = PQfnumber(res, "tableoid");
6535  i_oid = PQfnumber(res, "oid");
6536  i_aggname = PQfnumber(res, "aggname");
6537  i_aggnamespace = PQfnumber(res, "aggnamespace");
6538  i_pronargs = PQfnumber(res, "pronargs");
6539  i_proargtypes = PQfnumber(res, "proargtypes");
6540  i_proowner = PQfnumber(res, "proowner");
6541  i_aggacl = PQfnumber(res, "aggacl");
6542  i_acldefault = PQfnumber(res, "acldefault");
6543 
6544  for (i = 0; i < ntups; i++)
6545  {
6546  agginfo[i].aggfn.dobj.objType = DO_AGG;
6547  agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6548  agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6549  AssignDumpId(&agginfo[i].aggfn.dobj);
6550  agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
6551  agginfo[i].aggfn.dobj.namespace =
6552  findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
6553  agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
6554  agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6555  agginfo[i].aggfn.dacl.privtype = 0;
6556  agginfo[i].aggfn.dacl.initprivs = NULL;
6557  agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6558  agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
6559  agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
6560  agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
6561  if (agginfo[i].aggfn.nargs == 0)
6562  agginfo[i].aggfn.argtypes = NULL;
6563  else
6564  {
6565  agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
6566  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6567  agginfo[i].aggfn.argtypes,
6568  agginfo[i].aggfn.nargs);
6569  }
6570  agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
6571 
6572  /* Decide whether we want to dump it */
6573  selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
6574 
6575  /* Mark whether aggregate has an ACL */
6576  if (!PQgetisnull(res, i, i_aggacl))
6577  agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
6578  }
6579 
6580  PQclear(res);
6581 
6582  destroyPQExpBuffer(query);
6583 }
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2177
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:5813

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpOptions::binary_upgrade, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_AGG, Archive::dopt, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, InvalidOid, parseOidArray(), pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, and selectDumpableObject().

Referenced by getSchemaData().

◆ getAttrName()

static const char * getAttrName ( int  attrnum,
const TableInfo tblInfo 
)
static

Definition at line 17020 of file pg_dump.c.

17021 {
17022  if (attrnum > 0 && attrnum <= tblInfo->numatts)
17023  return tblInfo->attnames[attrnum - 1];
17024  switch (attrnum)
17025  {
17027  return "ctid";
17029  return "xmin";
17031  return "cmin";
17033  return "xmax";
17035  return "cmax";
17037  return "tableoid";
17038  }
17039  pg_fatal("invalid column number %d for table \"%s\"",
17040  attrnum, tblInfo->dobj.name);
17041  return NULL; /* keep compiler quiet */
17042 }
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:22
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:25
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:24
#define TableOidAttributeNumber
Definition: sysattr.h:26
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define MinCommandIdAttributeNumber
Definition: sysattr.h:23

References _tableInfo::attnames, _tableInfo::dobj, MaxCommandIdAttributeNumber, MaxTransactionIdAttributeNumber, MinCommandIdAttributeNumber, MinTransactionIdAttributeNumber, _dumpableObject::name, pg_fatal, SelfItemPointerAttributeNumber, and TableOidAttributeNumber.

Referenced by dumpConstraint(), and dumpTableSecLabel().

◆ getCasts()

void getCasts ( Archive fout)

Definition at line 8542 of file pg_dump.c.

8543 {
8544  PGresult *res;
8545  int ntups;
8546  int i;
8547  PQExpBuffer query = createPQExpBuffer();
8548  CastInfo *castinfo;
8549  int i_tableoid;
8550  int i_oid;
8551  int i_castsource;
8552  int i_casttarget;
8553  int i_castfunc;
8554  int i_castcontext;
8555  int i_castmethod;
8556 
8557  if (fout->remoteVersion >= 140000)
8558  {
8559  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8560  "castsource, casttarget, castfunc, castcontext, "
8561  "castmethod "
8562  "FROM pg_cast c "
8563  "WHERE NOT EXISTS ( "
8564  "SELECT 1 FROM pg_range r "
8565  "WHERE c.castsource = r.rngtypid "
8566  "AND c.casttarget = r.rngmultitypid "
8567  ") "
8568  "ORDER BY 3,4");
8569  }
8570  else
8571  {
8572  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8573  "castsource, casttarget, castfunc, castcontext, "
8574  "castmethod "
8575  "FROM pg_cast ORDER BY 3,4");
8576  }
8577 
8578  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8579 
8580  ntups = PQntuples(res);
8581 
8582  castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8583 
8584  i_tableoid = PQfnumber(res, "tableoid");
8585  i_oid = PQfnumber(res, "oid");
8586  i_castsource = PQfnumber(res, "castsource");
8587  i_casttarget = PQfnumber(res, "casttarget");
8588  i_castfunc = PQfnumber(res, "castfunc");
8589  i_castcontext = PQfnumber(res, "castcontext");
8590  i_castmethod = PQfnumber(res, "castmethod");
8591 
8592  for (i = 0; i < ntups; i++)
8593  {
8594  PQExpBufferData namebuf;
8595  TypeInfo *sTypeInfo;
8596  TypeInfo *tTypeInfo;
8597 
8598  castinfo[i].dobj.objType = DO_CAST;
8599  castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8600  castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8601  AssignDumpId(&castinfo[i].dobj);
8602  castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8603  castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8604  castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8605  castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8606  castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8607 
8608  /*
8609  * Try to name cast as concatenation of typnames. This is only used
8610  * for purposes of sorting. If we fail to find either type, the name
8611  * will be an empty string.
8612  */
8613  initPQExpBuffer(&namebuf);
8614  sTypeInfo = findTypeByOid(castinfo[i].castsource);
8615  tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8616  if (sTypeInfo && tTypeInfo)
8617  appendPQExpBuffer(&namebuf, "%s %s",
8618  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8619  castinfo[i].dobj.name = namebuf.data;
8620 
8621  /* Decide whether we want to dump it */
8622  selectDumpableCast(&(castinfo[i]), fout);
8623  }
8624 
8625  PQclear(res);
8626 
8627  destroyPQExpBuffer(query);
8628 }
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:2016

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _castInfo::castcontext, _castInfo::castfunc, _castInfo::castmethod, _castInfo::castsource, _castInfo::casttarget, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_CAST, _typeInfo::dobj, _castInfo::dobj, ExecuteSqlQuery(), findTypeByOid(), i, initPQExpBuffer(), _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, selectDumpableCast(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getCollations()

void getCollations ( Archive fout)

Definition at line 6141 of file pg_dump.c.

6142 {
6143  PGresult *res;
6144  int ntups;
6145  int i;
6146  PQExpBuffer query;
6147  CollInfo *collinfo;
6148  int i_tableoid;
6149  int i_oid;
6150  int i_collname;
6151  int i_collnamespace;
6152  int i_collowner;
6153 
6154  query = createPQExpBuffer();
6155 
6156  /*
6157  * find all collations, including builtin collations; we filter out
6158  * system-defined collations at dump-out time.
6159  */
6160 
6161  appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6162  "collnamespace, "
6163  "collowner "
6164  "FROM pg_collation");
6165 
6166  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6167 
6168  ntups = PQntuples(res);
6169 
6170  collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6171 
6172  i_tableoid = PQfnumber(res, "tableoid");
6173  i_oid = PQfnumber(res, "oid");
6174  i_collname = PQfnumber(res, "collname");
6175  i_collnamespace = PQfnumber(res, "collnamespace");
6176  i_collowner = PQfnumber(res, "collowner");
6177 
6178  for (i = 0; i < ntups; i++)
6179  {
6180  collinfo[i].dobj.objType = DO_COLLATION;
6181  collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6182  collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6183  AssignDumpId(&collinfo[i].dobj);
6184  collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6185  collinfo[i].dobj.namespace =
6186  findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6187  collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6188 
6189  /* Decide whether we want to dump it */
6190  selectDumpableObject(&(collinfo[i].dobj), fout);
6191  }
6192 
6193  PQclear(res);
6194 
6195  destroyPQExpBuffer(query);
6196 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_COLLATION, _collInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, _collInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getConstraints()

void getConstraints ( Archive fout,
TableInfo  tblinfo[],
int  numTables 
)

Definition at line 7809 of file pg_dump.c.

7810 {
7811  PQExpBuffer query = createPQExpBuffer();
7812  PQExpBuffer tbloids = createPQExpBuffer();
7813  PGresult *res;
7814  int ntups;
7815  int curtblindx;
7816  TableInfo *tbinfo = NULL;
7817  ConstraintInfo *constrinfo;
7818  int i_contableoid,
7819  i_conoid,
7820  i_conrelid,
7821  i_conname,
7822  i_confrelid,
7823  i_conindid,
7824  i_condef;
7825 
7826  /*
7827  * We want to perform just one query against pg_constraint. However, we
7828  * mustn't try to select every row of the catalog and then sort it out on
7829  * the client side, because some of the server-side functions we need
7830  * would be unsafe to apply to tables we don't have lock on. Hence, we
7831  * build an array of the OIDs of tables we care about (and now have lock
7832  * on!), and use a WHERE clause to constrain which rows are selected.
7833  */
7834  appendPQExpBufferChar(tbloids, '{');
7835  for (int i = 0; i < numTables; i++)
7836  {
7837  TableInfo *tinfo = &tblinfo[i];
7838 
7839  /*
7840  * For partitioned tables, foreign keys have no triggers so they must
7841  * be included anyway in case some foreign keys are defined.
7842  */
7843  if ((!tinfo->hastriggers &&
7844  tinfo->relkind != RELKIND_PARTITIONED_TABLE) ||
7845  !(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
7846  continue;
7847 
7848  /* OK, we need info for this table */
7849  if (tbloids->len > 1) /* do we have more than the '{'? */
7850  appendPQExpBufferChar(tbloids, ',');
7851  appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
7852  }
7853  appendPQExpBufferChar(tbloids, '}');
7854 
7855  appendPQExpBufferStr(query,
7856  "SELECT c.tableoid, c.oid, "
7857  "conrelid, conname, confrelid, ");
7858  if (fout->remoteVersion >= 110000)
7859  appendPQExpBufferStr(query, "conindid, ");
7860  else
7861  appendPQExpBufferStr(query, "0 AS conindid, ");
7862  appendPQExpBuffer(query,
7863  "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
7864  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7865  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
7866  "WHERE contype = 'f' ",
7867  tbloids->data);
7868  if (fout->remoteVersion >= 110000)
7869  appendPQExpBufferStr(query,
7870  "AND conparentid = 0 ");
7871  appendPQExpBufferStr(query,
7872  "ORDER BY conrelid, conname");
7873 
7874  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7875 
7876  ntups = PQntuples(res);
7877 
7878  i_contableoid = PQfnumber(res, "tableoid");
7879  i_conoid = PQfnumber(res, "oid");
7880  i_conrelid = PQfnumber(res, "conrelid");
7881  i_conname = PQfnumber(res, "conname");
7882  i_confrelid = PQfnumber(res, "confrelid");
7883  i_conindid = PQfnumber(res, "conindid");
7884  i_condef = PQfnumber(res, "condef");
7885 
7886  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
7887 
7888  curtblindx = -1;
7889  for (int j = 0; j < ntups; j++)
7890  {
7891  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
7892  TableInfo *reftable;
7893 
7894  /*
7895  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7896  * order.
7897  */
7898  if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
7899  {
7900  while (++curtblindx < numTables)
7901  {
7902  tbinfo = &tblinfo[curtblindx];
7903  if (tbinfo->dobj.catId.oid == conrelid)
7904  break;
7905  }
7906  if (curtblindx >= numTables)
7907  pg_fatal("unrecognized table OID %u", conrelid);
7908  }
7909 
7910  constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
7911  constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7912  constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7913  AssignDumpId(&constrinfo[j].dobj);
7914  constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7915  constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7916  constrinfo[j].contable = tbinfo;
7917  constrinfo[j].condomain = NULL;
7918  constrinfo[j].contype = 'f';
7919  constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
7920  constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
7921  constrinfo[j].conindex = 0;
7922  constrinfo[j].condeferrable = false;
7923  constrinfo[j].condeferred = false;
7924  constrinfo[j].conislocal = true;
7925  constrinfo[j].separate = true;
7926 
7927  /*
7928  * Restoring an FK that points to a partitioned table requires that
7929  * all partition indexes have been attached beforehand. Ensure that
7930  * happens by making the constraint depend on each index partition
7931  * attach object.
7932  */
7933  reftable = findTableByOid(constrinfo[j].confrelid);
7934  if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
7935  {
7936  Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
7937 
7938  if (indexOid != InvalidOid)
7939  {
7940  for (int k = 0; k < reftable->numIndexes; k++)
7941  {
7942  IndxInfo *refidx;
7943 
7944  /* not our index? */
7945  if (reftable->indexes[k].dobj.catId.oid != indexOid)
7946  continue;
7947 
7948  refidx = &reftable->indexes[k];
7949  addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
7950  break;
7951  }
7952  }
7953  }
7954  }
7955 
7956  PQclear(res);
7957 
7958  destroyPQExpBuffer(query);
7959  destroyPQExpBuffer(tbloids);
7960 }
struct _indxInfo * indexes
Definition: pg_dump.h:365
int numIndexes
Definition: pg_dump.h:364

References addConstrChildIdxDeps(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_FK_CONSTRAINT, _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, DUMP_COMPONENT_DEFINITION, ExecuteSqlQuery(), findTableByOid(), i, _tableInfo::indexes, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::numIndexes, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _tableInfo::relkind, Archive::remoteVersion, res, _constraintInfo::separate, CatalogId::tableoid, and tinfo.

Referenced by getSchemaData().

◆ getConversions()

void getConversions ( Archive fout)

Definition at line 6203 of file pg_dump.c.

6204 {
6205  PGresult *res;
6206  int ntups;
6207  int i;
6208  PQExpBuffer query;
6209  ConvInfo *convinfo;
6210  int i_tableoid;
6211  int i_oid;
6212  int i_conname;
6213  int i_connamespace;
6214  int i_conowner;
6215 
6216  query = createPQExpBuffer();
6217 
6218  /*
6219  * find all conversions, including builtin conversions; we filter out
6220  * system-defined conversions at dump-out time.
6221  */
6222 
6223  appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6224  "connamespace, "
6225  "conowner "
6226  "FROM pg_conversion");
6227 
6228  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6229 
6230  ntups = PQntuples(res);
6231 
6232  convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6233 
6234  i_tableoid = PQfnumber(res, "tableoid");
6235  i_oid = PQfnumber(res, "oid");
6236  i_conname = PQfnumber(res, "conname");
6237  i_connamespace = PQfnumber(res, "connamespace");
6238  i_conowner = PQfnumber(res, "conowner");
6239 
6240  for (i = 0; i < ntups; i++)
6241  {
6242  convinfo[i].dobj.objType = DO_CONVERSION;
6243  convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6244  convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6245  AssignDumpId(&convinfo[i].dobj);
6246  convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6247  convinfo[i].dobj.namespace =
6248  findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6249  convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6250 
6251  /* Decide whether we want to dump it */
6252  selectDumpableObject(&(convinfo[i].dobj), fout);
6253  }
6254 
6255  PQclear(res);
6256 
6257  destroyPQExpBuffer(query);
6258 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_CONVERSION, _convInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, _convInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getDefaultACLs()

void getDefaultACLs ( Archive fout)

Definition at line 9888 of file pg_dump.c.

9889 {
9890  DumpOptions *dopt = fout->dopt;
9891  DefaultACLInfo *daclinfo;
9892  PQExpBuffer query;
9893  PGresult *res;
9894  int i_oid;
9895  int i_tableoid;
9896  int i_defaclrole;
9897  int i_defaclnamespace;
9898  int i_defaclobjtype;
9899  int i_defaclacl;
9900  int i_acldefault;
9901  int i,
9902  ntups;
9903 
9904  query = createPQExpBuffer();
9905 
9906  /*
9907  * Global entries (with defaclnamespace=0) replace the hard-wired default
9908  * ACL for their object type. We should dump them as deltas from the
9909  * default ACL, since that will be used as a starting point for
9910  * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
9911  * non-global entries can only add privileges not revoke them. We must
9912  * dump those as-is (i.e., as deltas from an empty ACL).
9913  *
9914  * We can use defaclobjtype as the object type for acldefault(), except
9915  * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
9916  * 's'.
9917  */
9918  appendPQExpBufferStr(query,
9919  "SELECT oid, tableoid, "
9920  "defaclrole, "
9921  "defaclnamespace, "
9922  "defaclobjtype, "
9923  "defaclacl, "
9924  "CASE WHEN defaclnamespace = 0 THEN "
9925  "acldefault(CASE WHEN defaclobjtype = 'S' "
9926  "THEN 's'::\"char\" ELSE defaclobjtype END, "
9927  "defaclrole) ELSE '{}' END AS acldefault "
9928  "FROM pg_default_acl");
9929 
9930  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9931 
9932  ntups = PQntuples(res);
9933 
9934  daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
9935 
9936  i_oid = PQfnumber(res, "oid");
9937  i_tableoid = PQfnumber(res, "tableoid");
9938  i_defaclrole = PQfnumber(res, "defaclrole");
9939  i_defaclnamespace = PQfnumber(res, "defaclnamespace");
9940  i_defaclobjtype = PQfnumber(res, "defaclobjtype");
9941  i_defaclacl = PQfnumber(res, "defaclacl");
9942  i_acldefault = PQfnumber(res, "acldefault");
9943 
9944  for (i = 0; i < ntups; i++)
9945  {
9946  Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
9947 
9948  daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
9949  daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9950  daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9951  AssignDumpId(&daclinfo[i].dobj);
9952  /* cheesy ... is it worth coming up with a better object name? */
9953  daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
9954 
9955  if (nspid != InvalidOid)
9956  daclinfo[i].dobj.namespace = findNamespace(nspid);
9957  else
9958  daclinfo[i].dobj.namespace = NULL;
9959 
9960  daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9961  daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9962  daclinfo[i].dacl.privtype = 0;
9963  daclinfo[i].dacl.initprivs = NULL;
9964  daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
9965  daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
9966 
9967  /* Default ACLs are ACLs, of course */
9968  daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9969 
9970  /* Decide whether we want to dump it */
9971  selectDumpableDefaultACL(&(daclinfo[i]), dopt);
9972  }
9973 
9974  PQclear(res);
9975 
9976  destroyPQExpBuffer(query);
9977 }
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:1994

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _defaultACLInfo::dacl, PQExpBufferData::data, _defaultACLInfo::defaclobjtype, _defaultACLInfo::defaclrole, destroyPQExpBuffer(), DO_DEFAULT_ACL, _defaultACLInfo::dobj, Archive::dopt, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableAcl::initprivs, InvalidOid, _dumpableObject::name, nspid, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, selectDumpableDefaultACL(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getDependencies()

static void getDependencies ( Archive fout)
static

Definition at line 18693 of file pg_dump.c.

18694 {
18695  PQExpBuffer query;
18696  PGresult *res;
18697  int ntups,
18698  i;
18699  int i_classid,
18700  i_objid,
18701  i_refclassid,
18702  i_refobjid,
18703  i_deptype;
18704  DumpableObject *dobj,
18705  *refdobj;
18706 
18707  pg_log_info("reading dependency data");
18708 
18709  query = createPQExpBuffer();
18710 
18711  /*
18712  * Messy query to collect the dependency data we need. Note that we
18713  * ignore the sub-object column, so that dependencies of or on a column
18714  * look the same as dependencies of or on a whole table.
18715  *
18716  * PIN dependencies aren't interesting, and EXTENSION dependencies were
18717  * already processed by getExtensionMembership.
18718  */
18719  appendPQExpBufferStr(query, "SELECT "
18720  "classid, objid, refclassid, refobjid, deptype "
18721  "FROM pg_depend "
18722  "WHERE deptype != 'p' AND deptype != 'e'\n");
18723 
18724  /*
18725  * Since we don't treat pg_amop entries as separate DumpableObjects, we
18726  * have to translate their dependencies into dependencies of their parent
18727  * opfamily. Ignore internal dependencies though, as those will point to
18728  * their parent opclass, which we needn't consider here (and if we did,
18729  * it'd just result in circular dependencies). Also, "loose" opfamily
18730  * entries will have dependencies on their parent opfamily, which we
18731  * should drop since they'd likewise become useless self-dependencies.
18732  * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
18733  */
18734  appendPQExpBufferStr(query, "UNION ALL\n"
18735  "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
18736  "FROM pg_depend d, pg_amop o "
18737  "WHERE deptype NOT IN ('p', 'e', 'i') AND "
18738  "classid = 'pg_amop'::regclass AND objid = o.oid "
18739  "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
18740 
18741  /* Likewise for pg_amproc entries */
18742  appendPQExpBufferStr(query, "UNION ALL\n"
18743  "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
18744  "FROM pg_depend d, pg_amproc p "
18745  "WHERE deptype NOT IN ('p', 'e', 'i') AND "
18746  "classid = 'pg_amproc'::regclass AND objid = p.oid "
18747  "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
18748 
18749  /* Sort the output for efficiency below */
18750  appendPQExpBufferStr(query, "ORDER BY 1,2");
18751 
18752  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18753 
18754  ntups = PQntuples(res);
18755 
18756  i_classid = PQfnumber(res, "classid");
18757  i_objid = PQfnumber(res, "objid");
18758  i_refclassid = PQfnumber(res, "refclassid");
18759  i_refobjid = PQfnumber(res, "refobjid");
18760  i_deptype = PQfnumber(res, "deptype");
18761 
18762  /*
18763  * Since we ordered the SELECT by referencing ID, we can expect that
18764  * multiple entries for the same object will appear together; this saves
18765  * on searches.
18766  */
18767  dobj = NULL;
18768 
18769  for (i = 0; i < ntups; i++)
18770  {
18771  CatalogId objId;
18772  CatalogId refobjId;
18773  char deptype;
18774 
18775  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18776  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18777  refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
18778  refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
18779  deptype = *(PQgetvalue(res, i, i_deptype));
18780 
18781  if (dobj == NULL ||
18782  dobj->catId.tableoid != objId.tableoid ||
18783  dobj->catId.oid != objId.oid)
18784  dobj = findObjectByCatalogId(objId);
18785 
18786  /*
18787  * Failure to find objects mentioned in pg_depend is not unexpected,
18788  * since for example we don't collect info about TOAST tables.
18789  */
18790  if (dobj == NULL)
18791  {
18792 #ifdef NOT_USED
18793  pg_log_warning("no referencing object %u %u",
18794  objId.tableoid, objId.oid);
18795 #endif
18796  continue;
18797  }
18798 
18799  refdobj = findObjectByCatalogId(refobjId);
18800 
18801  if (refdobj == NULL)
18802  {
18803 #ifdef NOT_USED
18804  pg_log_warning("no referenced object %u %u",
18805  refobjId.tableoid, refobjId.oid);
18806 #endif
18807  continue;
18808  }
18809 
18810  /*
18811  * For 'x' dependencies, mark the object for later; we still add the
18812  * normal dependency, for possible ordering purposes. Currently
18813  * pg_dump_sort.c knows to put extensions ahead of all object types
18814  * that could possibly depend on them, but this is safer.
18815  */
18816  if (deptype == 'x')
18817  dobj->depends_on_ext = true;
18818 
18819  /*
18820  * Ordinarily, table rowtypes have implicit dependencies on their
18821  * tables. However, for a composite type the implicit dependency goes
18822  * the other way in pg_depend; which is the right thing for DROP but
18823  * it doesn't produce the dependency ordering we need. So in that one
18824  * case, we reverse the direction of the dependency.
18825  */
18826  if (deptype == 'i' &&
18827  dobj->objType == DO_TABLE &&
18828  refdobj->objType == DO_TYPE)
18829  addObjectDependency(refdobj, dobj->dumpId);
18830  else
18831  /* normal case */
18832  addObjectDependency(dobj, refdobj->dumpId);
18833  }
18834 
18835  PQclear(res);
18836 
18837  destroyPQExpBuffer(query);
18838 }

References addObjectDependency(), appendPQExpBufferStr(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpableObject::depends_on_ext, destroyPQExpBuffer(), DO_TABLE, DO_TYPE, _dumpableObject::dumpId, ExecuteSqlQuery(), findObjectByCatalogId(), i, _dumpableObject::objType, CatalogId::oid, pg_log_info, pg_log_warning, PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, and CatalogId::tableoid.

Referenced by main().

◆ getDomainConstraints()

static void getDomainConstraints ( Archive fout,
TypeInfo tyinfo 
)
static

Definition at line 7997 of file pg_dump.c.

7998 {
7999  int i;
8000  ConstraintInfo *constrinfo;
8001  PQExpBuffer query = createPQExpBuffer();
8002  PGresult *res;
8003  int i_tableoid,
8004  i_oid,
8005  i_conname,
8006  i_consrc;
8007  int ntups;
8008 
8010  {
8011  /* Set up query for constraint-specific details */
8012  appendPQExpBufferStr(query,
8013  "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
8014  "SELECT tableoid, oid, conname, "
8015  "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
8016  "convalidated "
8017  "FROM pg_catalog.pg_constraint "
8018  "WHERE contypid = $1 AND contype = 'c' "
8019  "ORDER BY conname");
8020 
8021  ExecuteSqlStatement(fout, query->data);
8022 
8024  }
8025 
8026  printfPQExpBuffer(query,
8027  "EXECUTE getDomainConstraints('%u')",
8028  tyinfo->dobj.catId.oid);
8029 
8030  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8031 
8032  ntups = PQntuples(res);
8033 
8034  i_tableoid = PQfnumber(res, "tableoid");
8035  i_oid = PQfnumber(res, "oid");
8036  i_conname = PQfnumber(res, "conname");
8037  i_consrc = PQfnumber(res, "consrc");
8038 
8039  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
8040 
8041  tyinfo->nDomChecks = ntups;
8042  tyinfo->domChecks = constrinfo;
8043 
8044  for (i = 0; i < ntups; i++)
8045  {
8046  bool validated = PQgetvalue(res, i, 4)[0] == 't';
8047 
8048  constrinfo[i].dobj.objType = DO_CONSTRAINT;
8049  constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8050  constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8051  AssignDumpId(&constrinfo[i].dobj);
8052  constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
8053  constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
8054  constrinfo[i].contable = NULL;
8055  constrinfo[i].condomain = tyinfo;
8056  constrinfo[i].contype = 'c';
8057  constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
8058  constrinfo[i].confrelid = InvalidOid;
8059  constrinfo[i].conindex = 0;
8060  constrinfo[i].condeferrable = false;
8061  constrinfo[i].condeferred = false;
8062  constrinfo[i].conislocal = true;
8063 
8064  constrinfo[i].separate = !validated;
8065 
8066  /*
8067  * Make the domain depend on the constraint, ensuring it won't be
8068  * output till any constraint dependencies are OK. If the constraint
8069  * has not been validated, it's going to be dumped after the domain
8070  * anyway, so this doesn't matter.
8071  */
8072  if (validated)
8073  addObjectDependency(&tyinfo->dobj,
8074  constrinfo[i].dobj.dumpId);
8075  }
8076 
8077  PQclear(res);
8078 
8079  destroyPQExpBuffer(query);
8080 }
@ PREPQUERY_GETDOMAINCONSTRAINTS
Definition: pg_backup.h:76

References addObjectDependency(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_CONSTRAINT, _typeInfo::dobj, _constraintInfo::dobj, _typeInfo::domChecks, _dumpableObject::dumpId, ExecuteSqlQuery(), ExecuteSqlStatement(), i, InvalidOid, Archive::is_prepared, _dumpableObject::name, _typeInfo::nDomChecks, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), PREPQUERY_GETDOMAINCONSTRAINTS, printfPQExpBuffer(), res, _constraintInfo::separate, and CatalogId::tableoid.

Referenced by getTypes().

◆ getEventTriggers()

void getEventTriggers ( Archive fout)

Definition at line 8380 of file pg_dump.c.

8381 {
8382  int i;
8383  PQExpBuffer query;
8384  PGresult *res;
8385  EventTriggerInfo *evtinfo;
8386  int i_tableoid,
8387  i_oid,
8388  i_evtname,
8389  i_evtevent,
8390  i_evtowner,
8391  i_evttags,
8392  i_evtfname,
8393  i_evtenabled;
8394  int ntups;
8395 
8396  /* Before 9.3, there are no event triggers */
8397  if (fout->remoteVersion < 90300)
8398  return;
8399 
8400  query = createPQExpBuffer();
8401 
8402  appendPQExpBufferStr(query,
8403  "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8404  "evtevent, evtowner, "
8405  "array_to_string(array("
8406  "select quote_literal(x) "
8407  " from unnest(evttags) as t(x)), ', ') as evttags, "
8408  "e.evtfoid::regproc as evtfname "
8409  "FROM pg_event_trigger e "
8410  "ORDER BY e.oid");
8411 
8412  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8413 
8414  ntups = PQntuples(res);
8415 
8416  evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8417 
8418  i_tableoid = PQfnumber(res, "tableoid");
8419  i_oid = PQfnumber(res, "oid");
8420  i_evtname = PQfnumber(res, "evtname");
8421  i_evtevent = PQfnumber(res, "evtevent");
8422  i_evtowner = PQfnumber(res, "evtowner");
8423  i_evttags = PQfnumber(res, "evttags");
8424  i_evtfname = PQfnumber(res, "evtfname");
8425  i_evtenabled = PQfnumber(res, "evtenabled");
8426 
8427  for (i = 0; i < ntups; i++)
8428  {
8429  evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8430  evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8431  evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8432  AssignDumpId(&evtinfo[i].dobj);
8433  evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8434  evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8435  evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8436  evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8437  evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8438  evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8439  evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8440 
8441  /* Decide whether we want to dump it */
8442  selectDumpableObject(&(evtinfo[i].dobj), fout);
8443  }
8444 
8445  PQclear(res);
8446 
8447  destroyPQExpBuffer(query);
8448 }
char * evtname
Definition: pg_dump.h:455

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_EVENT_TRIGGER, _evttriggerInfo::dobj, _evttriggerInfo::evtenabled, _evttriggerInfo::evtevent, _evttriggerInfo::evtfname, _evttriggerInfo::evtname, _evttriggerInfo::evtowner, _evttriggerInfo::evttags, ExecuteSqlQuery(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtendedStatistics()

void getExtendedStatistics ( Archive fout)

Definition at line 7730 of file pg_dump.c.

7731 {
7732  PQExpBuffer query;
7733  PGresult *res;
7734  StatsExtInfo *statsextinfo;
7735  int ntups;
7736  int i_tableoid;
7737  int i_oid;
7738  int i_stxname;
7739  int i_stxnamespace;
7740  int i_stxowner;
7741  int i_stxrelid;
7742  int i_stattarget;
7743  int i;
7744 
7745  /* Extended statistics were new in v10 */
7746  if (fout->remoteVersion < 100000)
7747  return;
7748 
7749  query = createPQExpBuffer();
7750 
7751  if (fout->remoteVersion < 130000)
7752  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7753  "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
7754  "FROM pg_catalog.pg_statistic_ext");
7755  else
7756  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7757  "stxnamespace, stxowner, stxrelid, stxstattarget "
7758  "FROM pg_catalog.pg_statistic_ext");
7759 
7760  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7761 
7762  ntups = PQntuples(res);
7763 
7764  i_tableoid = PQfnumber(res, "tableoid");
7765  i_oid = PQfnumber(res, "oid");
7766  i_stxname = PQfnumber(res, "stxname");
7767  i_stxnamespace = PQfnumber(res, "stxnamespace");
7768  i_stxowner = PQfnumber(res, "stxowner");
7769  i_stxrelid = PQfnumber(res, "stxrelid");
7770  i_stattarget = PQfnumber(res, "stxstattarget");
7771 
7772  statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
7773 
7774  for (i = 0; i < ntups; i++)
7775  {
7776  statsextinfo[i].dobj.objType = DO_STATSEXT;
7777  statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7778  statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7779  AssignDumpId(&statsextinfo[i].dobj);
7780  statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
7781  statsextinfo[i].dobj.namespace =
7782  findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
7783  statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
7784  statsextinfo[i].stattable =
7785  findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7786  if (PQgetisnull(res, i, i_stattarget))
7787  statsextinfo[i].stattarget = -1;
7788  else
7789  statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7790 
7791  /* Decide whether we want to dump it */
7792  selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
7793  }
7794 
7795  PQclear(res);
7796  destroyPQExpBuffer(query);
7797 }
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2159
TableInfo * stattable
Definition: pg_dump.h:428

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_STATSEXT, _statsExtInfo::dobj, ExecuteSqlQuery(), findNamespace(), findTableByOid(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _statsExtInfo::rolname, selectDumpableStatisticsObject(), _statsExtInfo::stattable, _statsExtInfo::stattarget, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtensionMembership()

void getExtensionMembership ( Archive fout,
ExtensionInfo  extinfo[],
int  numExtensions 
)

Definition at line 18419 of file pg_dump.c.

18421 {
18422  PQExpBuffer query;
18423  PGresult *res;
18424  int ntups,
18425  i;
18426  int i_classid,
18427  i_objid,
18428  i_refobjid;
18429  ExtensionInfo *ext;
18430 
18431  /* Nothing to do if no extensions */
18432  if (numExtensions == 0)
18433  return;
18434 
18435  query = createPQExpBuffer();
18436 
18437  /* refclassid constraint is redundant but may speed the search */
18438  appendPQExpBufferStr(query, "SELECT "
18439  "classid, objid, refobjid "
18440  "FROM pg_depend "
18441  "WHERE refclassid = 'pg_extension'::regclass "
18442  "AND deptype = 'e' "
18443  "ORDER BY 3");
18444 
18445  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18446 
18447  ntups = PQntuples(res);
18448 
18449  i_classid = PQfnumber(res, "classid");
18450  i_objid = PQfnumber(res, "objid");
18451  i_refobjid = PQfnumber(res, "refobjid");
18452 
18453  /*
18454  * Since we ordered the SELECT by referenced ID, we can expect that
18455  * multiple entries for the same extension will appear together; this
18456  * saves on searches.
18457  */
18458  ext = NULL;
18459 
18460  for (i = 0; i < ntups; i++)
18461  {
18462  CatalogId objId;
18463  Oid extId;
18464 
18465  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18466  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18467  extId = atooid(PQgetvalue(res, i, i_refobjid));
18468 
18469  if (ext == NULL ||
18470  ext->dobj.catId.oid != extId)
18471  ext = findExtensionByOid(extId);
18472 
18473  if (ext == NULL)
18474  {
18475  /* shouldn't happen */
18476  pg_log_warning("could not find referenced extension %u", extId);
18477  continue;
18478  }
18479 
18480  recordExtensionMembership(objId, ext);
18481  }
18482 
18483  PQclear(res);
18484 
18485  destroyPQExpBuffer(query);
18486 }
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1022
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:967

References appendPQExpBufferStr(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _extensionInfo::dobj, ExecuteSqlQuery(), findExtensionByOid(), i, CatalogId::oid, pg_log_warning, PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), recordExtensionMembership(), res, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtensions()

ExtensionInfo* getExtensions ( Archive fout,
int *  numExtensions 
)

Definition at line 5831 of file pg_dump.c.

5832 {
5833  DumpOptions *dopt = fout->dopt;
5834  PGresult *res;
5835  int ntups;
5836  int i;
5837  PQExpBuffer query;
5838  ExtensionInfo *extinfo = NULL;
5839  int i_tableoid;
5840  int i_oid;
5841  int i_extname;
5842  int i_nspname;
5843  int i_extrelocatable;
5844  int i_extversion;
5845  int i_extconfig;
5846  int i_extcondition;
5847 
5848  query = createPQExpBuffer();
5849 
5850  appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5851  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5852  "FROM pg_extension x "
5853  "JOIN pg_namespace n ON n.oid = x.extnamespace");
5854 
5855  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5856 
5857  ntups = PQntuples(res);
5858  if (ntups == 0)
5859  goto cleanup;
5860 
5861  extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5862 
5863  i_tableoid = PQfnumber(res, "tableoid");
5864  i_oid = PQfnumber(res, "oid");
5865  i_extname = PQfnumber(res, "extname");
5866  i_nspname = PQfnumber(res, "nspname");
5867  i_extrelocatable = PQfnumber(res, "extrelocatable");
5868  i_extversion = PQfnumber(res, "extversion");
5869  i_extconfig = PQfnumber(res, "extconfig");
5870  i_extcondition = PQfnumber(res, "extcondition");
5871 
5872  for (i = 0; i < ntups; i++)
5873  {
5874  extinfo[i].dobj.objType = DO_EXTENSION;
5875  extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5876  extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5877  AssignDumpId(&extinfo[i].dobj);
5878  extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5879  extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5880  extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5881  extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5882  extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5883  extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5884 
5885  /* Decide whether we want to dump it */
5886  selectDumpableExtension(&(extinfo[i]), dopt);
5887  }
5888 
5889 cleanup:
5890  PQclear(res);
5891  destroyPQExpBuffer(query);
5892 
5893  *numExtensions = ntups;
5894 
5895  return extinfo;
5896 }
static void cleanup(void)
Definition: bootstrap.c:691
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2102

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, cleanup(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_EXTENSION, _extensionInfo::dobj, Archive::dopt, ExecuteSqlQuery(), _extensionInfo::extcondition, _extensionInfo::extconfig, _extensionInfo::extversion, i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _extensionInfo::relocatable, res, selectDumpableExtension(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignDataWrappers()

void getForeignDataWrappers ( Archive fout)

Definition at line 9716 of file pg_dump.c.

9717 {
9718  PGresult *res;
9719  int ntups;
9720  int i;
9721  PQExpBuffer query;
9722  FdwInfo *fdwinfo;
9723  int i_tableoid;
9724  int i_oid;
9725  int i_fdwname;
9726  int i_fdwowner;
9727  int i_fdwhandler;
9728  int i_fdwvalidator;
9729  int i_fdwacl;
9730  int i_acldefault;
9731  int i_fdwoptions;
9732 
9733  query = createPQExpBuffer();
9734 
9735  appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
9736  "fdwowner, "
9737  "fdwhandler::pg_catalog.regproc, "
9738  "fdwvalidator::pg_catalog.regproc, "
9739  "fdwacl, "
9740  "acldefault('F', fdwowner) AS acldefault, "
9741  "array_to_string(ARRAY("
9742  "SELECT quote_ident(option_name) || ' ' || "
9743  "quote_literal(option_value) "
9744  "FROM pg_options_to_table(fdwoptions) "
9745  "ORDER BY option_name"
9746  "), E',\n ') AS fdwoptions "
9747  "FROM pg_foreign_data_wrapper");
9748 
9749  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9750 
9751  ntups = PQntuples(res);
9752 
9753  fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
9754 
9755  i_tableoid = PQfnumber(res, "tableoid");
9756  i_oid = PQfnumber(res, "oid");
9757  i_fdwname = PQfnumber(res, "fdwname");
9758  i_fdwowner = PQfnumber(res, "fdwowner");
9759  i_fdwhandler = PQfnumber(res, "fdwhandler");
9760  i_fdwvalidator = PQfnumber(res, "fdwvalidator");
9761  i_fdwacl = PQfnumber(res, "fdwacl");
9762  i_acldefault = PQfnumber(res, "acldefault");
9763  i_fdwoptions = PQfnumber(res, "fdwoptions");
9764 
9765  for (i = 0; i < ntups; i++)
9766  {
9767  fdwinfo[i].dobj.objType = DO_FDW;
9768  fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9769  fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9770  AssignDumpId(&fdwinfo[i].dobj);
9771  fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
9772  fdwinfo[i].dobj.namespace = NULL;
9773  fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
9774  fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9775  fdwinfo[i].dacl.privtype = 0;
9776  fdwinfo[i].dacl.initprivs = NULL;
9777  fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
9778  fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
9779  fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
9780  fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
9781 
9782  /* Decide whether we want to dump it */
9783  selectDumpableObject(&(fdwinfo[i].dobj), fout);
9784 
9785  /* Mark whether FDW has an ACL */
9786  if (!PQgetisnull(res, i, i_fdwacl))
9787  fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9788  }
9789 
9790  PQclear(res);
9791 
9792  destroyPQExpBuffer(query);
9793 }

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _fdwInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_FDW, _fdwInfo::dobj, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), _fdwInfo::fdwhandler, _fdwInfo::fdwoptions, _fdwInfo::fdwvalidator, getRoleName(), i, _dumpableAcl::initprivs, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, _fdwInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignServers()

void getForeignServers ( Archive fout)

Definition at line 9800 of file pg_dump.c.

9801 {
9802  PGresult *res;
9803  int ntups;
9804  int i;
9805  PQExpBuffer query;
9806  ForeignServerInfo *srvinfo;
9807  int i_tableoid;
9808  int i_oid;
9809  int i_srvname;
9810  int i_srvowner;
9811  int i_srvfdw;
9812  int i_srvtype;
9813  int i_srvversion;
9814  int i_srvacl;
9815  int i_acldefault;
9816  int i_srvoptions;
9817 
9818  query = createPQExpBuffer();
9819 
9820  appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
9821  "srvowner, "
9822  "srvfdw, srvtype, srvversion, srvacl, "
9823  "acldefault('S', srvowner) AS acldefault, "
9824  "array_to_string(ARRAY("
9825  "SELECT quote_ident(option_name) || ' ' || "
9826  "quote_literal(option_value) "
9827  "FROM pg_options_to_table(srvoptions) "
9828  "ORDER BY option_name"
9829  "), E',\n ') AS srvoptions "
9830  "FROM pg_foreign_server");
9831 
9832  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9833 
9834  ntups = PQntuples(res);
9835 
9836  srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
9837 
9838  i_tableoid = PQfnumber(res, "tableoid");
9839  i_oid = PQfnumber(res, "oid");
9840  i_srvname = PQfnumber(res, "srvname");
9841  i_srvowner = PQfnumber(res, "srvowner");
9842  i_srvfdw = PQfnumber(res, "srvfdw");
9843  i_srvtype = PQfnumber(res, "srvtype");
9844  i_srvversion = PQfnumber(res, "srvversion");
9845  i_srvacl = PQfnumber(res, "srvacl");
9846  i_acldefault = PQfnumber(res, "acldefault");
9847  i_srvoptions = PQfnumber(res, "srvoptions");
9848 
9849  for (i = 0; i < ntups; i++)
9850  {
9851  srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
9852  srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9853  srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9854  AssignDumpId(&srvinfo[i].dobj);
9855  srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
9856  srvinfo[i].dobj.namespace = NULL;
9857  srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
9858  srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9859  srvinfo[i].dacl.privtype = 0;
9860  srvinfo[i].dacl.initprivs = NULL;
9861  srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
9862  srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
9863  srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
9864  srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
9865  srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
9866 
9867  /* Decide whether we want to dump it */
9868  selectDumpableObject(&(srvinfo[i].dobj), fout);
9869 
9870  /* Servers have user mappings */
9872 
9873  /* Mark whether server has an ACL */
9874  if (!PQgetisnull(res, i, i_srvacl))
9875  srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9876  }
9877 
9878  PQclear(res);
9879 
9880  destroyPQExpBuffer(query);
9881 }

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _foreignServerInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_FOREIGN_SERVER, _foreignServerInfo::dobj, DUMP_COMPONENT_ACL, DUMP_COMPONENT_USERMAP, ExecuteSqlQuery(), getRoleName(), i, _dumpableAcl::initprivs, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, _foreignServerInfo::rolname, selectDumpableObject(), _foreignServerInfo::srvfdw, _foreignServerInfo::srvoptions, _foreignServerInfo::srvtype, _foreignServerInfo::srvversion, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getFormattedOperatorName()

static char * getFormattedOperatorName ( const char *  oproid)
static

Definition at line 13209 of file pg_dump.c.

13210 {
13211  OprInfo *oprInfo;
13212 
13213  /* In all cases "0" means a null reference */
13214  if (strcmp(oproid, "0") == 0)
13215  return NULL;
13216 
13217  oprInfo = findOprByOid(atooid(oproid));
13218  if (oprInfo == NULL)
13219  {
13220  pg_log_warning("could not find operator with OID %s",
13221  oproid);
13222  return NULL;
13223  }
13224 
13225  return psprintf("OPERATOR(%s.%s)",
13226  fmtId(oprInfo->dobj.namespace->dobj.name),
13227  oprInfo->dobj.name);
13228 }
OprInfo * findOprByOid(Oid oid)
Definition: common.c:913

References atooid, _oprInfo::dobj, findOprByOid(), fmtId(), _dumpableObject::name, pg_log_warning, and psprintf().

Referenced by dumpAgg(), and dumpOpr().

◆ getFormattedTypeName()

static const char * getFormattedTypeName ( Archive fout,
Oid  oid,
OidOptions  opts 
)
static

Definition at line 19090 of file pg_dump.c.

19091 {
19092  TypeInfo *typeInfo;
19093  char *result;
19094  PQExpBuffer query;
19095  PGresult *res;
19096 
19097  if (oid == 0)
19098  {
19099  if ((opts & zeroAsStar) != 0)
19100  return "*";
19101  else if ((opts & zeroAsNone) != 0)
19102  return "NONE";
19103  }
19104 
19105  /* see if we have the result cached in the type's TypeInfo record */
19106  typeInfo = findTypeByOid(oid);
19107  if (typeInfo && typeInfo->ftypname)
19108  return typeInfo->ftypname;
19109 
19110  query = createPQExpBuffer();
19111  appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
19112  oid);
19113 
19114  res = ExecuteSqlQueryForSingleRow(fout, query->data);
19115 
19116  /* result of format_type is already quoted */
19117  result = pg_strdup(PQgetvalue(res, 0, 0));
19118 
19119  PQclear(res);
19120  destroyPQExpBuffer(query);
19121 
19122  /*
19123  * Cache the result for re-use in later requests, if possible. If we
19124  * don't have a TypeInfo for the type, the string will be leaked once the
19125  * caller is done with it ... but that case really should not happen, so
19126  * leaking if it does seems acceptable.
19127  */
19128  if (typeInfo)
19129  typeInfo->ftypname = result;
19130 
19131  return result;
19132 }
static AmcheckOptions opts
Definition: pg_amcheck.c:111
char * ftypname
Definition: pg_dump.h:199

References appendPQExpBuffer(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), findTypeByOid(), _typeInfo::ftypname, opts, pg_strdup(), PQclear(), PQgetvalue(), res, zeroAsNone, and zeroAsStar.

Referenced by dumpBaseType(), dumpCast(), dumpFunc(), dumpTableSchema(), dumpTransform(), format_aggregate_signature(), and format_function_signature().

◆ getFuncs()

void getFuncs ( Archive fout)

Definition at line 6590 of file pg_dump.c.

6591 {
6592  DumpOptions *dopt = fout->dopt;
6593  PGresult *res;
6594  int ntups;
6595  int i;
6596  PQExpBuffer query = createPQExpBuffer();
6597  FuncInfo *finfo;
6598  int i_tableoid;
6599  int i_oid;
6600  int i_proname;
6601  int i_pronamespace;
6602  int i_proowner;
6603  int i_prolang;
6604  int i_pronargs;
6605  int i_proargtypes;
6606  int i_prorettype;
6607  int i_proacl;
6608  int i_acldefault;
6609 
6610  /*
6611  * Find all interesting functions. This is a bit complicated:
6612  *
6613  * 1. Always exclude aggregates; those are handled elsewhere.
6614  *
6615  * 2. Always exclude functions that are internally dependent on something
6616  * else, since presumably those will be created as a result of creating
6617  * the something else. This currently acts only to suppress constructor
6618  * functions for range types. Note this is OK only because the
6619  * constructors don't have any dependencies the range type doesn't have;
6620  * otherwise we might not get creation ordering correct.
6621  *
6622  * 3. Otherwise, we normally exclude functions in pg_catalog. However, if
6623  * they're members of extensions and we are in binary-upgrade mode then
6624  * include them, since we want to dump extension members individually in
6625  * that mode. Also, if they are used by casts or transforms then we need
6626  * to gather the information about them, though they won't be dumped if
6627  * they are built-in. Also, in 9.6 and up, include functions in
6628  * pg_catalog if they have an ACL different from what's shown in
6629  * pg_init_privs (so we have to join to pg_init_privs; annoying).
6630  */
6631  if (fout->remoteVersion >= 90600)
6632  {
6633  const char *not_agg_check;
6634 
6635  not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
6636  : "NOT p.proisagg");
6637 
6638  appendPQExpBuffer(query,
6639  "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
6640  "p.pronargs, p.proargtypes, p.prorettype, "
6641  "p.proacl, "
6642  "acldefault('f', p.proowner) AS acldefault, "
6643  "p.pronamespace, "
6644  "p.proowner "
6645  "FROM pg_proc p "
6646  "LEFT JOIN pg_init_privs pip ON "
6647  "(p.oid = pip.objoid "
6648  "AND pip.classoid = 'pg_proc'::regclass "
6649  "AND pip.objsubid = 0) "
6650  "WHERE %s"
6651  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6652  "WHERE classid = 'pg_proc'::regclass AND "
6653  "objid = p.oid AND deptype = 'i')"
6654  "\n AND ("
6655  "\n pronamespace != "
6656  "(SELECT oid FROM pg_namespace "
6657  "WHERE nspname = 'pg_catalog')"
6658  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6659  "\n WHERE pg_cast.oid > %u "
6660  "\n AND p.oid = pg_cast.castfunc)"
6661  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6662  "\n WHERE pg_transform.oid > %u AND "
6663  "\n (p.oid = pg_transform.trffromsql"
6664  "\n OR p.oid = pg_transform.trftosql))",
6665  not_agg_check,
6668  if (dopt->binary_upgrade)
6669  appendPQExpBufferStr(query,
6670  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6671  "classid = 'pg_proc'::regclass AND "
6672  "objid = p.oid AND "
6673  "refclassid = 'pg_extension'::regclass AND "
6674  "deptype = 'e')");
6675  appendPQExpBufferStr(query,
6676  "\n OR p.proacl IS DISTINCT FROM pip.initprivs");
6677  appendPQExpBufferChar(query, ')');
6678  }
6679  else
6680  {
6681  appendPQExpBuffer(query,
6682  "SELECT tableoid, oid, proname, prolang, "
6683  "pronargs, proargtypes, prorettype, proacl, "
6684  "acldefault('f', proowner) AS acldefault, "
6685  "pronamespace, "
6686  "proowner "
6687  "FROM pg_proc p "
6688  "WHERE NOT proisagg"
6689  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6690  "WHERE classid = 'pg_proc'::regclass AND "
6691  "objid = p.oid AND deptype = 'i')"
6692  "\n AND ("
6693  "\n pronamespace != "
6694  "(SELECT oid FROM pg_namespace "
6695  "WHERE nspname = 'pg_catalog')"
6696  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6697  "\n WHERE pg_cast.oid > '%u'::oid"
6698  "\n AND p.oid = pg_cast.castfunc)",
6700 
6701  if (fout->remoteVersion >= 90500)
6702  appendPQExpBuffer(query,
6703  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6704  "\n WHERE pg_transform.oid > '%u'::oid"
6705  "\n AND (p.oid = pg_transform.trffromsql"
6706  "\n OR p.oid = pg_transform.trftosql))",
6708 
6709  if (dopt->binary_upgrade)
6710  appendPQExpBufferStr(query,
6711  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6712  "classid = 'pg_proc'::regclass AND "
6713  "objid = p.oid AND "
6714  "refclassid = 'pg_extension'::regclass AND "
6715  "deptype = 'e')");
6716  appendPQExpBufferChar(query, ')');
6717  }
6718 
6719  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6720 
6721  ntups = PQntuples(res);
6722 
6723  finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
6724 
6725  i_tableoid = PQfnumber(res, "tableoid");
6726  i_oid = PQfnumber(res, "oid");
6727  i_proname = PQfnumber(res, "proname");
6728  i_pronamespace = PQfnumber(res, "pronamespace");
6729  i_proowner = PQfnumber(res, "proowner");
6730  i_prolang = PQfnumber(res, "prolang");
6731  i_pronargs = PQfnumber(res, "pronargs");
6732  i_proargtypes = PQfnumber(res, "proargtypes");
6733  i_prorettype = PQfnumber(res, "prorettype");
6734  i_proacl = PQfnumber(res, "proacl");
6735  i_acldefault = PQfnumber(res, "acldefault");
6736 
6737  for (i = 0; i < ntups; i++)
6738  {
6739  finfo[i].dobj.objType = DO_FUNC;
6740  finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6741  finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6742  AssignDumpId(&finfo[i].dobj);
6743  finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
6744  finfo[i].dobj.namespace =
6745  findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
6746  finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
6747  finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6748  finfo[i].dacl.privtype = 0;
6749  finfo[i].dacl.initprivs = NULL;
6750  finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6751  finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
6752  finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
6753  finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
6754  if (finfo[i].nargs == 0)
6755  finfo[i].argtypes = NULL;
6756  else
6757  {
6758  finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
6759  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6760  finfo[i].argtypes, finfo[i].nargs);
6761  }
6762  finfo[i].postponed_def = false; /* might get set during sort */
6763 
6764  /* Decide whether we want to dump it */
6765  selectDumpableObject(&(finfo[i].dobj), fout);
6766 
6767  /* Mark whether function has an ACL */
6768  if (!PQgetisnull(res, i, i_proacl))
6769  finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
6770  }
6771 
6772  PQclear(res);
6773 
6774  destroyPQExpBuffer(query);
6775 }
static Oid g_last_builtin_oid
Definition: pg_dump.c:147
Oid lang
Definition: pg_dump.h:228

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), _funcInfo::argtypes, AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _funcInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_FUNC, _funcInfo::dobj, Archive::dopt, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findNamespace(), g_last_builtin_oid, getRoleName(), i, _dumpableAcl::initprivs, _funcInfo::lang, _dumpableObject::name, _funcInfo::nargs, _dumpableObject::objType, CatalogId::oid, parseOidArray(), pg_malloc(), pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, _funcInfo::postponed_def, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, _funcInfo::prorettype, Archive::remoteVersion, res, _funcInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getIndexes()

void getIndexes ( Archive fout,
TableInfo  tblinfo[],
int  numTables 
)

Definition at line 7410 of file pg_dump.c.

7411 {
7412  PQExpBuffer query = createPQExpBuffer();
7413  PQExpBuffer tbloids = createPQExpBuffer();
7414  PGresult *res;
7415  int ntups;
7416  int curtblindx;
7417  IndxInfo *indxinfo;
7418  int i_tableoid,
7419  i_oid,
7420  i_indrelid,
7421  i_indexname,
7422  i_parentidx,
7423  i_indexdef,
7424  i_indnkeyatts,
7425  i_indnatts,
7426  i_indkey,
7427  i_indisclustered,
7428  i_indisreplident,
7429  i_indnullsnotdistinct,
7430  i_contype,
7431  i_conname,
7432  i_condeferrable,
7433  i_condeferred,
7434  i_conperiod,
7435  i_contableoid,
7436  i_conoid,
7437  i_condef,
7438  i_tablespace,
7439  i_indreloptions,
7440  i_indstatcols,
7441  i_indstatvals;
7442 
7443  /*
7444  * We want to perform just one query against pg_index. However, we
7445  * mustn't try to select every row of the catalog and then sort it out on
7446  * the client side, because some of the server-side functions we need
7447  * would be unsafe to apply to tables we don't have lock on. Hence, we
7448  * build an array of the OIDs of tables we care about (and now have lock
7449  * on!), and use a WHERE clause to constrain which rows are selected.
7450  */
7451  appendPQExpBufferChar(tbloids, '{');
7452  for (int i = 0; i < numTables; i++)
7453  {
7454  TableInfo *tbinfo = &tblinfo[i];
7455 
7456  if (!tbinfo->hasindex)
7457  continue;
7458 
7459  /*
7460  * We can ignore indexes of uninteresting tables.
7461  */
7462  if (!tbinfo->interesting)
7463  continue;
7464 
7465  /* OK, we need info for this table */
7466  if (tbloids->len > 1) /* do we have more than the '{'? */
7467  appendPQExpBufferChar(tbloids, ',');
7468  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
7469  }
7470  appendPQExpBufferChar(tbloids, '}');
7471 
7472  appendPQExpBufferStr(query,
7473  "SELECT t.tableoid, t.oid, i.indrelid, "
7474  "t.relname AS indexname, "
7475  "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7476  "i.indkey, i.indisclustered, "
7477  "c.contype, c.conname, "
7478  "c.condeferrable, c.condeferred, "
7479  "c.tableoid AS contableoid, "
7480  "c.oid AS conoid, "
7481  "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
7482  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
7483  "t.reloptions AS indreloptions, ");
7484 
7485 
7486  if (fout->remoteVersion >= 90400)
7487  appendPQExpBufferStr(query,
7488  "i.indisreplident, ");
7489  else
7490  appendPQExpBufferStr(query,
7491  "false AS indisreplident, ");
7492 
7493  if (fout->remoteVersion >= 110000)
7494  appendPQExpBufferStr(query,
7495  "inh.inhparent AS parentidx, "
7496  "i.indnkeyatts AS indnkeyatts, "
7497  "i.indnatts AS indnatts, "
7498  "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
7499  " FROM pg_catalog.pg_attribute "
7500  " WHERE attrelid = i.indexrelid AND "
7501  " attstattarget >= 0) AS indstatcols, "
7502  "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
7503  " FROM pg_catalog.pg_attribute "
7504  " WHERE attrelid = i.indexrelid AND "
7505  " attstattarget >= 0) AS indstatvals, ");
7506  else
7507  appendPQExpBufferStr(query,
7508  "0 AS parentidx, "
7509  "i.indnatts AS indnkeyatts, "
7510  "i.indnatts AS indnatts, "
7511  "'' AS indstatcols, "
7512  "'' AS indstatvals, ");
7513 
7514  if (fout->remoteVersion >= 150000)
7515  appendPQExpBufferStr(query,
7516  "i.indnullsnotdistinct, ");
7517  else
7518  appendPQExpBufferStr(query,
7519  "false AS indnullsnotdistinct, ");
7520 
7521  if (fout->remoteVersion >= 180000)
7522  appendPQExpBufferStr(query,
7523  "c.conperiod ");
7524  else
7525  appendPQExpBufferStr(query,
7526  "NULL AS conperiod ");
7527 
7528  /*
7529  * The point of the messy-looking outer join is to find a constraint that
7530  * is related by an internal dependency link to the index. If we find one,
7531  * create a CONSTRAINT entry linked to the INDEX entry. We assume an
7532  * index won't have more than one internal dependency.
7533  *
7534  * Note: the check on conrelid is redundant, but useful because that
7535  * column is indexed while conindid is not.
7536  */
7537  if (fout->remoteVersion >= 110000)
7538  {
7539  appendPQExpBuffer(query,
7540  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7541  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7542  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7543  "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
7544  "LEFT JOIN pg_catalog.pg_constraint c "
7545  "ON (i.indrelid = c.conrelid AND "
7546  "i.indexrelid = c.conindid AND "
7547  "c.contype IN ('p','u','x')) "
7548  "LEFT JOIN pg_catalog.pg_inherits inh "
7549  "ON (inh.inhrelid = indexrelid) "
7550  "WHERE (i.indisvalid OR t2.relkind = 'p') "
7551  "AND i.indisready "
7552  "ORDER BY i.indrelid, indexname",
7553  tbloids->data);
7554  }
7555  else
7556  {
7557  /*
7558  * the test on indisready is necessary in 9.2, and harmless in
7559  * earlier/later versions
7560  */
7561  appendPQExpBuffer(query,
7562  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7563  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7564  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7565  "LEFT JOIN pg_catalog.pg_constraint c "
7566  "ON (i.indrelid = c.conrelid AND "
7567  "i.indexrelid = c.conindid AND "
7568  "c.contype IN ('p','u','x')) "
7569  "WHERE i.indisvalid AND i.indisready "
7570  "ORDER BY i.indrelid, indexname",
7571  tbloids->data);
7572  }
7573 
7574  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7575 
7576  ntups = PQntuples(res);
7577 
7578  i_tableoid = PQfnumber(res, "tableoid");
7579  i_oid = PQfnumber(res, "oid");
7580  i_indrelid = PQfnumber(res, "indrelid");
7581  i_indexname = PQfnumber(res, "indexname");
7582  i_parentidx = PQfnumber(res, "parentidx");
7583  i_indexdef = PQfnumber(res, "indexdef");
7584  i_indnkeyatts = PQfnumber(res, "indnkeyatts");
7585  i_indnatts = PQfnumber(res, "indnatts");
7586  i_indkey = PQfnumber(res, "indkey");
7587  i_indisclustered = PQfnumber(res, "indisclustered");
7588  i_indisreplident = PQfnumber(res, "indisreplident");
7589  i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
7590  i_contype = PQfnumber(res, "contype");
7591  i_conname = PQfnumber(res, "conname");
7592  i_condeferrable = PQfnumber(res, "condeferrable");
7593  i_condeferred = PQfnumber(res, "condeferred");
7594  i_conperiod = PQfnumber(res, "conperiod");
7595  i_contableoid = PQfnumber(res, "contableoid");
7596  i_conoid = PQfnumber(res, "conoid");
7597  i_condef = PQfnumber(res, "condef");
7598  i_tablespace = PQfnumber(res, "tablespace");
7599  i_indreloptions = PQfnumber(res, "indreloptions");
7600  i_indstatcols = PQfnumber(res, "indstatcols");
7601  i_indstatvals = PQfnumber(res, "indstatvals");
7602 
7603  indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
7604 
7605  /*
7606  * Outer loop iterates once per table, not once per row. Incrementing of
7607  * j is handled by the inner loop.
7608  */
7609  curtblindx = -1;
7610  for (int j = 0; j < ntups;)
7611  {
7612  Oid indrelid = atooid(PQgetvalue(res, j, i_indrelid));
7613  TableInfo *tbinfo = NULL;
7614  int numinds;
7615 
7616  /* Count rows for this table */
7617  for (numinds = 1; numinds < ntups - j; numinds++)
7618  if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
7619  break;
7620 
7621  /*
7622  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7623  * order.
7624  */
7625  while (++curtblindx < numTables)
7626  {
7627  tbinfo = &tblinfo[curtblindx];
7628  if (tbinfo->dobj.catId.oid == indrelid)
7629  break;
7630  }
7631  if (curtblindx >= numTables)
7632  pg_fatal("unrecognized table OID %u", indrelid);
7633  /* cross-check that we only got requested tables */
7634  if (!tbinfo->hasindex ||
7635  !tbinfo->interesting)
7636  pg_fatal("unexpected index data for table \"%s\"",
7637  tbinfo->dobj.name);
7638 
7639  /* Save data for this table */
7640  tbinfo->indexes = indxinfo + j;
7641  tbinfo->numIndexes = numinds;
7642 
7643  for (int c = 0; c < numinds; c++, j++)
7644  {
7645  char contype;
7646 
7647  indxinfo[j].dobj.objType = DO_INDEX;
7648  indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
7649  indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
7650  AssignDumpId(&indxinfo[j].dobj);
7651  indxinfo[j].dobj.dump = tbinfo->dobj.dump;
7652  indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
7653  indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7654  indxinfo[j].indextable = tbinfo;
7655  indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
7656  indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
7657  indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
7658  indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
7659  indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
7660  indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
7661  indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
7662  indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
7663  parseOidArray(PQgetvalue(res, j, i_indkey),
7664  indxinfo[j].indkeys, indxinfo[j].indnattrs);
7665  indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
7666  indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
7667  indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
7668  indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
7669  indxinfo[j].partattaches = (SimplePtrList)
7670  {
7671  NULL, NULL
7672  };
7673  contype = *(PQgetvalue(res, j, i_contype));
7674 
7675  if (contype == 'p' || contype == 'u' || contype == 'x')
7676  {
7677  /*
7678  * If we found a constraint matching the index, create an
7679  * entry for it.
7680  */
7681  ConstraintInfo *constrinfo;
7682 
7683  constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
7684  constrinfo->dobj.objType = DO_CONSTRAINT;
7685  constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7686  constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7687  AssignDumpId(&constrinfo->dobj);
7688  constrinfo->dobj.dump = tbinfo->dobj.dump;
7689  constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7690  constrinfo->dobj.namespace = tbinfo->dobj.namespace;
7691  constrinfo->contable = tbinfo;
7692  constrinfo->condomain = NULL;
7693  constrinfo->contype = contype;
7694  if (contype == 'x')
7695  constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
7696  else
7697  constrinfo->condef = NULL;
7698  constrinfo->confrelid = InvalidOid;
7699  constrinfo->conindex = indxinfo[j].dobj.dumpId;
7700  constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
7701  constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
7702  constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
7703  constrinfo->conislocal = true;
7704  constrinfo->separate = true;
7705 
7706  indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
7707  }
7708  else
7709  {
7710  /* Plain secondary index */
7711  indxinfo[j].indexconstraint = 0;
7712  }
7713  }
7714  }
7715 
7716  PQclear(res);
7717 
7718  destroyPQExpBuffer(query);
7719  destroyPQExpBuffer(tbloids);
7720 }
char * c
struct SimplePtrList SimplePtrList
Oid parentidx
Definition: pg_dump.h:410
bool hasindex
Definition: pg_dump.h:297

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::conperiod, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_CONSTRAINT, DO_INDEX, _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), _tableInfo::hasindex, i, _indxInfo::indexconstraint, _indxInfo::indexdef, _tableInfo::indexes, _indxInfo::indextable, _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indkeys, _indxInfo::indnattrs, _indxInfo::indnkeyattrs, _indxInfo::indnullsnotdistinct, _indxInfo::indreloptions, _indxInfo::indstatcols, _indxInfo::indstatvals, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::numIndexes, _dumpableObject::objType, CatalogId::oid, _indxInfo::parentidx, parseOidArray(), _indxInfo::partattaches, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _constraintInfo::separate, CatalogId::tableoid, and _indxInfo::tablespace.

Referenced by getSchemaData().

◆ getInherits()

InhInfo* getInherits ( Archive fout,
int *  numInherits 
)

Definition at line 7294 of file pg_dump.c.

7295 {
7296  PGresult *res;
7297  int ntups;
7298  int i;
7299  PQExpBuffer query = createPQExpBuffer();
7300  InhInfo *inhinfo;
7301 
7302  int i_inhrelid;
7303  int i_inhparent;
7304 
7305  /* find all the inheritance information */
7306  appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7307 
7308  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7309 
7310  ntups = PQntuples(res);
7311 
7312  *numInherits = ntups;
7313 
7314  inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7315 
7316  i_inhrelid = PQfnumber(res, "inhrelid");
7317  i_inhparent = PQfnumber(res, "inhparent");
7318 
7319  for (i = 0; i < ntups; i++)
7320  {
7321  inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7322  inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7323  }
7324 
7325  PQclear(res);
7326 
7327  destroyPQExpBuffer(query);
7328 
7329  return inhinfo;
7330 }
Oid inhparent
Definition: pg_dump.h:521
Oid inhrelid
Definition: pg_dump.h:520

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), i, _inhInfo::inhparent, _inhInfo::inhrelid, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), and res.

Referenced by getSchemaData().

◆ getLOs()

static void getLOs ( Archive fout)
static

Definition at line 3712 of file pg_dump.c.

3713 {
3714  DumpOptions *dopt = fout->dopt;
3715  PQExpBuffer loQry = createPQExpBuffer();
3716  PGresult *res;
3717  int ntups;
3718  int i;
3719  int n;
3720  int i_oid;
3721  int i_lomowner;
3722  int i_lomacl;
3723  int i_acldefault;
3724 
3725  pg_log_info("reading large objects");
3726 
3727  /*
3728  * Fetch LO OIDs and owner/ACL data. Order the data so that all the blobs
3729  * with the same owner/ACL appear together.
3730  */
3731  appendPQExpBufferStr(loQry,
3732  "SELECT oid, lomowner, lomacl, "
3733  "acldefault('L', lomowner) AS acldefault "
3734  "FROM pg_largeobject_metadata "
3735  "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
3736 
3737  res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
3738 
3739  i_oid = PQfnumber(res, "oid");
3740  i_lomowner = PQfnumber(res, "lomowner");
3741  i_lomacl = PQfnumber(res, "lomacl");
3742  i_acldefault = PQfnumber(res, "acldefault");
3743 
3744  ntups = PQntuples(res);
3745 
3746  /*
3747  * Group the blobs into suitably-sized groups that have the same owner and
3748  * ACL setting, and build a metadata and a data DumpableObject for each
3749  * group. (If we supported initprivs for blobs, we'd have to insist that
3750  * groups also share initprivs settings, since the DumpableObject only has
3751  * room for one.) i is the index of the first tuple in the current group,
3752  * and n is the number of tuples we include in the group.
3753  */
3754  for (i = 0; i < ntups; i += n)
3755  {
3756  Oid thisoid = atooid(PQgetvalue(res, i, i_oid));
3757  char *thisowner = PQgetvalue(res, i, i_lomowner);
3758  char *thisacl = PQgetvalue(res, i, i_lomacl);
3759  LoInfo *loinfo;
3760  DumpableObject *lodata;
3761  char namebuf[64];
3762 
3763  /* Scan to find first tuple not to be included in group */
3764  n = 1;
3765  while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
3766  {
3767  if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
3768  strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
3769  break;
3770  n++;
3771  }
3772 
3773  /* Build the metadata DumpableObject */
3774  loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
3775 
3776  loinfo->dobj.objType = DO_LARGE_OBJECT;
3777  loinfo->dobj.catId.tableoid = LargeObjectRelationId;
3778  loinfo->dobj.catId.oid = thisoid;
3779  AssignDumpId(&loinfo->dobj);
3780 
3781  if (n > 1)
3782  snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
3783  atooid(PQgetvalue(res, i + n - 1, i_oid)));
3784  else
3785  snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
3786  loinfo->dobj.name = pg_strdup(namebuf);
3787  loinfo->dacl.acl = pg_strdup(thisacl);
3788  loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
3789  loinfo->dacl.privtype = 0;
3790  loinfo->dacl.initprivs = NULL;
3791  loinfo->rolname = getRoleName(thisowner);
3792  loinfo->numlos = n;
3793  loinfo->looids[0] = thisoid;
3794  /* Collect OIDs of the remaining blobs in this group */
3795  for (int k = 1; k < n; k++)
3796  {
3797  CatalogId extraID;
3798 
3799  loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
3800 
3801  /* Make sure we can look up loinfo by any of the blobs' OIDs */
3802  extraID.tableoid = LargeObjectRelationId;
3803  extraID.oid = loinfo->looids[k];
3804  recordAdditionalCatalogID(extraID, &loinfo->dobj);
3805  }
3806 
3807  /* LOs have data */
3808  loinfo->dobj.components |= DUMP_COMPONENT_DATA;
3809 
3810  /* Mark whether LO group has a non-empty ACL */
3811  if (!PQgetisnull(res, i, i_lomacl))
3812  loinfo->dobj.components |= DUMP_COMPONENT_ACL;
3813 
3814  /*
3815  * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
3816  * as it will be copied by pg_upgrade, which simply copies the
3817  * pg_largeobject table. We *do* however dump out anything but the
3818  * data, as pg_upgrade copies just pg_largeobject, but not
3819  * pg_largeobject_metadata, after the dump is restored.
3820  */
3821  if (dopt->binary_upgrade)
3822  loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
3823 
3824  /*
3825  * Create a "BLOBS" data item for the group, too. This is just a
3826  * placeholder for sorting; it carries no data now.
3827  */
3828  lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
3829  lodata->objType = DO_LARGE_OBJECT_DATA;
3830  lodata->catId = nilCatalogId;
3831  AssignDumpId(lodata);
3832  lodata->name = pg_strdup(namebuf);
3833  lodata->components |= DUMP_COMPONENT_DATA;
3834  /* Set up explicit dependency from data to metadata */
3835  lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
3836  lodata->dependencies[0] = loinfo->dobj.dumpId;
3837  lodata->nDeps = lodata->allocDeps = 1;
3838  }
3839 
3840  PQclear(res);
3841  destroyPQExpBuffer(loQry);
3842 }
void recordAdditionalCatalogID(CatalogId catId, DumpableObject *dobj)
Definition: common.c:696
#define MAX_BLOBS_PER_ARCHIVE_ENTRY
Definition: pg_dump.c:221

References _dumpableAcl::acl, _dumpableAcl::acldefault, _dumpableObject::allocDeps, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _loInfo::dacl, PQExpBufferData::data, _dumpableObject::dependencies, destroyPQExpBuffer(), DO_LARGE_OBJECT, DO_LARGE_OBJECT_DATA, _loInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DATA, _dumpableObject::dumpId, ExecuteSqlQuery(), getRoleName(), i, _dumpableAcl::initprivs, _loInfo::looids, MAX_BLOBS_PER_ARCHIVE_ENTRY, _dumpableObject::name, _dumpableObject::nDeps, nilCatalogId, _loInfo::numlos, _dumpableObject::objType, CatalogId::oid, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, recordAdditionalCatalogID(), res, _loInfo::rolname, snprintf, and CatalogId::tableoid.

Referenced by main().

◆ getNamespaces()

void getNamespaces ( Archive fout)

Definition at line 5699 of file pg_dump.c.

5700 {
5701  PGresult *res;
5702  int ntups;
5703  int i;
5704  PQExpBuffer query;
5705  NamespaceInfo *nsinfo;
5706  int i_tableoid;
5707  int i_oid;
5708  int i_nspname;
5709  int i_nspowner;
5710  int i_nspacl;
5711  int i_acldefault;
5712 
5713  query = createPQExpBuffer();
5714 
5715  /*
5716  * we fetch all namespaces including system ones, so that every object we
5717  * read in can be linked to a containing namespace.
5718  */
5719  appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5720  "n.nspowner, "
5721  "n.nspacl, "
5722  "acldefault('n', n.nspowner) AS acldefault "
5723  "FROM pg_namespace n");
5724 
5725  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5726 
5727  ntups = PQntuples(res);
5728 
5729  nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5730 
5731  i_tableoid = PQfnumber(res, "tableoid");
5732  i_oid = PQfnumber(res, "oid");
5733  i_nspname = PQfnumber(res, "nspname");
5734  i_nspowner = PQfnumber(res, "nspowner");
5735  i_nspacl = PQfnumber(res, "nspacl");
5736  i_acldefault = PQfnumber(res, "acldefault");
5737 
5738  for (i = 0; i < ntups; i++)
5739  {
5740  const char *nspowner;
5741 
5742  nsinfo[i].dobj.objType = DO_NAMESPACE;
5743  nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5744  nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5745  AssignDumpId(&nsinfo[i].dobj);
5746  nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5747  nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5748  nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5749  nsinfo[i].dacl.privtype = 0;
5750  nsinfo[i].dacl.initprivs = NULL;
5751  nspowner = PQgetvalue(res, i, i_nspowner);
5752  nsinfo[i].nspowner = atooid(nspowner);
5753  nsinfo[i].rolname = getRoleName(nspowner);
5754 
5755  /* Decide whether to dump this namespace */
5756  selectDumpableNamespace(&nsinfo[i], fout);
5757 
5758  /* Mark whether namespace has an ACL */
5759  if (!PQgetisnull(res, i, i_nspacl))
5760  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5761 
5762  /*
5763  * We ignore any pg_init_privs.initprivs entry for the public schema
5764  * and assume a predetermined default, for several reasons. First,
5765  * dropping and recreating the schema removes its pg_init_privs entry,
5766  * but an empty destination database starts with this ACL nonetheless.
5767  * Second, we support dump/reload of public schema ownership changes.
5768  * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5769  * initprivs continues to reflect the initial owner. Hence,
5770  * synthesize the value that nspacl will have after the restore's
5771  * ALTER SCHEMA OWNER. Third, this makes the destination database
5772  * match the source's ACL, even if the latter was an initdb-default
5773  * ACL, which changed in v15. An upgrade pulls in changes to most
5774  * system object ACLs that the DBA had not customized. We've made the
5775  * public schema depart from that, because changing its ACL so easily
5776  * breaks applications.
5777  */
5778  if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5779  {
5780  PQExpBuffer aclarray = createPQExpBuffer();
5781  PQExpBuffer aclitem = createPQExpBuffer();
5782 
5783  /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5784  appendPQExpBufferChar(aclarray, '{');
5785  quoteAclUserName(aclitem, nsinfo[i].rolname);
5786  appendPQExpBufferStr(aclitem, "=UC/");
5787  quoteAclUserName(aclitem, nsinfo[i].rolname);
5788  appendPGArray(aclarray, aclitem->data);
5789  resetPQExpBuffer(aclitem);
5790  appendPQExpBufferStr(aclitem, "=U/");
5791  quoteAclUserName(aclitem, nsinfo[i].rolname);
5792  appendPGArray(aclarray, aclitem->data);
5793  appendPQExpBufferChar(aclarray, '}');
5794 
5795  nsinfo[i].dacl.privtype = 'i';
5796  nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5797  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5798 
5799  destroyPQExpBuffer(aclarray);
5800  destroyPQExpBuffer(aclitem);
5801  }
5802  }
5803 
5804  PQclear(res);
5805  destroyPQExpBuffer(query);
5806 }
void quoteAclUserName(PQExpBuffer output, const char *input)
Definition: dumputils.c:544
NameData rolname
Definition: pg_authid.h:34
static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
Definition: pg_dump.c:1824
void appendPGArray(PQExpBuffer buffer, const char *value)
Definition: string_utils.c:740

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPGArray(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _namespaceInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_NAMESPACE, _namespaceInfo::dobj, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), getRoleName(), i, _dumpableAcl::initprivs, _dumpableObject::name, _namespaceInfo::nspowner, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, pstrdup(), quoteAclUserName(), res, resetPQExpBuffer(), _namespaceInfo::rolname, rolname, selectDumpableNamespace(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOpclasses()

void getOpclasses ( Archive fout)

Definition at line 6327 of file pg_dump.c.

6328 {
6329  PGresult *res;
6330  int ntups;
6331  int i;
6332  PQExpBuffer query = createPQExpBuffer();
6333  OpclassInfo *opcinfo;
6334  int i_tableoid;
6335  int i_oid;
6336  int i_opcname;
6337  int i_opcnamespace;
6338  int i_opcowner;
6339 
6340  /*
6341  * find all opclasses, including builtin opclasses; we filter out
6342  * system-defined opclasses at dump-out time.
6343  */
6344 
6345  appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
6346  "opcnamespace, "
6347  "opcowner "
6348  "FROM pg_opclass");
6349 
6350  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6351 
6352  ntups = PQntuples(res);
6353 
6354  opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6355 
6356  i_tableoid = PQfnumber(res, "tableoid");
6357  i_oid = PQfnumber(res, "oid");
6358  i_opcname = PQfnumber(res, "opcname");
6359  i_opcnamespace = PQfnumber(res, "opcnamespace");
6360  i_opcowner = PQfnumber(res, "opcowner");
6361 
6362  for (i = 0; i < ntups; i++)
6363  {
6364  opcinfo[i].dobj.objType = DO_OPCLASS;
6365  opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6366  opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6367  AssignDumpId(&opcinfo[i].dobj);
6368  opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6369  opcinfo[i].dobj.namespace =
6370  findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6371  opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6372 
6373  /* Decide whether we want to dump it */
6374  selectDumpableObject(&(opcinfo[i].dobj), fout);
6375  }
6376 
6377  PQclear(res);
6378 
6379  destroyPQExpBuffer(query);
6380 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_OPCLASS, _opclassInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, _opclassInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOperators()

void getOperators ( Archive fout)

Definition at line 6073 of file pg_dump.c.

6074 {
6075  PGresult *res;
6076  int ntups;
6077  int i;
6078  PQExpBuffer query = createPQExpBuffer();
6079  OprInfo *oprinfo;
6080  int i_tableoid;
6081  int i_oid;
6082  int i_oprname;
6083  int i_oprnamespace;
6084  int i_oprowner;
6085  int i_oprkind;
6086  int i_oprcode;
6087 
6088  /*
6089  * find all operators, including builtin operators; we filter out
6090  * system-defined operators at dump-out time.
6091  */
6092 
6093  appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
6094  "oprnamespace, "
6095  "oprowner, "
6096  "oprkind, "
6097  "oprcode::oid AS oprcode "
6098  "FROM pg_operator");
6099 
6100  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6101 
6102  ntups = PQntuples(res);
6103 
6104  oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6105 
6106  i_tableoid = PQfnumber(res, "tableoid");
6107  i_oid = PQfnumber(res, "oid");
6108  i_oprname = PQfnumber(res, "oprname");
6109  i_oprnamespace = PQfnumber(res, "oprnamespace");
6110  i_oprowner = PQfnumber(res, "oprowner");
6111  i_oprkind = PQfnumber(res, "oprkind");
6112  i_oprcode = PQfnumber(res, "oprcode");
6113 
6114  for (i = 0; i < ntups; i++)
6115  {
6116  oprinfo[i].dobj.objType = DO_OPERATOR;
6117  oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6118  oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6119  AssignDumpId(&oprinfo[i].dobj);
6120  oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6121  oprinfo[i].dobj.namespace =
6122  findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6123  oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6124  oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6125  oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6126 
6127  /* Decide whether we want to dump it */
6128  selectDumpableObject(&(oprinfo[i].dobj), fout);
6129  }
6130 
6131  PQclear(res);
6132 
6133  destroyPQExpBuffer(query);
6134 }
char oprkind
Definition: pg_dump.h:246

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_OPERATOR, _oprInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, _oprInfo::oprcode, _oprInfo::oprkind, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, _oprInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOpfamilies()

void getOpfamilies ( Archive fout)

Definition at line 6387 of file pg_dump.c.

6388 {
6389  PGresult *res;
6390  int ntups;
6391  int i;
6392  PQExpBuffer query;
6393  OpfamilyInfo *opfinfo;
6394  int i_tableoid;
6395  int i_oid;
6396  int i_opfname;
6397  int i_opfnamespace;
6398  int i_opfowner;
6399 
6400  query = createPQExpBuffer();
6401 
6402  /*
6403  * find all opfamilies, including builtin opfamilies; we filter out
6404  * system-defined opfamilies at dump-out time.
6405  */
6406 
6407  appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
6408  "opfnamespace, "
6409  "opfowner "
6410  "FROM pg_opfamily");
6411 
6412  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6413 
6414  ntups = PQntuples(res);
6415 
6416  opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6417 
6418  i_tableoid = PQfnumber(res, "tableoid");
6419  i_oid = PQfnumber(res, "oid");
6420  i_opfname = PQfnumber(res, "opfname");
6421  i_opfnamespace = PQfnumber(res, "opfnamespace");
6422  i_opfowner = PQfnumber(res, "opfowner");
6423 
6424  for (i = 0; i < ntups; i++)
6425  {
6426  opfinfo[i].dobj.objType = DO_OPFAMILY;
6427  opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6428  opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6429  AssignDumpId(&opfinfo[i].dobj);
6430  opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6431  opfinfo[i].dobj.namespace =
6432  findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6433  opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6434 
6435  /* Decide whether we want to dump it */
6436  selectDumpableObject(&(opfinfo[i].dobj), fout);
6437  }
6438 
6439  PQclear(res);
6440 
6441  destroyPQExpBuffer(query);
6442 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_OPFAMILY, _opfamilyInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, _opfamilyInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOwnedSeqs()

void getOwnedSeqs ( Archive fout,
TableInfo  tblinfo[],
int  numTables 
)

Definition at line 7231 of file pg_dump.c.

7232 {
7233  int i;
7234 
7235  /*
7236  * Force sequences that are "owned" by table columns to be dumped whenever
7237  * their owning table is being dumped.
7238  */
7239  for (i = 0; i < numTables; i++)
7240  {
7241  TableInfo *seqinfo = &tblinfo[i];
7242  TableInfo *owning_tab;
7243 
7244  if (!OidIsValid(seqinfo->owning_tab))
7245  continue; /* not an owned sequence */
7246 
7247  owning_tab = findTableByOid(seqinfo->owning_tab);
7248  if (owning_tab == NULL)
7249  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7250  seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7251 
7252  /*
7253  * Only dump identity sequences if we're going to dump the table that
7254  * it belongs to.
7255  */
7256  if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
7257  seqinfo->is_identity_sequence)
7258  {
7259  seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
7260  continue;
7261  }
7262 
7263  /*
7264  * Otherwise we need to dump the components that are being dumped for
7265  * the table and any components which the sequence is explicitly
7266  * marked with.
7267  *
7268  * We can't simply use the set of components which are being dumped
7269  * for the table as the table might be in an extension (and only the
7270  * non-extension components, eg: ACLs if changed, security labels, and
7271  * policies, are being dumped) while the sequence is not (and
7272  * therefore the definition and other components should also be
7273  * dumped).
7274  *
7275  * If the sequence is part of the extension then it should be properly
7276  * marked by checkExtensionMembership() and this will be a no-op as
7277  * the table will be equivalently marked.
7278  */
7279  seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
7280 
7281  if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7282  seqinfo->interesting = true;
7283  }
7284 }

References _dumpableObject::catId, _tableInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_NONE, findTableByOid(), i, _tableInfo::interesting, _tableInfo::is_identity_sequence, CatalogId::oid, OidIsValid, _tableInfo::owning_tab, and pg_fatal.

Referenced by getSchemaData().

◆ getPartitioningInfo()

void getPartitioningInfo ( Archive fout)

Definition at line 7350 of file pg_dump.c.

7351 {
7352  PQExpBuffer query;
7353  PGresult *res;
7354  int ntups;
7355 
7356  /* hash partitioning didn't exist before v11 */
7357  if (fout->remoteVersion < 110000)
7358  return;
7359  /* needn't bother if schema-only dump */
7360  if (fout->dopt->schemaOnly)
7361  return;
7362 
7363  query = createPQExpBuffer();
7364 
7365  /*
7366  * Unsafe partitioning schemes are exactly those for which hash enum_ops
7367  * appears among the partition opclasses. We needn't check partstrat.
7368  *
7369  * Note that this query may well retrieve info about tables we aren't
7370  * going to dump and hence have no lock on. That's okay since we need not
7371  * invoke any unsafe server-side functions.
7372  */
7373  appendPQExpBufferStr(query,
7374  "SELECT partrelid FROM pg_partitioned_table WHERE\n"
7375  "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
7376  "ON c.opcmethod = a.oid\n"
7377  "WHERE opcname = 'enum_ops' "
7378  "AND opcnamespace = 'pg_catalog'::regnamespace "
7379  "AND amname = 'hash') = ANY(partclass)");
7380 
7381  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7382 
7383  ntups = PQntuples(res);
7384 
7385  for (int i = 0; i < ntups; i++)
7386  {
7387  Oid tabrelid = atooid(PQgetvalue(res, i, 0));
7388  TableInfo *tbinfo;
7389 
7390  tbinfo = findTableByOid(tabrelid);
7391  if (tbinfo == NULL)
7392  pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
7393  tabrelid);
7394  tbinfo->unsafe_partitions = true;
7395  }
7396 
7397  PQclear(res);
7398 
7399  destroyPQExpBuffer(query);
7400 }

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::dopt, ExecuteSqlQuery(), findTableByOid(), i, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _dumpOptions::schemaOnly, and _tableInfo::unsafe_partitions.

Referenced by getSchemaData().

◆ getPolicies()

void getPolicies ( Archive fout,
TableInfo  tblinfo[],
int  numTables 
)

Definition at line 3986 of file pg_dump.c.

3987 {
3988  PQExpBuffer query;
3989  PQExpBuffer tbloids;
3990  PGresult *res;
3991  PolicyInfo *polinfo;
3992  int i_oid;
3993  int i_tableoid;
3994  int i_polrelid;
3995  int i_polname;
3996  int i_polcmd;
3997  int i_polpermissive;
3998  int i_polroles;
3999  int i_polqual;
4000  int i_polwithcheck;
4001  int i,
4002  j,
4003  ntups;
4004 
4005  /* No policies before 9.5 */
4006  if (fout->remoteVersion < 90500)
4007  return;
4008 
4009  query = createPQExpBuffer();
4010  tbloids = createPQExpBuffer();
4011 
4012  /*
4013  * Identify tables of interest, and check which ones have RLS enabled.
4014  */
4015  appendPQExpBufferChar(tbloids, '{');
4016  for (i = 0; i < numTables; i++)
4017  {
4018  TableInfo *tbinfo = &tblinfo[i];
4019 
4020  /* Ignore row security on tables not to be dumped */
4021  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
4022  continue;
4023 
4024  /* It can't have RLS or policies if it's not a table */
4025  if (tbinfo->relkind != RELKIND_RELATION &&
4026  tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
4027  continue;
4028 
4029  /* Add it to the list of table OIDs to be probed below */
4030  if (tbloids->len > 1) /* do we have more than the '{'? */
4031  appendPQExpBufferChar(tbloids, ',');
4032  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
4033 
4034  /* Is RLS enabled? (That's separate from whether it has policies) */
4035  if (tbinfo->rowsec)
4036  {
4038 
4039  /*
4040  * We represent RLS being enabled on a table by creating a
4041  * PolicyInfo object with null polname.
4042  *
4043  * Note: use tableoid 0 so that this object won't be mistaken for
4044  * something that pg_depend entries apply to.
4045  */
4046  polinfo = pg_malloc(sizeof(PolicyInfo));
4047  polinfo->dobj.objType = DO_POLICY;
4048  polinfo->dobj.catId.tableoid = 0;
4049  polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
4050  AssignDumpId(&polinfo->dobj);
4051  polinfo->dobj.namespace = tbinfo->dobj.namespace;
4052  polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
4053  polinfo->poltable = tbinfo;
4054  polinfo->polname = NULL;
4055  polinfo->polcmd = '\0';
4056  polinfo->polpermissive = 0;
4057  polinfo->polroles = NULL;
4058  polinfo->polqual = NULL;
4059  polinfo->polwithcheck = NULL;
4060  }
4061  }
4062  appendPQExpBufferChar(tbloids, '}');
4063 
4064  /*
4065  * Now, read all RLS policies belonging to the tables of interest, and
4066  * create PolicyInfo objects for them. (Note that we must filter the
4067  * results server-side not locally, because we dare not apply pg_get_expr
4068  * to tables we don't have lock on.)
4069  */
4070  pg_log_info("reading row-level security policies");
4071 
4072  printfPQExpBuffer(query,
4073  "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
4074  if (fout->remoteVersion >= 100000)
4075  appendPQExpBufferStr(query, "pol.polpermissive, ");
4076  else
4077  appendPQExpBufferStr(query, "'t' as polpermissive, ");
4078  appendPQExpBuffer(query,
4079  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
4080  " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, "
4081  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
4082  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
4083  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
4084  "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
4085  tbloids->data);
4086 
4087  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4088 
4089  ntups = PQntuples(res);
4090  if (ntups > 0)
4091  {
4092  i_oid = PQfnumber(res, "oid");
4093  i_tableoid = PQfnumber(res, "tableoid");
4094  i_polrelid = PQfnumber(res, "polrelid");
4095  i_polname = PQfnumber(res, "polname");
4096  i_polcmd = PQfnumber(res, "polcmd");
4097  i_polpermissive = PQfnumber(res, "polpermissive");
4098  i_polroles = PQfnumber(res, "polroles");
4099  i_polqual = PQfnumber(res, "polqual");
4100  i_polwithcheck = PQfnumber(res, "polwithcheck");
4101 
4102  polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
4103 
4104  for (j = 0; j < ntups; j++)
4105  {
4106  Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
4107  TableInfo *tbinfo = findTableByOid(polrelid);
4108 
4110 
4111  polinfo[j].dobj.objType = DO_POLICY;
4112  polinfo[j].dobj.catId.tableoid =
4113  atooid(PQgetvalue(res, j, i_tableoid));
4114  polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4115  AssignDumpId(&polinfo[j].dobj);
4116  polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4117  polinfo[j].poltable = tbinfo;
4118  polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
4119  polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
4120 
4121  polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
4122  polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
4123 
4124  if (PQgetisnull(res, j, i_polroles))
4125  polinfo[j].polroles = NULL;
4126  else
4127  polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
4128 
4129  if (PQgetisnull(res, j, i_polqual))
4130  polinfo[j].polqual = NULL;
4131  else
4132  polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
4133 
4134  if (PQgetisnull(res, j, i_polwithcheck))
4135  polinfo[j].polwithcheck = NULL;
4136  else
4137  polinfo[j].polwithcheck
4138  = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
4139  }
4140  }
4141 
4142  PQclear(res);
4143 
4144  destroyPQExpBuffer(query);
4145  destroyPQExpBuffer(tbloids);
4146 }
#define DUMP_COMPONENT_POLICY
Definition: pg_dump.h:102
bool rowsec
Definition: pg_dump.h:301

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_POLICY, _tableInfo::dobj, _policyInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_POLICY, ExecuteSqlQuery(), findTableByOid(), i, j, PQExpBufferData::len, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, _policyInfo::polcmd, _policyInfo::polname, _policyInfo::polpermissive, _policyInfo::polqual, _policyInfo::polroles, _policyInfo::poltable, _policyInfo::polwithcheck, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, res, _tableInfo::rowsec, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getProcLangs()

void getProcLangs ( Archive fout)

Definition at line 8458 of file pg_dump.c.

8459 {
8460  PGresult *res;
8461  int ntups;
8462  int i;
8463  PQExpBuffer query = createPQExpBuffer();
8464  ProcLangInfo *planginfo;
8465  int i_tableoid;
8466  int i_oid;
8467  int i_lanname;
8468  int i_lanpltrusted;
8469  int i_lanplcallfoid;
8470  int i_laninline;
8471  int i_lanvalidator;
8472  int i_lanacl;
8473  int i_acldefault;
8474  int i_lanowner;
8475 
8476  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8477  "lanname, lanpltrusted, lanplcallfoid, "
8478  "laninline, lanvalidator, "
8479  "lanacl, "
8480  "acldefault('l', lanowner) AS acldefault, "
8481  "lanowner "
8482  "FROM pg_language "
8483  "WHERE lanispl "
8484  "ORDER BY oid");
8485 
8486  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8487 
8488  ntups = PQntuples(res);
8489 
8490  planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8491 
8492  i_tableoid = PQfnumber(res, "tableoid");
8493  i_oid = PQfnumber(res, "oid");
8494  i_lanname = PQfnumber(res, "lanname");
8495  i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8496  i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8497  i_laninline = PQfnumber(res, "laninline");
8498  i_lanvalidator = PQfnumber(res, "lanvalidator");
8499  i_lanacl = PQfnumber(res, "lanacl");
8500  i_acldefault = PQfnumber(res, "acldefault");
8501  i_lanowner = PQfnumber(res, "lanowner");
8502 
8503  for (i = 0; i < ntups; i++)
8504  {
8505  planginfo[i].dobj.objType = DO_PROCLANG;
8506  planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8507  planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8508  AssignDumpId(&planginfo[i].dobj);
8509 
8510  planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8511  planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8512  planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8513  planginfo[i].dacl.privtype = 0;
8514  planginfo[i].dacl.initprivs = NULL;
8515  planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8516  planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8517  planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8518  planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8519  planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8520 
8521  /* Decide whether we want to dump it */
8522  selectDumpableProcLang(&(planginfo[i]), fout);
8523 
8524  /* Mark whether language has an ACL */
8525  if (!PQgetisnull(res, i, i_lanacl))
8526  planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8527  }
8528 
8529  PQclear(res);
8530 
8531  destroyPQExpBuffer(query);
8532 }
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:2041

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _procLangInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_PROCLANG, _procLangInfo::dobj, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), getRoleName(), i, _dumpableAcl::initprivs, _procLangInfo::laninline, _procLangInfo::lanowner, _procLangInfo::lanplcallfoid, _procLangInfo::lanpltrusted, _procLangInfo::lanvalidator, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, selectDumpableProcLang(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationNamespaces()

void getPublicationNamespaces ( Archive fout)

Definition at line 4477 of file pg_dump.c.

4478 {
4479  PQExpBuffer query;
4480  PGresult *res;
4481  PublicationSchemaInfo *pubsinfo;
4482  DumpOptions *dopt = fout->dopt;
4483  int i_tableoid;
4484  int i_oid;
4485  int i_pnpubid;
4486  int i_pnnspid;
4487  int i,
4488  j,
4489  ntups;
4490 
4491  if (dopt->no_publications || fout->remoteVersion < 150000)
4492  return;
4493 
4494  query = createPQExpBuffer();
4495 
4496  /* Collect all publication membership info. */
4497  appendPQExpBufferStr(query,
4498  "SELECT tableoid, oid, pnpubid, pnnspid "
4499  "FROM pg_catalog.pg_publication_namespace");
4500  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4501 
4502  ntups = PQntuples(res);
4503 
4504  i_tableoid = PQfnumber(res, "tableoid");
4505  i_oid = PQfnumber(res, "oid");
4506  i_pnpubid = PQfnumber(res, "pnpubid");
4507  i_pnnspid = PQfnumber(res, "pnnspid");
4508 
4509  /* this allocation may be more than we need */
4510  pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4511  j = 0;
4512 
4513  for (i = 0; i < ntups; i++)
4514  {
4515  Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4516  Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4517  PublicationInfo *pubinfo;
4518  NamespaceInfo *nspinfo;
4519 
4520  /*
4521  * Ignore any entries for which we aren't interested in either the
4522  * publication or the rel.
4523  */
4524  pubinfo = findPublicationByOid(pnpubid);
4525  if (pubinfo == NULL)
4526  continue;
4527  nspinfo = findNamespaceByOid(pnnspid);
4528  if (nspinfo == NULL)
4529  continue;
4530 
4531  /*
4532  * We always dump publication namespaces unless the corresponding
4533  * namespace is excluded from the dump.
4534  */
4535  if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
4536  continue;
4537 
4538  /* OK, make a DumpableObject for this relationship */
4540  pubsinfo[j].dobj.catId.tableoid =
4541  atooid(PQgetvalue(res, i, i_tableoid));
4542  pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4543  AssignDumpId(&pubsinfo[j].dobj);
4544  pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4545  pubsinfo[j].dobj.name = nspinfo->dobj.name;
4546  pubsinfo[j].publication = pubinfo;
4547  pubsinfo[j].pubschema = nspinfo;
4548 
4549  /* Decide whether we want to dump it */
4550  selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4551 
4552  j++;
4553  }
4554 
4555  PQclear(res);
4556  destroyPQExpBuffer(query);
4557 }
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:985
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2141
int no_publications
Definition: pg_backup.h:183

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_TABLE_IN_SCHEMA, _namespaceInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_NONE, ExecuteSqlQuery(), findNamespaceByOid(), findPublicationByOid(), i, j, _dumpableObject::name, _dumpOptions::no_publications, _dumpableObject::objType, CatalogId::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _PublicationSchemaInfo::publication, _PublicationSchemaInfo::pubschema, Archive::remoteVersion, res, selectDumpablePublicationObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublications()

void getPublications ( Archive fout)

Definition at line 4271 of file pg_dump.c.

4272 {
4273  DumpOptions *dopt = fout->dopt;
4274  PQExpBuffer query;
4275  PGresult *res;
4276  PublicationInfo *pubinfo;
4277  int i_tableoid;
4278  int i_oid;
4279  int i_pubname;
4280  int i_pubowner;
4281  int i_puballtables;
4282  int i_pubinsert;
4283  int i_pubupdate;
4284  int i_pubdelete;
4285  int i_pubtruncate;
4286  int i_pubviaroot;
4287  int i_pubgencols;
4288  int i,
4289  ntups;
4290 
4291  if (dopt->no_publications || fout->remoteVersion < 100000)
4292  return;
4293 
4294  query = createPQExpBuffer();
4295 
4296  /* Get the publications. */
4297  appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, "
4298  "p.pubowner, p.puballtables, p.pubinsert, "
4299  "p.pubupdate, p.pubdelete, ");
4300 
4301  if (fout->remoteVersion >= 110000)
4302  appendPQExpBufferStr(query, "p.pubtruncate, ");
4303  else
4304  appendPQExpBufferStr(query, "false AS pubtruncate, ");
4305 
4306  if (fout->remoteVersion >= 130000)
4307  appendPQExpBufferStr(query, "p.pubviaroot, ");
4308  else
4309  appendPQExpBufferStr(query, "false AS pubviaroot, ");
4310 
4311  if (fout->remoteVersion >= 180000)
4312  appendPQExpBufferStr(query, "p.pubgencols ");
4313  else
4314  appendPQExpBufferStr(query, "false AS pubgencols ");
4315 
4316  appendPQExpBufferStr(query, "FROM pg_publication p");
4317 
4318  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4319 
4320  ntups = PQntuples(res);
4321 
4322  if (ntups == 0)
4323  goto cleanup;
4324 
4325  i_tableoid = PQfnumber(res, "tableoid");
4326  i_oid = PQfnumber(res, "oid");
4327  i_pubname = PQfnumber(res, "pubname");
4328  i_pubowner = PQfnumber(res, "pubowner");
4329  i_puballtables = PQfnumber(res, "puballtables");
4330  i_pubinsert = PQfnumber(res, "pubinsert");
4331  i_pubupdate = PQfnumber(res, "pubupdate");
4332  i_pubdelete = PQfnumber(res, "pubdelete");
4333  i_pubtruncate = PQfnumber(res, "pubtruncate");
4334  i_pubviaroot = PQfnumber(res, "pubviaroot");
4335  i_pubgencols = PQfnumber(res, "pubgencols");
4336 
4337  pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4338 
4339  for (i = 0; i < ntups; i++)
4340  {
4341  pubinfo[i].dobj.objType = DO_PUBLICATION;
4342  pubinfo[i].dobj.catId.tableoid =
4343  atooid(PQgetvalue(res, i, i_tableoid));
4344  pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4345  AssignDumpId(&pubinfo[i].dobj);
4346  pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4347  pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4348  pubinfo[i].puballtables =
4349  (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4350  pubinfo[i].pubinsert =
4351  (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4352  pubinfo[i].pubupdate =
4353  (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4354  pubinfo[i].pubdelete =
4355  (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4356  pubinfo[i].pubtruncate =
4357  (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4358  pubinfo[i].pubviaroot =
4359  (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4360  pubinfo[i].pubgencols =
4361  (strcmp(PQgetvalue(res, i, i_pubgencols), "t") == 0);
4362 
4363  /* Decide whether we want to dump it */
4364  selectDumpableObject(&(pubinfo[i].dobj), fout);
4365  }
4366 
4367 cleanup:
4368  PQclear(res);
4369 
4370  destroyPQExpBuffer(query);
4371 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, cleanup(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION, _PublicationInfo::dobj, Archive::dopt, ExecuteSqlQuery(), getRoleName(), i, _dumpableObject::name, _dumpOptions::no_publications, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _PublicationInfo::puballtables, _PublicationInfo::pubdelete, _PublicationInfo::pubgencols, _PublicationInfo::pubinsert, _PublicationInfo::pubtruncate, _PublicationInfo::pubupdate, _PublicationInfo::pubviaroot, Archive::remoteVersion, res, _PublicationInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationTables()

void getPublicationTables ( Archive fout,
TableInfo  tblinfo[],
int  numTables 
)

Definition at line 4564 of file pg_dump.c.

4565 {
4566  PQExpBuffer query;
4567  PGresult *res;
4568  PublicationRelInfo *pubrinfo;
4569  DumpOptions *dopt = fout->dopt;
4570  int i_tableoid;
4571  int i_oid;
4572  int i_prpubid;
4573  int i_prrelid;
4574  int i_prrelqual;
4575  int i_prattrs;
4576  int i,
4577  j,
4578  ntups;
4579 
4580  if (dopt->no_publications || fout->remoteVersion < 100000)
4581  return;
4582 
4583  query = createPQExpBuffer();
4584 
4585  /* Collect all publication membership info. */
4586  if (fout->remoteVersion >= 150000)
4587  appendPQExpBufferStr(query,
4588  "SELECT tableoid, oid, prpubid, prrelid, "
4589  "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
4590  "(CASE\n"
4591  " WHEN pr.prattrs IS NOT NULL THEN\n"
4592  " (SELECT array_agg(attname)\n"
4593  " FROM\n"
4594  " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
4595  " pg_catalog.pg_attribute\n"
4596  " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
4597  " ELSE NULL END) prattrs "
4598  "FROM pg_catalog.pg_publication_rel pr");
4599  else
4600  appendPQExpBufferStr(query,
4601  "SELECT tableoid, oid, prpubid, prrelid, "
4602  "NULL AS prrelqual, NULL AS prattrs "
4603  "FROM pg_catalog.pg_publication_rel");
4604  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4605 
4606  ntups = PQntuples(res);
4607 
4608  i_tableoid = PQfnumber(res, "tableoid");
4609  i_oid = PQfnumber(res, "oid");
4610  i_prpubid = PQfnumber(res, "prpubid");
4611  i_prrelid = PQfnumber(res, "prrelid");
4612  i_prrelqual = PQfnumber(res, "prrelqual");
4613  i_prattrs = PQfnumber(res, "prattrs");
4614 
4615  /* this allocation may be more than we need */
4616  pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4617  j = 0;
4618 
4619  for (i = 0; i < ntups; i++)
4620  {
4621  Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4622  Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4623  PublicationInfo *pubinfo;
4624  TableInfo *tbinfo;
4625 
4626  /*
4627  * Ignore any entries for which we aren't interested in either the
4628  * publication or the rel.
4629  */
4630  pubinfo = findPublicationByOid(prpubid);
4631  if (pubinfo == NULL)
4632  continue;
4633  tbinfo = findTableByOid(prrelid);
4634  if (tbinfo == NULL)
4635  continue;
4636 
4637  /*
4638  * Ignore publication membership of tables whose definitions are not
4639  * to be dumped.
4640  */
4641  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
4642  continue;
4643 
4644  /* OK, make a DumpableObject for this relationship */
4645  pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4646  pubrinfo[j].dobj.catId.tableoid =
4647  atooid(PQgetvalue(res, i, i_tableoid));
4648  pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4649  AssignDumpId(&pubrinfo[j].dobj);
4650  pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4651  pubrinfo[j].dobj.name = tbinfo->dobj.name;
4652  pubrinfo[j].publication = pubinfo;
4653  pubrinfo[j].pubtable = tbinfo;
4654  if (PQgetisnull(res, i, i_prrelqual))
4655  pubrinfo[j].pubrelqual = NULL;
4656  else
4657  pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
4658 
4659  if (!PQgetisnull(res, i, i_prattrs))
4660  {
4661  char **attnames;
4662  int nattnames;
4663  PQExpBuffer attribs;
4664 
4665  if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
4666  &attnames, &nattnames))
4667  pg_fatal("could not parse %s array", "prattrs");
4668  attribs = createPQExpBuffer();
4669  for (int k = 0; k < nattnames; k++)
4670  {
4671  if (k > 0)
4672  appendPQExpBufferStr(attribs, ", ");
4673 
4674  appendPQExpBufferStr(attribs, fmtId(attnames[k]));
4675  }
4676  pubrinfo[j].pubrattrs = attribs->data;
4677  }
4678  else
4679  pubrinfo[j].pubrattrs = NULL;
4680 
4681  /* Decide whether we want to dump it */
4682  selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
4683 
4684  j++;
4685  }
4686 
4687  PQclear(res);
4688  destroyPQExpBuffer(query);
4689 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_REL, _tableInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, ExecuteSqlQuery(), findPublicationByOid(), findTableByOid(), fmtId(), i, j, _dumpableObject::name, _dumpOptions::no_publications, parsePGArray(), pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, and selectDumpablePublicationObject().

Referenced by getSchemaData().

◆ getRoleName()

static const char * getRoleName ( const char *  roleoid_str)
static

Definition at line 9985 of file pg_dump.c.

9986 {
9987  Oid roleoid = atooid(roleoid_str);
9988 
9989  /*
9990  * Do binary search to find the appropriate item.
9991  */
9992  if (nrolenames > 0)
9993  {
9994  RoleNameItem *low = &rolenames[0];
9995  RoleNameItem *high = &rolenames[nrolenames - 1];
9996 
9997  while (low <= high)
9998  {
9999  RoleNameItem *middle = low + (high - low) / 2;
10000 
10001  if (roleoid < middle->roleoid)
10002  high = middle - 1;
10003  else if (roleoid > middle->roleoid)
10004  low = middle + 1;
10005  else
10006  return middle->rolename; /* found a match */
10007  }
10008  }
10009 
10010  pg_fatal("role with OID %u does not exist", roleoid);
10011  return NULL; /* keep compiler quiet */
10012 }

References atooid, nrolenames, pg_fatal, RoleNameItem::rolename, rolenames, and RoleNameItem::roleoid.

Referenced by dumpDatabase(), getAggregates(), getCollations(), getConversions(), getDefaultACLs(), getEventTriggers(), getExtendedStatistics(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getLOs(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getProcLangs(), getPublications(), getSubscriptions(), getTables(), getTSConfigurations(), getTSDictionaries(), and getTypes().

◆ getRootTableInfo()

static TableInfo * getRootTableInfo ( const TableInfo tbinfo)
static

Definition at line 2636 of file pg_dump.c.

2637 {
2638  TableInfo *parentTbinfo;
2639 
2640  Assert(tbinfo->ispartition);
2641  Assert(tbinfo->numParents == 1);
2642 
2643  parentTbinfo = tbinfo->parents[0];
2644  while (parentTbinfo->ispartition)
2645  {
2646  Assert(parentTbinfo->numParents == 1);
2647  parentTbinfo = parentTbinfo->parents[0];
2648  }
2649 
2650  return parentTbinfo;
2651 }

References Assert, _tableInfo::ispartition, _tableInfo::numParents, and _tableInfo::parents.

Referenced by dumpTableData(), and dumpTableData_insert().

◆ getRules()

void getRules ( Archive fout)

Definition at line 8087 of file pg_dump.c.

8088 {
8089  PGresult *res;
8090  int ntups;
8091  int i;
8092  PQExpBuffer query = createPQExpBuffer();
8093  RuleInfo *ruleinfo;
8094  int i_tableoid;
8095  int i_oid;
8096  int i_rulename;
8097  int i_ruletable;
8098  int i_ev_type;
8099  int i_is_instead;
8100  int i_ev_enabled;
8101 
8102  appendPQExpBufferStr(query, "SELECT "
8103  "tableoid, oid, rulename, "
8104  "ev_class AS ruletable, ev_type, is_instead, "
8105  "ev_enabled "
8106  "FROM pg_rewrite "
8107  "ORDER BY oid");
8108 
8109  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8110 
8111  ntups = PQntuples(res);
8112 
8113  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8114 
8115  i_tableoid = PQfnumber(res, "tableoid");
8116  i_oid = PQfnumber(res, "oid");
8117  i_rulename = PQfnumber(res, "rulename");
8118  i_ruletable = PQfnumber(res, "ruletable");
8119  i_ev_type = PQfnumber(res, "ev_type");
8120  i_is_instead = PQfnumber(res, "is_instead");
8121  i_ev_enabled = PQfnumber(res, "ev_enabled");
8122 
8123  for (i = 0; i < ntups; i++)
8124  {
8125  Oid ruletableoid;
8126 
8127  ruleinfo[i].dobj.objType = DO_RULE;
8128  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8129  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8130  AssignDumpId(&ruleinfo[i].dobj);
8131  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8132  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8133  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8134  if (ruleinfo[i].ruletable == NULL)
8135  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8136  ruletableoid, ruleinfo[i].dobj.catId.oid);
8137  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8138  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8139  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8140  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8141  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8142  if (ruleinfo[i].ruletable)
8143  {
8144  /*
8145  * If the table is a view or materialized view, force its ON
8146  * SELECT rule to be sorted before the view itself --- this
8147  * ensures that any dependencies for the rule affect the table's
8148  * positioning. Other rules are forced to appear after their
8149  * table.
8150  */
8151  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8152  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8153  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8154  {
8155  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8156  ruleinfo[i].dobj.dumpId);
8157  /* We'll merge the rule into CREATE VIEW, if possible */
8158  ruleinfo[i].separate = false;
8159  }
8160  else
8161  {
8162  addObjectDependency(&ruleinfo[i].dobj,
8163  ruleinfo[i].ruletable->dobj.dumpId);
8164  ruleinfo[i].separate = true;
8165  }
8166  }
8167  else
8168  ruleinfo[i].separate = true;
8169  }
8170 
8171  PQclear(res);
8172 
8173  destroyPQExpBuffer(query);
8174 }

References addObjectDependency(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_RULE, _tableInfo::dobj, _ruleInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, _ruleInfo::ev_enabled, _ruleInfo::ev_type, ExecuteSqlQuery(), findTableByOid(), i, _ruleInfo::is_instead, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _tableInfo::relkind, res, _ruleInfo::ruletable, _ruleInfo::separate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSubscriptions()

void getSubscriptions ( Archive fout)

Definition at line 4840 of file pg_dump.c.

4841 {
4842  DumpOptions *dopt = fout->dopt;
4843  PQExpBuffer query;
4844  PGresult *res;
4845  SubscriptionInfo *subinfo;
4846  int i_tableoid;
4847  int i_oid;
4848  int i_subname;
4849  int i_subowner;
4850  int i_subbinary;
4851  int i_substream;
4852  int i_subtwophasestate;
4853  int i_subdisableonerr;
4854  int i_subpasswordrequired;
4855  int i_subrunasowner;
4856  int i_subconninfo;
4857  int i_subslotname;
4858  int i_subsynccommit;
4859  int i_subpublications;
4860  int i_suborigin;
4861  int i_suboriginremotelsn;
4862  int i_subenabled;
4863  int i_subfailover;
4864  int i,
4865  ntups;
4866 
4867  if (dopt->no_subscriptions || fout->remoteVersion < 100000)
4868  return;
4869 
4870  if (!is_superuser(fout))
4871  {
4872  int n;
4873 
4874  res = ExecuteSqlQuery(fout,
4875  "SELECT count(*) FROM pg_subscription "
4876  "WHERE subdbid = (SELECT oid FROM pg_database"
4877  " WHERE datname = current_database())",
4878  PGRES_TUPLES_OK);
4879  n = atoi(PQgetvalue(res, 0, 0));
4880  if (n > 0)
4881  pg_log_warning("subscriptions not dumped because current user is not a superuser");
4882  PQclear(res);
4883  return;
4884  }
4885 
4886  query = createPQExpBuffer();
4887 
4888  /* Get the subscriptions in current database. */
4889  appendPQExpBufferStr(query,
4890  "SELECT s.tableoid, s.oid, s.subname,\n"
4891  " s.subowner,\n"
4892  " s.subconninfo, s.subslotname, s.subsynccommit,\n"
4893  " s.subpublications,\n");
4894 
4895  if (fout->remoteVersion >= 140000)
4896  appendPQExpBufferStr(query, " s.subbinary,\n");
4897  else
4898  appendPQExpBufferStr(query, " false AS subbinary,\n");
4899 
4900  if (fout->remoteVersion >= 140000)
4901  appendPQExpBufferStr(query, " s.substream,\n");
4902  else
4903  appendPQExpBufferStr(query, " 'f' AS substream,\n");
4904 
4905  if (fout->remoteVersion >= 150000)
4906  appendPQExpBufferStr(query,
4907  " s.subtwophasestate,\n"
4908  " s.subdisableonerr,\n");
4909  else
4910  appendPQExpBuffer(query,
4911  " '%c' AS subtwophasestate,\n"
4912  " false AS subdisableonerr,\n",
4914 
4915  if (fout->remoteVersion >= 160000)
4916  appendPQExpBufferStr(query,
4917  " s.subpasswordrequired,\n"
4918  " s.subrunasowner,\n"
4919  " s.suborigin,\n");
4920  else
4921  appendPQExpBuffer(query,
4922  " 't' AS subpasswordrequired,\n"
4923  " 't' AS subrunasowner,\n"
4924  " '%s' AS suborigin,\n",
4926 
4927  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4928  appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
4929  " s.subenabled,\n");
4930  else
4931  appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
4932  " false AS subenabled,\n");
4933 
4934  if (fout->remoteVersion >= 170000)
4935  appendPQExpBufferStr(query,
4936  " s.subfailover\n");
4937  else
4938  appendPQExpBuffer(query,
4939  " false AS subfailover\n");
4940 
4941  appendPQExpBufferStr(query,
4942  "FROM pg_subscription s\n");
4943 
4944  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4945  appendPQExpBufferStr(query,
4946  "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
4947  " ON o.external_id = 'pg_' || s.oid::text \n");
4948 
4949  appendPQExpBufferStr(query,
4950  "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
4951  " WHERE datname = current_database())");
4952 
4953  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4954 
4955  ntups = PQntuples(res);
4956 
4957  /*
4958  * Get subscription fields. We don't include subskiplsn in the dump as
4959  * after restoring the dump this value may no longer be relevant.
4960  */
4961  i_tableoid = PQfnumber(res, "tableoid");
4962  i_oid = PQfnumber(res, "oid");
4963  i_subname = PQfnumber(res, "subname");
4964  i_subowner = PQfnumber(res, "subowner");
4965  i_subbinary = PQfnumber(res, "subbinary");
4966  i_substream = PQfnumber(res, "substream");
4967  i_subtwophasestate = PQfnumber(res, "subtwophasestate");
4968  i_subdisableonerr = PQfnumber(res, "subdisableonerr");
4969  i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
4970  i_subrunasowner = PQfnumber(res, "subrunasowner");
4971  i_subconninfo = PQfnumber(res, "subconninfo");
4972  i_subslotname = PQfnumber(res, "subslotname");
4973  i_subsynccommit = PQfnumber(res, "subsynccommit");
4974  i_subpublications = PQfnumber(res, "subpublications");
4975  i_suborigin = PQfnumber(res, "suborigin");
4976  i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
4977  i_subenabled = PQfnumber(res, "subenabled");
4978  i_subfailover = PQfnumber(res, "subfailover");
4979 
4980  subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
4981 
4982  for (i = 0; i < ntups; i++)
4983  {
4984  subinfo[i].dobj.objType = DO_SUBSCRIPTION;
4985  subinfo[i].dobj.catId.tableoid =
4986  atooid(PQgetvalue(res, i, i_tableoid));
4987  subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4988  AssignDumpId(&subinfo[i].dobj);
4989  subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
4990  subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
4991 
4992  subinfo[i].subbinary =
4993  pg_strdup(PQgetvalue(res, i, i_subbinary));
4994  subinfo[i].substream =
4995  pg_strdup(PQgetvalue(res, i, i_substream));
4996  subinfo[i].subtwophasestate =
4997  pg_strdup(PQgetvalue(res, i, i_subtwophasestate));
4998  subinfo[i].subdisableonerr =
4999  pg_strdup(PQgetvalue(res, i, i_subdisableonerr));
5000  subinfo[i].subpasswordrequired =
5001  pg_strdup(PQgetvalue(res, i, i_subpasswordrequired));
5002  subinfo[i].subrunasowner =
5003  pg_strdup(PQgetvalue(res, i, i_subrunasowner));
5004  subinfo[i].subconninfo =
5005  pg_strdup(PQgetvalue(res, i, i_subconninfo));
5006  if (PQgetisnull(res, i, i_subslotname))
5007  subinfo[i].subslotname = NULL;
5008  else
5009  subinfo[i].subslotname =
5010  pg_strdup(PQgetvalue(res, i, i_subslotname));
5011  subinfo[i].subsynccommit =
5012  pg_strdup(PQgetvalue(res, i, i_subsynccommit));
5013  subinfo[i].subpublications =
5014  pg_strdup(PQgetvalue(res, i, i_subpublications));
5015  subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
5016  if (PQgetisnull(res, i, i_suboriginremotelsn))
5017  subinfo[i].suboriginremotelsn = NULL;
5018  else
5019  subinfo[i].suboriginremotelsn =
5020  pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
5021  subinfo[i].subenabled =
5022  pg_strdup(PQgetvalue(res, i, i_subenabled));
5023  subinfo[i].subfailover =
5024  pg_strdup(PQgetvalue(res, i, i_subfailover));
5025 
5026  /* Decide whether we want to dump it */
5027  selectDumpableObject(&(subinfo[i].dobj), fout);
5028  }
5029  PQclear(res);
5030 
5031  destroyPQExpBuffer(query);
5032 }
static bool is_superuser(Archive *fout)
Definition: pg_dump.c:4800
int no_subscriptions
Definition: pg_backup.h:184

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_SUBSCRIPTION, _SubscriptionInfo::dobj, Archive::dopt, ExecuteSqlQuery(), getRoleName(), i, is_superuser(), LOGICALREP_ORIGIN_ANY, LOGICALREP_TWOPHASE_STATE_DISABLED, _dumpableObject::name, _dumpOptions::no_subscriptions, _dumpableObject::objType, CatalogId::oid, pg_log_warning, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _SubscriptionInfo::rolname, selectDumpableObject(), _SubscriptionInfo::subbinary, _SubscriptionInfo::subconninfo, _SubscriptionInfo::subdisableonerr, _SubscriptionInfo::subenabled, _SubscriptionInfo::subfailover, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, _SubscriptionInfo::subtwophasestate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSubscriptionTables()

void getSubscriptionTables ( Archive fout)

Definition at line 5040 of file pg_dump.c.

5041 {
5042  DumpOptions *dopt = fout->dopt;
5043  SubscriptionInfo *subinfo = NULL;
5044  SubRelInfo *subrinfo;
5045  PGresult *res;
5046  int i_srsubid;
5047  int i_srrelid;
5048  int i_srsubstate;
5049  int i_srsublsn;
5050  int ntups;
5051  Oid last_srsubid = InvalidOid;
5052 
5053  if (dopt->no_subscriptions || !dopt->binary_upgrade ||
5054  fout->remoteVersion < 170000)
5055  return;
5056 
5057  res = ExecuteSqlQuery(fout,
5058  "SELECT srsubid, srrelid, srsubstate, srsublsn "
5059  "FROM pg_catalog.pg_subscription_rel "
5060  "ORDER BY srsubid",
5061  PGRES_TUPLES_OK);
5062  ntups = PQntuples(res);
5063  if (ntups == 0)
5064  goto cleanup;
5065 
5066  /* Get pg_subscription_rel attributes */
5067  i_srsubid = PQfnumber(res, "srsubid");
5068  i_srrelid = PQfnumber(res, "srrelid");
5069  i_srsubstate = PQfnumber(res, "srsubstate");
5070  i_srsublsn = PQfnumber(res, "srsublsn");
5071 
5072  subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
5073  for (int i = 0; i < ntups; i++)
5074  {
5075  Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
5076  Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
5077  TableInfo *tblinfo;
5078 
5079  /*
5080  * If we switched to a new subscription, check if the subscription
5081  * exists.
5082  */
5083  if (cur_srsubid != last_srsubid)
5084  {
5085  subinfo = findSubscriptionByOid(cur_srsubid);
5086  if (subinfo == NULL)
5087  pg_fatal("subscription with OID %u does not exist", cur_srsubid);
5088 
5089  last_srsubid = cur_srsubid;
5090  }
5091 
5092  tblinfo = findTableByOid(relid);
5093  if (tblinfo == NULL)
5094  pg_fatal("failed sanity check, table with OID %u not found",
5095  relid);
5096 
5097  /* OK, make a DumpableObject for this relationship */
5098  subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
5099  subrinfo[i].dobj.catId.tableoid = relid;
5100  subrinfo[i].dobj.catId.oid = cur_srsubid;
5101  AssignDumpId(&subrinfo[i].dobj);
5102  subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
5103  subrinfo[i].tblinfo = tblinfo;
5104  subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
5105  if (PQgetisnull(res, i, i_srsublsn))
5106  subrinfo[i].srsublsn = NULL;
5107  else
5108  subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
5109 
5110  subrinfo[i].subinfo = subinfo;
5111 
5112  /* Decide whether we want to dump it */
5113  selectDumpableObject(&(subrinfo[i].dobj), fout);
5114  }
5115 
5116 cleanup:
5117  PQclear(res);
5118 }
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:1003

References AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, cleanup(), DO_SUBSCRIPTION_REL, _SubscriptionInfo::dobj, _SubRelInfo::dobj, Archive::dopt, ExecuteSqlQuery(), findSubscriptionByOid(), findTableByOid(), i, InvalidOid, _dumpableObject::name, _dumpOptions::no_subscriptions, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, selectDumpableObject(), _SubRelInfo::srsublsn, _SubRelInfo::srsubstate, _SubRelInfo::subinfo, CatalogId::tableoid, and _SubRelInfo::tblinfo.

Referenced by getSchemaData().

◆ getTableAttrs()

void getTableAttrs ( Archive fout,
TableInfo tblinfo,
int  numTables 
)

Definition at line 8736 of file pg_dump.c.

8737 {
8738  DumpOptions *dopt = fout->dopt;
8740  PQExpBuffer tbloids = createPQExpBuffer();
8741  PQExpBuffer checkoids = createPQExpBuffer();
8742  PGresult *res;
8743  int ntups;
8744  int curtblindx;
8745  int i_attrelid;
8746  int i_attnum;
8747  int i_attname;
8748  int i_atttypname;
8749  int i_attstattarget;
8750  int i_attstorage;
8751  int i_typstorage;
8752  int i_attidentity;
8753  int i_attgenerated;
8754  int i_attisdropped;
8755  int i_attlen;
8756  int i_attalign;
8757  int i_attislocal;
8758  int i_notnull_name;
8759  int i_notnull_noinherit;
8760  int i_notnull_islocal;
8761  int i_attoptions;
8762  int i_attcollation;
8763  int i_attcompression;
8764  int i_attfdwoptions;
8765  int i_attmissingval;
8766  int i_atthasdef;
8767 
8768  /*
8769  * We want to perform just one query against pg_attribute, and then just
8770  * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
8771  * (for CHECK constraints and for NOT NULL constraints). However, we
8772  * mustn't try to select every row of those catalogs and then sort it out
8773  * on the client side, because some of the server-side functions we need
8774  * would be unsafe to apply to tables we don't have lock on. Hence, we
8775  * build an array of the OIDs of tables we care about (and now have lock
8776  * on!), and use a WHERE clause to constrain which rows are selected.
8777  */
8778  appendPQExpBufferChar(tbloids, '{');
8779  appendPQExpBufferChar(checkoids, '{');
8780  for (int i = 0; i < numTables; i++)
8781  {
8782  TableInfo *tbinfo = &tblinfo[i];
8783 
8784  /* Don't bother to collect info for sequences */
8785  if (tbinfo->relkind == RELKIND_SEQUENCE)
8786  continue;
8787 
8788  /* Don't bother with uninteresting tables, either */
8789  if (!tbinfo->interesting)
8790  continue;
8791 
8792  /* OK, we need info for this table */
8793  if (tbloids->len > 1) /* do we have more than the '{'? */
8794  appendPQExpBufferChar(tbloids, ',');
8795  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8796 
8797  if (tbinfo->ncheck > 0)
8798  {
8799  /* Also make a list of the ones with check constraints */
8800  if (checkoids->len > 1) /* do we have more than the '{'? */
8801  appendPQExpBufferChar(checkoids, ',');
8802  appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
8803  }
8804  }
8805  appendPQExpBufferChar(tbloids, '}');
8806  appendPQExpBufferChar(checkoids, '}');
8807 
8808  /*
8809  * Find all the user attributes and their types.
8810  *
8811  * Since we only want to dump COLLATE clauses for attributes whose
8812  * collation is different from their type's default, we use a CASE here to
8813  * suppress uninteresting attcollations cheaply.
8814  */
8816  "SELECT\n"
8817  "a.attrelid,\n"
8818  "a.attnum,\n"
8819  "a.attname,\n"
8820  "a.attstattarget,\n"
8821  "a.attstorage,\n"
8822  "t.typstorage,\n"
8823  "a.atthasdef,\n"
8824  "a.attisdropped,\n"
8825  "a.attlen,\n"
8826  "a.attalign,\n"
8827  "a.attislocal,\n"
8828  "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
8829  "array_to_string(a.attoptions, ', ') AS attoptions,\n"
8830  "CASE WHEN a.attcollation <> t.typcollation "
8831  "THEN a.attcollation ELSE 0 END AS attcollation,\n"
8832  "pg_catalog.array_to_string(ARRAY("
8833  "SELECT pg_catalog.quote_ident(option_name) || "
8834  "' ' || pg_catalog.quote_literal(option_value) "
8835  "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8836  "ORDER BY option_name"
8837  "), E',\n ') AS attfdwoptions,\n");
8838 
8839  /*
8840  * Find out any NOT NULL markings for each column. In 18 and up we read
8841  * pg_constraint to obtain the constraint name. notnull_noinherit is set
8842  * according to the NO INHERIT property. For versions prior to 18, we
8843  * store an empty string as the name when a constraint is marked as
8844  * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
8845  * without a name); also, such cases are never NO INHERIT.
8846  *
8847  * We track in notnull_islocal whether the constraint was defined directly
8848  * in this table or via an ancestor, for binary upgrade. flagInhAttrs
8849  * might modify this later for servers older than 18; it's also in charge
8850  * of determining the correct inhcount.
8851  */
8852  if (fout->remoteVersion >= 180000)
8854  "co.conname AS notnull_name,\n"
8855  "co.connoinherit AS notnull_noinherit,\n"
8856  "co.conislocal AS notnull_islocal,\n");
8857  else
8859  "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
8860  "false AS notnull_noinherit,\n"
8861  "a.attislocal AS notnull_islocal,\n");
8862 
8863  if (fout->remoteVersion >= 140000)
8865  "a.attcompression AS attcompression,\n");
8866  else
8868  "'' AS attcompression,\n");
8869 
8870  if (fout->remoteVersion >= 100000)
8872  "a.attidentity,\n");
8873  else
8875  "'' AS attidentity,\n");
8876 
8877  if (fout->remoteVersion >= 110000)
8879  "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8880  "THEN a.attmissingval ELSE null END AS attmissingval,\n");
8881  else
8883  "NULL AS attmissingval,\n");
8884 
8885  if (fout->remoteVersion >= 120000)
8887  "a.attgenerated\n");
8888  else
8890  "'' AS attgenerated\n");
8891 
8892  /* need left join to pg_type to not fail on dropped columns ... */
8894  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8895  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
8896  "LEFT JOIN pg_catalog.pg_type t "
8897  "ON (a.atttypid = t.oid)\n",
8898  tbloids->data);
8899 
8900  /*
8901  * In versions 18 and up, we need pg_constraint for explicit NOT NULL
8902  * entries. Also, we need to know if the NOT NULL for each column is
8903  * backing a primary key.
8904  */
8905  if (fout->remoteVersion >= 180000)
8907  " LEFT JOIN pg_catalog.pg_constraint co ON "
8908  "(a.attrelid = co.conrelid\n"
8909  " AND co.contype = 'n' AND "
8910  "co.conkey = array[a.attnum])\n");
8911 
8913  "WHERE a.attnum > 0::pg_catalog.int2\n"
8914  "ORDER BY a.attrelid, a.attnum");
8915 
8916  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8917 
8918  ntups = PQntuples(res);
8919 
8920  i_attrelid = PQfnumber(res, "attrelid");
8921  i_attnum = PQfnumber(res, "attnum");
8922  i_attname = PQfnumber(res, "attname");
8923  i_atttypname = PQfnumber(res, "atttypname");
8924  i_attstattarget = PQfnumber(res, "attstattarget");
8925  i_attstorage = PQfnumber(res, "attstorage");
8926  i_typstorage = PQfnumber(res, "typstorage");
8927  i_attidentity = PQfnumber(res, "attidentity");
8928  i_attgenerated = PQfnumber(res, "attgenerated");
8929  i_attisdropped = PQfnumber(res, "attisdropped");
8930  i_attlen = PQfnumber(res, "attlen");
8931  i_attalign = PQfnumber(res, "attalign");
8932  i_attislocal = PQfnumber(res, "attislocal");
8933  i_notnull_name = PQfnumber(res, "notnull_name");
8934  i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
8935  i_notnull_islocal = PQfnumber(res, "notnull_islocal");
8936  i_attoptions = PQfnumber(res, "attoptions");
8937  i_attcollation = PQfnumber(res, "attcollation");
8938  i_attcompression = PQfnumber(res, "attcompression");
8939  i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8940  i_attmissingval = PQfnumber(res, "attmissingval");
8941  i_atthasdef = PQfnumber(res, "atthasdef");
8942 
8943  /* Within the next loop, we'll accumulate OIDs of tables with defaults */
8944  resetPQExpBuffer(tbloids);
8945  appendPQExpBufferChar(tbloids, '{');
8946 
8947  /*
8948  * Outer loop iterates once per table, not once per row. Incrementing of
8949  * r is handled by the inner loop.
8950  */
8951  curtblindx = -1;
8952  for (int r = 0; r < ntups;)
8953  {
8954  Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
8955  TableInfo *tbinfo = NULL;
8956  int numatts;
8957  bool hasdefaults;
8958 
8959  /* Count rows for this table */
8960  for (numatts = 1; numatts < ntups - r; numatts++)
8961  if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
8962  break;
8963 
8964  /*
8965  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8966  * order.
8967  */
8968  while (++curtblindx < numTables)
8969  {
8970  tbinfo = &tblinfo[curtblindx];
8971  if (tbinfo->dobj.catId.oid == attrelid)
8972  break;
8973  }
8974  if (curtblindx >= numTables)
8975  pg_fatal("unrecognized table OID %u", attrelid);
8976  /* cross-check that we only got requested tables */
8977  if (tbinfo->relkind == RELKIND_SEQUENCE ||
8978  !tbinfo->interesting)
8979  pg_fatal("unexpected column data for table \"%s\"",
8980  tbinfo->dobj.name);
8981 
8982  /* Save data for this table */
8983  tbinfo->numatts = numatts;
8984  tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
8985  tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
8986  tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
8987  tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
8988  tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
8989  tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
8990  tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
8991  tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
8992  tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
8993  tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
8994  tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
8995  tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
8996  tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
8997  tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
8998  tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
8999  tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
9000  tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
9001  tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
9002  tbinfo->notnull_islocal = (bool *) pg_malloc(numatts * sizeof(bool));
9003  tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
9004  hasdefaults = false;
9005 
9006  for (int j = 0; j < numatts; j++, r++)
9007  {
9008  if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
9009  pg_fatal("invalid column numbering in table \"%s\"",
9010  tbinfo->dobj.name);
9011  tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
9012  tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
9013  if (PQgetisnull(res, r, i_attstattarget))
9014  tbinfo->attstattarget[j] = -1;
9015  else
9016  tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
9017  tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
9018  tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
9019  tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
9020  tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
9021  tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
9022  tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
9023  tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
9024  tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
9025  tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
9026 
9027  /* Handle not-null constraint name and flags */
9028  determineNotNullFlags(fout, res, r,
9029  tbinfo, j,
9030  i_notnull_name, i_notnull_noinherit,
9031  i_notnull_islocal);
9032 
9033  tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
9034  tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
9035  tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
9036  tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
9037  tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
9038  tbinfo->attrdefs[j] = NULL; /* fix below */
9039  if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
9040  hasdefaults = true;
9041  }
9042 
9043  if (hasdefaults)
9044  {
9045  /* Collect OIDs of interesting tables that have defaults */
9046  if (tbloids->len > 1) /* do we have more than the '{'? */
9047  appendPQExpBufferChar(tbloids, ',');
9048  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9049  }
9050  }
9051 
9052  PQclear(res);
9053 
9054  /*
9055  * Now get info about column defaults. This is skipped for a data-only
9056  * dump, as it is only needed for table schemas.
9057  */
9058  if (!dopt->dataOnly && tbloids->len > 1)
9059  {
9060  AttrDefInfo *attrdefs;
9061  int numDefaults;
9062  TableInfo *tbinfo = NULL;
9063 
9064  pg_log_info("finding table default expressions");
9065 
9066  appendPQExpBufferChar(tbloids, '}');
9067 
9068  printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9069  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9070  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9071  "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9072  "ORDER BY a.adrelid, a.adnum",
9073  tbloids->data);
9074 
9075  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9076 
9077  numDefaults = PQntuples(res);
9078  attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9079 
9080  curtblindx = -1;
9081  for (int j = 0; j < numDefaults; j++)
9082  {
9083  Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9084  Oid adoid = atooid(PQgetvalue(res, j, 1));
9085  Oid adrelid = atooid(PQgetvalue(res, j, 2));
9086  int adnum = atoi(PQgetvalue(res, j, 3));
9087  char *adsrc = PQgetvalue(res, j, 4);
9088 
9089  /*
9090  * Locate the associated TableInfo; we rely on tblinfo[] being in
9091  * OID order.
9092  */
9093  if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9094  {
9095  while (++curtblindx < numTables)
9096  {
9097  tbinfo = &tblinfo[curtblindx];
9098  if (tbinfo->dobj.catId.oid == adrelid)
9099  break;
9100  }
9101  if (curtblindx >= numTables)
9102  pg_fatal("unrecognized table OID %u", adrelid);
9103  }
9104 
9105  if (adnum <= 0 || adnum > tbinfo->numatts)
9106  pg_fatal("invalid adnum value %d for table \"%s\"",
9107  adnum, tbinfo->dobj.name);
9108 
9109  /*
9110  * dropped columns shouldn't have defaults, but just in case,
9111  * ignore 'em
9112  */
9113  if (tbinfo->attisdropped[adnum - 1])
9114  continue;
9115 
9116  attrdefs[j].dobj.objType = DO_ATTRDEF;
9117  attrdefs[j].dobj.catId.tableoid = adtableoid;
9118  attrdefs[j].dobj.catId.oid = adoid;
9119  AssignDumpId(&attrdefs[j].dobj);
9120  attrdefs[j].adtable = tbinfo;
9121  attrdefs[j].adnum = adnum;
9122  attrdefs[j].adef_expr = pg_strdup(adsrc);
9123 
9124  attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9125  attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9126 
9127  attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9128 
9129  /*
9130  * Figure out whether the default/generation expression should be
9131  * dumped as part of the main CREATE TABLE (or similar) command or
9132  * as a separate ALTER TABLE (or similar) command. The preference
9133  * is to put it into the CREATE command, but in some cases that's
9134  * not possible.
9135  */
9136  if (tbinfo->attgenerated[adnum - 1])
9137  {
9138  /*
9139  * Column generation expressions cannot be dumped separately,
9140  * because there is no syntax for it. By setting separate to
9141  * false here we prevent the "default" from being processed as
9142  * its own dumpable object. Later, flagInhAttrs() will mark
9143  * it as not to be dumped at all, if possible (that is, if it
9144  * can be inherited from a parent).
9145  */
9146  attrdefs[j].separate = false;
9147  }
9148  else if (tbinfo->relkind == RELKIND_VIEW)
9149  {
9150  /*
9151  * Defaults on a VIEW must always be dumped as separate ALTER
9152  * TABLE commands.
9153  */
9154  attrdefs[j].separate = true;
9155  }
9156  else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9157  {
9158  /* column will be suppressed, print default separately */
9159  attrdefs[j].separate = true;
9160  }
9161  else
9162  {
9163  attrdefs[j].separate = false;
9164  }
9165 
9166  if (!attrdefs[j].separate)
9167  {
9168  /*
9169  * Mark the default as needing to appear before the table, so
9170  * that any dependencies it has must be emitted before the
9171  * CREATE TABLE. If this is not possible, we'll change to
9172  * "separate" mode while sorting dependencies.
9173  */
9174  addObjectDependency(&tbinfo->dobj,
9175  attrdefs[j].dobj.dumpId);
9176  }
9177 
9178  tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9179  }
9180 
9181  PQclear(res);
9182  }
9183 
9184  /*
9185  * Get info about table CHECK constraints. This is skipped for a
9186  * data-only dump, as it is only needed for table schemas.
9187  */
9188  if (!dopt->dataOnly && checkoids->len > 2)
9189  {
9190  ConstraintInfo *constrs;
9191  int numConstrs;
9192  int i_tableoid;
9193  int i_oid;
9194  int i_conrelid;
9195  int i_conname;
9196  int i_consrc;
9197  int i_conislocal;
9198  int i_convalidated;
9199 
9200  pg_log_info("finding table check constraints");
9201 
9202  resetPQExpBuffer(q);
9204  "SELECT c.tableoid, c.oid, conrelid, conname, "
9205  "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9206  "conislocal, convalidated "
9207  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9208  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9209  "WHERE contype = 'c' "
9210  "ORDER BY c.conrelid, c.conname",
9211  checkoids->data);
9212 
9213  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9214 
9215  numConstrs = PQntuples(res);
9216  constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9217 
9218  i_tableoid = PQfnumber(res, "tableoid");
9219  i_oid = PQfnumber(res, "oid");
9220  i_conrelid = PQfnumber(res, "conrelid");
9221  i_conname = PQfnumber(res, "conname");
9222  i_consrc = PQfnumber(res, "consrc");
9223  i_conislocal = PQfnumber(res, "conislocal");
9224  i_convalidated = PQfnumber(res, "convalidated");
9225 
9226  /* As above, this loop iterates once per table, not once per row */
9227  curtblindx = -1;
9228  for (int j = 0; j < numConstrs;)
9229  {
9230  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9231  TableInfo *tbinfo = NULL;
9232  int numcons;
9233 
9234  /* Count rows for this table */
9235  for (numcons = 1; numcons < numConstrs - j; numcons++)
9236  if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9237  break;
9238 
9239  /*
9240  * Locate the associated TableInfo; we rely on tblinfo[] being in
9241  * OID order.
9242  */
9243  while (++curtblindx < numTables)
9244  {
9245  tbinfo = &tblinfo[curtblindx];
9246  if (tbinfo->dobj.catId.oid == conrelid)
9247  break;
9248  }
9249  if (curtblindx >= numTables)
9250  pg_fatal("unrecognized table OID %u", conrelid);
9251 
9252  if (numcons != tbinfo->ncheck)
9253  {
9254  pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9255  "expected %d check constraints on table \"%s\" but found %d",
9256  tbinfo->ncheck),
9257  tbinfo->ncheck, tbinfo->dobj.name, numcons);
9258  pg_log_error_hint("The system catalogs might be corrupted.");
9259  exit_nicely(1);
9260  }
9261 
9262  tbinfo->checkexprs = constrs + j;
9263 
9264  for (int c = 0; c < numcons; c++, j++)
9265  {
9266  bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9267 
9268  constrs[j].dobj.objType = DO_CONSTRAINT;
9269  constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9270  constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9271  AssignDumpId(&constrs[j].dobj);
9272  constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9273  constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9274  constrs[j].contable = tbinfo;
9275  constrs[j].condomain = NULL;
9276  constrs[j].contype = 'c';
9277  constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9278  constrs[j].confrelid = InvalidOid;
9279  constrs[j].conindex = 0;
9280  constrs[j].condeferrable = false;
9281  constrs[j].condeferred = false;
9282  constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9283 
9284  /*
9285  * An unvalidated constraint needs to be dumped separately, so
9286  * that potentially-violating existing data is loaded before
9287  * the constraint.
9288  */
9289  constrs[j].separate = !validated;
9290 
9291  constrs[j].dobj.dump = tbinfo->dobj.dump;
9292 
9293  /*
9294  * Mark the constraint as needing to appear before the table
9295  * --- this is so that any other dependencies of the
9296  * constraint will be emitted before we try to create the
9297  * table. If the constraint is to be dumped separately, it
9298  * will be dumped after data is loaded anyway, so don't do it.
9299  * (There's an automatic dependency in the opposite direction
9300  * anyway, so don't need to add one manually here.)
9301  */
9302  if (!constrs[j].separate)
9303  addObjectDependency(&tbinfo->dobj,
9304  constrs[j].dobj.dumpId);
9305 
9306  /*
9307  * We will detect later whether the constraint must be split
9308  * out from the table definition.
9309  */
9310  }
9311  }
9312 
9313  PQclear(res);
9314  }
9315 
9316  destroyPQExpBuffer(q);
9317  destroyPQExpBuffer(tbloids);
9318  destroyPQExpBuffer(checkoids);
9319 }
#define pg_log_error_hint(...)
Definition: logging.h:112
static void determineNotNullFlags(Archive *fout, PGresult *res, int r, TableInfo *tbinfo, int j, int i_notnull_name, int i_notnull_noinherit, int i_notnull_islocal)
Definition: pg_dump.c:9357

References addObjectDependency(), _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attcompression, _tableInfo::attfdwoptions, _tableInfo::attgenerated, _tableInfo::attidentity, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attmissingval, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypnames, _dumpableObject::catId, _tableInfo::checkexprs, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), determineNotNullFlags(), DO_ATTRDEF, DO_CONSTRAINT, _tableInfo::dobj, _attrDefInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), exit_nicely, i, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull_constrs, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, _tableInfo::numatts, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, res, resetPQExpBuffer(), _attrDefInfo::separate, _constraintInfo::separate, shouldPrintColumn(), CatalogId::tableoid, and _tableInfo::typstorage.

Referenced by getSchemaData().

◆ getTableData()

static void getTableData ( DumpOptions dopt,
TableInfo tblinfo,
int  numTables,
char  relkind 
)
static

Definition at line 2836 of file pg_dump.c.

2837 {
2838  int i;
2839 
2840  for (i = 0; i < numTables; i++)
2841  {
2842  if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
2843  (!relkind || tblinfo[i].relkind == relkind))
2844  makeTableDataInfo(dopt, &(tblinfo[i]));
2845  }
2846 }
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2855

References DUMP_COMPONENT_DATA, i, makeTableDataInfo(), and _tableInfo::relkind.

Referenced by main().

◆ getTableDataFKConstraints()

static void getTableDataFKConstraints ( void  )
static

Definition at line 3044 of file pg_dump.c.

3045 {
3046  DumpableObject **dobjs;
3047  int numObjs;
3048  int i;
3049 
3050  /* Search through all the dumpable objects for FK constraints */
3051  getDumpableObjects(&dobjs, &numObjs);
3052  for (i = 0; i < numObjs; i++)
3053  {
3054  if (dobjs[i]->objType == DO_FK_CONSTRAINT)
3055  {
3056  ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
3057  TableInfo *ftable;
3058 
3059  /* Not interesting unless both tables are to be dumped */
3060  if (cinfo->contable == NULL ||
3061  cinfo->contable->dataObj == NULL)
3062  continue;
3063  ftable = findTableByOid(cinfo->confrelid);
3064  if (ftable == NULL ||
3065  ftable->dataObj == NULL)
3066  continue;
3067 
3068  /*
3069  * Okay, make referencing table's TABLE_DATA object depend on the
3070  * referenced table's TABLE_DATA object.
3071  */
3073  ftable->dataObj->dobj.dumpId);
3074  }
3075  }
3076  free(dobjs);
3077 }
void getDumpableObjects(DumpableObject ***objs, int *numObjs)
Definition: common.c:774

References addObjectDependency(), _constraintInfo::confrelid, _constraintInfo::contable, _tableInfo::dataObj, DO_FK_CONSTRAINT, _tableDataInfo::dobj, _dumpableObject::dumpId, findTableByOid(), free, getDumpableObjects(), and i.

Referenced by main().

◆ getTables()

TableInfo* getTables ( Archive fout,
int *  numTables 
)

Definition at line 6785 of file pg_dump.c.

6786 {
6787  DumpOptions *dopt = fout->dopt;
6788  PGresult *res;
6789  int ntups;
6790  int i;
6791  PQExpBuffer query = createPQExpBuffer();
6792  TableInfo *tblinfo;
6793  int i_reltableoid;
6794  int i_reloid;
6795  int i_relname;
6796  int i_relnamespace;
6797  int i_relkind;
6798  int i_reltype;
6799  int i_relowner;
6800  int i_relchecks;
6801  int i_relhasindex;
6802  int i_relhasrules;
6803  int i_relpages;
6804  int i_toastpages;
6805  int i_owning_tab;
6806  int i_owning_col;
6807  int i_reltablespace;
6808  int i_relhasoids;
6809  int i_relhastriggers;
6810  int i_relpersistence;
6811  int i_relispopulated;
6812  int i_relreplident;
6813  int i_relrowsec;
6814  int i_relforcerowsec;
6815  int i_relfrozenxid;
6816  int i_toastfrozenxid;
6817  int i_toastoid;
6818  int i_relminmxid;
6819  int i_toastminmxid;
6820  int i_reloptions;
6821  int i_checkoption;
6822  int i_toastreloptions;
6823  int i_reloftype;
6824  int i_foreignserver;
6825  int i_amname;
6826  int i_is_identity_sequence;
6827  int i_relacl;
6828  int i_acldefault;
6829  int i_ispartition;
6830 
6831  /*
6832  * Find all the tables and table-like objects.
6833  *
6834  * We must fetch all tables in this phase because otherwise we cannot
6835  * correctly identify inherited columns, owned sequences, etc.
6836  *
6837  * We include system catalogs, so that we can work if a user table is
6838  * defined to inherit from a system catalog (pretty weird, but...)
6839  *
6840  * Note: in this phase we should collect only a minimal amount of
6841  * information about each table, basically just enough to decide if it is
6842  * interesting. In particular, since we do not yet have lock on any user
6843  * table, we MUST NOT invoke any server-side data collection functions
6844  * (for instance, pg_get_partkeydef()). Those are likely to fail or give
6845  * wrong answers if any concurrent DDL is happening.
6846  */
6847 
6848  appendPQExpBufferStr(query,
6849  "SELECT c.tableoid, c.oid, c.relname, "
6850  "c.relnamespace, c.relkind, c.reltype, "
6851  "c.relowner, "
6852  "c.relchecks, "
6853  "c.relhasindex, c.relhasrules, c.relpages, "
6854  "c.relhastriggers, "
6855  "c.relpersistence, "
6856  "c.reloftype, "
6857  "c.relacl, "
6858  "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
6859  " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
6860  "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
6861  "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
6862  "ELSE 0 END AS foreignserver, "
6863  "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
6864  "tc.oid AS toid, "
6865  "tc.relpages AS toastpages, "
6866  "tc.reloptions AS toast_reloptions, "
6867  "d.refobjid AS owning_tab, "
6868  "d.refobjsubid AS owning_col, "
6869  "tsp.spcname AS reltablespace, ");
6870 
6871  if (fout->remoteVersion >= 120000)
6872  appendPQExpBufferStr(query,
6873  "false AS relhasoids, ");
6874  else
6875  appendPQExpBufferStr(query,
6876  "c.relhasoids, ");
6877 
6878  if (fout->remoteVersion >= 90300)
6879  appendPQExpBufferStr(query,
6880  "c.relispopulated, ");
6881  else
6882  appendPQExpBufferStr(query,
6883  "'t' as relispopulated, ");
6884 
6885  if (fout->remoteVersion >= 90400)
6886  appendPQExpBufferStr(query,
6887  "c.relreplident, ");
6888  else
6889  appendPQExpBufferStr(query,
6890  "'d' AS relreplident, ");
6891 
6892  if (fout->remoteVersion >= 90500)
6893  appendPQExpBufferStr(query,
6894  "c.relrowsecurity, c.relforcerowsecurity, ");
6895  else
6896  appendPQExpBufferStr(query,
6897  "false AS relrowsecurity, "
6898  "false AS relforcerowsecurity, ");
6899 
6900  if (fout->remoteVersion >= 90300)
6901  appendPQExpBufferStr(query,
6902  "c.relminmxid, tc.relminmxid AS tminmxid, ");
6903  else
6904  appendPQExpBufferStr(query,
6905  "0 AS relminmxid, 0 AS tminmxid, ");
6906 
6907  if (fout->remoteVersion >= 90300)
6908  appendPQExpBufferStr(query,
6909  "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
6910  "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
6911  "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
6912  else
6913  appendPQExpBufferStr(query,
6914  "c.reloptions, NULL AS checkoption, ");
6915 
6916  if (fout->remoteVersion >= 90600)
6917  appendPQExpBufferStr(query,
6918  "am.amname, ");
6919  else
6920  appendPQExpBufferStr(query,
6921  "NULL AS amname, ");
6922 
6923  if (fout->remoteVersion >= 90600)
6924  appendPQExpBufferStr(query,
6925  "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
6926  else
6927  appendPQExpBufferStr(query,
6928  "false AS is_identity_sequence, ");
6929 
6930  if (fout->remoteVersion >= 100000)
6931  appendPQExpBufferStr(query,
6932  "c.relispartition AS ispartition ");
6933  else
6934  appendPQExpBufferStr(query,
6935  "false AS ispartition ");
6936 
6937  /*
6938  * Left join to pg_depend to pick up dependency info linking sequences to
6939  * their owning column, if any (note this dependency is AUTO except for
6940  * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
6941  * collect the spcname.
6942  */
6943  appendPQExpBufferStr(query,
6944  "\nFROM pg_class c\n"
6945  "LEFT JOIN pg_depend d ON "
6946  "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
6947  "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
6948  "d.objsubid = 0 AND "
6949  "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
6950  "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
6951 
6952  /*
6953  * In 9.6 and up, left join to pg_am to pick up the amname.
6954  */
6955  if (fout->remoteVersion >= 90600)
6956  appendPQExpBufferStr(query,
6957  "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
6958 
6959  /*
6960  * We purposefully ignore toast OIDs for partitioned tables; the reason is
6961  * that versions 10 and 11 have them, but later versions do not, so
6962  * emitting them causes the upgrade to fail.
6963  */
6964  appendPQExpBufferStr(query,
6965  "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
6966  " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
6967  " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
6968 
6969  /*
6970  * Restrict to interesting relkinds (in particular, not indexes). Not all
6971  * relkinds are possible in older servers, but it's not worth the trouble
6972  * to emit a version-dependent list.
6973  *
6974  * Composite-type table entries won't be dumped as such, but we have to
6975  * make a DumpableObject for them so that we can track dependencies of the
6976  * composite type (pg_depend entries for columns of the composite type
6977  * link to the pg_class entry not the pg_type entry).
6978  */
6979  appendPQExpBufferStr(query,
6980  "WHERE c.relkind IN ("
6981  CppAsString2(RELKIND_RELATION) ", "
6982  CppAsString2(RELKIND_SEQUENCE) ", "
6983  CppAsString2(RELKIND_VIEW) ", "
6984  CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
6985  CppAsString2(RELKIND_MATVIEW) ", "
6986  CppAsString2(RELKIND_FOREIGN_TABLE) ", "
6987  CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
6988  "ORDER BY c.oid");
6989 
6990  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6991 
6992  ntups = PQntuples(res);
6993 
6994  *numTables = ntups;
6995 
6996  /*
6997  * Extract data from result and lock dumpable tables. We do the locking
6998  * before anything else, to minimize the window wherein a table could
6999  * disappear under us.
7000  *
7001  * Note that we have to save info about all tables here, even when dumping
7002  * only one, because we don't yet know which tables might be inheritance
7003  * ancestors of the target table.
7004  */
7005  tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
7006 
7007  i_reltableoid = PQfnumber(res, "tableoid");
7008  i_reloid = PQfnumber(res, "oid");
7009  i_relname = PQfnumber(res, "relname");
7010  i_relnamespace = PQfnumber(res, "relnamespace");
7011  i_relkind = PQfnumber(res, "relkind");
7012  i_reltype = PQfnumber(res, "reltype");
7013  i_relowner = PQfnumber(res, "relowner");
7014  i_relchecks = PQfnumber(res, "relchecks");
7015  i_relhasindex = PQfnumber(res, "relhasindex");
7016  i_relhasrules = PQfnumber(res, "relhasrules");
7017  i_relpages = PQfnumber(res, "relpages");
7018  i_toastpages = PQfnumber(res, "toastpages");
7019  i_owning_tab = PQfnumber(res, "owning_tab");
7020  i_owning_col = PQfnumber(res, "owning_col");
7021  i_reltablespace = PQfnumber(res, "reltablespace");
7022  i_relhasoids = PQfnumber(res, "relhasoids");
7023  i_relhastriggers = PQfnumber(res, "relhastriggers");
7024  i_relpersistence = PQfnumber(res, "relpersistence");
7025  i_relispopulated = PQfnumber(res, "relispopulated");
7026  i_relreplident = PQfnumber(res, "relreplident");
7027  i_relrowsec = PQfnumber(res, "relrowsecurity");
7028  i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
7029  i_relfrozenxid = PQfnumber(res, "relfrozenxid");
7030  i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
7031  i_toastoid = PQfnumber(res, "toid");
7032  i_relminmxid = PQfnumber(res, "relminmxid");
7033  i_toastminmxid = PQfnumber(res, "tminmxid");
7034  i_reloptions = PQfnumber(res, "reloptions");
7035  i_checkoption = PQfnumber(res, "checkoption");
7036  i_toastreloptions = PQfnumber(res, "toast_reloptions");
7037  i_reloftype = PQfnumber(res, "reloftype");
7038  i_foreignserver = PQfnumber(res, "foreignserver");
7039  i_amname = PQfnumber(res, "amname");
7040  i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
7041  i_relacl = PQfnumber(res, "relacl");
7042  i_acldefault = PQfnumber(res, "acldefault");
7043  i_ispartition = PQfnumber(res, "ispartition");
7044 
7045  if (dopt->lockWaitTimeout)
7046  {
7047  /*
7048  * Arrange to fail instead of waiting forever for a table lock.
7049  *
7050  * NB: this coding assumes that the only queries issued within the
7051  * following loop are LOCK TABLEs; else the timeout may be undesirably
7052  * applied to other things too.
7053  */
7054  resetPQExpBuffer(query);
7055  appendPQExpBufferStr(query, "SET statement_timeout = ");
7057  ExecuteSqlStatement(fout, query->data);
7058  }
7059 
7060  resetPQExpBuffer(query);
7061 
7062  for (i = 0; i < ntups; i++)
7063  {
7064  tblinfo[i].dobj.objType = DO_TABLE;
7065  tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
7066  tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
7067  AssignDumpId(&tblinfo[i].dobj);
7068  tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
7069  tblinfo[i].dobj.namespace =
7070  findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
7071  tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
7072  tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
7073  tblinfo[i].dacl.privtype = 0;
7074  tblinfo[i].dacl.initprivs = NULL;
7075  tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
7076  tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
7077  tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
7078  tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
7079  tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
7080  tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
7081  tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
7082  if (PQgetisnull(res, i, i_toastpages))
7083  tblinfo[i].toastpages = 0;
7084  else
7085  tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
7086  if (PQgetisnull(res, i, i_owning_tab))
7087  {
7088  tblinfo[i].owning_tab = InvalidOid;
7089  tblinfo[i].owning_col = 0;
7090  }
7091  else
7092  {
7093  tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
7094  tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
7095  }
7096  tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
7097  tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
7098  tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
7099  tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
7100  tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
7101  tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
7102  tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
7103  tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
7104  tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
7105  tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
7106  tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
7107  tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
7108  tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
7109  tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
7110  if (PQgetisnull(res, i, i_checkoption))
7111  tblinfo[i].checkoption = NULL;
7112  else
7113  tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
7114  tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
7115  tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
7116  tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
7117  if (PQgetisnull(res, i, i_amname))
7118  tblinfo[i].amname = NULL;
7119  else
7120  tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
7121  tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
7122  tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
7123 
7124  /* other fields were zeroed above */
7125 
7126  /*
7127  * Decide whether we want to dump this table.
7128  */
7129  if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
7130  tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
7131  else
7132  selectDumpableTable(&tblinfo[i], fout);
7133 
7134  /*
7135  * Now, consider the table "interesting" if we need to dump its
7136  * definition or its data. Later on, we'll skip a lot of data
7137  * collection for uninteresting tables.
7138  *
7139  * Note: the "interesting" flag will also be set by flagInhTables for
7140  * parents of interesting tables, so that we collect necessary
7141  * inheritance info even when the parents are not themselves being
7142  * dumped. This is the main reason why we need an "interesting" flag
7143  * that's separate from the components-to-dump bitmask.
7144  */
7145  tblinfo[i].interesting = (tblinfo[i].dobj.dump &
7147  DUMP_COMPONENT_DATA)) != 0;
7148 
7149  tblinfo[i].dummy_view = false; /* might get set during sort */
7150  tblinfo[i].postponed_def = false; /* might get set during sort */
7151 
7152  /* Tables have data */
7153  tblinfo[i].dobj.components |= DUMP_COMPONENT_DATA;
7154 
7155  /* Mark whether table has an ACL */
7156  if (!PQgetisnull(res, i, i_relacl))
7157  tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
7158  tblinfo[i].hascolumnACLs = false; /* may get set later */
7159 
7160  /*
7161  * Read-lock target tables to make sure they aren't DROPPED or altered
7162  * in schema before we get around to dumping them.
7163  *
7164  * Note that we don't explicitly lock parents of the target tables; we
7165  * assume our lock on the child is enough to prevent schema
7166  * alterations to parent tables.
7167  *
7168  * NOTE: it'd be kinda nice to lock other relations too, not only
7169  * plain or partitioned tables, but the backend doesn't presently
7170  * allow that.
7171  *
7172  * We only need to lock the table for certain components; see
7173  * pg_dump.h
7174  */
7175  if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
7176  (tblinfo[i].relkind == RELKIND_RELATION ||
7177  tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
7178  {
7179  /*
7180  * Tables are locked in batches. When dumping from a remote
7181  * server this can save a significant amount of time by reducing
7182  * the number of round trips.
7183  */
7184  if (query->len == 0)
7185  appendPQExpBuffer(query, "LOCK TABLE %s",
7186  fmtQualifiedDumpable(&tblinfo[i]));
7187  else
7188  {
7189  appendPQExpBuffer(query, ", %s",
7190  fmtQualifiedDumpable(&tblinfo[i]));
7191 
7192  /* Arbitrarily end a batch when query length reaches 100K. */
7193  if (query->len >= 100000)
7194  {
7195  /* Lock another batch of tables. */
7196  appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7197  ExecuteSqlStatement(fout, query->data);
7198  resetPQExpBuffer(query);
7199  }
7200  }
7201  }
7202  }
7203 
7204  if (query->len != 0)
7205  {
7206  /* Lock the tables in the last batch. */
7207  appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7208  ExecuteSqlStatement(fout, query->data);
7209  }
7210 
7211  if (dopt->lockWaitTimeout)
7212  {
7213  ExecuteSqlStatement(fout, "SET statement_timeout = 0");
7214  }
7215 
7216  PQclear(res);
7217 
7218  destroyPQExpBuffer(query);
7219 
7220  return tblinfo;
7221 }
static void selectDumpableTable(TableInfo *tbinfo, Archive *fout)
Definition: pg_dump.c:1910
#define DUMP_COMPONENTS_REQUIRING_LOCK
Definition: pg_dump.h:128
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
const char * lockWaitTimeout
Definition: pg_backup.h:174
Oid foreign_server
Definition: pg_dump.h:312
bool hasrules
Definition: pg_dump.h:298
bool hastriggers
Definition: pg_dump.h:299

References _dumpableAcl::acl, _dumpableAcl::acldefault, _tableInfo::amname, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), AssignDumpId(), atooid, _dumpableObject::catId, _tableInfo::checkoption, _dumpableObject::components, CppAsString2, createPQExpBuffer(), _tableInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_TABLE, _tableInfo::dobj, Archive::dopt, _tableInfo::dummy_view, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DATA, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, DUMP_COMPONENTS_REQUIRING_LOCK, ExecuteSqlQuery(), ExecuteSqlStatement(), findNamespace(), fmtQualifiedDumpable, _tableInfo::forcerowsec, _tableInfo::foreign_server, _tableInfo::frozenxid, GetConnection(), getRoleName(), _tableInfo::hascolumnACLs, _tableInfo::hasindex, _tableInfo::hasoids, _tableInfo::hasrules, _tableInfo::hastriggers, i, if(), _dumpableAcl::initprivs, _tableInfo::interesting, InvalidOid, _tableInfo::is_identity_sequence, _tableInfo::ispartition, PQExpBufferData::len, _dumpOptions::lockWaitTimeout, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, _dumpableObject::objType, CatalogId::oid, _tableInfo::owning_col, _tableInfo::owning_tab, pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, _tableInfo::postponed_def, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, _tableInfo::relispopulated, _tableInfo::relkind, _tableInfo::reloftype, _tableInfo::reloptions, _tableInfo::relpages, _tableInfo::relpersistence, _tableInfo::relreplident, _tableInfo::reltablespace, _tableInfo::reltype, Archive::remoteVersion, res, resetPQExpBuffer(), _tableInfo::rolname, _tableInfo::rowsec, selectDumpableTable(), CatalogId::tableoid, _tableInfo::toast_frozenxid, _tableInfo::toast_minmxid, _tableInfo::toast_oid, _tableInfo::toast_reloptions, and _tableInfo::toastpages.

Referenced by getSchemaData().

◆ getTransforms()

void getTransforms ( Archive fout)

Definition at line 8652 of file pg_dump.c.

8653 {
8654  PGresult *res;
8655  int ntups;
8656  int i;
8657  PQExpBuffer query;
8658  TransformInfo *transforminfo;
8659  int i_tableoid;
8660  int i_oid;
8661  int i_trftype;
8662  int i_trflang;
8663  int i_trffromsql;
8664  int i_trftosql;
8665 
8666  /* Transforms didn't exist pre-9.5 */
8667  if (fout->remoteVersion < 90500)
8668  return;
8669 
8670  query = createPQExpBuffer();
8671 
8672  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8673  "trftype, trflang, trffromsql::oid, trftosql::oid "
8674  "FROM pg_transform "
8675  "ORDER BY 3,4");
8676 
8677  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8678 
8679  ntups = PQntuples(res);
8680 
8681  transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8682 
8683  i_tableoid = PQfnumber(res, "tableoid");
8684  i_oid = PQfnumber(res, "oid");
8685  i_trftype = PQfnumber(res, "trftype");
8686  i_trflang = PQfnumber(res, "trflang");
8687  i_trffromsql = PQfnumber(res, "trffromsql");
8688  i_trftosql = PQfnumber(res, "trftosql");
8689 
8690  for (i = 0; i < ntups; i++)
8691  {
8692  PQExpBufferData namebuf;
8693  TypeInfo *typeInfo;
8694  char *lanname;
8695 
8696  transforminfo[i].dobj.objType = DO_TRANSFORM;
8697  transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8698  transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8699  AssignDumpId(&transforminfo[i].dobj);
8700  transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8701  transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8702  transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8703  transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8704 
8705  /*
8706  * Try to name transform as concatenation of type and language name.
8707  * This is only used for purposes of sorting. If we fail to find
8708  * either, the name will be an empty string.
8709  */
8710  initPQExpBuffer(&namebuf);
8711  typeInfo = findTypeByOid(transforminfo[i].trftype);
8712  lanname = get_language_name(fout, transforminfo[i].trflang);
8713  if (typeInfo && lanname)
8714  appendPQExpBuffer(&namebuf, "%s %s",
8715  typeInfo->dobj.name, lanname);
8716  transforminfo[i].dobj.name = namebuf.data;
8717  free(lanname);
8718 
8719  /* Decide whether we want to dump it */
8720  selectDumpableObject(&(transforminfo[i].dobj), fout);
8721  }
8722 
8723  PQclear(res);
8724 
8725  destroyPQExpBuffer(query);
8726 }

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TRANSFORM, _typeInfo::dobj, _transformInfo::dobj, ExecuteSqlQuery(), findTypeByOid(), free, get_language_name(), i, initPQExpBuffer(), _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, selectDumpableObject(), CatalogId::tableoid, _transformInfo::trffromsql, _transformInfo::trflang, _transformInfo::trftosql, and _transformInfo::trftype.

Referenced by getSchemaData().

◆ getTriggers()

void getTriggers ( Archive fout,
TableInfo  tblinfo[],
int  numTables 
)

Definition at line 8184 of file pg_dump.c.

8185 {
8186  PQExpBuffer query = createPQExpBuffer();
8187  PQExpBuffer tbloids = createPQExpBuffer();
8188  PGresult *res;
8189  int ntups;
8190  int curtblindx;
8191  TriggerInfo *tginfo;
8192  int i_tableoid,
8193  i_oid,
8194  i_tgrelid,
8195  i_tgname,
8196  i_tgenabled,
8197  i_tgispartition,
8198  i_tgdef;
8199 
8200  /*
8201  * We want to perform just one query against pg_trigger. However, we
8202  * mustn't try to select every row of the catalog and then sort it out on
8203  * the client side, because some of the server-side functions we need
8204  * would be unsafe to apply to tables we don't have lock on. Hence, we
8205  * build an array of the OIDs of tables we care about (and now have lock
8206  * on!), and use a WHERE clause to constrain which rows are selected.
8207  */
8208  appendPQExpBufferChar(tbloids, '{');
8209  for (int i = 0; i < numTables; i++)
8210  {
8211  TableInfo *tbinfo = &tblinfo[i];
8212 
8213  if (!tbinfo->hastriggers ||
8214  !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8215  continue;
8216 
8217  /* OK, we need info for this table */
8218  if (tbloids->len > 1) /* do we have more than the '{'? */
8219  appendPQExpBufferChar(tbloids, ',');
8220  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8221  }
8222  appendPQExpBufferChar(tbloids, '}');
8223 
8224  if (fout->remoteVersion >= 150000)
8225  {
8226  /*
8227  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8228  * result in non-forward-compatible dumps of WHEN clauses due to
8229  * under-parenthesization.
8230  *
8231  * NB: We need to see partition triggers in case the tgenabled flag
8232  * has been changed from the parent.
8233  */
8234  appendPQExpBuffer(query,
8235  "SELECT t.tgrelid, t.tgname, "
8236  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8237  "t.tgenabled, t.tableoid, t.oid, "
8238  "t.tgparentid <> 0 AS tgispartition\n"
8239  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8240  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8241  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8242  "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
8243  "OR t.tgenabled != u.tgenabled) "
8244  "ORDER BY t.tgrelid, t.tgname",
8245  tbloids->data);
8246  }
8247  else if (fout->remoteVersion >= 130000)
8248  {
8249  /*
8250  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8251  * result in non-forward-compatible dumps of WHEN clauses due to
8252  * under-parenthesization.
8253  *
8254  * NB: We need to see tgisinternal triggers in partitions, in case the
8255  * tgenabled flag has been changed from the parent.
8256  */
8257  appendPQExpBuffer(query,
8258  "SELECT t.tgrelid, t.tgname, "
8259  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8260  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
8261  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8262  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8263  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8264  "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
8265  "ORDER BY t.tgrelid, t.tgname",
8266  tbloids->data);
8267  }
8268  else if (fout->remoteVersion >= 110000)
8269  {
8270  /*
8271  * NB: We need to see tgisinternal triggers in partitions, in case the
8272  * tgenabled flag has been changed from the parent. No tgparentid in
8273  * version 11-12, so we have to match them via pg_depend.
8274  *
8275  * See above about pretty=true in pg_get_triggerdef.
8276  */
8277  appendPQExpBuffer(query,
8278  "SELECT t.tgrelid, t.tgname, "
8279  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8280  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
8281  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8282  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8283  "LEFT JOIN pg_catalog.pg_depend AS d ON "
8284  " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8285  " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8286  " d.objid = t.oid "
8287  "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8288  "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
8289  "ORDER BY t.tgrelid, t.tgname",
8290  tbloids->data);
8291  }
8292  else
8293  {
8294  /* See above about pretty=true in pg_get_triggerdef */
8295  appendPQExpBuffer(query,
8296  "SELECT t.tgrelid, t.tgname, "
8297  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8298  "t.tgenabled, false as tgispartition, "
8299  "t.tableoid, t.oid "
8300  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8301  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8302  "WHERE NOT tgisinternal "
8303  "ORDER BY t.tgrelid, t.tgname",
8304  tbloids->data);
8305  }
8306 
8307  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8308 
8309  ntups = PQntuples(res);
8310 
8311  i_tableoid = PQfnumber(res, "tableoid");
8312  i_oid = PQfnumber(res, "oid");
8313  i_tgrelid = PQfnumber(res, "tgrelid");
8314  i_tgname = PQfnumber(res, "tgname");
8315  i_tgenabled = PQfnumber(res, "tgenabled");
8316  i_tgispartition = PQfnumber(res, "tgispartition");
8317  i_tgdef = PQfnumber(res, "tgdef");
8318 
8319  tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
8320 
8321  /*
8322  * Outer loop iterates once per table, not once per row. Incrementing of
8323  * j is handled by the inner loop.
8324  */
8325  curtblindx = -1;
8326  for (int j = 0; j < ntups;)
8327  {
8328  Oid tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
8329  TableInfo *tbinfo = NULL;
8330  int numtrigs;
8331 
8332  /* Count rows for this table */
8333  for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
8334  if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
8335  break;
8336 
8337  /*
8338  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8339  * order.
8340  */
8341  while (++curtblindx < numTables)
8342  {
8343  tbinfo = &tblinfo[curtblindx];
8344  if (tbinfo->dobj.catId.oid == tgrelid)
8345  break;
8346  }
8347  if (curtblindx >= numTables)
8348  pg_fatal("unrecognized table OID %u", tgrelid);
8349 
8350  /* Save data for this table */
8351  tbinfo->triggers = tginfo + j;
8352  tbinfo->numTriggers = numtrigs;
8353 
8354  for (int c = 0; c < numtrigs; c++, j++)
8355  {
8356  tginfo[j].dobj.objType = DO_TRIGGER;
8357  tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8358  tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8359  AssignDumpId(&tginfo[j].dobj);
8360  tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
8361  tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8362  tginfo[j].tgtable = tbinfo;
8363  tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8364  tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
8365  tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
8366  }
8367  }
8368 
8369  PQclear(res);
8370 
8371  destroyPQExpBuffer(query);
8372  destroyPQExpBuffer(tbloids);
8373 }
struct _triggerInfo * triggers
Definition: pg_dump.h:368
int numTriggers
Definition: pg_dump.h:367

References appendPQExpBuffer(), appendPQExpBufferChar(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TRIGGER, _tableInfo::dobj, _triggerInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, ExecuteSqlQuery(), _tableInfo::hastriggers, i, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::numTriggers, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, CatalogId::tableoid, _triggerInfo::tgdef, _triggerInfo::tgenabled, _triggerInfo::tgispartition, _triggerInfo::tgtable, and _tableInfo::triggers.

Referenced by getSchemaData().

◆ getTSConfigurations()

void getTSConfigurations ( Archive fout)

Definition at line 9657 of file pg_dump.c.

9658 {
9659  PGresult *res;
9660  int ntups;
9661  int i;
9662  PQExpBuffer query;
9663  TSConfigInfo *cfginfo;
9664  int i_tableoid;
9665  int i_oid;
9666  int i_cfgname;
9667  int i_cfgnamespace;
9668  int i_cfgowner;
9669  int i_cfgparser;
9670 
9671  query = createPQExpBuffer();
9672 
9673  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9674  "cfgnamespace, cfgowner, cfgparser "
9675  "FROM pg_ts_config");
9676 
9677  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9678 
9679  ntups = PQntuples(res);
9680 
9681  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9682 
9683  i_tableoid = PQfnumber(res, "tableoid");
9684  i_oid = PQfnumber(res, "oid");
9685  i_cfgname = PQfnumber(res, "cfgname");
9686  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9687  i_cfgowner = PQfnumber(res, "cfgowner");
9688  i_cfgparser = PQfnumber(res, "cfgparser");
9689 
9690  for (i = 0; i < ntups; i++)
9691  {
9692  cfginfo[i].dobj.objType = DO_TSCONFIG;
9693  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9694  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9695  AssignDumpId(&cfginfo[i].dobj);
9696  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9697  cfginfo[i].dobj.namespace =
9698  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9699  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9700  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9701 
9702  /* Decide whether we want to dump it */
9703  selectDumpableObject(&(cfginfo[i].dobj), fout);
9704  }
9705 
9706  PQclear(res);
9707 
9708  destroyPQExpBuffer(query);
9709 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _cfgInfo::cfgparser, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TSCONFIG, _cfgInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, _cfgInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSDictionaries()

void getTSDictionaries ( Archive fout)

Definition at line 9532 of file pg_dump.c.

9533 {
9534  PGresult *res;
9535  int ntups;
9536  int i;
9537  PQExpBuffer query;
9538  TSDictInfo *dictinfo;
9539  int i_tableoid;
9540  int i_oid;
9541  int i_dictname;
9542  int i_dictnamespace;
9543  int i_dictowner;
9544  int i_dicttemplate;
9545  int i_dictinitoption;
9546 
9547  query = createPQExpBuffer();
9548 
9549  appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9550  "dictnamespace, dictowner, "
9551  "dicttemplate, dictinitoption "
9552  "FROM pg_ts_dict");
9553 
9554  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9555 
9556  ntups = PQntuples(res);
9557 
9558  dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9559 
9560  i_tableoid = PQfnumber(res, "tableoid");
9561  i_oid = PQfnumber(res, "oid");
9562  i_dictname = PQfnumber(res, "dictname");
9563  i_dictnamespace = PQfnumber(res, "dictnamespace");
9564  i_dictowner = PQfnumber(res, "dictowner");
9565  i_dictinitoption = PQfnumber(res, "dictinitoption");
9566  i_dicttemplate = PQfnumber(res, "dicttemplate");
9567 
9568  for (i = 0; i < ntups; i++)
9569  {
9570  dictinfo[i].dobj.objType = DO_TSDICT;
9571  dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9572  dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9573  AssignDumpId(&dictinfo[i].dobj);
9574  dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9575  dictinfo[i].dobj.namespace =
9576  findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9577  dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9578  dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9579  if (PQgetisnull(res, i, i_dictinitoption))
9580  dictinfo[i].dictinitoption = NULL;
9581  else
9582  dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9583 
9584  /* Decide whether we want to dump it */
9585  selectDumpableObject(&(dictinfo[i].dobj), fout);
9586  }
9587 
9588  PQclear(res);
9589 
9590  destroyPQExpBuffer(query);
9591 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _dictInfo::dictinitoption, _dictInfo::dicttemplate, DO_TSDICT, _dictInfo::dobj, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), res, _dictInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSParsers()

void getTSParsers ( Archive fout)

Definition at line 9458 of file pg_dump.c.

9459 {
9460  PGresult *res;
9461  int ntups;
9462  int i;
9463  PQExpBuffer query;
9464  TSParserInfo *prsinfo;
9465  int i_tableoid;
9466  int i_oid;
9467  int i_prsname;
9468  int i_prsnamespace;
9469  int i_prsstart;
9470  int i_prstoken;
9471  int i_prsend;
9472  int i_prsheadline;
9473  int i_prslextype;
9474 
9475  query = createPQExpBuffer();
9476 
9477  /*
9478  * find all text search objects, including builtin ones; we filter out
9479  * system-defined objects at dump-out time.
9480  */
9481 
9482  appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
9483  "prsstart::oid, prstoken::oid, "
9484  "prsend::oid, prsheadline::oid, prslextype::oid "
9485  "FROM pg_ts_parser");
9486 
9487  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9488 
9489  ntups = PQntuples(res);
9490 
9491  prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
9492 
9493  i_tableoid = PQfnumber(res, "tableoid");
9494  i_oid = PQfnumber(res, "oid");
9495  i_prsname = PQfnumber(res, "prsname");
9496  i_prsnamespace = PQfnumber(res, "prsnamespace");
9497  i_prsstart = PQfnumber(res, "prsstart");
9498  i_prstoken = PQfnumber(res, "prstoken");
9499  i_prsend = PQfnumber(res, "prsend");
9500  i_prsheadline = PQfnumber(res, "prsheadline");
9501  i_prslextype = PQfnumber(res, "prslextype");
9502 
9503  for (i = 0; i < ntups; i++)
9504  {
9505  prsinfo[i].dobj.objType = DO_TSPARSER;
9506  prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9507  prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9508  AssignDumpId(&prsinfo[i].dobj);
9509  prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
9510  prsinfo[i].dobj.namespace =
9511  findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
9512  prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
9513  prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
9514  prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
9515  prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
9516  prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
9517 
9518  /* Decide whether we want to dump it */
9519  selectDumpableObject(&(prsinfo[i].dobj), fout);
9520  }
9521 
9522  PQclear(res);
9523 
9524  destroyPQExpBuffer(query);
9525 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TSPARSER, _prsInfo::dobj, ExecuteSqlQuery(), findNamespace(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _prsInfo::prsend, _prsInfo::prsheadline, _prsInfo::prslextype, _prsInfo::prsstart, _prsInfo::prstoken, res, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSTemplates()

void getTSTemplates ( Archive fout)

Definition at line 9598 of file pg_dump.c.

9599 {
9600  PGresult *res;
9601  int ntups;
9602  int i;
9603  PQExpBuffer query;
9604  TSTemplateInfo *tmplinfo;
9605  int i_tableoid;
9606  int i_oid;
9607  int i_tmplname;
9608  int i_tmplnamespace;
9609  int i_tmplinit;
9610  int i_tmpllexize;
9611 
9612  query = createPQExpBuffer();
9613 
9614  appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
9615  "tmplnamespace, tmplinit::oid, tmpllexize::oid "
9616  "FROM pg_ts_template");
9617 
9618  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9619 
9620  ntups = PQntuples(res);
9621 
9622  tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
9623 
9624  i_tableoid = PQfnumber(res, "tableoid");
9625  i_oid = PQfnumber(res, "oid");
9626  i_tmplname = PQfnumber(res, "tmplname");
9627  i_tmplnamespace = PQfnumber(res, "tmplnamespace");
9628  i_tmplinit = PQfnumber(res, "tmplinit");
9629  i_tmpllexize = PQfnumber(res, "tmpllexize");
9630 
9631  for (i = 0; i < ntups; i++)
9632  {
9633  tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
9634  tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9635  tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9636  AssignDumpId(&tmplinfo[i].dobj);
9637  tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
9638  tmplinfo[i].dobj.namespace =
9639  findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
9640  tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
9641  tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
9642 
9643  /* Decide whether we want to dump it */
9644  selectDumpableObject(&(tmplinfo[i].dobj), fout);
9645  }
9646 
9647  PQclear(res);
9648 
9649  destroyPQExpBuffer(query);
9650 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TSTEMPLATE, _tmplInfo::dobj, ExecuteSqlQuery(), findNamespace(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), res, selectDumpableObject(), CatalogId::tableoid, _tmplInfo::tmplinit, and _tmplInfo::tmpllexize.

Referenced by getSchemaData().

◆ getTypes()

void getTypes ( Archive fout)

Definition at line 5906 of file pg_dump.c.

5907 {
5908  PGresult *res;
5909  int ntups;
5910  int i;
5911  PQExpBuffer query = createPQExpBuffer();
5912  TypeInfo *tyinfo;
5913  ShellTypeInfo *stinfo;
5914  int i_tableoid;
5915  int i_oid;
5916  int i_typname;
5917  int i_typnamespace;
5918  int i_typacl;
5919  int i_acldefault;
5920  int i_typowner;
5921  int i_typelem;
5922  int i_typrelid;
5923  int i_typrelkind;
5924  int i_typtype;
5925  int i_typisdefined;
5926  int i_isarray;
5927  int i_typarray;
5928 
5929  /*
5930  * we include even the built-in types because those may be used as array
5931  * elements by user-defined types
5932  *
5933  * we filter out the built-in types when we dump out the types
5934  *
5935  * same approach for undefined (shell) types and array types
5936  *
5937  * Note: as of 8.3 we can reliably detect whether a type is an
5938  * auto-generated array type by checking the element type's typarray.
5939  * (Before that the test is capable of generating false positives.) We
5940  * still check for name beginning with '_', though, so as to avoid the
5941  * cost of the subselect probe for all standard types. This would have to
5942  * be revisited if the backend ever allows renaming of array types.
5943  */
5944  appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
5945  "typnamespace, typacl, "
5946  "acldefault('T', typowner) AS acldefault, "
5947  "typowner, "
5948  "typelem, typrelid, typarray, "
5949  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
5950  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
5951  "typtype, typisdefined, "
5952  "typname[0] = '_' AND typelem != 0 AND "
5953  "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
5954  "FROM pg_type");
5955 
5956  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5957 
5958  ntups = PQntuples(res);
5959 
5960  tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
5961 
5962  i_tableoid = PQfnumber(res, "tableoid");
5963  i_oid = PQfnumber(res, "oid");
5964  i_typname = PQfnumber(res, "typname");
5965  i_typnamespace = PQfnumber(res, "typnamespace");
5966  i_typacl = PQfnumber(res, "typacl");
5967  i_acldefault = PQfnumber(res, "acldefault");
5968  i_typowner = PQfnumber(res, "typowner");
5969  i_typelem = PQfnumber(res, "typelem");
5970  i_typrelid = PQfnumber(res, "typrelid");
5971  i_typrelkind = PQfnumber(res, "typrelkind");
5972  i_typtype = PQfnumber(res, "typtype");
5973  i_typisdefined = PQfnumber(res, "typisdefined");
5974  i_isarray = PQfnumber(res, "isarray");
5975  i_typarray = PQfnumber(res, "typarray");
5976 
5977  for (i = 0; i < ntups; i++)
5978  {
5979  tyinfo[i].dobj.objType = DO_TYPE;
5980  tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5981  tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5982  AssignDumpId(&tyinfo[i].dobj);
5983  tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
5984  tyinfo[i].dobj.namespace =
5985  findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
5986  tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
5987  tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5988  tyinfo[i].dacl.privtype = 0;
5989  tyinfo[i].dacl.initprivs = NULL;
5990  tyinfo[i].ftypname = NULL; /* may get filled later */
5991  tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
5992  tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
5993  tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
5994  tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
5995  tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
5996  tyinfo[i].shellType = NULL;
5997 
5998  if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
5999  tyinfo[i].isDefined = true;
6000  else
6001  tyinfo[i].isDefined = false;
6002 
6003  if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
6004  tyinfo[i].isArray = true;
6005  else
6006  tyinfo[i].isArray = false;
6007 
6008  tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
6009 
6010  if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
6011  tyinfo[i].isMultirange = true;
6012  else
6013  tyinfo[i].isMultirange = false;
6014 
6015  /* Decide whether we want to dump it */
6016  selectDumpableType(&tyinfo[i], fout);
6017 
6018  /* Mark whether type has an ACL */
6019  if (!PQgetisnull(res, i, i_typacl))
6020  tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
6021 
6022  /*
6023  * If it's a domain, fetch info about its constraints, if any
6024  */
6025  tyinfo[i].nDomChecks = 0;
6026  tyinfo[i].domChecks = NULL;
6027  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6028  tyinfo[i].typtype == TYPTYPE_DOMAIN)
6029  getDomainConstraints(fout, &(tyinfo[i]));
6030 
6031  /*
6032  * If it's a base type, make a DumpableObject representing a shell
6033  * definition of the type. We will need to dump that ahead of the I/O
6034  * functions for the type. Similarly, range types need a shell
6035  * definition in case they have a canonicalize function.
6036  *
6037  * Note: the shell type doesn't have a catId. You might think it
6038  * should copy the base type's catId, but then it might capture the
6039  * pg_depend entries for the type, which we don't want.
6040  */
6041  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6042  (tyinfo[i].typtype == TYPTYPE_BASE ||
6043  tyinfo[i].typtype == TYPTYPE_RANGE))
6044  {
6045  stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
6046  stinfo->dobj.objType = DO_SHELL_TYPE;
6047  stinfo->dobj.catId = nilCatalogId;
6048  AssignDumpId(&stinfo->dobj);
6049  stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
6050  stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
6051  stinfo->baseType = &(tyinfo[i]);
6052  tyinfo[i].shellType = stinfo;
6053 
6054  /*
6055  * Initially mark the shell type as not to be dumped. We'll only
6056  * dump it if the I/O or canonicalize functions need to be dumped;
6057  * this is taken care of while sorting dependencies.
6058  */
6059  stinfo->dobj.dump = DUMP_COMPONENT_NONE;
6060  }
6061  }
6062 
6063  PQclear(res);
6064 
6065  destroyPQExpBuffer(query);
6066 }
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:7997
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:1949
bool isMultirange
Definition: pg_dump.h:207
char typrelkind
Definition: pg_dump.h:204
Oid typarray
Definition: pg_dump.h:203
struct _shellTypeInfo * shellType
Definition: pg_dump.h:210
bool isArray
Definition: pg_dump.h:206

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _shellTypeInfo::baseType, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_SHELL_TYPE, DO_TYPE, _typeInfo::dobj, _shellTypeInfo::dobj, _typeInfo::domChecks, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, ExecuteSqlQuery(), findNamespace(), _typeInfo::ftypname, getDomainConstraints(), getRoleName(), i, _dumpableAcl::initprivs, _typeInfo::isArray, _typeInfo::isDefined, _typeInfo::isMultirange, _dumpableObject::name, _typeInfo::nDomChecks, nilCatalogId, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, _typeInfo::rolname, selectDumpableType(), _typeInfo::shellType, CatalogId::tableoid, _typeInfo::typarray, _typeInfo::typelem, _typeInfo::typrelid, _typeInfo::typrelkind, and _typeInfo::typtype.

Referenced by getSchemaData().

◆ help()

static void help ( const char *  progname)
static

Definition at line 1153 of file pg_dump.c.

1154 {
1155  printf(_("%s dumps a database as a text file or to other formats.\n\n"), progname);
1156  printf(_("Usage:\n"));
1157  printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
1158 
1159  printf(_("\nGeneral options:\n"));
1160  printf(_(" -f, --file=FILENAME output file or directory name\n"));
1161  printf(_(" -F, --format=c|d|t|p output file format (custom, directory, tar,\n"
1162  " plain text (default))\n"));
1163  printf(_(" -j, --jobs=NUM use this many parallel jobs to dump\n"));
1164  printf(_(" -v, --verbose verbose mode\n"));
1165  printf(_(" -V, --version output version information, then exit\n"));
1166  printf(_(" -Z, --compress=METHOD[:DETAIL]\n"
1167  " compress as specified\n"));
1168  printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
1169  printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
1170  printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
1171  printf(_(" -?, --help show this help, then exit\n"));
1172 
1173  printf(_("\nOptions controlling the output content:\n"));
1174  printf(_(" -a, --data-only dump only the data, not the schema\n"));
1175  printf(_(" -b, --large-objects include large objects in dump\n"));
1176  printf(_(" --blobs (same as --large-objects, deprecated)\n"));
1177  printf(_(" -B, --no-large-objects exclude large objects in dump\n"));
1178  printf(_(" --no-blobs (same as --no-large-objects, deprecated)\n"));
1179  printf(_(" -c, --clean clean (drop) database objects before recreating\n"));
1180  printf(_(" -C, --create include commands to create database in dump\n"));
1181  printf(_(" -e, --extension=PATTERN dump the specified extension(s) only\n"));
1182  printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
1183  printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n"));
1184  printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
1185  printf(_(" -O, --no-owner skip restoration of object ownership in\n"
1186  " plain-text format\n"));
1187  printf(_(" -s, --schema-only dump only the schema, no data\n"));
1188  printf(_(" -S, --superuser=NAME superuser user name to use in plain-text format\n"));
1189  printf(_(" -t, --table=PATTERN dump only the specified table(s)\n"));
1190  printf(_(" -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n"));
1191  printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
1192  printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
1193  printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
1194  printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
1195  printf(_(" --disable-triggers disable triggers during data-only restore\n"));
1196  printf(_(" --enable-row-security enable row security (dump only content user has\n"
1197  " access to)\n"));
1198  printf(_(" --exclude-extension=PATTERN do NOT dump the specified extension(s)\n"));
1199  printf(_(" --exclude-table-and-children=PATTERN\n"
1200  " do NOT dump the specified table(s), including\n"
1201  " child and partition tables\n"));
1202  printf(_(" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
1203  printf(_(" --exclude-table-data-and-children=PATTERN\n"
1204  " do NOT dump data for the specified table(s),\n"
1205  " including child and partition tables\n"));
1206  printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
1207  printf(_(" --filter=FILENAME include or exclude objects and data from dump\n"
1208  " based on expressions in FILENAME\n"));
1209  printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
1210  printf(_(" --include-foreign-data=PATTERN\n"
1211  " include data of foreign tables on foreign\n"
1212  " servers matching PATTERN\n"));
1213  printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
1214  printf(_(" --load-via-partition-root load partitions via the root table\n"));
1215  printf(_(" --no-comments do not dump comment commands\n"));
1216  printf(_(" --no-publications do not dump publications\n"));
1217  printf(_(" --no-security-labels do not dump security label assignments\n"));
1218  printf(_(" --no-subscriptions do not dump subscriptions\n"));
1219  printf(_(" --no-table-access-method do not dump table access methods\n"));
1220  printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
1221  printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
1222  printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
1223  printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
1224  printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
1225  printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
1226  printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
1227  printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
1228  printf(_(" --snapshot=SNAPSHOT use given snapshot for the dump\n"));
1229  printf(_(" --strict-names require table and/or schema include patterns to\n"
1230  " match at least one entity each\n"));
1231  printf(_(" --table-and-children=PATTERN dump only the specified table(s), including\n"
1232  " child and partition tables\n"));
1233  printf(_(" --use-set-session-authorization\n"
1234  " use SET SESSION AUTHORIZATION commands instead of\n"
1235  " ALTER OWNER commands to set ownership\n"));
1236 
1237  printf(_("\nConnection options:\n"));
1238  printf(_(" -d, --dbname=DBNAME database to dump\n"));
1239  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
1240  printf(_(" -p, --port=PORT database server port number\n"));
1241  printf(_(" -U, --username=NAME connect as specified database user\n"));
1242  printf(_(" -w, --no-password never prompt for password\n"));
1243  printf(_(" -W, --password force password prompt (should happen automatically)\n"));
1244  printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
1245 
1246  printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
1247  "variable value is used.\n\n"));
1248  printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1249  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1250 }
#define _(x)
Definition: elog.c:90
const char * progname
Definition: main.c:43
#define printf(...)
Definition: port.h:244

References _, printf, and progname.

Referenced by main().

◆ is_superuser()

static bool is_superuser ( Archive fout)
static

Definition at line 4800 of file pg_dump.c.

4801 {
4802  ArchiveHandle *AH = (ArchiveHandle *) fout;
4803  const char *val;
4804 
4805  val = PQparameterStatus(AH->connection, "is_superuser");
4806 
4807  if (val && strcmp(val, "on") == 0)
4808  return true;
4809 
4810  return false;
4811 }
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7155
long val
Definition: informix.c:689

References _archiveHandle::connection, PQparameterStatus(), and val.

Referenced by check_role(), check_session_authorization(), get_prompt(), getSubscriptions(), InitializeSessionUserId(), SetCurrentRoleId(), SetOuterUserId(), SetSessionAuthorization(), and SetSessionUserId().

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 403 of file pg_dump.c.

404 {
405  int c;
406  const char *filename = NULL;
407  const char *format = "p";
408  TableInfo *tblinfo;
409  int numTables;
410  DumpableObject **dobjs;
411  int numObjs;
412  DumpableObject *boundaryObjs;
413  int i;
414  int optindex;
415  RestoreOptions *ropt;
416  Archive *fout; /* the script file */
417  bool g_verbose = false;
418  const char *dumpencoding = NULL;
419  const char *dumpsnapshot = NULL;
420  char *use_role = NULL;
421  int numWorkers = 1;
422  int plainText = 0;
423  ArchiveFormat archiveFormat = archUnknown;
424  ArchiveMode archiveMode;
425  pg_compress_specification compression_spec = {0};
426  char *compression_detail = NULL;
427  char *compression_algorithm_str = "none";
428  char *error_detail = NULL;
429  bool user_compression_defined = false;
431 
432  static DumpOptions dopt;
433 
434  static struct option long_options[] = {
435  {"data-only", no_argument, NULL, 'a'},
436  {"blobs", no_argument, NULL, 'b'},
437  {"large-objects", no_argument, NULL, 'b'},
438  {"no-blobs", no_argument, NULL, 'B'},
439  {"no-large-objects", no_argument, NULL, 'B'},
440  {"clean", no_argument, NULL, 'c'},
441  {"create", no_argument, NULL, 'C'},
442  {"dbname", required_argument, NULL, 'd'},
443  {"extension", required_argument, NULL, 'e'},
444  {"file", required_argument, NULL, 'f'},
445  {"format", required_argument, NULL, 'F'},
446  {"host", required_argument, NULL, 'h'},
447  {"jobs", 1, NULL, 'j'},
448  {"no-reconnect", no_argument, NULL, 'R'},
449  {"no-owner", no_argument, NULL, 'O'},
450  {"port", required_argument, NULL, 'p'},
451  {"schema", required_argument, NULL, 'n'},
452  {"exclude-schema", required_argument, NULL, 'N'},
453  {"schema-only", no_argument, NULL, 's'},
454  {"superuser", required_argument, NULL, 'S'},
455  {"table", required_argument, NULL, 't'},
456  {"exclude-table", required_argument, NULL, 'T'},
457  {"no-password", no_argument, NULL, 'w'},
458  {"password", no_argument, NULL, 'W'},
459  {"username", required_argument, NULL, 'U'},
460  {"verbose", no_argument, NULL, 'v'},
461  {"no-privileges", no_argument, NULL, 'x'},
462  {"no-acl", no_argument, NULL, 'x'},
463  {"compress", required_argument, NULL, 'Z'},
464  {"encoding", required_argument, NULL, 'E'},
465  {"help", no_argument, NULL, '?'},
466  {"version", no_argument, NULL, 'V'},
467 
468  /*
469  * the following options don't have an equivalent short option letter
470  */
471  {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
472  {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
473  {"column-inserts", no_argument, &dopt.column_inserts, 1},
474  {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
475  {"disable-triggers", no_argument, &dopt.disable_triggers, 1},
476  {"enable-row-security", no_argument, &dopt.enable_row_security, 1},
477  {"exclude-table-data", required_argument, NULL, 4},
478  {"extra-float-digits", required_argument, NULL, 8},
479  {"if-exists", no_argument, &dopt.if_exists, 1},
480  {"inserts", no_argument, NULL, 9},
481  {"lock-wait-timeout", required_argument, NULL, 2},
482  {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1},
483  {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
484  {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
485  {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1},
486  {"role", required_argument, NULL, 3},
487  {"section", required_argument, NULL, 5},
488  {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
489  {"snapshot", required_argument, NULL, 6},
490  {"strict-names", no_argument, &strict_names, 1},
491  {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
492  {"no-comments", no_argument, &dopt.no_comments, 1},
493  {"no-publications", no_argument, &dopt.no_publications, 1},
494  {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
495  {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
496  {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
497  {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
498  {"no-sync", no_argument, NULL, 7},
499  {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
500  {"rows-per-insert", required_argument, NULL, 10},
501  {"include-foreign-data", required_argument, NULL, 11},
502  {"table-and-children", required_argument, NULL, 12},
503  {"exclude-table-and-children", required_argument, NULL, 13},
504  {"exclude-table-data-and-children", required_argument, NULL, 14},
505  {"sync-method", required_argument, NULL, 15},
506  {"filter", required_argument, NULL, 16},
507  {"exclude-extension", required_argument, NULL, 17},
508 
509  {NULL, 0, NULL, 0}
510  };
511 
512  pg_logging_init(argv[0]);
514  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
515 
516  /*
517  * Initialize what we need for parallel execution, especially for thread
518  * support on Windows.
519  */
521 
522  progname = get_progname(argv[0]);
523 
524  if (argc > 1)
525  {
526  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
527  {
528  help(progname);
529  exit_nicely(0);
530  }
531  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
532  {
533  puts("pg_dump (PostgreSQL) " PG_VERSION);
534  exit_nicely(0);
535  }
536  }
537 
538  InitDumpOptions(&dopt);
539 
540  while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:",
541  long_options, &optindex)) != -1)
542  {
543  switch (c)
544  {
545  case 'a': /* Dump data only */
546  dopt.dataOnly = true;
547  break;
548 
549  case 'b': /* Dump LOs */
550  dopt.outputLOs = true;
551  break;
552 
553  case 'B': /* Don't dump LOs */
554  dopt.dontOutputLOs = true;
555  break;
556 
557  case 'c': /* clean (i.e., drop) schema prior to create */
558  dopt.outputClean = 1;
559  break;
560 
561  case 'C': /* Create DB */
562  dopt.outputCreateDB = 1;
563  break;
564 
565  case 'd': /* database name */
566  dopt.cparams.dbname = pg_strdup(optarg);
567  break;
568 
569  case 'e': /* include extension(s) */
571  dopt.include_everything = false;
572  break;
573 
574  case 'E': /* Dump encoding */
575  dumpencoding = pg_strdup(optarg);
576  break;
577 
578  case 'f':
580  break;
581 
582  case 'F':
584  break;
585 
586  case 'h': /* server host */
587  dopt.cparams.pghost = pg_strdup(optarg);
588  break;
589 
590  case 'j': /* number of dump jobs */
591  if (!option_parse_int(optarg, "-j/--jobs", 1,
592  PG_MAX_JOBS,
593  &numWorkers))
594  exit_nicely(1);
595  break;
596 
597  case 'n': /* include schema(s) */
599  dopt.include_everything = false;
600  break;
601 
602  case 'N': /* exclude schema(s) */
604  break;
605 
606  case 'O': /* Don't reconnect to match owner */
607  dopt.outputNoOwner = 1;
608  break;
609 
610  case 'p': /* server port */
611  dopt.cparams.pgport = pg_strdup(optarg);
612  break;
613 
614  case 'R':
615  /* no-op, still accepted for backwards compatibility */
616  break;
617 
618  case 's': /* dump schema only */
619  dopt.schemaOnly = true;
620  break;
621 
622  case 'S': /* Username for superuser in plain text output */
624  break;
625 
626  case 't': /* include table(s) */
628  dopt.include_everything = false;
629  break;
630 
631  case 'T': /* exclude table(s) */
633  break;
634 
635  case 'U':
637  break;
638 
639  case 'v': /* verbose */
640  g_verbose = true;
642  break;
643 
644  case 'w':
646  break;
647 
648  case 'W':
650  break;
651 
652  case 'x': /* skip ACL dump */
653  dopt.aclsSkip = true;
654  break;
655 
656  case 'Z': /* Compression */
657  parse_compress_options(optarg, &compression_algorithm_str,
658  &compression_detail);
659  user_compression_defined = true;
660  break;
661 
662  case 0:
663  /* This covers the long options. */
664  break;
665 
666  case 2: /* lock-wait-timeout */
668  break;
669 
670  case 3: /* SET ROLE */
671  use_role = pg_strdup(optarg);
672  break;
673 
674  case 4: /* exclude table(s) data */
676  break;
677 
678  case 5: /* section */
680  break;
681 
682  case 6: /* snapshot */
683  dumpsnapshot = pg_strdup(optarg);
684  break;
685 
686  case 7: /* no-sync */
687  dosync = false;
688  break;
689 
690  case 8:
692  if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
694  exit_nicely(1);
695  break;
696 
697  case 9: /* inserts */
698 
699  /*
700  * dump_inserts also stores --rows-per-insert, careful not to
701  * overwrite that.
702  */
703  if (dopt.dump_inserts == 0)
705  break;
706 
707  case 10: /* rows per insert */
708  if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
709  &dopt.dump_inserts))
710  exit_nicely(1);
711  break;
712 
713  case 11: /* include foreign data */
715  optarg);
716  break;
717 
718  case 12: /* include table(s) and their children */
720  optarg);
721  dopt.include_everything = false;
722  break;
723 
724  case 13: /* exclude table(s) and their children */
726  optarg);
727  break;
728 
729  case 14: /* exclude data of table(s) and children */
731  optarg);
732  break;
733 
734  case 15:
736  exit_nicely(1);
737  break;
738 
739  case 16: /* read object filters from file */
740  read_dump_filters(optarg, &dopt);
741  break;
742 
743  case 17: /* exclude extension(s) */
745  optarg);
746  break;
747 
748  default:
749  /* getopt_long already emitted a complaint */
750  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
751  exit_nicely(1);
752  }
753  }
754 
755  /*
756  * Non-option argument specifies database name as long as it wasn't
757  * already specified with -d / --dbname
758  */
759  if (optind < argc && dopt.cparams.dbname == NULL)
760  dopt.cparams.dbname = argv[optind++];
761 
762  /* Complain if any arguments remain */
763  if (optind < argc)
764  {
765  pg_log_error("too many command-line arguments (first is \"%s\")",
766  argv[optind]);
767  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
768  exit_nicely(1);
769  }
770 
771  /* --column-inserts implies --inserts */
772  if (dopt.column_inserts && dopt.dump_inserts == 0)
774 
775  /*
776  * Binary upgrade mode implies dumping sequence data even in schema-only
777  * mode. This is not exposed as a separate option, but kept separate
778  * internally for clarity.
779  */
780  if (dopt.binary_upgrade)
781  dopt.sequence_data = 1;
782 
783  if (dopt.dataOnly && dopt.schemaOnly)
784  pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
785 
787  pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
788 
789  if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
790  pg_fatal("option --include-foreign-data is not supported with parallel backup");
791 
792  if (dopt.dataOnly && dopt.outputClean)
793  pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
794 
795  if (dopt.if_exists && !dopt.outputClean)
796  pg_fatal("option --if-exists requires option -c/--clean");
797 
798  /*
799  * --inserts are already implied above if --column-inserts or
800  * --rows-per-insert were specified.
801  */
802  if (dopt.do_nothing && dopt.dump_inserts == 0)
803  pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
804 
805  /* Identify archive format to emit */
806  archiveFormat = parseArchiveFormat(format, &archiveMode);
807 
808  /* archiveFormat specific setup */
809  if (archiveFormat == archNull)
810  plainText = 1;
811 
812  /*
813  * Custom and directory formats are compressed by default with gzip when
814  * available, not the others. If gzip is not available, no compression is
815  * done by default.
816  */
817  if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
818  !user_compression_defined)
819  {
820 #ifdef HAVE_LIBZ
821  compression_algorithm_str = "gzip";
822 #else
823  compression_algorithm_str = "none";
824 #endif
825  }
826 
827  /*
828  * Compression options
829  */
830  if (!parse_compress_algorithm(compression_algorithm_str,
832  pg_fatal("unrecognized compression algorithm: \"%s\"",
833  compression_algorithm_str);
834 
836  &compression_spec);
837  error_detail = validate_compress_specification(&compression_spec);
838  if (error_detail != NULL)
839  pg_fatal("invalid compression specification: %s",
840  error_detail);
841 
842  error_detail = supports_compression(compression_spec);
843  if (error_detail != NULL)
844  pg_fatal("%s", error_detail);
845 
846  /*
847  * Disable support for zstd workers for now - these are based on
848  * threading, and it's unclear how it interacts with parallel dumps on
849  * platforms where that relies on threads too (e.g. Windows).
850  */
851  if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
852  pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
853  "workers");
854 
855  /*
856  * If emitting an archive format, we always want to emit a DATABASE item,
857  * in case --create is specified at pg_restore time.
858  */
859  if (!plainText)
860  dopt.outputCreateDB = 1;
861 
862  /* Parallel backup only in the directory archive format so far */
863  if (archiveFormat != archDirectory && numWorkers > 1)
864  pg_fatal("parallel backup only supported by the directory format");
865 
866  /* Open the output file */
867  fout = CreateArchive(filename, archiveFormat, compression_spec,
868  dosync, archiveMode, setupDumpWorker, sync_method);
869 
870  /* Make dump options accessible right away */
871  SetArchiveOptions(fout, &dopt, NULL);
872 
873  /* Register the cleanup hook */
874  on_exit_close_archive(fout);
875 
876  /* Let the archiver know how noisy to be */
877  fout->verbose = g_verbose;
878 
879 
880  /*
881  * We allow the server to be back to 9.2, and up to any minor release of
882  * our own major version. (See also version check in pg_dumpall.c.)
883  */
884  fout->minRemoteVersion = 90200;
885  fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
886 
887  fout->numWorkers = numWorkers;
888 
889  /*
890  * Open the database using the Archiver, so it knows about it. Errors mean
891  * death.
892  */
893  ConnectDatabase(fout, &dopt.cparams, false);
894  setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
895 
896  /*
897  * On hot standbys, never try to dump unlogged table data, since it will
898  * just throw an error.
899  */
900  if (fout->isStandby)
901  dopt.no_unlogged_table_data = true;
902 
903  /*
904  * Find the last built-in OID, if needed (prior to 8.1)
905  *
906  * With 8.1 and above, we can just use FirstNormalObjectId - 1.
907  */
909 
910  pg_log_info("last built-in OID is %u", g_last_builtin_oid);
911 
912  /* Expand schema selection patterns into OID lists */
913  if (schema_include_patterns.head != NULL)
914  {
917  strict_names);
918  if (schema_include_oids.head == NULL)
919  pg_fatal("no matching schemas were found");
920  }
923  false);
924  /* non-matching exclusion patterns aren't an error */
925 
926  /* Expand table selection patterns into OID lists */
929  strict_names, false);
932  strict_names, true);
933  if ((table_include_patterns.head != NULL ||
935  table_include_oids.head == NULL)
936  pg_fatal("no matching tables were found");
937 
940  false, false);
943  false, true);
944 
947  false, false);
950  false, true);
951 
954 
955  /* non-matching exclusion patterns aren't an error */
956 
957  /* Expand extension selection patterns into OID lists */
958  if (extension_include_patterns.head != NULL)
959  {
962  strict_names);
963  if (extension_include_oids.head == NULL)
964  pg_fatal("no matching extensions were found");
965  }
968  false);
969  /* non-matching exclusion patterns aren't an error */
970 
971  /*
972  * Dumping LOs is the default for dumps where an inclusion switch is not
973  * used (an "include everything" dump). -B can be used to exclude LOs
974  * from those dumps. -b can be used to include LOs even when an inclusion
975  * switch is used.
976  *
977  * -s means "schema only" and LOs are data, not schema, so we never
978  * include LOs when -s is used.
979  */
980  if (dopt.include_everything && !dopt.schemaOnly && !dopt.dontOutputLOs)
981  dopt.outputLOs = true;
982 
983  /*
984  * Collect role names so we can map object owner OIDs to names.
985  */
986  collectRoleNames(fout);
987 
988  /*
989  * Now scan the database and create DumpableObject structs for all the
990  * objects we intend to dump.
991  */
992  tblinfo = getSchemaData(fout, &numTables);
993 
994  if (!dopt.schemaOnly)
995  {
996  getTableData(&dopt, tblinfo, numTables, 0);
998  if (dopt.dataOnly)
1000  }
1001 
1002  if (dopt.schemaOnly && dopt.sequence_data)
1003  getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
1004 
1005  /*
1006  * In binary-upgrade mode, we do not have to worry about the actual LO
1007  * data or the associated metadata that resides in the pg_largeobject and
1008  * pg_largeobject_metadata tables, respectively.
1009  *
1010  * However, we do need to collect LO information as there may be comments
1011  * or other information on LOs that we do need to dump out.
1012  */
1013  if (dopt.outputLOs || dopt.binary_upgrade)
1014  getLOs(fout);
1015 
1016  /*
1017  * Collect dependency data to assist in ordering the objects.
1018  */
1019  getDependencies(fout);
1020 
1021  /*
1022  * Collect ACLs, comments, and security labels, if wanted.
1023  */
1024  if (!dopt.aclsSkip)
1025  getAdditionalACLs(fout);
1026  if (!dopt.no_comments)
1027  collectComments(fout);
1028  if (!dopt.no_security_labels)
1029  collectSecLabels(fout);
1030 
1031  /* For binary upgrade mode, collect required pg_class information. */
1032  if (dopt.binary_upgrade)
1034 
1035  /* Collect sequence information. */
1036  collectSequences(fout);
1037 
1038  /* Lastly, create dummy objects to represent the section boundaries */
1039  boundaryObjs = createBoundaryObjects();
1040 
1041  /* Get pointers to all the known DumpableObjects */
1042  getDumpableObjects(&dobjs, &numObjs);
1043 
1044  /*
1045  * Add dummy dependencies to enforce the dump section ordering.
1046  */
1047  addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
1048 
1049  /*
1050  * Sort the objects into a safe dump order (no forward references).
1051  *
1052  * We rely on dependency information to help us determine a safe order, so
1053  * the initial sort is mostly for cosmetic purposes: we sort by name to
1054  * ensure that logically identical schemas will dump identically.
1055  */
1056  sortDumpableObjectsByTypeName(dobjs, numObjs);
1057 
1058  sortDumpableObjects(dobjs, numObjs,
1059  boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
1060 
1061  /*
1062  * Create archive TOC entries for all the objects to be dumped, in a safe
1063  * order.
1064  */
1065 
1066  /*
1067  * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
1068  */
1069  dumpEncoding(fout);
1070  dumpStdStrings(fout);
1071  dumpSearchPath(fout);
1072 
1073  /* The database items are always next, unless we don't want them at all */
1074  if (dopt.outputCreateDB)
1075  dumpDatabase(fout);
1076 
1077  /* Now the rearrangeable objects. */
1078  for (i = 0; i < numObjs; i++)
1079  dumpDumpableObject(fout, dobjs[i]);
1080 
1081  /*
1082  * Set up options info to ensure we dump what we want.
1083  */
1084  ropt = NewRestoreOptions();
1085  ropt->filename = filename;
1086 
1087  /* if you change this list, see dumpOptionsFromRestoreOptions */
1088  ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
1089  ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
1090  ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
1091  ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
1093  ropt->dropSchema = dopt.outputClean;
1094  ropt->dataOnly = dopt.dataOnly;
1095  ropt->schemaOnly = dopt.schemaOnly;
1096  ropt->if_exists = dopt.if_exists;
1097  ropt->column_inserts = dopt.column_inserts;
1098  ropt->dumpSections = dopt.dumpSections;
1099  ropt->aclsSkip = dopt.aclsSkip;
1100  ropt->superuser = dopt.outputSuperuser;
1101  ropt->createDB = dopt.outputCreateDB;
1102  ropt->noOwner = dopt.outputNoOwner;
1103  ropt->noTableAm = dopt.outputNoTableAm;
1104  ropt->noTablespace = dopt.outputNoTablespaces;
1105  ropt->disable_triggers = dopt.disable_triggers;
1106  ropt->use_setsessauth = dopt.use_setsessauth;
1108  ropt->dump_inserts = dopt.dump_inserts;
1109  ropt->no_comments = dopt.no_comments;
1110  ropt->no_publications = dopt.no_publications;
1112  ropt->no_subscriptions = dopt.no_subscriptions;
1113  ropt->lockWaitTimeout = dopt.lockWaitTimeout;
1116  ropt->sequence_data = dopt.sequence_data;
1117  ropt->binary_upgrade = dopt.binary_upgrade;
1118 
1119  ropt->compression_spec = compression_spec;
1120 
1121  ropt->suppressDumpWarnings = true; /* We've already shown them */
1122 
1123  SetArchiveOptions(fout, &dopt, ropt);
1124 
1125  /* Mark which entries should be output */
1127 
1128  /*
1129  * The archive's TOC entries are now marked as to which ones will actually
1130  * be output, so we can set up their dependency lists properly. This isn't
1131  * necessary for plain-text output, though.
1132  */
1133  if (!plainText)
1135 
1136  /*
1137  * And finally we can do the actual output.
1138  *
1139  * Note: for non-plain-text output formats, the output file is written
1140  * inside CloseArchive(). This is, um, bizarre; but not worth changing
1141  * right now.
1142  */
1143  if (plainText)
1144  RestoreArchive(fout);
1145 
1146  CloseArchive(fout);
1147 
1148  exit_nicely(0);
1149 }
TableInfo * getSchemaData(Archive *fout, int *numTablesPtr)
Definition: common.c:97
void on_exit_close_archive(Archive *AHX)
Definition: parallel.c:330
void init_parallel_dump_utils(void)
Definition: parallel.c:238
#define PG_MAX_JOBS
Definition: parallel.h:48
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1219
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:429
char * supports_compression(const pg_compress_specification compression_spec)
Definition: compress_io.c:87
bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm)
Definition: compression.c:49
void parse_compress_specification(pg_compress_algorithm algorithm, char *specification, pg_compress_specification *result)
Definition: compression.c:107
char * validate_compress_specification(pg_compress_specification *spec)
Definition: compression.c:344
#define PG_COMPRESSION_OPTION_WORKERS
Definition: compression.h:29
void parse_compress_options(const char *option, char **algorithm, char **detail)
DataDirSyncMethod
Definition: file_utils.h:28
@ DATA_DIR_SYNC_METHOD_FSYNC
Definition: file_utils.h:29
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:60
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
static DataDirSyncMethod sync_method
Definition: initdb.c:170
void pg_logging_increase_verbosity(void)
Definition: logging.c:185
void pg_logging_init(const char *argv0)
Definition: logging.c:83
void pg_logging_set_level(enum pg_log_level new_level)
Definition: logging.c:176
@ PG_LOG_WARNING
Definition: logging.h:38
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
bool parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
Definition: option_utils.c:90
void ConnectDatabase(Archive *AHX, const ConnParams *cparams, bool isReconnect)
Definition: pg_backup_db.c:108
void ProcessArchiveRestoreOptions(Archive *AHX)
RestoreOptions * NewRestoreOptions(void)
Archive * CreateArchive(const char *FileSpec, const ArchiveFormat fmt, const pg_compress_specification compression_spec, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker, DataDirSyncMethod sync_method)
enum _archiveFormat ArchiveFormat
void CloseArchive(Archive *AHX)
void SetArchiveOptions(Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
void RestoreArchive(Archive *AHX)
@ archUnknown
Definition: pg_backup.h:41
@ archCustom
Definition: pg_backup.h:42
@ archDirectory
Definition: pg_backup.h:45
@ archNull
Definition: pg_backup.h:44
void InitDumpOptions(DumpOptions *opts)
void set_dump_section(const char *arg, int *dumpSections)
static char format
static void expand_schema_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
Definition: pg_dump.c:1489
static void dumpEncoding(Archive *AH)
Definition: pg_dump.c:3601
static SimpleStringList schema_include_patterns
Definition: pg_dump.c:160
static void collectBinaryUpgradeClassOids(Archive *fout)
Definition: pg_dump.c:5531
static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
Definition: pg_dump.c:18870
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3650
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:18846
static void dumpDatabase(Archive *fout)
Definition: pg_dump.c:3085
static SimpleStringList table_include_patterns
Definition: pg_dump.c:165
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:163
static bool have_extra_float_digits
Definition: pg_dump.c:187
static SimpleOidList extension_include_oids
Definition: pg_dump.c:179
static int extra_float_digits
Definition: pg_dump.c:188
static SimpleStringList extension_include_patterns
Definition: pg_dump.c:178
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:182
static SimpleStringList table_exclude_patterns
Definition: pg_dump.c:168
static pg_compress_algorithm compression_algorithm
Definition: pg_dump.c:152
static void dumpStdStrings(Archive *AH)
Definition: pg_dump.c:3626
static void help(const char *progname)
Definition: pg_dump.c:1153
static void BuildArchiveDependencies(Archive *fout)
Definition: pg_dump.c:18986
static void collectRoleNames(Archive *fout)
Definition: pg_dump.c:10021
static bool dosync
Definition: pg_dump.c:145
static void getDependencies(Archive *fout)
Definition: pg_dump.c:18693
static void buildMatViewRefreshDependencies(Archive *fout)
Definition: pg_dump.c:2929
#define DUMP_DEFAULT_ROWS_PER_INSERT
Definition: pg_dump.c:214
static SimpleStringList foreign_servers_include_patterns
Definition: pg_dump.c:175
static void setupDumpWorker(Archive *AH)
Definition: pg_dump.c:1422
static SimpleStringList table_include_patterns_and_children
Definition: pg_dump.c:166
static void getAdditionalACLs(Archive *fout)
Definition: pg_dump.c:10056
static void getTableDataFKConstraints(void)
Definition: pg_dump.c:3044
static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
Definition: pg_dump.c:2836
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:170
static void collectComments(Archive *fout)
Definition: pg_dump.c:10476
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:10561
static void getLOs(Archive *fout)
Definition: pg_dump.c:3712
static void setup_connection(Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role)
Definition: pg_dump.c:1253
static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names, bool with_child_tables)
Definition: pg_dump.c:1653
static void expand_foreign_server_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
Definition: pg_dump.c:1601
static SimpleStringList extension_exclude_patterns
Definition: pg_dump.c:181
static SimpleOidList table_include_oids
Definition: pg_dump.c:167
static SimpleStringList tabledata_exclude_patterns
Definition: pg_dump.c:171
static void collectSecLabels(Archive *fout)
Definition: pg_dump.c:15618
static void collectSequences(Archive *fout)
Definition: pg_dump.c:17649
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode)
Definition: pg_dump.c:1451
static void read_dump_filters(const char *filename, DumpOptions *dopt)
Definition: pg_dump.c:19206
static SimpleStringList tabledata_exclude_patterns_and_children
Definition: pg_dump.c:172
static SimpleOidList tabledata_exclude_oids
Definition: pg_dump.c:173
static SimpleStringList table_exclude_patterns_and_children
Definition: pg_dump.c:169
static SimpleOidList foreign_servers_include_oids
Definition: pg_dump.c:176
static void expand_extension_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
Definition: pg_dump.c:1548
static SimpleOidList schema_include_oids
Definition: pg_dump.c:161
static SimpleStringList schema_exclude_patterns
Definition: pg_dump.c:162
void sortDumpableObjects(DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId)
Definition: pg_dump_sort.c:332
void sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
Definition: pg_dump_sort.c:188
static char * filename
Definition: pg_dumpall.c:119
PGDLLIMPORT int optind
Definition: getopt.c:51
PGDLLIMPORT char * optarg
Definition: getopt.c:53
const char * get_progname(const char *argv0)
Definition: path.c:575
bool quote_all_identifiers
Definition: ruleutils.c:337
void simple_string_list_append(SimpleStringList *list, const char *val)
Definition: simple_list.c:63
int minRemoteVersion
Definition: pg_backup.h:223
bool isStandby
Definition: pg_backup.h:221
int maxRemoteVersion
Definition: pg_backup.h:224
int numWorkers
Definition: pg_backup.h:226
int verbose
Definition: pg_backup.h:218
SimpleOidListCell * head
Definition: simple_list.h:28
char * pgport
Definition: pg_backup.h:86
char * pghost
Definition: pg_backup.h:87
trivalue promptPassword
Definition: pg_backup.h:89
char * username
Definition: pg_backup.h:88
char * dbname
Definition: pg_backup.h:85
bool dontOutputLOs
Definition: pg_backup.h:201
int use_setsessauth
Definition: pg_backup.h:191
int outputCreateDB
Definition: pg_backup.h:199
bool include_everything
Definition: pg_backup.h:196
bool outputLOs
Definition: pg_backup.h:200
int serializable_deferrable
Definition: pg_backup.h:187
int outputNoTableAm
Definition: pg_backup.h:189
int enable_row_security
Definition: pg_backup.h:192
char * outputSuperuser
Definition: pg_backup.h:203
int dumpSections
Definition: pg_backup.h:172
int no_unlogged_table_data
Definition: pg_backup.h:186
ConnParams cparams
Definition: pg_backup.h:165
int outputClean
Definition: pg_backup.h:198
int disable_triggers
Definition: pg_backup.h:188
int outputNoOwner
Definition: pg_backup.h:202
int include_everything
Definition: pg_backup.h:125
int suppressDumpWarnings
Definition: pg_backup.h:151
ConnParams cparams
Definition: pg_backup.h:145
pg_compress_specification compression_spec
Definition: pg_backup.h:149
int no_subscriptions
Definition: pg_backup.h:115
int disable_dollar_quoting
Definition: pg_backup.h:108
const char * filename
Definition: pg_backup.h:118
int no_security_labels
Definition: pg_backup.h:114
char * superuser
Definition: pg_backup.h:105
const char * lockWaitTimeout
Definition: pg_backup.h:124
int enable_row_security
Definition: pg_backup.h:158
int disable_triggers
Definition: pg_backup.h:101
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_NO
Definition: vacuumlo.c:37
ArchiveMode
Definition: xlog.h:64

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, addBoundaryDependencies(), archCustom, archDirectory, archNull, archUnknown, _restoreOptions::binary_upgrade, _dumpOptions::binary_upgrade, BuildArchiveDependencies(), buildMatViewRefreshDependencies(), CloseArchive(), collectBinaryUpgradeClassOids(), collectComments(), collectRoleNames(), collectSecLabels(), collectSequences(), _restoreOptions::column_inserts, _dumpOptions::column_inserts, compression_algorithm, _restoreOptions::compression_spec, ConnectDatabase(), _restoreOptions::cparams, _dumpOptions::cparams, CreateArchive(), createBoundaryObjects(), _restoreOptions::createDB, DATA_DIR_SYNC_METHOD_FSYNC, _restoreOptions::dataOnly, _dumpOptions::dataOnly, _connParams::dbname, _restoreOptions::disable_dollar_quoting, _dumpOptions::disable_dollar_quoting, _restoreOptions::disable_triggers, _dumpOptions::disable_triggers, _dumpOptions::do_nothing, _dumpOptions::dontOutputLOs, dosync, _restoreOptions::dropSchema, DUMP_DEFAULT_ROWS_PER_INSERT, _restoreOptions::dump_inserts, _dumpOptions::dump_inserts, dumpDatabase(), dumpDumpableObject(), dumpEncoding(), dumpSearchPath(), _restoreOptions::dumpSections, _dumpOptions::dumpSections, dumpStdStrings(), _restoreOptions::enable_row_security, _dumpOptions::enable_row_security, exit_nicely, expand_extension_name_patterns(), expand_foreign_server_name_patterns(), expand_schema_name_patterns(), expand_table_name_patterns(), extension_exclude_oids, extension_exclude_patterns, extension_include_oids, extension_include_patterns, extra_float_digits, _restoreOptions::filename, filename, FirstNormalObjectId, foreign_servers_include_oids, foreign_servers_include_patterns, format, g_last_builtin_oid, get_progname(), getAdditionalACLs(), getDependencies(), getDumpableObjects(), getLOs(), getopt_long(), getSchemaData(), getTableData(), getTableDataFKConstraints(), have_extra_float_digits, SimpleOidList::head, SimpleStringList::head, help(), i, _restoreOptions::if_exists, _dumpOptions::if_exists, _restoreOptions::include_everything, _dumpOptions::include_everything, init_parallel_dump_utils(), InitDumpOptions(), Archive::isStandby, _dumpOptions::load_via_partition_root, _restoreOptions::lockWaitTimeout, _dumpOptions::lockWaitTimeout, Archive::maxRemoteVersion, Archive::minRemoteVersion, NewRestoreOptions(), no_argument, _restoreOptions::no_comments, _dumpOptions::no_comments, _restoreOptions::no_publications, _dumpOptions::no_publications, _restoreOptions::no_security_labels, _dumpOptions::no_security_labels, _restoreOptions::no_subscriptions, _dumpOptions::no_subscriptions, _dumpOptions::no_toast_compression, _dumpOptions::no_unlogged_table_data, _restoreOptions::noOwner, _restoreOptions::noTableAm, _restoreOptions::noTablespace, Archive::numWorkers, on_exit_close_archive(), optarg, optind, option_parse_int(), pg_compress_specification::options, _dumpOptions::outputClean, _dumpOptions::outputCreateDB, _dumpOptions::outputLOs, _dumpOptions::outputNoOwner, _dumpOptions::outputNoTableAm, _dumpOptions::outputNoTablespaces, _dumpOptions::outputSuperuser, parse_compress_algorithm(), parse_compress_options(), parse_compress_specification(), parse_sync_method(), parseArchiveFormat(), PG_COMPRESSION_OPTION_WORKERS, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_info, pg_log_warning, PG_LOG_WARNING, pg_logging_increase_verbosity(), pg_logging_init(), pg_logging_set_level(), PG_MAX_JOBS, pg_strdup(), PG_TEXTDOMAIN, _connParams::pghost, _connParams::pgport, ProcessArchiveRestoreOptions(), progname, _connParams::promptPassword, quote_all_identifiers, read_dump_filters(), required_argument, RestoreArchive(), schema_exclude_oids, schema_exclude_patterns, schema_include_oids, schema_include_patterns, _restoreOptions::schemaOnly, _dumpOptions::schemaOnly, _restoreOptions::sequence_data, _dumpOptions::sequence_data, _dumpOptions::serializable_deferrable, set_dump_section(), set_pglocale_pgservice(), SetArchiveOptions(), setup_connection(), setupDumpWorker(), simple_string_list_append(), sortDumpableObjects(), sortDumpableObjectsByTypeName(), strict_names, _restoreOptions::superuser, supports_compression(), _restoreOptions::suppressDumpWarnings, sync_method, table_exclude_oids, table_exclude_patterns, table_exclude_patterns_and_children, table_include_oids, table_include_patterns, table_include_patterns_and_children, tabledata_exclude_oids, tabledata_exclude_patterns, tabledata_exclude_patterns_and_children, TRI_NO, TRI_YES, _restoreOptions::use_setsessauth, _dumpOptions::use_setsessauth, _connParams::username, validate_compress_specification(), and Archive::verbose.

◆ makeTableDataInfo()

static void makeTableDataInfo ( DumpOptions dopt,
TableInfo tbinfo 
)
static

Definition at line 2855 of file pg_dump.c.

2856 {
2857  TableDataInfo *tdinfo;
2858 
2859  /*
2860  * Nothing to do if we already decided to dump the table. This will
2861  * happen for "config" tables.
2862  */
2863  if (tbinfo->dataObj != NULL)
2864  return;
2865 
2866  /* Skip VIEWs (no data to dump) */
2867  if (tbinfo->relkind == RELKIND_VIEW)
2868  return;
2869  /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
2870  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
2873  tbinfo->foreign_server)))
2874  return;
2875  /* Skip partitioned tables (data in partitions) */
2876  if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
2877  return;
2878 
2879  /* Don't dump data in unlogged tables, if so requested */
2880  if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
2881  dopt->no_unlogged_table_data)
2882  return;
2883 
2884  /* Check that the data is not explicitly excluded */
2886  tbinfo->dobj.catId.oid))
2887  return;
2888 
2889  /* OK, let's dump it */
2890  tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
2891 
2892  if (tbinfo->relkind == RELKIND_MATVIEW)
2893  tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
2894  else if (tbinfo->relkind == RELKIND_SEQUENCE)
2895  tdinfo->dobj.objType = DO_SEQUENCE_SET;
2896  else
2897  tdinfo->dobj.objType = DO_TABLE_DATA;
2898 
2899  /*
2900  * Note: use tableoid 0 so that this object won't be mistaken for
2901  * something that pg_depend entries apply to.
2902  */
2903  tdinfo->dobj.catId.tableoid = 0;
2904  tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
2905  AssignDumpId(&tdinfo->dobj);
2906  tdinfo->dobj.name = tbinfo->dobj.name;
2907  tdinfo->dobj.namespace = tbinfo->dobj.namespace;
2908  tdinfo->tdtable = tbinfo;
2909  tdinfo->filtercond = NULL; /* might get set later */
2910  addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
2911 
2912  /* A TableDataInfo contains data, of course */
2913  tdinfo->dobj.components |= DUMP_COMPONENT_DATA;
2914 
2915  tbinfo->dataObj = tdinfo;
2916 
2917  /* Make sure that we'll collect per-column info for this table. */
2918  tbinfo->interesting = true;
2919 }
bool simple_oid_list_member(SimpleOidList *list, Oid val)
Definition: simple_list.c:45

References addObjectDependency(), AssignDumpId(), _dumpableObject::catId, _dumpableObject::components, _tableInfo::dataObj, DO_REFRESH_MATVIEW, DO_SEQUENCE_SET, DO_TABLE_DATA, _tableInfo::dobj, _tableDataInfo::dobj, DUMP_COMPONENT_DATA, _dumpableObject::dumpId, _tableDataInfo::filtercond, _tableInfo::foreign_server, foreign_servers_include_oids, SimpleOidList::head, _tableInfo::interesting, _dumpableObject::name, _dumpOptions::no_unlogged_table_data, _dumpableObject::objType, CatalogId::oid, pg_malloc(), _tableInfo::relkind, _tableInfo::relpersistence, simple_oid_list_member(), tabledata_exclude_oids, CatalogId::tableoid, and _tableDataInfo::tdtable.

Referenced by getTableData(), and processExtensionTables().

◆ nonemptyReloptions()

static bool nonemptyReloptions ( const char *  reloptions)
static

Definition at line 19175 of file pg_dump.c.

19176 {
19177  /* Don't want to print it if it's just "{}" */
19178  return (reloptions != NULL && strlen(reloptions) > 2);
19179 }

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

◆ parse_sequence_type()

static SeqType parse_sequence_type ( const char *  name)
inlinestatic

Definition at line 17618 of file pg_dump.c.

17619 {
17620  for (int i = 0; i < lengthof(SeqTypeNames); i++)
17621  {
17622  if (strcmp(SeqTypeNames[i], name) == 0)
17623  return (SeqType) i;
17624  }
17625 
17626  pg_fatal("unrecognized sequence type: %s", name);
17627  return (SeqType) 0; /* keep compiler quiet */
17628 }
#define lengthof(array)
Definition: c.h:793

References i, lengthof, name, pg_fatal, and SeqTypeNames.

Referenced by collectSequences(), and dumpSequence().

◆ parseArchiveFormat()

static ArchiveFormat parseArchiveFormat ( const char *  format,
ArchiveMode mode 
)
static

Definition at line 1451 of file pg_dump.c.

1452 {
1453  ArchiveFormat archiveFormat;
1454 
1455  *mode = archModeWrite;
1456 
1457  if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
1458  {
1459  /* This is used by pg_dumpall, and is not documented */
1460  archiveFormat = archNull;
1461  *mode = archModeAppend;
1462  }
1463  else if (pg_strcasecmp(format, "c") == 0)
1464  archiveFormat = archCustom;
1465  else if (pg_strcasecmp(format, "custom") == 0)
1466  archiveFormat = archCustom;
1467  else if (pg_strcasecmp(format, "d") == 0)
1468  archiveFormat = archDirectory;
1469  else if (pg_strcasecmp(format, "directory") == 0)
1470  archiveFormat = archDirectory;
1471  else if (pg_strcasecmp(format, "p") == 0)
1472  archiveFormat = archNull;
1473  else if (pg_strcasecmp(format, "plain") == 0)
1474  archiveFormat = archNull;
1475  else if (pg_strcasecmp(format, "t") == 0)
1476  archiveFormat = archTar;
1477  else if (pg_strcasecmp(format, "tar") == 0)
1478  archiveFormat = archTar;
1479  else
1480  pg_fatal("invalid output format \"%s\" specified", format);
1481  return archiveFormat;
1482 }
@ archModeWrite
Definition: pg_backup.h:51
@ archModeAppend
Definition: pg_backup.h:50
@ archTar
Definition: pg_backup.h:43
static PgChecksumMode mode
Definition: pg_checksums.c:55

References archCustom, archDirectory, archModeAppend, archModeWrite, archNull, archTar, format, mode, pg_fatal, and pg_strcasecmp().

Referenced by main().

◆ processExtensionTables()

void processExtensionTables ( Archive fout,
ExtensionInfo  extinfo[],
int  numExtensions 
)

Definition at line 18512 of file pg_dump.c.

18514 {
18515  DumpOptions *dopt = fout->dopt;
18516  PQExpBuffer query;
18517  PGresult *res;
18518  int ntups,
18519  i;
18520  int i_conrelid,
18521  i_confrelid;
18522 
18523  /* Nothing to do if no extensions */
18524  if (numExtensions == 0)
18525  return;
18526 
18527  /*
18528  * Identify extension configuration tables and create TableDataInfo
18529  * objects for them, ensuring their data will be dumped even though the
18530  * tables themselves won't be.
18531  *
18532  * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
18533  * user data in a configuration table is treated like schema data. This
18534  * seems appropriate since system data in a config table would get
18535  * reloaded by CREATE EXTENSION. If the extension is not listed in the
18536  * list of extensions to be included, none of its data is dumped.
18537  */
18538  for (i = 0; i < numExtensions; i++)
18539  {
18540  ExtensionInfo *curext = &(extinfo[i]);
18541  char *extconfig = curext->extconfig;
18542  char *extcondition = curext->extcondition;
18543  char **extconfigarray = NULL;
18544  char **extconditionarray = NULL;
18545  int nconfigitems = 0;
18546  int nconditionitems = 0;
18547 
18548  /*
18549  * Check if this extension is listed as to include in the dump. If
18550  * not, any table data associated with it is discarded.
18551  */
18552  if (extension_include_oids.head != NULL &&
18554  curext->dobj.catId.oid))
18555  continue;
18556 
18557  /*
18558  * Check if this extension is listed as to exclude in the dump. If
18559  * yes, any table data associated with it is discarded.
18560  */
18561  if (extension_exclude_oids.head != NULL &&
18563  curext->dobj.catId.oid))
18564  continue;
18565 
18566  if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
18567  {
18568  int j;
18569 
18570  if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
18571  pg_fatal("could not parse %s array", "extconfig");
18572  if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
18573  pg_fatal("could not parse %s array", "extcondition");
18574  if (nconfigitems != nconditionitems)
18575  pg_fatal("mismatched number of configurations and conditions for extension");
18576 
18577  for (j = 0; j < nconfigitems; j++)
18578  {
18579  TableInfo *configtbl;
18580  Oid configtbloid = atooid(extconfigarray[j]);
18581  bool dumpobj =
18583 
18584  configtbl = findTableByOid(configtbloid);
18585  if (configtbl == NULL)
18586  continue;
18587 
18588  /*
18589  * Tables of not-to-be-dumped extensions shouldn't be dumped
18590  * unless the table or its schema is explicitly included
18591  */
18592  if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
18593  {
18594  /* check table explicitly requested */
18595  if (table_include_oids.head != NULL &&
18597  configtbloid))
18598  dumpobj = true;
18599 
18600  /* check table's schema explicitly requested */
18601  if (configtbl->dobj.namespace->dobj.dump &
18603  dumpobj = true;
18604  }
18605 
18606  /* check table excluded by an exclusion switch */
18607  if (table_exclude_oids.head != NULL &&
18609  configtbloid))
18610  dumpobj = false;
18611 
18612  /* check schema excluded by an exclusion switch */
18614  configtbl->dobj.namespace->dobj.catId.oid))
18615  dumpobj = false;
18616 
18617  if (dumpobj)
18618  {
18619  makeTableDataInfo(dopt, configtbl);
18620  if (configtbl->dataObj != NULL)
18621  {
18622  if (strlen(extconditionarray[j]) > 0)
18623  configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
18624  }
18625  }
18626  }
18627  }
18628  if (extconfigarray)
18629  free(extconfigarray);
18630  if (extconditionarray)
18631  free(extconditionarray);
18632  }
18633 
18634  /*
18635  * Now that all the TableDataInfo objects have been created for all the
18636  * extensions, check their FK dependencies and register them to try and
18637  * dump the data out in an order that they can be restored in.
18638  *
18639  * Note that this is not a problem for user tables as their FKs are
18640  * recreated after the data has been loaded.
18641  */
18642 
18643  query = createPQExpBuffer();
18644 
18645  printfPQExpBuffer(query,
18646  "SELECT conrelid, confrelid "
18647  "FROM pg_constraint "
18648  "JOIN pg_depend ON (objid = confrelid) "
18649  "WHERE contype = 'f' "
18650  "AND refclassid = 'pg_extension'::regclass "
18651  "AND classid = 'pg_class'::regclass;");
18652 
18653  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18654  ntups = PQntuples(res);
18655 
18656  i_conrelid = PQfnumber(res, "conrelid");
18657  i_confrelid = PQfnumber(res, "confrelid");
18658 
18659  /* Now get the dependencies and register them */
18660  for (i = 0; i < ntups; i++)
18661  {
18662  Oid conrelid,
18663  confrelid;
18664  TableInfo *reftable,
18665  *contable;
18666 
18667  conrelid = atooid(PQgetvalue(res, i, i_conrelid));
18668  confrelid = atooid(PQgetvalue(res, i, i_confrelid));
18669  contable = findTableByOid(conrelid);
18670  reftable = findTableByOid(confrelid);
18671 
18672  if (reftable == NULL ||
18673  reftable->dataObj == NULL ||
18674  contable == NULL ||
18675  contable->dataObj == NULL)
18676  continue;
18677 
18678  /*
18679  * Make referencing TABLE_DATA object depend on the referenced table's
18680  * TABLE_DATA object.
18681  */
18682  addObjectDependency(&contable->dataObj->dobj,
18683  reftable->dataObj->dobj.dumpId);
18684  }
18685  PQclear(res);
18686  destroyPQExpBuffer(query);
18687 }

References addObjectDependency(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _tableInfo::dataObj, destroyPQExpBuffer(), _extensionInfo::dobj, _tableInfo::dobj, _tableDataInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DATA, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, ExecuteSqlQuery(), _extensionInfo::extcondition, _extensionInfo::extconfig, extension_exclude_oids, extension_include_oids, _tableDataInfo::filtercond, findTableByOid(), free, SimpleOidList::head, i, j, makeTableDataInfo(), CatalogId::oid, parsePGArray(), pg_fatal, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), res, schema_exclude_oids, simple_oid_list_member(), table_exclude_oids, and table_include_oids.

Referenced by getSchemaData().

◆ prohibit_crossdb_refs()

static void prohibit_crossdb_refs ( PGconn conn,
const char *  dbname,
const char *  pattern 
)
static

Definition at line 1749 of file pg_dump.c.

1750 {
1751  const char *db;
1752 
1753  db = PQdb(conn);
1754  if (db == NULL)
1755  pg_fatal("You are currently not connected to a database.");
1756 
1757  if (strcmp(db, dbname) != 0)
1758  pg_fatal("cross-database references are not implemented: %s",
1759  pattern);
1760 }
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:7036

References conn, dbname, pg_fatal, and PQdb().

Referenced by expand_schema_name_patterns(), and expand_table_name_patterns().

◆ read_dump_filters()

static void read_dump_filters ( const char *  filename,
DumpOptions dopt 
)
static

Definition at line 19206 of file pg_dump.c.

19207 {
19208  FilterStateData fstate;
19209  char *objname;
19210  FilterCommandType comtype;
19211  FilterObjectType objtype;
19212 
19213  filter_init(&fstate, filename, exit_nicely);
19214 
19215  while (filter_read_item(&fstate, &objname, &comtype, &objtype))
19216  {
19217  if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
19218  {
19219  switch (objtype)
19220  {
19222  break;
19229  pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
19230  "include",
19231  filter_object_type_name(objtype));
19232  exit_nicely(1);
19233  break; /* unreachable */
19234 
19237  break;
19240  break;
19243  dopt->include_everything = false;
19244  break;
19247  dopt->include_everything = false;
19248  break;
19251  objname);
19252  dopt->include_everything = false;
19253  break;
19254  }
19255  }
19256  else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
19257  {
19258  switch (objtype)
19259  {
19261  break;
19267  pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
19268  "exclude",
19269  filter_object_type_name(objtype));
19270  exit_nicely(1);
19271  break;
19272 
19275  break;
19278  objname);
19279  break;
19282  objname);
19283  break;
19286  break;
19289  break;
19292  objname);
19293  break;
19294  }
19295  }
19296  else
19297  {
19298  Assert(comtype == FILTER_COMMAND_TYPE_NONE);
19299  Assert(objtype == FILTER_OBJECT_TYPE_NONE);
19300  }
19301 
19302  if (objname)
19303  free(objname);
19304  }
19305 
19306  filter_free(&fstate);
19307 }
void filter_init(FilterStateData *fstate, const char *filename, exit_function f_exit)
Definition: filter.c:36
void filter_free(FilterStateData *fstate)
Definition: filter.c:60
bool filter_read_item(FilterStateData *fstate, char **objname, FilterCommandType *comtype, FilterObjectType *objtype)
Definition: filter.c:389
void pg_log_filter_error(FilterStateData *fstate, const char *fmt,...)
Definition: filter.c:154
const char * filter_object_type_name(FilterObjectType fot)
Definition: filter.c:82
FilterObjectType
Definition: filter.h:48
@ FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN
Definition: filter.h:51
@ FILTER_OBJECT_TYPE_SCHEMA
Definition: filter.h:57
@ FILTER_OBJECT_TYPE_INDEX
Definition: filter.h:56
@ FILTER_OBJECT_TYPE_TRIGGER
Definition: filter.h:60
@ FILTER_OBJECT_TYPE_FOREIGN_DATA
Definition: filter.h:54
@ FILTER_OBJECT_TYPE_DATABASE
Definition: filter.h:52
@ FILTER_OBJECT_TYPE_FUNCTION
Definition: filter.h:55
@ FILTER_OBJECT_TYPE_TABLE_DATA
Definition: filter.h:50
@ FILTER_OBJECT_TYPE_NONE
Definition: filter.h:49
@ FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN
Definition: filter.h:59
@ FILTER_OBJECT_TYPE_EXTENSION
Definition: filter.h:53
@ FILTER_OBJECT_TYPE_TABLE
Definition: filter.h:58
FilterCommandType
Definition: filter.h:38
@ FILTER_COMMAND_TYPE_NONE
Definition: filter.h:39
@ FILTER_COMMAND_TYPE_EXCLUDE
Definition: filter.h:41
@ FILTER_COMMAND_TYPE_INCLUDE
Definition: filter.h:40

References _, Assert, exit_nicely, extension_exclude_patterns, extension_include_patterns, filename, FILTER_COMMAND_TYPE_EXCLUDE, FILTER_COMMAND_TYPE_INCLUDE, FILTER_COMMAND_TYPE_NONE, filter_free(), filter_init(), FILTER_OBJECT_TYPE_DATABASE, FILTER_OBJECT_TYPE_EXTENSION, FILTER_OBJECT_TYPE_FOREIGN_DATA, FILTER_OBJECT_TYPE_FUNCTION, FILTER_OBJECT_TYPE_INDEX, filter_object_type_name(), FILTER_OBJECT_TYPE_NONE, FILTER_OBJECT_TYPE_SCHEMA, FILTER_OBJECT_TYPE_TABLE, FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN, FILTER_OBJECT_TYPE_TABLE_DATA, FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN, FILTER_OBJECT_TYPE_TRIGGER, filter_read_item(), foreign_servers_include_patterns, free, _dumpOptions::include_everything, pg_log_filter_error(), schema_exclude_patterns, schema_include_patterns, simple_string_list_append(), table_exclude_patterns, table_exclude_patterns_and_children, table_include_patterns, table_include_patterns_and_children, tabledata_exclude_patterns, and tabledata_exclude_patterns_and_children.

Referenced by main().

◆ refreshMatViewData()

static void refreshMatViewData ( Archive fout,
const TableDataInfo tdinfo 
)
static

Definition at line 2801 of file pg_dump.c.

2802 {
2803  TableInfo *tbinfo = tdinfo->tdtable;
2804  PQExpBuffer q;
2805 
2806  /* If the materialized view is not flagged as populated, skip this. */
2807  if (!tbinfo->relispopulated)
2808  return;
2809 
2810  q = createPQExpBuffer();
2811 
2812  appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
2813  fmtQualifiedDumpable(tbinfo));
2814 
2815  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2816  ArchiveEntry(fout,
2817  tdinfo->dobj.catId, /* catalog ID */
2818  tdinfo->dobj.dumpId, /* dump ID */
2819  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2820  .namespace = tbinfo->dobj.namespace->dobj.name,
2821  .owner = tbinfo->rolname,
2822  .description = "MATERIALIZED VIEW DATA",
2823  .section = SECTION_POST_DATA,
2824  .createStmt = q->data,
2825  .deps = tdinfo->dobj.dependencies,
2826  .nDeps = tdinfo->dobj.nDeps));
2827 
2828  destroyPQExpBuffer(q);
2829 }

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpableObject::dependencies, destroyPQExpBuffer(), _tableInfo::dobj, _tableDataInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_DATA, _dumpableObject::dumpId, fmtQualifiedDumpable, _dumpableObject::name, _dumpableObject::nDeps, _tableInfo::relispopulated, _tableInfo::rolname, SECTION_POST_DATA, and _tableDataInfo::tdtable.

Referenced by dumpDumpableObject().

◆ selectDumpableAccessMethod()

static void selectDumpableAccessMethod ( AccessMethodInfo method,
Archive fout 
)
static

Definition at line 2074 of file pg_dump.c.

2075 {
2076  if (checkExtensionMembership(&method->dobj, fout))
2077  return; /* extension membership overrides all else */
2078 
2079  /*
2080  * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
2081  * they do not support ACLs currently.
2082  */
2083  if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2084  method->dobj.dump = DUMP_COMPONENT_NONE;
2085  else
2086  method->dobj.dump = fout->dopt->include_everything ?
2088 }
static bool checkExtensionMembership(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:1774
#define DUMP_COMPONENT_ALL
Definition: pg_dump.h:104

References _dumpableObject::catId, checkExtensionMembership(), _accessMethodInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, g_last_builtin_oid, _dumpOptions::include_everything, and CatalogId::oid.

Referenced by getAccessMethods().

◆ selectDumpableCast()

static void selectDumpableCast ( CastInfo cast,
Archive fout 
)
static

Definition at line 2016 of file pg_dump.c.

2017 {
2018  if (checkExtensionMembership(&cast->dobj, fout))
2019  return; /* extension membership overrides all else */
2020 
2021  /*
2022  * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
2023  * support ACLs currently.
2024  */
2025  if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2026  cast->dobj.dump = DUMP_COMPONENT_NONE;
2027  else
2028  cast->dobj.dump = fout->dopt->include_everything ?
2030 }

References _dumpableObject::catId, checkExtensionMembership(), _castInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, g_last_builtin_oid, _dumpOptions::include_everything, and CatalogId::oid.

Referenced by getCasts().

◆ selectDumpableDefaultACL()

static void selectDumpableDefaultACL ( DefaultACLInfo dinfo,
DumpOptions dopt 
)
static

Definition at line 1994 of file pg_dump.c.

1995 {
1996  /* Default ACLs can't be extension members */
1997 
1998  if (dinfo->dobj.namespace)
1999  /* default ACLs are considered part of the namespace */
2000  dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
2001  else
2002  dinfo->dobj.dump = dopt->include_everything ?
2004 }

References _defaultACLInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, and _dumpOptions::include_everything.

Referenced by getDefaultACLs().

◆ selectDumpableExtension()

static void selectDumpableExtension ( ExtensionInfo extinfo,
DumpOptions dopt 
)
static

Definition at line 2102 of file pg_dump.c.

2103 {
2104  /*
2105  * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
2106  * change permissions on their member objects, if they wish to, and have
2107  * those changes preserved.
2108  */
2109  if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2110  extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
2111  else
2112  {
2113  /* check if there is a list of extensions to dump */
2114  if (extension_include_oids.head != NULL)
2115  extinfo->dobj.dump = extinfo->dobj.dump_contains =
2117  extinfo->dobj.catId.oid) ?
2119  else
2120  extinfo->dobj.dump = extinfo->dobj.dump_contains =
2121  dopt->include_everything ?
2123 
2124  /* check that the extension is not explicitly excluded */
2125  if (extinfo->dobj.dump &&
2127  extinfo->dobj.catId.oid))
2128  extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
2129  }
2130 }

References _dumpableObject::catId, _extensionInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, extension_exclude_oids, extension_include_oids, g_last_builtin_oid, SimpleOidList::head, _dumpOptions::include_everything, CatalogId::oid, and simple_oid_list_member().

Referenced by getExtensions().

◆ selectDumpableNamespace()

static void selectDumpableNamespace ( NamespaceInfo nsinfo,
Archive fout 
)
static

Definition at line 1824 of file pg_dump.c.

1825 {
1826  /*
1827  * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
1828  * and (for --clean) a DROP SCHEMA statement. (In the absence of
1829  * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
1830  */
1831  nsinfo->create = true;
1832 
1833  /*
1834  * If specific tables are being dumped, do not dump any complete
1835  * namespaces. If specific namespaces are being dumped, dump just those
1836  * namespaces. Otherwise, dump all non-system namespaces.
1837  */
1838  if (table_include_oids.head != NULL)
1839  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1840  else if (schema_include_oids.head != NULL)
1841  nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
1843  nsinfo->dobj.catId.oid) ?
1845  else if (fout->remoteVersion >= 90600 &&
1846  strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
1847  {
1848  /*
1849  * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
1850  * they are interesting (and not the original ACLs which were set at
1851  * initdb time, see pg_init_privs).
1852  */
1853  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
1854  }
1855  else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
1856  strcmp(nsinfo->dobj.name, "information_schema") == 0)
1857  {
1858  /* Other system schemas don't get dumped */
1859  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1860  }
1861  else if (strcmp(nsinfo->dobj.name, "public") == 0)
1862  {
1863  /*
1864  * The public schema is a strange beast that sits in a sort of
1865  * no-mans-land between being a system object and a user object.
1866  * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
1867  * a comment and an indication of ownership. If the owner is the
1868  * default, omit that superfluous DUMP_COMPONENT_DEFINITION. Before
1869  * v15, the default owner was BOOTSTRAP_SUPERUSERID.
1870  */
1871  nsinfo->create = false;
1872  nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
1873  if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
1874  nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
1876 
1877  /*
1878  * Also, make like it has a comment even if it doesn't; this is so
1879  * that we'll emit a command to drop the comment, if appropriate.
1880  * (Without this, we'd not call dumpCommentExtended for it.)
1881  */
1883  }
1884  else
1885  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
1886 
1887  /*
1888  * In any case, a namespace can be excluded by an exclusion switch
1889  */
1890  if (nsinfo->dobj.dump_contains &&
1892  nsinfo->dobj.catId.oid))
1893  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1894 
1895  /*
1896  * If the schema belongs to an extension, allow extension membership to
1897  * override the dump decision for the schema itself. However, this does
1898  * not change dump_contains, so this won't change what we do with objects
1899  * within the schema. (If they belong to the extension, they'll get
1900  * suppressed by it, otherwise not.)
1901  */
1902  (void) checkExtensionMembership(&nsinfo->dobj, fout);
1903 }

References _dumpableObject::catId, checkExtensionMembership(), _dumpableObject::components, _namespaceInfo::create, _namespaceInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_ALL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, SimpleOidList::head, _dumpableObject::name, _namespaceInfo::nspowner, CatalogId::oid, Archive::remoteVersion, schema_exclude_oids, schema_include_oids, simple_oid_list_member(), and table_include_oids.

Referenced by getNamespaces().

◆ selectDumpableObject()

static void selectDumpableObject ( DumpableObject dobj,
Archive fout 
)
static

Definition at line 2177 of file pg_dump.c.

2178 {
2179  if (checkExtensionMembership(dobj, fout))
2180  return; /* extension membership overrides all else */
2181 
2182  /*
2183  * Default policy is to dump if parent namespace is dumpable, or for
2184  * non-namespace-associated items, dump if we're dumping "everything".
2185  */
2186  if (dobj->namespace)
2187  dobj->dump = dobj->namespace->dobj.dump_contains;
2188  else
2189  dobj->dump = fout->dopt->include_everything ?
2191 }

References checkExtensionMembership(), Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, and _dumpOptions::include_everything.

Referenced by getAggregates(), getCollations(), getConversions(), getEventTriggers(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getOpclasses(), getOperators(), getOpfamilies(), getPublications(), getSubscriptions(), getSubscriptionTables(), getTransforms(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), and getTSTemplates().

◆ selectDumpableProcLang()

static void selectDumpableProcLang ( ProcLangInfo plang,
Archive fout 
)
static

Definition at line 2041 of file pg_dump.c.

2042 {
2043  if (checkExtensionMembership(&plang->dobj, fout))
2044  return; /* extension membership overrides all else */
2045 
2046  /*
2047  * Only include procedural languages when we are dumping everything.
2048  *
2049  * For from-initdb procedural languages, only include ACLs, as we do for
2050  * the pg_catalog namespace. We need this because procedural languages do
2051  * not live in any namespace.
2052  */
2053  if (!fout->dopt->include_everything)
2054  plang->dobj.dump = DUMP_COMPONENT_NONE;
2055  else
2056  {
2057  if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2058  plang->dobj.dump = fout->remoteVersion < 90600 ?
2060  else
2061  plang->dobj.dump = DUMP_COMPONENT_ALL;
2062  }
2063 }

References _dumpableObject::catId, checkExtensionMembership(), _procLangInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, g_last_builtin_oid, _dumpOptions::include_everything, CatalogId::oid, and Archive::remoteVersion.

Referenced by getProcLangs().

◆ selectDumpablePublicationObject()

static void selectDumpablePublicationObject ( DumpableObject dobj,
Archive fout 
)
static

Definition at line 2141 of file pg_dump.c.

2142 {
2143  if (checkExtensionMembership(dobj, fout))
2144  return; /* extension membership overrides all else */
2145 
2146  dobj->dump = fout->dopt->include_everything ?
2148 }

References checkExtensionMembership(), Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, and _dumpOptions::include_everything.

Referenced by getPublicationNamespaces(), and getPublicationTables().

◆ selectDumpableStatisticsObject()

static void selectDumpableStatisticsObject ( StatsExtInfo sobj,
Archive fout 
)
static

Definition at line 2159 of file pg_dump.c.

2160 {
2161  if (checkExtensionMembership(&sobj->dobj, fout))
2162  return; /* extension membership overrides all else */
2163 
2164  sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
2165  if (sobj->stattable == NULL ||
2167  sobj->dobj.dump = DUMP_COMPONENT_NONE;
2168 }

References checkExtensionMembership(), _tableInfo::dobj, _statsExtInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, and _statsExtInfo::stattable.

Referenced by getExtendedStatistics().

◆ selectDumpableTable()

static void selectDumpableTable ( TableInfo tbinfo,
Archive fout 
)
static

Definition at line 1910 of file pg_dump.c.

1911 {
1912  if (checkExtensionMembership(&tbinfo->dobj, fout))
1913  return; /* extension membership overrides all else */
1914 
1915  /*
1916  * If specific tables are being dumped, dump just those tables; else, dump
1917  * according to the parent namespace's dump flag.
1918  */
1919  if (table_include_oids.head != NULL)
1921  tbinfo->dobj.catId.oid) ?
1923  else
1924  tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
1925 
1926  /*
1927  * In any case, a table can be excluded by an exclusion switch
1928  */
1929  if (tbinfo->dobj.dump &&
1931  tbinfo->dobj.catId.oid))
1932  tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
1933 }

References _dumpableObject::catId, checkExtensionMembership(), _tableInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, SimpleOidList::head, CatalogId::oid, simple_oid_list_member(), table_exclude_oids, and table_include_oids.

Referenced by getTables().

◆ selectDumpableType()

static void selectDumpableType ( TypeInfo tyinfo,
Archive fout 
)
static

Definition at line 1949 of file pg_dump.c.

1950 {
1951  /* skip complex types, except for standalone composite types */
1952  if (OidIsValid(tyinfo->typrelid) &&
1953  tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
1954  {
1955  TableInfo *tytable = findTableByOid(tyinfo->typrelid);
1956 
1957  tyinfo->dobj.objType = DO_DUMMY_TYPE;
1958  if (tytable != NULL)
1959  tyinfo->dobj.dump = tytable->dobj.dump;
1960  else
1961  tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
1962  return;
1963  }
1964 
1965  /* skip auto-generated array and multirange types */
1966  if (tyinfo->isArray || tyinfo->isMultirange)
1967  {
1968  tyinfo->dobj.objType = DO_DUMMY_TYPE;
1969 
1970  /*
1971  * Fall through to set the dump flag; we assume that the subsequent
1972  * rules will do the same thing as they would for the array's base
1973  * type or multirange's range type. (We cannot reliably look up the
1974  * base type here, since getTypes may not have processed it yet.)
1975  */
1976  }
1977 
1978  if (checkExtensionMembership(&tyinfo->dobj, fout))
1979  return; /* extension membership overrides all else */
1980 
1981  /* Dump based on if the contents of the namespace are being dumped */
1982  tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
1983 }

References checkExtensionMembership(), DO_DUMMY_TYPE, _typeInfo::dobj, _tableInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_NONE, _dumpableObject::dump_contains, findTableByOid(), _typeInfo::isArray, _typeInfo::isMultirange, _dumpableObject::objType, OidIsValid, _typeInfo::typrelid, and _typeInfo::typrelkind.

Referenced by getTypes().

◆ SequenceItemCmp()

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

Definition at line 17634 of file pg_dump.c.

17635 {
17636  SequenceItem v1 = *((const SequenceItem *) p1);
17637  SequenceItem v2 = *((const SequenceItem *) p2);
17638 
17639  return pg_cmp_u32(v1.oid, v2.oid);
17640 }

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

Referenced by dumpSequence(), and dumpSequenceData().

◆ set_restrict_relation_kind()

static void set_restrict_relation_kind ( Archive AH,
const char *  value 
)
static

Definition at line 4819 of file pg_dump.c.

4820 {
4821  PQExpBuffer query = createPQExpBuffer();
4822  PGresult *res;
4823 
4824  appendPQExpBuffer(query,
4825  "SELECT set_config(name, '%s', false) "
4826  "FROM pg_settings "
4827  "WHERE name = 'restrict_nonsystem_relation_kind'",
4828  value);
4829  res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
4830 
4831  PQclear(res);
4832  destroyPQExpBuffer(query);
4833 }
static struct @160 value

References appendPQExpBuffer(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), PGRES_TUPLES_OK, PQclear(), res, and value.

Referenced by dumpTableData_copy(), dumpTableData_insert(), and setup_connection().

◆ setup_connection()

static void setup_connection ( Archive AH,
const char *  dumpencoding,
const char *  dumpsnapshot,
char *  use_role 
)
static

Definition at line 1253 of file pg_dump.c.

1255 {
1256  DumpOptions *dopt = AH->dopt;
1257  PGconn *conn = GetConnection(AH);
1258  const char *std_strings;
1259 
1261 
1262  /*
1263  * Set the client encoding if requested.
1264  */
1265  if (dumpencoding)
1266  {
1267  if (PQsetClientEncoding(conn, dumpencoding) < 0)
1268  pg_fatal("invalid client encoding \"%s\" specified",
1269  dumpencoding);
1270  }
1271 
1272  /*
1273  * Get the active encoding and the standard_conforming_strings setting, so
1274  * we know how to escape strings.
1275  */
1277 
1278  std_strings = PQparameterStatus(conn, "standard_conforming_strings");
1279  AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
1280 
1281  /*
1282  * Set the role if requested. In a parallel dump worker, we'll be passed
1283  * use_role == NULL, but AH->use_role is already set (if user specified it
1284  * originally) and we should use that.
1285  */
1286  if (!use_role && AH->use_role)
1287  use_role = AH->use_role;
1288 
1289  /* Set the role if requested */
1290  if (use_role)
1291  {
1292  PQExpBuffer query = createPQExpBuffer();
1293 
1294  appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
1295  ExecuteSqlStatement(AH, query->data);
1296  destroyPQExpBuffer(query);
1297 
1298  /* save it for possible later use by parallel workers */
1299  if (!AH->use_role)
1300  AH->use_role = pg_strdup(use_role);
1301  }
1302 
1303  /* Set the datestyle to ISO to ensure the dump's portability */
1304  ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
1305 
1306  /* Likewise, avoid using sql_standard intervalstyle */
1307  ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
1308 
1309  /*
1310  * Use an explicitly specified extra_float_digits if it has been provided.
1311  * Otherwise, set extra_float_digits so that we can dump float data
1312  * exactly (given correctly implemented float I/O code, anyway).
1313  */
1315  {
1317 
1318  appendPQExpBuffer(q, "SET extra_float_digits TO %d",
1320  ExecuteSqlStatement(AH, q->data);
1321  destroyPQExpBuffer(q);
1322  }
1323  else
1324  ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
1325 
1326  /*
1327  * Disable synchronized scanning, to prevent unpredictable changes in row
1328  * ordering across a dump and reload.
1329  */
1330  ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
1331 
1332  /*
1333  * Disable timeouts if supported.
1334  */
1335  ExecuteSqlStatement(AH, "SET statement_timeout = 0");
1336  if (AH->remoteVersion >= 90300)
1337  ExecuteSqlStatement(AH, "SET lock_timeout = 0");
1338  if (AH->remoteVersion >= 90600)
1339  ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
1340  if (AH->remoteVersion >= 170000)
1341  ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
1342 
1343  /*
1344  * Quote all identifiers, if requested.
1345  */
1347  ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
1348 
1349  /*
1350  * Adjust row-security mode, if supported.
1351  */
1352  if (AH->remoteVersion >= 90500)
1353  {
1354  if (dopt->enable_row_security)
1355  ExecuteSqlStatement(AH, "SET row_security = on");
1356  else
1357  ExecuteSqlStatement(AH, "SET row_security = off");
1358  }
1359 
1360  /*
1361  * For security reasons, we restrict the expansion of non-system views and
1362  * access to foreign tables during the pg_dump process. This restriction
1363  * is adjusted when dumping foreign table data.
1364  */
1365  set_restrict_relation_kind(AH, "view, foreign-table");
1366 
1367  /*
1368  * Initialize prepared-query state to "nothing prepared". We do this here
1369  * so that a parallel dump worker will have its own state.
1370  */
1371  AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
1372 
1373  /*
1374  * Start transaction-snapshot mode transaction to dump consistent data.
1375  */
1376  ExecuteSqlStatement(AH, "BEGIN");
1377 
1378  /*
1379  * To support the combination of serializable_deferrable with the jobs
1380  * option we use REPEATABLE READ for the worker connections that are
1381  * passed a snapshot. As long as the snapshot is acquired in a
1382  * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
1383  * REPEATABLE READ transaction provides the appropriate integrity
1384  * guarantees. This is a kluge, but safe for back-patching.
1385  */
1386  if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
1388  "SET TRANSACTION ISOLATION LEVEL "
1389  "SERIALIZABLE, READ ONLY, DEFERRABLE");
1390  else
1392  "SET TRANSACTION ISOLATION LEVEL "
1393  "REPEATABLE READ, READ ONLY");
1394 
1395  /*
1396  * If user specified a snapshot to use, select that. In a parallel dump
1397  * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
1398  * is already set (if the server can handle it) and we should use that.
1399  */
1400  if (dumpsnapshot)
1401  AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
1402 
1403  if (AH->sync_snapshot_id)
1404  {
1405  PQExpBuffer query = createPQExpBuffer();
1406 
1407  appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
1409  ExecuteSqlStatement(AH, query->data);
1410  destroyPQExpBuffer(query);
1411  }
1412  else if (AH->numWorkers > 1)
1413  {
1414  if (AH->isStandby && AH->remoteVersion < 100000)
1415  pg_fatal("parallel dumps from standby servers are not supported by this server version");
1417  }
1418 }
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7288
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7296
#define NUM_PREP_QUERIES
Definition: pg_backup.h:79
static char * get_synchronized_snapshot(Archive *fout)
Definition: pg_dump.c:1437
char * use_role
Definition: pg_backup.h:235
char * sync_snapshot_id
Definition: pg_backup.h:227

References ALWAYS_SECURE_SEARCH_PATH_SQL, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), conn, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::dopt, _dumpOptions::enable_row_security, Archive::encoding, ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), extra_float_digits, fmtId(), get_synchronized_snapshot(), GetConnection(), have_extra_float_digits, Archive::is_prepared, Archive::isStandby, NUM_PREP_QUERIES, Archive::numWorkers, pg_fatal, pg_malloc0(), pg_strdup(), PQclear(), PQclientEncoding(), PQparameterStatus(), PQsetClientEncoding(), quote_all_identifiers, Archive::remoteVersion, _dumpOptions::serializable_deferrable, set_restrict_relation_kind(), Archive::std_strings, Archive::sync_snapshot_id, and Archive::use_role.

Referenced by main(), and setupDumpWorker().

◆ setupDumpWorker()

static void setupDumpWorker ( Archive AH)
static

Definition at line 1422 of file pg_dump.c.

1423 {
1424  /*
1425  * We want to re-select all the same values the leader connection is
1426  * using. We'll have inherited directly-usable values in
1427  * AH->sync_snapshot_id and AH->use_role, but we need to translate the
1428  * inherited encoding value back to a string to pass to setup_connection.
1429  */
1430  setup_connection(AH,
1432  NULL,
1433  NULL);
1434 }

References Archive::encoding, pg_encoding_to_char, and setup_connection().

Referenced by CreateArchive(), and main().

◆ shouldPrintColumn()

bool shouldPrintColumn ( const DumpOptions dopt,
const TableInfo tbinfo,
int  colno 
)

Definition at line 9443 of file pg_dump.c.

9444 {
9445  if (dopt->binary_upgrade)
9446  return true;
9447  if (tbinfo->attisdropped[colno])
9448  return false;
9449  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9450 }

References _tableInfo::attisdropped, _tableInfo::attislocal, _dumpOptions::binary_upgrade, and _tableInfo::ispartition.

Referenced by dumpTableSchema(), flagInhAttrs(), and getTableAttrs().

◆ StaticAssertDecl()

StaticAssertDecl ( lengthof(SeqTypeNames = =(SEQTYPE_BIGINT+1),
"array length mismatch"   
)

Variable Documentation

◆ binaryUpgradeClassOids

BinaryUpgradeClassOidItem* binaryUpgradeClassOids = NULL
static

Definition at line 203 of file pg_dump.c.

Referenced by binary_upgrade_set_pg_class_oids(), and collectBinaryUpgradeClassOids().

◆ comments

CommentItem* comments = NULL
static

◆ compression_algorithm

pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE
static

Definition at line 152 of file pg_dump.c.

Referenced by main().

◆ dosync

bool dosync = true
static

Definition at line 145 of file pg_dump.c.

Referenced by _allocAH(), CreateArchive(), and main().

◆ extension_exclude_oids

SimpleOidList extension_exclude_oids = {NULL, NULL}
static

Definition at line 182 of file pg_dump.c.

Referenced by main(), processExtensionTables(), and selectDumpableExtension().

◆ extension_exclude_patterns

SimpleStringList extension_exclude_patterns = {NULL, NULL}
static

Definition at line 181 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ extension_include_oids

SimpleOidList extension_include_oids = {NULL, NULL}
static

Definition at line 179 of file pg_dump.c.

Referenced by main(), processExtensionTables(), and selectDumpableExtension().

◆ extension_include_patterns

SimpleStringList extension_include_patterns = {NULL, NULL}
static

Definition at line 178 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ extra_float_digits

int extra_float_digits
static

Definition at line 188 of file pg_dump.c.

Referenced by main(), and setup_connection().

◆ foreign_servers_include_oids

SimpleOidList foreign_servers_include_oids = {NULL, NULL}
static

Definition at line 176 of file pg_dump.c.

Referenced by main(), and makeTableDataInfo().

◆ foreign_servers_include_patterns

SimpleStringList foreign_servers_include_patterns = {NULL, NULL}
static

Definition at line 175 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ g_last_builtin_oid

Oid g_last_builtin_oid
static

◆ have_extra_float_digits

bool have_extra_float_digits = false
static

Definition at line 187 of file pg_dump.c.

Referenced by main(), and setup_connection().

◆ nbinaryUpgradeClassOids

int nbinaryUpgradeClassOids = 0
static

Definition at line 204 of file pg_dump.c.

Referenced by binary_upgrade_set_pg_class_oids(), and collectBinaryUpgradeClassOids().

◆ ncomments

int ncomments = 0
static

◆ nilCatalogId

◆ nrolenames

int nrolenames = 0
static

Definition at line 192 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ nseclabels

int nseclabels = 0
static

Definition at line 200 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ nsequences

int nsequences = 0
static

Definition at line 208 of file pg_dump.c.

Referenced by collectSequences(), dumpSequence(), and dumpSequenceData().

◆ rolenames

RoleNameItem* rolenames = NULL
static

Definition at line 191 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ schema_exclude_oids

SimpleOidList schema_exclude_oids = {NULL, NULL}
static

Definition at line 163 of file pg_dump.c.

Referenced by main(), processExtensionTables(), and selectDumpableNamespace().

◆ schema_exclude_patterns

SimpleStringList schema_exclude_patterns = {NULL, NULL}
static

Definition at line 162 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ schema_include_oids

SimpleOidList schema_include_oids = {NULL, NULL}
static

Definition at line 161 of file pg_dump.c.

Referenced by main(), and selectDumpableNamespace().

◆ schema_include_patterns

SimpleStringList schema_include_patterns = {NULL, NULL}
static

Definition at line 160 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ seclabels

SecLabelItem* seclabels = NULL
static

Definition at line 199 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ SeqTypeNames

const char* const SeqTypeNames[]
static
Initial value:
=
{
[SEQTYPE_SMALLINT] = "smallint",
[SEQTYPE_INTEGER] = "integer",
[SEQTYPE_BIGINT] = "bigint",
}

Definition at line 113 of file pg_dump.c.

Referenced by dumpSequence(), and parse_sequence_type().

◆ sequences

SequenceItem* sequences = NULL
static

Definition at line 207 of file pg_dump.c.

Referenced by collectSequences(), dumpSequence(), and dumpSequenceData().

◆ strict_names

int strict_names = 0
static

◆ table_exclude_oids

SimpleOidList table_exclude_oids = {NULL, NULL}
static

Definition at line 170 of file pg_dump.c.

Referenced by main(), processExtensionTables(), and selectDumpableTable().

◆ table_exclude_patterns

SimpleStringList table_exclude_patterns = {NULL, NULL}
static

Definition at line 168 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ table_exclude_patterns_and_children

SimpleStringList table_exclude_patterns_and_children = {NULL, NULL}
static

Definition at line 169 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ table_include_oids

SimpleOidList table_include_oids = {NULL, NULL}
static

◆ table_include_patterns

SimpleStringList table_include_patterns = {NULL, NULL}
static

Definition at line 165 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ table_include_patterns_and_children

SimpleStringList table_include_patterns_and_children = {NULL, NULL}
static

Definition at line 166 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ tabledata_exclude_oids

SimpleOidList tabledata_exclude_oids = {NULL, NULL}
static

Definition at line 173 of file pg_dump.c.

Referenced by main(), and makeTableDataInfo().

◆ tabledata_exclude_patterns

SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
static

Definition at line 171 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ tabledata_exclude_patterns_and_children

SimpleStringList tabledata_exclude_patterns_and_children = {NULL, NULL}
static

Definition at line 172 of file pg_dump.c.

Referenced by main(), and read_dump_filters().