PostgreSQL Source Code  git master
pg_dump.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_aggregate_d.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_attribute_d.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_cast_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_default_acl_d.h"
#include "catalog/pg_largeobject_d.h"
#include "catalog/pg_largeobject_metadata_d.h"
#include "catalog/pg_proc_d.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_trigger_d.h"
#include "catalog/pg_type_d.h"
#include "common/connect.h"
#include "common/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
 

Macros

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

Typedefs

typedef enum OidOptions OidOptions
 

Enumerations

enum  OidOptions { zeroIsError = 1 , zeroAsStar = 2 , zeroAsNone = 4 }
 

Functions

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 dumpSequence (Archive *fout, const TableInfo *tbinfo)
 
static void dumpSequenceData (Archive *fout, const TableDataInfo *tdinfo)
 
static void dumpIndex (Archive *fout, const IndxInfo *indxinfo)
 
static void dumpIndexAttach (Archive *fout, const IndexAttachInfo *attachinfo)
 
static void dumpStatisticsExt (Archive *fout, const StatsExtInfo *statsextinfo)
 
static void dumpConstraint (Archive *fout, const ConstraintInfo *coninfo)
 
static void dumpTableConstraintComment (Archive *fout, const ConstraintInfo *coninfo)
 
static void dumpTSParser (Archive *fout, const TSParserInfo *prsinfo)
 
static void dumpTSDictionary (Archive *fout, const TSDictInfo *dictinfo)
 
static void dumpTSTemplate (Archive *fout, const TSTemplateInfo *tmplinfo)
 
static void dumpTSConfig (Archive *fout, const TSConfigInfo *cfginfo)
 
static void dumpForeignDataWrapper (Archive *fout, const FdwInfo *fdwinfo)
 
static void dumpForeignServer (Archive *fout, const ForeignServerInfo *srvinfo)
 
static void dumpUserMappings (Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
 
static void dumpDefaultACL (Archive *fout, const DefaultACLInfo *daclinfo)
 
static DumpId dumpACL (Archive *fout, DumpId objDumpId, DumpId altDumpId, const char *type, const char *name, const char *subname, const char *nspname, const char *tag, const char *owner, const DumpableAcl *dacl)
 
static void getDependencies (Archive *fout)
 
static void BuildArchiveDependencies (Archive *fout)
 
static void findDumpableDependencies (ArchiveHandle *AH, const DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
 
static DumpableObjectcreateBoundaryObjects (void)
 
static void addBoundaryDependencies (DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
 
static void addConstrChildIdxDeps (DumpableObject *dobj, const IndxInfo *refidx)
 
static void getDomainConstraints (Archive *fout, TypeInfo *tyinfo)
 
static void getTableData (DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
 
static void makeTableDataInfo (DumpOptions *dopt, TableInfo *tbinfo)
 
static void buildMatViewRefreshDependencies (Archive *fout)
 
static void getTableDataFKConstraints (void)
 
static char * format_function_arguments (const FuncInfo *finfo, const char *funcargs, bool is_agg)
 
static char * format_function_signature (Archive *fout, const FuncInfo *finfo, bool honor_quotes)
 
static char * convertRegProcReference (const char *proc)
 
static char * getFormattedOperatorName (const char *oproid)
 
static char * convertTSFunction (Archive *fout, Oid funcOid)
 
static const char * getFormattedTypeName (Archive *fout, Oid oid, OidOptions opts)
 
static void getLOs (Archive *fout)
 
static void dumpLO (Archive *fout, const LoInfo *loinfo)
 
static int dumpLOs (Archive *fout, const void *arg)
 
static void dumpPolicy (Archive *fout, const PolicyInfo *polinfo)
 
static void dumpPublication (Archive *fout, const PublicationInfo *pubinfo)
 
static void dumpPublicationTable (Archive *fout, const PublicationRelInfo *pubrinfo)
 
static void dumpSubscription (Archive *fout, const SubscriptionInfo *subinfo)
 
static void dumpSubscriptionTable (Archive *fout, const SubRelInfo *subrinfo)
 
static void dumpDatabase (Archive *fout)
 
static void dumpDatabaseConfig (Archive *AH, PQExpBuffer outbuf, const char *dbname, Oid dboid)
 
static void dumpEncoding (Archive *AH)
 
static void dumpStdStrings (Archive *AH)
 
static void dumpSearchPath (Archive *AH)
 
static void binary_upgrade_set_type_oids_by_type_oid (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_type_oid, bool force_array_type, bool include_multirange_type)
 
static void binary_upgrade_set_type_oids_by_rel (Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tbinfo)
 
static void binary_upgrade_set_pg_class_oids (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid, bool is_index)
 
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 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)
 
PublicationInfogetPublications (Archive *fout, int *numPublications)
 
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)
 
NamespaceInfogetNamespaces (Archive *fout, int *numNamespaces)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
TypeInfogetTypes (Archive *fout, int *numTypes)
 
OprInfogetOperators (Archive *fout, int *numOprs)
 
CollInfogetCollations (Archive *fout, int *numCollations)
 
ConvInfogetConversions (Archive *fout, int *numConversions)
 
AccessMethodInfogetAccessMethods (Archive *fout, int *numAccessMethods)
 
OpclassInfogetOpclasses (Archive *fout, int *numOpclasses)
 
OpfamilyInfogetOpfamilies (Archive *fout, int *numOpfamilies)
 
AggInfogetAggregates (Archive *fout, int *numAggs)
 
FuncInfogetFuncs (Archive *fout, int *numFuncs)
 
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)
 
RuleInfogetRules (Archive *fout, int *numRules)
 
void getTriggers (Archive *fout, TableInfo tblinfo[], int numTables)
 
EventTriggerInfogetEventTriggers (Archive *fout, int *numEventTriggers)
 
ProcLangInfogetProcLangs (Archive *fout, int *numProcLangs)
 
CastInfogetCasts (Archive *fout, int *numCasts)
 
static char * get_language_name (Archive *fout, Oid langid)
 
TransformInfogetTransforms (Archive *fout, int *numTransforms)
 
void getTableAttrs (Archive *fout, TableInfo *tblinfo, int numTables)
 
bool shouldPrintColumn (const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
 
TSParserInfogetTSParsers (Archive *fout, int *numTSParsers)
 
TSDictInfogetTSDictionaries (Archive *fout, int *numTSDicts)
 
TSTemplateInfogetTSTemplates (Archive *fout, int *numTSTemplates)
 
TSConfigInfogetTSConfigurations (Archive *fout, int *numTSConfigs)
 
FdwInfogetForeignDataWrappers (Archive *fout, int *numForeignDataWrappers)
 
ForeignServerInfogetForeignServers (Archive *fout, int *numForeignServers)
 
DefaultACLInfogetDefaultACLs (Archive *fout, int *numDefaultACLs)
 
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)
 
void getExtensionMembership (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void processExtensionTables (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 

Variables

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
 

Macro Definition Documentation

◆ DUMP_DEFAULT_ROWS_PER_INSERT

#define DUMP_DEFAULT_ROWS_PER_INSERT   1

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

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

Definition at line 171 of file pg_dump.c.

Typedef Documentation

◆ OidOptions

typedef enum OidOptions OidOptions

Enumeration Type Documentation

◆ OidOptions

enum OidOptions
Enumerator
zeroIsError 
zeroAsStar 
zeroAsNone 

Definition at line 95 of file pg_dump.c.

96 {
97  zeroIsError = 1,
98  zeroAsStar = 2,
99  zeroAsNone = 4,
100 } OidOptions;
OidOptions
Definition: pg_dump.c:96
@ zeroIsError
Definition: pg_dump.c:97
@ zeroAsStar
Definition: pg_dump.c:98
@ zeroAsNone
Definition: pg_dump.c:99

Function Documentation

◆ addBoundaryDependencies()

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

Definition at line 18698 of file pg_dump.c.

18700 {
18701  DumpableObject *preDataBound = boundaryObjs + 0;
18702  DumpableObject *postDataBound = boundaryObjs + 1;
18703  int i;
18704 
18705  for (i = 0; i < numObjs; i++)
18706  {
18707  DumpableObject *dobj = dobjs[i];
18708 
18709  /*
18710  * The classification of object types here must match the SECTION_xxx
18711  * values assigned during subsequent ArchiveEntry calls!
18712  */
18713  switch (dobj->objType)
18714  {
18715  case DO_NAMESPACE:
18716  case DO_EXTENSION:
18717  case DO_TYPE:
18718  case DO_SHELL_TYPE:
18719  case DO_FUNC:
18720  case DO_AGG:
18721  case DO_OPERATOR:
18722  case DO_ACCESS_METHOD:
18723  case DO_OPCLASS:
18724  case DO_OPFAMILY:
18725  case DO_COLLATION:
18726  case DO_CONVERSION:
18727  case DO_TABLE:
18728  case DO_TABLE_ATTACH:
18729  case DO_ATTRDEF:
18730  case DO_PROCLANG:
18731  case DO_CAST:
18732  case DO_DUMMY_TYPE:
18733  case DO_TSPARSER:
18734  case DO_TSDICT:
18735  case DO_TSTEMPLATE:
18736  case DO_TSCONFIG:
18737  case DO_FDW:
18738  case DO_FOREIGN_SERVER:
18739  case DO_TRANSFORM:
18740  /* Pre-data objects: must come before the pre-data boundary */
18741  addObjectDependency(preDataBound, dobj->dumpId);
18742  break;
18743  case DO_TABLE_DATA:
18744  case DO_SEQUENCE_SET:
18745  case DO_LARGE_OBJECT:
18746  case DO_LARGE_OBJECT_DATA:
18747  /* Data objects: must come between the boundaries */
18748  addObjectDependency(dobj, preDataBound->dumpId);
18749  addObjectDependency(postDataBound, dobj->dumpId);
18750  break;
18751  case DO_INDEX:
18752  case DO_INDEX_ATTACH:
18753  case DO_STATSEXT:
18754  case DO_REFRESH_MATVIEW:
18755  case DO_TRIGGER:
18756  case DO_EVENT_TRIGGER:
18757  case DO_DEFAULT_ACL:
18758  case DO_POLICY:
18759  case DO_PUBLICATION:
18760  case DO_PUBLICATION_REL:
18762  case DO_SUBSCRIPTION:
18763  case DO_SUBSCRIPTION_REL:
18764  /* Post-data objects: must come after the post-data boundary */
18765  addObjectDependency(dobj, postDataBound->dumpId);
18766  break;
18767  case DO_RULE:
18768  /* Rules are post-data, but only if dumped separately */
18769  if (((RuleInfo *) dobj)->separate)
18770  addObjectDependency(dobj, postDataBound->dumpId);
18771  break;
18772  case DO_CONSTRAINT:
18773  case DO_FK_CONSTRAINT:
18774  /* Constraints are post-data, but only if dumped separately */
18775  if (((ConstraintInfo *) dobj)->separate)
18776  addObjectDependency(dobj, postDataBound->dumpId);
18777  break;
18778  case DO_PRE_DATA_BOUNDARY:
18779  /* nothing to do */
18780  break;
18781  case DO_POST_DATA_BOUNDARY:
18782  /* must come after the pre-data boundary */
18783  addObjectDependency(dobj, preDataBound->dumpId);
18784  break;
18785  }
18786  }
18787 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:809
int i
Definition: isn.c:73
@ DO_EVENT_TRIGGER
Definition: pg_dump.h:79
@ DO_REFRESH_MATVIEW
Definition: pg_dump.h:80
@ DO_POLICY
Definition: pg_dump.h:81
@ DO_CAST
Definition: pg_dump.h:63
@ DO_FOREIGN_SERVER
Definition: pg_dump.h:72
@ DO_PRE_DATA_BOUNDARY
Definition: pg_dump.h:77
@ DO_PROCLANG
Definition: pg_dump.h:62
@ DO_TYPE
Definition: pg_dump.h:42
@ DO_INDEX
Definition: pg_dump.h:55
@ DO_COLLATION
Definition: pg_dump.h:50
@ DO_LARGE_OBJECT
Definition: pg_dump.h:75
@ DO_TSCONFIG
Definition: pg_dump.h:70
@ DO_OPERATOR
Definition: pg_dump.h:46
@ DO_FK_CONSTRAINT
Definition: pg_dump.h:61
@ DO_CONSTRAINT
Definition: pg_dump.h:60
@ DO_SUBSCRIPTION
Definition: pg_dump.h:85
@ DO_DEFAULT_ACL
Definition: pg_dump.h:73
@ DO_FDW
Definition: pg_dump.h:71
@ DO_SUBSCRIPTION_REL
Definition: pg_dump.h:86
@ DO_SEQUENCE_SET
Definition: pg_dump.h:65
@ DO_ATTRDEF
Definition: pg_dump.h:54
@ DO_PUBLICATION_REL
Definition: pg_dump.h:83
@ DO_TABLE_ATTACH
Definition: pg_dump.h:53
@ DO_OPCLASS
Definition: pg_dump.h:48
@ DO_INDEX_ATTACH
Definition: pg_dump.h:56
@ DO_TSTEMPLATE
Definition: pg_dump.h:69
@ DO_STATSEXT
Definition: pg_dump.h:57
@ DO_FUNC
Definition: pg_dump.h:44
@ DO_POST_DATA_BOUNDARY
Definition: pg_dump.h:78
@ DO_LARGE_OBJECT_DATA
Definition: pg_dump.h:76
@ DO_OPFAMILY
Definition: pg_dump.h:49
@ DO_TRANSFORM
Definition: pg_dump.h:74
@ DO_ACCESS_METHOD
Definition: pg_dump.h:47
@ DO_PUBLICATION_TABLE_IN_SCHEMA
Definition: pg_dump.h:84
@ DO_CONVERSION
Definition: pg_dump.h:51
@ DO_TRIGGER
Definition: pg_dump.h:59
@ DO_RULE
Definition: pg_dump.h:58
@ DO_DUMMY_TYPE
Definition: pg_dump.h:66
@ DO_TSDICT
Definition: pg_dump.h:68
@ DO_TSPARSER
Definition: pg_dump.h:67
@ DO_EXTENSION
Definition: pg_dump.h:41
@ DO_TABLE_DATA
Definition: pg_dump.h:64
@ DO_PUBLICATION
Definition: pg_dump.h:82
@ DO_TABLE
Definition: pg_dump.h:52
@ DO_NAMESPACE
Definition: pg_dump.h:40
@ DO_AGG
Definition: pg_dump.h:45
@ DO_SHELL_TYPE
Definition: pg_dump.h:43
DumpId dumpId
Definition: pg_dump.h:137
DumpableObjectType objType
Definition: pg_dump.h:135

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

Referenced by main().

◆ addConstrChildIdxDeps()

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

Definition at line 7887 of file pg_dump.c.

7888 {
7889  SimplePtrListCell *cell;
7890 
7891  Assert(dobj->objType == DO_FK_CONSTRAINT);
7892 
7893  for (cell = refidx->partattaches.head; cell; cell = cell->next)
7894  {
7895  IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
7896 
7897  addObjectDependency(dobj, attach->dobj.dumpId);
7898 
7899  if (attach->partitionIdx->partattaches.head != NULL)
7900  addConstrChildIdxDeps(dobj, attach->partitionIdx);
7901  }
7902 }
#define Assert(condition)
Definition: c.h:858
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:7887
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 5220 of file pg_dump.c.

5226 {
5227  if (dobj->depends_on_ext)
5228  {
5229  char *nm;
5230  PGresult *res;
5231  PQExpBuffer query;
5232  int ntups;
5233  int i_extname;
5234  int i;
5235 
5236  /* dodge fmtId() non-reentrancy */
5237  nm = pg_strdup(objname);
5238 
5239  query = createPQExpBuffer();
5240  appendPQExpBuffer(query,
5241  "SELECT e.extname "
5242  "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5243  "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5244  "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5245  "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5246  catalog,
5247  dobj->catId.oid);
5248  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5249  ntups = PQntuples(res);
5250  i_extname = PQfnumber(res, "extname");
5251  for (i = 0; i < ntups; i++)
5252  {
5253  appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5254  keyword, nm,
5255  fmtId(PQgetvalue(res, i, i_extname)));
5256  }
5257 
5258  PQclear(res);
5259  destroyPQExpBuffer(query);
5260  pg_free(nm);
5261  }
5262 }
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:103
PGresult * ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
Definition: pg_backup_db.c:290
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
CatalogId catId
Definition: pg_dump.h:136
bool depends_on_ext
Definition: pg_dump.h:144

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

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

◆ appendReloptionsArrayAH()

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

Definition at line 19015 of file pg_dump.c.

19017 {
19018  bool res;
19019 
19020  res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
19021  fout->std_strings);
19022  if (!res)
19023  pg_log_warning("could not parse %s array", "reloptions");
19024 }
#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:230
int encoding
Definition: pg_backup.h:229

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

5514 {
5515  DumpableObject *extobj = NULL;
5516  int i;
5517 
5518  if (!dobj->ext_member)
5519  return;
5520 
5521  /*
5522  * Find the parent extension. We could avoid this search if we wanted to
5523  * add a link field to DumpableObject, but the space costs of that would
5524  * be considerable. We assume that member objects could only have a
5525  * direct dependency on their own extension, not any others.
5526  */
5527  for (i = 0; i < dobj->nDeps; i++)
5528  {
5529  extobj = findObjectByDumpId(dobj->dependencies[i]);
5530  if (extobj && extobj->objType == DO_EXTENSION)
5531  break;
5532  extobj = NULL;
5533  }
5534  if (extobj == NULL)
5535  pg_fatal("could not find parent extension for %s %s",
5536  objtype, objname);
5537 
5538  appendPQExpBufferStr(upgrade_buffer,
5539  "\n-- For binary upgrade, handle extension membership the hard way\n");
5540  appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5541  fmtId(extobj->name),
5542  objtype);
5543  if (objnamespace && *objnamespace)
5544  appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5545  appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5546 }
DumpableObject * findObjectByDumpId(DumpId dumpId)
Definition: common.c:756
#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,
bool  is_index 
)
static

Definition at line 5393 of file pg_dump.c.

5396 {
5397  PQExpBuffer upgrade_query = createPQExpBuffer();
5398  PGresult *upgrade_res;
5399  RelFileNumber relfilenumber;
5400  Oid toast_oid;
5401  RelFileNumber toast_relfilenumber;
5402  char relkind;
5403  Oid toast_index_oid;
5404  RelFileNumber toast_index_relfilenumber;
5405 
5406  /*
5407  * Preserve the OID and relfilenumber of the table, table's index, table's
5408  * toast table and toast table's index if any.
5409  *
5410  * One complexity is that the current table definition might not require
5411  * the creation of a TOAST table, but the old database might have a TOAST
5412  * table that was created earlier, before some wide columns were dropped.
5413  * By setting the TOAST oid we force creation of the TOAST heap and index
5414  * by the new backend, so we can copy the files during binary upgrade
5415  * without worrying about this case.
5416  */
5417  appendPQExpBuffer(upgrade_query,
5418  "SELECT c.relkind, c.relfilenode, c.reltoastrelid, ct.relfilenode AS toast_relfilenode, i.indexrelid, cti.relfilenode AS toast_index_relfilenode "
5419  "FROM pg_catalog.pg_class c LEFT JOIN "
5420  "pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5421  "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5422  "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5423  "WHERE c.oid = '%u'::pg_catalog.oid;",
5424  pg_class_oid);
5425 
5426  upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5427 
5428  relkind = *PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "relkind"));
5429 
5430  relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5431  PQfnumber(upgrade_res, "relfilenode")));
5432  toast_oid = atooid(PQgetvalue(upgrade_res, 0,
5433  PQfnumber(upgrade_res, "reltoastrelid")));
5434  toast_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5435  PQfnumber(upgrade_res, "toast_relfilenode")));
5436  toast_index_oid = atooid(PQgetvalue(upgrade_res, 0,
5437  PQfnumber(upgrade_res, "indexrelid")));
5438  toast_index_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5439  PQfnumber(upgrade_res, "toast_index_relfilenode")));
5440 
5441  appendPQExpBufferStr(upgrade_buffer,
5442  "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5443 
5444  if (!is_index)
5445  {
5446  appendPQExpBuffer(upgrade_buffer,
5447  "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5448  pg_class_oid);
5449 
5450  /*
5451  * Not every relation has storage. Also, in a pre-v12 database,
5452  * partitioned tables have a relfilenumber, which should not be
5453  * preserved when upgrading.
5454  */
5455  if (RelFileNumberIsValid(relfilenumber) && relkind != RELKIND_PARTITIONED_TABLE)
5456  appendPQExpBuffer(upgrade_buffer,
5457  "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5458  relfilenumber);
5459 
5460  /*
5461  * In a pre-v12 database, partitioned tables might be marked as having
5462  * toast tables, but we should ignore them if so.
5463  */
5464  if (OidIsValid(toast_oid) &&
5465  relkind != RELKIND_PARTITIONED_TABLE)
5466  {
5467  appendPQExpBuffer(upgrade_buffer,
5468  "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5469  toast_oid);
5470  appendPQExpBuffer(upgrade_buffer,
5471  "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5472  toast_relfilenumber);
5473 
5474  /* every toast table has an index */
5475  appendPQExpBuffer(upgrade_buffer,
5476  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5477  toast_index_oid);
5478  appendPQExpBuffer(upgrade_buffer,
5479  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5480  toast_index_relfilenumber);
5481  }
5482 
5483  PQclear(upgrade_res);
5484  }
5485  else
5486  {
5487  /* Preserve the OID and relfilenumber of the index */
5488  appendPQExpBuffer(upgrade_buffer,
5489  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5490  pg_class_oid);
5491  appendPQExpBuffer(upgrade_buffer,
5492  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5493  relfilenumber);
5494  }
5495 
5496  appendPQExpBufferChar(upgrade_buffer, '\n');
5497 
5498  destroyPQExpBuffer(upgrade_query);
5499 }
#define OidIsValid(objectId)
Definition: c.h:775
PGresult * ExecuteSqlQueryForSingleRow(Archive *fout, const char *query)
Definition: pg_backup_db.c:305
unsigned int Oid
Definition: postgres_ext.h:31
#define atooid(x)
Definition: postgres_ext.h:42
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
Oid RelFileNumber
Definition: relpath.h:25
#define RelFileNumberIsValid(relnumber)
Definition: relpath.h:27

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), OidIsValid, PQclear(), PQfnumber(), PQgetvalue(), and RelFileNumberIsValid.

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

5384 {
5385  Oid pg_type_oid = tbinfo->reltype;
5386 
5387  if (OidIsValid(pg_type_oid))
5388  binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5389  pg_type_oid, false, false);
5390 }
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:5296
Oid reltype
Definition: pg_dump.h:309

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

5301 {
5302  PQExpBuffer upgrade_query = createPQExpBuffer();
5303  PGresult *res;
5304  Oid pg_type_array_oid;
5305  Oid pg_type_multirange_oid;
5306  Oid pg_type_multirange_array_oid;
5307 
5308  appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5309  appendPQExpBuffer(upgrade_buffer,
5310  "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5311  pg_type_oid);
5312 
5313  appendPQExpBuffer(upgrade_query,
5314  "SELECT typarray "
5315  "FROM pg_catalog.pg_type "
5316  "WHERE oid = '%u'::pg_catalog.oid;",
5317  pg_type_oid);
5318 
5319  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5320 
5321  pg_type_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5322 
5323  PQclear(res);
5324 
5325  if (!OidIsValid(pg_type_array_oid) && force_array_type)
5326  pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5327 
5328  if (OidIsValid(pg_type_array_oid))
5329  {
5330  appendPQExpBufferStr(upgrade_buffer,
5331  "\n-- For binary upgrade, must preserve pg_type array oid\n");
5332  appendPQExpBuffer(upgrade_buffer,
5333  "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5334  pg_type_array_oid);
5335  }
5336 
5337  /*
5338  * Pre-set the multirange type oid and its own array type oid.
5339  */
5340  if (include_multirange_type)
5341  {
5342  if (fout->remoteVersion >= 140000)
5343  {
5344  printfPQExpBuffer(upgrade_query,
5345  "SELECT t.oid, t.typarray "
5346  "FROM pg_catalog.pg_type t "
5347  "JOIN pg_catalog.pg_range r "
5348  "ON t.oid = r.rngmultitypid "
5349  "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5350  pg_type_oid);
5351 
5352  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5353 
5354  pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5355  pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5356 
5357  PQclear(res);
5358  }
5359  else
5360  {
5361  pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5362  pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5363  }
5364 
5365  appendPQExpBufferStr(upgrade_buffer,
5366  "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5367  appendPQExpBuffer(upgrade_buffer,
5368  "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5369  pg_type_multirange_oid);
5370  appendPQExpBufferStr(upgrade_buffer,
5371  "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5372  appendPQExpBuffer(upgrade_buffer,
5373  "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5374  pg_type_multirange_array_oid);
5375  }
5376 
5377  destroyPQExpBuffer(upgrade_query);
5378 }
static Oid get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
Definition: pg_dump.c:5265
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
int remoteVersion
Definition: pg_backup.h:219

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

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

◆ BuildArchiveDependencies()

static void BuildArchiveDependencies ( Archive fout)
static

Definition at line 18814 of file pg_dump.c.

18815 {
18816  ArchiveHandle *AH = (ArchiveHandle *) fout;
18817  TocEntry *te;
18818 
18819  /* Scan all TOC entries in the archive */
18820  for (te = AH->toc->next; te != AH->toc; te = te->next)
18821  {
18822  DumpableObject *dobj;
18823  DumpId *dependencies;
18824  int nDeps;
18825  int allocDeps;
18826 
18827  /* No need to process entries that will not be dumped */
18828  if (te->reqs == 0)
18829  continue;
18830  /* Ignore entries that already have "special" dependencies */
18831  if (te->nDeps > 0)
18832  continue;
18833  /* Otherwise, look up the item's original DumpableObject, if any */
18834  dobj = findObjectByDumpId(te->dumpId);
18835  if (dobj == NULL)
18836  continue;
18837  /* No work if it has no dependencies */
18838  if (dobj->nDeps <= 0)
18839  continue;
18840  /* Set up work array */
18841  allocDeps = 64;
18842  dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
18843  nDeps = 0;
18844  /* Recursively find all dumpable dependencies */
18845  findDumpableDependencies(AH, dobj,
18846  &dependencies, &nDeps, &allocDeps);
18847  /* And save 'em ... */
18848  if (nDeps > 0)
18849  {
18850  dependencies = (DumpId *) pg_realloc(dependencies,
18851  nDeps * sizeof(DumpId));
18852  te->dependencies = dependencies;
18853  te->nDeps = nDeps;
18854  }
18855  else
18856  free(dependencies);
18857  }
18858 }
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:270
static void findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
Definition: pg_dump.c:18862
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 2841 of file pg_dump.c.

2842 {
2843  PQExpBuffer query;
2844  PGresult *res;
2845  int ntups,
2846  i;
2847  int i_classid,
2848  i_objid,
2849  i_refobjid;
2850 
2851  /* No Mat Views before 9.3. */
2852  if (fout->remoteVersion < 90300)
2853  return;
2854 
2855  query = createPQExpBuffer();
2856 
2857  appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
2858  "( "
2859  "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
2860  "FROM pg_depend d1 "
2861  "JOIN pg_class c1 ON c1.oid = d1.objid "
2862  "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
2863  " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
2864  "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
2865  "AND d2.objid = r1.oid "
2866  "AND d2.refobjid <> d1.objid "
2867  "JOIN pg_class c2 ON c2.oid = d2.refobjid "
2868  "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
2869  CppAsString2(RELKIND_VIEW) ") "
2870  "WHERE d1.classid = 'pg_class'::regclass "
2871  "UNION "
2872  "SELECT w.objid, d3.refobjid, c3.relkind "
2873  "FROM w "
2874  "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
2875  "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
2876  "AND d3.objid = r3.oid "
2877  "AND d3.refobjid <> w.refobjid "
2878  "JOIN pg_class c3 ON c3.oid = d3.refobjid "
2879  "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
2880  CppAsString2(RELKIND_VIEW) ") "
2881  ") "
2882  "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
2883  "FROM w "
2884  "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
2885 
2886  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
2887 
2888  ntups = PQntuples(res);
2889 
2890  i_classid = PQfnumber(res, "classid");
2891  i_objid = PQfnumber(res, "objid");
2892  i_refobjid = PQfnumber(res, "refobjid");
2893 
2894  for (i = 0; i < ntups; i++)
2895  {
2896  CatalogId objId;
2897  CatalogId refobjId;
2898  DumpableObject *dobj;
2899  DumpableObject *refdobj;
2900  TableInfo *tbinfo;
2901  TableInfo *reftbinfo;
2902 
2903  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
2904  objId.oid = atooid(PQgetvalue(res, i, i_objid));
2905  refobjId.tableoid = objId.tableoid;
2906  refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
2907 
2908  dobj = findObjectByCatalogId(objId);
2909  if (dobj == NULL)
2910  continue;
2911 
2912  Assert(dobj->objType == DO_TABLE);
2913  tbinfo = (TableInfo *) dobj;
2914  Assert(tbinfo->relkind == RELKIND_MATVIEW);
2915  dobj = (DumpableObject *) tbinfo->dataObj;
2916  if (dobj == NULL)
2917  continue;
2918  Assert(dobj->objType == DO_REFRESH_MATVIEW);
2919 
2920  refdobj = findObjectByCatalogId(refobjId);
2921  if (refdobj == NULL)
2922  continue;
2923 
2924  Assert(refdobj->objType == DO_TABLE);
2925  reftbinfo = (TableInfo *) refdobj;
2926  Assert(reftbinfo->relkind == RELKIND_MATVIEW);
2927  refdobj = (DumpableObject *) reftbinfo->dataObj;
2928  if (refdobj == NULL)
2929  continue;
2930  Assert(refdobj->objType == DO_REFRESH_MATVIEW);
2931 
2932  addObjectDependency(dobj, refdobj->dumpId);
2933 
2934  if (!reftbinfo->relispopulated)
2935  tbinfo->relispopulated = false;
2936  }
2937 
2938  PQclear(res);
2939 
2940  destroyPQExpBuffer(query);
2941 }
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:769
#define CppAsString2(x)
Definition: c.h:327
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Oid tableoid
Definition: pg_backup.h:266
bool relispopulated
Definition: pg_dump.h:290
struct _tableDataInfo * dataObj
Definition: pg_dump.h:366
char relkind
Definition: pg_dump.h:288

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

1704 {
1705  ExtensionInfo *ext = findOwningExtension(dobj->catId);
1706 
1707  if (ext == NULL)
1708  return false;
1709 
1710  dobj->ext_member = true;
1711 
1712  /* Record dependency so that getDependencies needn't deal with that */
1713  addObjectDependency(dobj, ext->dobj.dumpId);
1714 
1715  /*
1716  * In 9.6 and above, mark the member object to have any non-initial ACLs
1717  * dumped. (Any initial ACLs will be removed later, using data from
1718  * pg_init_privs, so that we'll dump only the delta from the extension's
1719  * initial setup.)
1720  *
1721  * Prior to 9.6, we do not include any extension member components.
1722  *
1723  * In binary upgrades, we still dump all components of the members
1724  * individually, since the idea is to exactly reproduce the database
1725  * contents rather than replace the extension contents with something
1726  * different.
1727  *
1728  * Note: it might be interesting someday to implement storage and delta
1729  * dumping of extension members' RLS policies and/or security labels.
1730  * However there is a pitfall for RLS policies: trying to dump them
1731  * requires getting a lock on their tables, and the calling user might not
1732  * have privileges for that. We need no lock to examine a table's ACLs,
1733  * so the current feature doesn't have a problem of that sort.
1734  */
1735  if (fout->dopt->binary_upgrade)
1736  dobj->dump = ext->dobj.dump;
1737  else
1738  {
1739  if (fout->remoteVersion < 90600)
1740  dobj->dump = DUMP_COMPONENT_NONE;
1741  else
1742  dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
1743  }
1744 
1745  return true;
1746 }
ExtensionInfo * findOwningExtension(CatalogId catalogId)
Definition: common.c:1060
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:101
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:96
DumpOptions * dopt
Definition: pg_backup.h:214
int binary_upgrade
Definition: pg_backup.h:166
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().

◆ collectComments()

static void collectComments ( Archive fout)
static

Definition at line 10512 of file pg_dump.c.

10513 {
10514  PGresult *res;
10515  PQExpBuffer query;
10516  int i_description;
10517  int i_classoid;
10518  int i_objoid;
10519  int i_objsubid;
10520  int ntups;
10521  int i;
10522  DumpableObject *dobj;
10523 
10524  query = createPQExpBuffer();
10525 
10526  appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
10527  "FROM pg_catalog.pg_description "
10528  "ORDER BY classoid, objoid, objsubid");
10529 
10530  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10531 
10532  /* Construct lookup table containing OIDs in numeric form */
10533 
10534  i_description = PQfnumber(res, "description");
10535  i_classoid = PQfnumber(res, "classoid");
10536  i_objoid = PQfnumber(res, "objoid");
10537  i_objsubid = PQfnumber(res, "objsubid");
10538 
10539  ntups = PQntuples(res);
10540 
10541  comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
10542  ncomments = 0;
10543  dobj = NULL;
10544 
10545  for (i = 0; i < ntups; i++)
10546  {
10547  CatalogId objId;
10548  int subid;
10549 
10550  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
10551  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
10552  subid = atoi(PQgetvalue(res, i, i_objsubid));
10553 
10554  /* We needn't remember comments that don't match any dumpable object */
10555  if (dobj == NULL ||
10556  dobj->catId.tableoid != objId.tableoid ||
10557  dobj->catId.oid != objId.oid)
10558  dobj = findObjectByCatalogId(objId);
10559  if (dobj == NULL)
10560  continue;
10561 
10562  /*
10563  * Comments on columns of composite types are linked to the type's
10564  * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
10565  * in the type's own DumpableObject.
10566  */
10567  if (subid != 0 && dobj->objType == DO_TABLE &&
10568  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
10569  {
10570  TypeInfo *cTypeInfo;
10571 
10572  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
10573  if (cTypeInfo)
10574  cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
10575  }
10576  else
10577  dobj->components |= DUMP_COMPONENT_COMMENT;
10578 
10579  comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
10581  comments[ncomments].objoid = objId.oid;
10582  comments[ncomments].objsubid = subid;
10583  ncomments++;
10584  }
10585 
10586  PQclear(res);
10587  destroyPQExpBuffer(query);
10588 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:890
static int ncomments
Definition: pg_dump.c:154
static CommentItem * comments
Definition: pg_dump.c:153
#define DUMP_COMPONENT_COMMENT
Definition: pg_dump.h:99
Oid classoid
Definition: pg_dump.c:81
Oid objoid
Definition: pg_dump.c:82
int objsubid
Definition: pg_dump.c:83
const char * descr
Definition: pg_dump.c:80
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 10057 of file pg_dump.c.

10058 {
10059  PGresult *res;
10060  const char *query;
10061  int i;
10062 
10063  query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
10064 
10065  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
10066 
10068 
10070 
10071  for (i = 0; i < nrolenames; i++)
10072  {
10075  }
10076 
10077  PQclear(res);
10078 }
static RoleNameItem * rolenames
Definition: pg_dump.c:149
static int nrolenames
Definition: pg_dump.c:150
const char * rolename
Definition: pg_dump.c:75
Oid roleoid
Definition: pg_dump.c:74

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

15655 {
15656  PGresult *res;
15657  PQExpBuffer query;
15658  int i_label;
15659  int i_provider;
15660  int i_classoid;
15661  int i_objoid;
15662  int i_objsubid;
15663  int ntups;
15664  int i;
15665  DumpableObject *dobj;
15666 
15667  query = createPQExpBuffer();
15668 
15669  appendPQExpBufferStr(query,
15670  "SELECT label, provider, classoid, objoid, objsubid "
15671  "FROM pg_catalog.pg_seclabel "
15672  "ORDER BY classoid, objoid, objsubid");
15673 
15674  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15675 
15676  /* Construct lookup table containing OIDs in numeric form */
15677  i_label = PQfnumber(res, "label");
15678  i_provider = PQfnumber(res, "provider");
15679  i_classoid = PQfnumber(res, "classoid");
15680  i_objoid = PQfnumber(res, "objoid");
15681  i_objsubid = PQfnumber(res, "objsubid");
15682 
15683  ntups = PQntuples(res);
15684 
15685  seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
15686  nseclabels = 0;
15687  dobj = NULL;
15688 
15689  for (i = 0; i < ntups; i++)
15690  {
15691  CatalogId objId;
15692  int subid;
15693 
15694  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
15695  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
15696  subid = atoi(PQgetvalue(res, i, i_objsubid));
15697 
15698  /* We needn't remember labels that don't match any dumpable object */
15699  if (dobj == NULL ||
15700  dobj->catId.tableoid != objId.tableoid ||
15701  dobj->catId.oid != objId.oid)
15702  dobj = findObjectByCatalogId(objId);
15703  if (dobj == NULL)
15704  continue;
15705 
15706  /*
15707  * Labels on columns of composite types are linked to the type's
15708  * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
15709  * in the type's own DumpableObject.
15710  */
15711  if (subid != 0 && dobj->objType == DO_TABLE &&
15712  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
15713  {
15714  TypeInfo *cTypeInfo;
15715 
15716  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
15717  if (cTypeInfo)
15718  cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
15719  }
15720  else
15721  dobj->components |= DUMP_COMPONENT_SECLABEL;
15722 
15726  seclabels[nseclabels].objoid = objId.oid;
15727  seclabels[nseclabels].objsubid = subid;
15728  nseclabels++;
15729  }
15730 
15731  PQclear(res);
15732  destroyPQExpBuffer(query);
15733 }
static int nseclabels
Definition: pg_dump.c:158
static SecLabelItem * seclabels
Definition: pg_dump.c:157
#define DUMP_COMPONENT_SECLABEL
Definition: pg_dump.h:100
const char * provider
Definition: pg_dump.c:88
Oid classoid
Definition: pg_dump.c:90
int objsubid
Definition: pg_dump.c:92
const char * label
Definition: pg_dump.c:89
Oid objoid
Definition: pg_dump.c:91

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().

◆ convertRegProcReference()

static char * convertRegProcReference ( const char *  proc)
static

Definition at line 13204 of file pg_dump.c.

13205 {
13206  char *name;
13207  char *paren;
13208  bool inquote;
13209 
13210  /* In all cases "-" means a null reference */
13211  if (strcmp(proc, "-") == 0)
13212  return NULL;
13213 
13214  name = pg_strdup(proc);
13215  /* find non-double-quoted left paren */
13216  inquote = false;
13217  for (paren = name; *paren; paren++)
13218  {
13219  if (*paren == '(' && !inquote)
13220  {
13221  *paren = '\0';
13222  break;
13223  }
13224  if (*paren == '"')
13225  inquote = !inquote;
13226  }
13227  return name;
13228 }
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 13275 of file pg_dump.c.

13276 {
13277  char *result;
13278  char query[128];
13279  PGresult *res;
13280 
13281  snprintf(query, sizeof(query),
13282  "SELECT '%u'::pg_catalog.regproc", funcOid);
13283  res = ExecuteSqlQueryForSingleRow(fout, query);
13284 
13285  result = pg_strdup(PQgetvalue(res, 0, 0));
13286 
13287  PQclear(res);
13288 
13289  return result;
13290 }
#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 18674 of file pg_dump.c.

18675 {
18676  DumpableObject *dobjs;
18677 
18678  dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
18679 
18680  dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
18681  dobjs[0].catId = nilCatalogId;
18682  AssignDumpId(dobjs + 0);
18683  dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
18684 
18685  dobjs[1].objType = DO_POST_DATA_BOUNDARY;
18686  dobjs[1].catId = nilCatalogId;
18687  AssignDumpId(dobjs + 1);
18688  dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
18689 
18690  return dobjs;
18691 }
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:648
static const CatalogId nilCatalogId
Definition: pg_dump.c:142

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

15930 {
15931  PQExpBuffer result = createPQExpBuffer();
15932  int j;
15933 
15934  appendPQExpBufferStr(result, "SELECT");
15935 
15936  for (j = 0; j < tbinfo->numatts; j++)
15937  {
15938  if (j > 0)
15939  appendPQExpBufferChar(result, ',');
15940  appendPQExpBufferStr(result, "\n ");
15941 
15942  appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
15943 
15944  /*
15945  * Must add collation if not default for the type, because CREATE OR
15946  * REPLACE VIEW won't change it
15947  */
15948  if (OidIsValid(tbinfo->attcollation[j]))
15949  {
15950  CollInfo *coll;
15951 
15952  coll = findCollationByOid(tbinfo->attcollation[j]);
15953  if (coll)
15954  appendPQExpBuffer(result, " COLLATE %s",
15955  fmtQualifiedDumpable(coll));
15956  }
15957 
15958  appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
15959  }
15960 
15961  return result;
15962 }
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:945
int j
Definition: isn.c:74
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:176
int numatts
Definition: pg_dump.h:332
Oid * attcollation
Definition: pg_dump.h:345
char ** atttypnames
Definition: pg_dump.h:334
char ** attnames
Definition: pg_dump.h:333

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

15881 {
15882  PQExpBuffer query = createPQExpBuffer();
15883  PQExpBuffer result = createPQExpBuffer();
15884  PGresult *res;
15885  int len;
15886 
15887  /* Fetch the view definition */
15888  appendPQExpBuffer(query,
15889  "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
15890  tbinfo->dobj.catId.oid);
15891 
15892  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15893 
15894  if (PQntuples(res) != 1)
15895  {
15896  if (PQntuples(res) < 1)
15897  pg_fatal("query to obtain definition of view \"%s\" returned no data",
15898  tbinfo->dobj.name);
15899  else
15900  pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
15901  tbinfo->dobj.name);
15902  }
15903 
15904  len = PQgetlength(res, 0, 0);
15905 
15906  if (len == 0)
15907  pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
15908  tbinfo->dobj.name);
15909 
15910  /* Strip off the trailing semicolon so that other things may follow. */
15911  Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
15912  appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
15913 
15914  PQclear(res);
15915  destroyPQExpBuffer(query);
15916 
15917  return result;
15918 }
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:285

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

Referenced by dumpRule(), and dumpTableSchema().

◆ dumpAccessMethod()

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

Definition at line 13297 of file pg_dump.c.

13298 {
13299  DumpOptions *dopt = fout->dopt;
13300  PQExpBuffer q;
13301  PQExpBuffer delq;
13302  char *qamname;
13303 
13304  /* Do nothing in data-only dump */
13305  if (dopt->dataOnly)
13306  return;
13307 
13308  q = createPQExpBuffer();
13309  delq = createPQExpBuffer();
13310 
13311  qamname = pg_strdup(fmtId(aminfo->dobj.name));
13312 
13313  appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
13314 
13315  switch (aminfo->amtype)
13316  {
13317  case AMTYPE_INDEX:
13318  appendPQExpBufferStr(q, "TYPE INDEX ");
13319  break;
13320  case AMTYPE_TABLE:
13321  appendPQExpBufferStr(q, "TYPE TABLE ");
13322  break;
13323  default:
13324  pg_log_warning("invalid type \"%c\" of access method \"%s\"",
13325  aminfo->amtype, qamname);
13326  destroyPQExpBuffer(q);
13327  destroyPQExpBuffer(delq);
13328  free(qamname);
13329  return;
13330  }
13331 
13332  appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
13333 
13334  appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
13335  qamname);
13336 
13337  if (dopt->binary_upgrade)
13339  "ACCESS METHOD", qamname, NULL);
13340 
13341  if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13342  ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
13343  ARCHIVE_OPTS(.tag = aminfo->dobj.name,
13344  .description = "ACCESS METHOD",
13345  .section = SECTION_PRE_DATA,
13346  .createStmt = q->data,
13347  .dropStmt = delq->data));
13348 
13349  /* Dump Access Method Comments */
13350  if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13351  dumpComment(fout, "ACCESS METHOD", qamname,
13352  NULL, "",
13353  aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
13354 
13355  destroyPQExpBuffer(q);
13356  destroyPQExpBuffer(delq);
13357  free(qamname);
13358 }
@ 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:10321
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:5509
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:97
char * amhandler
Definition: pg_dump.h:253
DumpableObject dobj
Definition: pg_dump.h:251
bool dataOnly
Definition: pg_backup.h:170

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

15289 {
15290  DumpId aclDumpId = InvalidDumpId;
15291  DumpOptions *dopt = fout->dopt;
15292  const char *acls = dacl->acl;
15293  const char *acldefault = dacl->acldefault;
15294  char privtype = dacl->privtype;
15295  const char *initprivs = dacl->initprivs;
15296  const char *baseacls;
15297  PQExpBuffer sql;
15298 
15299  /* Do nothing if ACL dump is not enabled */
15300  if (dopt->aclsSkip)
15301  return InvalidDumpId;
15302 
15303  /* --data-only skips ACLs *except* large object ACLs */
15304  if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15305  return InvalidDumpId;
15306 
15307  sql = createPQExpBuffer();
15308 
15309  /*
15310  * In binary upgrade mode, we don't run an extension's script but instead
15311  * dump out the objects independently and then recreate them. To preserve
15312  * any initial privileges which were set on extension objects, we need to
15313  * compute the set of GRANT and REVOKE commands necessary to get from the
15314  * default privileges of an object to its initial privileges as recorded
15315  * in pg_init_privs.
15316  *
15317  * At restore time, we apply these commands after having called
15318  * binary_upgrade_set_record_init_privs(true). That tells the backend to
15319  * copy the results into pg_init_privs. This is how we preserve the
15320  * contents of that catalog across binary upgrades.
15321  */
15322  if (dopt->binary_upgrade && privtype == 'e' &&
15323  initprivs && *initprivs != '\0')
15324  {
15325  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
15326  if (!buildACLCommands(name, subname, nspname, type,
15327  initprivs, acldefault, owner,
15328  "", fout->remoteVersion, sql))
15329  pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
15330  initprivs, acldefault, name, type);
15331  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
15332  }
15333 
15334  /*
15335  * Now figure the GRANT and REVOKE commands needed to get to the object's
15336  * actual current ACL, starting from the initprivs if given, else from the
15337  * object-type-specific default. Also, while buildACLCommands will assume
15338  * that a NULL/empty acls string means it needn't do anything, what that
15339  * actually represents is the object-type-specific default; so we need to
15340  * substitute the acldefault string to get the right results in that case.
15341  */
15342  if (initprivs && *initprivs != '\0')
15343  {
15344  baseacls = initprivs;
15345  if (acls == NULL || *acls == '\0')
15346  acls = acldefault;
15347  }
15348  else
15349  baseacls = acldefault;
15350 
15351  if (!buildACLCommands(name, subname, nspname, type,
15352  acls, baseacls, owner,
15353  "", fout->remoteVersion, sql))
15354  pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
15355  acls, baseacls, name, type);
15356 
15357  if (sql->len > 0)
15358  {
15359  PQExpBuffer tagbuf = createPQExpBuffer();
15360  DumpId aclDeps[2];
15361  int nDeps = 0;
15362 
15363  if (tag)
15364  appendPQExpBufferStr(tagbuf, tag);
15365  else if (subname)
15366  appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
15367  else
15368  appendPQExpBuffer(tagbuf, "%s %s", type, name);
15369 
15370  aclDeps[nDeps++] = objDumpId;
15371  if (altDumpId != InvalidDumpId)
15372  aclDeps[nDeps++] = altDumpId;
15373 
15374  aclDumpId = createDumpId();
15375 
15376  ArchiveEntry(fout, nilCatalogId, aclDumpId,
15377  ARCHIVE_OPTS(.tag = tagbuf->data,
15378  .namespace = nspname,
15379  .owner = owner,
15380  .description = "ACL",
15381  .section = SECTION_NONE,
15382  .createStmt = sql->data,
15383  .deps = aclDeps,
15384  .nDeps = nDeps));
15385 
15386  destroyPQExpBuffer(tagbuf);
15387  }
15388 
15389  destroyPQExpBuffer(sql);
15390 
15391  return aclDumpId;
15392 }
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:786
DumpId createDumpId(void)
Definition: common.c:736
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:272
NameData subname
bool aclsSkip
Definition: pg_backup.h:172
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 14250 of file pg_dump.c.

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

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

16878 {
16879  DumpOptions *dopt = fout->dopt;
16880  TableInfo *tbinfo = adinfo->adtable;
16881  int adnum = adinfo->adnum;
16882  PQExpBuffer q;
16883  PQExpBuffer delq;
16884  char *qualrelname;
16885  char *tag;
16886  char *foreign;
16887 
16888  /* Do nothing in data-only dump */
16889  if (dopt->dataOnly)
16890  return;
16891 
16892  /* Skip if not "separate"; it was dumped in the table's definition */
16893  if (!adinfo->separate)
16894  return;
16895 
16896  q = createPQExpBuffer();
16897  delq = createPQExpBuffer();
16898 
16899  qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
16900 
16901  foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
16902 
16904  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
16905  foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
16906  adinfo->adef_expr);
16907 
16908  appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
16909  foreign, qualrelname,
16910  fmtId(tbinfo->attnames[adnum - 1]));
16911 
16912  tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
16913 
16914  if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16915  ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
16916  ARCHIVE_OPTS(.tag = tag,
16917  .namespace = tbinfo->dobj.namespace->dobj.name,
16918  .owner = tbinfo->rolname,
16919  .description = "DEFAULT",
16920  .section = SECTION_PRE_DATA,
16921  .createStmt = q->data,
16922  .dropStmt = delq->data));
16923 
16924  free(tag);
16925  destroyPQExpBuffer(q);
16926  destroyPQExpBuffer(delq);
16927  free(qualrelname);
16928 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
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:287

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

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

12752 {
12753  DumpOptions *dopt = fout->dopt;
12754  PQExpBuffer defqry;
12755  PQExpBuffer delqry;
12756  PQExpBuffer labelq;
12757  PQExpBuffer castargs;
12758  FuncInfo *funcInfo = NULL;
12759  const char *sourceType;
12760  const char *targetType;
12761 
12762  /* Do nothing in data-only dump */
12763  if (dopt->dataOnly)
12764  return;
12765 
12766  /* Cannot dump if we don't have the cast function's info */
12767  if (OidIsValid(cast->castfunc))
12768  {
12769  funcInfo = findFuncByOid(cast->castfunc);
12770  if (funcInfo == NULL)
12771  pg_fatal("could not find function definition for function with OID %u",
12772  cast->castfunc);
12773  }
12774 
12775  defqry = createPQExpBuffer();
12776  delqry = createPQExpBuffer();
12777  labelq = createPQExpBuffer();
12778  castargs = createPQExpBuffer();
12779 
12780  sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
12781  targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
12782  appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
12783  sourceType, targetType);
12784 
12785  appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
12786  sourceType, targetType);
12787 
12788  switch (cast->castmethod)
12789  {
12790  case COERCION_METHOD_BINARY:
12791  appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
12792  break;
12793  case COERCION_METHOD_INOUT:
12794  appendPQExpBufferStr(defqry, "WITH INOUT");
12795  break;
12796  case COERCION_METHOD_FUNCTION:
12797  if (funcInfo)
12798  {
12799  char *fsig = format_function_signature(fout, funcInfo, true);
12800 
12801  /*
12802  * Always qualify the function name (format_function_signature
12803  * won't qualify it).
12804  */
12805  appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
12806  fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
12807  free(fsig);
12808  }
12809  else
12810  pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
12811  break;
12812  default:
12813  pg_log_warning("bogus value in pg_cast.castmethod field");
12814  }
12815 
12816  if (cast->castcontext == 'a')
12817  appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
12818  else if (cast->castcontext == 'i')
12819  appendPQExpBufferStr(defqry, " AS IMPLICIT");
12820  appendPQExpBufferStr(defqry, ";\n");
12821 
12822  appendPQExpBuffer(labelq, "CAST (%s AS %s)",
12823  sourceType, targetType);
12824 
12825  appendPQExpBuffer(castargs, "(%s AS %s)",
12826  sourceType, targetType);
12827 
12828  if (dopt->binary_upgrade)
12829  binary_upgrade_extension_member(defqry, &cast->dobj,
12830  "CAST", castargs->data, NULL);
12831 
12832  if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
12833  ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
12834  ARCHIVE_OPTS(.tag = labelq->data,
12835  .description = "CAST",
12836  .section = SECTION_PRE_DATA,
12837  .createStmt = defqry->data,
12838  .dropStmt = delqry->data));
12839 
12840  /* Dump Cast Comments */
12841  if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
12842  dumpComment(fout, "CAST", castargs->data,
12843  NULL, "",
12844  cast->dobj.catId, 0, cast->dobj.dumpId);
12845 
12846  destroyPQExpBuffer(defqry);
12847  destroyPQExpBuffer(delqry);
12848  destroyPQExpBuffer(labelq);
12849  destroyPQExpBuffer(castargs);
12850 }
FuncInfo * findFuncByOid(Oid oid)
Definition: common.c:909
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:224

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

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

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

10325 {
10326  dumpCommentExtended(fout, type, name, namespace, owner,
10327  catalogId, subid, dumpId, NULL);
10328 }
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:10221

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

10226 {
10227  DumpOptions *dopt = fout->dopt;
10229  int ncomments;
10230 
10231  /* do nothing, if --no-comments is supplied */
10232  if (dopt->no_comments)
10233  return;
10234 
10235  /* Comments are schema not data ... except LO comments are data */
10236  if (strcmp(type, "LARGE OBJECT") != 0)
10237  {
10238  if (dopt->dataOnly)
10239  return;
10240  }
10241  else
10242  {
10243  /* We do dump LO comments in binary-upgrade mode */
10244  if (dopt->schemaOnly && !dopt->binary_upgrade)
10245  return;
10246  }
10247 
10248  /* Search for comments associated with catalogId, using table */
10249  ncomments = findComments(catalogId.tableoid, catalogId.oid,
10250  &comments);
10251 
10252  /* Is there one matching the subid? */
10253  while (ncomments > 0)
10254  {
10255  if (comments->objsubid == subid)
10256  break;
10257  comments++;
10258  ncomments--;
10259  }
10260 
10261  if (initdb_comment != NULL)
10262  {
10263  static CommentItem empty_comment = {.descr = ""};
10264 
10265  /*
10266  * initdb creates this object with a comment. Skip dumping the
10267  * initdb-provided comment, which would complicate matters for
10268  * non-superuser use of pg_dump. When the DBA has removed initdb's
10269  * comment, replicate that.
10270  */
10271  if (ncomments == 0)
10272  {
10273  comments = &empty_comment;
10274  ncomments = 1;
10275  }
10276  else if (strcmp(comments->descr, initdb_comment) == 0)
10277  ncomments = 0;
10278  }
10279 
10280  /* If a comment exists, build COMMENT ON statement */
10281  if (ncomments > 0)
10282  {
10283  PQExpBuffer query = createPQExpBuffer();
10285 
10286  appendPQExpBuffer(query, "COMMENT ON %s ", type);
10287  if (namespace && *namespace)
10288  appendPQExpBuffer(query, "%s.", fmtId(namespace));
10289  appendPQExpBuffer(query, "%s IS ", name);
10290  appendStringLiteralAH(query, comments->descr, fout);
10291  appendPQExpBufferStr(query, ";\n");
10292 
10293  appendPQExpBuffer(tag, "%s %s", type, name);
10294 
10295  /*
10296  * We mark comments as SECTION_NONE because they really belong in the
10297  * same section as their parent, whether that is pre-data or
10298  * post-data.
10299  */
10301  ARCHIVE_OPTS(.tag = tag->data,
10302  .namespace = namespace,
10303  .owner = owner,
10304  .description = "COMMENT",
10305  .section = SECTION_NONE,
10306  .createStmt = query->data,
10307  .deps = &dumpId,
10308  .nDeps = 1));
10309 
10310  destroyPQExpBuffer(query);
10311  destroyPQExpBuffer(tag);
10312  }
10313 }
static int findComments(Oid classoid, Oid objoid, CommentItem **items)
Definition: pg_dump.c:10435
int no_comments
Definition: pg_backup.h:180
bool schemaOnly
Definition: pg_backup.h:169

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

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

12018 {
12020  int ncomments;
12021  PQExpBuffer query;
12022  PQExpBuffer target;
12023  int i;
12024  int ntups;
12025  int i_attname;
12026  int i_attnum;
12027  int i_attisdropped;
12028 
12029  /* do nothing, if --no-comments is supplied */
12030  if (fout->dopt->no_comments)
12031  return;
12032 
12033  /* Search for comments associated with type's pg_class OID */
12034  ncomments = findComments(RelationRelationId, tyinfo->typrelid,
12035  &comments);
12036 
12037  /* If no comments exist, we're done */
12038  if (ncomments <= 0)
12039  return;
12040 
12041  /* Build COMMENT ON statements */
12042  query = createPQExpBuffer();
12043  target = createPQExpBuffer();
12044 
12045  ntups = PQntuples(res);
12046  i_attnum = PQfnumber(res, "attnum");
12047  i_attname = PQfnumber(res, "attname");
12048  i_attisdropped = PQfnumber(res, "attisdropped");
12049  while (ncomments > 0)
12050  {
12051  const char *attname;
12052 
12053  attname = NULL;
12054  for (i = 0; i < ntups; i++)
12055  {
12056  if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
12057  PQgetvalue(res, i, i_attisdropped)[0] != 't')
12058  {
12059  attname = PQgetvalue(res, i, i_attname);
12060  break;
12061  }
12062  }
12063  if (attname) /* just in case we don't find it */
12064  {
12065  const char *descr = comments->descr;
12066 
12067  resetPQExpBuffer(target);
12068  appendPQExpBuffer(target, "COLUMN %s.",
12069  fmtId(tyinfo->dobj.name));
12071 
12072  resetPQExpBuffer(query);
12073  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
12074  fmtQualifiedDumpable(tyinfo));
12075  appendPQExpBuffer(query, "%s IS ", fmtId(attname));
12076  appendStringLiteralAH(query, descr, fout);
12077  appendPQExpBufferStr(query, ";\n");
12078 
12080  ARCHIVE_OPTS(.tag = target->data,
12081  .namespace = tyinfo->dobj.namespace->dobj.name,
12082  .owner = tyinfo->rolname,
12083  .description = "COMMENT",
12084  .section = SECTION_NONE,
12085  .createStmt = query->data,
12086  .deps = &(tyinfo->dobj.dumpId),
12087  .nDeps = 1));
12088  }
12089 
12090  comments++;
12091  ncomments--;
12092  }
12093 
12094  destroyPQExpBuffer(query);
12095  destroyPQExpBuffer(target);
12096 }
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 17224 of file pg_dump.c.

17225 {
17226  DumpOptions *dopt = fout->dopt;
17227  TableInfo *tbinfo = coninfo->contable;
17228  PQExpBuffer q;
17229  PQExpBuffer delq;
17230  char *tag = NULL;
17231  char *foreign;
17232 
17233  /* Do nothing in data-only dump */
17234  if (dopt->dataOnly)
17235  return;
17236 
17237  q = createPQExpBuffer();
17238  delq = createPQExpBuffer();
17239 
17240  foreign = tbinfo &&
17241  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
17242 
17243  if (coninfo->contype == 'p' ||
17244  coninfo->contype == 'u' ||
17245  coninfo->contype == 'x')
17246  {
17247  /* Index-related constraint */
17248  IndxInfo *indxinfo;
17249  int k;
17250 
17251  indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
17252 
17253  if (indxinfo == NULL)
17254  pg_fatal("missing index for constraint \"%s\"",
17255  coninfo->dobj.name);
17256 
17257  if (dopt->binary_upgrade)
17259  indxinfo->dobj.catId.oid, true);
17260 
17261  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
17262  fmtQualifiedDumpable(tbinfo));
17263  appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
17264  fmtId(coninfo->dobj.name));
17265 
17266  if (coninfo->condef)
17267  {
17268  /* pg_get_constraintdef should have provided everything */
17269  appendPQExpBuffer(q, "%s;\n", coninfo->condef);
17270  }
17271  else
17272  {
17274  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
17275 
17276  /*
17277  * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
17278  * indexes. Being able to create this was fixed, but we need to
17279  * make the index distinct in order to be able to restore the
17280  * dump.
17281  */
17282  if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
17283  appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
17284  appendPQExpBufferStr(q, " (");
17285  for (k = 0; k < indxinfo->indnkeyattrs; k++)
17286  {
17287  int indkey = (int) indxinfo->indkeys[k];
17288  const char *attname;
17289 
17290  if (indkey == InvalidAttrNumber)
17291  break;
17292  attname = getAttrName(indkey, tbinfo);
17293 
17294  appendPQExpBuffer(q, "%s%s",
17295  (k == 0) ? "" : ", ",
17296  fmtId(attname));
17297  }
17298  if (coninfo->conperiod)
17299  appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
17300 
17301  if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
17302  appendPQExpBufferStr(q, ") INCLUDE (");
17303 
17304  for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
17305  {
17306  int indkey = (int) indxinfo->indkeys[k];
17307  const char *attname;
17308 
17309  if (indkey == InvalidAttrNumber)
17310  break;
17311  attname = getAttrName(indkey, tbinfo);
17312 
17313  appendPQExpBuffer(q, "%s%s",
17314  (k == indxinfo->indnkeyattrs) ? "" : ", ",
17315  fmtId(attname));
17316  }
17317 
17318  appendPQExpBufferChar(q, ')');
17319 
17320  if (nonemptyReloptions(indxinfo->indreloptions))
17321  {
17322  appendPQExpBufferStr(q, " WITH (");
17323  appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
17324  appendPQExpBufferChar(q, ')');
17325  }
17326 
17327  if (coninfo->condeferrable)
17328  {
17329  appendPQExpBufferStr(q, " DEFERRABLE");
17330  if (coninfo->condeferred)
17331  appendPQExpBufferStr(q, " INITIALLY DEFERRED");
17332  }
17333 
17334  appendPQExpBufferStr(q, ";\n");
17335  }
17336 
17337  /*
17338  * Append ALTER TABLE commands as needed to set properties that we
17339  * only have ALTER TABLE syntax for. Keep this in sync with the
17340  * similar code in dumpIndex!
17341  */
17342 
17343  /*
17344  * Drop any not-null constraints that were added to support the PK,
17345  * but leave them alone if they have a definition coming from their
17346  * parent.
17347  */
17348  if (coninfo->contype == 'p')
17349  for (int i = 0; i < tbinfo->numatts; i++)
17350  if (tbinfo->notnull_throwaway[i] &&
17351  !tbinfo->notnull_inh[i])
17352  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s DROP CONSTRAINT %s;",
17353  fmtQualifiedDumpable(tbinfo),
17354  tbinfo->notnull_constrs[i]);
17355 
17356  /* If the index is clustered, we need to record that. */
17357  if (indxinfo->indisclustered)
17358  {
17359  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17360  fmtQualifiedDumpable(tbinfo));
17361  /* index name is not qualified in this syntax */
17362  appendPQExpBuffer(q, " ON %s;\n",
17363  fmtId(indxinfo->dobj.name));
17364  }
17365 
17366  /* If the index defines identity, we need to record that. */
17367  if (indxinfo->indisreplident)
17368  {
17369  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17370  fmtQualifiedDumpable(tbinfo));
17371  /* index name is not qualified in this syntax */
17372  appendPQExpBuffer(q, " INDEX %s;\n",
17373  fmtId(indxinfo->dobj.name));
17374  }
17375 
17376  /* Indexes can depend on extensions */
17377  append_depends_on_extension(fout, q, &indxinfo->dobj,
17378  "pg_catalog.pg_class", "INDEX",
17379  fmtQualifiedDumpable(indxinfo));
17380 
17381  appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
17382  fmtQualifiedDumpable(tbinfo));
17383  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17384  fmtId(coninfo->dobj.name));
17385 
17386  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17387 
17388  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17389  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17390  ARCHIVE_OPTS(.tag = tag,
17391  .namespace = tbinfo->dobj.namespace->dobj.name,
17392  .tablespace = indxinfo->tablespace,
17393  .owner = tbinfo->rolname,
17394  .description = "CONSTRAINT",
17395  .section = SECTION_POST_DATA,
17396  .createStmt = q->data,
17397  .dropStmt = delq->data));
17398  }
17399  else if (coninfo->contype == 'f')
17400  {
17401  char *only;
17402 
17403  /*
17404  * Foreign keys on partitioned tables are always declared as
17405  * inheriting to partitions; for all other cases, emit them as
17406  * applying ONLY directly to the named table, because that's how they
17407  * work for regular inherited tables.
17408  */
17409  only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
17410 
17411  /*
17412  * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
17413  * current table data is not processed
17414  */
17415  appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
17416  only, fmtQualifiedDumpable(tbinfo));
17417  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17418  fmtId(coninfo->dobj.name),
17419  coninfo->condef);
17420 
17421  appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
17422  only, fmtQualifiedDumpable(tbinfo));
17423  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17424  fmtId(coninfo->dobj.name));
17425 
17426  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17427 
17428  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17429  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17430  ARCHIVE_OPTS(.tag = tag,
17431  .namespace = tbinfo->dobj.namespace->dobj.name,
17432  .owner = tbinfo->rolname,
17433  .description = "FK CONSTRAINT",
17434  .section = SECTION_POST_DATA,
17435  .createStmt = q->data,
17436  .dropStmt = delq->data));
17437  }
17438  else if (coninfo->contype == 'c' && tbinfo)
17439  {
17440  /* CHECK constraint on a table */
17441 
17442  /* Ignore if not to be dumped separately, or if it was inherited */
17443  if (coninfo->separate && coninfo->conislocal)
17444  {
17445  /* not ONLY since we want it to propagate to children */
17446  appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
17447  fmtQualifiedDumpable(tbinfo));
17448  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17449  fmtId(coninfo->dobj.name),
17450  coninfo->condef);
17451 
17452  appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
17453  fmtQualifiedDumpable(tbinfo));
17454  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17455  fmtId(coninfo->dobj.name));
17456 
17457  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17458 
17459  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17460  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17461  ARCHIVE_OPTS(.tag = tag,
17462  .namespace = tbinfo->dobj.namespace->dobj.name,
17463  .owner = tbinfo->rolname,
17464  .description = "CHECK CONSTRAINT",
17465  .section = SECTION_POST_DATA,
17466  .createStmt = q->data,
17467  .dropStmt = delq->data));
17468  }
17469  }
17470  else if (coninfo->contype == 'c' && tbinfo == NULL)
17471  {
17472  /* CHECK constraint on a domain */
17473  TypeInfo *tyinfo = coninfo->condomain;
17474 
17475  /* Ignore if not to be dumped separately */
17476  if (coninfo->separate)
17477  {
17478  appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
17479  fmtQualifiedDumpable(tyinfo));
17480  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17481  fmtId(coninfo->dobj.name),
17482  coninfo->condef);
17483 
17484  appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
17485  fmtQualifiedDumpable(tyinfo));
17486  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17487  fmtId(coninfo->dobj.name));
17488 
17489  tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
17490 
17491  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17492  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17493  ARCHIVE_OPTS(.tag = tag,
17494  .namespace = tyinfo->dobj.namespace->dobj.name,
17495  .owner = tyinfo->rolname,
17496  .description = "CHECK CONSTRAINT",
17497  .section = SECTION_POST_DATA,
17498  .createStmt = q->data,
17499  .dropStmt = delq->data));
17500  }
17501  }
17502  else
17503  {
17504  pg_fatal("unrecognized constraint type: %c",
17505  coninfo->contype);
17506  }
17507 
17508  /* Dump Constraint Comments --- only works for table constraints */
17509  if (tbinfo && coninfo->separate &&
17510  coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17511  dumpTableConstraintComment(fout, coninfo);
17512 
17513  free(tag);
17514  destroyPQExpBuffer(q);
17515  destroyPQExpBuffer(delq);
17516 }
#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:5220
static const char * getAttrName(int attrnum, const TableInfo *tblInfo)
Definition: pg_dump.c:16938
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
Definition: pg_dump.c:19015
static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:17526
static bool nonemptyReloptions(const char *reloptions)
Definition: pg_dump.c:19003
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
char ** notnull_constrs
Definition: pg_dump.h:349
bool * notnull_throwaway
Definition: pg_dump.h:354
bool * notnull_inh
Definition: pg_dump.h:355

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(), i, if(), _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indkeys, _indxInfo::indnattrs, _indxInfo::indnkeyattrs, _indxInfo::indnullsnotdistinct, _indxInfo::indreloptions, InvalidAttrNumber, _dumpableObject::name, nonemptyReloptions(), _tableInfo::notnull_constrs, _tableInfo::notnull_inh, _tableInfo::notnull_throwaway, _tableInfo::numatts, 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 14122 of file pg_dump.c.

14123 {
14124  DumpOptions *dopt = fout->dopt;
14125  PQExpBuffer query;
14126  PQExpBuffer q;
14127  PQExpBuffer delq;
14128  char *qconvname;
14129  PGresult *res;
14130  int i_conforencoding;
14131  int i_contoencoding;
14132  int i_conproc;
14133  int i_condefault;
14134  const char *conforencoding;
14135  const char *contoencoding;
14136  const char *conproc;
14137  bool condefault;
14138 
14139  /* Do nothing in data-only dump */
14140  if (dopt->dataOnly)
14141  return;
14142 
14143  query = createPQExpBuffer();
14144  q = createPQExpBuffer();
14145  delq = createPQExpBuffer();
14146 
14147  qconvname = pg_strdup(fmtId(convinfo->dobj.name));
14148 
14149  /* Get conversion-specific details */
14150  appendPQExpBuffer(query, "SELECT "
14151  "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
14152  "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
14153  "conproc, condefault "
14154  "FROM pg_catalog.pg_conversion c "
14155  "WHERE c.oid = '%u'::pg_catalog.oid",
14156  convinfo->dobj.catId.oid);
14157 
14158  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14159 
14160  i_conforencoding = PQfnumber(res, "conforencoding");
14161  i_contoencoding = PQfnumber(res, "contoencoding");
14162  i_conproc = PQfnumber(res, "conproc");
14163  i_condefault = PQfnumber(res, "condefault");
14164 
14165  conforencoding = PQgetvalue(res, 0, i_conforencoding);
14166  contoencoding = PQgetvalue(res, 0, i_contoencoding);
14167  conproc = PQgetvalue(res, 0, i_conproc);
14168  condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
14169 
14170  appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
14171  fmtQualifiedDumpable(convinfo));
14172 
14173  appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
14174  (condefault) ? "DEFAULT " : "",
14175  fmtQualifiedDumpable(convinfo));
14176  appendStringLiteralAH(q, conforencoding, fout);
14177  appendPQExpBufferStr(q, " TO ");
14178  appendStringLiteralAH(q, contoencoding, fout);
14179  /* regproc output is already sufficiently quoted */
14180  appendPQExpBuffer(q, " FROM %s;\n", conproc);
14181 
14182  if (dopt->binary_upgrade)
14183  binary_upgrade_extension_member(q, &convinfo->dobj,
14184  "CONVERSION", qconvname,
14185  convinfo->dobj.namespace->dobj.name);
14186 
14187  if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14188  ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
14189  ARCHIVE_OPTS(.tag = convinfo->dobj.name,
14190  .namespace = convinfo->dobj.namespace->dobj.name,
14191  .owner = convinfo->rolname,
14192  .description = "CONVERSION",
14193  .section = SECTION_PRE_DATA,
14194  .createStmt = q->data,
14195  .dropStmt = delq->data));
14196 
14197  /* Dump Conversion Comments */
14198  if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14199  dumpComment(fout, "CONVERSION", qconvname,
14200  convinfo->dobj.namespace->dobj.name, convinfo->rolname,
14201  convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
14202 
14203  PQclear(res);
14204 
14205  destroyPQExpBuffer(query);
14206  destroyPQExpBuffer(q);
14207  destroyPQExpBuffer(delq);
14208  free(qconvname);
14209 }
DumpableObject dobj
Definition: pg_dump.h:276
const char * rolname
Definition: pg_dump.h:277

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

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

3465 {
3466  PGconn *conn = GetConnection(AH);
3468  PGresult *res;
3469 
3470  /* First collect database-specific options */
3471  printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
3472  "WHERE setrole = 0 AND setdatabase = '%u'::oid",
3473  dboid);
3474 
3475  res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3476 
3477  for (int i = 0; i < PQntuples(res); i++)
3479  "DATABASE", dbname, NULL, NULL,
3480  outbuf);
3481 
3482  PQclear(res);
3483 
3484  /* Now look for role-and-database-specific options */
3485  printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
3486  "FROM pg_db_role_setting s, pg_roles r "
3487  "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
3488  dboid);
3489 
3490  res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3491 
3492  for (int i = 0; i < PQntuples(res); i++)
3494  "ROLE", PQgetvalue(res, i, 0),
3495  "DATABASE", dbname,
3496  outbuf);
3497 
3498  PQclear(res);
3499 
3501 }
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:73
char * dbname
Definition: streamutil.c:52

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

15197 {
15198  DumpOptions *dopt = fout->dopt;
15199  PQExpBuffer q;
15200  PQExpBuffer tag;
15201  const char *type;
15202 
15203  /* Do nothing in data-only dump, or if we're skipping ACLs */
15204  if (dopt->dataOnly || dopt->aclsSkip)
15205  return;
15206 
15207  q = createPQExpBuffer();
15208  tag = createPQExpBuffer();
15209 
15210  switch (daclinfo->defaclobjtype)
15211  {
15212  case DEFACLOBJ_RELATION:
15213  type = "TABLES";
15214  break;
15215  case DEFACLOBJ_SEQUENCE:
15216  type = "SEQUENCES";
15217  break;
15218  case DEFACLOBJ_FUNCTION:
15219  type = "FUNCTIONS";
15220  break;
15221  case DEFACLOBJ_TYPE:
15222  type = "TYPES";
15223  break;
15224  case DEFACLOBJ_NAMESPACE:
15225  type = "SCHEMAS";
15226  break;
15227  default:
15228  /* shouldn't get here */
15229  pg_fatal("unrecognized object type in default privileges: %d",
15230  (int) daclinfo->defaclobjtype);
15231  type = ""; /* keep compiler quiet */
15232  }
15233 
15234  appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
15235 
15236  /* build the actual command(s) for this tuple */
15238  daclinfo->dobj.namespace != NULL ?
15239  daclinfo->dobj.namespace->dobj.name : NULL,
15240  daclinfo->dacl.acl,
15241  daclinfo->dacl.acldefault,
15242  daclinfo->defaclrole,
15243  fout->remoteVersion,
15244  q))
15245  pg_fatal("could not parse default ACL list (%s)",
15246  daclinfo->dacl.acl);
15247 
15248  if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
15249  ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
15250  ARCHIVE_OPTS(.tag = tag->data,
15251  .namespace = daclinfo->dobj.namespace ?
15252  daclinfo->dobj.namespace->dobj.name : NULL,
15253  .owner = daclinfo->defaclrole,
15254  .description = "DEFAULT ACL",
15255  .section = SECTION_POST_DATA,
15256  .createStmt = q->data));
15257 
15258  destroyPQExpBuffer(tag);
15259  destroyPQExpBuffer(q);
15260 }
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 11637 of file pg_dump.c.

11638 {
11639  DumpOptions *dopt = fout->dopt;
11641  PQExpBuffer delq = createPQExpBuffer();
11642  PQExpBuffer query = createPQExpBuffer();
11643  PGresult *res;
11644  int i;
11645  char *qtypname;
11646  char *qualtypname;
11647  char *typnotnull;
11648  char *typdefn;
11649  char *typdefault;
11650  Oid typcollation;
11651  bool typdefault_is_literal = false;
11652 
11653  if (!fout->is_prepared[PREPQUERY_DUMPDOMAIN])
11654  {
11655  /* Set up query for domain-specific details */
11656  appendPQExpBufferStr(query,
11657  "PREPARE dumpDomain(pg_catalog.oid) AS\n");
11658 
11659  appendPQExpBufferStr(query, "SELECT t.typnotnull, "
11660  "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
11661  "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
11662  "t.typdefault, "
11663  "CASE WHEN t.typcollation <> u.typcollation "
11664  "THEN t.typcollation ELSE 0 END AS typcollation "
11665  "FROM pg_catalog.pg_type t "
11666  "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
11667  "WHERE t.oid = $1");
11668 
11669  ExecuteSqlStatement(fout, query->data);
11670 
11671  fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
11672  }
11673 
11674  printfPQExpBuffer(query,
11675  "EXECUTE dumpDomain('%u')",
11676  tyinfo->dobj.catId.oid);
11677 
11678  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11679 
11680  typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
11681  typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
11682  if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
11683  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
11684  else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
11685  {
11686  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
11687  typdefault_is_literal = true; /* it needs quotes */
11688  }
11689  else
11690  typdefault = NULL;
11691  typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
11692 
11693  if (dopt->binary_upgrade)
11695  tyinfo->dobj.catId.oid,
11696  true, /* force array type */
11697  false); /* force multirange type */
11698 
11699  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11700  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11701 
11703  "CREATE DOMAIN %s AS %s",
11704  qualtypname,
11705  typdefn);
11706 
11707  /* Print collation only if different from base type's collation */
11708  if (OidIsValid(typcollation))
11709  {
11710  CollInfo *coll;
11711 
11712  coll = findCollationByOid(typcollation);
11713  if (coll)
11714  appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
11715  }
11716 
11717  if (typnotnull[0] == 't')
11718  appendPQExpBufferStr(q, " NOT NULL");
11719 
11720  if (typdefault != NULL)
11721  {
11722  appendPQExpBufferStr(q, " DEFAULT ");
11723  if (typdefault_is_literal)
11724  appendStringLiteralAH(q, typdefault, fout);
11725  else
11726  appendPQExpBufferStr(q, typdefault);
11727  }
11728 
11729  PQclear(res);
11730 
11731  /*
11732  * Add any CHECK constraints for the domain
11733  */
11734  for (i = 0; i < tyinfo->nDomChecks; i++)
11735  {
11736  ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
11737 
11738  if (!domcheck->separate)
11739  appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
11740  fmtId(domcheck->dobj.name), domcheck->condef);
11741  }
11742 
11743  appendPQExpBufferStr(q, ";\n");
11744 
11745  appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
11746 
11747  if (dopt->binary_upgrade)
11749  "DOMAIN", qtypname,
11750  tyinfo->dobj.namespace->dobj.name);
11751 
11752  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11753  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11754  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11755  .namespace = tyinfo->dobj.namespace->dobj.name,
11756  .owner = tyinfo->rolname,
11757  .description = "DOMAIN",
11758  .section = SECTION_PRE_DATA,
11759  .createStmt = q->data,
11760  .dropStmt = delq->data));
11761 
11762  /* Dump Domain Comments and Security Labels */
11763  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11764  dumpComment(fout, "DOMAIN", qtypname,
11765  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11766  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11767 
11768  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11769  dumpSecLabel(fout, "DOMAIN", qtypname,
11770  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11771  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11772 
11773  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11774  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11775  qtypname, NULL,
11776  tyinfo->dobj.namespace->dobj.name,
11777  NULL, tyinfo->rolname, &tyinfo->dacl);
11778 
11779  /* Dump any per-constraint comments */
11780  for (i = 0; i < tyinfo->nDomChecks; i++)
11781  {
11782  ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
11783  PQExpBuffer conprefix = createPQExpBuffer();
11784 
11785  appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
11786  fmtId(domcheck->dobj.name));
11787 
11788  if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
11789  dumpComment(fout, conprefix->data, qtypname,
11790  tyinfo->dobj.namespace->dobj.name,
11791  tyinfo->rolname,
11792  domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
11793 
11794  destroyPQExpBuffer(conprefix);
11795  }
11796 
11797  destroyPQExpBuffer(q);
11798  destroyPQExpBuffer(delq);
11799  destroyPQExpBuffer(query);
11800  free(qtypname);
11801  free(qualtypname);
11802 }
@ PREPQUERY_DUMPDOMAIN
Definition: pg_backup.h:69
struct _constraintInfo * domChecks
Definition: pg_dump.h:212
int nDomChecks
Definition: pg_dump.h:211

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

10598 {
10599  /*
10600  * Clear any dump-request bits for components that don't exist for this
10601  * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
10602  * request for every kind of object.)
10603  */
10604  dobj->dump &= dobj->components;
10605 
10606  /* Now, short-circuit if there's nothing to be done here. */
10607  if (dobj->dump == 0)
10608  return;
10609 
10610  switch (dobj->objType)
10611  {
10612  case DO_NAMESPACE:
10613  dumpNamespace(fout, (const NamespaceInfo *) dobj);
10614  break;
10615  case DO_EXTENSION:
10616  dumpExtension(fout, (const ExtensionInfo *) dobj);
10617  break;
10618  case DO_TYPE:
10619  dumpType(fout, (const TypeInfo *) dobj);
10620  break;
10621  case DO_SHELL_TYPE:
10622  dumpShellType(fout, (const ShellTypeInfo *) dobj);
10623  break;
10624  case DO_FUNC:
10625  dumpFunc(fout, (const FuncInfo *) dobj);
10626  break;
10627  case DO_AGG:
10628  dumpAgg(fout, (const AggInfo *) dobj);
10629  break;
10630  case DO_OPERATOR:
10631  dumpOpr(fout, (const OprInfo *) dobj);
10632  break;
10633  case DO_ACCESS_METHOD:
10634  dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
10635  break;
10636  case DO_OPCLASS:
10637  dumpOpclass(fout, (const OpclassInfo *) dobj);
10638  break;
10639  case DO_OPFAMILY:
10640  dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
10641  break;
10642  case DO_COLLATION:
10643  dumpCollation(fout, (const CollInfo *) dobj);
10644  break;
10645  case DO_CONVERSION:
10646  dumpConversion(fout, (const ConvInfo *) dobj);
10647  break;
10648  case DO_TABLE:
10649  dumpTable(fout, (const TableInfo *) dobj);
10650  break;
10651  case DO_TABLE_ATTACH:
10652  dumpTableAttach(fout, (const TableAttachInfo *) dobj);
10653  break;
10654  case DO_ATTRDEF:
10655  dumpAttrDef(fout, (const AttrDefInfo *) dobj);
10656  break;
10657  case DO_INDEX:
10658  dumpIndex(fout, (const IndxInfo *) dobj);
10659  break;
10660  case DO_INDEX_ATTACH:
10661  dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
10662  break;
10663  case DO_STATSEXT:
10664  dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
10665  break;
10666  case DO_REFRESH_MATVIEW:
10667  refreshMatViewData(fout, (const TableDataInfo *) dobj);
10668  break;
10669  case DO_RULE:
10670  dumpRule(fout, (const RuleInfo *) dobj);
10671  break;
10672  case DO_TRIGGER:
10673  dumpTrigger(fout, (const TriggerInfo *) dobj);
10674  break;
10675  case DO_EVENT_TRIGGER:
10676  dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
10677  break;
10678  case DO_CONSTRAINT:
10679  dumpConstraint(fout, (const ConstraintInfo *) dobj);
10680  break;
10681  case DO_FK_CONSTRAINT:
10682  dumpConstraint(fout, (const ConstraintInfo *) dobj);
10683  break;
10684  case DO_PROCLANG:
10685  dumpProcLang(fout, (const ProcLangInfo *) dobj);
10686  break;
10687  case DO_CAST:
10688  dumpCast(fout, (const CastInfo *) dobj);
10689  break;
10690  case DO_TRANSFORM:
10691  dumpTransform(fout, (const TransformInfo *) dobj);
10692  break;
10693  case DO_SEQUENCE_SET:
10694  dumpSequenceData(fout, (const TableDataInfo *) dobj);
10695  break;
10696  case DO_TABLE_DATA:
10697  dumpTableData(fout, (const TableDataInfo *) dobj);
10698  break;
10699  case DO_DUMMY_TYPE:
10700  /* table rowtypes and array types are never dumped separately */
10701  break;
10702  case DO_TSPARSER:
10703  dumpTSParser(fout, (const TSParserInfo *) dobj);
10704  break;
10705  case DO_TSDICT:
10706  dumpTSDictionary(fout, (const TSDictInfo *) dobj);
10707  break;
10708  case DO_TSTEMPLATE:
10709  dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
10710  break;
10711  case DO_TSCONFIG:
10712  dumpTSConfig(fout, (const TSConfigInfo *) dobj);
10713  break;
10714  case DO_FDW:
10715  dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
10716  break;
10717  case DO_FOREIGN_SERVER:
10718  dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
10719  break;
10720  case DO_DEFAULT_ACL:
10721  dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
10722  break;
10723  case DO_LARGE_OBJECT:
10724  dumpLO(fout, (const LoInfo *) dobj);
10725  break;
10726  case DO_LARGE_OBJECT_DATA:
10727  if (dobj->dump & DUMP_COMPONENT_DATA)
10728  {
10729  LoInfo *loinfo;
10730  TocEntry *te;
10731 
10732  loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
10733  if (loinfo == NULL)
10734  pg_fatal("missing metadata for large objects \"%s\"",
10735  dobj->name);
10736 
10737  te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
10738  ARCHIVE_OPTS(.tag = dobj->name,
10739  .owner = loinfo->rolname,
10740  .description = "BLOBS",
10741  .section = SECTION_DATA,
10742  .deps = dobj->dependencies,
10743  .nDeps = dobj->nDeps,
10744  .dumpFn = dumpLOs,
10745  .dumpArg = loinfo));
10746 
10747  /*
10748  * Set the TocEntry's dataLength in case we are doing a
10749  * parallel dump and want to order dump jobs by table size.
10750  * (We need some size estimate for every TocEntry with a
10751  * DataDumper function.) We don't currently have any cheap
10752  * way to estimate the size of LOs, but fortunately it doesn't
10753  * matter too much as long as we get large batches of LOs
10754  * processed reasonably early. Assume 8K per blob.
10755  */
10756  te->dataLength = loinfo->numlos * (pgoff_t) 8192;
10757  }
10758  break;
10759  case DO_POLICY:
10760  dumpPolicy(fout, (const PolicyInfo *) dobj);
10761  break;
10762  case DO_PUBLICATION:
10763  dumpPublication(fout, (const PublicationInfo *) dobj);
10764  break;
10765  case DO_PUBLICATION_REL:
10766  dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
10767  break;
10770  (const PublicationSchemaInfo *) dobj);
10771  break;
10772  case DO_SUBSCRIPTION:
10773  dumpSubscription(fout, (const SubscriptionInfo *) dobj);
10774  break;
10775  case DO_SUBSCRIPTION_REL:
10776  dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
10777  break;
10778  case DO_PRE_DATA_BOUNDARY:
10779  case DO_POST_DATA_BOUNDARY:
10780  /* never dumped, nothing to do */
10781  break;
10782  }
10783 }
@ SECTION_DATA
Definition: pg_backup.h:59
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:16877
static void dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
Definition: pg_dump.c:4596
static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
Definition: pg_dump.c:10790
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:12751
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:16967
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:14674
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:14250
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:17869
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15740
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:17147
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:17224
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:10995
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:16809
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:13297
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:12985
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:17819
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:12335
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:15002
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2601
static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
Definition: pg_dump.c:12105
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2713
static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
Definition: pg_dump.c:4281
static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
Definition: pg_dump.c:4059
static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
Definition: pg_dump.c:13646
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:15196
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:14754
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:17108
static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
Definition: pg_dump.c:5004
static void dumpTransform(Archive *fout, const TransformInfo *transform)
Definition: pg_dump.c:12856
static void dumpLO(Archive *fout, const LoInfo *loinfo)
Definition: pg_dump.c:3756
static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
Definition: pg_dump.c:4639
static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
Definition: pg_dump.c:14610
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:18080
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:10867
static int dumpLOs(Archive *fout, const void *arg)
Definition: pg_dump.c:3846
static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
Definition: pg_dump.c:5073
static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
Definition: pg_dump.c:17995
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:14122
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:14932
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:12151
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:14812
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:13865
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:13365
#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 3507 of file pg_dump.c.

3508 {
3509  const char *encname = pg_encoding_to_char(AH->encoding);
3511 
3512  pg_log_info("saving encoding = %s", encname);
3513 
3514  appendPQExpBufferStr(qry, "SET client_encoding = ");
3515  appendStringLiteralAH(qry, encname, AH);
3516  appendPQExpBufferStr(qry, ";\n");
3517 
3519  ARCHIVE_OPTS(.tag = "ENCODING",
3520  .description = "ENCODING",
3521  .section = SECTION_PRE_DATA,
3522  .createStmt = qry->data));
3523 
3524  destroyPQExpBuffer(qry);
3525 }
#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 11026 of file pg_dump.c.

11027 {
11028  DumpOptions *dopt = fout->dopt;
11030  PQExpBuffer delq = createPQExpBuffer();
11031  PQExpBuffer query = createPQExpBuffer();
11032  PGresult *res;
11033  int num,
11034  i;
11035  Oid enum_oid;
11036  char *qtypname;
11037  char *qualtypname;
11038  char *label;
11039  int i_enumlabel;
11040  int i_oid;
11041 
11042  if (!fout->is_prepared[PREPQUERY_DUMPENUMTYPE])
11043  {
11044  /* Set up query for enum-specific details */
11045  appendPQExpBufferStr(query,
11046  "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
11047  "SELECT oid, enumlabel "
11048  "FROM pg_catalog.pg_enum "
11049  "WHERE enumtypid = $1 "
11050  "ORDER BY enumsortorder");
11051 
11052  ExecuteSqlStatement(fout, query->data);
11053 
11054  fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
11055  }
11056 
11057  printfPQExpBuffer(query,
11058  "EXECUTE dumpEnumType('%u')",
11059  tyinfo->dobj.catId.oid);
11060 
11061  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11062 
11063  num = PQntuples(res);
11064 
11065  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11066  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11067 
11068  /*
11069  * CASCADE shouldn't be required here as for normal types since the I/O
11070  * functions are generic and do not get dropped.
11071  */
11072  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11073 
11074  if (dopt->binary_upgrade)
11076  tyinfo->dobj.catId.oid,
11077  false, false);
11078 
11079  appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
11080  qualtypname);
11081 
11082  if (!dopt->binary_upgrade)
11083  {
11084  i_enumlabel = PQfnumber(res, "enumlabel");
11085 
11086  /* Labels with server-assigned oids */
11087  for (i = 0; i < num; i++)
11088  {
11089  label = PQgetvalue(res, i, i_enumlabel);
11090  if (i > 0)
11091  appendPQExpBufferChar(q, ',');
11092  appendPQExpBufferStr(q, "\n ");
11093  appendStringLiteralAH(q, label, fout);
11094  }
11095  }
11096 
11097  appendPQExpBufferStr(q, "\n);\n");
11098 
11099  if (dopt->binary_upgrade)
11100  {
11101  i_oid = PQfnumber(res, "oid");
11102  i_enumlabel = PQfnumber(res, "enumlabel");
11103 
11104  /* Labels with dump-assigned (preserved) oids */
11105  for (i = 0; i < num; i++)
11106  {
11107  enum_oid = atooid(PQgetvalue(res, i, i_oid));
11108  label = PQgetvalue(res, i, i_enumlabel);
11109 
11110  if (i == 0)
11111  appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
11113  "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
11114  enum_oid);
11115  appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
11116  appendStringLiteralAH(q, label, fout);
11117  appendPQExpBufferStr(q, ";\n\n");
11118  }
11119  }
11120 
11121  if (dopt->binary_upgrade)
11123  "TYPE", qtypname,
11124  tyinfo->dobj.namespace->dobj.name);
11125 
11126  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11127  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11128  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11129  .namespace = tyinfo->dobj.namespace->dobj.name,
11130  .owner = tyinfo->rolname,
11131  .description = "TYPE",
11132  .section = SECTION_PRE_DATA,
11133  .createStmt = q->data,
11134  .dropStmt = delq->data));
11135 
11136  /* Dump Type Comments and Security Labels */
11137  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11138  dumpComment(fout, "TYPE", qtypname,
11139  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11140  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11141 
11142  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11143  dumpSecLabel(fout, "TYPE", qtypname,
11144  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11145  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11146 
11147  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11148  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11149  qtypname, NULL,
11150  tyinfo->dobj.namespace->dobj.name,
11151  NULL, tyinfo->rolname, &tyinfo->dacl);
11152 
11153  PQclear(res);
11154  destroyPQExpBuffer(q);
11155  destroyPQExpBuffer(delq);
11156  destroyPQExpBuffer(query);
11157  free(qtypname);
11158  free(qualtypname);
11159 }
@ 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 17995 of file pg_dump.c.

17996 {
17997  DumpOptions *dopt = fout->dopt;
17998  PQExpBuffer query;
17999  PQExpBuffer delqry;
18000  char *qevtname;
18001 
18002  /* Do nothing in data-only dump */
18003  if (dopt->dataOnly)
18004  return;
18005 
18006  query = createPQExpBuffer();
18007  delqry = createPQExpBuffer();
18008 
18009  qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
18010 
18011  appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
18012  appendPQExpBufferStr(query, qevtname);
18013  appendPQExpBufferStr(query, " ON ");
18014  appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
18015 
18016  if (strcmp("", evtinfo->evttags) != 0)
18017  {
18018  appendPQExpBufferStr(query, "\n WHEN TAG IN (");
18019  appendPQExpBufferStr(query, evtinfo->evttags);
18020  appendPQExpBufferChar(query, ')');
18021  }
18022 
18023  appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
18024  appendPQExpBufferStr(query, evtinfo->evtfname);
18025  appendPQExpBufferStr(query, "();\n");
18026 
18027  if (evtinfo->evtenabled != 'O')
18028  {
18029  appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
18030  qevtname);
18031  switch (evtinfo->evtenabled)
18032  {
18033  case 'D':
18034  appendPQExpBufferStr(query, "DISABLE");
18035  break;
18036  case 'A':
18037  appendPQExpBufferStr(query, "ENABLE ALWAYS");
18038  break;
18039  case 'R':
18040  appendPQExpBufferStr(query, "ENABLE REPLICA");
18041  break;
18042  default:
18043  appendPQExpBufferStr(query, "ENABLE");
18044  break;
18045  }
18046  appendPQExpBufferStr(query, ";\n");
18047  }
18048 
18049  appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
18050  qevtname);
18051 
18052  if (dopt->binary_upgrade)
18053  binary_upgrade_extension_member(query, &evtinfo->dobj,
18054  "EVENT TRIGGER", qevtname, NULL);
18055 
18056  if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18057  ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
18058  ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
18059  .owner = evtinfo->evtowner,
18060  .description = "EVENT TRIGGER",
18061  .section = SECTION_POST_DATA,
18062  .createStmt = query->data,
18063  .dropStmt = delqry->data));
18064 
18065  if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18066  dumpComment(fout, "EVENT TRIGGER", qevtname,
18067  NULL, evtinfo->evtowner,
18068  evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
18069 
18070  destroyPQExpBuffer(query);
18071  destroyPQExpBuffer(delqry);
18072  free(qevtname);
18073 }
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 10867 of file pg_dump.c.

10868 {
10869  DumpOptions *dopt = fout->dopt;
10870  PQExpBuffer q;
10871  PQExpBuffer delq;
10872  char *qextname;
10873 
10874  /* Do nothing in data-only dump */
10875  if (dopt->dataOnly)
10876  return;
10877 
10878  q = createPQExpBuffer();
10879  delq = createPQExpBuffer();
10880 
10881  qextname = pg_strdup(fmtId(extinfo->dobj.name));
10882 
10883  appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
10884 
10885  if (!dopt->binary_upgrade)
10886  {
10887  /*
10888  * In a regular dump, we simply create the extension, intentionally
10889  * not specifying a version, so that the destination installation's
10890  * default version is used.
10891  *
10892  * Use of IF NOT EXISTS here is unlike our behavior for other object
10893  * types; but there are various scenarios in which it's convenient to
10894  * manually create the desired extension before restoring, so we
10895  * prefer to allow it to exist already.
10896  */
10897  appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
10898  qextname, fmtId(extinfo->namespace));
10899  }
10900  else
10901  {
10902  /*
10903  * In binary-upgrade mode, it's critical to reproduce the state of the
10904  * database exactly, so our procedure is to create an empty extension,
10905  * restore all the contained objects normally, and add them to the
10906  * extension one by one. This function performs just the first of
10907  * those steps. binary_upgrade_extension_member() takes care of
10908  * adding member objects as they're created.
10909  */
10910  int i;
10911  int n;
10912 
10913  appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
10914 
10915  /*
10916  * We unconditionally create the extension, so we must drop it if it
10917  * exists. This could happen if the user deleted 'plpgsql' and then
10918  * readded it, causing its oid to be greater than g_last_builtin_oid.
10919  */
10920  appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
10921 
10923  "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
10924  appendStringLiteralAH(q, extinfo->dobj.name, fout);
10925  appendPQExpBufferStr(q, ", ");
10926  appendStringLiteralAH(q, extinfo->namespace, fout);
10927  appendPQExpBufferStr(q, ", ");
10928  appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
10929  appendStringLiteralAH(q, extinfo->extversion, fout);
10930  appendPQExpBufferStr(q, ", ");
10931 
10932  /*
10933  * Note that we're pushing extconfig (an OID array) back into
10934  * pg_extension exactly as-is. This is OK because pg_class OIDs are
10935  * preserved in binary upgrade.
10936  */
10937  if (strlen(extinfo->extconfig) > 2)
10938  appendStringLiteralAH(q, extinfo->extconfig, fout);
10939  else
10940  appendPQExpBufferStr(q, "NULL");
10941  appendPQExpBufferStr(q, ", ");
10942  if (strlen(extinfo->extcondition) > 2)
10943  appendStringLiteralAH(q, extinfo->extcondition, fout);
10944  else
10945  appendPQExpBufferStr(q, "NULL");
10946  appendPQExpBufferStr(q, ", ");
10947  appendPQExpBufferStr(q, "ARRAY[");
10948  n = 0;
10949  for (i = 0; i < extinfo->dobj.nDeps; i++)
10950  {
10951  DumpableObject *extobj;
10952 
10953  extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
10954  if (extobj && extobj->objType == DO_EXTENSION)
10955  {
10956  if (n++ > 0)
10957  appendPQExpBufferChar(q, ',');
10958  appendStringLiteralAH(q, extobj->name, fout);
10959  }
10960  }
10961  appendPQExpBufferStr(q, "]::pg_catalog.text[]");
10962  appendPQExpBufferStr(q, ");\n");
10963  }
10964 
10965  if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10966  ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
10967  ARCHIVE_OPTS(.tag = extinfo->dobj.name,
10968  .description = "EXTENSION",
10969  .section = SECTION_PRE_DATA,
10970  .createStmt = q->data,
10971  .dropStmt = delq->data));
10972 
10973  /* Dump Extension Comments and Security Labels */
10974  if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10975  dumpComment(fout, "EXTENSION", qextname,
10976  NULL, "",
10977  extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
10978 
10979  if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10980  dumpSecLabel(fout, "EXTENSION", qextname,
10981  NULL, "",
10982  extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
10983 
10984  free(qextname);
10985 
10986  destroyPQExpBuffer(q);
10987  destroyPQExpBuffer(delq);
10988 }
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 14932 of file pg_dump.c.

14933 {
14934  DumpOptions *dopt = fout->dopt;
14935  PQExpBuffer q;
14936  PQExpBuffer delq;
14937  char *qfdwname;
14938 
14939  /* Do nothing in data-only dump */
14940  if (dopt->dataOnly)
14941  return;
14942 
14943  q = createPQExpBuffer();
14944  delq = createPQExpBuffer();
14945 
14946  qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
14947 
14948  appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
14949  qfdwname);
14950 
14951  if (strcmp(fdwinfo->fdwhandler, "-") != 0)
14952  appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
14953 
14954  if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
14955  appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
14956 
14957  if (strlen(fdwinfo->fdwoptions) > 0)
14958  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
14959 
14960  appendPQExpBufferStr(q, ";\n");
14961 
14962  appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
14963  qfdwname);
14964 
14965  if (dopt->binary_upgrade)
14967  "FOREIGN DATA WRAPPER", qfdwname,
14968  NULL);
14969 
14970  if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14971  ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
14972  ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
14973  .owner = fdwinfo->rolname,
14974  .description = "FOREIGN DATA WRAPPER",
14975  .section = SECTION_PRE_DATA,
14976  .createStmt = q->data,
14977  .dropStmt = delq->data));
14978 
14979  /* Dump Foreign Data Wrapper Comments */
14980  if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14981  dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
14982  NULL, fdwinfo->rolname,
14983  fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
14984 
14985  /* Handle the ACL */
14986  if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14987  dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
14988  "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
14989  NULL, fdwinfo->rolname, &fdwinfo->dacl);
14990 
14991  free(qfdwname);
14992 
14993  destroyPQExpBuffer(q);
14994  destroyPQExpBuffer(delq);
14995 }
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 15002 of file pg_dump.c.

15003 {
15004  DumpOptions *dopt = fout->dopt;
15005  PQExpBuffer q;
15006  PQExpBuffer delq;
15007  PQExpBuffer query;
15008  PGresult *res;
15009  char *qsrvname;
15010  char *fdwname;
15011 
15012  /* Do nothing in data-only dump */
15013  if (dopt->dataOnly)
15014  return;
15015 
15016  q = createPQExpBuffer();
15017  delq = createPQExpBuffer();
15018  query = createPQExpBuffer();
15019 
15020  qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
15021 
15022  /* look up the foreign-data wrapper */
15023  appendPQExpBuffer(query, "SELECT fdwname "
15024  "FROM pg_foreign_data_wrapper w "
15025  "WHERE w.oid = '%u'",
15026  srvinfo->srvfdw);
15027  res = ExecuteSqlQueryForSingleRow(fout, query->data);
15028  fdwname = PQgetvalue(res, 0, 0);
15029 
15030  appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
15031  if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
15032  {
15033  appendPQExpBufferStr(q, " TYPE ");
15034  appendStringLiteralAH(q, srvinfo->srvtype, fout);
15035  }
15036  if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
15037  {
15038  appendPQExpBufferStr(q, " VERSION ");
15039  appendStringLiteralAH(q, srvinfo->srvversion, fout);
15040  }
15041 
15042  appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
15043  appendPQExpBufferStr(q, fmtId(fdwname));
15044 
15045  if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
15046  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
15047 
15048  appendPQExpBufferStr(q, ";\n");
15049 
15050  appendPQExpBuffer(delq, "DROP SERVER %s;\n",
15051  qsrvname);
15052 
15053  if (dopt->binary_upgrade)
15055  "SERVER", qsrvname, NULL);
15056 
15057  if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15058  ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
15059  ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
15060  .owner = srvinfo->rolname,
15061  .description = "SERVER",
15062  .section = SECTION_PRE_DATA,
15063  .createStmt = q->data,
15064  .dropStmt = delq->data));
15065 
15066  /* Dump Foreign Server Comments */
15067  if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15068  dumpComment(fout, "SERVER", qsrvname,
15069  NULL, srvinfo->rolname,
15070  srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
15071 
15072  /* Handle the ACL */
15073  if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
15074  dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
15075  "FOREIGN SERVER", qsrvname, NULL, NULL,
15076  NULL, srvinfo->rolname, &srvinfo->dacl);
15077 
15078  /* Dump user mappings */
15079  if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
15080  dumpUserMappings(fout,
15081  srvinfo->dobj.name, NULL,
15082  srvinfo->rolname,
15083  srvinfo->dobj.catId, srvinfo->dobj.dumpId);
15084 
15085  PQclear(res);
15086 
15087  free(qsrvname);
15088 
15089  destroyPQExpBuffer(q);
15090  destroyPQExpBuffer(delq);
15091  destroyPQExpBuffer(query);
15092 }
static void dumpUserMappings(Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
Definition: pg_dump.c:15102
#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 12335 of file pg_dump.c.

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

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

16968 {
16969  DumpOptions *dopt = fout->dopt;
16970  TableInfo *tbinfo = indxinfo->indextable;
16971  bool is_constraint = (indxinfo->indexconstraint != 0);
16972  PQExpBuffer q;
16973  PQExpBuffer delq;
16974  char *qindxname;
16975  char *qqindxname;
16976 
16977  /* Do nothing in data-only dump */
16978  if (dopt->dataOnly)
16979  return;
16980 
16981  q = createPQExpBuffer();
16982  delq = createPQExpBuffer();
16983 
16984  qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16985  qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
16986 
16987  /*
16988  * If there's an associated constraint, don't dump the index per se, but
16989  * do dump any comment for it. (This is safe because dependency ordering
16990  * will have ensured the constraint is emitted first.) Note that the
16991  * emitted comment has to be shown as depending on the constraint, not the
16992  * index, in such cases.
16993  */
16994  if (!is_constraint)
16995  {
16996  char *indstatcols = indxinfo->indstatcols;
16997  char *indstatvals = indxinfo->indstatvals;
16998  char **indstatcolsarray = NULL;
16999  char **indstatvalsarray = NULL;
17000  int nstatcols = 0;
17001  int nstatvals = 0;
17002 
17003  if (dopt->binary_upgrade)
17005  indxinfo->dobj.catId.oid, true);
17006 
17007  /* Plain secondary index */
17008  appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
17009 
17010  /*
17011  * Append ALTER TABLE commands as needed to set properties that we
17012  * only have ALTER TABLE syntax for. Keep this in sync with the
17013  * similar code in dumpConstraint!
17014  */
17015 
17016  /* If the index is clustered, we need to record that. */
17017  if (indxinfo->indisclustered)
17018  {
17019  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17020  fmtQualifiedDumpable(tbinfo));
17021  /* index name is not qualified in this syntax */
17022  appendPQExpBuffer(q, " ON %s;\n",
17023  qindxname);
17024  }
17025 
17026  /*
17027  * If the index has any statistics on some of its columns, generate
17028  * the associated ALTER INDEX queries.
17029  */
17030  if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
17031  {
17032  int j;
17033 
17034  if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
17035  pg_fatal("could not parse index statistic columns");
17036  if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
17037  pg_fatal("could not parse index statistic values");
17038  if (nstatcols != nstatvals)
17039  pg_fatal("mismatched number of columns and values for index statistics");
17040 
17041  for (j = 0; j < nstatcols; j++)
17042  {
17043  appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
17044 
17045  /*
17046  * Note that this is a column number, so no quotes should be
17047  * used.
17048  */
17049  appendPQExpBuffer(q, "ALTER COLUMN %s ",
17050  indstatcolsarray[j]);
17051  appendPQExpBuffer(q, "SET STATISTICS %s;\n",
17052  indstatvalsarray[j]);
17053  }
17054  }
17055 
17056  /* Indexes can depend on extensions */
17057  append_depends_on_extension(fout, q, &indxinfo->dobj,
17058  "pg_catalog.pg_class",
17059  "INDEX", qqindxname);
17060 
17061  /* If the index defines identity, we need to record that. */
17062  if (indxinfo->indisreplident)
17063  {
17064  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17065  fmtQualifiedDumpable(tbinfo));
17066  /* index name is not qualified in this syntax */
17067  appendPQExpBuffer(q, " INDEX %s;\n",
17068  qindxname);
17069  }
17070 
17071  appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
17072 
17073  if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17074  ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
17075  ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
17076  .namespace = tbinfo->dobj.namespace->dobj.name,
17077  .tablespace = indxinfo->tablespace,
17078  .owner = tbinfo->rolname,
17079  .description = "INDEX",
17080  .section = SECTION_POST_DATA,
17081  .createStmt = q->data,
17082  .dropStmt = delq->data));
17083 
17084  free(indstatcolsarray);
17085  free(indstatvalsarray);
17086  }
17087 
17088  /* Dump Index Comments */
17089  if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17090  dumpComment(fout, "INDEX", qindxname,
17091  tbinfo->dobj.namespace->dobj.name,
17092  tbinfo->rolname,
17093  indxinfo->dobj.catId, 0,
17094  is_constraint ? indxinfo->indexconstraint :
17095  indxinfo->dobj.dumpId);
17096 
17097  destroyPQExpBuffer(q);
17098  destroyPQExpBuffer(delq);
17099  free(qindxname);
17100  free(qqindxname);
17101 }
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 17108 of file pg_dump.c.

17109 {
17110  /* Do nothing in data-only dump */
17111  if (fout->dopt->dataOnly)
17112  return;
17113 
17114  if (attachinfo->partitionIdx->dobj.dump & DUMP_COMPONENT_DEFINITION)
17115  {
17117 
17118  appendPQExpBuffer(q, "ALTER INDEX %s ",
17119  fmtQualifiedDumpable(attachinfo->parentIdx));
17120  appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
17121  fmtQualifiedDumpable(attachinfo->partitionIdx));
17122 
17123  /*
17124  * There is no point in creating a drop query as the drop is done by
17125  * index drop. (If you think to change this, see also
17126  * _printTocEntry().) Although this object doesn't really have
17127  * ownership as such, set the owner field anyway to ensure that the
17128  * command is run by the correct role at restore time.
17129  */
17130  ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
17131  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
17132  .namespace = attachinfo->dobj.namespace->dobj.name,
17133  .owner = attachinfo->parentIdx->indextable->rolname,
17134  .description = "INDEX ATTACH",
17135  .section = SECTION_POST_DATA,
17136  .createStmt = q->data));
17137 
17138  destroyPQExpBuffer(q);
17139  }
17140 }
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 3756 of file pg_dump.c.

3757 {
3758  PQExpBuffer cquery = createPQExpBuffer();
3759 
3760  /*
3761  * The "definition" is just a newline-separated list of OIDs. We need to
3762  * put something into the dropStmt too, but it can just be a comment.
3763  */
3764  for (int i = 0; i < loinfo->numlos; i++)
3765  appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
3766 
3767  if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
3768  ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
3769  ARCHIVE_OPTS(.tag = loinfo->dobj.name,
3770  .owner = loinfo->rolname,
3771  .description = "BLOB METADATA",
3772  .section = SECTION_DATA,
3773  .createStmt = cquery->data,
3774  .dropStmt = "-- dummy"));
3775 
3776  /*
3777  * Dump per-blob comments and seclabels if any. We assume these are rare
3778  * enough that it's okay to generate retail TOC entries for them.
3779  */
3780  if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
3782  {
3783  for (int i = 0; i < loinfo->numlos; i++)
3784  {
3785  CatalogId catId;
3786  char namebuf[32];
3787 
3788  /* Build identifying info for this blob */
3789  catId.tableoid = loinfo->dobj.catId.tableoid;
3790  catId.oid = loinfo->looids[i];
3791  snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
3792 
3793  if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
3794  dumpComment(fout, "LARGE OBJECT", namebuf,
3795  NULL, loinfo->rolname,
3796  catId, 0, loinfo->dobj.dumpId);
3797 
3798  if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
3799  dumpSecLabel(fout, "LARGE OBJECT", namebuf,
3800  NULL, loinfo->rolname,
3801  catId, 0, loinfo->dobj.dumpId);
3802  }
3803  }
3804 
3805  /*
3806  * Dump the ACLs if any (remember that all blobs in the group will have
3807  * the same ACL). If there's just one blob, dump a simple ACL entry; if
3808  * there's more, make a "LARGE OBJECTS" entry that really contains only
3809  * the ACL for the first blob. _printTocEntry() will be cued by the tag
3810  * string to emit a mutated version for each blob.
3811  */
3812  if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
3813  {
3814  char namebuf[32];
3815 
3816  /* Build identifying info for the first blob */
3817  snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
3818 
3819  if (loinfo->numlos > 1)
3820  {
3821  char tagbuf[64];
3822 
3823  snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
3824  loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
3825 
3826  dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
3827  "LARGE OBJECT", namebuf, NULL, NULL,
3828  tagbuf, loinfo->rolname, &loinfo->dacl);
3829  }
3830  else
3831  {
3832  dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
3833  "LARGE OBJECT", namebuf, NULL, NULL,
3834  NULL, loinfo->rolname, &loinfo->dacl);
3835  }
3836  }
3837 
3838  destroyPQExpBuffer(cquery);
3839 }
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 3846 of file pg_dump.c.

3847 {
3848  const LoInfo *loinfo = (const LoInfo *) arg;
3849  PGconn *conn = GetConnection(fout);
3850  char buf[LOBBUFSIZE];
3851 
3852  pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
3853 
3854  for (int i = 0; i < loinfo->numlos; i++)
3855  {
3856  Oid loOid = loinfo->looids[i];
3857  int loFd;
3858  int cnt;
3859 
3860  /* Open the LO */
3861  loFd = lo_open(conn, loOid, INV_READ);
3862  if (loFd == -1)
3863  pg_fatal("could not open large object %u: %s",
3864  loOid, PQerrorMessage(conn));
3865 
3866  StartLO(fout, loOid);
3867 
3868  /* Now read it in chunks, sending data to archive */
3869  do
3870  {
3871  cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
3872  if (cnt < 0)
3873  pg_fatal("error reading large object %u: %s",
3874  loOid, PQerrorMessage(conn));
3875 
3876  WriteData(fout, buf, cnt);
3877  } while (cnt > 0);
3878 
3879  lo_close(conn, loFd);
3880 
3881  EndLO(fout, loOid);
3882  }
3883 
3884  return 1;
3885 }
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:154
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7147
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 10790 of file pg_dump.c.

10791 {
10792  DumpOptions *dopt = fout->dopt;
10793  PQExpBuffer q;
10794  PQExpBuffer delq;
10795  char *qnspname;
10796 
10797  /* Do nothing in data-only dump */
10798  if (dopt->dataOnly)
10799  return;
10800 
10801  q = createPQExpBuffer();
10802  delq = createPQExpBuffer();
10803 
10804  qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
10805 
10806  if (nspinfo->create)
10807  {
10808  appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
10809  appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
10810  }
10811  else
10812  {
10813  /* see selectDumpableNamespace() */
10814  appendPQExpBufferStr(delq,
10815  "-- *not* dropping schema, since initdb creates it\n");
10817  "-- *not* creating schema, since initdb creates it\n");
10818  }
10819 
10820  if (dopt->binary_upgrade)
10822  "SCHEMA", qnspname, NULL);
10823 
10824  if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10825  ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
10826  ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
10827  .owner = nspinfo->rolname,
10828  .description = "SCHEMA",
10829  .section = SECTION_PRE_DATA,
10830  .createStmt = q->data,
10831  .dropStmt = delq->data));
10832 
10833  /* Dump Schema Comments and Security Labels */
10834  if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10835  {
10836  const char *initdb_comment = NULL;
10837 
10838  if (!nspinfo->create && strcmp(qnspname, "public") == 0)
10839  initdb_comment = "standard public schema";
10840  dumpCommentExtended(fout, "SCHEMA", qnspname,
10841  NULL, nspinfo->rolname,
10842  nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
10843  initdb_comment);
10844  }
10845 
10846  if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10847  dumpSecLabel(fout, "SCHEMA", qnspname,
10848  NULL, nspinfo->rolname,
10849  nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10850 
10851  if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10852  dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
10853  qnspname, NULL, NULL,
10854  NULL, nspinfo->rolname, &nspinfo->dacl);
10855 
10856  free(qnspname);
10857 
10858  destroyPQExpBuffer(q);
10859  destroyPQExpBuffer(delq);
10860 }
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 13365 of file pg_dump.c.

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

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

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

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

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

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

4060 {
4061  DumpOptions *dopt = fout->dopt;
4062  TableInfo *tbinfo = polinfo->poltable;
4063  PQExpBuffer query;
4064  PQExpBuffer delqry;
4065  PQExpBuffer polprefix;
4066  char *qtabname;
4067  const char *cmd;
4068  char *tag;
4069 
4070  /* Do nothing in data-only dump */
4071  if (dopt->dataOnly)
4072  return;
4073 
4074  /*
4075  * If polname is NULL, then this record is just indicating that ROW LEVEL
4076  * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
4077  * ROW LEVEL SECURITY.
4078  */
4079  if (polinfo->polname == NULL)
4080  {
4081  query = createPQExpBuffer();
4082 
4083  appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
4084  fmtQualifiedDumpable(tbinfo));
4085 
4086  /*
4087  * We must emit the ROW SECURITY object's dependency on its table
4088  * explicitly, because it will not match anything in pg_depend (unlike
4089  * the case for other PolicyInfo objects).
4090  */
4091  if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4092  ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4093  ARCHIVE_OPTS(.tag = polinfo->dobj.name,
4094  .namespace = polinfo->dobj.namespace->dobj.name,
4095  .owner = tbinfo->rolname,
4096  .description = "ROW SECURITY",
4097  .section = SECTION_POST_DATA,
4098  .createStmt = query->data,
4099  .deps = &(tbinfo->dobj.dumpId),
4100  .nDeps = 1));
4101 
4102  destroyPQExpBuffer(query);
4103  return;
4104  }
4105 
4106  if (polinfo->polcmd == '*')
4107  cmd = "";
4108  else if (polinfo->polcmd == 'r')
4109  cmd = " FOR SELECT";
4110  else if (polinfo->polcmd == 'a')
4111  cmd = " FOR INSERT";
4112  else if (polinfo->polcmd == 'w')
4113  cmd = " FOR UPDATE";
4114  else if (polinfo->polcmd == 'd')
4115  cmd = " FOR DELETE";
4116  else
4117  pg_fatal("unexpected policy command type: %c",
4118  polinfo->polcmd);
4119 
4120  query = createPQExpBuffer();
4121  delqry = createPQExpBuffer();
4122  polprefix = createPQExpBuffer();
4123 
4124  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
4125 
4126  appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
4127 
4128  appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
4129  !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
4130 
4131  if (polinfo->polroles != NULL)
4132  appendPQExpBuffer(query, " TO %s", polinfo->polroles);
4133 
4134  if (polinfo->polqual != NULL)
4135  appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
4136 
4137  if (polinfo->polwithcheck != NULL)
4138  appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
4139 
4140  appendPQExpBufferStr(query, ";\n");
4141 
4142  appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
4143  appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
4144 
4145  appendPQExpBuffer(polprefix, "POLICY %s ON",
4146  fmtId(polinfo->polname));
4147 
4148  tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
4149 
4150  if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4151  ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4152  ARCHIVE_OPTS(.tag = tag,
4153  .namespace = polinfo->dobj.namespace->dobj.name,
4154  .owner = tbinfo->rolname,
4155  .description = "POLICY",
4156  .section = SECTION_POST_DATA,
4157  .createStmt = query->data,
4158  .dropStmt = delqry->data));
4159 
4160  if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4161  dumpComment(fout, polprefix->data, qtabname,
4162  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
4163  polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
4164 
4165  free(tag);
4166  destroyPQExpBuffer(query);
4167  destroyPQExpBuffer(delqry);
4168  destroyPQExpBuffer(polprefix);
4169  free(qtabname);
4170 }
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 12151 of file pg_dump.c.

12152 {
12153  DumpOptions *dopt = fout->dopt;
12154  PQExpBuffer defqry;
12155  PQExpBuffer delqry;
12156  bool useParams;
12157  char *qlanname;
12158  FuncInfo *funcInfo;
12159  FuncInfo *inlineInfo = NULL;
12160  FuncInfo *validatorInfo = NULL;
12161 
12162  /* Do nothing in data-only dump */
12163  if (dopt->dataOnly)
12164  return;
12165 
12166  /*
12167  * Try to find the support function(s). It is not an error if we don't
12168  * find them --- if the functions are in the pg_catalog schema, as is
12169  * standard in 8.1 and up, then we won't have loaded them. (In this case
12170  * we will emit a parameterless CREATE LANGUAGE command, which will
12171  * require PL template knowledge in the backend to reload.)
12172  */
12173 
12174  funcInfo = findFuncByOid(plang->lanplcallfoid);
12175  if (funcInfo != NULL && !funcInfo->dobj.dump)
12176  funcInfo = NULL; /* treat not-dumped same as not-found */
12177 
12178  if (OidIsValid(plang->laninline))
12179  {
12180  inlineInfo = findFuncByOid(plang->laninline);
12181  if (inlineInfo != NULL && !inlineInfo->dobj.dump)
12182  inlineInfo = NULL;
12183  }
12184 
12185  if (OidIsValid(plang->lanvalidator))
12186  {
12187  validatorInfo = findFuncByOid(plang->lanvalidator);
12188  if (validatorInfo != NULL && !validatorInfo->dobj.dump)
12189  validatorInfo = NULL;
12190  }
12191 
12192  /*
12193  * If the functions are dumpable then emit a complete CREATE LANGUAGE with
12194  * parameters. Otherwise, we'll write a parameterless command, which will
12195  * be interpreted as CREATE EXTENSION.
12196  */
12197  useParams = (funcInfo != NULL &&
12198  (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
12199  (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
12200 
12201  defqry = createPQExpBuffer();
12202  delqry = createPQExpBuffer();
12203 
12204  qlanname = pg_strdup(fmtId(plang->dobj.name));
12205 
12206  appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
12207  qlanname);
12208 
12209  if (useParams)
12210  {
12211  appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
12212  plang->lanpltrusted ? "TRUSTED " : "",
12213  qlanname);
12214  appendPQExpBuffer(defqry, " HANDLER %s",
12215  fmtQualifiedDumpable(funcInfo));
12216  if (OidIsValid(plang->laninline))
12217  appendPQExpBuffer(defqry, " INLINE %s",
12218  fmtQualifiedDumpable(inlineInfo));
12219  if (OidIsValid(plang->lanvalidator))
12220  appendPQExpBuffer(defqry, " VALIDATOR %s",
12221  fmtQualifiedDumpable(validatorInfo));
12222  }
12223  else
12224  {
12225  /*
12226  * If not dumping parameters, then use CREATE OR REPLACE so that the
12227  * command will not fail if the language is preinstalled in the target
12228  * database.
12229  *
12230  * Modern servers will interpret this as CREATE EXTENSION IF NOT
12231  * EXISTS; perhaps we should emit that instead? But it might just add
12232  * confusion.
12233  */
12234  appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
12235  qlanname);
12236  }
12237  appendPQExpBufferStr(defqry, ";\n");
12238 
12239  if (dopt->binary_upgrade)
12240  binary_upgrade_extension_member(defqry, &plang->dobj,
12241  "LANGUAGE", qlanname, NULL);
12242 
12243  if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
12244  ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
12245  ARCHIVE_OPTS(.tag = plang->dobj.name,
12246  .owner = plang->lanowner,
12247  .description = "PROCEDURAL LANGUAGE",
12248  .section = SECTION_PRE_DATA,
12249  .createStmt = defqry->data,
12250  .dropStmt = delqry->data,
12251  ));
12252 
12253  /* Dump Proc Lang Comments and Security Labels */
12254  if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
12255  dumpComment(fout, "LANGUAGE", qlanname,
12256  NULL, plang->lanowner,
12257  plang->dobj.catId, 0, plang->dobj.dumpId);
12258 
12259  if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
12260  dumpSecLabel(fout, "LANGUAGE", qlanname,
12261  NULL, plang->lanowner,
12262  plang->dobj.catId, 0, plang->dobj.dumpId);
12263 
12264  if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
12265  dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
12266  qlanname, NULL, NULL,
12267  NULL, plang->lanowner, &plang->dacl);
12268 
12269  free(qlanname);
12270 
12271  destroyPQExpBuffer(defqry);
12272  destroyPQExpBuffer(delqry);
12273 }
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 4281 of file pg_dump.c.

4282 {
4283  DumpOptions *dopt = fout->dopt;
4284  PQExpBuffer delq;
4285  PQExpBuffer query;
4286  char *qpubname;
4287  bool first = true;
4288 
4289  /* Do nothing in data-only dump */
4290  if (dopt->dataOnly)
4291  return;
4292 
4293  delq = createPQExpBuffer();
4294  query = createPQExpBuffer();
4295 
4296  qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
4297 
4298  appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
4299  qpubname);
4300 
4301  appendPQExpBuffer(query, "CREATE PUBLICATION %s",
4302  qpubname);
4303 
4304  if (pubinfo->puballtables)
4305  appendPQExpBufferStr(query, " FOR ALL TABLES");
4306 
4307  appendPQExpBufferStr(query, " WITH (publish = '");
4308  if (pubinfo->pubinsert)
4309  {
4310  appendPQExpBufferStr(query, "insert");
4311  first = false;
4312  }
4313 
4314  if (pubinfo->pubupdate)
4315  {
4316  if (!first)
4317  appendPQExpBufferStr(query, ", ");
4318 
4319  appendPQExpBufferStr(query, "update");
4320  first = false;
4321  }
4322 
4323  if (pubinfo->pubdelete)
4324  {
4325  if (!first)
4326  appendPQExpBufferStr(query, ", ");
4327 
4328  appendPQExpBufferStr(query, "delete");
4329  first = false;
4330  }
4331 
4332  if (pubinfo->pubtruncate)
4333  {
4334  if (!first)
4335  appendPQExpBufferStr(query, ", ");
4336 
4337  appendPQExpBufferStr(query, "truncate");
4338  first = false;
4339  }
4340 
4341  appendPQExpBufferChar(query, '\'');
4342 
4343  if (pubinfo->pubviaroot)
4344  appendPQExpBufferStr(query, ", publish_via_partition_root = true");
4345 
4346  appendPQExpBufferStr(query, ");\n");
4347 
4348  if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4349  ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
4350  ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
4351  .owner = pubinfo->rolname,
4352  .description = "PUBLICATION",
4353  .section = SECTION_POST_DATA,
4354  .createStmt = query->data,
4355  .dropStmt = delq->data));
4356 
4357  if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4358  dumpComment(fout, "PUBLICATION", qpubname,
4359  NULL, pubinfo->rolname,
4360  pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4361 
4362  if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4363  dumpSecLabel(fout, "PUBLICATION", qpubname,
4364  NULL, pubinfo->rolname,
4365  pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4366 
4367  destroyPQExpBuffer(delq);
4368  destroyPQExpBuffer(query);
4369  free(qpubname);
4370 }
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::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 4596 of file pg_dump.c.

4597 {
4598  DumpOptions *dopt = fout->dopt;
4599  NamespaceInfo *schemainfo = pubsinfo->pubschema;
4600  PublicationInfo *pubinfo = pubsinfo->publication;
4601  PQExpBuffer query;
4602  char *tag;
4603 
4604  /* Do nothing in data-only dump */
4605  if (dopt->dataOnly)
4606  return;
4607 
4608  tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
4609 
4610  query = createPQExpBuffer();
4611 
4612  appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
4613  appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
4614 
4615  /*
4616  * There is no point in creating drop query as the drop is done by schema
4617  * drop.
4618  */
4619  if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4620  ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
4621  ARCHIVE_OPTS(.tag = tag,
4622  .namespace = schemainfo->dobj.name,
4623  .owner = pubinfo->rolname,
4624  .description = "PUBLICATION TABLES IN SCHEMA",
4625  .section = SECTION_POST_DATA,
4626  .createStmt = query->data));
4627 
4628  /* These objects can't currently have comments or seclabels */
4629 
4630  free(tag);
4631  destroyPQExpBuffer(query);
4632 }
NamespaceInfo * pubschema
Definition: pg_dump.h:656
DumpableObject dobj
Definition: pg_dump.h:654
PublicationInfo * publication
Definition: pg_dump.h:655

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

4640 {
4641  DumpOptions *dopt = fout->dopt;
4642  PublicationInfo *pubinfo = pubrinfo->publication;
4643  TableInfo *tbinfo = pubrinfo->pubtable;
4644  PQExpBuffer query;
4645  char *tag;
4646 
4647  /* Do nothing in data-only dump */
4648  if (dopt->dataOnly)
4649  return;
4650 
4651  tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
4652 
4653  query = createPQExpBuffer();
4654 
4655  appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
4656  fmtId(pubinfo->dobj.name));
4657  appendPQExpBuffer(query, " %s",
4658  fmtQualifiedDumpable(tbinfo));
4659 
4660  if (pubrinfo->pubrattrs)
4661  appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
4662 
4663  if (pubrinfo->pubrelqual)
4664  {
4665  /*
4666  * It's necessary to add parentheses around the expression because
4667  * pg_get_expr won't supply the parentheses for things like WHERE
4668  * TRUE.
4669  */
4670  appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
4671  }
4672  appendPQExpBufferStr(query, ";\n");
4673 
4674  /*
4675  * There is no point in creating a drop query as the drop is done by table
4676  * drop. (If you think to change this, see also _printTocEntry().)
4677  * Although this object doesn't really have ownership as such, set the
4678  * owner field anyway to ensure that the command is run by the correct
4679  * role at restore time.
4680  */
4681  if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4682  ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
4683  ARCHIVE_OPTS(.tag = tag,
4684  .namespace = tbinfo->dobj.namespace->dobj.name,
4685  .owner = pubinfo->rolname,
4686  .description = "PUBLICATION TABLE",
4687  .section = SECTION_POST_DATA,
4688  .createStmt = query->data));
4689 
4690  /* These objects can't currently have comments or seclabels */
4691 
4692  free(tag);
4693  destroyPQExpBuffer(query);
4694 }

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

11167 {
11168  DumpOptions *dopt = fout->dopt;
11170  PQExpBuffer delq = createPQExpBuffer();
11171  PQExpBuffer query = createPQExpBuffer();
11172  PGresult *res;
11173  Oid collationOid;
11174  char *qtypname;
11175  char *qualtypname;
11176  char *procname;
11177 
11179  {
11180  /* Set up query for range-specific details */
11181  appendPQExpBufferStr(query,
11182  "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
11183 
11184  appendPQExpBufferStr(query,
11185  "SELECT ");
11186 
11187  if (fout->remoteVersion >= 140000)
11188  appendPQExpBufferStr(query,
11189  "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
11190  else
11191  appendPQExpBufferStr(query,
11192  "NULL AS rngmultitype, ");
11193 
11194  appendPQExpBufferStr(query,
11195  "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
11196  "opc.opcname AS opcname, "
11197  "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
11198  " WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
11199  "opc.opcdefault, "
11200  "CASE WHEN rngcollation = st.typcollation THEN 0 "
11201  " ELSE rngcollation END AS collation, "
11202  "rngcanonical, rngsubdiff "
11203  "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
11204  " pg_catalog.pg_opclass opc "
11205  "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
11206  "rngtypid = $1");
11207 
11208  ExecuteSqlStatement(fout, query->data);
11209 
11210  fout->is_prepared[PREPQUERY_DUMPRANGETYPE] = true;
11211  }
11212 
11213  printfPQExpBuffer(query,
11214  "EXECUTE dumpRangeType('%u')",
11215  tyinfo->dobj.catId.oid);
11216 
11217  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11218 
11219  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11220  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11221 
11222  /*
11223  * CASCADE shouldn't be required here as for normal types since the I/O
11224  * functions are generic and do not get dropped.
11225  */
11226  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11227 
11228  if (dopt->binary_upgrade)
11230  tyinfo->dobj.catId.oid,
11231  false, true);
11232 
11233  appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
11234  qualtypname);
11235 
11236  appendPQExpBuffer(q, "\n subtype = %s",
11237  PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
11238 
11239  if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
11240  appendPQExpBuffer(q, ",\n multirange_type_name = %s",
11241  PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
11242 
11243  /* print subtype_opclass only if not default for subtype */
11244  if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
11245  {
11246  char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
11247  char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
11248 
11249  appendPQExpBuffer(q, ",\n subtype_opclass = %s.",
11250  fmtId(nspname));
11251  appendPQExpBufferStr(q, fmtId(opcname));
11252  }
11253 
11254  collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
11255  if (OidIsValid(collationOid))
11256  {
11257  CollInfo *coll = findCollationByOid(collationOid);
11258 
11259  if (coll)
11260  appendPQExpBuffer(q, ",\n collation = %s",
11261  fmtQualifiedDumpable(coll));
11262  }
11263 
11264  procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
11265  if (strcmp(procname, "-") != 0)
11266  appendPQExpBuffer(q, ",\n canonical = %s", procname);
11267 
11268  procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
11269  if (strcmp(procname, "-") != 0)
11270  appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
11271 
11272  appendPQExpBufferStr(q, "\n);\n");
11273 
11274  if (dopt->binary_upgrade)
11276  "TYPE", qtypname,
11277  tyinfo->dobj.namespace->dobj.name);
11278 
11279  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11280  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11281  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11282  .namespace = tyinfo->dobj.namespace->dobj.name,
11283  .owner = tyinfo->rolname,
11284  .description = "TYPE",
11285  .section = SECTION_PRE_DATA,
11286  .createStmt = q->data,
11287  .dropStmt = delq->data));
11288 
11289  /* Dump Type Comments and Security Labels */
11290  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11291  dumpComment(fout, "TYPE", qtypname,
11292  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11293  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11294 
11295  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11296  dumpSecLabel(fout, "TYPE", qtypname,
11297  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11298  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11299 
11300  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11301  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11302  qtypname, NULL,
11303  tyinfo->dobj.namespace->dobj.name,
11304  NULL, tyinfo->rolname, &tyinfo->dacl);
11305 
11306  PQclear(res);
11307  destroyPQExpBuffer(q);
11308  destroyPQExpBuffer(delq);
11309  destroyPQExpBuffer(query);
11310  free(qtypname);
11311  free(qualtypname);
11312 }
@ 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 18080 of file pg_dump.c.

18081 {
18082  DumpOptions *dopt = fout->dopt;
18083  TableInfo *tbinfo = rinfo->ruletable;
18084  bool is_view;
18085  PQExpBuffer query;
18086  PQExpBuffer cmd;
18087  PQExpBuffer delcmd;
18088  PQExpBuffer ruleprefix;
18089  char *qtabname;
18090  PGresult *res;
18091  char *tag;
18092 
18093  /* Do nothing in data-only dump */
18094  if (dopt->dataOnly)
18095  return;
18096 
18097  /*
18098  * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
18099  * we do not want to dump it as a separate object.
18100  */
18101  if (!rinfo->separate)
18102  return;
18103 
18104  /*
18105  * If it's an ON SELECT rule, we want to print it as a view definition,
18106  * instead of a rule.
18107  */
18108  is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
18109 
18110  query = createPQExpBuffer();
18111  cmd = createPQExpBuffer();
18112  delcmd = createPQExpBuffer();
18113  ruleprefix = createPQExpBuffer();
18114 
18115  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18116 
18117  if (is_view)
18118  {
18119  PQExpBuffer result;
18120 
18121  /*
18122  * We need OR REPLACE here because we'll be replacing a dummy view.
18123  * Otherwise this should look largely like the regular view dump code.
18124  */
18125  appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
18126  fmtQualifiedDumpable(tbinfo));
18127  if (nonemptyReloptions(tbinfo->reloptions))
18128  {
18129  appendPQExpBufferStr(cmd, " WITH (");
18130  appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
18131  appendPQExpBufferChar(cmd, ')');
18132  }
18133  result = createViewAsClause(fout, tbinfo);
18134  appendPQExpBuffer(cmd, " AS\n%s", result->data);
18135  destroyPQExpBuffer(result);
18136  if (tbinfo->checkoption != NULL)
18137  appendPQExpBuffer(cmd, "\n WITH %s CHECK OPTION",
18138  tbinfo->checkoption);
18139  appendPQExpBufferStr(cmd, ";\n");
18140  }
18141  else
18142  {
18143  /* In the rule case, just print pg_get_ruledef's result verbatim */
18144  appendPQExpBuffer(query,
18145  "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
18146  rinfo->dobj.catId.oid);
18147 
18148  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18149 
18150  if (PQntuples(res) != 1)
18151  pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
18152  rinfo->dobj.name, tbinfo->dobj.name);
18153 
18154  printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
18155 
18156  PQclear(res);
18157  }
18158 
18159  /*
18160  * Add the command to alter the rules replication firing semantics if it
18161  * differs from the default.
18162  */
18163  if (rinfo->ev_enabled != 'O')
18164  {
18165  appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
18166  switch (rinfo->ev_enabled)
18167  {
18168  case 'A':
18169  appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
18170  fmtId(rinfo->dobj.name));
18171  break;
18172  case 'R':
18173  appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
18174  fmtId(rinfo->dobj.name));
18175  break;
18176  case 'D':
18177  appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
18178  fmtId(rinfo->dobj.name));
18179  break;
18180  }
18181  }
18182 
18183  if (is_view)
18184  {
18185  /*
18186  * We can't DROP a view's ON SELECT rule. Instead, use CREATE OR
18187  * REPLACE VIEW to replace the rule with something with minimal
18188  * dependencies.
18189  */
18190  PQExpBuffer result;
18191 
18192  appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
18193  fmtQualifiedDumpable(tbinfo));
18194  result = createDummyViewAsClause(fout, tbinfo);
18195  appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
18196  destroyPQExpBuffer(result);
18197  }
18198  else
18199  {
18200  appendPQExpBuffer(delcmd, "DROP RULE %s ",
18201  fmtId(rinfo->dobj.name));
18202  appendPQExpBuffer(delcmd, "ON %s;\n",
18203  fmtQualifiedDumpable(tbinfo));
18204  }
18205 
18206  appendPQExpBuffer(ruleprefix, "RULE %s ON",
18207  fmtId(rinfo->dobj.name));
18208 
18209  tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
18210 
18211  if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18212  ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
18213  ARCHIVE_OPTS(.tag = tag,
18214  .namespace = tbinfo->dobj.namespace->dobj.name,
18215  .owner = tbinfo->rolname,
18216  .description = "RULE",
18217  .section = SECTION_POST_DATA,
18218  .createStmt = cmd->data,
18219  .dropStmt = delcmd->data));
18220 
18221  /* Dump rule comments */
18222  if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18223  dumpComment(fout, ruleprefix->data, qtabname,
18224  tbinfo->dobj.namespace->dobj.name,
18225  tbinfo->rolname,
18226  rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
18227 
18228  free(tag);
18229  destroyPQExpBuffer(query);
18230  destroyPQExpBuffer(cmd);
18231  destroyPQExpBuffer(delcmd);
18232  destroyPQExpBuffer(ruleprefix);
18233  free(qtabname);
18234 }
static PQExpBuffer createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15929
static PQExpBuffer createViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15880
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:294
char * reloptions
Definition: pg_dump.h:293

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

3557 {
3559  PQExpBuffer path = createPQExpBuffer();
3560  PGresult *res;
3561  char **schemanames = NULL;
3562  int nschemanames = 0;
3563  int i;
3564 
3565  /*
3566  * We use the result of current_schemas(), not the search_path GUC,
3567  * because that might contain wildcards such as "$user", which won't
3568  * necessarily have the same value during restore. Also, this way avoids
3569  * listing schemas that may appear in search_path but not actually exist,
3570  * which seems like a prudent exclusion.
3571  */
3573  "SELECT pg_catalog.current_schemas(false)");
3574 
3575  if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
3576  pg_fatal("could not parse result of current_schemas()");
3577 
3578  /*
3579  * We use set_config(), not a simple "SET search_path" command, because
3580  * the latter has less-clean behavior if the search path is empty. While
3581  * that's likely to get fixed at some point, it seems like a good idea to
3582  * be as backwards-compatible as possible in what we put into archives.
3583  */
3584  for (i = 0; i < nschemanames; i++)
3585  {
3586  if (i > 0)
3587  appendPQExpBufferStr(path, ", ");
3588  appendPQExpBufferStr(path, fmtId(schemanames[i]));
3589  }
3590 
3591  appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
3592  appendStringLiteralAH(qry, path->data, AH);
3593  appendPQExpBufferStr(qry, ", false);\n");
3594 
3595  pg_log_info("saving search_path = %s", path->data);
3596 
3598  ARCHIVE_OPTS(.tag = "SEARCHPATH",
3599  .description = "SEARCHPATH",
3600  .section = SECTION_PRE_DATA,
3601  .createStmt = qry->data));
3602 
3603  /* Also save it in AH->searchpath, in case we're doing plain text dump */
3604  AH->searchpath = pg_strdup(qry->data);
3605 
3606  free(schemanames);
3607  PQclear(res);
3608  destroyPQExpBuffer(qry);
3609  destroyPQExpBuffer(path);
3610 }
char * searchpath
Definition: pg_backup.h:233

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

15416 {
15417  DumpOptions *dopt = fout->dopt;
15418  SecLabelItem *labels;
15419  int nlabels;
15420  int i;
15421  PQExpBuffer query;
15422 
15423  /* do nothing, if --no-security-labels is supplied */
15424  if (dopt->no_security_labels)
15425  return;
15426 
15427  /*
15428  * Security labels are schema not data ... except large object labels are
15429  * data
15430  */
15431  if (strcmp(type, "LARGE OBJECT") != 0)
15432  {
15433  if (dopt->dataOnly)
15434  return;
15435  }
15436  else
15437  {
15438  /* We do dump large object security labels in binary-upgrade mode */
15439  if (dopt->schemaOnly && !dopt->binary_upgrade)
15440  return;
15441  }
15442 
15443  /* Search for security labels associated with catalogId, using table */
15444  nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
15445 
15446  query = createPQExpBuffer();
15447 
15448  for (i = 0; i < nlabels; i++)
15449  {
15450  /*
15451  * Ignore label entries for which the subid doesn't match.
15452  */
15453  if (labels[i].objsubid != subid)
15454  continue;
15455 
15456  appendPQExpBuffer(query,
15457  "SECURITY LABEL FOR %s ON %s ",
15458  fmtId(labels[i].provider), type);
15459  if (namespace && *namespace)
15460  appendPQExpBuffer(query, "%s.", fmtId(namespace));
15461  appendPQExpBuffer(query, "%s IS ", name);
15462  appendStringLiteralAH(query, labels[i].label, fout);
15463  appendPQExpBufferStr(query, ";\n");
15464  }
15465 
15466  if (query->len > 0)
15467  {
15469 
15470  appendPQExpBuffer(tag, "%s %s", type, name);
15472  ARCHIVE_OPTS(.tag = tag->data,
15473  .namespace = namespace,
15474  .owner = owner,
15475  .description = "SECURITY LABEL",
15476  .section = SECTION_NONE,
15477  .createStmt = query->data,
15478  .deps = &dumpId,
15479  .nDeps = 1));
15480  destroyPQExpBuffer(tag);
15481  }
15482 
15483  destroyPQExpBuffer(query);
15484 }
static JitProviderCallbacks provider
Definition: jit.c:43
static int findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
Definition: pg_dump.c:15575

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

17554 {
17555  DumpOptions *dopt = fout->dopt;
17556  PGresult *res;
17557  char *startv,
17558  *incby,
17559  *maxv,
17560  *minv,
17561  *cache,
17562  *seqtype;
17563  bool cycled;
17564  bool is_ascending;
17565  int64 default_minv,
17566  default_maxv;
17567  char bufm[32],
17568  bufx[32];
17569  PQExpBuffer query = createPQExpBuffer();
17570  PQExpBuffer delqry = createPQExpBuffer();
17571  char *qseqname;
17572  TableInfo *owning_tab = NULL;
17573 
17574  qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
17575 
17576  if (fout->remoteVersion >= 100000)
17577  {
17578  appendPQExpBuffer(query,
17579  "SELECT format_type(seqtypid, NULL), "
17580  "seqstart, seqincrement, "
17581  "seqmax, seqmin, "
17582  "seqcache, seqcycle "
17583  "FROM pg_catalog.pg_sequence "
17584  "WHERE seqrelid = '%u'::oid",
17585  tbinfo->dobj.catId.oid);
17586  }
17587  else
17588  {
17589  /*
17590  * Before PostgreSQL 10, sequence metadata is in the sequence itself.
17591  *
17592  * Note: it might seem that 'bigint' potentially needs to be
17593  * schema-qualified, but actually that's a keyword.
17594  */
17595  appendPQExpBuffer(query,
17596  "SELECT 'bigint' AS sequence_type, "
17597  "start_value, increment_by, max_value, min_value, "
17598  "cache_value, is_cycled FROM %s",
17599  fmtQualifiedDumpable(tbinfo));
17600  }
17601 
17602  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17603 
17604  if (PQntuples(res) != 1)
17605  pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
17606  "query to get data of sequence \"%s\" returned %d rows (expected 1)",
17607  PQntuples(res)),
17608  tbinfo->dobj.name, PQntuples(res));
17609 
17610  seqtype = PQgetvalue(res, 0, 0);
17611  startv = PQgetvalue(res, 0, 1);
17612  incby = PQgetvalue(res, 0, 2);
17613  maxv = PQgetvalue(res, 0, 3);
17614  minv = PQgetvalue(res, 0, 4);
17615  cache = PQgetvalue(res, 0, 5);
17616  cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
17617 
17618  /* Calculate default limits for a sequence of this type */
17619  is_ascending = (incby[0] != '-');
17620  if (strcmp(seqtype, "smallint") == 0)
17621  {
17622  default_minv = is_ascending ? 1 : PG_INT16_MIN;
17623  default_maxv = is_ascending ? PG_INT16_MAX : -1;
17624  }
17625  else if (strcmp(seqtype, "integer") == 0)
17626  {
17627  default_minv = is_ascending ? 1 : PG_INT32_MIN;
17628  default_maxv = is_ascending ? PG_INT32_MAX : -1;
17629  }
17630  else if (strcmp(seqtype, "bigint") == 0)
17631  {
17632  default_minv = is_ascending ? 1 : PG_INT64_MIN;
17633  default_maxv = is_ascending ? PG_INT64_MAX : -1;
17634  }
17635  else
17636  {
17637  pg_fatal("unrecognized sequence type: %s", seqtype);
17638  default_minv = default_maxv = 0; /* keep compiler quiet */
17639  }
17640 
17641  /*
17642  * 64-bit strtol() isn't very portable, so convert the limits to strings
17643  * and compare that way.
17644  */
17645  snprintf(bufm, sizeof(bufm), INT64_FORMAT, default_minv);
17646  snprintf(bufx, sizeof(bufx), INT64_FORMAT, default_maxv);
17647 
17648  /* Don't print minv/maxv if they match the respective default limit */
17649  if (strcmp(minv, bufm) == 0)
17650  minv = NULL;
17651  if (strcmp(maxv, bufx) == 0)
17652  maxv = NULL;
17653 
17654  /*
17655  * Identity sequences are not to be dropped separately.
17656  */
17657  if (!tbinfo->is_identity_sequence)
17658  {
17659  appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
17660  fmtQualifiedDumpable(tbinfo));
17661  }
17662 
17663  resetPQExpBuffer(query);
17664 
17665  if (dopt->binary_upgrade)
17666  {
17668  tbinfo->dobj.catId.oid, false);
17669 
17670  /*
17671  * In older PG versions a sequence will have a pg_type entry, but v14
17672  * and up don't use that, so don't attempt to preserve the type OID.
17673  */
17674  }
17675 
17676  if (tbinfo->is_identity_sequence)
17677  {
17678  owning_tab = findTableByOid(tbinfo->owning_tab);
17679 
17680  appendPQExpBuffer(query,
17681  "ALTER TABLE %s ",
17682  fmtQualifiedDumpable(owning_tab));
17683  appendPQExpBuffer(query,
17684  "ALTER COLUMN %s ADD GENERATED ",
17685  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
17686  if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
17687  appendPQExpBufferStr(query, "ALWAYS");
17688  else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
17689  appendPQExpBufferStr(query, "BY DEFAULT");
17690  appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n",
17691  fmtQualifiedDumpable(tbinfo));
17692  }
17693  else
17694  {
17695  appendPQExpBuffer(query,
17696  "CREATE %sSEQUENCE %s\n",
17697  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
17698  "UNLOGGED " : "",
17699  fmtQualifiedDumpable(tbinfo));
17700 
17701  if (strcmp(seqtype, "bigint") != 0)
17702  appendPQExpBuffer(query, " AS %s\n", seqtype);
17703  }
17704 
17705  appendPQExpBuffer(query, " START WITH %s\n", startv);
17706 
17707  appendPQExpBuffer(query, " INCREMENT BY %s\n", incby);
17708 
17709  if (minv)
17710  appendPQExpBuffer(query, " MINVALUE %s\n", minv);
17711  else
17712  appendPQExpBufferStr(query, " NO MINVALUE\n");
17713 
17714  if (maxv)
17715  appendPQExpBuffer(query, " MAXVALUE %s\n", maxv);
17716  else
17717  appendPQExpBufferStr(query, " NO MAXVALUE\n");
17718 
17719  appendPQExpBuffer(query,
17720  " CACHE %s%s",
17721  cache, (cycled ? "\n CYCLE" : ""));
17722 
17723  if (tbinfo->is_identity_sequence)
17724  {
17725  appendPQExpBufferStr(query, "\n);\n");
17726  if (tbinfo->relpersistence != owning_tab->relpersistence)
17727  appendPQExpBuffer(query,
17728  "ALTER SEQUENCE %s SET %s;\n",
17729  fmtQualifiedDumpable(tbinfo),
17730  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
17731  "UNLOGGED" : "LOGGED");
17732  }
17733  else
17734  appendPQExpBufferStr(query, ";\n");
17735 
17736  /* binary_upgrade: no need to clear TOAST table oid */
17737 
17738  if (dopt->binary_upgrade)
17739  binary_upgrade_extension_member(query, &tbinfo->dobj,
17740  "SEQUENCE", qseqname,
17741  tbinfo->dobj.namespace->dobj.name);
17742 
17743  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17744  ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
17745  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17746  .namespace = tbinfo->dobj.namespace->dobj.name,
17747  .owner = tbinfo->rolname,
17748  .description = "SEQUENCE",
17749  .section = SECTION_PRE_DATA,
17750  .createStmt = query->data,
17751  .dropStmt = delqry->data));
17752 
17753  /*
17754  * If the sequence is owned by a table column, emit the ALTER for it as a
17755  * separate TOC entry immediately following the sequence's own entry. It's
17756  * OK to do this rather than using full sorting logic, because the
17757  * dependency that tells us it's owned will have forced the table to be
17758  * created first. We can't just include the ALTER in the TOC entry
17759  * because it will fail if we haven't reassigned the sequence owner to
17760  * match the table's owner.
17761  *
17762  * We need not schema-qualify the table reference because both sequence
17763  * and table must be in the same schema.
17764  */
17765  if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
17766  {
17767  owning_tab = findTableByOid(tbinfo->owning_tab);
17768 
17769  if (owning_tab == NULL)
17770  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
17771  tbinfo->owning_tab, tbinfo->dobj.catId.oid);
17772 
17773  if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
17774  {
17775  resetPQExpBuffer(query);
17776  appendPQExpBuffer(query, "ALTER SEQUENCE %s",
17777  fmtQualifiedDumpable(tbinfo));
17778  appendPQExpBuffer(query, " OWNED BY %s",
17779  fmtQualifiedDumpable(owning_tab));
17780  appendPQExpBuffer(query, ".%s;\n",
17781  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
17782 
17783  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17785  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17786  .namespace = tbinfo->dobj.namespace->dobj.name,
17787  .owner = tbinfo->rolname,
17788  .description = "SEQUENCE OWNED BY",
17789  .section = SECTION_PRE_DATA,
17790  .createStmt = query->data,
17791  .deps = &(tbinfo->dobj.dumpId),
17792  .nDeps = 1));
17793  }
17794  }
17795 
17796  /* Dump Sequence Comments and Security Labels */
17797  if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17798  dumpComment(fout, "SEQUENCE", qseqname,
17799  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17800  tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
17801 
17802  if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
17803  dumpSecLabel(fout, "SEQUENCE", qseqname,
17804  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17805  tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
17806 
17807  PQclear(res);
17808 
17809  destroyPQExpBuffer(query);
17810  destroyPQExpBuffer(delqry);
17811  free(qseqname);
17812 }
TableInfo * findTableByOid(Oid oid)
Definition: common.c:854
#define PG_INT32_MAX
Definition: c.h:589
#define ngettext(s, p, n)
Definition: c.h:1181
#define INT64_FORMAT
Definition: c.h:548
#define PG_INT16_MIN
Definition: c.h:585
#define PG_INT64_MAX
Definition: c.h:592
#define PG_INT64_MIN
Definition: c.h:591
#define PG_INT32_MIN
Definition: c.h:588
#define PG_INT16_MAX
Definition: c.h:586
char * attidentity
Definition: pg_dump.h:339
bool is_identity_sequence
Definition: pg_dump.h:315
int owning_col
Definition: pg_dump.h:314
Oid owning_tab
Definition: pg_dump.h:313
char relpersistence
Definition: pg_dump.h:289

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _tableInfo::attidentity, _tableInfo::attnames, _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, createDumpId(), createPQExpBuffer(), 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, INT64_FORMAT, _tableInfo::is_identity_sequence, _dumpableObject::name, ngettext, nilCatalogId, CatalogId::oid, OidIsValid, _tableInfo::owning_col, _tableInfo::owning_tab, pg_fatal, PG_INT16_MAX, PG_INT16_MIN, PG_INT32_MAX, PG_INT32_MIN, PG_INT64_MAX, PG_INT64_MIN, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), _tableInfo::relpersistence, Archive::remoteVersion, res, resetPQExpBuffer(), _tableInfo::rolname, SECTION_PRE_DATA, and snprintf.

Referenced by dumpTable().

◆ dumpSequenceData()

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

Definition at line 17819 of file pg_dump.c.

17820 {
17821  TableInfo *tbinfo = tdinfo->tdtable;
17822  PGresult *res;
17823  char *last;
17824  bool called;
17825  PQExpBuffer query = createPQExpBuffer();
17826 
17827  appendPQExpBuffer(query,
17828  "SELECT last_value, is_called FROM %s",
17829  fmtQualifiedDumpable(tbinfo));
17830 
17831  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17832 
17833  if (PQntuples(res) != 1)
17834  pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
17835  "query to get data of sequence \"%s\" returned %d rows (expected 1)",
17836  PQntuples(res)),
17837  tbinfo->dobj.name, PQntuples(res));
17838 
17839  last = PQgetvalue(res, 0, 0);
17840  called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
17841 
17842  resetPQExpBuffer(query);
17843  appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
17844  appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
17845  appendPQExpBuffer(query, ", %s, %s);\n",
17846  last, (called ? "true" : "false"));
17847 
17848  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
17850  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17851  .namespace = tbinfo->dobj.namespace->dobj.name,
17852  .owner = tbinfo->rolname,
17853  .description = "SEQUENCE SET",
17854  .section = SECTION_DATA,
17855  .createStmt = query->data,
17856  .deps = &(tbinfo->dobj.dumpId),
17857  .nDeps = 1));
17858 
17859  PQclear(res);
17860 
17861  destroyPQExpBuffer(query);
17862 }
TableInfo * tdtable
Definition: pg_dump.h:390
DumpableObject dobj
Definition: pg_dump.h:389

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _tableDataInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_DATA, _dumpableObject::dumpId, ExecuteSqlQuery(), fmtQualifiedDumpable, _dumpableObject::name, ngettext, nilCatalogId, pg_fatal, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), res, resetPQExpBuffer(), _tableInfo::rolname, SECTION_DATA, and _tableDataInfo::tdtable.

Referenced by dumpDumpableObject().

◆ dumpShellType()

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

Definition at line 12105 of file pg_dump.c.

12106 {
12107  DumpOptions *dopt = fout->dopt;
12108  PQExpBuffer q;
12109 
12110  /* Do nothing in data-only dump */
12111  if (dopt->dataOnly)
12112  return;
12113 
12114  q = createPQExpBuffer();
12115 
12116  /*
12117  * Note the lack of a DROP command for the shell type; any required DROP
12118  * is driven off the base type entry, instead. This interacts with
12119  * _printTocEntry()'s use of the presence of a DROP command to decide
12120  * whether an entry needs an ALTER OWNER command. We don't want to alter
12121  * the shell type's owner immediately on creation; that should happen only
12122  * after it's filled in, otherwise the backend complains.
12123  */
12124 
12125  if (dopt->binary_upgrade)
12127  stinfo->baseType->dobj.catId.oid,
12128  false, false);
12129 
12130  appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12131  fmtQualifiedDumpable(stinfo));
12132 
12133  if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12134  ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
12135  ARCHIVE_OPTS(.tag = stinfo->dobj.name,
12136  .namespace = stinfo->dobj.namespace->dobj.name,
12137  .owner = stinfo->baseType->rolname,
12138  .description = "SHELL TYPE",
12139  .section = SECTION_PRE_DATA,
12140  .createStmt = q->data));
12141 
12142  destroyPQExpBuffer(q);
12143 }
TypeInfo * baseType
Definition: pg_dump.h:219
DumpableObject dobj
Definition: pg_dump.h:217

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

17148 {
17149  DumpOptions *dopt = fout->dopt;
17150  PQExpBuffer q;
17151  PQExpBuffer delq;
17152  PQExpBuffer query;
17153  char *qstatsextname;
17154  PGresult *res;
17155  char *stxdef;
17156 
17157  /* Do nothing in data-only dump */
17158  if (dopt->dataOnly)
17159  return;
17160 
17161  q = createPQExpBuffer();
17162  delq = createPQExpBuffer();
17163  query = createPQExpBuffer();
17164 
17165  qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
17166 
17167  appendPQExpBuffer(query, "SELECT "
17168  "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
17169  statsextinfo->dobj.catId.oid);
17170 
17171  res = ExecuteSqlQueryForSingleRow(fout, query->data);
17172 
17173  stxdef = PQgetvalue(res, 0, 0);
17174 
17175  /* Result of pg_get_statisticsobjdef is complete except for semicolon */
17176  appendPQExpBuffer(q, "%s;\n", stxdef);
17177 
17178  /*
17179  * We only issue an ALTER STATISTICS statement if the stxstattarget entry
17180  * for this statistics object is not the default value.
17181  */
17182  if (statsextinfo->stattarget >= 0)
17183  {
17184  appendPQExpBuffer(q, "ALTER STATISTICS %s ",
17185  fmtQualifiedDumpable(statsextinfo));
17186  appendPQExpBuffer(q, "SET STATISTICS %d;\n",
17187  statsextinfo->stattarget);
17188  }
17189 
17190  appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
17191  fmtQualifiedDumpable(statsextinfo));
17192 
17193  if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17194  ArchiveEntry(fout, statsextinfo->dobj.catId,
17195  statsextinfo->dobj.dumpId,
17196  ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
17197  .namespace = statsextinfo->dobj.namespace->dobj.name,
17198  .owner = statsextinfo->rolname,
17199  .description = "STATISTICS",
17200  .section = SECTION_POST_DATA,
17201  .createStmt = q->data,
17202  .dropStmt = delq->data));
17203 
17204  /* Dump Statistics Comments */
17205  if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17206  dumpComment(fout, "STATISTICS", qstatsextname,
17207  statsextinfo->dobj.namespace->dobj.name,
17208  statsextinfo->rolname,
17209  statsextinfo->dobj.catId, 0,
17210  statsextinfo->dobj.dumpId);
17211 
17212  PQclear(res);
17213  destroyPQExpBuffer(q);
17214  destroyPQExpBuffer(delq);
17215  destroyPQExpBuffer(query);
17216  free(qstatsextname);
17217 }
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 3532 of file pg_dump.c.

3533 {
3534  const char *stdstrings = AH->std_strings ? "on" : "off";
3536 
3537  pg_log_info("saving standard_conforming_strings = %s",
3538  stdstrings);
3539 
3540  appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
3541  stdstrings);
3542 
3544  ARCHIVE_OPTS(.tag = "STDSTRINGS",
3545  .description = "STDSTRINGS",
3546  .section = SECTION_PRE_DATA,
3547  .createStmt = qry->data));
3548 
3549  destroyPQExpBuffer(qry);
3550 }

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

5074 {
5075  DumpOptions *dopt = fout->dopt;
5076  PQExpBuffer delq;
5077  PQExpBuffer query;
5078  PQExpBuffer publications;
5079  char *qsubname;
5080  char **pubnames = NULL;
5081  int npubnames = 0;
5082  int i;
5083  char two_phase_disabled[] = {LOGICALREP_TWOPHASE_STATE_DISABLED, '\0'};
5084 
5085  /* Do nothing in data-only dump */
5086  if (dopt->dataOnly)
5087  return;
5088 
5089  delq = createPQExpBuffer();
5090  query = createPQExpBuffer();
5091 
5092  qsubname = pg_strdup(fmtId(subinfo->dobj.name));
5093 
5094  appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
5095  qsubname);
5096 
5097  appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
5098  qsubname);
5099  appendStringLiteralAH(query, subinfo->subconninfo, fout);
5100 
5101  /* Build list of quoted publications and append them to query. */
5102  if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
5103  pg_fatal("could not parse %s array", "subpublications");
5104 
5105  publications = createPQExpBuffer();
5106  for (i = 0; i < npubnames; i++)
5107  {
5108  if (i > 0)
5109  appendPQExpBufferStr(publications, ", ");
5110 
5111  appendPQExpBufferStr(publications, fmtId(pubnames[i]));
5112  }
5113 
5114  appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
5115  if (subinfo->subslotname)
5116  appendStringLiteralAH(query, subinfo->subslotname, fout);
5117  else
5118  appendPQExpBufferStr(query, "NONE");
5119 
5120  if (strcmp(subinfo->subbinary, "t") == 0)
5121  appendPQExpBufferStr(query, ", binary = true");
5122 
5123  if (strcmp(subinfo->substream, "t") == 0)
5124  appendPQExpBufferStr(query, ", streaming = on");
5125  else if (strcmp(subinfo->substream, "p") == 0)
5126  appendPQExpBufferStr(query, ", streaming = parallel");
5127 
5128  if (strcmp(subinfo->subtwophasestate, two_phase_disabled) != 0)
5129  appendPQExpBufferStr(query, ", two_phase = on");
5130 
5131  if (strcmp(subinfo->subdisableonerr, "t") == 0)
5132  appendPQExpBufferStr(query, ", disable_on_error = true");
5133 
5134  if (strcmp(subinfo->subpasswordrequired, "t") != 0)
5135  appendPQExpBuffer(query, ", password_required = false");
5136 
5137  if (strcmp(subinfo->subrunasowner, "t") == 0)
5138  appendPQExpBufferStr(query, ", run_as_owner = true");
5139 
5140  if (strcmp(subinfo->subfailover, "t") == 0)
5141  appendPQExpBufferStr(query, ", failover = true");
5142 
5143  if (strcmp(subinfo->subsynccommit, "off") != 0)
5144  appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
5145 
5146  if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
5147  appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
5148 
5149  appendPQExpBufferStr(query, ");\n");
5150 
5151  /*
5152  * In binary-upgrade mode, we allow the replication to continue after the
5153  * upgrade.
5154  */
5155  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5156  {
5157  if (subinfo->suboriginremotelsn)
5158  {
5159  /*
5160  * Preserve the remote_lsn for the subscriber's replication
5161  * origin. This value is required to start the replication from
5162  * the position before the upgrade. This value will be stale if
5163  * the publisher gets upgraded before the subscriber node.
5164  * However, this shouldn't be a problem as the upgrade of the
5165  * publisher ensures that all the transactions were replicated
5166  * before upgrading it.
5167  */
5168  appendPQExpBufferStr(query,
5169  "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
5170  appendPQExpBufferStr(query,
5171  "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
5172  appendStringLiteralAH(query, subinfo->dobj.name, fout);
5173  appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
5174  }
5175 
5176  if (strcmp(subinfo->subenabled, "t") == 0)
5177  {
5178  /*
5179  * Enable the subscription to allow the replication to continue
5180  * after the upgrade.
5181  */
5182  appendPQExpBufferStr(query,
5183  "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
5184  appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
5185  }
5186  }
5187 
5188  if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5189  ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
5190  ARCHIVE_OPTS(.tag = subinfo->dobj.name,
5191  .owner = subinfo->rolname,
5192  .description = "SUBSCRIPTION",
5193  .section = SECTION_POST_DATA,
5194  .createStmt = query->data,
5195  .dropStmt = delq->data));
5196 
5197  if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
5198  dumpComment(fout, "SUBSCRIPTION", qsubname,
5199  NULL, subinfo->rolname,
5200  subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5201 
5202  if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
5203  dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
5204  NULL, subinfo->rolname,
5205  subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5206 
5207  destroyPQExpBuffer(publications);
5208  free(pubnames);
5209 
5210  destroyPQExpBuffer(delq);
5211  destroyPQExpBuffer(query);
5212  free(qsubname);
5213 }
#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:678
char * suborigin
Definition: pg_dump.h:677
char * subbinary
Definition: pg_dump.h:667
const char * rolname
Definition: pg_dump.h:665
char * subrunasowner
Definition: pg_dump.h:672
char * subsynccommit
Definition: pg_dump.h:675
char * subpublications
Definition: pg_dump.h:676
char * subtwophasestate
Definition: pg_dump.h:669
char * subfailover
Definition: pg_dump.h:679
char * subenabled
Definition: pg_dump.h:666
char * substream
Definition: pg_dump.h:668
char * subpasswordrequired
Definition: pg_dump.h:671
char * subslotname
Definition: pg_dump.h:674
char * subdisableonerr
Definition: pg_dump.h:670
char * subconninfo
Definition: pg_dump.h:673
DumpableObject dobj
Definition: pg_dump.h:664

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

5005 {
5006  DumpOptions *dopt = fout->dopt;
5007  SubscriptionInfo *subinfo = subrinfo->subinfo;
5008  PQExpBuffer query;
5009  char *tag;
5010 
5011  /* Do nothing in data-only dump */
5012  if (dopt->dataOnly)
5013  return;
5014 
5015  Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
5016 
5017  tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
5018 
5019  query = createPQExpBuffer();
5020 
5021  if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5022  {
5023  /*
5024  * binary_upgrade_add_sub_rel_state will add the subscription relation
5025  * to pg_subscription_rel table. This will be used only in
5026  * binary-upgrade mode.
5027  */
5028  appendPQExpBufferStr(query,
5029  "\n-- For binary upgrade, must preserve the subscriber table.\n");
5030  appendPQExpBufferStr(query,
5031  "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
5032  appendStringLiteralAH(query, subrinfo->dobj.name, fout);
5033  appendPQExpBuffer(query,
5034  ", %u, '%c'",
5035  subrinfo->tblinfo->dobj.catId.oid,
5036  subrinfo->srsubstate);
5037 
5038  if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
5039  appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
5040  else
5041  appendPQExpBuffer(query, ", NULL");
5042 
5043  appendPQExpBufferStr(query, ");\n");
5044  }
5045 
5046  /*
5047  * There is no point in creating a drop query as the drop is done by table
5048  * drop. (If you think to change this, see also _printTocEntry().)
5049  * Although this object doesn't really have ownership as such, set the
5050  * owner field anyway to ensure that the command is run by the correct
5051  * role at restore time.
5052  */
5053  if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5054  ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
5055  ARCHIVE_OPTS(.tag = tag,
5056  .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
5057  .owner = subinfo->rolname,
5058  .description = "SUBSCRIPTION TABLE",
5059  .section = SECTION_POST_DATA,
5060  .createStmt = query->data));
5061 
5062  /* These objects can't currently have comments or seclabels */
5063 
5064  free(tag);
5065  destroyPQExpBuffer(query);
5066 }
DumpableObject dobj
Definition: pg_dump.h:694
char * srsublsn
Definition: pg_dump.h:698
SubscriptionInfo * subinfo
Definition: pg_dump.h:695
TableInfo * tblinfo
Definition: pg_dump.h:696
char srsubstate
Definition: pg_dump.h:697

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

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

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

16810 {
16811  DumpOptions *dopt = fout->dopt;
16812  PQExpBuffer q;
16813  PGresult *res;
16814  char *partbound;
16815 
16816  /* Do nothing in data-only dump */
16817  if (dopt->dataOnly)
16818  return;
16819 
16820  q = createPQExpBuffer();
16821 
16823  {
16824  /* Set up query for partbound details */
16826  "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
16827 
16829  "SELECT pg_get_expr(c.relpartbound, c.oid) "
16830  "FROM pg_class c "
16831  "WHERE c.oid = $1");
16832 
16833  ExecuteSqlStatement(fout, q->data);
16834 
16835  fout->is_prepared[PREPQUERY_DUMPTABLEATTACH] = true;
16836  }
16837 
16839  "EXECUTE dumpTableAttach('%u')",
16840  attachinfo->partitionTbl->dobj.catId.oid);
16841 
16842  res = ExecuteSqlQueryForSingleRow(fout, q->data);
16843  partbound = PQgetvalue(res, 0, 0);
16844 
16845  /* Perform ALTER TABLE on the parent */
16847  "ALTER TABLE ONLY %s ",
16848  fmtQualifiedDumpable(attachinfo->parentTbl));
16850  "ATTACH PARTITION %s %s;\n",
16851  fmtQualifiedDumpable(attachinfo->partitionTbl),
16852  partbound);
16853 
16854  /*
16855  * There is no point in creating a drop query as the drop is done by table
16856  * drop. (If you think to change this, see also _printTocEntry().)
16857  * Although this object doesn't really have ownership as such, set the
16858  * owner field anyway to ensure that the command is run by the correct
16859  * role at restore time.
16860  */
16861  ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
16862  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
16863  .namespace = attachinfo->dobj.namespace->dobj.name,
16864  .owner = attachinfo->partitionTbl->rolname,
16865  .description = "TABLE ATTACH",
16866  .section = SECTION_PRE_DATA,
16867  .createStmt = q->data));
16868 
16869  PQclear(res);
16870  destroyPQExpBuffer(q);
16871 }
@ 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 10337 of file pg_dump.c.

10339 {
10340  DumpOptions *dopt = fout->dopt;
10342  int ncomments;
10343  PQExpBuffer query;
10344  PQExpBuffer tag;
10345 
10346  /* do nothing, if --no-comments is supplied */
10347  if (dopt->no_comments)
10348  return;
10349 
10350  /* Comments are SCHEMA not data */
10351  if (dopt->dataOnly)
10352  return;
10353 
10354  /* Search for comments associated with relation, using table */
10356  tbinfo->dobj.catId.oid,
10357  &comments);
10358 
10359  /* If comments exist, build COMMENT ON statements */
10360  if (ncomments <= 0)
10361  return;
10362 
10363  query = createPQExpBuffer();
10364  tag = createPQExpBuffer();
10365 
10366  while (ncomments > 0)
10367  {
10368  const char *descr = comments->descr;
10369  int objsubid = comments->objsubid;
10370 
10371  if (objsubid == 0)
10372  {
10373  resetPQExpBuffer(tag);
10374  appendPQExpBuffer(tag, "%s %s", reltypename,
10375  fmtId(tbinfo->dobj.name));
10376 
10377  resetPQExpBuffer(query);
10378  appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
10379  fmtQualifiedDumpable(tbinfo));
10380  appendStringLiteralAH(query, descr, fout);
10381  appendPQExpBufferStr(query, ";\n");
10382 
10384  ARCHIVE_OPTS(.tag = tag->data,
10385  .namespace = tbinfo->dobj.namespace->dobj.name,
10386  .owner = tbinfo->rolname,
10387  .description = "COMMENT",
10388  .section = SECTION_NONE,
10389  .createStmt = query->data,
10390  .deps = &(tbinfo->dobj.dumpId),
10391  .nDeps = 1));
10392  }
10393  else if (objsubid > 0 && objsubid <= tbinfo->numatts)
10394  {
10395  resetPQExpBuffer(tag);
10396  appendPQExpBuffer(tag, "COLUMN %s.",
10397  fmtId(tbinfo->dobj.name));
10398  appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
10399 
10400  resetPQExpBuffer(query);
10401  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
10402  fmtQualifiedDumpable(tbinfo));
10403  appendPQExpBuffer(query, "%s IS ",
10404  fmtId(tbinfo->attnames[objsubid - 1]));
10405  appendStringLiteralAH(query, descr, fout);
10406  appendPQExpBufferStr(query, ";\n");
10407 
10409  ARCHIVE_OPTS(.tag = tag->data,
10410  .namespace = tbinfo->dobj.namespace->dobj.name,
10411  .owner = tbinfo->rolname,
10412  .description = "COMMENT",
10413  .section = SECTION_NONE,
10414  .createStmt = query->data,
10415  .deps = &(tbinfo->dobj.dumpId),
10416  .nDeps = 1));
10417  }
10418 
10419  comments++;
10420  ncomments--;
10421  }
10422 
10423  destroyPQExpBuffer(query);
10424  destroyPQExpBuffer(tag);
10425 }

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

17527 {
17528  TableInfo *tbinfo = coninfo->contable;
17529  PQExpBuffer conprefix = createPQExpBuffer();
17530  char *qtabname;
17531 
17532  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17533 
17534  appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
17535  fmtId(coninfo->dobj.name));
17536 
17537  if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17538  dumpComment(fout, conprefix->data, qtabname,
17539  tbinfo->dobj.namespace->dobj.name,
17540  tbinfo->rolname,
17541  coninfo->dobj.catId, 0,
17542  coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
17543 
17544  destroyPQExpBuffer(conprefix);
17545  free(qtabname);
17546 }

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

2602 {
2603  DumpOptions *dopt = fout->dopt;
2604  TableInfo *tbinfo = tdinfo->tdtable;
2605  PQExpBuffer copyBuf = createPQExpBuffer();
2606  PQExpBuffer clistBuf = createPQExpBuffer();
2607  DataDumperPtr dumpFn;
2608  char *tdDefn = NULL;
2609  char *copyStmt;
2610  const char *copyFrom;
2611 
2612  /* We had better have loaded per-column details about this table */
2613  Assert(tbinfo->interesting);
2614 
2615  /*
2616  * When load-via-partition-root is set or forced, get the root table name
2617  * for the partition table, so that we can reload data through the root
2618  * table. Then construct a comment to be inserted into the TOC entry's
2619  * defn field, so that such cases can be identified reliably.
2620  */
2621  if (tbinfo->ispartition &&
2622  (dopt->load_via_partition_root ||
2623  forcePartitionRootLoad(tbinfo)))
2624  {
2625  TableInfo *parentTbinfo;
2626 
2627  parentTbinfo = getRootTableInfo(tbinfo);
2628  copyFrom = fmtQualifiedDumpable(parentTbinfo);
2629  printfPQExpBuffer(copyBuf, "-- load via partition root %s",
2630  copyFrom);
2631  tdDefn = pg_strdup(copyBuf->data);
2632  }
2633  else
2634  copyFrom = fmtQualifiedDumpable(tbinfo);
2635 
2636  if (dopt->dump_inserts == 0)
2637  {
2638  /* Dump/restore using COPY */
2639  dumpFn = dumpTableData_copy;
2640  /* must use 2 steps here 'cause fmtId is nonreentrant */
2641  printfPQExpBuffer(copyBuf, "COPY %s ",
2642  copyFrom);
2643  appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
2644  fmtCopyColumnList(tbinfo, clistBuf));
2645  copyStmt = copyBuf->data;
2646  }
2647  else
2648  {
2649  /* Restore using INSERT */
2650  dumpFn = dumpTableData_insert;
2651  copyStmt = NULL;
2652  }
2653 
2654  /*
2655  * Note: although the TableDataInfo is a full DumpableObject, we treat its
2656  * dependency on its table as "special" and pass it to ArchiveEntry now.
2657  * See comments for BuildArchiveDependencies.
2658  */
2659  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2660  {
2661  TocEntry *te;
2662 
2663  te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
2664  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2665  .namespace = tbinfo->dobj.namespace->dobj.name,
2666  .owner = tbinfo->rolname,
2667  .description = "TABLE DATA",
2668  .section = SECTION_DATA,
2669  .createStmt = tdDefn,
2670  .copyStmt = copyStmt,
2671  .deps = &(tbinfo->dobj.dumpId),
2672  .nDeps = 1,
2673  .dumpFn = dumpFn,
2674  .dumpArg = tdinfo));
2675 
2676  /*
2677  * Set the TocEntry's dataLength in case we are doing a parallel dump
2678  * and want to order dump jobs by table size. We choose to measure
2679  * dataLength in table pages (including TOAST pages) during dump, so
2680  * no scaling is needed.
2681  *
2682  * However, relpages is declared as "integer" in pg_class, and hence
2683  * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
2684  * Cast so that we get the right interpretation of table sizes
2685  * exceeding INT_MAX pages.
2686  */
2687  te->dataLength = (BlockNumber) tbinfo->relpages;
2688  te->dataLength += (BlockNumber) tbinfo->toastpages;
2689 
2690  /*
2691  * If pgoff_t is only 32 bits wide, the above refinement is useless,
2692  * and instead we'd better worry about integer overflow. Clamp to
2693  * INT_MAX if the correct result exceeds that.
2694  */
2695  if (sizeof(te->dataLength) == 4 &&
2696  (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
2697  te->dataLength < 0))
2698  te->dataLength = INT_MAX;
2699  }
2700 
2701  destroyPQExpBuffer(copyBuf);
2702  destroyPQExpBuffer(clistBuf);
2703 }
uint32 BlockNumber
Definition: block.h:31
int(* DataDumperPtr)(Archive *AH, const void *userArg)
Definition: pg_backup.h:278
static bool forcePartitionRootLoad(const TableInfo *tbinfo)
Definition: pg_dump.c:2573
static int dumpTableData_copy(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2128
static const char * fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
Definition: pg_dump.c:18969
static int dumpTableData_insert(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2287
static TableInfo * getRootTableInfo(const TableInfo *tbinfo)
Definition: pg_dump.c:2548
int dump_inserts
Definition: pg_backup.h:174
int load_via_partition_root
Definition: pg_backup.h:192
bool ispartition
Definition: pg_dump.h:322
bool interesting
Definition: pg_dump.h:319
int toastpages
Definition: pg_dump.h:317
int relpages
Definition: pg_dump.h:316

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

2129 {
2130  TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2131  TableInfo *tbinfo = tdinfo->tdtable;
2132  const char *classname = tbinfo->dobj.name;
2134 
2135  /*
2136  * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
2137  * which uses it already.
2138  */
2139  PQExpBuffer clistBuf = createPQExpBuffer();
2140  PGconn *conn = GetConnection(fout);
2141  PGresult *res;
2142  int ret;
2143  char *copybuf;
2144  const char *column_list;
2145 
2146  pg_log_info("dumping contents of table \"%s.%s\"",
2147  tbinfo->dobj.namespace->dobj.name, classname);
2148 
2149  /*
2150  * Specify the column list explicitly so that we have no possibility of
2151  * retrieving data in the wrong column order. (The default column
2152  * ordering of COPY will not be what we want in certain corner cases
2153  * involving ADD COLUMN and inheritance.)
2154  */
2155  column_list = fmtCopyColumnList(tbinfo, clistBuf);
2156 
2157  /*
2158  * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
2159  * a filter condition was specified. For other cases a simple COPY
2160  * suffices.
2161  */
2162  if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2163  {
2164  appendPQExpBufferStr(q, "COPY (SELECT ");
2165  /* klugery to get rid of parens in column list */
2166  if (strlen(column_list) > 2)
2167  {
2168  appendPQExpBufferStr(q, column_list + 1);
2169  q->data[q->len - 1] = ' ';
2170  }
2171  else
2172  appendPQExpBufferStr(q, "* ");
2173 
2174  appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
2175  fmtQualifiedDumpable(tbinfo),
2176  tdinfo->filtercond ? tdinfo->filtercond : "");
2177  }
2178  else
2179  {
2180  appendPQExpBuffer(q, "COPY %s %s TO stdout;",
2181  fmtQualifiedDumpable(tbinfo),
2182  column_list);
2183  }
2184  res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
2185  PQclear(res);
2186  destroyPQExpBuffer(clistBuf);
2187 
2188  for (;;)
2189  {
2190  ret = PQgetCopyData(conn, &copybuf, 0);
2191 
2192  if (ret < 0)
2193  break; /* done or error */
2194 
2195  if (copybuf)
2196  {
2197  WriteData(fout, copybuf, ret);
2198  PQfreemem(copybuf);
2199  }
2200 
2201  /* ----------
2202  * THROTTLE:
2203  *
2204  * There was considerable discussion in late July, 2000 regarding
2205  * slowing down pg_dump when backing up large tables. Users with both
2206  * slow & fast (multi-processor) machines experienced performance
2207  * degradation when doing a backup.
2208  *
2209  * Initial attempts based on sleeping for a number of ms for each ms
2210  * of work were deemed too complex, then a simple 'sleep in each loop'
2211  * implementation was suggested. The latter failed because the loop
2212  * was too tight. Finally, the following was implemented:
2213  *
2214  * If throttle is non-zero, then
2215  * See how long since the last sleep.
2216  * Work out how long to sleep (based on ratio).
2217  * If sleep is more than 100ms, then
2218  * sleep
2219  * reset timer
2220  * EndIf
2221  * EndIf
2222  *
2223  * where the throttle value was the number of ms to sleep per ms of
2224  * work. The calculation was done in each loop.
2225  *
2226  * Most of the hard work is done in the backend, and this solution
2227  * still did not work particularly well: on slow machines, the ratio
2228  * was 50:1, and on medium paced machines, 1:1, and on fast
2229  * multi-processor machines, it had little or no effect, for reasons
2230  * that were unclear.
2231  *
2232  * Further discussion ensued, and the proposal was dropped.
2233  *
2234  * For those people who want this feature, it can be implemented using
2235  * gettimeofday in each loop, calculating the time since last sleep,
2236  * multiplying that by the sleep ratio, then if the result is more
2237  * than a preset 'minimum sleep time' (say 100ms), call the 'select'
2238  * function to sleep for a subsecond period ie.
2239  *
2240  * select(0, NULL, NULL, NULL, &tvi);
2241  *
2242  * This will return after the interval specified in the structure tvi.
2243  * Finally, call gettimeofday again to save the 'last sleep time'.
2244  * ----------
2245  */
2246  }
2247  archprintf(fout, "\\.\n\n\n");
2248 
2249  if (ret == -2)
2250  {
2251  /* copy data transfer failed */
2252  pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
2253  pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2254  pg_log_error_detail("Command was: %s", q->data);
2255  exit_nicely(1);
2256  }
2257 
2258  /* Check command status and return to normal libpq state */
2259  res = PQgetResult(conn);
2261  {
2262  pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
2263  pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2264  pg_log_error_detail("Command was: %s", q->data);
2265  exit_nicely(1);
2266  }
2267  PQclear(res);
2268 
2269  /* Do this to ensure we've pumped libpq back to idle state */
2270  if (PQgetResult(conn) != NULL)
2271  pg_log_warning("unexpected extra results during COPY of table \"%s\"",
2272  classname);
2273 
2274  destroyPQExpBuffer(q);
2275  return 1;
2276 }
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:100
@ PGRES_COPY_OUT
Definition: libpq-fe.h:106
#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
#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, _tableDataInfo::tdtable, and WriteData().

Referenced by dumpTableData().

◆ dumpTableData_insert()

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

Definition at line 2287 of file pg_dump.c.

2288 {
2289  TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2290  TableInfo *tbinfo = tdinfo->tdtable;
2291  DumpOptions *dopt = fout->dopt;
2293  PQExpBuffer insertStmt = NULL;
2294  char *attgenerated;
2295  PGresult *res;
2296  int nfields,
2297  i;
2298  int rows_per_statement = dopt->dump_inserts;
2299  int rows_this_statement = 0;
2300 
2301  /*
2302  * If we're going to emit INSERTs with column names, the most efficient
2303  * way to deal with generated columns is to exclude them entirely. For
2304  * INSERTs without column names, we have to emit DEFAULT rather than the
2305  * actual column value --- but we can save a few cycles by fetching nulls
2306  * rather than the uninteresting-to-us value.
2307  */
2308  attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
2309  appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
2310  nfields = 0;
2311  for (i = 0; i < tbinfo->numatts; i++)
2312  {
2313  if (tbinfo->attisdropped[i])
2314  continue;
2315  if (tbinfo->attgenerated[i] && dopt->column_inserts)
2316  continue;
2317  if (nfields > 0)
2318  appendPQExpBufferStr(q, ", ");
2319  if (tbinfo->attgenerated[i])
2320  appendPQExpBufferStr(q, "NULL");
2321  else
2322  appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
2323  attgenerated[nfields] = tbinfo->attgenerated[i];
2324  nfields++;
2325  }
2326  /* Servers before 9.4 will complain about zero-column SELECT */
2327  if (nfields == 0)
2328  appendPQExpBufferStr(q, "NULL");
2329  appendPQExpBuffer(q, " FROM ONLY %s",
2330  fmtQualifiedDumpable(tbinfo));
2331  if (tdinfo->filtercond)
2332  appendPQExpBuffer(q, " %s", tdinfo->filtercond);
2333 
2334  ExecuteSqlStatement(fout, q->data);
2335 
2336  while (1)
2337  {
2338  res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
2339  PGRES_TUPLES_OK);
2340 
2341  /* cross-check field count, allowing for dummy NULL if any */
2342  if (nfields != PQnfields(res) &&
2343  !(nfields == 0 && PQnfields(res) == 1))
2344  pg_fatal("wrong number of fields retrieved from table \"%s\"",
2345  tbinfo->dobj.name);
2346 
2347  /*
2348  * First time through, we build as much of the INSERT statement as
2349  * possible in "insertStmt", which we can then just print for each
2350  * statement. If the table happens to have zero dumpable columns then
2351  * this will be a complete statement, otherwise it will end in
2352  * "VALUES" and be ready to have the row's column values printed.
2353  */
2354  if (insertStmt == NULL)
2355  {
2356  TableInfo *targettab;
2357 
2358  insertStmt = createPQExpBuffer();
2359 
2360  /*
2361  * When load-via-partition-root is set or forced, get the root
2362  * table name for the partition table, so that we can reload data
2363  * through the root table.
2364  */
2365  if (tbinfo->ispartition &&
2366  (dopt->load_via_partition_root ||
2367  forcePartitionRootLoad(tbinfo)))
2368  targettab = getRootTableInfo(tbinfo);
2369  else
2370  targettab = tbinfo;
2371 
2372  appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
2373  fmtQualifiedDumpable(targettab));
2374 
2375  /* corner case for zero-column table */
2376  if (nfields == 0)
2377  {
2378  appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
2379  }
2380  else
2381  {
2382  /* append the list of column names if required */
2383  if (dopt->column_inserts)
2384  {
2385  appendPQExpBufferChar(insertStmt, '(');
2386  for (int field = 0; field < nfields; field++)
2387  {
2388  if (field > 0)
2389  appendPQExpBufferStr(insertStmt, ", ");
2390  appendPQExpBufferStr(insertStmt,
2391  fmtId(PQfname(res, field)));
2392  }
2393  appendPQExpBufferStr(insertStmt, ") ");
2394  }
2395 
2396  if (tbinfo->needs_override)
2397  appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
2398 
2399  appendPQExpBufferStr(insertStmt, "VALUES");
2400  }
2401  }
2402 
2403  for (int tuple = 0; tuple < PQntuples(res); tuple++)
2404  {
2405  /* Write the INSERT if not in the middle of a multi-row INSERT. */
2406  if (rows_this_statement == 0)
2407  archputs(insertStmt->data, fout);
2408 
2409  /*
2410  * If it is zero-column table then we've already written the
2411  * complete statement, which will mean we've disobeyed
2412  * --rows-per-insert when it's set greater than 1. We do support
2413  * a way to make this multi-row with: SELECT UNION ALL SELECT
2414  * UNION ALL ... but that's non-standard so we should avoid it
2415  * given that using INSERTs is mostly only ever needed for
2416  * cross-database exports.
2417  */
2418  if (nfields == 0)
2419  continue;
2420 
2421  /* Emit a row heading */
2422  if (rows_per_statement == 1)
2423  archputs(" (", fout);
2424  else if (rows_this_statement > 0)
2425  archputs(",\n\t(", fout);
2426  else
2427  archputs("\n\t(", fout);
2428 
2429  for (int field = 0; field < nfields; field++)
2430  {
2431  if (field > 0)
2432  archputs(", ", fout);
2433  if (attgenerated[field])
2434  {
2435  archputs("DEFAULT", fout);
2436  continue;
2437  }
2438  if (PQgetisnull(res, tuple, field))
2439  {
2440  archputs("NULL", fout);
2441  continue;
2442  }
2443 
2444  /* XXX This code is partially duplicated in ruleutils.c */
2445  switch (PQftype(res, field))
2446  {
2447  case INT2OID:
2448  case INT4OID:
2449  case INT8OID:
2450  case OIDOID:
2451  case FLOAT4OID:
2452  case FLOAT8OID:
2453  case NUMERICOID:
2454  {
2455  /*
2456  * These types are printed without quotes unless
2457  * they contain values that aren't accepted by the
2458  * scanner unquoted (e.g., 'NaN'). Note that
2459  * strtod() and friends might accept NaN, so we
2460  * can't use that to test.
2461  *
2462  * In reality we only need to defend against
2463  * infinity and NaN, so we need not get too crazy
2464  * about pattern matching here.
2465  */
2466  const char *s = PQgetvalue(res, tuple, field);
2467 
2468  if (strspn(s, "0123456789 +-eE.") == strlen(s))
2469  archputs(s, fout);
2470  else
2471  archprintf(fout, "'%s'", s);
2472  }
2473  break;
2474 
2475  case BITOID:
2476  case VARBITOID:
2477  archprintf(fout, "B'%s'",
2478  PQgetvalue(res, tuple, field));
2479  break;
2480 
2481  case BOOLOID:
2482  if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
2483  archputs("true", fout);
2484  else
2485  archputs("false", fout);
2486  break;
2487 
2488  default:
2489  /* All other types are printed as string literals. */
2490  resetPQExpBuffer(q);
2492  PQgetvalue(res, tuple, field),
2493  fout);
2494  archputs(q->data, fout);
2495  break;
2496  }
2497  }
2498 
2499  /* Terminate the row ... */
2500  archputs(")", fout);
2501 
2502  /* ... and the statement, if the target no. of rows is reached */
2503  if (++rows_this_statement >= rows_per_statement)
2504  {
2505  if (dopt->do_nothing)
2506  archputs(" ON CONFLICT DO NOTHING;\n", fout);
2507  else
2508  archputs(";\n", fout);
2509  /* Reset the row counter */
2510  rows_this_statement = 0;
2511  }
2512  }
2513 
2514  if (PQntuples(res) <= 0)
2515  {
2516  PQclear(res);
2517  break;
2518  }
2519  PQclear(res);
2520  }
2521 
2522  /* Terminate any statements that didn't make the row count. */
2523  if (rows_this_statement > 0)
2524  {
2525  if (dopt->do_nothing)
2526  archputs(" ON CONFLICT DO NOTHING;\n", fout);
2527  else
2528  archputs(";\n", fout);
2529  }
2530 
2531  archputs("\n\n", fout);
2532 
2533  ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
2534 
2535  destroyPQExpBuffer(q);
2536  if (insertStmt != NULL)
2537  destroyPQExpBuffer(insertStmt);
2538  free(attgenerated);
2539 
2540  return 1;
2541 }
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:178
int do_nothing
Definition: pg_backup.h:205
char * attgenerated
Definition: pg_dump.h:340
bool * attisdropped
Definition: pg_dump.h:338
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(), res, resetPQExpBuffer(), and _tableDataInfo::tdtable.

Referenced by dumpTableData().

◆ dumpTableSchema()

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

Definition at line 15969 of file pg_dump.c.

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

References _attrDefInfo::adef_expr, _tableInfo::amname, append_depends_on_extension(), 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, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, _dumpOptions::no_toast_compression, nonemptyReloptions(), _tableInfo::notnull_constrs, _tableInfo::notnull_inh, _tableInfo::notnull_noinh, _tableInfo::notnull_throwaway, _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, _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 15493 of file pg_dump.c.

15494 {
15495  DumpOptions *dopt = fout->dopt;
15496  SecLabelItem *labels;
15497  int nlabels;
15498  int i;
15499  PQExpBuffer query;
15500  PQExpBuffer target;
15501 
15502  /* do nothing, if --no-security-labels is supplied */
15503  if (dopt->no_security_labels)
15504  return;
15505 
15506  /* SecLabel are SCHEMA not data */
15507  if (dopt->dataOnly)
15508  return;
15509 
15510  /* Search for comments associated with relation, using table */
15511  nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
15512  tbinfo->dobj.catId.oid,
15513  &labels);
15514 
15515  /* If security labels exist, build SECURITY LABEL statements */
15516  if (nlabels <= 0)
15517  return;
15518 
15519  query = createPQExpBuffer();
15520  target = createPQExpBuffer();
15521 
15522  for (i = 0; i < nlabels; i++)
15523  {
15524  const char *colname;
15525  const char *provider = labels[i].provider;
15526  const char *label = labels[i].label;
15527  int objsubid = labels[i].objsubid;
15528 
15529  resetPQExpBuffer(target);
15530  if (objsubid == 0)
15531  {
15532  appendPQExpBuffer(target, "%s %s", reltypename,
15533  fmtQualifiedDumpable(tbinfo));
15534  }
15535  else
15536  {
15537  colname = getAttrName(objsubid, tbinfo);
15538  /* first fmtXXX result must be consumed before calling again */
15539  appendPQExpBuffer(target, "COLUMN %s",
15540  fmtQualifiedDumpable(tbinfo));
15541  appendPQExpBuffer(target, ".%s", fmtId(colname));
15542  }
15543  appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
15544  fmtId(provider), target->data);
15545  appendStringLiteralAH(query, label, fout);
15546  appendPQExpBufferStr(query, ";\n");
15547  }
15548  if (query->len > 0)
15549  {
15550  resetPQExpBuffer(target);
15551  appendPQExpBuffer(target, "%s %s", reltypename,
15552  fmtId(tbinfo->dobj.name));
15554  ARCHIVE_OPTS(.tag = target->data,
15555  .namespace = tbinfo->dobj.namespace->dobj.name,
15556  .owner = tbinfo->rolname,
15557  .description = "SECURITY LABEL",
15558  .section = SECTION_NONE,
15559  .createStmt = query->data,
15560  .deps = &(tbinfo->dobj.dumpId),
15561  .nDeps = 1));
15562  }
15563  destroyPQExpBuffer(query);
15564  destroyPQExpBuffer(target);
15565 }

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

12857 {
12858  DumpOptions *dopt = fout->dopt;
12859  PQExpBuffer defqry;
12860  PQExpBuffer delqry;
12861  PQExpBuffer labelq;
12862  PQExpBuffer transformargs;
12863  FuncInfo *fromsqlFuncInfo = NULL;
12864  FuncInfo *tosqlFuncInfo = NULL;
12865  char *lanname;
12866  const char *transformType;
12867 
12868  /* Do nothing in data-only dump */
12869  if (dopt->dataOnly)
12870  return;
12871 
12872  /* Cannot dump if we don't have the transform functions' info */
12873  if (OidIsValid(transform->trffromsql))
12874  {
12875  fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
12876  if (fromsqlFuncInfo == NULL)
12877  pg_fatal("could not find function definition for function with OID %u",
12878  transform->trffromsql);
12879  }
12880  if (OidIsValid(transform->trftosql))
12881  {
12882  tosqlFuncInfo = findFuncByOid(transform->trftosql);
12883  if (tosqlFuncInfo == NULL)
12884  pg_fatal("could not find function definition for function with OID %u",
12885  transform->trftosql);
12886  }
12887 
12888  defqry = createPQExpBuffer();
12889  delqry = createPQExpBuffer();
12890  labelq = createPQExpBuffer();
12891  transformargs = createPQExpBuffer();
12892 
12893  lanname = get_language_name(fout, transform->trflang);
12894  transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
12895 
12896  appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
12897  transformType, lanname);
12898 
12899  appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
12900  transformType, lanname);
12901 
12902  if (!transform->trffromsql && !transform->trftosql)
12903  pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
12904 
12905  if (transform->trffromsql)
12906  {
12907  if (fromsqlFuncInfo)
12908  {
12909  char *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
12910 
12911  /*
12912  * Always qualify the function name (format_function_signature
12913  * won't qualify it).
12914  */
12915  appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
12916  fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
12917  free(fsig);
12918  }
12919  else
12920  pg_log_warning("bogus value in pg_transform.trffromsql field");
12921  }
12922 
12923  if (transform->trftosql)
12924  {
12925  if (transform->trffromsql)
12926  appendPQExpBufferStr(defqry, ", ");
12927 
12928  if (tosqlFuncInfo)
12929  {
12930  char *fsig = format_function_signature(fout, tosqlFuncInfo, true);
12931 
12932  /*
12933  * Always qualify the function name (format_function_signature
12934  * won't qualify it).
12935  */
12936  appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
12937  fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
12938  free(fsig);
12939  }
12940  else
12941  pg_log_warning("bogus value in pg_transform.trftosql field");
12942  }
12943 
12944  appendPQExpBufferStr(defqry, ");\n");
12945 
12946  appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
12947  transformType, lanname);
12948 
12949  appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
12950  transformType, lanname);
12951 
12952  if (dopt->binary_upgrade)
12953  binary_upgrade_extension_member(defqry, &transform->dobj,
12954  "TRANSFORM", transformargs->data, NULL);
12955 
12956  if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
12957  ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
12958  ARCHIVE_OPTS(.tag = labelq->data,
12959  .description = "TRANSFORM",
12960  .section = SECTION_PRE_DATA,
12961  .createStmt = defqry->data,
12962  .dropStmt = delqry->data,
12963  .deps = transform->dobj.dependencies,
12964  .nDeps = transform->dobj.nDeps));
12965 
12966  /* Dump Transform Comments */
12967  if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
12968  dumpComment(fout, "TRANSFORM", transformargs->data,
12969  NULL, "",
12970  transform->dobj.catId, 0, transform->dobj.dumpId);
12971 
12972  free(lanname);
12973  destroyPQExpBuffer(defqry);
12974  destroyPQExpBuffer(delqry);
12975  destroyPQExpBuffer(labelq);
12976  destroyPQExpBuffer(transformargs);
12977 }
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8569
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 17869 of file pg_dump.c.

17870 {
17871  DumpOptions *dopt = fout->dopt;
17872  TableInfo *tbinfo = tginfo->tgtable;
17873  PQExpBuffer query;
17874  PQExpBuffer delqry;
17875  PQExpBuffer trigprefix;
17876  PQExpBuffer trigidentity;
17877  char *qtabname;
17878  char *tag;
17879 
17880  /* Do nothing in data-only dump */
17881  if (dopt->dataOnly)
17882  return;
17883 
17884  query = createPQExpBuffer();
17885  delqry = createPQExpBuffer();
17886  trigprefix = createPQExpBuffer();
17887  trigidentity = createPQExpBuffer();
17888 
17889  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17890 
17891  appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
17892  appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
17893 
17894  appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
17895  appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
17896 
17897  /* Triggers can depend on extensions */
17898  append_depends_on_extension(fout, query, &tginfo->dobj,
17899  "pg_catalog.pg_trigger", "TRIGGER",
17900  trigidentity->data);
17901 
17902  if (tginfo->tgispartition)
17903  {
17904  Assert(tbinfo->ispartition);
17905 
17906  /*
17907  * Partition triggers only appear here because their 'tgenabled' flag
17908  * differs from its parent's. The trigger is created already, so
17909  * remove the CREATE and replace it with an ALTER. (Clear out the
17910  * DROP query too, so that pg_dump --create does not cause errors.)
17911  */
17912  resetPQExpBuffer(query);
17913  resetPQExpBuffer(delqry);
17914  appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17915  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17916  fmtQualifiedDumpable(tbinfo));
17917  switch (tginfo->tgenabled)
17918  {
17919  case 'f':
17920  case 'D':
17921  appendPQExpBufferStr(query, "DISABLE");
17922  break;
17923  case 't':
17924  case 'O':
17925  appendPQExpBufferStr(query, "ENABLE");
17926  break;
17927  case 'R':
17928  appendPQExpBufferStr(query, "ENABLE REPLICA");
17929  break;
17930  case 'A':
17931  appendPQExpBufferStr(query, "ENABLE ALWAYS");
17932  break;
17933  }
17934  appendPQExpBuffer(query, " TRIGGER %s;\n",
17935  fmtId(tginfo->dobj.name));
17936  }
17937  else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17938  {
17939  appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17940  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17941  fmtQualifiedDumpable(tbinfo));
17942  switch (tginfo->tgenabled)
17943  {
17944  case 'D':
17945  case 'f':
17946  appendPQExpBufferStr(query, "DISABLE");
17947  break;
17948  case 'A':
17949  appendPQExpBufferStr(query, "ENABLE ALWAYS");
17950  break;
17951  case 'R':
17952  appendPQExpBufferStr(query, "ENABLE REPLICA");
17953  break;
17954  default:
17955  appendPQExpBufferStr(query, "ENABLE");
17956  break;
17957  }
17958  appendPQExpBuffer(query, " TRIGGER %s;\n",
17959  fmtId(tginfo->dobj.name));
17960  }
17961 
17962  appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
17963  fmtId(tginfo->dobj.name));
17964 
17965  tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
17966 
17967  if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17968  ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
17969  ARCHIVE_OPTS(.tag = tag,
17970  .namespace = tbinfo->dobj.namespace->dobj.name,
17971  .owner = tbinfo->rolname,
17972  .description = "TRIGGER",
17973  .section = SECTION_POST_DATA,
17974  .createStmt = query->data,
17975  .dropStmt = delqry->data));
17976 
17977  if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17978  dumpComment(fout, trigprefix->data, qtabname,
17979  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17980  tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
17981 
17982  free(tag);
17983  destroyPQExpBuffer(query);
17984  destroyPQExpBuffer(delqry);
17985  destroyPQExpBuffer(trigprefix);
17986  destroyPQExpBuffer(trigidentity);
17987  free(qtabname);
17988 }
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 14812 of file pg_dump.c.

14813 {
14814  DumpOptions *dopt = fout->dopt;
14815  PQExpBuffer q;
14816  PQExpBuffer delq;
14817  PQExpBuffer query;
14818  char *qcfgname;
14819  PGresult *res;
14820  char *nspname;
14821  char *prsname;
14822  int ntups,
14823  i;
14824  int i_tokenname;
14825  int i_dictname;
14826 
14827  /* Do nothing in data-only dump */
14828  if (dopt->dataOnly)
14829  return;
14830 
14831  q = createPQExpBuffer();
14832  delq = createPQExpBuffer();
14833  query = createPQExpBuffer();
14834 
14835  qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
14836 
14837  /* Fetch name and namespace of the config's parser */
14838  appendPQExpBuffer(query, "SELECT nspname, prsname "
14839  "FROM pg_ts_parser p, pg_namespace n "
14840  "WHERE p.oid = '%u' AND n.oid = prsnamespace",
14841  cfginfo->cfgparser);
14842  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14843  nspname = PQgetvalue(res, 0, 0);
14844  prsname = PQgetvalue(res, 0, 1);
14845 
14846  appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
14847  fmtQualifiedDumpable(cfginfo));
14848 
14849  appendPQExpBuffer(q, " PARSER = %s.", fmtId(nspname));
14850  appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
14851 
14852  PQclear(res);
14853 
14854  resetPQExpBuffer(query);
14855  appendPQExpBuffer(query,
14856  "SELECT\n"
14857  " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
14858  " WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
14859  " m.mapdict::pg_catalog.regdictionary AS dictname\n"
14860  "FROM pg_catalog.pg_ts_config_map AS m\n"
14861  "WHERE m.mapcfg = '%u'\n"
14862  "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
14863  cfginfo->cfgparser, cfginfo->dobj.catId.oid);
14864 
14865  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14866  ntups = PQntuples(res);
14867 
14868  i_tokenname = PQfnumber(res, "tokenname");
14869  i_dictname = PQfnumber(res, "dictname");
14870 
14871  for (i = 0; i < ntups; i++)
14872  {
14873  char *tokenname = PQgetvalue(res, i, i_tokenname);
14874  char *dictname = PQgetvalue(res, i, i_dictname);
14875 
14876  if (i == 0 ||
14877  strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
14878  {
14879  /* starting a new token type, so start a new command */
14880  if (i > 0)
14881  appendPQExpBufferStr(q, ";\n");
14882  appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
14883  fmtQualifiedDumpable(cfginfo));
14884  /* tokenname needs quoting, dictname does NOT */
14885  appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
14886  fmtId(tokenname), dictname);
14887  }
14888  else
14889  appendPQExpBuffer(q, ", %s", dictname);
14890  }
14891 
14892  if (ntups > 0)
14893  appendPQExpBufferStr(q, ";\n");
14894 
14895  PQclear(res);
14896 
14897  appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
14898  fmtQualifiedDumpable(cfginfo));
14899 
14900  if (dopt->binary_upgrade)
14902  "TEXT SEARCH CONFIGURATION", qcfgname,
14903  cfginfo->dobj.namespace->dobj.name);
14904 
14905  if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14906  ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
14907  ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
14908  .namespace = cfginfo->dobj.namespace->dobj.name,
14909  .owner = cfginfo->rolname,
14910  .description = "TEXT SEARCH CONFIGURATION",
14911  .section = SECTION_PRE_DATA,
14912  .createStmt = q->data,
14913  .dropStmt = delq->data));
14914 
14915  /* Dump Configuration Comments */
14916  if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14917  dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
14918  cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
14919  cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
14920 
14921  destroyPQExpBuffer(q);
14922  destroyPQExpBuffer(delq);
14923  destroyPQExpBuffer(query);
14924  free(qcfgname);
14925 }
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 14674 of file pg_dump.c.

14675 {
14676  DumpOptions *dopt = fout->dopt;
14677  PQExpBuffer q;
14678  PQExpBuffer delq;
14679  PQExpBuffer query;
14680  char *qdictname;
14681  PGresult *res;
14682  char *nspname;
14683  char *tmplname;
14684 
14685  /* Do nothing in data-only dump */
14686  if (dopt->dataOnly)
14687  return;
14688 
14689  q = createPQExpBuffer();
14690  delq = createPQExpBuffer();
14691  query = createPQExpBuffer();
14692 
14693  qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
14694 
14695  /* Fetch name and namespace of the dictionary's template */
14696  appendPQExpBuffer(query, "SELECT nspname, tmplname "
14697  "FROM pg_ts_template p, pg_namespace n "
14698  "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
14699  dictinfo->dicttemplate);
14700  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14701  nspname = PQgetvalue(res, 0, 0);
14702  tmplname = PQgetvalue(res, 0, 1);
14703 
14704  appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
14705  fmtQualifiedDumpable(dictinfo));
14706 
14707  appendPQExpBufferStr(q, " TEMPLATE = ");
14708  appendPQExpBuffer(q, "%s.", fmtId(nspname));
14709  appendPQExpBufferStr(q, fmtId(tmplname));
14710 
14711  PQclear(res);
14712 
14713  /* the dictinitoption can be dumped straight into the command */
14714  if (dictinfo->dictinitoption)
14715  appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
14716 
14717  appendPQExpBufferStr(q, " );\n");
14718 
14719  appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
14720  fmtQualifiedDumpable(dictinfo));
14721 
14722  if (dopt->binary_upgrade)
14723  binary_upgrade_extension_member(q, &dictinfo->dobj,
14724  "TEXT SEARCH DICTIONARY", qdictname,
14725  dictinfo->dobj.namespace->dobj.name);
14726 
14727  if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14728  ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
14729  ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
14730  .namespace = dictinfo->dobj.namespace->dobj.name,
14731  .owner = dictinfo->rolname,
14732  .description = "TEXT SEARCH DICTIONARY",
14733  .section = SECTION_PRE_DATA,
14734  .createStmt = q->data,
14735  .dropStmt = delq->data));
14736 
14737  /* Dump Dictionary Comments */
14738  if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14739  dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
14740  dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
14741  dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
14742 
14743  destroyPQExpBuffer(q);
14744  destroyPQExpBuffer(delq);
14745  destroyPQExpBuffer(query);
14746  free(qdictname);
14747 }
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 14610 of file pg_dump.c.

14611 {
14612  DumpOptions *dopt = fout->dopt;
14613  PQExpBuffer q;
14614  PQExpBuffer delq;
14615  char *qprsname;
14616 
14617  /* Do nothing in data-only dump */
14618  if (dopt->dataOnly)
14619  return;
14620 
14621  q = createPQExpBuffer();
14622  delq = createPQExpBuffer();
14623 
14624  qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
14625 
14626  appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
14627  fmtQualifiedDumpable(prsinfo));
14628 
14629  appendPQExpBuffer(q, " START = %s,\n",
14630  convertTSFunction(fout, prsinfo->prsstart));
14631  appendPQExpBuffer(q, " GETTOKEN = %s,\n",
14632  convertTSFunction(fout, prsinfo->prstoken));
14633  appendPQExpBuffer(q, " END = %s,\n",
14634  convertTSFunction(fout, prsinfo->prsend));
14635  if (prsinfo->prsheadline != InvalidOid)
14636  appendPQExpBuffer(q, " HEADLINE = %s,\n",
14637  convertTSFunction(fout, prsinfo->prsheadline));
14638  appendPQExpBuffer(q, " LEXTYPES = %s );\n",
14639  convertTSFunction(fout, prsinfo->prslextype));
14640 
14641  appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
14642  fmtQualifiedDumpable(prsinfo));
14643 
14644  if (dopt->binary_upgrade)
14646  "TEXT SEARCH PARSER", qprsname,
14647  prsinfo->dobj.namespace->dobj.name);
14648 
14649  if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14650  ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
14651  ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
14652  .namespace = prsinfo->dobj.namespace->dobj.name,
14653  .description = "TEXT SEARCH PARSER",
14654  .section = SECTION_PRE_DATA,
14655  .createStmt = q->data,
14656  .dropStmt = delq->data));
14657 
14658  /* Dump Parser Comments */
14659  if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14660  dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
14661  prsinfo->dobj.namespace->dobj.name, "",
14662  prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
14663 
14664  destroyPQExpBuffer(q);
14665  destroyPQExpBuffer(delq);
14666  free(qprsname);
14667 }
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:13275
#define InvalidOid
Definition: postgres_ext.h:36
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 14754 of file pg_dump.c.

14755 {
14756  DumpOptions *dopt = fout->dopt;
14757  PQExpBuffer q;
14758  PQExpBuffer delq;
14759  char *qtmplname;
14760 
14761  /* Do nothing in data-only dump */
14762  if (dopt->dataOnly)
14763  return;
14764 
14765  q = createPQExpBuffer();
14766  delq = createPQExpBuffer();
14767 
14768  qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
14769 
14770  appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
14771  fmtQualifiedDumpable(tmplinfo));
14772 
14773  if (tmplinfo->tmplinit != InvalidOid)
14774  appendPQExpBuffer(q, " INIT = %s,\n",
14775  convertTSFunction(fout, tmplinfo->tmplinit));
14776  appendPQExpBuffer(q, " LEXIZE = %s );\n",
14777  convertTSFunction(fout, tmplinfo->tmpllexize));
14778 
14779  appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
14780  fmtQualifiedDumpable(tmplinfo));
14781 
14782  if (dopt->binary_upgrade)
14783  binary_upgrade_extension_member(q, &tmplinfo->dobj,
14784  "TEXT SEARCH TEMPLATE", qtmplname,
14785  tmplinfo->dobj.namespace->dobj.name);
14786 
14787  if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14788  ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
14789  ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
14790  .namespace = tmplinfo->dobj.namespace->dobj.name,
14791  .description = "TEXT SEARCH TEMPLATE",
14792  .section = SECTION_PRE_DATA,
14793  .createStmt = q->data,
14794  .dropStmt = delq->data));
14795 
14796  /* Dump Template Comments */
14797  if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14798  dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
14799  tmplinfo->dobj.namespace->dobj.name, "",
14800  tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
14801 
14802  destroyPQExpBuffer(q);
14803  destroyPQExpBuffer(delq);
14804  free(qtmplname);
14805 }
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 10995 of file pg_dump.c.

10996 {
10997  DumpOptions *dopt = fout->dopt;
10998 
10999  /* Do nothing in data-only dump */
11000  if (dopt->dataOnly)
11001  return;
11002 
11003  /* Dump out in proper style */
11004  if (tyinfo->typtype == TYPTYPE_BASE)
11005  dumpBaseType(fout, tyinfo);
11006  else if (tyinfo->typtype == TYPTYPE_DOMAIN)
11007  dumpDomain(fout, tyinfo);
11008  else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
11009  dumpCompositeType(fout, tyinfo);
11010  else if (tyinfo->typtype == TYPTYPE_ENUM)
11011  dumpEnumType(fout, tyinfo);
11012  else if (tyinfo->typtype == TYPTYPE_RANGE)
11013  dumpRangeType(fout, tyinfo);
11014  else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
11015  dumpUndefinedType(fout, tyinfo);
11016  else
11017  pg_log_warning("typtype of data type \"%s\" appears to be invalid",
11018  tyinfo->dobj.name);
11019 }
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11388
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11166
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11637
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11324
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11810
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11026
bool isDefined
Definition: pg_dump.h:207
char typtype
Definition: pg_dump.h:204

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

11325 {
11326  DumpOptions *dopt = fout->dopt;
11328  PQExpBuffer delq = createPQExpBuffer();
11329  char *qtypname;
11330  char *qualtypname;
11331 
11332  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11333  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11334 
11335  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11336 
11337  if (dopt->binary_upgrade)
11339  tyinfo->dobj.catId.oid,
11340  false, false);
11341 
11342  appendPQExpBuffer(q, "CREATE TYPE %s;\n",
11343  qualtypname);
11344 
11345  if (dopt->binary_upgrade)
11347  "TYPE", qtypname,
11348  tyinfo->dobj.namespace->dobj.name);
11349 
11350  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11351  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11352  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11353  .namespace = tyinfo->dobj.namespace->dobj.name,
11354  .owner = tyinfo->rolname,
11355  .description = "TYPE",
11356  .section = SECTION_PRE_DATA,
11357  .createStmt = q->data,
11358  .dropStmt = delq->data));
11359 
11360  /* Dump Type Comments and Security Labels */
11361  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11362  dumpComment(fout, "TYPE", qtypname,
11363  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11364  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11365 
11366  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11367  dumpSecLabel(fout, "TYPE", qtypname,
11368  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11369  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11370 
11371  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11372  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11373  qtypname, NULL,
11374  tyinfo->dobj.namespace->dobj.name,
11375  NULL, tyinfo->rolname, &tyinfo->dacl);
11376 
11377  destroyPQExpBuffer(q);
11378  destroyPQExpBuffer(delq);
11379  free(qtypname);
11380  free(qualtypname);
11381 }

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

15106 {
15107  PQExpBuffer q;
15108  PQExpBuffer delq;
15109  PQExpBuffer query;
15110  PQExpBuffer tag;
15111  PGresult *res;
15112  int ntups;
15113  int i_usename;
15114  int i_umoptions;
15115  int i;
15116 
15117  q = createPQExpBuffer();
15118  tag = createPQExpBuffer();
15119  delq = createPQExpBuffer();
15120  query = createPQExpBuffer();
15121 
15122  /*
15123  * We read from the publicly accessible view pg_user_mappings, so as not
15124  * to fail if run by a non-superuser. Note that the view will show
15125  * umoptions as null if the user hasn't got privileges for the associated
15126  * server; this means that pg_dump will dump such a mapping, but with no
15127  * OPTIONS clause. A possible alternative is to skip such mappings
15128  * altogether, but it's not clear that that's an improvement.
15129  */
15130  appendPQExpBuffer(query,
15131  "SELECT usename, "
15132  "array_to_string(ARRAY("
15133  "SELECT quote_ident(option_name) || ' ' || "
15134  "quote_literal(option_value) "
15135  "FROM pg_options_to_table(umoptions) "
15136  "ORDER BY option_name"
15137  "), E',\n ') AS umoptions "
15138  "FROM pg_user_mappings "
15139  "WHERE srvid = '%u' "
15140  "ORDER BY usename",
15141  catalogId.oid);
15142 
15143  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15144 
15145  ntups = PQntuples(res);
15146  i_usename = PQfnumber(res, "usename");
15147  i_umoptions = PQfnumber(res, "umoptions");
15148 
15149  for (i = 0; i < ntups; i++)
15150  {
15151  char *usename;
15152  char *umoptions;
15153 
15154  usename = PQgetvalue(res, i, i_usename);
15155  umoptions = PQgetvalue(res, i, i_umoptions);
15156 
15157  resetPQExpBuffer(q);
15158  appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
15159  appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
15160 
15161  if (umoptions && strlen(umoptions) > 0)
15162  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions);
15163 
15164  appendPQExpBufferStr(q, ";\n");
15165 
15166  resetPQExpBuffer(delq);
15167  appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
15168  appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
15169 
15170  resetPQExpBuffer(tag);
15171  appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
15172  usename, servername);
15173 
15175  ARCHIVE_OPTS(.tag = tag->data,
15176  .namespace = namespace,
15177  .owner = owner,
15178  .description = "USER MAPPING",
15179  .section = SECTION_PRE_DATA,
15180  .createStmt = q->data,
15181  .dropStmt = delq->data));
15182  }
15183 
15184  PQclear(res);
15185 
15186  destroyPQExpBuffer(query);
15187  destroyPQExpBuffer(delq);
15188  destroyPQExpBuffer(tag);
15189  destroyPQExpBuffer(q);
15190 }

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

1481 {
1482  PQExpBuffer query;
1483  PGresult *res;
1484  SimpleStringListCell *cell;
1485  int i;
1486 
1487  if (patterns->head == NULL)
1488  return; /* nothing to do */
1489 
1490  query = createPQExpBuffer();
1491 
1492  /*
1493  * The loop below runs multiple SELECTs might sometimes result in
1494  * duplicate entries in the OID list, but we don't care.
1495  */
1496  for (cell = patterns->head; cell; cell = cell->next)
1497  {
1498  int dotcnt;
1499 
1500  appendPQExpBufferStr(query,
1501  "SELECT oid FROM pg_catalog.pg_extension e\n");
1502  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1503  false, NULL, "e.extname", NULL, NULL, NULL,
1504  &dotcnt);
1505  if (dotcnt > 0)
1506  pg_fatal("improper qualified name (too many dotted names): %s",
1507  cell->val);
1508 
1509  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1510  if (strict_names && PQntuples(res) == 0)
1511  pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
1512 
1513  for (i = 0; i < PQntuples(res); i++)
1514  {
1516  }
1517 
1518  PQclear(res);
1519  resetPQExpBuffer(query);
1520  }
1521 
1522  destroyPQExpBuffer(query);
1523 }
static int strict_names
Definition: pg_dump.c:108
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 1530 of file pg_dump.c.

1533 {
1534  PQExpBuffer query;
1535  PGresult *res;
1536  SimpleStringListCell *cell;
1537  int i;
1538 
1539  if (patterns->head == NULL)
1540  return; /* nothing to do */
1541 
1542  query = createPQExpBuffer();
1543 
1544  /*
1545  * The loop below runs multiple SELECTs might sometimes result in
1546  * duplicate entries in the OID list, but we don't care.
1547  */
1548 
1549  for (cell = patterns->head; cell; cell = cell->next)
1550  {
1551  int dotcnt;
1552 
1553  appendPQExpBufferStr(query,
1554  "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
1555  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1556  false, NULL, "s.srvname", NULL, NULL, NULL,
1557  &dotcnt);
1558  if (dotcnt > 0)
1559  pg_fatal("improper qualified name (too many dotted names): %s",
1560  cell->val);
1561 
1562  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1563  if (PQntuples(res) == 0)
1564  pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
1565 
1566  for (i = 0; i < PQntuples(res); i++)
1568 
1569  PQclear(res);
1570  resetPQExpBuffer(query);
1571  }
1572 
1573  destroyPQExpBuffer(query);
1574 }

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

1422 {
1423  PQExpBuffer query;
1424  PGresult *res;
1425  SimpleStringListCell *cell;
1426  int i;
1427 
1428  if (patterns->head == NULL)
1429  return; /* nothing to do */
1430 
1431  query = createPQExpBuffer();
1432 
1433  /*
1434  * The loop below runs multiple SELECTs might sometimes result in
1435  * duplicate entries in the OID list, but we don't care.
1436  */
1437 
1438  for (cell = patterns->head; cell; cell = cell->next)
1439  {
1440  PQExpBufferData dbbuf;
1441  int dotcnt;
1442 
1443  appendPQExpBufferStr(query,
1444  "SELECT oid FROM pg_catalog.pg_namespace n\n");
1445  initPQExpBuffer(&dbbuf);
1446  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1447  false, NULL, "n.nspname", NULL, NULL, &dbbuf,
1448  &dotcnt);
1449  if (dotcnt > 1)
1450  pg_fatal("improper qualified name (too many dotted names): %s",
1451  cell->val);
1452  else if (dotcnt == 1)
1453  prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1454  termPQExpBuffer(&dbbuf);
1455 
1456  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1457  if (strict_names && PQntuples(res) == 0)
1458  pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
1459 
1460  for (i = 0; i < PQntuples(res); i++)
1461  {
1463  }
1464 
1465  PQclear(res);
1466  resetPQExpBuffer(query);
1467  }
1468 
1469  destroyPQExpBuffer(query);
1470 }
static void prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
Definition: pg_dump.c:1678
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 1582 of file pg_dump.c.

1585 {
1586  PQExpBuffer query;
1587  PGresult *res;
1588  SimpleStringListCell *cell;
1589  int i;
1590 
1591  if (patterns->head == NULL)
1592  return; /* nothing to do */
1593 
1594  query = createPQExpBuffer();
1595 
1596  /*
1597  * this might sometimes result in duplicate entries in the OID list, but
1598  * we don't care.
1599  */
1600 
1601  for (cell = patterns->head; cell; cell = cell->next)
1602  {
1603  PQExpBufferData dbbuf;
1604  int dotcnt;
1605 
1606  /*
1607  * Query must remain ABSOLUTELY devoid of unqualified names. This
1608  * would be unnecessary given a pg_table_is_visible() variant taking a
1609  * search_path argument.
1610  *
1611  * For with_child_tables, we start with the basic query's results and
1612  * recursively search the inheritance tree to add child tables.
1613  */
1614  if (with_child_tables)
1615  {
1616  appendPQExpBuffer(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
1617  }
1618 
1619  appendPQExpBuffer(query,
1620  "SELECT c.oid"
1621  "\nFROM pg_catalog.pg_class c"
1622  "\n LEFT JOIN pg_catalog.pg_namespace n"
1623  "\n ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
1624  "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
1625  "\n (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
1626  RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
1627  RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
1628  RELKIND_PARTITIONED_TABLE);
1629  initPQExpBuffer(&dbbuf);
1630  processSQLNamePattern(GetConnection(fout), query, cell->val, true,
1631  false, "n.nspname", "c.relname", NULL,
1632  "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
1633  &dotcnt);
1634  if (dotcnt > 2)
1635  pg_fatal("improper relation name (too many dotted names): %s",
1636  cell->val);
1637  else if (dotcnt == 2)
1638  prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1639  termPQExpBuffer(&dbbuf);
1640 
1641  if (with_child_tables)
1642  {
1643  appendPQExpBuffer(query, "UNION"
1644  "\nSELECT i.inhrelid"
1645  "\nFROM partition_tree p"
1646  "\n JOIN pg_catalog.pg_inherits i"
1647  "\n ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
1648  "\n)"
1649  "\nSELECT relid FROM partition_tree");
1650  }
1651 
1652  ExecuteSqlStatement(fout, "RESET search_path");
1653  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1656  if (strict_names && PQntuples(res) == 0)
1657  pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
1658 
1659  for (i = 0; i < PQntuples(res); i++)
1660  {
1662  }
1663 
1664  PQclear(res);
1665  resetPQExpBuffer(query);
1666  }
1667 
1668  destroyPQExpBuffer(query);
1669 }
#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 10435 of file pg_dump.c.

10436 {
10437  CommentItem *middle = NULL;
10438  CommentItem *low;
10439  CommentItem *high;
10440  int nmatch;
10441 
10442  /*
10443  * Do binary search to find some item matching the object.
10444  */
10445  low = &comments[0];
10446  high = &comments[ncomments - 1];
10447  while (low <= high)
10448  {
10449  middle = low + (high - low) / 2;
10450 
10451  if (classoid < middle->classoid)
10452  high = middle - 1;
10453  else if (classoid > middle->classoid)
10454  low = middle + 1;
10455  else if (objoid < middle->objoid)
10456  high = middle - 1;
10457  else if (objoid > middle->objoid)
10458  low = middle + 1;
10459  else
10460  break; /* found a match */
10461  }
10462 
10463  if (low > high) /* no matches */
10464  {
10465  *items = NULL;
10466  return 0;
10467  }
10468 
10469  /*
10470  * Now determine how many items match the object. The search loop
10471  * invariant still holds: only items between low and high inclusive could
10472  * match.
10473  */
10474  nmatch = 1;
10475  while (middle > low)
10476  {
10477  if (classoid != middle[-1].classoid ||
10478  objoid != middle[-1].objoid)
10479  break;
10480  middle--;
10481  nmatch++;
10482  }
10483 
10484  *items = middle;
10485 
10486  middle += nmatch;
10487  while (middle <= high)
10488  {
10489  if (classoid != middle->classoid ||
10490  objoid != middle->objoid)
10491  break;
10492  middle++;
10493  nmatch++;
10494  }
10495 
10496  return nmatch;
10497 }
static ItemArray items
Definition: test_tidstore.c:49

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

18864 {
18865  int i;
18866 
18867  /*
18868  * Ignore section boundary objects: if we search through them, we'll
18869  * report lots of bogus dependencies.
18870  */
18871  if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
18872  dobj->objType == DO_POST_DATA_BOUNDARY)
18873  return;
18874 
18875  for (i = 0; i < dobj->nDeps; i++)
18876  {
18877  DumpId depid = dobj->dependencies[i];
18878 
18879  if (TocIDRequired(AH, depid) != 0)
18880  {
18881  /* Object will be dumped, so just reference it as a dependency */
18882  if (*nDeps >= *allocDeps)
18883  {
18884  *allocDeps *= 2;
18885  *dependencies = (DumpId *) pg_realloc(*dependencies,
18886  *allocDeps * sizeof(DumpId));
18887  }
18888  (*dependencies)[*nDeps] = depid;
18889  (*nDeps)++;
18890  }
18891  else
18892  {
18893  /*
18894  * Object will not be dumped, so recursively consider its deps. We
18895  * rely on the assumption that sortDumpableObjects already broke
18896  * any dependency loops, else we might recurse infinitely.
18897  */
18898  DumpableObject *otherdobj = findObjectByDumpId(depid);
18899 
18900  if (otherdobj)
18901  findDumpableDependencies(AH, otherdobj,
18902  dependencies, nDeps, allocDeps);
18903  }
18904  }
18905 }
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 5674 of file pg_dump.c.

5675 {
5676  NamespaceInfo *nsinfo;
5677 
5678  nsinfo = findNamespaceByOid(nsoid);
5679  if (nsinfo == NULL)
5680  pg_fatal("schema with OID %u does not exist", nsoid);
5681  return nsinfo;
5682 }
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:963

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

15576 {
15577  SecLabelItem *middle = NULL;
15578  SecLabelItem *low;
15579  SecLabelItem *high;
15580  int nmatch;
15581 
15582  if (nseclabels <= 0) /* no labels, so no match is possible */
15583  {
15584  *items = NULL;
15585  return 0;
15586  }
15587 
15588  /*
15589  * Do binary search to find some item matching the object.
15590  */
15591  low = &seclabels[0];
15592  high = &seclabels[nseclabels - 1];
15593  while (low <= high)
15594  {
15595  middle = low + (high - low) / 2;
15596 
15597  if (classoid < middle->classoid)
15598  high = middle - 1;
15599  else if (classoid > middle->classoid)
15600  low = middle + 1;
15601  else if (objoid < middle->objoid)
15602  high = middle - 1;
15603  else if (objoid > middle->objoid)
15604  low = middle + 1;
15605  else
15606  break; /* found a match */
15607  }
15608 
15609  if (low > high) /* no matches */
15610  {
15611  *items = NULL;
15612  return 0;
15613  }
15614 
15615  /*
15616  * Now determine how many items match the object. The search loop
15617  * invariant still holds: only items between low and high inclusive could
15618  * match.
15619  */
15620  nmatch = 1;
15621  while (middle > low)
15622  {
15623  if (classoid != middle[-1].classoid ||
15624  objoid != middle[-1].objoid)
15625  break;
15626  middle--;
15627  nmatch++;
15628  }
15629 
15630  *items = middle;
15631 
15632  middle += nmatch;
15633  while (middle <= high)
15634  {
15635  if (classoid != middle->classoid ||
15636  objoid != middle->objoid)
15637  break;
15638  middle++;
15639  nmatch++;
15640  }
15641 
15642  return nmatch;
15643 }

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

18970 {
18971  int numatts = ti->numatts;
18972  char **attnames = ti->attnames;
18973  bool *attisdropped = ti->attisdropped;
18974  char *attgenerated = ti->attgenerated;
18975  bool needComma;
18976  int i;
18977 
18978  appendPQExpBufferChar(buffer, '(');
18979  needComma = false;
18980  for (i = 0; i < numatts; i++)
18981  {
18982  if (attisdropped[i])
18983  continue;
18984  if (attgenerated[i])
18985  continue;
18986  if (needComma)
18987  appendPQExpBufferStr(buffer, ", ");
18988  appendPQExpBufferStr(buffer, fmtId(attnames[i]));
18989  needComma = true;
18990  }
18991 
18992  if (!needComma)
18993  return ""; /* no undropped columns */
18994 
18995  appendPQExpBufferChar(buffer, ')');
18996  return buffer->data;
18997 }

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

2574 {
2575  TableInfo *parentTbinfo;
2576 
2577  Assert(tbinfo->ispartition);
2578  Assert(tbinfo->numParents == 1);
2579 
2580  parentTbinfo = tbinfo->parents[0];
2581  if (parentTbinfo->unsafe_partitions)
2582  return true;
2583  while (parentTbinfo->ispartition)
2584  {
2585  Assert(parentTbinfo->numParents == 1);
2586  parentTbinfo = parentTbinfo->parents[0];
2587  if (parentTbinfo->unsafe_partitions)
2588  return true;
2589  }
2590 
2591  return false;
2592 }
bool unsafe_partitions
Definition: pg_dump.h:323

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

14219 {
14221  int j;
14222 
14223  initPQExpBuffer(&buf);
14224  if (honor_quotes)
14225  appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
14226  else
14227  appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
14228 
14229  if (agginfo->aggfn.nargs == 0)
14230  appendPQExpBufferStr(&buf, "(*)");
14231  else
14232  {
14233  appendPQExpBufferChar(&buf, '(');
14234  for (j = 0; j < agginfo->aggfn.nargs; j++)
14235  appendPQExpBuffer(&buf, "%s%s",
14236  (j > 0) ? ", " : "",
14237  getFormattedTypeName(fout,
14238  agginfo->aggfn.argtypes[j],
14239  zeroIsError));
14240  appendPQExpBufferChar(&buf, ')');
14241  }
14242  return buf.data;
14243 }

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

12284 {
12286 
12287  initPQExpBuffer(&fn);
12288  appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
12289  if (is_agg && finfo->nargs == 0)
12290  appendPQExpBufferStr(&fn, "(*)");
12291  else
12292  appendPQExpBuffer(&fn, "(%s)", funcargs);
12293  return fn.data;
12294 }
int nargs
Definition: pg_dump.h:228
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 12306 of file pg_dump.c.

12307 {
12309  int j;
12310 
12311  initPQExpBuffer(&fn);
12312  if (honor_quotes)
12313  appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
12314  else
12315  appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
12316  for (j = 0; j < finfo->nargs; j++)
12317  {
12318  if (j > 0)
12319  appendPQExpBufferStr(&fn, ", ");
12320 
12322  getFormattedTypeName(fout, finfo->argtypes[j],
12323  zeroIsError));
12324  }
12325  appendPQExpBufferChar(&fn, ')');
12326  return fn.data;
12327 }
Oid * argtypes
Definition: pg_dump.h:229

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

8570 {
8571  PQExpBuffer query;
8572  PGresult *res;
8573  char *lanname;
8574 
8575  query = createPQExpBuffer();
8576  appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
8577  res = ExecuteSqlQueryForSingleRow(fout, query->data);
8578  lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
8579  destroyPQExpBuffer(query);
8580  PQclear(res);
8581 
8582  return lanname;
8583 }

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

5266 {
5267  /*
5268  * If the old version didn't assign an array type, but the new version
5269  * does, we must select an unused type OID to assign. This currently only
5270  * happens for domains, when upgrading pre-v11 to v11 and up.
5271  *
5272  * Note: local state here is kind of ugly, but we must have some, since we
5273  * mustn't choose the same unused OID more than once.
5274  */
5275  static Oid next_possible_free_oid = FirstNormalObjectId;
5276  PGresult *res;
5277  bool is_dup;
5278 
5279  do
5280  {
5281  ++next_possible_free_oid;
5282  printfPQExpBuffer(upgrade_query,
5283  "SELECT EXISTS(SELECT 1 "
5284  "FROM pg_catalog.pg_type "
5285  "WHERE oid = '%u'::pg_catalog.oid);",
5286  next_possible_free_oid);
5287  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5288  is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
5289  PQclear(res);
5290  } while (is_dup);
5291 
5292  return next_possible_free_oid;
5293 }
#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 1366 of file pg_dump.c.

1367 {
1368  char *query = "SELECT pg_catalog.pg_export_snapshot()";
1369  char *result;
1370  PGresult *res;
1371 
1372  res = ExecuteSqlQueryForSingleRow(fout, query);
1373  result = pg_strdup(PQgetvalue(res, 0, 0));
1374  PQclear(res);
1375 
1376  return result;
1377 }

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

Referenced by setup_connection().

◆ getAccessMethods()

AccessMethodInfo* getAccessMethods ( Archive fout,
int *  numAccessMethods 
)

Definition at line 6147 of file pg_dump.c.

6148 {
6149  PGresult *res;
6150  int ntups;
6151  int i;
6152  PQExpBuffer query;
6153  AccessMethodInfo *aminfo;
6154  int i_tableoid;
6155  int i_oid;
6156  int i_amname;
6157  int i_amhandler;
6158  int i_amtype;
6159 
6160  /* Before 9.6, there are no user-defined access methods */
6161  if (fout->remoteVersion < 90600)
6162  {
6163  *numAccessMethods = 0;
6164  return NULL;
6165  }
6166 
6167  query = createPQExpBuffer();
6168 
6169  /* Select all access methods from pg_am table */
6170  appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6171  "amhandler::pg_catalog.regproc AS amhandler "
6172  "FROM pg_am");
6173 
6174  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6175 
6176  ntups = PQntuples(res);
6177  *numAccessMethods = ntups;
6178 
6179  aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6180 
6181  i_tableoid = PQfnumber(res, "tableoid");
6182  i_oid = PQfnumber(res, "oid");
6183  i_amname = PQfnumber(res, "amname");
6184  i_amhandler = PQfnumber(res, "amhandler");
6185  i_amtype = PQfnumber(res, "amtype");
6186 
6187  for (i = 0; i < ntups; i++)
6188  {
6189  aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6190  aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6191  aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6192  AssignDumpId(&aminfo[i].dobj);
6193  aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6194  aminfo[i].dobj.namespace = NULL;
6195  aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6196  aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6197 
6198  /* Decide whether we want to dump it */
6199  selectDumpableAccessMethod(&(aminfo[i]), fout);
6200  }
6201 
6202  PQclear(res);
6203 
6204  destroyPQExpBuffer(query);
6205 
6206  return aminfo;
6207 }
static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
Definition: pg_dump.c:2003

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

10093 {
10094  PQExpBuffer query = createPQExpBuffer();
10095  PGresult *res;
10096  int ntups,
10097  i;
10098 
10099  /* Check for per-column ACLs */
10100  appendPQExpBufferStr(query,
10101  "SELECT DISTINCT attrelid FROM pg_attribute "
10102  "WHERE attacl IS NOT NULL");
10103 
10104  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10105 
10106  ntups = PQntuples(res);
10107  for (i = 0; i < ntups; i++)
10108  {
10109  Oid relid = atooid(PQgetvalue(res, i, 0));
10110  TableInfo *tblinfo;
10111 
10112  tblinfo = findTableByOid(relid);
10113  /* OK to ignore tables we haven't got a DumpableObject for */
10114  if (tblinfo)
10115  {
10116  tblinfo->dobj.components |= DUMP_COMPONENT_ACL;
10117  tblinfo->hascolumnACLs = true;
10118  }
10119  }
10120  PQclear(res);
10121 
10122  /* Fetch initial-privileges data */
10123  if (fout->remoteVersion >= 90600)
10124  {
10125  printfPQExpBuffer(query,
10126  "SELECT objoid, classoid, objsubid, privtype, initprivs "
10127  "FROM pg_init_privs");
10128 
10129  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10130 
10131  ntups = PQntuples(res);
10132  for (i = 0; i < ntups; i++)
10133  {
10134  Oid objoid = atooid(PQgetvalue(res, i, 0));
10135  Oid classoid = atooid(PQgetvalue(res, i, 1));
10136  int objsubid = atoi(PQgetvalue(res, i, 2));
10137  char privtype = *(PQgetvalue(res, i, 3));
10138  char *initprivs = PQgetvalue(res, i, 4);
10139  CatalogId objId;
10140  DumpableObject *dobj;
10141 
10142  objId.tableoid = classoid;
10143  objId.oid = objoid;
10144  dobj = findObjectByCatalogId(objId);
10145  /* OK to ignore entries we haven't got a DumpableObject for */
10146  if (dobj)
10147  {
10148  /* Cope with sub-object initprivs */
10149  if (objsubid != 0)
10150  {
10151  if (dobj->objType == DO_TABLE)
10152  {
10153  /* For a column initprivs, set the table's ACL flags */
10154  dobj->components |= DUMP_COMPONENT_ACL;
10155  ((TableInfo *) dobj)->hascolumnACLs = true;
10156  }
10157  else
10158  pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10159  classoid, objoid, objsubid);
10160  continue;
10161  }
10162 
10163  /*
10164  * We ignore any pg_init_privs.initprivs entry for the public
10165  * schema, as explained in getNamespaces().
10166  */
10167  if (dobj->objType == DO_NAMESPACE &&
10168  strcmp(dobj->name, "public") == 0)
10169  continue;
10170 
10171  /* Else it had better be of a type we think has ACLs */
10172  if (dobj->objType == DO_NAMESPACE ||
10173  dobj->objType == DO_TYPE ||
10174  dobj->objType == DO_FUNC ||
10175  dobj->objType == DO_AGG ||
10176  dobj->objType == DO_TABLE ||
10177  dobj->objType == DO_PROCLANG ||
10178  dobj->objType == DO_FDW ||
10179  dobj->objType == DO_FOREIGN_SERVER)
10180  {
10181  DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj;
10182 
10183  daobj->dacl.privtype = privtype;
10184  daobj->dacl.initprivs = pstrdup(initprivs);
10185  }
10186  else
10187  pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10188  classoid, objoid, objsubid);
10189  }
10190  }
10191  PQclear(res);
10192  }
10193 
10194  destroyPQExpBuffer(query);
10195 }
char * pstrdup(const char *in)
Definition: mcxt.c:1695
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()

AggInfo* getAggregates ( Archive fout,
int *  numAggs 
)

Definition at line 6352 of file pg_dump.c.

6353 {
6354  DumpOptions *dopt = fout->dopt;
6355  PGresult *res;
6356  int ntups;
6357  int i;
6358  PQExpBuffer query = createPQExpBuffer();
6359  AggInfo *agginfo;
6360  int i_tableoid;
6361  int i_oid;
6362  int i_aggname;
6363  int i_aggnamespace;
6364  int i_pronargs;
6365  int i_proargtypes;
6366  int i_proowner;
6367  int i_aggacl;
6368  int i_acldefault;
6369 
6370  /*
6371  * Find all interesting aggregates. See comment in getFuncs() for the
6372  * rationale behind the filtering logic.
6373  */
6374  if (fout->remoteVersion >= 90600)
6375  {
6376  const char *agg_check;
6377 
6378  agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
6379  : "p.proisagg");
6380 
6381  appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
6382  "p.proname AS aggname, "
6383  "p.pronamespace AS aggnamespace, "
6384  "p.pronargs, p.proargtypes, "
6385  "p.proowner, "
6386  "p.proacl AS aggacl, "
6387  "acldefault('f', p.proowner) AS acldefault "
6388  "FROM pg_proc p "
6389  "LEFT JOIN pg_init_privs pip ON "
6390  "(p.oid = pip.objoid "
6391  "AND pip.classoid = 'pg_proc'::regclass "
6392  "AND pip.objsubid = 0) "
6393  "WHERE %s AND ("
6394  "p.pronamespace != "
6395  "(SELECT oid FROM pg_namespace "
6396  "WHERE nspname = 'pg_catalog') OR "
6397  "p.proacl IS DISTINCT FROM pip.initprivs",
6398  agg_check);
6399  if (dopt->binary_upgrade)
6400  appendPQExpBufferStr(query,
6401  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6402  "classid = 'pg_proc'::regclass AND "
6403  "objid = p.oid AND "
6404  "refclassid = 'pg_extension'::regclass AND "
6405  "deptype = 'e')");
6406  appendPQExpBufferChar(query, ')');
6407  }
6408  else
6409  {
6410  appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
6411  "pronamespace AS aggnamespace, "
6412  "pronargs, proargtypes, "
6413  "proowner, "
6414  "proacl AS aggacl, "
6415  "acldefault('f', proowner) AS acldefault "
6416  "FROM pg_proc p "
6417  "WHERE proisagg AND ("
6418  "pronamespace != "
6419  "(SELECT oid FROM pg_namespace "
6420  "WHERE nspname = 'pg_catalog')");
6421  if (dopt->binary_upgrade)
6422  appendPQExpBufferStr(query,
6423  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6424  "classid = 'pg_proc'::regclass AND "
6425  "objid = p.oid AND "
6426  "refclassid = 'pg_extension'::regclass AND "
6427  "deptype = 'e')");
6428  appendPQExpBufferChar(query, ')');
6429  }
6430 
6431  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6432 
6433  ntups = PQntuples(res);
6434  *numAggs = ntups;
6435 
6436  agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
6437 
6438  i_tableoid = PQfnumber(res, "tableoid");
6439  i_oid = PQfnumber(res, "oid");
6440  i_aggname = PQfnumber(res, "aggname");
6441  i_aggnamespace = PQfnumber(res, "aggnamespace");
6442  i_pronargs = PQfnumber(res, "pronargs");
6443  i_proargtypes = PQfnumber(res, "proargtypes");
6444  i_proowner = PQfnumber(res, "proowner");
6445  i_aggacl = PQfnumber(res, "aggacl");
6446  i_acldefault = PQfnumber(res, "acldefault");
6447 
6448  for (i = 0; i < ntups; i++)
6449  {
6450  agginfo[i].aggfn.dobj.objType = DO_AGG;
6451  agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6452  agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6453  AssignDumpId(&agginfo[i].aggfn.dobj);
6454  agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
6455  agginfo[i].aggfn.dobj.namespace =
6456  findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
6457  agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
6458  agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6459  agginfo[i].aggfn.dacl.privtype = 0;
6460  agginfo[i].aggfn.dacl.initprivs = NULL;
6461  agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6462  agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
6463  agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
6464  agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
6465  if (agginfo[i].aggfn.nargs == 0)
6466  agginfo[i].aggfn.argtypes = NULL;
6467  else
6468  {
6469  agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
6470  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6471  agginfo[i].aggfn.argtypes,
6472  agginfo[i].aggfn.nargs);
6473  }
6474  agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
6475 
6476  /* Decide whether we want to dump it */
6477  selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
6478 
6479  /* Mark whether aggregate has an ACL */
6480  if (!PQgetisnull(res, i, i_aggacl))
6481  agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
6482  }
6483 
6484  PQclear(res);
6485 
6486  destroyPQExpBuffer(query);
6487 
6488  return agginfo;
6489 }
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2106
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:5674

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

16939 {
16940  if (attrnum > 0 && attrnum <= tblInfo->numatts)
16941  return tblInfo->attnames[attrnum - 1];
16942  switch (attrnum)
16943  {
16945  return "ctid";
16947  return "xmin";
16949  return "cmin";
16951  return "xmax";
16953  return "cmax";
16955  return "tableoid";
16956  }
16957  pg_fatal("invalid column number %d for table \"%s\"",
16958  attrnum, tblInfo->dobj.name);
16959  return NULL; /* keep compiler quiet */
16960 }
#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()

CastInfo* getCasts ( Archive fout,
int *  numCasts 
)

Definition at line 8476 of file pg_dump.c.

8477 {
8478  PGresult *res;
8479  int ntups;
8480  int i;
8481  PQExpBuffer query = createPQExpBuffer();
8482  CastInfo *castinfo;
8483  int i_tableoid;
8484  int i_oid;
8485  int i_castsource;
8486  int i_casttarget;
8487  int i_castfunc;
8488  int i_castcontext;
8489  int i_castmethod;
8490 
8491  if (fout->remoteVersion >= 140000)
8492  {
8493  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8494  "castsource, casttarget, castfunc, castcontext, "
8495  "castmethod "
8496  "FROM pg_cast c "
8497  "WHERE NOT EXISTS ( "
8498  "SELECT 1 FROM pg_range r "
8499  "WHERE c.castsource = r.rngtypid "
8500  "AND c.casttarget = r.rngmultitypid "
8501  ") "
8502  "ORDER BY 3,4");
8503  }
8504  else
8505  {
8506  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8507  "castsource, casttarget, castfunc, castcontext, "
8508  "castmethod "
8509  "FROM pg_cast ORDER BY 3,4");
8510  }
8511 
8512  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8513 
8514  ntups = PQntuples(res);
8515 
8516  *numCasts = ntups;
8517 
8518  castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8519 
8520  i_tableoid = PQfnumber(res, "tableoid");
8521  i_oid = PQfnumber(res, "oid");
8522  i_castsource = PQfnumber(res, "castsource");
8523  i_casttarget = PQfnumber(res, "casttarget");
8524  i_castfunc = PQfnumber(res, "castfunc");
8525  i_castcontext = PQfnumber(res, "castcontext");
8526  i_castmethod = PQfnumber(res, "castmethod");
8527 
8528  for (i = 0; i < ntups; i++)
8529  {
8530  PQExpBufferData namebuf;
8531  TypeInfo *sTypeInfo;
8532  TypeInfo *tTypeInfo;
8533 
8534  castinfo[i].dobj.objType = DO_CAST;
8535  castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8536  castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8537  AssignDumpId(&castinfo[i].dobj);
8538  castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8539  castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8540  castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8541  castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8542  castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8543 
8544  /*
8545  * Try to name cast as concatenation of typnames. This is only used
8546  * for purposes of sorting. If we fail to find either type, the name
8547  * will be an empty string.
8548  */
8549  initPQExpBuffer(&namebuf);
8550  sTypeInfo = findTypeByOid(castinfo[i].castsource);
8551  tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8552  if (sTypeInfo && tTypeInfo)
8553  appendPQExpBuffer(&namebuf, "%s %s",
8554  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8555  castinfo[i].dobj.name = namebuf.data;
8556 
8557  /* Decide whether we want to dump it */
8558  selectDumpableCast(&(castinfo[i]), fout);
8559  }
8560 
8561  PQclear(res);
8562 
8563  destroyPQExpBuffer(query);
8564 
8565  return castinfo;
8566 }
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:1945

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()

CollInfo* getCollations ( Archive fout,
int *  numCollations 
)

Definition at line 6011 of file pg_dump.c.

6012 {
6013  PGresult *res;
6014  int ntups;
6015  int i;
6016  PQExpBuffer query;
6017  CollInfo *collinfo;
6018  int i_tableoid;
6019  int i_oid;
6020  int i_collname;
6021  int i_collnamespace;
6022  int i_collowner;
6023 
6024  query = createPQExpBuffer();
6025 
6026  /*
6027  * find all collations, including builtin collations; we filter out
6028  * system-defined collations at dump-out time.
6029  */
6030 
6031  appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6032  "collnamespace, "
6033  "collowner "
6034  "FROM pg_collation");
6035 
6036  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6037 
6038  ntups = PQntuples(res);
6039  *numCollations = ntups;
6040 
6041  collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6042 
6043  i_tableoid = PQfnumber(res, "tableoid");
6044  i_oid = PQfnumber(res, "oid");
6045  i_collname = PQfnumber(res, "collname");
6046  i_collnamespace = PQfnumber(res, "collnamespace");
6047  i_collowner = PQfnumber(res, "collowner");
6048 
6049  for (i = 0; i < ntups; i++)
6050  {
6051  collinfo[i].dobj.objType = DO_COLLATION;
6052  collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6053  collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6054  AssignDumpId(&collinfo[i].dobj);
6055  collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6056  collinfo[i].dobj.namespace =
6057  findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6058  collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6059 
6060  /* Decide whether we want to dump it */
6061  selectDumpableObject(&(collinfo[i].dobj), fout);
6062  }
6063 
6064  PQclear(res);
6065 
6066  destroyPQExpBuffer(query);
6067 
6068  return collinfo;
6069 }

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

7723 {
7724  PQExpBuffer query = createPQExpBuffer();
7725  PQExpBuffer tbloids = createPQExpBuffer();
7726  PGresult *res;
7727  int ntups;
7728  int curtblindx;
7729  TableInfo *tbinfo = NULL;
7730  ConstraintInfo *constrinfo;
7731  int i_contableoid,
7732  i_conoid,
7733  i_conrelid,
7734  i_conname,
7735  i_confrelid,
7736  i_conindid,
7737  i_condef;
7738 
7739  /*
7740  * We want to perform just one query against pg_constraint. However, we
7741  * mustn't try to select every row of the catalog and then sort it out on
7742  * the client side, because some of the server-side functions we need
7743  * would be unsafe to apply to tables we don't have lock on. Hence, we
7744  * build an array of the OIDs of tables we care about (and now have lock
7745  * on!), and use a WHERE clause to constrain which rows are selected.
7746  */
7747  appendPQExpBufferChar(tbloids, '{');
7748  for (int i = 0; i < numTables; i++)
7749  {
7750  TableInfo *tinfo = &tblinfo[i];
7751 
7752  /*
7753  * For partitioned tables, foreign keys have no triggers so they must
7754  * be included anyway in case some foreign keys are defined.
7755  */
7756  if ((!tinfo->hastriggers &&
7757  tinfo->relkind != RELKIND_PARTITIONED_TABLE) ||
7758  !(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
7759  continue;
7760 
7761  /* OK, we need info for this table */
7762  if (tbloids->len > 1) /* do we have more than the '{'? */
7763  appendPQExpBufferChar(tbloids, ',');
7764  appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
7765  }
7766  appendPQExpBufferChar(tbloids, '}');
7767 
7768  appendPQExpBufferStr(query,
7769  "SELECT c.tableoid, c.oid, "
7770  "conrelid, conname, confrelid, ");
7771  if (fout->remoteVersion >= 110000)
7772  appendPQExpBufferStr(query, "conindid, ");
7773  else
7774  appendPQExpBufferStr(query, "0 AS conindid, ");
7775  appendPQExpBuffer(query,
7776  "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
7777  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7778  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
7779  "WHERE contype = 'f' ",
7780  tbloids->data);
7781  if (fout->remoteVersion >= 110000)
7782  appendPQExpBufferStr(query,
7783  "AND conparentid = 0 ");
7784  appendPQExpBufferStr(query,
7785  "ORDER BY conrelid, conname");
7786 
7787  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7788 
7789  ntups = PQntuples(res);
7790 
7791  i_contableoid = PQfnumber(res, "tableoid");
7792  i_conoid = PQfnumber(res, "oid");
7793  i_conrelid = PQfnumber(res, "conrelid");
7794  i_conname = PQfnumber(res, "conname");
7795  i_confrelid = PQfnumber(res, "confrelid");
7796  i_conindid = PQfnumber(res, "conindid");
7797  i_condef = PQfnumber(res, "condef");
7798 
7799  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
7800 
7801  curtblindx = -1;
7802  for (int j = 0; j < ntups; j++)
7803  {
7804  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
7805  TableInfo *reftable;
7806 
7807  /*
7808  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7809  * order.
7810  */
7811  if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
7812  {
7813  while (++curtblindx < numTables)
7814  {
7815  tbinfo = &tblinfo[curtblindx];
7816  if (tbinfo->dobj.catId.oid == conrelid)
7817  break;
7818  }
7819  if (curtblindx >= numTables)
7820  pg_fatal("unrecognized table OID %u", conrelid);
7821  }
7822 
7823  constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
7824  constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7825  constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7826  AssignDumpId(&constrinfo[j].dobj);
7827  constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7828  constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7829  constrinfo[j].contable = tbinfo;
7830  constrinfo[j].condomain = NULL;
7831  constrinfo[j].contype = 'f';
7832  constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
7833  constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
7834  constrinfo[j].conindex = 0;
7835  constrinfo[j].condeferrable = false;
7836  constrinfo[j].condeferred = false;
7837  constrinfo[j].conislocal = true;
7838  constrinfo[j].separate = true;
7839 
7840  /*
7841  * Restoring an FK that points to a partitioned table requires that
7842  * all partition indexes have been attached beforehand. Ensure that
7843  * happens by making the constraint depend on each index partition
7844  * attach object.
7845  */
7846  reftable = findTableByOid(constrinfo[j].confrelid);
7847  if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
7848  {
7849  Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
7850 
7851  if (indexOid != InvalidOid)
7852  {
7853  for (int k = 0; k < reftable->numIndexes; k++)
7854  {
7855  IndxInfo *refidx;
7856 
7857  /* not our index? */
7858  if (reftable->indexes[k].dobj.catId.oid != indexOid)
7859  continue;
7860 
7861  refidx = &reftable->indexes[k];
7862  addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
7863  break;
7864  }
7865  }
7866  }
7867  }
7868 
7869  PQclear(res);
7870 
7871  destroyPQExpBuffer(query);
7872  destroyPQExpBuffer(tbloids);
7873 }
static const gbtree_vinfo tinfo
Definition: btree_bit.c:109
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()

ConvInfo* getConversions ( Archive fout,
int *  numConversions 
)

Definition at line 6079 of file pg_dump.c.

6080 {
6081  PGresult *res;
6082  int ntups;
6083  int i;
6084  PQExpBuffer query;
6085  ConvInfo *convinfo;
6086  int i_tableoid;
6087  int i_oid;
6088  int i_conname;
6089  int i_connamespace;
6090  int i_conowner;
6091 
6092  query = createPQExpBuffer();
6093 
6094  /*
6095  * find all conversions, including builtin conversions; we filter out
6096  * system-defined conversions at dump-out time.
6097  */
6098 
6099  appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6100  "connamespace, "
6101  "conowner "
6102  "FROM pg_conversion");
6103 
6104  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6105 
6106  ntups = PQntuples(res);
6107  *numConversions = ntups;
6108 
6109  convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6110 
6111  i_tableoid = PQfnumber(res, "tableoid");
6112  i_oid = PQfnumber(res, "oid");
6113  i_conname = PQfnumber(res, "conname");
6114  i_connamespace = PQfnumber(res, "connamespace");
6115  i_conowner = PQfnumber(res, "conowner");
6116 
6117  for (i = 0; i < ntups; i++)
6118  {
6119  convinfo[i].dobj.objType = DO_CONVERSION;
6120  convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6121  convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6122  AssignDumpId(&convinfo[i].dobj);
6123  convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6124  convinfo[i].dobj.namespace =
6125  findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6126  convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6127 
6128  /* Decide whether we want to dump it */
6129  selectDumpableObject(&(convinfo[i].dobj), fout);
6130  }
6131 
6132  PQclear(res);
6133 
6134  destroyPQExpBuffer(query);
6135 
6136  return convinfo;
6137 }

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()

DefaultACLInfo* getDefaultACLs ( Archive fout,
int *  numDefaultACLs 
)

Definition at line 9921 of file pg_dump.c.

9922 {
9923  DumpOptions *dopt = fout->dopt;
9924  DefaultACLInfo *daclinfo;
9925  PQExpBuffer query;
9926  PGresult *res;
9927  int i_oid;
9928  int i_tableoid;
9929  int i_defaclrole;
9930  int i_defaclnamespace;
9931  int i_defaclobjtype;
9932  int i_defaclacl;
9933  int i_acldefault;
9934  int i,
9935  ntups;
9936 
9937  query = createPQExpBuffer();
9938 
9939  /*
9940  * Global entries (with defaclnamespace=0) replace the hard-wired default
9941  * ACL for their object type. We should dump them as deltas from the
9942  * default ACL, since that will be used as a starting point for
9943  * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
9944  * non-global entries can only add privileges not revoke them. We must
9945  * dump those as-is (i.e., as deltas from an empty ACL).
9946  *
9947  * We can use defaclobjtype as the object type for acldefault(), except
9948  * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
9949  * 's'.
9950  */
9951  appendPQExpBufferStr(query,
9952  "SELECT oid, tableoid, "
9953  "defaclrole, "
9954  "defaclnamespace, "
9955  "defaclobjtype, "
9956  "defaclacl, "
9957  "CASE WHEN defaclnamespace = 0 THEN "
9958  "acldefault(CASE WHEN defaclobjtype = 'S' "
9959  "THEN 's'::\"char\" ELSE defaclobjtype END, "
9960  "defaclrole) ELSE '{}' END AS acldefault "
9961  "FROM pg_default_acl");
9962 
9963  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9964 
9965  ntups = PQntuples(res);
9966  *numDefaultACLs = ntups;
9967 
9968  daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
9969 
9970  i_oid = PQfnumber(res, "oid");
9971  i_tableoid = PQfnumber(res, "tableoid");
9972  i_defaclrole = PQfnumber(res, "defaclrole");
9973  i_defaclnamespace = PQfnumber(res, "defaclnamespace");
9974  i_defaclobjtype = PQfnumber(res, "defaclobjtype");
9975  i_defaclacl = PQfnumber(res, "defaclacl");
9976  i_acldefault = PQfnumber(res, "acldefault");
9977 
9978  for (i = 0; i < ntups; i++)
9979  {
9980  Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
9981 
9982  daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
9983  daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9984  daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9985  AssignDumpId(&daclinfo[i].dobj);
9986  /* cheesy ... is it worth coming up with a better object name? */
9987  daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
9988 
9989  if (nspid != InvalidOid)
9990  daclinfo[i].dobj.namespace = findNamespace(nspid);
9991  else
9992  daclinfo[i].dobj.namespace = NULL;
9993 
9994  daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9995  daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9996  daclinfo[i].dacl.privtype = 0;
9997  daclinfo[i].dacl.initprivs = NULL;
9998  daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
9999  daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
10000 
10001  /* Default ACLs are ACLs, of course */
10002  daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10003 
10004  /* Decide whether we want to dump it */
10005  selectDumpableDefaultACL(&(daclinfo[i]), dopt);
10006  }
10007 
10008  PQclear(res);
10009 
10010  destroyPQExpBuffer(query);
10011 
10012  return daclinfo;
10013 }
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:1923

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

18522 {
18523  PQExpBuffer query;
18524  PGresult *res;
18525  int ntups,
18526  i;
18527  int i_classid,
18528  i_objid,
18529  i_refclassid,
18530  i_refobjid,
18531  i_deptype;
18532  DumpableObject *dobj,
18533  *refdobj;
18534 
18535  pg_log_info("reading dependency data");
18536 
18537  query = createPQExpBuffer();
18538 
18539  /*
18540  * Messy query to collect the dependency data we need. Note that we
18541  * ignore the sub-object column, so that dependencies of or on a column
18542  * look the same as dependencies of or on a whole table.
18543  *
18544  * PIN dependencies aren't interesting, and EXTENSION dependencies were
18545  * already processed by getExtensionMembership.
18546  */
18547  appendPQExpBufferStr(query, "SELECT "
18548  "classid, objid, refclassid, refobjid, deptype "
18549  "FROM pg_depend "
18550  "WHERE deptype != 'p' AND deptype != 'e'\n");
18551 
18552  /*
18553  * Since we don't treat pg_amop entries as separate DumpableObjects, we
18554  * have to translate their dependencies into dependencies of their parent
18555  * opfamily. Ignore internal dependencies though, as those will point to
18556  * their parent opclass, which we needn't consider here (and if we did,
18557  * it'd just result in circular dependencies). Also, "loose" opfamily
18558  * entries will have dependencies on their parent opfamily, which we
18559  * should drop since they'd likewise become useless self-dependencies.
18560  * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
18561  */
18562  appendPQExpBufferStr(query, "UNION ALL\n"
18563  "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
18564  "FROM pg_depend d, pg_amop o "
18565  "WHERE deptype NOT IN ('p', 'e', 'i') AND "
18566  "classid = 'pg_amop'::regclass AND objid = o.oid "
18567  "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
18568 
18569  /* Likewise for pg_amproc entries */
18570  appendPQExpBufferStr(query, "UNION ALL\n"
18571  "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
18572  "FROM pg_depend d, pg_amproc p "
18573  "WHERE deptype NOT IN ('p', 'e', 'i') AND "
18574  "classid = 'pg_amproc'::regclass AND objid = p.oid "
18575  "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
18576 
18577  /* Sort the output for efficiency below */
18578  appendPQExpBufferStr(query, "ORDER BY 1,2");
18579 
18580  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18581 
18582  ntups = PQntuples(res);
18583 
18584  i_classid = PQfnumber(res, "classid");
18585  i_objid = PQfnumber(res, "objid");
18586  i_refclassid = PQfnumber(res, "refclassid");
18587  i_refobjid = PQfnumber(res, "refobjid");
18588  i_deptype = PQfnumber(res, "deptype");
18589 
18590  /*
18591  * Since we ordered the SELECT by referencing ID, we can expect that
18592  * multiple entries for the same object will appear together; this saves
18593  * on searches.
18594  */
18595  dobj = NULL;
18596 
18597  for (i = 0; i < ntups; i++)
18598  {
18599  CatalogId objId;
18600  CatalogId refobjId;
18601  char deptype;
18602 
18603  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18604  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18605  refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
18606  refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
18607  deptype = *(PQgetvalue(res, i, i_deptype));
18608 
18609  if (dobj == NULL ||
18610  dobj->catId.tableoid != objId.tableoid ||
18611  dobj->catId.oid != objId.oid)
18612  dobj = findObjectByCatalogId(objId);
18613 
18614  /*
18615  * Failure to find objects mentioned in pg_depend is not unexpected,
18616  * since for example we don't collect info about TOAST tables.
18617  */
18618  if (dobj == NULL)
18619  {
18620 #ifdef NOT_USED
18621  pg_log_warning("no referencing object %u %u",
18622  objId.tableoid, objId.oid);
18623 #endif
18624  continue;
18625  }
18626 
18627  refdobj = findObjectByCatalogId(refobjId);
18628 
18629  if (refdobj == NULL)
18630  {
18631 #ifdef NOT_USED
18632  pg_log_warning("no referenced object %u %u",
18633  refobjId.tableoid, refobjId.oid);
18634 #endif
18635  continue;
18636  }
18637 
18638  /*
18639  * For 'x' dependencies, mark the object for later; we still add the
18640  * normal dependency, for possible ordering purposes. Currently
18641  * pg_dump_sort.c knows to put extensions ahead of all object types
18642  * that could possibly depend on them, but this is safer.
18643  */
18644  if (deptype == 'x')
18645  dobj->depends_on_ext = true;
18646 
18647  /*
18648  * Ordinarily, table rowtypes have implicit dependencies on their
18649  * tables. However, for a composite type the implicit dependency goes
18650  * the other way in pg_depend; which is the right thing for DROP but
18651  * it doesn't produce the dependency ordering we need. So in that one
18652  * case, we reverse the direction of the dependency.
18653  */
18654  if (deptype == 'i' &&
18655  dobj->objType == DO_TABLE &&
18656  refdobj->objType == DO_TYPE)
18657  addObjectDependency(refdobj, dobj->dumpId);
18658  else
18659  /* normal case */
18660  addObjectDependency(dobj, refdobj->dumpId);
18661  }
18662 
18663  PQclear(res);
18664 
18665  destroyPQExpBuffer(query);
18666 }

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

7911 {
7912  int i;
7913  ConstraintInfo *constrinfo;
7914  PQExpBuffer query = createPQExpBuffer();
7915  PGresult *res;
7916  int i_tableoid,
7917  i_oid,
7918  i_conname,
7919  i_consrc;
7920  int ntups;
7921 
7923  {
7924  /* Set up query for constraint-specific details */
7925  appendPQExpBufferStr(query,
7926  "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
7927  "SELECT tableoid, oid, conname, "
7928  "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
7929  "convalidated "
7930  "FROM pg_catalog.pg_constraint "
7931  "WHERE contypid = $1 AND contype = 'c' "
7932  "ORDER BY conname");
7933 
7934  ExecuteSqlStatement(fout, query->data);
7935 
7937  }
7938 
7939  printfPQExpBuffer(query,
7940  "EXECUTE getDomainConstraints('%u')",
7941  tyinfo->dobj.catId.oid);
7942 
7943  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7944 
7945  ntups = PQntuples(res);
7946 
7947  i_tableoid = PQfnumber(res, "tableoid");
7948  i_oid = PQfnumber(res, "oid");
7949  i_conname = PQfnumber(res, "conname");
7950  i_consrc = PQfnumber(res, "consrc");
7951 
7952  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
7953 
7954  tyinfo->nDomChecks = ntups;
7955  tyinfo->domChecks = constrinfo;
7956 
7957  for (i = 0; i < ntups; i++)
7958  {
7959  bool validated = PQgetvalue(res, i, 4)[0] == 't';
7960 
7961  constrinfo[i].dobj.objType = DO_CONSTRAINT;
7962  constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7963  constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7964  AssignDumpId(&constrinfo[i].dobj);
7965  constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
7966  constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
7967  constrinfo[i].contable = NULL;
7968  constrinfo[i].condomain = tyinfo;
7969  constrinfo[i].contype = 'c';
7970  constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
7971  constrinfo[i].confrelid = InvalidOid;
7972  constrinfo[i].conindex = 0;
7973  constrinfo[i].condeferrable = false;
7974  constrinfo[i].condeferred = false;
7975  constrinfo[i].conislocal = true;
7976 
7977  constrinfo[i].separate = !validated;
7978 
7979  /*
7980  * Make the domain depend on the constraint, ensuring it won't be
7981  * output till any constraint dependencies are OK. If the constraint
7982  * has not been validated, it's going to be dumped after the domain
7983  * anyway, so this doesn't matter.
7984  */
7985  if (validated)
7986  addObjectDependency(&tyinfo->dobj,
7987  constrinfo[i].dobj.dumpId);
7988  }
7989 
7990  PQclear(res);
7991 
7992  destroyPQExpBuffer(query);
7993 }
@ 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()

EventTriggerInfo* getEventTriggers ( Archive fout,
int *  numEventTriggers 
)

Definition at line 8299 of file pg_dump.c.

8300 {
8301  int i;
8302  PQExpBuffer query;
8303  PGresult *res;
8304  EventTriggerInfo *evtinfo;
8305  int i_tableoid,
8306  i_oid,
8307  i_evtname,
8308  i_evtevent,
8309  i_evtowner,
8310  i_evttags,
8311  i_evtfname,
8312  i_evtenabled;
8313  int ntups;
8314 
8315  /* Before 9.3, there are no event triggers */
8316  if (fout->remoteVersion < 90300)
8317  {
8318  *numEventTriggers = 0;
8319  return NULL;
8320  }
8321 
8322  query = createPQExpBuffer();
8323 
8324  appendPQExpBufferStr(query,
8325  "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8326  "evtevent, evtowner, "
8327  "array_to_string(array("
8328  "select quote_literal(x) "
8329  " from unnest(evttags) as t(x)), ', ') as evttags, "
8330  "e.evtfoid::regproc as evtfname "
8331  "FROM pg_event_trigger e "
8332  "ORDER BY e.oid");
8333 
8334  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8335 
8336  ntups = PQntuples(res);
8337 
8338  *numEventTriggers = ntups;
8339 
8340  evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8341 
8342  i_tableoid = PQfnumber(res, "tableoid");
8343  i_oid = PQfnumber(res, "oid");
8344  i_evtname = PQfnumber(res, "evtname");
8345  i_evtevent = PQfnumber(res, "evtevent");
8346  i_evtowner = PQfnumber(res, "evtowner");
8347  i_evttags = PQfnumber(res, "evttags");
8348  i_evtfname = PQfnumber(res, "evtfname");
8349  i_evtenabled = PQfnumber(res, "evtenabled");
8350 
8351  for (i = 0; i < ntups; i++)
8352  {
8353  evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8354  evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8355  evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8356  AssignDumpId(&evtinfo[i].dobj);
8357  evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8358  evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8359  evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8360  evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8361  evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8362  evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8363  evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8364 
8365  /* Decide whether we want to dump it */
8366  selectDumpableObject(&(evtinfo[i].dobj), fout);
8367  }
8368 
8369  PQclear(res);
8370 
8371  destroyPQExpBuffer(query);
8372 
8373  return evtinfo;
8374 }
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 7643 of file pg_dump.c.

7644 {
7645  PQExpBuffer query;
7646  PGresult *res;
7647  StatsExtInfo *statsextinfo;
7648  int ntups;
7649  int i_tableoid;
7650  int i_oid;
7651  int i_stxname;
7652  int i_stxnamespace;
7653  int i_stxowner;
7654  int i_stxrelid;
7655  int i_stattarget;
7656  int i;
7657 
7658  /* Extended statistics were new in v10 */
7659  if (fout->remoteVersion < 100000)
7660  return;
7661 
7662  query = createPQExpBuffer();
7663 
7664  if (fout->remoteVersion < 130000)
7665  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7666  "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
7667  "FROM pg_catalog.pg_statistic_ext");
7668  else
7669  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7670  "stxnamespace, stxowner, stxrelid, stxstattarget "
7671  "FROM pg_catalog.pg_statistic_ext");
7672 
7673  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7674 
7675  ntups = PQntuples(res);
7676 
7677  i_tableoid = PQfnumber(res, "tableoid");
7678  i_oid = PQfnumber(res, "oid");
7679  i_stxname = PQfnumber(res, "stxname");
7680  i_stxnamespace = PQfnumber(res, "stxnamespace");
7681  i_stxowner = PQfnumber(res, "stxowner");
7682  i_stxrelid = PQfnumber(res, "stxrelid");
7683  i_stattarget = PQfnumber(res, "stxstattarget");
7684 
7685  statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
7686 
7687  for (i = 0; i < ntups; i++)
7688  {
7689  statsextinfo[i].dobj.objType = DO_STATSEXT;
7690  statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7691  statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7692  AssignDumpId(&statsextinfo[i].dobj);
7693  statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
7694  statsextinfo[i].dobj.namespace =
7695  findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
7696  statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
7697  statsextinfo[i].stattable =
7698  findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7699  if (PQgetisnull(res, i, i_stattarget))
7700  statsextinfo[i].stattarget = -1;
7701  else
7702  statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7703 
7704  /* Decide whether we want to dump it */
7705  selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
7706  }
7707 
7708  PQclear(res);
7709  destroyPQExpBuffer(query);
7710 }
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2088
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 18247 of file pg_dump.c.

18249 {
18250  PQExpBuffer query;
18251  PGresult *res;
18252  int ntups,
18253  i;
18254  int i_classid,
18255  i_objid,
18256  i_refobjid;
18257  ExtensionInfo *ext;
18258 
18259  /* Nothing to do if no extensions */
18260  if (numExtensions == 0)
18261  return;
18262 
18263  query = createPQExpBuffer();
18264 
18265  /* refclassid constraint is redundant but may speed the search */
18266  appendPQExpBufferStr(query, "SELECT "
18267  "classid, objid, refobjid "
18268  "FROM pg_depend "
18269  "WHERE refclassid = 'pg_extension'::regclass "
18270  "AND deptype = 'e' "
18271  "ORDER BY 3");
18272 
18273  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18274 
18275  ntups = PQntuples(res);
18276 
18277  i_classid = PQfnumber(res, "classid");
18278  i_objid = PQfnumber(res, "objid");
18279  i_refobjid = PQfnumber(res, "refobjid");
18280 
18281  /*
18282  * Since we ordered the SELECT by referenced ID, we can expect that
18283  * multiple entries for the same extension will appear together; this
18284  * saves on searches.
18285  */
18286  ext = NULL;
18287 
18288  for (i = 0; i < ntups; i++)
18289  {
18290  CatalogId objId;
18291  Oid extId;
18292 
18293  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18294  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18295  extId = atooid(PQgetvalue(res, i, i_refobjid));
18296 
18297  if (ext == NULL ||
18298  ext->dobj.catId.oid != extId)
18299  ext = findExtensionByOid(extId);
18300 
18301  if (ext == NULL)
18302  {
18303  /* shouldn't happen */
18304  pg_log_warning("could not find referenced extension %u", extId);
18305  continue;
18306  }
18307 
18308  recordExtensionMembership(objId, ext);
18309  }
18310 
18311  PQclear(res);
18312 
18313  destroyPQExpBuffer(query);
18314 }
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1036
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:981

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

5693 {
5694  DumpOptions *dopt = fout->dopt;
5695  PGresult *res;
5696  int ntups;
5697  int i;
5698  PQExpBuffer query;
5699  ExtensionInfo *extinfo;
5700  int i_tableoid;
5701  int i_oid;
5702  int i_extname;
5703  int i_nspname;
5704  int i_extrelocatable;
5705  int i_extversion;
5706  int i_extconfig;
5707  int i_extcondition;
5708 
5709  query = createPQExpBuffer();
5710 
5711  appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5712  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5713  "FROM pg_extension x "
5714  "JOIN pg_namespace n ON n.oid = x.extnamespace");
5715 
5716  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5717 
5718  ntups = PQntuples(res);
5719 
5720  extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5721 
5722  i_tableoid = PQfnumber(res, "tableoid");
5723  i_oid = PQfnumber(res, "oid");
5724  i_extname = PQfnumber(res, "extname");
5725  i_nspname = PQfnumber(res, "nspname");
5726  i_extrelocatable = PQfnumber(res, "extrelocatable");
5727  i_extversion = PQfnumber(res, "extversion");
5728  i_extconfig = PQfnumber(res, "extconfig");
5729  i_extcondition = PQfnumber(res, "extcondition");
5730 
5731  for (i = 0; i < ntups; i++)
5732  {
5733  extinfo[i].dobj.objType = DO_EXTENSION;
5734  extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5735  extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5736  AssignDumpId(&extinfo[i].dobj);
5737  extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5738  extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5739  extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5740  extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5741  extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5742  extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5743 
5744  /* Decide whether we want to dump it */
5745  selectDumpableExtension(&(extinfo[i]), dopt);
5746  }
5747 
5748  PQclear(res);
5749  destroyPQExpBuffer(query);
5750 
5751  *numExtensions = ntups;
5752 
5753  return extinfo;
5754 }
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2031

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, 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()

FdwInfo* getForeignDataWrappers ( Archive fout,
int *  numForeignDataWrappers 
)

Definition at line 9737 of file pg_dump.c.

9738 {
9739  PGresult *res;
9740  int ntups;
9741  int i;
9742  PQExpBuffer query;
9743  FdwInfo *fdwinfo;
9744  int i_tableoid;
9745  int i_oid;
9746  int i_fdwname;
9747  int i_fdwowner;
9748  int i_fdwhandler;
9749  int i_fdwvalidator;
9750  int i_fdwacl;
9751  int i_acldefault;
9752  int i_fdwoptions;
9753 
9754  query = createPQExpBuffer();
9755 
9756  appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
9757  "fdwowner, "
9758  "fdwhandler::pg_catalog.regproc, "
9759  "fdwvalidator::pg_catalog.regproc, "
9760  "fdwacl, "
9761  "acldefault('F', fdwowner) AS acldefault, "
9762  "array_to_string(ARRAY("
9763  "SELECT quote_ident(option_name) || ' ' || "
9764  "quote_literal(option_value) "
9765  "FROM pg_options_to_table(fdwoptions) "
9766  "ORDER BY option_name"
9767  "), E',\n ') AS fdwoptions "
9768  "FROM pg_foreign_data_wrapper");
9769 
9770  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9771 
9772  ntups = PQntuples(res);
9773  *numForeignDataWrappers = ntups;
9774 
9775  fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
9776 
9777  i_tableoid = PQfnumber(res, "tableoid");
9778  i_oid = PQfnumber(res, "oid");
9779  i_fdwname = PQfnumber(res, "fdwname");
9780  i_fdwowner = PQfnumber(res, "fdwowner");
9781  i_fdwhandler = PQfnumber(res, "fdwhandler");
9782  i_fdwvalidator = PQfnumber(res, "fdwvalidator");
9783  i_fdwacl = PQfnumber(res, "fdwacl");
9784  i_acldefault = PQfnumber(res, "acldefault");
9785  i_fdwoptions = PQfnumber(res, "fdwoptions");
9786 
9787  for (i = 0; i < ntups; i++)
9788  {
9789  fdwinfo[i].dobj.objType = DO_FDW;
9790  fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9791  fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9792  AssignDumpId(&fdwinfo[i].dobj);
9793  fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
9794  fdwinfo[i].dobj.namespace = NULL;
9795  fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
9796  fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9797  fdwinfo[i].dacl.privtype = 0;
9798  fdwinfo[i].dacl.initprivs = NULL;
9799  fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
9800  fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
9801  fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
9802  fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
9803 
9804  /* Decide whether we want to dump it */
9805  selectDumpableObject(&(fdwinfo[i].dobj), fout);
9806 
9807  /* Mark whether FDW has an ACL */
9808  if (!PQgetisnull(res, i, i_fdwacl))
9809  fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9810  }
9811 
9812  PQclear(res);
9813 
9814  destroyPQExpBuffer(query);
9815 
9816  return fdwinfo;
9817 }

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()

ForeignServerInfo* getForeignServers ( Archive fout,
int *  numForeignServers 
)

Definition at line 9827 of file pg_dump.c.

9828 {
9829  PGresult *res;
9830  int ntups;
9831  int i;
9832  PQExpBuffer query;
9833  ForeignServerInfo *srvinfo;
9834  int i_tableoid;
9835  int i_oid;
9836  int i_srvname;
9837  int i_srvowner;
9838  int i_srvfdw;
9839  int i_srvtype;
9840  int i_srvversion;
9841  int i_srvacl;
9842  int i_acldefault;
9843  int i_srvoptions;
9844 
9845  query = createPQExpBuffer();
9846 
9847  appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
9848  "srvowner, "
9849  "srvfdw, srvtype, srvversion, srvacl, "
9850  "acldefault('S', srvowner) AS acldefault, "
9851  "array_to_string(ARRAY("
9852  "SELECT quote_ident(option_name) || ' ' || "
9853  "quote_literal(option_value) "
9854  "FROM pg_options_to_table(srvoptions) "
9855  "ORDER BY option_name"
9856  "), E',\n ') AS srvoptions "
9857  "FROM pg_foreign_server");
9858 
9859  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9860 
9861  ntups = PQntuples(res);
9862  *numForeignServers = ntups;
9863 
9864  srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
9865 
9866  i_tableoid = PQfnumber(res, "tableoid");
9867  i_oid = PQfnumber(res, "oid");
9868  i_srvname = PQfnumber(res, "srvname");
9869  i_srvowner = PQfnumber(res, "srvowner");
9870  i_srvfdw = PQfnumber(res, "srvfdw");
9871  i_srvtype = PQfnumber(res, "srvtype");
9872  i_srvversion = PQfnumber(res, "srvversion");
9873  i_srvacl = PQfnumber(res, "srvacl");
9874  i_acldefault = PQfnumber(res, "acldefault");
9875  i_srvoptions = PQfnumber(res, "srvoptions");
9876 
9877  for (i = 0; i < ntups; i++)
9878  {
9879  srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
9880  srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9881  srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9882  AssignDumpId(&srvinfo[i].dobj);
9883  srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
9884  srvinfo[i].dobj.namespace = NULL;
9885  srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
9886  srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9887  srvinfo[i].dacl.privtype = 0;
9888  srvinfo[i].dacl.initprivs = NULL;
9889  srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
9890  srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
9891  srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
9892  srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
9893  srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
9894 
9895  /* Decide whether we want to dump it */
9896  selectDumpableObject(&(srvinfo[i].dobj), fout);
9897 
9898  /* Servers have user mappings */
9900 
9901  /* Mark whether server has an ACL */
9902  if (!PQgetisnull(res, i, i_srvacl))
9903  srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9904  }
9905 
9906  PQclear(res);
9907 
9908  destroyPQExpBuffer(query);
9909 
9910  return srvinfo;
9911 }

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

13246 {
13247  OprInfo *oprInfo;
13248 
13249  /* In all cases "0" means a null reference */
13250  if (strcmp(oproid, "0") == 0)
13251  return NULL;
13252 
13253  oprInfo = findOprByOid(atooid(oproid));
13254  if (oprInfo == NULL)
13255  {
13256  pg_log_warning("could not find operator with OID %s",
13257  oproid);
13258  return NULL;
13259  }
13260 
13261  return psprintf("OPERATOR(%s.%s)",
13262  fmtId(oprInfo->dobj.namespace->dobj.name),
13263  oprInfo->dobj.name);
13264 }
OprInfo * findOprByOid(Oid oid)
Definition: common.c:927

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

18919 {
18920  TypeInfo *typeInfo;
18921  char *result;
18922  PQExpBuffer query;
18923  PGresult *res;
18924 
18925  if (oid == 0)
18926  {
18927  if ((opts & zeroAsStar) != 0)
18928  return "*";
18929  else if ((opts & zeroAsNone) != 0)
18930  return "NONE";
18931  }
18932 
18933  /* see if we have the result cached in the type's TypeInfo record */
18934  typeInfo = findTypeByOid(oid);
18935  if (typeInfo && typeInfo->ftypname)
18936  return typeInfo->ftypname;
18937 
18938  query = createPQExpBuffer();
18939  appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
18940  oid);
18941 
18942  res = ExecuteSqlQueryForSingleRow(fout, query->data);
18943 
18944  /* result of format_type is already quoted */
18945  result = pg_strdup(PQgetvalue(res, 0, 0));
18946 
18947  PQclear(res);
18948  destroyPQExpBuffer(query);
18949 
18950  /*
18951  * Cache the result for re-use in later requests, if possible. If we
18952  * don't have a TypeInfo for the type, the string will be leaked once the
18953  * caller is done with it ... but that case really should not happen, so
18954  * leaking if it does seems acceptable.
18955  */
18956  if (typeInfo)
18957  typeInfo->ftypname = result;
18958 
18959  return result;
18960 }
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()

FuncInfo* getFuncs ( Archive fout,
int *  numFuncs 
)

Definition at line 6499 of file pg_dump.c.

6500 {
6501  DumpOptions *dopt = fout->dopt;
6502  PGresult *res;
6503  int ntups;
6504  int i;
6505  PQExpBuffer query = createPQExpBuffer();
6506  FuncInfo *finfo;
6507  int i_tableoid;
6508  int i_oid;
6509  int i_proname;
6510  int i_pronamespace;
6511  int i_proowner;
6512  int i_prolang;
6513  int i_pronargs;
6514  int i_proargtypes;
6515  int i_prorettype;
6516  int i_proacl;
6517  int i_acldefault;
6518 
6519  /*
6520  * Find all interesting functions. This is a bit complicated:
6521  *
6522  * 1. Always exclude aggregates; those are handled elsewhere.
6523  *
6524  * 2. Always exclude functions that are internally dependent on something
6525  * else, since presumably those will be created as a result of creating
6526  * the something else. This currently acts only to suppress constructor
6527  * functions for range types. Note this is OK only because the
6528  * constructors don't have any dependencies the range type doesn't have;
6529  * otherwise we might not get creation ordering correct.
6530  *
6531  * 3. Otherwise, we normally exclude functions in pg_catalog. However, if
6532  * they're members of extensions and we are in binary-upgrade mode then
6533  * include them, since we want to dump extension members individually in
6534  * that mode. Also, if they are used by casts or transforms then we need
6535  * to gather the information about them, though they won't be dumped if
6536  * they are built-in. Also, in 9.6 and up, include functions in
6537  * pg_catalog if they have an ACL different from what's shown in
6538  * pg_init_privs (so we have to join to pg_init_privs; annoying).
6539  */
6540  if (fout->remoteVersion >= 90600)
6541  {
6542  const char *not_agg_check;
6543 
6544  not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
6545  : "NOT p.proisagg");
6546 
6547  appendPQExpBuffer(query,
6548  "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
6549  "p.pronargs, p.proargtypes, p.prorettype, "
6550  "p.proacl, "
6551  "acldefault('f', p.proowner) AS acldefault, "
6552  "p.pronamespace, "
6553  "p.proowner "
6554  "FROM pg_proc p "
6555  "LEFT JOIN pg_init_privs pip ON "
6556  "(p.oid = pip.objoid "
6557  "AND pip.classoid = 'pg_proc'::regclass "
6558  "AND pip.objsubid = 0) "
6559  "WHERE %s"
6560  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6561  "WHERE classid = 'pg_proc'::regclass AND "
6562  "objid = p.oid AND deptype = 'i')"
6563  "\n AND ("
6564  "\n pronamespace != "
6565  "(SELECT oid FROM pg_namespace "
6566  "WHERE nspname = 'pg_catalog')"
6567  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6568  "\n WHERE pg_cast.oid > %u "
6569  "\n AND p.oid = pg_cast.castfunc)"
6570  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6571  "\n WHERE pg_transform.oid > %u AND "
6572  "\n (p.oid = pg_transform.trffromsql"
6573  "\n OR p.oid = pg_transform.trftosql))",
6574  not_agg_check,
6577  if (dopt->binary_upgrade)
6578  appendPQExpBufferStr(query,
6579  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6580  "classid = 'pg_proc'::regclass AND "
6581  "objid = p.oid AND "
6582  "refclassid = 'pg_extension'::regclass AND "
6583  "deptype = 'e')");
6584  appendPQExpBufferStr(query,
6585  "\n OR p.proacl IS DISTINCT FROM pip.initprivs");
6586  appendPQExpBufferChar(query, ')');
6587  }
6588  else
6589  {
6590  appendPQExpBuffer(query,
6591  "SELECT tableoid, oid, proname, prolang, "
6592  "pronargs, proargtypes, prorettype, proacl, "
6593  "acldefault('f', proowner) AS acldefault, "
6594  "pronamespace, "
6595  "proowner "
6596  "FROM pg_proc p "
6597  "WHERE NOT proisagg"
6598  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6599  "WHERE classid = 'pg_proc'::regclass AND "
6600  "objid = p.oid AND deptype = 'i')"
6601  "\n AND ("
6602  "\n pronamespace != "
6603  "(SELECT oid FROM pg_namespace "
6604  "WHERE nspname = 'pg_catalog')"
6605  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6606  "\n WHERE pg_cast.oid > '%u'::oid"
6607  "\n AND p.oid = pg_cast.castfunc)",
6609 
6610  if (fout->remoteVersion >= 90500)
6611  appendPQExpBuffer(query,
6612  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6613  "\n WHERE pg_transform.oid > '%u'::oid"
6614  "\n AND (p.oid = pg_transform.trffromsql"
6615  "\n OR p.oid = pg_transform.trftosql))",
6617 
6618  if (dopt->binary_upgrade)
6619  appendPQExpBufferStr(query,
6620  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6621  "classid = 'pg_proc'::regclass AND "
6622  "objid = p.oid AND "
6623  "refclassid = 'pg_extension'::regclass AND "
6624  "deptype = 'e')");
6625  appendPQExpBufferChar(query, ')');
6626  }
6627 
6628  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6629 
6630  ntups = PQntuples(res);
6631 
6632  *numFuncs = ntups;
6633 
6634  finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
6635 
6636  i_tableoid = PQfnumber(res, "tableoid");
6637  i_oid = PQfnumber(res, "oid");
6638  i_proname = PQfnumber(res, "proname");
6639  i_pronamespace = PQfnumber(res, "pronamespace");
6640  i_proowner = PQfnumber(res, "proowner");
6641  i_prolang = PQfnumber(res, "prolang");
6642  i_pronargs = PQfnumber(res, "pronargs");
6643  i_proargtypes = PQfnumber(res, "proargtypes");
6644  i_prorettype = PQfnumber(res, "prorettype");
6645  i_proacl = PQfnumber(res, "proacl");
6646  i_acldefault = PQfnumber(res, "acldefault");
6647 
6648  for (i = 0; i < ntups; i++)
6649  {
6650  finfo[i].dobj.objType = DO_FUNC;
6651  finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6652  finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6653  AssignDumpId(&finfo[i].dobj);
6654  finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
6655  finfo[i].dobj.namespace =
6656  findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
6657  finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
6658  finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6659  finfo[i].dacl.privtype = 0;
6660  finfo[i].dacl.initprivs = NULL;
6661  finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6662  finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
6663  finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
6664  finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
6665  if (finfo[i].nargs == 0)
6666  finfo[i].argtypes = NULL;
6667  else
6668  {
6669  finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
6670  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6671  finfo[i].argtypes, finfo[i].nargs);
6672  }
6673  finfo[i].postponed_def = false; /* might get set during sort */
6674 
6675  /* Decide whether we want to dump it */
6676  selectDumpableObject(&(finfo[i].dobj), fout);
6677 
6678  /* Mark whether function has an ACL */
6679  if (!PQgetisnull(res, i, i_proacl))
6680  finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
6681  }
6682 
6683  PQclear(res);
6684 
6685  destroyPQExpBuffer(query);
6686 
6687  return finfo;
6688 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static Oid g_last_builtin_oid
Definition: pg_dump.c:105
Oid lang
Definition: pg_dump.h:227

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

7324 {
7325  PQExpBuffer query = createPQExpBuffer();
7326  PQExpBuffer tbloids = createPQExpBuffer();
7327  PGresult *res;
7328  int ntups;
7329  int curtblindx;
7330  IndxInfo *indxinfo;
7331  int i_tableoid,
7332  i_oid,
7333  i_indrelid,
7334  i_indexname,
7335  i_parentidx,
7336  i_indexdef,
7337  i_indnkeyatts,
7338  i_indnatts,
7339  i_indkey,
7340  i_indisclustered,
7341  i_indisreplident,
7342  i_indnullsnotdistinct,
7343  i_contype,
7344  i_conname,
7345  i_condeferrable,
7346  i_condeferred,
7347  i_conperiod,
7348  i_contableoid,
7349  i_conoid,
7350  i_condef,
7351  i_tablespace,
7352  i_indreloptions,
7353  i_indstatcols,
7354  i_indstatvals;
7355 
7356  /*
7357  * We want to perform just one query against pg_index. However, we
7358  * mustn't try to select every row of the catalog and then sort it out on
7359  * the client side, because some of the server-side functions we need
7360  * would be unsafe to apply to tables we don't have lock on. Hence, we
7361  * build an array of the OIDs of tables we care about (and now have lock
7362  * on!), and use a WHERE clause to constrain which rows are selected.
7363  */
7364  appendPQExpBufferChar(tbloids, '{');
7365  for (int i = 0; i < numTables; i++)
7366  {
7367  TableInfo *tbinfo = &tblinfo[i];
7368 
7369  if (!tbinfo->hasindex)
7370  continue;
7371 
7372  /*
7373  * We can ignore indexes of uninteresting tables.
7374  */
7375  if (!tbinfo->interesting)
7376  continue;
7377 
7378  /* OK, we need info for this table */
7379  if (tbloids->len > 1) /* do we have more than the '{'? */
7380  appendPQExpBufferChar(tbloids, ',');
7381  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
7382  }
7383  appendPQExpBufferChar(tbloids, '}');
7384 
7385  appendPQExpBufferStr(query,
7386  "SELECT t.tableoid, t.oid, i.indrelid, "
7387  "t.relname AS indexname, "
7388  "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7389  "i.indkey, i.indisclustered, "
7390  "c.contype, c.conname, "
7391  "c.condeferrable, c.condeferred, "
7392  "c.tableoid AS contableoid, "
7393  "c.oid AS conoid, "
7394  "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
7395  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
7396  "t.reloptions AS indreloptions, ");
7397 
7398 
7399  if (fout->remoteVersion >= 90400)
7400  appendPQExpBufferStr(query,
7401  "i.indisreplident, ");
7402  else
7403  appendPQExpBufferStr(query,
7404  "false AS indisreplident, ");
7405 
7406  if (fout->remoteVersion >= 110000)
7407  appendPQExpBufferStr(query,
7408  "inh.inhparent AS parentidx, "
7409  "i.indnkeyatts AS indnkeyatts, "
7410  "i.indnatts AS indnatts, "
7411  "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
7412  " FROM pg_catalog.pg_attribute "
7413  " WHERE attrelid = i.indexrelid AND "
7414  " attstattarget >= 0) AS indstatcols, "
7415  "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
7416  " FROM pg_catalog.pg_attribute "
7417  " WHERE attrelid = i.indexrelid AND "
7418  " attstattarget >= 0) AS indstatvals, ");
7419  else
7420  appendPQExpBufferStr(query,
7421  "0 AS parentidx, "
7422  "i.indnatts AS indnkeyatts, "
7423  "i.indnatts AS indnatts, "
7424  "'' AS indstatcols, "
7425  "'' AS indstatvals, ");
7426 
7427  if (fout->remoteVersion >= 150000)
7428  appendPQExpBufferStr(query,
7429  "i.indnullsnotdistinct, ");
7430  else
7431  appendPQExpBufferStr(query,
7432  "false AS indnullsnotdistinct, ");
7433 
7434  if (fout->remoteVersion >= 170000)
7435  appendPQExpBufferStr(query,
7436  "c.conperiod ");
7437  else
7438  appendPQExpBufferStr(query,
7439  "NULL AS conperiod ");
7440 
7441  /*
7442  * The point of the messy-looking outer join is to find a constraint that
7443  * is related by an internal dependency link to the index. If we find one,
7444  * create a CONSTRAINT entry linked to the INDEX entry. We assume an
7445  * index won't have more than one internal dependency.
7446  *
7447  * Note: the check on conrelid is redundant, but useful because that
7448  * column is indexed while conindid is not.
7449  */
7450  if (fout->remoteVersion >= 110000)
7451  {
7452  appendPQExpBuffer(query,
7453  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7454  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7455  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7456  "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
7457  "LEFT JOIN pg_catalog.pg_constraint c "
7458  "ON (i.indrelid = c.conrelid AND "
7459  "i.indexrelid = c.conindid AND "
7460  "c.contype IN ('p','u','x')) "
7461  "LEFT JOIN pg_catalog.pg_inherits inh "
7462  "ON (inh.inhrelid = indexrelid) "
7463  "WHERE (i.indisvalid OR t2.relkind = 'p') "
7464  "AND i.indisready "
7465  "ORDER BY i.indrelid, indexname",
7466  tbloids->data);
7467  }
7468  else
7469  {
7470  /*
7471  * the test on indisready is necessary in 9.2, and harmless in
7472  * earlier/later versions
7473  */
7474  appendPQExpBuffer(query,
7475  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7476  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7477  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7478  "LEFT JOIN pg_catalog.pg_constraint c "
7479  "ON (i.indrelid = c.conrelid AND "
7480  "i.indexrelid = c.conindid AND "
7481  "c.contype IN ('p','u','x')) "
7482  "WHERE i.indisvalid AND i.indisready "
7483  "ORDER BY i.indrelid, indexname",
7484  tbloids->data);
7485  }
7486 
7487  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7488 
7489  ntups = PQntuples(res);
7490 
7491  i_tableoid = PQfnumber(res, "tableoid");
7492  i_oid = PQfnumber(res, "oid");
7493  i_indrelid = PQfnumber(res, "indrelid");
7494  i_indexname = PQfnumber(res, "indexname");
7495  i_parentidx = PQfnumber(res, "parentidx");
7496  i_indexdef = PQfnumber(res, "indexdef");
7497  i_indnkeyatts = PQfnumber(res, "indnkeyatts");
7498  i_indnatts = PQfnumber(res, "indnatts");
7499  i_indkey = PQfnumber(res, "indkey");
7500  i_indisclustered = PQfnumber(res, "indisclustered");
7501  i_indisreplident = PQfnumber(res, "indisreplident");
7502  i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
7503  i_contype = PQfnumber(res, "contype");
7504  i_conname = PQfnumber(res, "conname");
7505  i_condeferrable = PQfnumber(res, "condeferrable");
7506  i_condeferred = PQfnumber(res, "condeferred");
7507  i_conperiod = PQfnumber(res, "conperiod");
7508  i_contableoid = PQfnumber(res, "contableoid");
7509  i_conoid = PQfnumber(res, "conoid");
7510  i_condef = PQfnumber(res, "condef");
7511  i_tablespace = PQfnumber(res, "tablespace");
7512  i_indreloptions = PQfnumber(res, "indreloptions");
7513  i_indstatcols = PQfnumber(res, "indstatcols");
7514  i_indstatvals = PQfnumber(res, "indstatvals");
7515 
7516  indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
7517 
7518  /*
7519  * Outer loop iterates once per table, not once per row. Incrementing of
7520  * j is handled by the inner loop.
7521  */
7522  curtblindx = -1;
7523  for (int j = 0; j < ntups;)
7524  {
7525  Oid indrelid = atooid(PQgetvalue(res, j, i_indrelid));
7526  TableInfo *tbinfo = NULL;
7527  int numinds;
7528 
7529  /* Count rows for this table */
7530  for (numinds = 1; numinds < ntups - j; numinds++)
7531  if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
7532  break;
7533 
7534  /*
7535  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7536  * order.
7537  */
7538  while (++curtblindx < numTables)
7539  {
7540  tbinfo = &tblinfo[curtblindx];
7541  if (tbinfo->dobj.catId.oid == indrelid)
7542  break;
7543  }
7544  if (curtblindx >= numTables)
7545  pg_fatal("unrecognized table OID %u", indrelid);
7546  /* cross-check that we only got requested tables */
7547  if (!tbinfo->hasindex ||
7548  !tbinfo->interesting)
7549  pg_fatal("unexpected index data for table \"%s\"",
7550  tbinfo->dobj.name);
7551 
7552  /* Save data for this table */
7553  tbinfo->indexes = indxinfo + j;
7554  tbinfo->numIndexes = numinds;
7555 
7556  for (int c = 0; c < numinds; c++, j++)
7557  {
7558  char contype;
7559 
7560  indxinfo[j].dobj.objType = DO_INDEX;
7561  indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
7562  indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
7563  AssignDumpId(&indxinfo[j].dobj);
7564  indxinfo[j].dobj.dump = tbinfo->dobj.dump;
7565  indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
7566  indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7567  indxinfo[j].indextable = tbinfo;
7568  indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
7569  indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
7570  indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
7571  indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
7572  indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
7573  indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
7574  indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
7575  indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
7576  parseOidArray(PQgetvalue(res, j, i_indkey),
7577  indxinfo[j].indkeys, indxinfo[j].indnattrs);
7578  indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
7579  indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
7580  indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
7581  indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
7582  indxinfo[j].partattaches = (SimplePtrList)
7583  {
7584  NULL, NULL
7585  };
7586  contype = *(PQgetvalue(res, j, i_contype));
7587 
7588  if (contype == 'p' || contype == 'u' || contype == 'x')
7589  {
7590  /*
7591  * If we found a constraint matching the index, create an
7592  * entry for it.
7593  */
7594  ConstraintInfo *constrinfo;
7595 
7596  constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
7597  constrinfo->dobj.objType = DO_CONSTRAINT;
7598  constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7599  constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7600  AssignDumpId(&constrinfo->dobj);
7601  constrinfo->dobj.dump = tbinfo->dobj.dump;
7602  constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7603  constrinfo->dobj.namespace = tbinfo->dobj.namespace;
7604  constrinfo->contable = tbinfo;
7605  constrinfo->condomain = NULL;
7606  constrinfo->contype = contype;
7607  if (contype == 'x')
7608  constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
7609  else
7610  constrinfo->condef = NULL;
7611  constrinfo->confrelid = InvalidOid;
7612  constrinfo->conindex = indxinfo[j].dobj.dumpId;
7613  constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
7614  constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
7615  constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
7616  constrinfo->conislocal = true;
7617  constrinfo->separate = true;
7618 
7619  indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
7620  }
7621  else
7622  {
7623  /* Plain secondary index */
7624  indxinfo[j].indexconstraint = 0;
7625  }
7626  }
7627  }
7628 
7629  PQclear(res);
7630 
7631  destroyPQExpBuffer(query);
7632  destroyPQExpBuffer(tbloids);
7633 }
char * c
struct SimplePtrList SimplePtrList
Oid parentidx
Definition: pg_dump.h:410
bool hasindex
Definition: pg_dump.h:296

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

7208 {
7209  PGresult *res;
7210  int ntups;
7211  int i;
7212  PQExpBuffer query = createPQExpBuffer();
7213  InhInfo *inhinfo;
7214 
7215  int i_inhrelid;
7216  int i_inhparent;
7217 
7218  /* find all the inheritance information */
7219  appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7220 
7221  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7222 
7223  ntups = PQntuples(res);
7224 
7225  *numInherits = ntups;
7226 
7227  inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7228 
7229  i_inhrelid = PQfnumber(res, "inhrelid");
7230  i_inhparent = PQfnumber(res, "inhparent");
7231 
7232  for (i = 0; i < ntups; i++)
7233  {
7234  inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7235  inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7236  }
7237 
7238  PQclear(res);
7239 
7240  destroyPQExpBuffer(query);
7241 
7242  return inhinfo;
7243 }
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 3618 of file pg_dump.c.

3619 {
3620  DumpOptions *dopt = fout->dopt;
3621  PQExpBuffer loQry = createPQExpBuffer();
3622  PGresult *res;
3623  int ntups;
3624  int i;
3625  int n;
3626  int i_oid;
3627  int i_lomowner;
3628  int i_lomacl;
3629  int i_acldefault;
3630 
3631  pg_log_info("reading large objects");
3632 
3633  /*
3634  * Fetch LO OIDs and owner/ACL data. Order the data so that all the blobs
3635  * with the same owner/ACL appear together.
3636  */
3637  appendPQExpBufferStr(loQry,
3638  "SELECT oid, lomowner, lomacl, "
3639  "acldefault('L', lomowner) AS acldefault "
3640  "FROM pg_largeobject_metadata "
3641  "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
3642 
3643  res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
3644 
3645  i_oid = PQfnumber(res, "oid");
3646  i_lomowner = PQfnumber(res, "lomowner");
3647  i_lomacl = PQfnumber(res, "lomacl");
3648  i_acldefault = PQfnumber(res, "acldefault");
3649 
3650  ntups = PQntuples(res);
3651 
3652  /*
3653  * Group the blobs into suitably-sized groups that have the same owner and
3654  * ACL setting, and build a metadata and a data DumpableObject for each
3655  * group. (If we supported initprivs for blobs, we'd have to insist that
3656  * groups also share initprivs settings, since the DumpableObject only has
3657  * room for one.) i is the index of the first tuple in the current group,
3658  * and n is the number of tuples we include in the group.
3659  */
3660  for (i = 0; i < ntups; i += n)
3661  {
3662  Oid thisoid = atooid(PQgetvalue(res, i, i_oid));
3663  char *thisowner = PQgetvalue(res, i, i_lomowner);
3664  char *thisacl = PQgetvalue(res, i, i_lomacl);
3665  LoInfo *loinfo;
3666  DumpableObject *lodata;
3667  char namebuf[64];
3668 
3669  /* Scan to find first tuple not to be included in group */
3670  n = 1;
3671  while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
3672  {
3673  if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
3674  strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
3675  break;
3676  n++;
3677  }
3678 
3679  /* Build the metadata DumpableObject */
3680  loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
3681 
3682  loinfo->dobj.objType = DO_LARGE_OBJECT;
3683  loinfo->dobj.catId.tableoid = LargeObjectRelationId;
3684  loinfo->dobj.catId.oid = thisoid;
3685  AssignDumpId(&loinfo->dobj);
3686 
3687  if (n > 1)
3688  snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
3689  atooid(PQgetvalue(res, i + n - 1, i_oid)));
3690  else
3691  snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
3692  loinfo->dobj.name = pg_strdup(namebuf);
3693  loinfo->dacl.acl = pg_strdup(thisacl);
3694  loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
3695  loinfo->dacl.privtype = 0;
3696  loinfo->dacl.initprivs = NULL;
3697  loinfo->rolname = getRoleName(thisowner);
3698  loinfo->numlos = n;
3699  loinfo->looids[0] = thisoid;
3700  /* Collect OIDs of the remaining blobs in this group */
3701  for (int k = 1; k < n; k++)
3702  {
3703  CatalogId extraID;
3704 
3705  loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
3706 
3707  /* Make sure we can look up loinfo by any of the blobs' OIDs */
3708  extraID.tableoid = LargeObjectRelationId;
3709  extraID.oid = loinfo->looids[k];
3710  recordAdditionalCatalogID(extraID, &loinfo->dobj);
3711  }
3712 
3713  /* LOs have data */
3714  loinfo->dobj.components |= DUMP_COMPONENT_DATA;
3715 
3716  /* Mark whether LO group has a non-empty ACL */
3717  if (!PQgetisnull(res, i, i_lomacl))
3718  loinfo->dobj.components |= DUMP_COMPONENT_ACL;
3719 
3720  /*
3721  * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
3722  * as it will be copied by pg_upgrade, which simply copies the
3723  * pg_largeobject table. We *do* however dump out anything but the
3724  * data, as pg_upgrade copies just pg_largeobject, but not
3725  * pg_largeobject_metadata, after the dump is restored.
3726  */
3727  if (dopt->binary_upgrade)
3728  loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
3729 
3730  /*
3731  * Create a "BLOBS" data item for the group, too. This is just a
3732  * placeholder for sorting; it carries no data now.
3733  */
3734  lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
3735  lodata->objType = DO_LARGE_OBJECT_DATA;
3736  lodata->catId = nilCatalogId;
3737  AssignDumpId(lodata);
3738  lodata->name = pg_strdup(namebuf);
3739  lodata->components |= DUMP_COMPONENT_DATA;
3740  /* Set up explicit dependency from data to metadata */
3741  lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
3742  lodata->dependencies[0] = loinfo->dobj.dumpId;
3743  lodata->nDeps = lodata->allocDeps = 1;
3744  }
3745 
3746  PQclear(res);
3747  destroyPQExpBuffer(loQry);
3748 }
void recordAdditionalCatalogID(CatalogId catId, DumpableObject *dobj)
Definition: common.c:710
#define MAX_BLOBS_PER_ARCHIVE_ENTRY
Definition: pg_dump.c:171

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()

NamespaceInfo* getNamespaces ( Archive fout,
int *  numNamespaces 
)

Definition at line 5556 of file pg_dump.c.

5557 {
5558  PGresult *res;
5559  int ntups;
5560  int i;
5561  PQExpBuffer query;
5562  NamespaceInfo *nsinfo;
5563  int i_tableoid;
5564  int i_oid;
5565  int i_nspname;
5566  int i_nspowner;
5567  int i_nspacl;
5568  int i_acldefault;
5569 
5570  query = createPQExpBuffer();
5571 
5572  /*
5573  * we fetch all namespaces including system ones, so that every object we
5574  * read in can be linked to a containing namespace.
5575  */
5576  appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5577  "n.nspowner, "
5578  "n.nspacl, "
5579  "acldefault('n', n.nspowner) AS acldefault "
5580  "FROM pg_namespace n");
5581 
5582  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5583 
5584  ntups = PQntuples(res);
5585 
5586  nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5587 
5588  i_tableoid = PQfnumber(res, "tableoid");
5589  i_oid = PQfnumber(res, "oid");
5590  i_nspname = PQfnumber(res, "nspname");
5591  i_nspowner = PQfnumber(res, "nspowner");
5592  i_nspacl = PQfnumber(res, "nspacl");
5593  i_acldefault = PQfnumber(res, "acldefault");
5594 
5595  for (i = 0; i < ntups; i++)
5596  {
5597  const char *nspowner;
5598 
5599  nsinfo[i].dobj.objType = DO_NAMESPACE;
5600  nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5601  nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5602  AssignDumpId(&nsinfo[i].dobj);
5603  nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5604  nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5605  nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5606  nsinfo[i].dacl.privtype = 0;
5607  nsinfo[i].dacl.initprivs = NULL;
5608  nspowner = PQgetvalue(res, i, i_nspowner);
5609  nsinfo[i].nspowner = atooid(nspowner);
5610  nsinfo[i].rolname = getRoleName(nspowner);
5611 
5612  /* Decide whether to dump this namespace */
5613  selectDumpableNamespace(&nsinfo[i], fout);
5614 
5615  /* Mark whether namespace has an ACL */
5616  if (!PQgetisnull(res, i, i_nspacl))
5617  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5618 
5619  /*
5620  * We ignore any pg_init_privs.initprivs entry for the public schema
5621  * and assume a predetermined default, for several reasons. First,
5622  * dropping and recreating the schema removes its pg_init_privs entry,
5623  * but an empty destination database starts with this ACL nonetheless.
5624  * Second, we support dump/reload of public schema ownership changes.
5625  * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5626  * initprivs continues to reflect the initial owner. Hence,
5627  * synthesize the value that nspacl will have after the restore's
5628  * ALTER SCHEMA OWNER. Third, this makes the destination database
5629  * match the source's ACL, even if the latter was an initdb-default
5630  * ACL, which changed in v15. An upgrade pulls in changes to most
5631  * system object ACLs that the DBA had not customized. We've made the
5632  * public schema depart from that, because changing its ACL so easily
5633  * breaks applications.
5634  */
5635  if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5636  {
5637  PQExpBuffer aclarray = createPQExpBuffer();
5638  PQExpBuffer aclitem = createPQExpBuffer();
5639 
5640  /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5641  appendPQExpBufferChar(aclarray, '{');
5642  quoteAclUserName(aclitem, nsinfo[i].rolname);
5643  appendPQExpBufferStr(aclitem, "=UC/");
5644  quoteAclUserName(aclitem, nsinfo[i].rolname);
5645  appendPGArray(aclarray, aclitem->data);
5646  resetPQExpBuffer(aclitem);
5647  appendPQExpBufferStr(aclitem, "=U/");
5648  quoteAclUserName(aclitem, nsinfo[i].rolname);
5649  appendPGArray(aclarray, aclitem->data);
5650  appendPQExpBufferChar(aclarray, '}');
5651 
5652  nsinfo[i].dacl.privtype = 'i';
5653  nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5654  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5655 
5656  destroyPQExpBuffer(aclarray);
5657  destroyPQExpBuffer(aclitem);
5658  }
5659  }
5660 
5661  PQclear(res);
5662  destroyPQExpBuffer(query);
5663 
5664  *numNamespaces = ntups;
5665 
5666  return nsinfo;
5667 }
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:1753
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()

OpclassInfo* getOpclasses ( Archive fout,
int *  numOpclasses 
)

Definition at line 6218 of file pg_dump.c.

6219 {
6220  PGresult *res;
6221  int ntups;
6222  int i;
6223  PQExpBuffer query = createPQExpBuffer();
6224  OpclassInfo *opcinfo;
6225  int i_tableoid;
6226  int i_oid;
6227  int i_opcname;
6228  int i_opcnamespace;
6229  int i_opcowner;
6230 
6231  /*
6232  * find all opclasses, including builtin opclasses; we filter out
6233  * system-defined opclasses at dump-out time.
6234  */
6235 
6236  appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
6237  "opcnamespace, "
6238  "opcowner "
6239  "FROM pg_opclass");
6240 
6241  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6242 
6243  ntups = PQntuples(res);
6244  *numOpclasses = ntups;
6245 
6246  opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6247 
6248  i_tableoid = PQfnumber(res, "tableoid");
6249  i_oid = PQfnumber(res, "oid");
6250  i_opcname = PQfnumber(res, "opcname");
6251  i_opcnamespace = PQfnumber(res, "opcnamespace");
6252  i_opcowner = PQfnumber(res, "opcowner");
6253 
6254  for (i = 0; i < ntups; i++)
6255  {
6256  opcinfo[i].dobj.objType = DO_OPCLASS;
6257  opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6258  opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6259  AssignDumpId(&opcinfo[i].dobj);
6260  opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6261  opcinfo[i].dobj.namespace =
6262  findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6263  opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6264 
6265  /* Decide whether we want to dump it */
6266  selectDumpableObject(&(opcinfo[i].dobj), fout);
6267  }
6268 
6269  PQclear(res);
6270 
6271  destroyPQExpBuffer(query);
6272 
6273  return opcinfo;
6274 }

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()

OprInfo* getOperators ( Archive fout,
int *  numOprs 
)

Definition at line 5937 of file pg_dump.c.

5938 {
5939  PGresult *res;
5940  int ntups;
5941  int i;
5942  PQExpBuffer query = createPQExpBuffer();
5943  OprInfo *oprinfo;
5944  int i_tableoid;
5945  int i_oid;
5946  int i_oprname;
5947  int i_oprnamespace;
5948  int i_oprowner;
5949  int i_oprkind;
5950  int i_oprcode;
5951 
5952  /*
5953  * find all operators, including builtin operators; we filter out
5954  * system-defined operators at dump-out time.
5955  */
5956 
5957  appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
5958  "oprnamespace, "
5959  "oprowner, "
5960  "oprkind, "
5961  "oprcode::oid AS oprcode "
5962  "FROM pg_operator");
5963 
5964  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5965 
5966  ntups = PQntuples(res);
5967  *numOprs = ntups;
5968 
5969  oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
5970 
5971  i_tableoid = PQfnumber(res, "tableoid");
5972  i_oid = PQfnumber(res, "oid");
5973  i_oprname = PQfnumber(res, "oprname");
5974  i_oprnamespace = PQfnumber(res, "oprnamespace");
5975  i_oprowner = PQfnumber(res, "oprowner");
5976  i_oprkind = PQfnumber(res, "oprkind");
5977  i_oprcode = PQfnumber(res, "oprcode");
5978 
5979  for (i = 0; i < ntups; i++)
5980  {
5981  oprinfo[i].dobj.objType = DO_OPERATOR;
5982  oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5983  oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5984  AssignDumpId(&oprinfo[i].dobj);
5985  oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
5986  oprinfo[i].dobj.namespace =
5987  findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
5988  oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
5989  oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
5990  oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
5991 
5992  /* Decide whether we want to dump it */
5993  selectDumpableObject(&(oprinfo[i].dobj), fout);
5994  }
5995 
5996  PQclear(res);
5997 
5998  destroyPQExpBuffer(query);
5999 
6000  return oprinfo;
6001 }
char oprkind
Definition: pg_dump.h:245

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()

OpfamilyInfo* getOpfamilies ( Archive fout,
int *  numOpfamilies 
)

Definition at line 6284 of file pg_dump.c.

6285 {
6286  PGresult *res;
6287  int ntups;
6288  int i;
6289  PQExpBuffer query;
6290  OpfamilyInfo *opfinfo;
6291  int i_tableoid;
6292  int i_oid;
6293  int i_opfname;
6294  int i_opfnamespace;
6295  int i_opfowner;
6296 
6297  query = createPQExpBuffer();
6298 
6299  /*
6300  * find all opfamilies, including builtin opfamilies; we filter out
6301  * system-defined opfamilies at dump-out time.
6302  */
6303 
6304  appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
6305  "opfnamespace, "
6306  "opfowner "
6307  "FROM pg_opfamily");
6308 
6309  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6310 
6311  ntups = PQntuples(res);
6312  *numOpfamilies = ntups;
6313 
6314  opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6315 
6316  i_tableoid = PQfnumber(res, "tableoid");
6317  i_oid = PQfnumber(res, "oid");
6318  i_opfname = PQfnumber(res, "opfname");
6319  i_opfnamespace = PQfnumber(res, "opfnamespace");
6320  i_opfowner = PQfnumber(res, "opfowner");
6321 
6322  for (i = 0; i < ntups; i++)
6323  {
6324  opfinfo[i].dobj.objType = DO_OPFAMILY;
6325  opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6326  opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6327  AssignDumpId(&opfinfo[i].dobj);
6328  opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6329  opfinfo[i].dobj.namespace =
6330  findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6331  opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6332 
6333  /* Decide whether we want to dump it */
6334  selectDumpableObject(&(opfinfo[i].dobj), fout);
6335  }
6336 
6337  PQclear(res);
6338 
6339  destroyPQExpBuffer(query);
6340 
6341  return opfinfo;
6342 }

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

7145 {
7146  int i;
7147 
7148  /*
7149  * Force sequences that are "owned" by table columns to be dumped whenever
7150  * their owning table is being dumped.
7151  */
7152  for (i = 0; i < numTables; i++)
7153  {
7154  TableInfo *seqinfo = &tblinfo[i];
7155  TableInfo *owning_tab;
7156 
7157  if (!OidIsValid(seqinfo->owning_tab))
7158  continue; /* not an owned sequence */
7159 
7160  owning_tab = findTableByOid(seqinfo->owning_tab);
7161  if (owning_tab == NULL)
7162  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7163  seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7164 
7165  /*
7166  * Only dump identity sequences if we're going to dump the table that
7167  * it belongs to.
7168  */
7169  if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
7170  seqinfo->is_identity_sequence)
7171  {
7172  seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
7173  continue;
7174  }
7175 
7176  /*
7177  * Otherwise we need to dump the components that are being dumped for
7178  * the table and any components which the sequence is explicitly
7179  * marked with.
7180  *
7181  * We can't simply use the set of components which are being dumped
7182  * for the table as the table might be in an extension (and only the
7183  * non-extension components, eg: ACLs if changed, security labels, and
7184  * policies, are being dumped) while the sequence is not (and
7185  * therefore the definition and other components should also be
7186  * dumped).
7187  *
7188  * If the sequence is part of the extension then it should be properly
7189  * marked by checkExtensionMembership() and this will be a no-op as
7190  * the table will be equivalently marked.
7191  */
7192  seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
7193 
7194  if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7195  seqinfo->interesting = true;
7196  }
7197 }

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

7264 {
7265  PQExpBuffer query;
7266  PGresult *res;
7267  int ntups;
7268 
7269  /* hash partitioning didn't exist before v11 */
7270  if (fout->remoteVersion < 110000)
7271  return;
7272  /* needn't bother if schema-only dump */
7273  if (fout->dopt->schemaOnly)
7274  return;
7275 
7276  query = createPQExpBuffer();
7277 
7278  /*
7279  * Unsafe partitioning schemes are exactly those for which hash enum_ops
7280  * appears among the partition opclasses. We needn't check partstrat.
7281  *
7282  * Note that this query may well retrieve info about tables we aren't
7283  * going to dump and hence have no lock on. That's okay since we need not
7284  * invoke any unsafe server-side functions.
7285  */
7286  appendPQExpBufferStr(query,
7287  "SELECT partrelid FROM pg_partitioned_table WHERE\n"
7288  "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
7289  "ON c.opcmethod = a.oid\n"
7290  "WHERE opcname = 'enum_ops' "
7291  "AND opcnamespace = 'pg_catalog'::regnamespace "
7292  "AND amname = 'hash') = ANY(partclass)");
7293 
7294  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7295 
7296  ntups = PQntuples(res);
7297 
7298  for (int i = 0; i < ntups; i++)
7299  {
7300  Oid tabrelid = atooid(PQgetvalue(res, i, 0));
7301  TableInfo *tbinfo;
7302 
7303  tbinfo = findTableByOid(tabrelid);
7304  if (tbinfo == NULL)
7305  pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
7306  tabrelid);
7307  tbinfo->unsafe_partitions = true;
7308  }
7309 
7310  PQclear(res);
7311 
7312  destroyPQExpBuffer(query);
7313 }

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

3893 {
3894  PQExpBuffer query;
3895  PQExpBuffer tbloids;
3896  PGresult *res;
3897  PolicyInfo *polinfo;
3898  int i_oid;
3899  int i_tableoid;
3900  int i_polrelid;
3901  int i_polname;
3902  int i_polcmd;
3903  int i_polpermissive;
3904  int i_polroles;
3905  int i_polqual;
3906  int i_polwithcheck;
3907  int i,
3908  j,
3909  ntups;
3910 
3911  /* No policies before 9.5 */
3912  if (fout->remoteVersion < 90500)
3913  return;
3914 
3915  query = createPQExpBuffer();
3916  tbloids = createPQExpBuffer();
3917 
3918  /*
3919  * Identify tables of interest, and check which ones have RLS enabled.
3920  */
3921  appendPQExpBufferChar(tbloids, '{');
3922  for (i = 0; i < numTables; i++)
3923  {
3924  TableInfo *tbinfo = &tblinfo[i];
3925 
3926  /* Ignore row security on tables not to be dumped */
3927  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3928  continue;
3929 
3930  /* It can't have RLS or policies if it's not a table */
3931  if (tbinfo->relkind != RELKIND_RELATION &&
3932  tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
3933  continue;
3934 
3935  /* Add it to the list of table OIDs to be probed below */
3936  if (tbloids->len > 1) /* do we have more than the '{'? */
3937  appendPQExpBufferChar(tbloids, ',');
3938  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
3939 
3940  /* Is RLS enabled? (That's separate from whether it has policies) */
3941  if (tbinfo->rowsec)
3942  {
3944 
3945  /*
3946  * We represent RLS being enabled on a table by creating a
3947  * PolicyInfo object with null polname.
3948  *
3949  * Note: use tableoid 0 so that this object won't be mistaken for
3950  * something that pg_depend entries apply to.
3951  */
3952  polinfo = pg_malloc(sizeof(PolicyInfo));
3953  polinfo->dobj.objType = DO_POLICY;
3954  polinfo->dobj.catId.tableoid = 0;
3955  polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
3956  AssignDumpId(&polinfo->dobj);
3957  polinfo->dobj.namespace = tbinfo->dobj.namespace;
3958  polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
3959  polinfo->poltable = tbinfo;
3960  polinfo->polname = NULL;
3961  polinfo->polcmd = '\0';
3962  polinfo->polpermissive = 0;
3963  polinfo->polroles = NULL;
3964  polinfo->polqual = NULL;
3965  polinfo->polwithcheck = NULL;
3966  }
3967  }
3968  appendPQExpBufferChar(tbloids, '}');
3969 
3970  /*
3971  * Now, read all RLS policies belonging to the tables of interest, and
3972  * create PolicyInfo objects for them. (Note that we must filter the
3973  * results server-side not locally, because we dare not apply pg_get_expr
3974  * to tables we don't have lock on.)
3975  */
3976  pg_log_info("reading row-level security policies");
3977 
3978  printfPQExpBuffer(query,
3979  "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3980  if (fout->remoteVersion >= 100000)
3981  appendPQExpBufferStr(query, "pol.polpermissive, ");
3982  else
3983  appendPQExpBufferStr(query, "'t' as polpermissive, ");
3984  appendPQExpBuffer(query,
3985  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
3986  " 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, "
3987  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
3988  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
3989  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
3990  "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
3991  tbloids->data);
3992 
3993  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3994 
3995  ntups = PQntuples(res);
3996  if (ntups > 0)
3997  {
3998  i_oid = PQfnumber(res, "oid");
3999  i_tableoid = PQfnumber(res, "tableoid");
4000  i_polrelid = PQfnumber(res, "polrelid");
4001  i_polname = PQfnumber(res, "polname");
4002  i_polcmd = PQfnumber(res, "polcmd");
4003  i_polpermissive = PQfnumber(res, "polpermissive");
4004  i_polroles = PQfnumber(res, "polroles");
4005  i_polqual = PQfnumber(res, "polqual");
4006  i_polwithcheck = PQfnumber(res, "polwithcheck");
4007 
4008  polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
4009 
4010  for (j = 0; j < ntups; j++)
4011  {
4012  Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
4013  TableInfo *tbinfo = findTableByOid(polrelid);
4014 
4016 
4017  polinfo[j].dobj.objType = DO_POLICY;
4018  polinfo[j].dobj.catId.tableoid =
4019  atooid(PQgetvalue(res, j, i_tableoid));
4020  polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4021  AssignDumpId(&polinfo[j].dobj);
4022  polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4023  polinfo[j].poltable = tbinfo;
4024  polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
4025  polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
4026 
4027  polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
4028  polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
4029 
4030  if (PQgetisnull(res, j, i_polroles))
4031  polinfo[j].polroles = NULL;
4032  else
4033  polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
4034 
4035  if (PQgetisnull(res, j, i_polqual))
4036  polinfo[j].polqual = NULL;
4037  else
4038  polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
4039 
4040  if (PQgetisnull(res, j, i_polwithcheck))
4041  polinfo[j].polwithcheck = NULL;
4042  else
4043  polinfo[j].polwithcheck
4044  = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
4045  }
4046  }
4047 
4048  PQclear(res);
4049 
4050  destroyPQExpBuffer(query);
4051  destroyPQExpBuffer(tbloids);
4052 }
#define DUMP_COMPONENT_POLICY
Definition: pg_dump.h:102
bool rowsec
Definition: pg_dump.h:300

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()

ProcLangInfo* getProcLangs ( Archive fout,
int *  numProcLangs 
)

Definition at line 8386 of file pg_dump.c.

8387 {
8388  PGresult *res;
8389  int ntups;
8390  int i;
8391  PQExpBuffer query = createPQExpBuffer();
8392  ProcLangInfo *planginfo;
8393  int i_tableoid;
8394  int i_oid;
8395  int i_lanname;
8396  int i_lanpltrusted;
8397  int i_lanplcallfoid;
8398  int i_laninline;
8399  int i_lanvalidator;
8400  int i_lanacl;
8401  int i_acldefault;
8402  int i_lanowner;
8403 
8404  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8405  "lanname, lanpltrusted, lanplcallfoid, "
8406  "laninline, lanvalidator, "
8407  "lanacl, "
8408  "acldefault('l', lanowner) AS acldefault, "
8409  "lanowner "
8410  "FROM pg_language "
8411  "WHERE lanispl "
8412  "ORDER BY oid");
8413 
8414  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8415 
8416  ntups = PQntuples(res);
8417 
8418  *numProcLangs = ntups;
8419 
8420  planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8421 
8422  i_tableoid = PQfnumber(res, "tableoid");
8423  i_oid = PQfnumber(res, "oid");
8424  i_lanname = PQfnumber(res, "lanname");
8425  i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8426  i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8427  i_laninline = PQfnumber(res, "laninline");
8428  i_lanvalidator = PQfnumber(res, "lanvalidator");
8429  i_lanacl = PQfnumber(res, "lanacl");
8430  i_acldefault = PQfnumber(res, "acldefault");
8431  i_lanowner = PQfnumber(res, "lanowner");
8432 
8433  for (i = 0; i < ntups; i++)
8434  {
8435  planginfo[i].dobj.objType = DO_PROCLANG;
8436  planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8437  planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8438  AssignDumpId(&planginfo[i].dobj);
8439 
8440  planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8441  planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8442  planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8443  planginfo[i].dacl.privtype = 0;
8444  planginfo[i].dacl.initprivs = NULL;
8445  planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8446  planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8447  planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8448  planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8449  planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8450 
8451  /* Decide whether we want to dump it */
8452  selectDumpableProcLang(&(planginfo[i]), fout);
8453 
8454  /* Mark whether language has an ACL */
8455  if (!PQgetisnull(res, i, i_lanacl))
8456  planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8457  }
8458 
8459  PQclear(res);
8460 
8461  destroyPQExpBuffer(query);
8462 
8463  return planginfo;
8464 }
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:1970

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

4378 {
4379  PQExpBuffer query;
4380  PGresult *res;
4381  PublicationSchemaInfo *pubsinfo;
4382  DumpOptions *dopt = fout->dopt;
4383  int i_tableoid;
4384  int i_oid;
4385  int i_pnpubid;
4386  int i_pnnspid;
4387  int i,
4388  j,
4389  ntups;
4390 
4391  if (dopt->no_publications || fout->remoteVersion < 150000)
4392  return;
4393 
4394  query = createPQExpBuffer();
4395 
4396  /* Collect all publication membership info. */
4397  appendPQExpBufferStr(query,
4398  "SELECT tableoid, oid, pnpubid, pnnspid "
4399  "FROM pg_catalog.pg_publication_namespace");
4400  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4401 
4402  ntups = PQntuples(res);
4403 
4404  i_tableoid = PQfnumber(res, "tableoid");
4405  i_oid = PQfnumber(res, "oid");
4406  i_pnpubid = PQfnumber(res, "pnpubid");
4407  i_pnnspid = PQfnumber(res, "pnnspid");
4408 
4409  /* this allocation may be more than we need */
4410  pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4411  j = 0;
4412 
4413  for (i = 0; i < ntups; i++)
4414  {
4415  Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4416  Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4417  PublicationInfo *pubinfo;
4418  NamespaceInfo *nspinfo;
4419 
4420  /*
4421  * Ignore any entries for which we aren't interested in either the
4422  * publication or the rel.
4423  */
4424  pubinfo = findPublicationByOid(pnpubid);
4425  if (pubinfo == NULL)
4426  continue;
4427  nspinfo = findNamespaceByOid(pnnspid);
4428  if (nspinfo == NULL)
4429  continue;
4430 
4431  /*
4432  * We always dump publication namespaces unless the corresponding
4433  * namespace is excluded from the dump.
4434  */
4435  if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
4436  continue;
4437 
4438  /* OK, make a DumpableObject for this relationship */
4440  pubsinfo[j].dobj.catId.tableoid =
4441  atooid(PQgetvalue(res, i, i_tableoid));
4442  pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4443  AssignDumpId(&pubsinfo[j].dobj);
4444  pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4445  pubsinfo[j].dobj.name = nspinfo->dobj.name;
4446  pubsinfo[j].publication = pubinfo;
4447  pubsinfo[j].pubschema = nspinfo;
4448 
4449  /* Decide whether we want to dump it */
4450  selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4451 
4452  j++;
4453  }
4454 
4455  PQclear(res);
4456  destroyPQExpBuffer(query);
4457 }
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:999
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2070
int no_publications
Definition: pg_backup.h:182

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()

PublicationInfo* getPublications ( Archive fout,
int *  numPublications 
)

Definition at line 4177 of file pg_dump.c.

4178 {
4179  DumpOptions *dopt = fout->dopt;
4180  PQExpBuffer query;
4181  PGresult *res;
4182  PublicationInfo *pubinfo;
4183  int i_tableoid;
4184  int i_oid;
4185  int i_pubname;
4186  int i_pubowner;
4187  int i_puballtables;
4188  int i_pubinsert;
4189  int i_pubupdate;
4190  int i_pubdelete;
4191  int i_pubtruncate;
4192  int i_pubviaroot;
4193  int i,
4194  ntups;
4195 
4196  if (dopt->no_publications || fout->remoteVersion < 100000)
4197  {
4198  *numPublications = 0;
4199  return NULL;
4200  }
4201 
4202  query = createPQExpBuffer();
4203 
4204  resetPQExpBuffer(query);
4205 
4206  /* Get the publications. */
4207  if (fout->remoteVersion >= 130000)
4208  appendPQExpBufferStr(query,
4209  "SELECT p.tableoid, p.oid, p.pubname, "
4210  "p.pubowner, "
4211  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
4212  "FROM pg_publication p");
4213  else if (fout->remoteVersion >= 110000)
4214  appendPQExpBufferStr(query,
4215  "SELECT p.tableoid, p.oid, p.pubname, "
4216  "p.pubowner, "
4217  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
4218  "FROM pg_publication p");
4219  else
4220  appendPQExpBufferStr(query,
4221  "SELECT p.tableoid, p.oid, p.pubname, "
4222  "p.pubowner, "
4223  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot "
4224  "FROM pg_publication p");
4225 
4226  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4227 
4228  ntups = PQntuples(res);
4229 
4230  i_tableoid = PQfnumber(res, "tableoid");
4231  i_oid = PQfnumber(res, "oid");
4232  i_pubname = PQfnumber(res, "pubname");
4233  i_pubowner = PQfnumber(res, "pubowner");
4234  i_puballtables = PQfnumber(res, "puballtables");
4235  i_pubinsert = PQfnumber(res, "pubinsert");
4236  i_pubupdate = PQfnumber(res, "pubupdate");
4237  i_pubdelete = PQfnumber(res, "pubdelete");
4238  i_pubtruncate = PQfnumber(res, "pubtruncate");
4239  i_pubviaroot = PQfnumber(res, "pubviaroot");
4240 
4241  pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4242 
4243  for (i = 0; i < ntups; i++)
4244  {
4245  pubinfo[i].dobj.objType = DO_PUBLICATION;
4246  pubinfo[i].dobj.catId.tableoid =
4247  atooid(PQgetvalue(res, i, i_tableoid));
4248  pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4249  AssignDumpId(&pubinfo[i].dobj);
4250  pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4251  pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4252  pubinfo[i].puballtables =
4253  (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4254  pubinfo[i].pubinsert =
4255  (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4256  pubinfo[i].pubupdate =
4257  (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4258  pubinfo[i].pubdelete =
4259  (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4260  pubinfo[i].pubtruncate =
4261  (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4262  pubinfo[i].pubviaroot =
4263  (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4264 
4265  /* Decide whether we want to dump it */
4266  selectDumpableObject(&(pubinfo[i].dobj), fout);
4267  }
4268  PQclear(res);
4269 
4270  destroyPQExpBuffer(query);
4271 
4272  *numPublications = ntups;
4273  return pubinfo;
4274 }

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, 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::pubinsert, _PublicationInfo::pubtruncate, _PublicationInfo::pubupdate, _PublicationInfo::pubviaroot, Archive::remoteVersion, res, resetPQExpBuffer(), _PublicationInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationTables()

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

Definition at line 4464 of file pg_dump.c.

4465 {
4466  PQExpBuffer query;
4467  PGresult *res;
4468  PublicationRelInfo *pubrinfo;
4469  DumpOptions *dopt = fout->dopt;
4470  int i_tableoid;
4471  int i_oid;
4472  int i_prpubid;
4473  int i_prrelid;
4474  int i_prrelqual;
4475  int i_prattrs;
4476  int i,
4477  j,
4478  ntups;
4479 
4480  if (dopt->no_publications || fout->remoteVersion < 100000)
4481  return;
4482 
4483  query = createPQExpBuffer();
4484 
4485  /* Collect all publication membership info. */
4486  if (fout->remoteVersion >= 150000)
4487  appendPQExpBufferStr(query,
4488  "SELECT tableoid, oid, prpubid, prrelid, "
4489  "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
4490  "(CASE\n"
4491  " WHEN pr.prattrs IS NOT NULL THEN\n"
4492  " (SELECT array_agg(attname)\n"
4493  " FROM\n"
4494  " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
4495  " pg_catalog.pg_attribute\n"
4496  " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
4497  " ELSE NULL END) prattrs "
4498  "FROM pg_catalog.pg_publication_rel pr");
4499  else
4500  appendPQExpBufferStr(query,
4501  "SELECT tableoid, oid, prpubid, prrelid, "
4502  "NULL AS prrelqual, NULL AS prattrs "
4503  "FROM pg_catalog.pg_publication_rel");
4504  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4505 
4506  ntups = PQntuples(res);
4507 
4508  i_tableoid = PQfnumber(res, "tableoid");
4509  i_oid = PQfnumber(res, "oid");
4510  i_prpubid = PQfnumber(res, "prpubid");
4511  i_prrelid = PQfnumber(res, "prrelid");
4512  i_prrelqual = PQfnumber(res, "prrelqual");
4513  i_prattrs = PQfnumber(res, "prattrs");
4514 
4515  /* this allocation may be more than we need */
4516  pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4517  j = 0;
4518 
4519  for (i = 0; i < ntups; i++)
4520  {
4521  Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4522  Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4523  PublicationInfo *pubinfo;
4524  TableInfo *tbinfo;
4525 
4526  /*
4527  * Ignore any entries for which we aren't interested in either the
4528  * publication or the rel.
4529  */
4530  pubinfo = findPublicationByOid(prpubid);
4531  if (pubinfo == NULL)
4532  continue;
4533  tbinfo = findTableByOid(prrelid);
4534  if (tbinfo == NULL)
4535  continue;
4536 
4537  /*
4538  * Ignore publication membership of tables whose definitions are not
4539  * to be dumped.
4540  */
4541  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
4542  continue;
4543 
4544  /* OK, make a DumpableObject for this relationship */
4545  pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4546  pubrinfo[j].dobj.catId.tableoid =
4547  atooid(PQgetvalue(res, i, i_tableoid));
4548  pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4549  AssignDumpId(&pubrinfo[j].dobj);
4550  pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4551  pubrinfo[j].dobj.name = tbinfo->dobj.name;
4552  pubrinfo[j].publication = pubinfo;
4553  pubrinfo[j].pubtable = tbinfo;
4554  if (PQgetisnull(res, i, i_prrelqual))
4555  pubrinfo[j].pubrelqual = NULL;
4556  else
4557  pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
4558 
4559  if (!PQgetisnull(res, i, i_prattrs))
4560  {
4561  char **attnames;
4562  int nattnames;
4563  PQExpBuffer attribs;
4564 
4565  if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
4566  &attnames, &nattnames))
4567  pg_fatal("could not parse %s array", "prattrs");
4568  attribs = createPQExpBuffer();
4569  for (int k = 0; k < nattnames; k++)
4570  {
4571  if (k > 0)
4572  appendPQExpBufferStr(attribs, ", ");
4573 
4574  appendPQExpBufferStr(attribs, fmtId(attnames[k]));
4575  }
4576  pubrinfo[j].pubrattrs = attribs->data;
4577  }
4578  else
4579  pubrinfo[j].pubrattrs = NULL;
4580 
4581  /* Decide whether we want to dump it */
4582  selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
4583 
4584  j++;
4585  }
4586 
4587  PQclear(res);
4588  destroyPQExpBuffer(query);
4589 }

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

10022 {
10023  Oid roleoid = atooid(roleoid_str);
10024 
10025  /*
10026  * Do binary search to find the appropriate item.
10027  */
10028  if (nrolenames > 0)
10029  {
10030  RoleNameItem *low = &rolenames[0];
10031  RoleNameItem *high = &rolenames[nrolenames - 1];
10032 
10033  while (low <= high)
10034  {
10035  RoleNameItem *middle = low + (high - low) / 2;
10036 
10037  if (roleoid < middle->roleoid)
10038  high = middle - 1;
10039  else if (roleoid > middle->roleoid)
10040  low = middle + 1;
10041  else
10042  return middle->rolename; /* found a match */
10043  }
10044  }
10045 
10046  pg_fatal("role with OID %u does not exist", roleoid);
10047  return NULL; /* keep compiler quiet */
10048 }

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

2549 {
2550  TableInfo *parentTbinfo;
2551 
2552  Assert(tbinfo->ispartition);
2553  Assert(tbinfo->numParents == 1);
2554 
2555  parentTbinfo = tbinfo->parents[0];
2556  while (parentTbinfo->ispartition)
2557  {
2558  Assert(parentTbinfo->numParents == 1);
2559  parentTbinfo = parentTbinfo->parents[0];
2560  }
2561 
2562  return parentTbinfo;
2563 }

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

Referenced by dumpTableData(), and dumpTableData_insert().

◆ getRules()

RuleInfo* getRules ( Archive fout,
int *  numRules 
)

Definition at line 8002 of file pg_dump.c.

8003 {
8004  PGresult *res;
8005  int ntups;
8006  int i;
8007  PQExpBuffer query = createPQExpBuffer();
8008  RuleInfo *ruleinfo;
8009  int i_tableoid;
8010  int i_oid;
8011  int i_rulename;
8012  int i_ruletable;
8013  int i_ev_type;
8014  int i_is_instead;
8015  int i_ev_enabled;
8016 
8017  appendPQExpBufferStr(query, "SELECT "
8018  "tableoid, oid, rulename, "
8019  "ev_class AS ruletable, ev_type, is_instead, "
8020  "ev_enabled "
8021  "FROM pg_rewrite "
8022  "ORDER BY oid");
8023 
8024  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8025 
8026  ntups = PQntuples(res);
8027 
8028  *numRules = ntups;
8029 
8030  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8031 
8032  i_tableoid = PQfnumber(res, "tableoid");
8033  i_oid = PQfnumber(res, "oid");
8034  i_rulename = PQfnumber(res, "rulename");
8035  i_ruletable = PQfnumber(res, "ruletable");
8036  i_ev_type = PQfnumber(res, "ev_type");
8037  i_is_instead = PQfnumber(res, "is_instead");
8038  i_ev_enabled = PQfnumber(res, "ev_enabled");
8039 
8040  for (i = 0; i < ntups; i++)
8041  {
8042  Oid ruletableoid;
8043 
8044  ruleinfo[i].dobj.objType = DO_RULE;
8045  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8046  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8047  AssignDumpId(&ruleinfo[i].dobj);
8048  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8049  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8050  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8051  if (ruleinfo[i].ruletable == NULL)
8052  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8053  ruletableoid, ruleinfo[i].dobj.catId.oid);
8054  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8055  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8056  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8057  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8058  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8059  if (ruleinfo[i].ruletable)
8060  {
8061  /*
8062  * If the table is a view or materialized view, force its ON
8063  * SELECT rule to be sorted before the view itself --- this
8064  * ensures that any dependencies for the rule affect the table's
8065  * positioning. Other rules are forced to appear after their
8066  * table.
8067  */
8068  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8069  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8070  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8071  {
8072  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8073  ruleinfo[i].dobj.dumpId);
8074  /* We'll merge the rule into CREATE VIEW, if possible */
8075  ruleinfo[i].separate = false;
8076  }
8077  else
8078  {
8079  addObjectDependency(&ruleinfo[i].dobj,
8080  ruleinfo[i].ruletable->dobj.dumpId);
8081  ruleinfo[i].separate = true;
8082  }
8083  }
8084  else
8085  ruleinfo[i].separate = true;
8086  }
8087 
8088  PQclear(res);
8089 
8090  destroyPQExpBuffer(query);
8091 
8092  return ruleinfo;
8093 }

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

4719 {
4720  DumpOptions *dopt = fout->dopt;
4721  PQExpBuffer query;
4722  PGresult *res;
4723  SubscriptionInfo *subinfo;
4724  int i_tableoid;
4725  int i_oid;
4726  int i_subname;
4727  int i_subowner;
4728  int i_subbinary;
4729  int i_substream;
4730  int i_subtwophasestate;
4731  int i_subdisableonerr;
4732  int i_subpasswordrequired;
4733  int i_subrunasowner;
4734  int i_subconninfo;
4735  int i_subslotname;
4736  int i_subsynccommit;
4737  int i_subpublications;
4738  int i_suborigin;
4739  int i_suboriginremotelsn;
4740  int i_subenabled;
4741  int i_subfailover;
4742  int i,
4743  ntups;
4744 
4745  if (dopt->no_subscriptions || fout->remoteVersion < 100000)
4746  return;
4747 
4748  if (!is_superuser(fout))
4749  {
4750  int n;
4751 
4752  res = ExecuteSqlQuery(fout,
4753  "SELECT count(*) FROM pg_subscription "
4754  "WHERE subdbid = (SELECT oid FROM pg_database"
4755  " WHERE datname = current_database())",
4756  PGRES_TUPLES_OK);
4757  n = atoi(PQgetvalue(res, 0, 0));
4758  if (n > 0)
4759  pg_log_warning("subscriptions not dumped because current user is not a superuser");
4760  PQclear(res);
4761  return;
4762  }
4763 
4764  query = createPQExpBuffer();
4765 
4766  /* Get the subscriptions in current database. */
4767  appendPQExpBufferStr(query,
4768  "SELECT s.tableoid, s.oid, s.subname,\n"
4769  " s.subowner,\n"
4770  " s.subconninfo, s.subslotname, s.subsynccommit,\n"
4771  " s.subpublications,\n");
4772 
4773  if (fout->remoteVersion >= 140000)
4774  appendPQExpBufferStr(query, " s.subbinary,\n");
4775  else
4776  appendPQExpBufferStr(query, " false AS subbinary,\n");
4777 
4778  if (fout->remoteVersion >= 140000)
4779  appendPQExpBufferStr(query, " s.substream,\n");
4780  else
4781  appendPQExpBufferStr(query, " 'f' AS substream,\n");
4782 
4783  if (fout->remoteVersion >= 150000)
4784  appendPQExpBufferStr(query,
4785  " s.subtwophasestate,\n"
4786  " s.subdisableonerr,\n");
4787  else
4788  appendPQExpBuffer(query,
4789  " '%c' AS subtwophasestate,\n"
4790  " false AS subdisableonerr,\n",
4792 
4793  if (fout->remoteVersion >= 160000)
4794  appendPQExpBufferStr(query,
4795  " s.subpasswordrequired,\n"
4796  " s.subrunasowner,\n"
4797  " s.suborigin,\n");
4798  else
4799  appendPQExpBuffer(query,
4800  " 't' AS subpasswordrequired,\n"
4801  " 't' AS subrunasowner,\n"
4802  " '%s' AS suborigin,\n",
4804 
4805  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4806  appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
4807  " s.subenabled,\n");
4808  else
4809  appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
4810  " false AS subenabled,\n");
4811 
4812  if (fout->remoteVersion >= 170000)
4813  appendPQExpBufferStr(query,
4814  " s.subfailover\n");
4815  else
4816  appendPQExpBuffer(query,
4817  " false AS subfailover\n");
4818 
4819  appendPQExpBufferStr(query,
4820  "FROM pg_subscription s\n");
4821 
4822  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4823  appendPQExpBufferStr(query,
4824  "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
4825  " ON o.external_id = 'pg_' || s.oid::text \n");
4826 
4827  appendPQExpBufferStr(query,
4828  "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
4829  " WHERE datname = current_database())");
4830 
4831  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4832 
4833  ntups = PQntuples(res);
4834 
4835  /*
4836  * Get subscription fields. We don't include subskiplsn in the dump as
4837  * after restoring the dump this value may no longer be relevant.
4838  */
4839  i_tableoid = PQfnumber(res, "tableoid");
4840  i_oid = PQfnumber(res, "oid");
4841  i_subname = PQfnumber(res, "subname");
4842  i_subowner = PQfnumber(res, "subowner");
4843  i_subbinary = PQfnumber(res, "subbinary");
4844  i_substream = PQfnumber(res, "substream");
4845  i_subtwophasestate = PQfnumber(res, "subtwophasestate");
4846  i_subdisableonerr = PQfnumber(res, "subdisableonerr");
4847  i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
4848  i_subrunasowner = PQfnumber(res, "subrunasowner");
4849  i_subconninfo = PQfnumber(res, "subconninfo");
4850  i_subslotname = PQfnumber(res, "subslotname");
4851  i_subsynccommit = PQfnumber(res, "subsynccommit");
4852  i_subpublications = PQfnumber(res, "subpublications");
4853  i_suborigin = PQfnumber(res, "suborigin");
4854  i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
4855  i_subenabled = PQfnumber(res, "subenabled");
4856  i_subfailover = PQfnumber(res, "subfailover");
4857 
4858  subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
4859 
4860  for (i = 0; i < ntups; i++)
4861  {
4862  subinfo[i].dobj.objType = DO_SUBSCRIPTION;
4863  subinfo[i].dobj.catId.tableoid =
4864  atooid(PQgetvalue(res, i, i_tableoid));
4865  subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4866  AssignDumpId(&subinfo[i].dobj);
4867  subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
4868  subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
4869 
4870  subinfo[i].subbinary =
4871  pg_strdup(PQgetvalue(res, i, i_subbinary));
4872  subinfo[i].substream =
4873  pg_strdup(PQgetvalue(res, i, i_substream));
4874  subinfo[i].subtwophasestate =
4875  pg_strdup(PQgetvalue(res, i, i_subtwophasestate));
4876  subinfo[i].subdisableonerr =
4877  pg_strdup(PQgetvalue(res, i, i_subdisableonerr));
4878  subinfo[i].subpasswordrequired =
4879  pg_strdup(PQgetvalue(res, i, i_subpasswordrequired));
4880  subinfo[i].subrunasowner =
4881  pg_strdup(PQgetvalue(res, i, i_subrunasowner));
4882  subinfo[i].subconninfo =
4883  pg_strdup(PQgetvalue(res, i, i_subconninfo));
4884  if (PQgetisnull(res, i, i_subslotname))
4885  subinfo[i].subslotname = NULL;
4886  else
4887  subinfo[i].subslotname =
4888  pg_strdup(PQgetvalue(res, i, i_subslotname));
4889  subinfo[i].subsynccommit =
4890  pg_strdup(PQgetvalue(res, i, i_subsynccommit));
4891  subinfo[i].subpublications =
4892  pg_strdup(PQgetvalue(res, i, i_subpublications));
4893  subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
4894  if (PQgetisnull(res, i, i_suboriginremotelsn))
4895  subinfo[i].suboriginremotelsn = NULL;
4896  else
4897  subinfo[i].suboriginremotelsn =
4898  pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
4899  subinfo[i].subenabled =
4900  pg_strdup(PQgetvalue(res, i, i_subenabled));
4901  subinfo[i].subfailover =
4902  pg_strdup(PQgetvalue(res, i, i_subfailover));
4903 
4904  /* Decide whether we want to dump it */
4905  selectDumpableObject(&(subinfo[i].dobj), fout);
4906  }
4907  PQclear(res);
4908 
4909  destroyPQExpBuffer(query);
4910 }
static bool is_superuser(Archive *fout)
Definition: pg_dump.c:4700
int no_subscriptions
Definition: pg_backup.h:183

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

4919 {
4920  DumpOptions *dopt = fout->dopt;
4921  SubscriptionInfo *subinfo = NULL;
4922  SubRelInfo *subrinfo;
4923  PGresult *res;
4924  int i_srsubid;
4925  int i_srrelid;
4926  int i_srsubstate;
4927  int i_srsublsn;
4928  int ntups;
4929  Oid last_srsubid = InvalidOid;
4930 
4931  if (dopt->no_subscriptions || !dopt->binary_upgrade ||
4932  fout->remoteVersion < 170000)
4933  return;
4934 
4935  res = ExecuteSqlQuery(fout,
4936  "SELECT srsubid, srrelid, srsubstate, srsublsn "
4937  "FROM pg_catalog.pg_subscription_rel "
4938  "ORDER BY srsubid",
4939  PGRES_TUPLES_OK);
4940  ntups = PQntuples(res);
4941  if (ntups == 0)
4942  goto cleanup;
4943 
4944  /* Get pg_subscription_rel attributes */
4945  i_srsubid = PQfnumber(res, "srsubid");
4946  i_srrelid = PQfnumber(res, "srrelid");
4947  i_srsubstate = PQfnumber(res, "srsubstate");
4948  i_srsublsn = PQfnumber(res, "srsublsn");
4949 
4950  subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
4951  for (int i = 0; i < ntups; i++)
4952  {
4953  Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
4954  Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
4955  TableInfo *tblinfo;
4956 
4957  /*
4958  * If we switched to a new subscription, check if the subscription
4959  * exists.
4960  */
4961  if (cur_srsubid != last_srsubid)
4962  {
4963  subinfo = findSubscriptionByOid(cur_srsubid);
4964  if (subinfo == NULL)
4965  pg_fatal("subscription with OID %u does not exist", cur_srsubid);
4966 
4967  last_srsubid = cur_srsubid;
4968  }
4969 
4970  tblinfo = findTableByOid(relid);
4971  if (tblinfo == NULL)
4972  pg_fatal("failed sanity check, table with OID %u not found",
4973  relid);
4974 
4975  /* OK, make a DumpableObject for this relationship */
4976  subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
4977  subrinfo[i].dobj.catId.tableoid = relid;
4978  subrinfo[i].dobj.catId.oid = cur_srsubid;
4979  AssignDumpId(&subrinfo[i].dobj);
4980  subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
4981  subrinfo[i].tblinfo = tblinfo;
4982  subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
4983  if (PQgetisnull(res, i, i_srsublsn))
4984  subrinfo[i].srsublsn = NULL;
4985  else
4986  subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
4987 
4988  subrinfo[i].subinfo = subinfo;
4989 
4990  /* Decide whether we want to dump it */
4991  selectDumpableObject(&(subrinfo[i].dobj), fout);
4992  }
4993 
4994 cleanup:
4995  PQclear(res);
4996 }
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:1017
static void cleanup(void)
Definition: bootstrap.c:682

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

8684 {
8685  DumpOptions *dopt = fout->dopt;
8687  PQExpBuffer tbloids = createPQExpBuffer();
8688  PQExpBuffer checkoids = createPQExpBuffer();
8689  PGresult *res;
8690  int ntups;
8691  int curtblindx;
8692  int i_attrelid;
8693  int i_attnum;
8694  int i_attname;
8695  int i_atttypname;
8696  int i_attstattarget;
8697  int i_attstorage;
8698  int i_typstorage;
8699  int i_attidentity;
8700  int i_attgenerated;
8701  int i_attisdropped;
8702  int i_attlen;
8703  int i_attalign;
8704  int i_attislocal;
8705  int i_notnull_name;
8706  int i_notnull_noinherit;
8707  int i_notnull_is_pk;
8708  int i_notnull_inh;
8709  int i_attoptions;
8710  int i_attcollation;
8711  int i_attcompression;
8712  int i_attfdwoptions;
8713  int i_attmissingval;
8714  int i_atthasdef;
8715 
8716  /*
8717  * We want to perform just one query against pg_attribute, and then just
8718  * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
8719  * (for CHECK constraints and for NOT NULL constraints). However, we
8720  * mustn't try to select every row of those catalogs and then sort it out
8721  * on the client side, because some of the server-side functions we need
8722  * would be unsafe to apply to tables we don't have lock on. Hence, we
8723  * build an array of the OIDs of tables we care about (and now have lock
8724  * on!), and use a WHERE clause to constrain which rows are selected.
8725  */
8726  appendPQExpBufferChar(tbloids, '{');
8727  appendPQExpBufferChar(checkoids, '{');
8728  for (int i = 0; i < numTables; i++)
8729  {
8730  TableInfo *tbinfo = &tblinfo[i];
8731 
8732  /* Don't bother to collect info for sequences */
8733  if (tbinfo->relkind == RELKIND_SEQUENCE)
8734  continue;
8735 
8736  /* Don't bother with uninteresting tables, either */
8737  if (!tbinfo->interesting)
8738  continue;
8739 
8740  /* OK, we need info for this table */
8741  if (tbloids->len > 1) /* do we have more than the '{'? */
8742  appendPQExpBufferChar(tbloids, ',');
8743  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8744 
8745  if (tbinfo->ncheck > 0)
8746  {
8747  /* Also make a list of the ones with check constraints */
8748  if (checkoids->len > 1) /* do we have more than the '{'? */
8749  appendPQExpBufferChar(checkoids, ',');
8750  appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
8751  }
8752  }
8753  appendPQExpBufferChar(tbloids, '}');
8754  appendPQExpBufferChar(checkoids, '}');
8755 
8756  /*
8757  * Find all the user attributes and their types.
8758  *
8759  * Since we only want to dump COLLATE clauses for attributes whose
8760  * collation is different from their type's default, we use a CASE here to
8761  * suppress uninteresting attcollations cheaply.
8762  */
8764  "SELECT\n"
8765  "a.attrelid,\n"
8766  "a.attnum,\n"
8767  "a.attname,\n"
8768  "a.attstattarget,\n"
8769  "a.attstorage,\n"
8770  "t.typstorage,\n"
8771  "a.atthasdef,\n"
8772  "a.attisdropped,\n"
8773  "a.attlen,\n"
8774  "a.attalign,\n"
8775  "a.attislocal,\n"
8776  "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
8777  "array_to_string(a.attoptions, ', ') AS attoptions,\n"
8778  "CASE WHEN a.attcollation <> t.typcollation "
8779  "THEN a.attcollation ELSE 0 END AS attcollation,\n"
8780  "pg_catalog.array_to_string(ARRAY("
8781  "SELECT pg_catalog.quote_ident(option_name) || "
8782  "' ' || pg_catalog.quote_literal(option_value) "
8783  "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8784  "ORDER BY option_name"
8785  "), E',\n ') AS attfdwoptions,\n");
8786 
8787  /*
8788  * Find out any NOT NULL markings for each column. In 17 and up we read
8789  * pg_constraint to obtain the constraint name. notnull_noinherit is set
8790  * according to the NO INHERIT property. For versions prior to 17, we
8791  * store an empty string as the name when a constraint is marked as
8792  * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
8793  * without a name); also, such cases are never NO INHERIT.
8794  *
8795  * We track in notnull_inh whether the constraint was defined directly in
8796  * this table or via an ancestor, for binary upgrade.
8797  *
8798  * Lastly, we need to know if the PK for the table involves each column;
8799  * for columns that are there we need a NOT NULL marking even if there's
8800  * no explicit constraint, to avoid the table having to be scanned for
8801  * NULLs after the data is loaded when the PK is created, later in the
8802  * dump; for this case we add throwaway constraints that are dropped once
8803  * the PK is created.
8804  *
8805  * Another complication arises from columns that have attnotnull set, but
8806  * for which no corresponding not-null nor PK constraint exists. This can
8807  * happen if, for example, a primary key is dropped indirectly -- say,
8808  * because one of its columns is dropped. This is an irregular condition,
8809  * so we don't work hard to preserve it, and instead act as though an
8810  * unnamed not-null constraint exists.
8811  */
8812  if (fout->remoteVersion >= 170000)
8814  "CASE WHEN co.conname IS NOT NULL THEN co.conname "
8815  " WHEN a.attnotnull AND copk.conname IS NULL THEN '' ELSE NULL END AS notnull_name,\n"
8816  "CASE WHEN co.conname IS NOT NULL THEN co.connoinherit "
8817  " WHEN a.attnotnull THEN false ELSE NULL END AS notnull_noinherit,\n"
8818  "copk.conname IS NOT NULL as notnull_is_pk,\n"
8819  "CASE WHEN co.conname IS NOT NULL THEN "
8820  " coalesce(NOT co.conislocal, true) "
8821  "ELSE false END as notnull_inh,\n");
8822  else
8824  "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
8825  "false AS notnull_noinherit,\n"
8826  "copk.conname IS NOT NULL AS notnull_is_pk,\n"
8827  "NOT a.attislocal AS notnull_inh,\n");
8828 
8829  if (fout->remoteVersion >= 140000)
8831  "a.attcompression AS attcompression,\n");
8832  else
8834  "'' AS attcompression,\n");
8835 
8836  if (fout->remoteVersion >= 100000)
8838  "a.attidentity,\n");
8839  else
8841  "'' AS attidentity,\n");
8842 
8843  if (fout->remoteVersion >= 110000)
8845  "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8846  "THEN a.attmissingval ELSE null END AS attmissingval,\n");
8847  else
8849  "NULL AS attmissingval,\n");
8850 
8851  if (fout->remoteVersion >= 120000)
8853  "a.attgenerated\n");
8854  else
8856  "'' AS attgenerated\n");
8857 
8858  /* need left join to pg_type to not fail on dropped columns ... */
8860  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8861  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
8862  "LEFT JOIN pg_catalog.pg_type t "
8863  "ON (a.atttypid = t.oid)\n",
8864  tbloids->data);
8865 
8866  /*
8867  * In versions 16 and up, we need pg_constraint for explicit NOT NULL
8868  * entries. Also, we need to know if the NOT NULL for each column is
8869  * backing a primary key.
8870  */
8871  if (fout->remoteVersion >= 170000)
8873  " LEFT JOIN pg_catalog.pg_constraint co ON "
8874  "(a.attrelid = co.conrelid\n"
8875  " AND co.contype = 'n' AND "
8876  "co.conkey = array[a.attnum])\n");
8877 
8879  "LEFT JOIN pg_catalog.pg_constraint copk ON "
8880  "(copk.conrelid = src.tbloid\n"
8881  " AND copk.contype = 'p' AND "
8882  "copk.conkey @> array[a.attnum])\n"
8883  "WHERE a.attnum > 0::pg_catalog.int2\n"
8884  "ORDER BY a.attrelid, a.attnum");
8885 
8886  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8887 
8888  ntups = PQntuples(res);
8889 
8890  i_attrelid = PQfnumber(res, "attrelid");
8891  i_attnum = PQfnumber(res, "attnum");
8892  i_attname = PQfnumber(res, "attname");
8893  i_atttypname = PQfnumber(res, "atttypname");
8894  i_attstattarget = PQfnumber(res, "attstattarget");
8895  i_attstorage = PQfnumber(res, "attstorage");
8896  i_typstorage = PQfnumber(res, "typstorage");
8897  i_attidentity = PQfnumber(res, "attidentity");
8898  i_attgenerated = PQfnumber(res, "attgenerated");
8899  i_attisdropped = PQfnumber(res, "attisdropped");
8900  i_attlen = PQfnumber(res, "attlen");
8901  i_attalign = PQfnumber(res, "attalign");
8902  i_attislocal = PQfnumber(res, "attislocal");
8903  i_notnull_name = PQfnumber(res, "notnull_name");
8904  i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
8905  i_notnull_is_pk = PQfnumber(res, "notnull_is_pk");
8906  i_notnull_inh = PQfnumber(res, "notnull_inh");
8907  i_attoptions = PQfnumber(res, "attoptions");
8908  i_attcollation = PQfnumber(res, "attcollation");
8909  i_attcompression = PQfnumber(res, "attcompression");
8910  i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8911  i_attmissingval = PQfnumber(res, "attmissingval");
8912  i_atthasdef = PQfnumber(res, "atthasdef");
8913 
8914  /* Within the next loop, we'll accumulate OIDs of tables with defaults */
8915  resetPQExpBuffer(tbloids);
8916  appendPQExpBufferChar(tbloids, '{');
8917 
8918  /*
8919  * Outer loop iterates once per table, not once per row. Incrementing of
8920  * r is handled by the inner loop.
8921  */
8922  curtblindx = -1;
8923  for (int r = 0; r < ntups;)
8924  {
8925  Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
8926  TableInfo *tbinfo = NULL;
8927  int numatts;
8928  bool hasdefaults;
8929  int notnullcount;
8930 
8931  /* Count rows for this table */
8932  for (numatts = 1; numatts < ntups - r; numatts++)
8933  if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
8934  break;
8935 
8936  /*
8937  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8938  * order.
8939  */
8940  while (++curtblindx < numTables)
8941  {
8942  tbinfo = &tblinfo[curtblindx];
8943  if (tbinfo->dobj.catId.oid == attrelid)
8944  break;
8945  }
8946  if (curtblindx >= numTables)
8947  pg_fatal("unrecognized table OID %u", attrelid);
8948  /* cross-check that we only got requested tables */
8949  if (tbinfo->relkind == RELKIND_SEQUENCE ||
8950  !tbinfo->interesting)
8951  pg_fatal("unexpected column data for table \"%s\"",
8952  tbinfo->dobj.name);
8953 
8954  notnullcount = 0;
8955 
8956  /* Save data for this table */
8957  tbinfo->numatts = numatts;
8958  tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
8959  tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
8960  tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
8961  tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
8962  tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
8963  tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
8964  tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
8965  tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
8966  tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
8967  tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
8968  tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
8969  tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
8970  tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
8971  tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
8972  tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
8973  tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
8974  tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
8975  tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
8976  tbinfo->notnull_throwaway = (bool *) pg_malloc(numatts * sizeof(bool));
8977  tbinfo->notnull_inh = (bool *) pg_malloc(numatts * sizeof(bool));
8978  tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
8979  hasdefaults = false;
8980 
8981  for (int j = 0; j < numatts; j++, r++)
8982  {
8983  bool use_named_notnull = false;
8984  bool use_unnamed_notnull = false;
8985  bool use_throwaway_notnull = false;
8986 
8987  if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
8988  pg_fatal("invalid column numbering in table \"%s\"",
8989  tbinfo->dobj.name);
8990  tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
8991  tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
8992  if (PQgetisnull(res, r, i_attstattarget))
8993  tbinfo->attstattarget[j] = -1;
8994  else
8995  tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
8996  tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
8997  tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
8998  tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
8999  tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
9000  tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
9001  tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
9002  tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
9003  tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
9004  tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
9005 
9006  /*
9007  * Not-null constraints require a jumping through a few hoops.
9008  * First, if the user has specified a constraint name that's not
9009  * the system-assigned default name, then we need to preserve
9010  * that. But if they haven't, then we don't want to use the
9011  * verbose syntax in the dump output. (Also, in versions prior to
9012  * 17, there was no constraint name at all.)
9013  *
9014  * (XXX Comparing the name this way to a supposed default name is
9015  * a bit of a hack, but it beats having to store a boolean flag in
9016  * pg_constraint just for this, or having to compute the knowledge
9017  * at pg_dump time from the server.)
9018  *
9019  * We also need to know if a column is part of the primary key. In
9020  * that case, we want to mark the column as not-null at table
9021  * creation time, so that the table doesn't have to be scanned to
9022  * check for nulls when the PK is created afterwards; this is
9023  * especially critical during pg_upgrade (where the data would not
9024  * be scanned at all otherwise.) If the column is part of the PK
9025  * and does not have any other not-null constraint, then we
9026  * fabricate a throwaway constraint name that we later use to
9027  * remove the constraint after the PK has been created.
9028  *
9029  * For inheritance child tables, we don't want to print not-null
9030  * when the constraint was defined at the parent level instead of
9031  * locally.
9032  */
9033 
9034  /*
9035  * We use notnull_inh to suppress unwanted not-null constraints in
9036  * inheritance children, when said constraints come from the
9037  * parent(s).
9038  */
9039  tbinfo->notnull_inh[j] = PQgetvalue(res, r, i_notnull_inh)[0] == 't';
9040 
9041  if (fout->remoteVersion < 170000)
9042  {
9043  if (!PQgetisnull(res, r, i_notnull_name) &&
9044  dopt->binary_upgrade &&
9045  !tbinfo->ispartition &&
9046  tbinfo->notnull_inh[j])
9047  {
9048  use_named_notnull = true;
9049  /* XXX should match ChooseConstraintName better */
9050  tbinfo->notnull_constrs[j] =
9051  psprintf("%s_%s_not_null", tbinfo->dobj.name,
9052  tbinfo->attnames[j]);
9053  }
9054  else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
9055  use_throwaway_notnull = true;
9056  else if (!PQgetisnull(res, r, i_notnull_name))
9057  use_unnamed_notnull = true;
9058  }
9059  else
9060  {
9061  if (!PQgetisnull(res, r, i_notnull_name))
9062  {
9063  /*
9064  * In binary upgrade of inheritance child tables, must
9065  * have a constraint name that we can UPDATE later.
9066  */
9067  if (dopt->binary_upgrade &&
9068  !tbinfo->ispartition &&
9069  tbinfo->notnull_inh[j])
9070  {
9071  use_named_notnull = true;
9072  tbinfo->notnull_constrs[j] =
9073  pstrdup(PQgetvalue(res, r, i_notnull_name));
9074 
9075  }
9076  else
9077  {
9078  char *default_name;
9079 
9080  /* XXX should match ChooseConstraintName better */
9081  default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
9082  tbinfo->attnames[j]);
9083  if (strcmp(default_name,
9084  PQgetvalue(res, r, i_notnull_name)) == 0)
9085  use_unnamed_notnull = true;
9086  else
9087  {
9088  use_named_notnull = true;
9089  tbinfo->notnull_constrs[j] =
9090  pstrdup(PQgetvalue(res, r, i_notnull_name));
9091  }
9092  }
9093  }
9094  else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
9095  use_throwaway_notnull = true;
9096  }
9097 
9098  if (use_unnamed_notnull)
9099  {
9100  tbinfo->notnull_constrs[j] = "";
9101  tbinfo->notnull_throwaway[j] = false;
9102  }
9103  else if (use_named_notnull)
9104  {
9105  /* The name itself has already been determined */
9106  tbinfo->notnull_throwaway[j] = false;
9107  }
9108  else if (use_throwaway_notnull)
9109  {
9110  /*
9111  * Give this constraint a throwaway name.
9112  */
9113  tbinfo->notnull_constrs[j] =
9114  psprintf("pgdump_throwaway_notnull_%d", notnullcount++);
9115  tbinfo->notnull_throwaway[j] = true;
9116  tbinfo->notnull_inh[j] = false;
9117  }
9118  else
9119  {
9120  tbinfo->notnull_constrs[j] = NULL;
9121  tbinfo->notnull_throwaway[j] = false;
9122  }
9123 
9124  /*
9125  * Throwaway constraints must always be NO INHERIT; otherwise do
9126  * what the catalog says.
9127  */
9128  tbinfo->notnull_noinh[j] = use_throwaway_notnull ||
9129  PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
9130 
9131  tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
9132  tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
9133  tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
9134  tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
9135  tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
9136  tbinfo->attrdefs[j] = NULL; /* fix below */
9137  if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
9138  hasdefaults = true;
9139  }
9140 
9141  if (hasdefaults)
9142  {
9143  /* Collect OIDs of interesting tables that have defaults */
9144  if (tbloids->len > 1) /* do we have more than the '{'? */
9145  appendPQExpBufferChar(tbloids, ',');
9146  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9147  }
9148  }
9149 
9150  PQclear(res);
9151 
9152  /*
9153  * Now get info about column defaults. This is skipped for a data-only
9154  * dump, as it is only needed for table schemas.
9155  */
9156  if (!dopt->dataOnly && tbloids->len > 1)
9157  {
9158  AttrDefInfo *attrdefs;
9159  int numDefaults;
9160  TableInfo *tbinfo = NULL;
9161 
9162  pg_log_info("finding table default expressions");
9163 
9164  appendPQExpBufferChar(tbloids, '}');
9165 
9166  printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9167  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9168  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9169  "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9170  "ORDER BY a.adrelid, a.adnum",
9171  tbloids->data);
9172 
9173  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9174 
9175  numDefaults = PQntuples(res);
9176  attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9177 
9178  curtblindx = -1;
9179  for (int j = 0; j < numDefaults; j++)
9180  {
9181  Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9182  Oid adoid = atooid(PQgetvalue(res, j, 1));
9183  Oid adrelid = atooid(PQgetvalue(res, j, 2));
9184  int adnum = atoi(PQgetvalue(res, j, 3));
9185  char *adsrc = PQgetvalue(res, j, 4);
9186 
9187  /*
9188  * Locate the associated TableInfo; we rely on tblinfo[] being in
9189  * OID order.
9190  */
9191  if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9192  {
9193  while (++curtblindx < numTables)
9194  {
9195  tbinfo = &tblinfo[curtblindx];
9196  if (tbinfo->dobj.catId.oid == adrelid)
9197  break;
9198  }
9199  if (curtblindx >= numTables)
9200  pg_fatal("unrecognized table OID %u", adrelid);
9201  }
9202 
9203  if (adnum <= 0 || adnum > tbinfo->numatts)
9204  pg_fatal("invalid adnum value %d for table \"%s\"",
9205  adnum, tbinfo->dobj.name);
9206 
9207  /*
9208  * dropped columns shouldn't have defaults, but just in case,
9209  * ignore 'em
9210  */
9211  if (tbinfo->attisdropped[adnum - 1])
9212  continue;
9213 
9214  attrdefs[j].dobj.objType = DO_ATTRDEF;
9215  attrdefs[j].dobj.catId.tableoid = adtableoid;
9216  attrdefs[j].dobj.catId.oid = adoid;
9217  AssignDumpId(&attrdefs[j].dobj);
9218  attrdefs[j].adtable = tbinfo;
9219  attrdefs[j].adnum = adnum;
9220  attrdefs[j].adef_expr = pg_strdup(adsrc);
9221 
9222  attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9223  attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9224 
9225  attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9226 
9227  /*
9228  * Figure out whether the default/generation expression should be
9229  * dumped as part of the main CREATE TABLE (or similar) command or
9230  * as a separate ALTER TABLE (or similar) command. The preference
9231  * is to put it into the CREATE command, but in some cases that's
9232  * not possible.
9233  */
9234  if (tbinfo->attgenerated[adnum - 1])
9235  {
9236  /*
9237  * Column generation expressions cannot be dumped separately,
9238  * because there is no syntax for it. By setting separate to
9239  * false here we prevent the "default" from being processed as
9240  * its own dumpable object. Later, flagInhAttrs() will mark
9241  * it as not to be dumped at all, if possible (that is, if it
9242  * can be inherited from a parent).
9243  */
9244  attrdefs[j].separate = false;
9245  }
9246  else if (tbinfo->relkind == RELKIND_VIEW)
9247  {
9248  /*
9249  * Defaults on a VIEW must always be dumped as separate ALTER
9250  * TABLE commands.
9251  */
9252  attrdefs[j].separate = true;
9253  }
9254  else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9255  {
9256  /* column will be suppressed, print default separately */
9257  attrdefs[j].separate = true;
9258  }
9259  else
9260  {
9261  attrdefs[j].separate = false;
9262  }
9263 
9264  if (!attrdefs[j].separate)
9265  {
9266  /*
9267  * Mark the default as needing to appear before the table, so
9268  * that any dependencies it has must be emitted before the
9269  * CREATE TABLE. If this is not possible, we'll change to
9270  * "separate" mode while sorting dependencies.
9271  */
9272  addObjectDependency(&tbinfo->dobj,
9273  attrdefs[j].dobj.dumpId);
9274  }
9275 
9276  tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9277  }
9278 
9279  PQclear(res);
9280  }
9281 
9282  /*
9283  * Get info about table CHECK constraints. This is skipped for a
9284  * data-only dump, as it is only needed for table schemas.
9285  */
9286  if (!dopt->dataOnly && checkoids->len > 2)
9287  {
9288  ConstraintInfo *constrs;
9289  int numConstrs;
9290  int i_tableoid;
9291  int i_oid;
9292  int i_conrelid;
9293  int i_conname;
9294  int i_consrc;
9295  int i_conislocal;
9296  int i_convalidated;
9297 
9298  pg_log_info("finding table check constraints");
9299 
9300  resetPQExpBuffer(q);
9302  "SELECT c.tableoid, c.oid, conrelid, conname, "
9303  "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9304  "conislocal, convalidated "
9305  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9306  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9307  "WHERE contype = 'c' "
9308  "ORDER BY c.conrelid, c.conname",
9309  checkoids->data);
9310 
9311  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9312 
9313  numConstrs = PQntuples(res);
9314  constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9315 
9316  i_tableoid = PQfnumber(res, "tableoid");
9317  i_oid = PQfnumber(res, "oid");
9318  i_conrelid = PQfnumber(res, "conrelid");
9319  i_conname = PQfnumber(res, "conname");
9320  i_consrc = PQfnumber(res, "consrc");
9321  i_conislocal = PQfnumber(res, "conislocal");
9322  i_convalidated = PQfnumber(res, "convalidated");
9323 
9324  /* As above, this loop iterates once per table, not once per row */
9325  curtblindx = -1;
9326  for (int j = 0; j < numConstrs;)
9327  {
9328  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9329  TableInfo *tbinfo = NULL;
9330  int numcons;
9331 
9332  /* Count rows for this table */
9333  for (numcons = 1; numcons < numConstrs - j; numcons++)
9334  if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9335  break;
9336 
9337  /*
9338  * Locate the associated TableInfo; we rely on tblinfo[] being in
9339  * OID order.
9340  */
9341  while (++curtblindx < numTables)
9342  {
9343  tbinfo = &tblinfo[curtblindx];
9344  if (tbinfo->dobj.catId.oid == conrelid)
9345  break;
9346  }
9347  if (curtblindx >= numTables)
9348  pg_fatal("unrecognized table OID %u", conrelid);
9349 
9350  if (numcons != tbinfo->ncheck)
9351  {
9352  pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9353  "expected %d check constraints on table \"%s\" but found %d",
9354  tbinfo->ncheck),
9355  tbinfo->ncheck, tbinfo->dobj.name, numcons);
9356  pg_log_error_hint("The system catalogs might be corrupted.");
9357  exit_nicely(1);
9358  }
9359 
9360  tbinfo->checkexprs = constrs + j;
9361 
9362  for (int c = 0; c < numcons; c++, j++)
9363  {
9364  bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9365 
9366  constrs[j].dobj.objType = DO_CONSTRAINT;
9367  constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9368  constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9369  AssignDumpId(&constrs[j].dobj);
9370  constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9371  constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9372  constrs[j].contable = tbinfo;
9373  constrs[j].condomain = NULL;
9374  constrs[j].contype = 'c';
9375  constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9376  constrs[j].confrelid = InvalidOid;
9377  constrs[j].conindex = 0;
9378  constrs[j].condeferrable = false;
9379  constrs[j].condeferred = false;
9380  constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9381 
9382  /*
9383  * An unvalidated constraint needs to be dumped separately, so
9384  * that potentially-violating existing data is loaded before
9385  * the constraint.
9386  */
9387  constrs[j].separate = !validated;
9388 
9389  constrs[j].dobj.dump = tbinfo->dobj.dump;
9390 
9391  /*
9392  * Mark the constraint as needing to appear before the table
9393  * --- this is so that any other dependencies of the
9394  * constraint will be emitted before we try to create the
9395  * table. If the constraint is to be dumped separately, it
9396  * will be dumped after data is loaded anyway, so don't do it.
9397  * (There's an automatic dependency in the opposite direction
9398  * anyway, so don't need to add one manually here.)
9399  */
9400  if (!constrs[j].separate)
9401  addObjectDependency(&tbinfo->dobj,
9402  constrs[j].dobj.dumpId);
9403 
9404  /*
9405  * We will detect later whether the constraint must be split
9406  * out from the table definition.
9407  */
9408  }
9409  }
9410 
9411  PQclear(res);
9412  }
9413 
9414  destroyPQExpBuffer(q);
9415  destroyPQExpBuffer(tbloids);
9416  destroyPQExpBuffer(checkoids);
9417 }
#define pg_log_error_hint(...)
Definition: logging.h:112

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, _dumpOptions::binary_upgrade, _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(), DO_ATTRDEF, DO_CONSTRAINT, _tableInfo::dobj, _attrDefInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), exit_nicely, i, _tableInfo::interesting, InvalidOid, _tableInfo::ispartition, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull_constrs, _tableInfo::notnull_inh, _tableInfo::notnull_noinh, _tableInfo::notnull_throwaway, _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(), psprintf(), pstrdup(), _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 2748 of file pg_dump.c.

2749 {
2750  int i;
2751 
2752  for (i = 0; i < numTables; i++)
2753  {
2754  if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
2755  (!relkind || tblinfo[i].relkind == relkind))
2756  makeTableDataInfo(dopt, &(tblinfo[i]));
2757  }
2758 }
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2767

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

Referenced by main().

◆ getTableDataFKConstraints()

static void getTableDataFKConstraints ( void  )
static

Definition at line 2956 of file pg_dump.c.

2957 {
2958  DumpableObject **dobjs;
2959  int numObjs;
2960  int i;
2961 
2962  /* Search through all the dumpable objects for FK constraints */
2963  getDumpableObjects(&dobjs, &numObjs);
2964  for (i = 0; i < numObjs; i++)
2965  {
2966  if (dobjs[i]->objType == DO_FK_CONSTRAINT)
2967  {
2968  ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
2969  TableInfo *ftable;
2970 
2971  /* Not interesting unless both tables are to be dumped */
2972  if (cinfo->contable == NULL ||
2973  cinfo->contable->dataObj == NULL)
2974  continue;
2975  ftable = findTableByOid(cinfo->confrelid);
2976  if (ftable == NULL ||
2977  ftable->dataObj == NULL)
2978  continue;
2979 
2980  /*
2981  * Okay, make referencing table's TABLE_DATA object depend on the
2982  * referenced table's TABLE_DATA object.
2983  */
2985  ftable->dataObj->dobj.dumpId);
2986  }
2987  }
2988  free(dobjs);
2989 }
void getDumpableObjects(DumpableObject ***objs, int *numObjs)
Definition: common.c:788

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

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

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()

TransformInfo* getTransforms ( Archive fout,
int *  numTransforms 
)

Definition at line 8592 of file pg_dump.c.

8593 {
8594  PGresult *res;
8595  int ntups;
8596  int i;
8597  PQExpBuffer query;
8598  TransformInfo *transforminfo;
8599  int i_tableoid;
8600  int i_oid;
8601  int i_trftype;
8602  int i_trflang;
8603  int i_trffromsql;
8604  int i_trftosql;
8605 
8606  /* Transforms didn't exist pre-9.5 */
8607  if (fout->remoteVersion < 90500)
8608  {
8609  *numTransforms = 0;
8610  return NULL;
8611  }
8612 
8613  query = createPQExpBuffer();
8614 
8615  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8616  "trftype, trflang, trffromsql::oid, trftosql::oid "
8617  "FROM pg_transform "
8618  "ORDER BY 3,4");
8619 
8620  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8621 
8622  ntups = PQntuples(res);
8623 
8624  *numTransforms = ntups;
8625 
8626  transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8627 
8628  i_tableoid = PQfnumber(res, "tableoid");
8629  i_oid = PQfnumber(res, "oid");
8630  i_trftype = PQfnumber(res, "trftype");
8631  i_trflang = PQfnumber(res, "trflang");
8632  i_trffromsql = PQfnumber(res, "trffromsql");
8633  i_trftosql = PQfnumber(res, "trftosql");
8634 
8635  for (i = 0; i < ntups; i++)
8636  {
8637  PQExpBufferData namebuf;
8638  TypeInfo *typeInfo;
8639  char *lanname;
8640 
8641  transforminfo[i].dobj.objType = DO_TRANSFORM;
8642  transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8643  transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8644  AssignDumpId(&transforminfo[i].dobj);
8645  transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8646  transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8647  transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8648  transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8649 
8650  /*
8651  * Try to name transform as concatenation of type and language name.
8652  * This is only used for purposes of sorting. If we fail to find
8653  * either, the name will be an empty string.
8654  */
8655  initPQExpBuffer(&namebuf);
8656  typeInfo = findTypeByOid(transforminfo[i].trftype);
8657  lanname = get_language_name(fout, transforminfo[i].trflang);
8658  if (typeInfo && lanname)
8659  appendPQExpBuffer(&namebuf, "%s %s",
8660  typeInfo->dobj.name, lanname);
8661  transforminfo[i].dobj.name = namebuf.data;
8662  free(lanname);
8663 
8664  /* Decide whether we want to dump it */
8665  selectDumpableObject(&(transforminfo[i].dobj), fout);
8666  }
8667 
8668  PQclear(res);
8669 
8670  destroyPQExpBuffer(query);
8671 
8672  return transforminfo;
8673 }

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

8104 {
8105  PQExpBuffer query = createPQExpBuffer();
8106  PQExpBuffer tbloids = createPQExpBuffer();
8107  PGresult *res;
8108  int ntups;
8109  int curtblindx;
8110  TriggerInfo *tginfo;
8111  int i_tableoid,
8112  i_oid,
8113  i_tgrelid,
8114  i_tgname,
8115  i_tgenabled,
8116  i_tgispartition,
8117  i_tgdef;
8118 
8119  /*
8120  * We want to perform just one query against pg_trigger. However, we
8121  * mustn't try to select every row of the catalog and then sort it out on
8122  * the client side, because some of the server-side functions we need
8123  * would be unsafe to apply to tables we don't have lock on. Hence, we
8124  * build an array of the OIDs of tables we care about (and now have lock
8125  * on!), and use a WHERE clause to constrain which rows are selected.
8126  */
8127  appendPQExpBufferChar(tbloids, '{');
8128  for (int i = 0; i < numTables; i++)
8129  {
8130  TableInfo *tbinfo = &tblinfo[i];
8131 
8132  if (!tbinfo->hastriggers ||
8133  !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8134  continue;
8135 
8136  /* OK, we need info for this table */
8137  if (tbloids->len > 1) /* do we have more than the '{'? */
8138  appendPQExpBufferChar(tbloids, ',');
8139  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8140  }
8141  appendPQExpBufferChar(tbloids, '}');
8142 
8143  if (fout->remoteVersion >= 150000)
8144  {
8145  /*
8146  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8147  * result in non-forward-compatible dumps of WHEN clauses due to
8148  * under-parenthesization.
8149  *
8150  * NB: We need to see partition triggers in case the tgenabled flag
8151  * has been changed from the parent.
8152  */
8153  appendPQExpBuffer(query,
8154  "SELECT t.tgrelid, t.tgname, "
8155  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8156  "t.tgenabled, t.tableoid, t.oid, "
8157  "t.tgparentid <> 0 AS tgispartition\n"
8158  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8159  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8160  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8161  "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
8162  "OR t.tgenabled != u.tgenabled) "
8163  "ORDER BY t.tgrelid, t.tgname",
8164  tbloids->data);
8165  }
8166  else if (fout->remoteVersion >= 130000)
8167  {
8168  /*
8169  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8170  * result in non-forward-compatible dumps of WHEN clauses due to
8171  * under-parenthesization.
8172  *
8173  * NB: We need to see tgisinternal triggers in partitions, in case the
8174  * tgenabled flag has been changed from the parent.
8175  */
8176  appendPQExpBuffer(query,
8177  "SELECT t.tgrelid, t.tgname, "
8178  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8179  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
8180  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8181  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8182  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8183  "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
8184  "ORDER BY t.tgrelid, t.tgname",
8185  tbloids->data);
8186  }
8187  else if (fout->remoteVersion >= 110000)
8188  {
8189  /*
8190  * NB: We need to see tgisinternal triggers in partitions, in case the
8191  * tgenabled flag has been changed from the parent. No tgparentid in
8192  * version 11-12, so we have to match them via pg_depend.
8193  *
8194  * See above about pretty=true in pg_get_triggerdef.
8195  */
8196  appendPQExpBuffer(query,
8197  "SELECT t.tgrelid, t.tgname, "
8198  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8199  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
8200  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8201  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8202  "LEFT JOIN pg_catalog.pg_depend AS d ON "
8203  " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8204  " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8205  " d.objid = t.oid "
8206  "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8207  "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
8208  "ORDER BY t.tgrelid, t.tgname",
8209  tbloids->data);
8210  }
8211  else
8212  {
8213  /* See above about pretty=true in pg_get_triggerdef */
8214  appendPQExpBuffer(query,
8215  "SELECT t.tgrelid, t.tgname, "
8216  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8217  "t.tgenabled, false as tgispartition, "
8218  "t.tableoid, t.oid "
8219  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8220  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8221  "WHERE NOT tgisinternal "
8222  "ORDER BY t.tgrelid, t.tgname",
8223  tbloids->data);
8224  }
8225 
8226  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8227 
8228  ntups = PQntuples(res);
8229 
8230  i_tableoid = PQfnumber(res, "tableoid");
8231  i_oid = PQfnumber(res, "oid");
8232  i_tgrelid = PQfnumber(res, "tgrelid");
8233  i_tgname = PQfnumber(res, "tgname");
8234  i_tgenabled = PQfnumber(res, "tgenabled");
8235  i_tgispartition = PQfnumber(res, "tgispartition");
8236  i_tgdef = PQfnumber(res, "tgdef");
8237 
8238  tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
8239 
8240  /*
8241  * Outer loop iterates once per table, not once per row. Incrementing of
8242  * j is handled by the inner loop.
8243  */
8244  curtblindx = -1;
8245  for (int j = 0; j < ntups;)
8246  {
8247  Oid tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
8248  TableInfo *tbinfo = NULL;
8249  int numtrigs;
8250 
8251  /* Count rows for this table */
8252  for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
8253  if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
8254  break;
8255 
8256  /*
8257  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8258  * order.
8259  */
8260  while (++curtblindx < numTables)
8261  {
8262  tbinfo = &tblinfo[curtblindx];
8263  if (tbinfo->dobj.catId.oid == tgrelid)
8264  break;
8265  }
8266  if (curtblindx >= numTables)
8267  pg_fatal("unrecognized table OID %u", tgrelid);
8268 
8269  /* Save data for this table */
8270  tbinfo->triggers = tginfo + j;
8271  tbinfo->numTriggers = numtrigs;
8272 
8273  for (int c = 0; c < numtrigs; c++, j++)
8274  {
8275  tginfo[j].dobj.objType = DO_TRIGGER;
8276  tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8277  tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8278  AssignDumpId(&tginfo[j].dobj);
8279  tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
8280  tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8281  tginfo[j].tgtable = tbinfo;
8282  tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8283  tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
8284  tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
8285  }
8286  }
8287 
8288  PQclear(res);
8289 
8290  destroyPQExpBuffer(query);
8291  destroyPQExpBuffer(tbloids);
8292 }
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()

TSConfigInfo* getTSConfigurations ( Archive fout,
int *  numTSConfigs 
)

Definition at line 9672 of file pg_dump.c.

9673 {
9674  PGresult *res;
9675  int ntups;
9676  int i;
9677  PQExpBuffer query;
9678  TSConfigInfo *cfginfo;
9679  int i_tableoid;
9680  int i_oid;
9681  int i_cfgname;
9682  int i_cfgnamespace;
9683  int i_cfgowner;
9684  int i_cfgparser;
9685 
9686  query = createPQExpBuffer();
9687 
9688  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9689  "cfgnamespace, cfgowner, cfgparser "
9690  "FROM pg_ts_config");
9691 
9692  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9693 
9694  ntups = PQntuples(res);
9695  *numTSConfigs = ntups;
9696 
9697  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9698 
9699  i_tableoid = PQfnumber(res, "tableoid");
9700  i_oid = PQfnumber(res, "oid");
9701  i_cfgname = PQfnumber(res, "cfgname");
9702  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9703  i_cfgowner = PQfnumber(res, "cfgowner");
9704  i_cfgparser = PQfnumber(res, "cfgparser");
9705 
9706  for (i = 0; i < ntups; i++)
9707  {
9708  cfginfo[i].dobj.objType = DO_TSCONFIG;
9709  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9710  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9711  AssignDumpId(&cfginfo[i].dobj);
9712  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9713  cfginfo[i].dobj.namespace =
9714  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9715  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9716  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9717 
9718  /* Decide whether we want to dump it */
9719  selectDumpableObject(&(cfginfo[i].dobj), fout);
9720  }
9721 
9722  PQclear(res);
9723 
9724  destroyPQExpBuffer(query);
9725 
9726  return cfginfo;
9727 }

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()

TSDictInfo* getTSDictionaries ( Archive fout,
int *  numTSDicts 
)

Definition at line 9535 of file pg_dump.c.

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

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()

TSParserInfo* getTSParsers ( Archive fout,
int *  numTSParsers 
)

Definition at line 9455 of file pg_dump.c.

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

TSTemplateInfo* getTSTemplates ( Archive fout,
int *  numTSTemplates 
)

Definition at line 9607 of file pg_dump.c.

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

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()

TypeInfo* getTypes ( Archive fout,
int *  numTypes 
)

Definition at line 5767 of file pg_dump.c.

5768 {
5769  PGresult *res;
5770  int ntups;
5771  int i;
5772  PQExpBuffer query = createPQExpBuffer();
5773  TypeInfo *tyinfo;
5774  ShellTypeInfo *stinfo;
5775  int i_tableoid;
5776  int i_oid;
5777  int i_typname;
5778  int i_typnamespace;
5779  int i_typacl;
5780  int i_acldefault;
5781  int i_typowner;
5782  int i_typelem;
5783  int i_typrelid;
5784  int i_typrelkind;
5785  int i_typtype;
5786  int i_typisdefined;
5787  int i_isarray;
5788 
5789  /*
5790  * we include even the built-in types because those may be used as array
5791  * elements by user-defined types
5792  *
5793  * we filter out the built-in types when we dump out the types
5794  *
5795  * same approach for undefined (shell) types and array types
5796  *
5797  * Note: as of 8.3 we can reliably detect whether a type is an
5798  * auto-generated array type by checking the element type's typarray.
5799  * (Before that the test is capable of generating false positives.) We
5800  * still check for name beginning with '_', though, so as to avoid the
5801  * cost of the subselect probe for all standard types. This would have to
5802  * be revisited if the backend ever allows renaming of array types.
5803  */
5804  appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
5805  "typnamespace, typacl, "
5806  "acldefault('T', typowner) AS acldefault, "
5807  "typowner, "
5808  "typelem, typrelid, "
5809  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
5810  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
5811  "typtype, typisdefined, "
5812  "typname[0] = '_' AND typelem != 0 AND "
5813  "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
5814  "FROM pg_type");
5815 
5816  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5817 
5818  ntups = PQntuples(res);
5819 
5820  tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
5821 
5822  i_tableoid = PQfnumber(res, "tableoid");
5823  i_oid = PQfnumber(res, "oid");
5824  i_typname = PQfnumber(res, "typname");
5825  i_typnamespace = PQfnumber(res, "typnamespace");
5826  i_typacl = PQfnumber(res, "typacl");
5827  i_acldefault = PQfnumber(res, "acldefault");
5828  i_typowner = PQfnumber(res, "typowner");
5829  i_typelem = PQfnumber(res, "typelem");
5830  i_typrelid = PQfnumber(res, "typrelid");
5831  i_typrelkind = PQfnumber(res, "typrelkind");
5832  i_typtype = PQfnumber(res, "typtype");
5833  i_typisdefined = PQfnumber(res, "typisdefined");
5834  i_isarray = PQfnumber(res, "isarray");
5835 
5836  for (i = 0; i < ntups; i++)
5837  {
5838  tyinfo[i].dobj.objType = DO_TYPE;
5839  tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5840  tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5841  AssignDumpId(&tyinfo[i].dobj);
5842  tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
5843  tyinfo[i].dobj.namespace =
5844  findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
5845  tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
5846  tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5847  tyinfo[i].dacl.privtype = 0;
5848  tyinfo[i].dacl.initprivs = NULL;
5849  tyinfo[i].ftypname = NULL; /* may get filled later */
5850  tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
5851  tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
5852  tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
5853  tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
5854  tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
5855  tyinfo[i].shellType = NULL;
5856 
5857  if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
5858  tyinfo[i].isDefined = true;
5859  else
5860  tyinfo[i].isDefined = false;
5861 
5862  if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
5863  tyinfo[i].isArray = true;
5864  else
5865  tyinfo[i].isArray = false;
5866 
5867  if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
5868  tyinfo[i].isMultirange = true;
5869  else
5870  tyinfo[i].isMultirange = false;
5871 
5872  /* Decide whether we want to dump it */
5873  selectDumpableType(&tyinfo[i], fout);
5874 
5875  /* Mark whether type has an ACL */
5876  if (!PQgetisnull(res, i, i_typacl))
5877  tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5878 
5879  /*
5880  * If it's a domain, fetch info about its constraints, if any
5881  */
5882  tyinfo[i].nDomChecks = 0;
5883  tyinfo[i].domChecks = NULL;
5884  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
5885  tyinfo[i].typtype == TYPTYPE_DOMAIN)
5886  getDomainConstraints(fout, &(tyinfo[i]));
5887 
5888  /*
5889  * If it's a base type, make a DumpableObject representing a shell
5890  * definition of the type. We will need to dump that ahead of the I/O
5891  * functions for the type. Similarly, range types need a shell
5892  * definition in case they have a canonicalize function.
5893  *
5894  * Note: the shell type doesn't have a catId. You might think it
5895  * should copy the base type's catId, but then it might capture the
5896  * pg_depend entries for the type, which we don't want.
5897  */
5898  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
5899  (tyinfo[i].typtype == TYPTYPE_BASE ||
5900  tyinfo[i].typtype == TYPTYPE_RANGE))
5901  {
5902  stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
5903  stinfo->dobj.objType = DO_SHELL_TYPE;
5904  stinfo->dobj.catId = nilCatalogId;
5905  AssignDumpId(&stinfo->dobj);
5906  stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
5907  stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
5908  stinfo->baseType = &(tyinfo[i]);
5909  tyinfo[i].shellType = stinfo;
5910 
5911  /*
5912  * Initially mark the shell type as not to be dumped. We'll only
5913  * dump it if the I/O or canonicalize functions need to be dumped;
5914  * this is taken care of while sorting dependencies.
5915  */
5916  stinfo->dobj.dump = DUMP_COMPONENT_NONE;
5917  }
5918  }
5919 
5920  *numTypes = ntups;
5921 
5922  PQclear(res);
5923 
5924  destroyPQExpBuffer(query);
5925 
5926  return tyinfo;
5927 }
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:7910
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:1878
bool isMultirange
Definition: pg_dump.h:206
char typrelkind
Definition: pg_dump.h:203
struct _shellTypeInfo * shellType
Definition: pg_dump.h:209
bool isArray
Definition: pg_dump.h:205

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::typelem, _typeInfo::typrelid, _typeInfo::typrelkind, and _typeInfo::typtype.

Referenced by getSchemaData().

◆ help()

static void help ( const char *  progname)
static

Definition at line 1089 of file pg_dump.c.

1090 {
1091  printf(_("%s dumps a database as a text file or to other formats.\n\n"), progname);
1092  printf(_("Usage:\n"));
1093  printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
1094 
1095  printf(_("\nGeneral options:\n"));
1096  printf(_(" -f, --file=FILENAME output file or directory name\n"));
1097  printf(_(" -F, --format=c|d|t|p output file format (custom, directory, tar,\n"
1098  " plain text (default))\n"));
1099  printf(_(" -j, --jobs=NUM use this many parallel jobs to dump\n"));
1100  printf(_(" -v, --verbose verbose mode\n"));
1101  printf(_(" -V, --version output version information, then exit\n"));
1102  printf(_(" -Z, --compress=METHOD[:DETAIL]\n"
1103  " compress as specified\n"));
1104  printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
1105  printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
1106  printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
1107  printf(_(" -?, --help show this help, then exit\n"));
1108 
1109  printf(_("\nOptions controlling the output content:\n"));
1110  printf(_(" -a, --data-only dump only the data, not the schema\n"));
1111  printf(_(" -b, --large-objects include large objects in dump\n"));
1112  printf(_(" --blobs (same as --large-objects, deprecated)\n"));
1113  printf(_(" -B, --no-large-objects exclude large objects in dump\n"));
1114  printf(_(" --no-blobs (same as --no-large-objects, deprecated)\n"));
1115  printf(_(" -c, --clean clean (drop) database objects before recreating\n"));
1116  printf(_(" -C, --create include commands to create database in dump\n"));
1117  printf(_(" -e, --extension=PATTERN dump the specified extension(s) only\n"));
1118  printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
1119  printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n"));
1120  printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
1121  printf(_(" -O, --no-owner skip restoration of object ownership in\n"
1122  " plain-text format\n"));
1123  printf(_(" -s, --schema-only dump only the schema, no data\n"));
1124  printf(_(" -S, --superuser=NAME superuser user name to use in plain-text format\n"));
1125  printf(_(" -t, --table=PATTERN dump only the specified table(s)\n"));
1126  printf(_(" -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n"));
1127  printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
1128  printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
1129  printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
1130  printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
1131  printf(_(" --disable-triggers disable triggers during data-only restore\n"));
1132  printf(_(" --enable-row-security enable row security (dump only content user has\n"
1133  " access to)\n"));
1134  printf(_(" --exclude-extension=PATTERN do NOT dump the specified extension(s)\n"));
1135  printf(_(" --exclude-table-and-children=PATTERN\n"
1136  " do NOT dump the specified table(s), including\n"
1137  " child and partition tables\n"));
1138  printf(_(" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
1139  printf(_(" --exclude-table-data-and-children=PATTERN\n"
1140  " do NOT dump data for the specified table(s),\n"
1141  " including child and partition tables\n"));
1142  printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
1143  printf(_(" --filter=FILENAME include or exclude objects and data from dump\n"
1144  " based on expressions in FILENAME\n"));
1145  printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
1146  printf(_(" --include-foreign-data=PATTERN\n"
1147  " include data of foreign tables on foreign\n"
1148  " servers matching PATTERN\n"));
1149  printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
1150  printf(_(" --load-via-partition-root load partitions via the root table\n"));
1151  printf(_(" --no-comments do not dump comments\n"));
1152  printf(_(" --no-publications do not dump publications\n"));
1153  printf(_(" --no-security-labels do not dump security label assignments\n"));
1154  printf(_(" --no-subscriptions do not dump subscriptions\n"));
1155  printf(_(" --no-table-access-method do not dump table access methods\n"));
1156  printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
1157  printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
1158  printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
1159  printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
1160  printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
1161  printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
1162  printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
1163  printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
1164  printf(_(" --snapshot=SNAPSHOT use given snapshot for the dump\n"));
1165  printf(_(" --strict-names require table and/or schema include patterns to\n"
1166  " match at least one entity each\n"));
1167  printf(_(" --table-and-children=PATTERN dump only the specified table(s), including\n"
1168  " child and partition tables\n"));
1169  printf(_(" --use-set-session-authorization\n"
1170  " use SET SESSION AUTHORIZATION commands instead of\n"
1171  " ALTER OWNER commands to set ownership\n"));
1172 
1173  printf(_("\nConnection options:\n"));
1174  printf(_(" -d, --dbname=DBNAME database to dump\n"));
1175  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
1176  printf(_(" -p, --port=PORT database server port number\n"));
1177  printf(_(" -U, --username=NAME connect as specified database user\n"));
1178  printf(_(" -w, --no-password never prompt for password\n"));
1179  printf(_(" -W, --password force password prompt (should happen automatically)\n"));
1180  printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
1181 
1182  printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
1183  "variable value is used.\n\n"));
1184  printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1185  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1186 }
#define _(x)
Definition: elog.c:90
const char * progname
Definition: main.c:44
#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 4700 of file pg_dump.c.

4701 {
4702  ArchiveHandle *AH = (ArchiveHandle *) fout;
4703  const char *val;
4704 
4705  val = PQparameterStatus(AH->connection, "is_superuser");
4706 
4707  if (val && strcmp(val, "on") == 0)
4708  return true;
4709 
4710  return false;
4711 }
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7112
long val
Definition: informix.c:670

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

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

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 346 of file pg_dump.c.

347 {
348  int c;
349  const char *filename = NULL;
350  const char *format = "p";
351  TableInfo *tblinfo;
352  int numTables;
353  DumpableObject **dobjs;
354  int numObjs;
355  DumpableObject *boundaryObjs;
356  int i;
357  int optindex;
358  RestoreOptions *ropt;
359  Archive *fout; /* the script file */
360  bool g_verbose = false;
361  const char *dumpencoding = NULL;
362  const char *dumpsnapshot = NULL;
363  char *use_role = NULL;
364  int numWorkers = 1;
365  int plainText = 0;
366  ArchiveFormat archiveFormat = archUnknown;
367  ArchiveMode archiveMode;
368  pg_compress_specification compression_spec = {0};
369  char *compression_detail = NULL;
370  char *compression_algorithm_str = "none";
371  char *error_detail = NULL;
372  bool user_compression_defined = false;
374 
375  static DumpOptions dopt;
376 
377  static struct option long_options[] = {
378  {"data-only", no_argument, NULL, 'a'},
379  {"blobs", no_argument, NULL, 'b'},
380  {"large-objects", no_argument, NULL, 'b'},
381  {"no-blobs", no_argument, NULL, 'B'},
382  {"no-large-objects", no_argument, NULL, 'B'},
383  {"clean", no_argument, NULL, 'c'},
384  {"create", no_argument, NULL, 'C'},
385  {"dbname", required_argument, NULL, 'd'},
386  {"extension", required_argument, NULL, 'e'},
387  {"file", required_argument, NULL, 'f'},
388  {"format", required_argument, NULL, 'F'},
389  {"host", required_argument, NULL, 'h'},
390  {"jobs", 1, NULL, 'j'},
391  {"no-reconnect", no_argument, NULL, 'R'},
392  {"no-owner", no_argument, NULL, 'O'},
393  {"port", required_argument, NULL, 'p'},
394  {"schema", required_argument, NULL, 'n'},
395  {"exclude-schema", required_argument, NULL, 'N'},
396  {"schema-only", no_argument, NULL, 's'},
397  {"superuser", required_argument, NULL, 'S'},
398  {"table", required_argument, NULL, 't'},
399  {"exclude-table", required_argument, NULL, 'T'},
400  {"no-password", no_argument, NULL, 'w'},
401  {"password", no_argument, NULL, 'W'},
402  {"username", required_argument, NULL, 'U'},
403  {"verbose", no_argument, NULL, 'v'},
404  {"no-privileges", no_argument, NULL, 'x'},
405  {"no-acl", no_argument, NULL, 'x'},
406  {"compress", required_argument, NULL, 'Z'},
407  {"encoding", required_argument, NULL, 'E'},
408  {"help", no_argument, NULL, '?'},
409  {"version", no_argument, NULL, 'V'},
410 
411  /*
412  * the following options don't have an equivalent short option letter
413  */
414  {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
415  {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
416  {"column-inserts", no_argument, &dopt.column_inserts, 1},
417  {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
418  {"disable-triggers", no_argument, &dopt.disable_triggers, 1},
419  {"enable-row-security", no_argument, &dopt.enable_row_security, 1},
420  {"exclude-table-data", required_argument, NULL, 4},
421  {"extra-float-digits", required_argument, NULL, 8},
422  {"if-exists", no_argument, &dopt.if_exists, 1},
423  {"inserts", no_argument, NULL, 9},
424  {"lock-wait-timeout", required_argument, NULL, 2},
425  {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1},
426  {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
427  {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
428  {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1},
429  {"role", required_argument, NULL, 3},
430  {"section", required_argument, NULL, 5},
431  {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
432  {"snapshot", required_argument, NULL, 6},
433  {"strict-names", no_argument, &strict_names, 1},
434  {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
435  {"no-comments", no_argument, &dopt.no_comments, 1},
436  {"no-publications", no_argument, &dopt.no_publications, 1},
437  {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
438  {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
439  {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
440  {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
441  {"no-sync", no_argument, NULL, 7},
442  {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
443  {"rows-per-insert", required_argument, NULL, 10},
444  {"include-foreign-data", required_argument, NULL, 11},
445  {"table-and-children", required_argument, NULL, 12},
446  {"exclude-table-and-children", required_argument, NULL, 13},
447  {"exclude-table-data-and-children", required_argument, NULL, 14},
448  {"sync-method", required_argument, NULL, 15},
449  {"filter", required_argument, NULL, 16},
450  {"exclude-extension", required_argument, NULL, 17},
451 
452  {NULL, 0, NULL, 0}
453  };
454 
455  pg_logging_init(argv[0]);
457  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
458 
459  /*
460  * Initialize what we need for parallel execution, especially for thread
461  * support on Windows.
462  */
464 
465  progname = get_progname(argv[0]);
466 
467  if (argc > 1)
468  {
469  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
470  {
471  help(progname);
472  exit_nicely(0);
473  }
474  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
475  {
476  puts("pg_dump (PostgreSQL) " PG_VERSION);
477  exit_nicely(0);
478  }
479  }
480 
481  InitDumpOptions(&dopt);
482 
483  while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:",
484  long_options, &optindex)) != -1)
485  {
486  switch (c)
487  {
488  case 'a': /* Dump data only */
489  dopt.dataOnly = true;
490  break;
491 
492  case 'b': /* Dump LOs */
493  dopt.outputLOs = true;
494  break;
495 
496  case 'B': /* Don't dump LOs */
497  dopt.dontOutputLOs = true;
498  break;
499 
500  case 'c': /* clean (i.e., drop) schema prior to create */
501  dopt.outputClean = 1;
502  break;
503 
504  case 'C': /* Create DB */
505  dopt.outputCreateDB = 1;
506  break;
507 
508  case 'd': /* database name */
509  dopt.cparams.dbname = pg_strdup(optarg);
510  break;
511 
512  case 'e': /* include extension(s) */
514  dopt.include_everything = false;
515  break;
516 
517  case 'E': /* Dump encoding */
518  dumpencoding = pg_strdup(optarg);
519  break;
520 
521  case 'f':
523  break;
524 
525  case 'F':
527  break;
528 
529  case 'h': /* server host */
530  dopt.cparams.pghost = pg_strdup(optarg);
531  break;
532 
533  case 'j': /* number of dump jobs */
534  if (!option_parse_int(optarg, "-j/--jobs", 1,
535  PG_MAX_JOBS,
536  &numWorkers))
537  exit_nicely(1);
538  break;
539 
540  case 'n': /* include schema(s) */
542  dopt.include_everything = false;
543  break;
544 
545  case 'N': /* exclude schema(s) */
547  break;
548 
549  case 'O': /* Don't reconnect to match owner */
550  dopt.outputNoOwner = 1;
551  break;
552 
553  case 'p': /* server port */
554  dopt.cparams.pgport = pg_strdup(optarg);
555  break;
556 
557  case 'R':
558  /* no-op, still accepted for backwards compatibility */
559  break;
560 
561  case 's': /* dump schema only */
562  dopt.schemaOnly = true;
563  break;
564 
565  case 'S': /* Username for superuser in plain text output */
567  break;
568 
569  case 't': /* include table(s) */
571  dopt.include_everything = false;
572  break;
573 
574  case 'T': /* exclude table(s) */
576  break;
577 
578  case 'U':
580  break;
581 
582  case 'v': /* verbose */
583  g_verbose = true;
585  break;
586 
587  case 'w':
589  break;
590 
591  case 'W':
593  break;
594 
595  case 'x': /* skip ACL dump */
596  dopt.aclsSkip = true;
597  break;
598 
599  case 'Z': /* Compression */
600  parse_compress_options(optarg, &compression_algorithm_str,
601  &compression_detail);
602  user_compression_defined = true;
603  break;
604 
605  case 0:
606  /* This covers the long options. */
607  break;
608 
609  case 2: /* lock-wait-timeout */
611  break;
612 
613  case 3: /* SET ROLE */
614  use_role = pg_strdup(optarg);
615  break;
616 
617  case 4: /* exclude table(s) data */
619  break;
620 
621  case 5: /* section */
623  break;
624 
625  case 6: /* snapshot */
626  dumpsnapshot = pg_strdup(optarg);
627  break;
628 
629  case 7: /* no-sync */
630  dosync = false;
631  break;
632 
633  case 8:
635  if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
637  exit_nicely(1);
638  break;
639 
640  case 9: /* inserts */
641 
642  /*
643  * dump_inserts also stores --rows-per-insert, careful not to
644  * overwrite that.
645  */
646  if (dopt.dump_inserts == 0)
648  break;
649 
650  case 10: /* rows per insert */
651  if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
652  &dopt.dump_inserts))
653  exit_nicely(1);
654  break;
655 
656  case 11: /* include foreign data */
658  optarg);
659  break;
660 
661  case 12: /* include table(s) and their children */
663  optarg);
664  dopt.include_everything = false;
665  break;
666 
667  case 13: /* exclude table(s) and their children */
669  optarg);
670  break;
671 
672  case 14: /* exclude data of table(s) and children */
674  optarg);
675  break;
676 
677  case 15:
679  exit_nicely(1);
680  break;
681 
682  case 16: /* read object filters from file */
683  read_dump_filters(optarg, &dopt);
684  break;
685 
686  case 17: /* exclude extension(s) */
688  optarg);
689  break;
690 
691  default:
692  /* getopt_long already emitted a complaint */
693  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
694  exit_nicely(1);
695  }
696  }
697 
698  /*
699  * Non-option argument specifies database name as long as it wasn't
700  * already specified with -d / --dbname
701  */
702  if (optind < argc && dopt.cparams.dbname == NULL)
703  dopt.cparams.dbname = argv[optind++];
704 
705  /* Complain if any arguments remain */
706  if (optind < argc)
707  {
708  pg_log_error("too many command-line arguments (first is \"%s\")",
709  argv[optind]);
710  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
711  exit_nicely(1);
712  }
713 
714  /* --column-inserts implies --inserts */
715  if (dopt.column_inserts && dopt.dump_inserts == 0)
717 
718  /*
719  * Binary upgrade mode implies dumping sequence data even in schema-only
720  * mode. This is not exposed as a separate option, but kept separate
721  * internally for clarity.
722  */
723  if (dopt.binary_upgrade)
724  dopt.sequence_data = 1;
725 
726  if (dopt.dataOnly && dopt.schemaOnly)
727  pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
728 
730  pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
731 
732  if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
733  pg_fatal("option --include-foreign-data is not supported with parallel backup");
734 
735  if (dopt.dataOnly && dopt.outputClean)
736  pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
737 
738  if (dopt.if_exists && !dopt.outputClean)
739  pg_fatal("option --if-exists requires option -c/--clean");
740 
741  /*
742  * --inserts are already implied above if --column-inserts or
743  * --rows-per-insert were specified.
744  */
745  if (dopt.do_nothing && dopt.dump_inserts == 0)
746  pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
747 
748  /* Identify archive format to emit */
749  archiveFormat = parseArchiveFormat(format, &archiveMode);
750 
751  /* archiveFormat specific setup */
752  if (archiveFormat == archNull)
753  plainText = 1;
754 
755  /*
756  * Custom and directory formats are compressed by default with gzip when
757  * available, not the others. If gzip is not available, no compression is
758  * done by default.
759  */
760  if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
761  !user_compression_defined)
762  {
763 #ifdef HAVE_LIBZ
764  compression_algorithm_str = "gzip";
765 #else
766  compression_algorithm_str = "none";
767 #endif
768  }
769 
770  /*
771  * Compression options
772  */
773  if (!parse_compress_algorithm(compression_algorithm_str,
775  pg_fatal("unrecognized compression algorithm: \"%s\"",
776  compression_algorithm_str);
777 
779  &compression_spec);
780  error_detail = validate_compress_specification(&compression_spec);
781  if (error_detail != NULL)
782  pg_fatal("invalid compression specification: %s",
783  error_detail);
784 
785  error_detail = supports_compression(compression_spec);
786  if (error_detail != NULL)
787  pg_fatal("%s", error_detail);
788 
789  /*
790  * Disable support for zstd workers for now - these are based on
791  * threading, and it's unclear how it interacts with parallel dumps on
792  * platforms where that relies on threads too (e.g. Windows).
793  */
794  if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
795  pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
796  "workers");
797 
798  /*
799  * If emitting an archive format, we always want to emit a DATABASE item,
800  * in case --create is specified at pg_restore time.
801  */
802  if (!plainText)
803  dopt.outputCreateDB = 1;
804 
805  /* Parallel backup only in the directory archive format so far */
806  if (archiveFormat != archDirectory && numWorkers > 1)
807  pg_fatal("parallel backup only supported by the directory format");
808 
809  /* Open the output file */
810  fout = CreateArchive(filename, archiveFormat, compression_spec,
811  dosync, archiveMode, setupDumpWorker, sync_method);
812 
813  /* Make dump options accessible right away */
814  SetArchiveOptions(fout, &dopt, NULL);
815 
816  /* Register the cleanup hook */
817  on_exit_close_archive(fout);
818 
819  /* Let the archiver know how noisy to be */
820  fout->verbose = g_verbose;
821 
822 
823  /*
824  * We allow the server to be back to 9.2, and up to any minor release of
825  * our own major version. (See also version check in pg_dumpall.c.)
826  */
827  fout->minRemoteVersion = 90200;
828  fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
829 
830  fout->numWorkers = numWorkers;
831 
832  /*
833  * Open the database using the Archiver, so it knows about it. Errors mean
834  * death.
835  */
836  ConnectDatabase(fout, &dopt.cparams, false);
837  setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
838 
839  /*
840  * On hot standbys, never try to dump unlogged table data, since it will
841  * just throw an error.
842  */
843  if (fout->isStandby)
844  dopt.no_unlogged_table_data = true;
845 
846  /*
847  * Find the last built-in OID, if needed (prior to 8.1)
848  *
849  * With 8.1 and above, we can just use FirstNormalObjectId - 1.
850  */
852 
853  pg_log_info("last built-in OID is %u", g_last_builtin_oid);
854 
855  /* Expand schema selection patterns into OID lists */
856  if (schema_include_patterns.head != NULL)
857  {
860  strict_names);
861  if (schema_include_oids.head == NULL)
862  pg_fatal("no matching schemas were found");
863  }
866  false);
867  /* non-matching exclusion patterns aren't an error */
868 
869  /* Expand table selection patterns into OID lists */
872  strict_names, false);
875  strict_names, true);
876  if ((table_include_patterns.head != NULL ||
878  table_include_oids.head == NULL)
879  pg_fatal("no matching tables were found");
880 
883  false, false);
886  false, true);
887 
890  false, false);
893  false, true);
894 
897 
898  /* non-matching exclusion patterns aren't an error */
899 
900  /* Expand extension selection patterns into OID lists */
901  if (extension_include_patterns.head != NULL)
902  {
905  strict_names);
906  if (extension_include_oids.head == NULL)
907  pg_fatal("no matching extensions were found");
908  }
911  false);
912  /* non-matching exclusion patterns aren't an error */
913 
914  /*
915  * Dumping LOs is the default for dumps where an inclusion switch is not
916  * used (an "include everything" dump). -B can be used to exclude LOs
917  * from those dumps. -b can be used to include LOs even when an inclusion
918  * switch is used.
919  *
920  * -s means "schema only" and LOs are data, not schema, so we never
921  * include LOs when -s is used.
922  */
923  if (dopt.include_everything && !dopt.schemaOnly && !dopt.dontOutputLOs)
924  dopt.outputLOs = true;
925 
926  /*
927  * Collect role names so we can map object owner OIDs to names.
928  */
929  collectRoleNames(fout);
930 
931  /*
932  * Now scan the database and create DumpableObject structs for all the
933  * objects we intend to dump.
934  */
935  tblinfo = getSchemaData(fout, &numTables);
936 
937  if (!dopt.schemaOnly)
938  {
939  getTableData(&dopt, tblinfo, numTables, 0);
941  if (dopt.dataOnly)
943  }
944 
945  if (dopt.schemaOnly && dopt.sequence_data)
946  getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
947 
948  /*
949  * In binary-upgrade mode, we do not have to worry about the actual LO
950  * data or the associated metadata that resides in the pg_largeobject and
951  * pg_largeobject_metadata tables, respectively.
952  *
953  * However, we do need to collect LO information as there may be comments
954  * or other information on LOs that we do need to dump out.
955  */
956  if (dopt.outputLOs || dopt.binary_upgrade)
957  getLOs(fout);
958 
959  /*
960  * Collect dependency data to assist in ordering the objects.
961  */
962  getDependencies(fout);
963 
964  /*
965  * Collect ACLs, comments, and security labels, if wanted.
966  */
967  if (!dopt.aclsSkip)
968  getAdditionalACLs(fout);
969  if (!dopt.no_comments)
970  collectComments(fout);
971  if (!dopt.no_security_labels)
972  collectSecLabels(fout);
973 
974  /* Lastly, create dummy objects to represent the section boundaries */
975  boundaryObjs = createBoundaryObjects();
976 
977  /* Get pointers to all the known DumpableObjects */
978  getDumpableObjects(&dobjs, &numObjs);
979 
980  /*
981  * Add dummy dependencies to enforce the dump section ordering.
982  */
983  addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
984 
985  /*
986  * Sort the objects into a safe dump order (no forward references).
987  *
988  * We rely on dependency information to help us determine a safe order, so
989  * the initial sort is mostly for cosmetic purposes: we sort by name to
990  * ensure that logically identical schemas will dump identically.
991  */
992  sortDumpableObjectsByTypeName(dobjs, numObjs);
993 
994  sortDumpableObjects(dobjs, numObjs,
995  boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
996 
997  /*
998  * Create archive TOC entries for all the objects to be dumped, in a safe
999  * order.
1000  */
1001 
1002  /*
1003  * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
1004  */
1005  dumpEncoding(fout);
1006  dumpStdStrings(fout);
1007  dumpSearchPath(fout);
1008 
1009  /* The database items are always next, unless we don't want them at all */
1010  if (dopt.outputCreateDB)
1011  dumpDatabase(fout);
1012 
1013  /* Now the rearrangeable objects. */
1014  for (i = 0; i < numObjs; i++)
1015  dumpDumpableObject(fout, dobjs[i]);
1016 
1017  /*
1018  * Set up options info to ensure we dump what we want.
1019  */
1020  ropt = NewRestoreOptions();
1021  ropt->filename = filename;
1022 
1023  /* if you change this list, see dumpOptionsFromRestoreOptions */
1024  ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
1025  ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
1026  ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
1027  ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
1029  ropt->dropSchema = dopt.outputClean;
1030  ropt->dataOnly = dopt.dataOnly;
1031  ropt->schemaOnly = dopt.schemaOnly;
1032  ropt->if_exists = dopt.if_exists;
1033  ropt->column_inserts = dopt.column_inserts;
1034  ropt->dumpSections = dopt.dumpSections;
1035  ropt->aclsSkip = dopt.aclsSkip;
1036  ropt->superuser = dopt.outputSuperuser;
1037  ropt->createDB = dopt.outputCreateDB;
1038  ropt->noOwner = dopt.outputNoOwner;
1039  ropt->noTableAm = dopt.outputNoTableAm;
1040  ropt->noTablespace = dopt.outputNoTablespaces;
1041  ropt->disable_triggers = dopt.disable_triggers;
1042  ropt->use_setsessauth = dopt.use_setsessauth;
1044  ropt->dump_inserts = dopt.dump_inserts;
1045  ropt->no_comments = dopt.no_comments;
1046  ropt->no_publications = dopt.no_publications;
1048  ropt->no_subscriptions = dopt.no_subscriptions;
1049  ropt->lockWaitTimeout = dopt.lockWaitTimeout;
1052  ropt->sequence_data = dopt.sequence_data;
1053  ropt->binary_upgrade = dopt.binary_upgrade;
1054 
1055  ropt->compression_spec = compression_spec;
1056 
1057  ropt->suppressDumpWarnings = true; /* We've already shown them */
1058 
1059  SetArchiveOptions(fout, &dopt, ropt);
1060 
1061  /* Mark which entries should be output */
1063 
1064  /*
1065  * The archive's TOC entries are now marked as to which ones will actually
1066  * be output, so we can set up their dependency lists properly. This isn't
1067  * necessary for plain-text output, though.
1068  */
1069  if (!plainText)
1071 
1072  /*
1073  * And finally we can do the actual output.
1074  *
1075  * Note: for non-plain-text output formats, the output file is written
1076  * inside CloseArchive(). This is, um, bizarre; but not worth changing
1077  * right now.
1078  */
1079  if (plainText)
1080  RestoreArchive(fout);
1081 
1082  CloseArchive(fout);
1083 
1084  exit_nicely(0);
1085 }
TableInfo * getSchemaData(Archive *fout, int *numTablesPtr)
Definition: common.c:99
void on_exit_close_archive(Archive *AHX)
Definition: parallel.c:328
void init_parallel_dump_utils(void)
Definition: parallel.c:236
#define PG_MAX_JOBS
Definition: parallel.h:48
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1214
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:448
char * supports_compression(const pg_compress_specification compression_spec)
Definition: compress_io.c:88
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:182
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:173
@ 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:110
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:1418
static void dumpEncoding(Archive *AH)
Definition: pg_dump.c:3507
static SimpleStringList schema_include_patterns
Definition: pg_dump.c:118
static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
Definition: pg_dump.c:18698
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3556
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:18674
static void dumpDatabase(Archive *fout)
Definition: pg_dump.c:2997
static SimpleStringList table_include_patterns
Definition: pg_dump.c:123
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:121
static bool have_extra_float_digits
Definition: pg_dump.c:145
static SimpleOidList extension_include_oids
Definition: pg_dump.c:137
static int extra_float_digits
Definition: pg_dump.c:146
static SimpleStringList extension_include_patterns
Definition: pg_dump.c:136
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:140
static SimpleStringList table_exclude_patterns
Definition: pg_dump.c:126
static pg_compress_algorithm compression_algorithm
Definition: pg_dump.c:110
static void dumpStdStrings(Archive *AH)
Definition: pg_dump.c:3532
static void help(const char *progname)
Definition: pg_dump.c:1089
static void BuildArchiveDependencies(Archive *fout)
Definition: pg_dump.c:18814
static void collectRoleNames(Archive *fout)
Definition: pg_dump.c:10057
static bool dosync
Definition: pg_dump.c:103
static void getDependencies(Archive *fout)
Definition: pg_dump.c:18521
static void buildMatViewRefreshDependencies(Archive *fout)
Definition: pg_dump.c:2841
#define DUMP_DEFAULT_ROWS_PER_INSERT
Definition: pg_dump.c:164
static SimpleStringList foreign_servers_include_patterns
Definition: pg_dump.c:133
static void setupDumpWorker(Archive *AH)
Definition: pg_dump.c:1351
static SimpleStringList table_include_patterns_and_children
Definition: pg_dump.c:124
static void getAdditionalACLs(Archive *fout)
Definition: pg_dump.c:10092
static void getTableDataFKConstraints(void)
Definition: pg_dump.c:2956
static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
Definition: pg_dump.c:2748
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:128
static void collectComments(Archive *fout)
Definition: pg_dump.c:10512
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:10597
static void getLOs(Archive *fout)
Definition: pg_dump.c:3618
static void setup_connection(Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role)
Definition: pg_dump.c:1189
static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names, bool with_child_tables)
Definition: pg_dump.c:1582
static void expand_foreign_server_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
Definition: pg_dump.c:1530
static SimpleStringList extension_exclude_patterns
Definition: pg_dump.c:139
static SimpleOidList table_include_oids
Definition: pg_dump.c:125
static SimpleStringList tabledata_exclude_patterns
Definition: pg_dump.c:129
static void collectSecLabels(Archive *fout)
Definition: pg_dump.c:15654
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode)
Definition: pg_dump.c:1380
static void read_dump_filters(const char *filename, DumpOptions *dopt)
Definition: pg_dump.c:19034
static SimpleStringList tabledata_exclude_patterns_and_children
Definition: pg_dump.c:130
static SimpleOidList tabledata_exclude_oids
Definition: pg_dump.c:131
static SimpleStringList table_exclude_patterns_and_children
Definition: pg_dump.c:127
static SimpleOidList foreign_servers_include_oids
Definition: pg_dump.c:134
static void expand_extension_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
Definition: pg_dump.c:1477
static SimpleOidList schema_include_oids
Definition: pg_dump.c:119
static SimpleStringList schema_exclude_patterns
Definition: pg_dump.c:120
void sortDumpableObjects(DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId)
Definition: pg_dump_sort.c:322
void sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
Definition: pg_dump_sort.c:189
static char * filename
Definition: pg_dumpall.c:119
PGDLLIMPORT int optind
Definition: getopt.c:50
PGDLLIMPORT char * optarg
Definition: getopt.c:52
const char * get_progname(const char *argv0)
Definition: path.c:574
bool quote_all_identifiers
Definition: ruleutils.c:323
void simple_string_list_append(SimpleStringList *list, const char *val)
Definition: simple_list.c:63
int minRemoteVersion
Definition: pg_backup.h:222
bool isStandby
Definition: pg_backup.h:220
int maxRemoteVersion
Definition: pg_backup.h:223
int numWorkers
Definition: pg_backup.h:225
int verbose
Definition: pg_backup.h:217
SimpleOidListCell * head
Definition: simple_list.h:28
char * pgport
Definition: pg_backup.h:85
char * pghost
Definition: pg_backup.h:86
trivalue promptPassword
Definition: pg_backup.h:88
char * username
Definition: pg_backup.h:87
char * dbname
Definition: pg_backup.h:84
bool dontOutputLOs
Definition: pg_backup.h:200
int use_setsessauth
Definition: pg_backup.h:190
int outputCreateDB
Definition: pg_backup.h:198
bool include_everything
Definition: pg_backup.h:195
int sequence_data
Definition: pg_backup.h:204
bool outputLOs
Definition: pg_backup.h:199
int serializable_deferrable
Definition: pg_backup.h:186
int outputNoTableAm
Definition: pg_backup.h:188
int enable_row_security
Definition: pg_backup.h:191
char * outputSuperuser
Definition: pg_backup.h:202
int dumpSections
Definition: pg_backup.h:171
int no_unlogged_table_data
Definition: pg_backup.h:185
ConnParams cparams
Definition: pg_backup.h:164
int outputClean
Definition: pg_backup.h:197
int disable_triggers
Definition: pg_backup.h:187
int outputNoOwner
Definition: pg_backup.h:201
int include_everything
Definition: pg_backup.h:124
int suppressDumpWarnings
Definition: pg_backup.h:150
ConnParams cparams
Definition: pg_backup.h:144
pg_compress_specification compression_spec
Definition: pg_backup.h:148
int no_subscriptions
Definition: pg_backup.h:114
int disable_dollar_quoting
Definition: pg_backup.h:107
const char * filename
Definition: pg_backup.h:117
int no_security_labels
Definition: pg_backup.h:113
char * superuser
Definition: pg_backup.h:104
const char * lockWaitTimeout
Definition: pg_backup.h:123
int enable_row_security
Definition: pg_backup.h:157
int disable_triggers
Definition: pg_backup.h:100
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_NO
Definition: vacuumlo.c:37
ArchiveMode
Definition: xlog.h:62

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, addBoundaryDependencies(), archCustom, archDirectory, archNull, archUnknown, _restoreOptions::binary_upgrade, _dumpOptions::binary_upgrade, BuildArchiveDependencies(), buildMatViewRefreshDependencies(), CloseArchive(), collectComments(), collectRoleNames(), collectSecLabels(), _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 2767 of file pg_dump.c.

2768 {
2769  TableDataInfo *tdinfo;
2770 
2771  /*
2772  * Nothing to do if we already decided to dump the table. This will
2773  * happen for "config" tables.
2774  */
2775  if (tbinfo->dataObj != NULL)
2776  return;
2777 
2778  /* Skip VIEWs (no data to dump) */
2779  if (tbinfo->relkind == RELKIND_VIEW)
2780  return;
2781  /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
2782  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
2785  tbinfo->foreign_server)))
2786  return;
2787  /* Skip partitioned tables (data in partitions) */
2788  if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
2789  return;
2790 
2791  /* Don't dump data in unlogged tables, if so requested */
2792  if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
2793  dopt->no_unlogged_table_data)
2794  return;
2795 
2796  /* Check that the data is not explicitly excluded */
2798  tbinfo->dobj.catId.oid))
2799  return;
2800 
2801  /* OK, let's dump it */
2802  tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
2803 
2804  if (tbinfo->relkind == RELKIND_MATVIEW)
2805  tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
2806  else if (tbinfo->relkind == RELKIND_SEQUENCE)
2807  tdinfo->dobj.objType = DO_SEQUENCE_SET;
2808  else
2809  tdinfo->dobj.objType = DO_TABLE_DATA;
2810 
2811  /*
2812  * Note: use tableoid 0 so that this object won't be mistaken for
2813  * something that pg_depend entries apply to.
2814  */
2815  tdinfo->dobj.catId.tableoid = 0;
2816  tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
2817  AssignDumpId(&tdinfo->dobj);
2818  tdinfo->dobj.name = tbinfo->dobj.name;
2819  tdinfo->dobj.namespace = tbinfo->dobj.namespace;
2820  tdinfo->tdtable = tbinfo;
2821  tdinfo->filtercond = NULL; /* might get set later */
2822  addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
2823 
2824  /* A TableDataInfo contains data, of course */
2825  tdinfo->dobj.components |= DUMP_COMPONENT_DATA;
2826 
2827  tbinfo->dataObj = tdinfo;
2828 
2829  /* Make sure that we'll collect per-column info for this table. */
2830  tbinfo->interesting = true;
2831 }
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 19003 of file pg_dump.c.

19004 {
19005  /* Don't want to print it if it's just "{}" */
19006  return (reloptions != NULL && strlen(reloptions) > 2);
19007 }

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

◆ parseArchiveFormat()

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

Definition at line 1380 of file pg_dump.c.

1381 {
1382  ArchiveFormat archiveFormat;
1383 
1384  *mode = archModeWrite;
1385 
1386  if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
1387  {
1388  /* This is used by pg_dumpall, and is not documented */
1389  archiveFormat = archNull;
1390  *mode = archModeAppend;
1391  }
1392  else if (pg_strcasecmp(format, "c") == 0)
1393  archiveFormat = archCustom;
1394  else if (pg_strcasecmp(format, "custom") == 0)
1395  archiveFormat = archCustom;
1396  else if (pg_strcasecmp(format, "d") == 0)
1397  archiveFormat = archDirectory;
1398  else if (pg_strcasecmp(format, "directory") == 0)
1399  archiveFormat = archDirectory;
1400  else if (pg_strcasecmp(format, "p") == 0)
1401  archiveFormat = archNull;
1402  else if (pg_strcasecmp(format, "plain") == 0)
1403  archiveFormat = archNull;
1404  else if (pg_strcasecmp(format, "t") == 0)
1405  archiveFormat = archTar;
1406  else if (pg_strcasecmp(format, "tar") == 0)
1407  archiveFormat = archTar;
1408  else
1409  pg_fatal("invalid output format \"%s\" specified", format);
1410  return archiveFormat;
1411 }
@ 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:56

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

18342 {
18343  DumpOptions *dopt = fout->dopt;
18344  PQExpBuffer query;
18345  PGresult *res;
18346  int ntups,
18347  i;
18348  int i_conrelid,
18349  i_confrelid;
18350 
18351  /* Nothing to do if no extensions */
18352  if (numExtensions == 0)
18353  return;
18354 
18355  /*
18356  * Identify extension configuration tables and create TableDataInfo
18357  * objects for them, ensuring their data will be dumped even though the
18358  * tables themselves won't be.
18359  *
18360  * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
18361  * user data in a configuration table is treated like schema data. This
18362  * seems appropriate since system data in a config table would get
18363  * reloaded by CREATE EXTENSION. If the extension is not listed in the
18364  * list of extensions to be included, none of its data is dumped.
18365  */
18366  for (i = 0; i < numExtensions; i++)
18367  {
18368  ExtensionInfo *curext = &(extinfo[i]);
18369  char *extconfig = curext->extconfig;
18370  char *extcondition = curext->extcondition;
18371  char **extconfigarray = NULL;
18372  char **extconditionarray = NULL;
18373  int nconfigitems = 0;
18374  int nconditionitems = 0;
18375 
18376  /*
18377  * Check if this extension is listed as to include in the dump. If
18378  * not, any table data associated with it is discarded.
18379  */
18380  if (extension_include_oids.head != NULL &&
18382  curext->dobj.catId.oid))
18383  continue;
18384 
18385  /*
18386  * Check if this extension is listed as to exclude in the dump. If
18387  * yes, any table data associated with it is discarded.
18388  */
18389  if (extension_exclude_oids.head != NULL &&
18391  curext->dobj.catId.oid))
18392  continue;
18393 
18394  if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
18395  {
18396  int j;
18397 
18398  if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
18399  pg_fatal("could not parse %s array", "extconfig");
18400  if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
18401  pg_fatal("could not parse %s array", "extcondition");
18402  if (nconfigitems != nconditionitems)
18403  pg_fatal("mismatched number of configurations and conditions for extension");
18404 
18405  for (j = 0; j < nconfigitems; j++)
18406  {
18407  TableInfo *configtbl;
18408  Oid configtbloid = atooid(extconfigarray[j]);
18409  bool dumpobj =
18411 
18412  configtbl = findTableByOid(configtbloid);
18413  if (configtbl == NULL)
18414  continue;
18415 
18416  /*
18417  * Tables of not-to-be-dumped extensions shouldn't be dumped
18418  * unless the table or its schema is explicitly included
18419  */
18420  if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
18421  {
18422  /* check table explicitly requested */
18423  if (table_include_oids.head != NULL &&
18425  configtbloid))
18426  dumpobj = true;
18427 
18428  /* check table's schema explicitly requested */
18429  if (configtbl->dobj.namespace->dobj.dump &
18431  dumpobj = true;
18432  }
18433 
18434  /* check table excluded by an exclusion switch */
18435  if (table_exclude_oids.head != NULL &&
18437  configtbloid))
18438  dumpobj = false;
18439 
18440  /* check schema excluded by an exclusion switch */
18442  configtbl->dobj.namespace->dobj.catId.oid))
18443  dumpobj = false;
18444 
18445  if (dumpobj)
18446  {
18447  makeTableDataInfo(dopt, configtbl);
18448  if (configtbl->dataObj != NULL)
18449  {
18450  if (strlen(extconditionarray[j]) > 0)
18451  configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
18452  }
18453  }
18454  }
18455  }
18456  if (extconfigarray)
18457  free(extconfigarray);
18458  if (extconditionarray)
18459  free(extconditionarray);
18460  }
18461 
18462  /*
18463  * Now that all the TableDataInfo objects have been created for all the
18464  * extensions, check their FK dependencies and register them to try and
18465  * dump the data out in an order that they can be restored in.
18466  *
18467  * Note that this is not a problem for user tables as their FKs are
18468  * recreated after the data has been loaded.
18469  */
18470 
18471  query = createPQExpBuffer();
18472 
18473  printfPQExpBuffer(query,
18474  "SELECT conrelid, confrelid "
18475  "FROM pg_constraint "
18476  "JOIN pg_depend ON (objid = confrelid) "
18477  "WHERE contype = 'f' "
18478  "AND refclassid = 'pg_extension'::regclass "
18479  "AND classid = 'pg_class'::regclass;");
18480 
18481  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18482  ntups = PQntuples(res);
18483 
18484  i_conrelid = PQfnumber(res, "conrelid");
18485  i_confrelid = PQfnumber(res, "confrelid");
18486 
18487  /* Now get the dependencies and register them */
18488  for (i = 0; i < ntups; i++)
18489  {
18490  Oid conrelid,
18491  confrelid;
18492  TableInfo *reftable,
18493  *contable;
18494 
18495  conrelid = atooid(PQgetvalue(res, i, i_conrelid));
18496  confrelid = atooid(PQgetvalue(res, i, i_confrelid));
18497  contable = findTableByOid(conrelid);
18498  reftable = findTableByOid(confrelid);
18499 
18500  if (reftable == NULL ||
18501  reftable->dataObj == NULL ||
18502  contable == NULL ||
18503  contable->dataObj == NULL)
18504  continue;
18505 
18506  /*
18507  * Make referencing TABLE_DATA object depend on the referenced table's
18508  * TABLE_DATA object.
18509  */
18510  addObjectDependency(&contable->dataObj->dobj,
18511  reftable->dataObj->dobj.dumpId);
18512  }
18513  PQclear(res);
18514  destroyPQExpBuffer(query);
18515 }

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

1679 {
1680  const char *db;
1681 
1682  db = PQdb(conn);
1683  if (db == NULL)
1684  pg_fatal("You are currently not connected to a database.");
1685 
1686  if (strcmp(db, dbname) != 0)
1687  pg_fatal("cross-database references are not implemented: %s",
1688  pattern);
1689 }
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6993

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

19035 {
19036  FilterStateData fstate;
19037  char *objname;
19038  FilterCommandType comtype;
19039  FilterObjectType objtype;
19040 
19041  filter_init(&fstate, filename, exit_nicely);
19042 
19043  while (filter_read_item(&fstate, &objname, &comtype, &objtype))
19044  {
19045  if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
19046  {
19047  switch (objtype)
19048  {
19050  break;
19057  pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
19058  "include",
19059  filter_object_type_name(objtype));
19060  exit_nicely(1);
19061  break; /* unreachable */
19062 
19065  break;
19068  break;
19071  dopt->include_everything = false;
19072  break;
19075  dopt->include_everything = false;
19076  break;
19079  objname);
19080  dopt->include_everything = false;
19081  break;
19082  }
19083  }
19084  else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
19085  {
19086  switch (objtype)
19087  {
19089  break;
19095  pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
19096  "exclude",
19097  filter_object_type_name(objtype));
19098  exit_nicely(1);
19099  break;
19100 
19103  break;
19106  objname);
19107  break;
19110  objname);
19111  break;
19114  break;
19117  break;
19120  objname);
19121  break;
19122  }
19123  }
19124  else
19125  {
19126  Assert(comtype == FILTER_COMMAND_TYPE_NONE);
19127  Assert(objtype == FILTER_OBJECT_TYPE_NONE);
19128  }
19129 
19130  if (objname)
19131  free(objname);
19132  }
19133 
19134  filter_free(&fstate);
19135 }
void filter_init(FilterStateData *fstate, const char *filename, exit_function f_exit)
Definition: filter.c:37
void filter_free(FilterStateData *fstate)
Definition: filter.c:61
bool filter_read_item(FilterStateData *fstate, char **objname, FilterCommandType *comtype, FilterObjectType *objtype)
Definition: filter.c:388
void pg_log_filter_error(FilterStateData *fstate, const char *fmt,...)
Definition: filter.c:155
const char * filter_object_type_name(FilterObjectType fot)
Definition: filter.c:83
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 2713 of file pg_dump.c.

2714 {
2715  TableInfo *tbinfo = tdinfo->tdtable;
2716  PQExpBuffer q;
2717 
2718  /* If the materialized view is not flagged as populated, skip this. */
2719  if (!tbinfo->relispopulated)
2720  return;
2721 
2722  q = createPQExpBuffer();
2723 
2724  appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
2725  fmtQualifiedDumpable(tbinfo));
2726 
2727  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2728  ArchiveEntry(fout,
2729  tdinfo->dobj.catId, /* catalog ID */
2730  tdinfo->dobj.dumpId, /* dump ID */
2731  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2732  .namespace = tbinfo->dobj.namespace->dobj.name,
2733  .owner = tbinfo->rolname,
2734  .description = "MATERIALIZED VIEW DATA",
2735  .section = SECTION_POST_DATA,
2736  .createStmt = q->data,
2737  .deps = tdinfo->dobj.dependencies,
2738  .nDeps = tdinfo->dobj.nDeps));
2739 
2740  destroyPQExpBuffer(q);
2741 }

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

2004 {
2005  if (checkExtensionMembership(&method->dobj, fout))
2006  return; /* extension membership overrides all else */
2007 
2008  /*
2009  * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
2010  * they do not support ACLs currently.
2011  */
2012  if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2013  method->dobj.dump = DUMP_COMPONENT_NONE;
2014  else
2015  method->dobj.dump = fout->dopt->include_everything ?
2017 }
static bool checkExtensionMembership(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:1703
#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 1945 of file pg_dump.c.

1946 {
1947  if (checkExtensionMembership(&cast->dobj, fout))
1948  return; /* extension membership overrides all else */
1949 
1950  /*
1951  * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
1952  * support ACLs currently.
1953  */
1954  if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
1955  cast->dobj.dump = DUMP_COMPONENT_NONE;
1956  else
1957  cast->dobj.dump = fout->dopt->include_everything ?
1959 }

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

1924 {
1925  /* Default ACLs can't be extension members */
1926 
1927  if (dinfo->dobj.namespace)
1928  /* default ACLs are considered part of the namespace */
1929  dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
1930  else
1931  dinfo->dobj.dump = dopt->include_everything ?
1933 }

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

2032 {
2033  /*
2034  * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
2035  * change permissions on their member objects, if they wish to, and have
2036  * those changes preserved.
2037  */
2038  if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2039  extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
2040  else
2041  {
2042  /* check if there is a list of extensions to dump */
2043  if (extension_include_oids.head != NULL)
2044  extinfo->dobj.dump = extinfo->dobj.dump_contains =
2046  extinfo->dobj.catId.oid) ?
2048  else
2049  extinfo->dobj.dump = extinfo->dobj.dump_contains =
2050  dopt->include_everything ?
2052 
2053  /* check that the extension is not explicitly excluded */
2054  if (extinfo->dobj.dump &&
2056  extinfo->dobj.catId.oid))
2057  extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
2058  }
2059 }

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

1754 {
1755  /*
1756  * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
1757  * and (for --clean) a DROP SCHEMA statement. (In the absence of
1758  * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
1759  */
1760  nsinfo->create = true;
1761 
1762  /*
1763  * If specific tables are being dumped, do not dump any complete
1764  * namespaces. If specific namespaces are being dumped, dump just those
1765  * namespaces. Otherwise, dump all non-system namespaces.
1766  */
1767  if (table_include_oids.head != NULL)
1768  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1769  else if (schema_include_oids.head != NULL)
1770  nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
1772  nsinfo->dobj.catId.oid) ?
1774  else if (fout->remoteVersion >= 90600 &&
1775  strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
1776  {
1777  /*
1778  * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
1779  * they are interesting (and not the original ACLs which were set at
1780  * initdb time, see pg_init_privs).
1781  */
1782  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
1783  }
1784  else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
1785  strcmp(nsinfo->dobj.name, "information_schema") == 0)
1786  {
1787  /* Other system schemas don't get dumped */
1788  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1789  }
1790  else if (strcmp(nsinfo->dobj.name, "public") == 0)
1791  {
1792  /*
1793  * The public schema is a strange beast that sits in a sort of
1794  * no-mans-land between being a system object and a user object.
1795  * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
1796  * a comment and an indication of ownership. If the owner is the
1797  * default, omit that superfluous DUMP_COMPONENT_DEFINITION. Before
1798  * v15, the default owner was BOOTSTRAP_SUPERUSERID.
1799  */
1800  nsinfo->create = false;
1801  nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
1802  if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
1803  nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
1805 
1806  /*
1807  * Also, make like it has a comment even if it doesn't; this is so
1808  * that we'll emit a command to drop the comment, if appropriate.
1809  * (Without this, we'd not call dumpCommentExtended for it.)
1810  */
1812  }
1813  else
1814  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
1815 
1816  /*
1817  * In any case, a namespace can be excluded by an exclusion switch
1818  */
1819  if (nsinfo->dobj.dump_contains &&
1821  nsinfo->dobj.catId.oid))
1822  nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1823 
1824  /*
1825  * If the schema belongs to an extension, allow extension membership to
1826  * override the dump decision for the schema itself. However, this does
1827  * not change dump_contains, so this won't change what we do with objects
1828  * within the schema. (If they belong to the extension, they'll get
1829  * suppressed by it, otherwise not.)
1830  */
1831  (void) checkExtensionMembership(&nsinfo->dobj, fout);
1832 }

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

2107 {
2108  if (checkExtensionMembership(dobj, fout))
2109  return; /* extension membership overrides all else */
2110 
2111  /*
2112  * Default policy is to dump if parent namespace is dumpable, or for
2113  * non-namespace-associated items, dump if we're dumping "everything".
2114  */
2115  if (dobj->namespace)
2116  dobj->dump = dobj->namespace->dobj.dump_contains;
2117  else
2118  dobj->dump = fout->dopt->include_everything ?
2120 }

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

1971 {
1972  if (checkExtensionMembership(&plang->dobj, fout))
1973  return; /* extension membership overrides all else */
1974 
1975  /*
1976  * Only include procedural languages when we are dumping everything.
1977  *
1978  * For from-initdb procedural languages, only include ACLs, as we do for
1979  * the pg_catalog namespace. We need this because procedural languages do
1980  * not live in any namespace.
1981  */
1982  if (!fout->dopt->include_everything)
1983  plang->dobj.dump = DUMP_COMPONENT_NONE;
1984  else
1985  {
1986  if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
1987  plang->dobj.dump = fout->remoteVersion < 90600 ?
1989  else
1990  plang->dobj.dump = DUMP_COMPONENT_ALL;
1991  }
1992 }

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

2071 {
2072  if (checkExtensionMembership(dobj, fout))
2073  return; /* extension membership overrides all else */
2074 
2075  dobj->dump = fout->dopt->include_everything ?
2077 }

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

2089 {
2090  if (checkExtensionMembership(&sobj->dobj, fout))
2091  return; /* extension membership overrides all else */
2092 
2093  sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
2094  if (sobj->stattable == NULL ||
2096  sobj->dobj.dump = DUMP_COMPONENT_NONE;
2097 }

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

1840 {
1841  if (checkExtensionMembership(&tbinfo->dobj, fout))
1842  return; /* extension membership overrides all else */
1843 
1844  /*
1845  * If specific tables are being dumped, dump just those tables; else, dump
1846  * according to the parent namespace's dump flag.
1847  */
1848  if (table_include_oids.head != NULL)
1850  tbinfo->dobj.catId.oid) ?
1852  else
1853  tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
1854 
1855  /*
1856  * In any case, a table can be excluded by an exclusion switch
1857  */
1858  if (tbinfo->dobj.dump &&
1860  tbinfo->dobj.catId.oid))
1861  tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
1862 }

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

1879 {
1880  /* skip complex types, except for standalone composite types */
1881  if (OidIsValid(tyinfo->typrelid) &&
1882  tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
1883  {
1884  TableInfo *tytable = findTableByOid(tyinfo->typrelid);
1885 
1886  tyinfo->dobj.objType = DO_DUMMY_TYPE;
1887  if (tytable != NULL)
1888  tyinfo->dobj.dump = tytable->dobj.dump;
1889  else
1890  tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
1891  return;
1892  }
1893 
1894  /* skip auto-generated array and multirange types */
1895  if (tyinfo->isArray || tyinfo->isMultirange)
1896  {
1897  tyinfo->dobj.objType = DO_DUMMY_TYPE;
1898 
1899  /*
1900  * Fall through to set the dump flag; we assume that the subsequent
1901  * rules will do the same thing as they would for the array's base
1902  * type or multirange's range type. (We cannot reliably look up the
1903  * base type here, since getTypes may not have processed it yet.)
1904  */
1905  }
1906 
1907  if (checkExtensionMembership(&tyinfo->dobj, fout))
1908  return; /* extension membership overrides all else */
1909 
1910  /* Dump based on if the contents of the namespace are being dumped */
1911  tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
1912 }

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().

◆ setup_connection()

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

Definition at line 1189 of file pg_dump.c.

1191 {
1192  DumpOptions *dopt = AH->dopt;
1193  PGconn *conn = GetConnection(AH);
1194  const char *std_strings;
1195 
1197 
1198  /*
1199  * Set the client encoding if requested.
1200  */
1201  if (dumpencoding)
1202  {
1203  if (PQsetClientEncoding(conn, dumpencoding) < 0)
1204  pg_fatal("invalid client encoding \"%s\" specified",
1205  dumpencoding);
1206  }
1207 
1208  /*
1209  * Get the active encoding and the standard_conforming_strings setting, so
1210  * we know how to escape strings.
1211  */
1213 
1214  std_strings = PQparameterStatus(conn, "standard_conforming_strings");
1215  AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
1216 
1217  /*
1218  * Set the role if requested. In a parallel dump worker, we'll be passed
1219  * use_role == NULL, but AH->use_role is already set (if user specified it
1220  * originally) and we should use that.
1221  */
1222  if (!use_role && AH->use_role)
1223  use_role = AH->use_role;
1224 
1225  /* Set the role if requested */
1226  if (use_role)
1227  {
1228  PQExpBuffer query = createPQExpBuffer();
1229 
1230  appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
1231  ExecuteSqlStatement(AH, query->data);
1232  destroyPQExpBuffer(query);
1233 
1234  /* save it for possible later use by parallel workers */
1235  if (!AH->use_role)
1236  AH->use_role = pg_strdup(use_role);
1237  }
1238 
1239  /* Set the datestyle to ISO to ensure the dump's portability */
1240  ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
1241 
1242  /* Likewise, avoid using sql_standard intervalstyle */
1243  ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
1244 
1245  /*
1246  * Use an explicitly specified extra_float_digits if it has been provided.
1247  * Otherwise, set extra_float_digits so that we can dump float data
1248  * exactly (given correctly implemented float I/O code, anyway).
1249  */
1251  {
1253 
1254  appendPQExpBuffer(q, "SET extra_float_digits TO %d",
1256  ExecuteSqlStatement(AH, q->data);
1257  destroyPQExpBuffer(q);
1258  }
1259  else
1260  ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
1261 
1262  /*
1263  * Disable synchronized scanning, to prevent unpredictable changes in row
1264  * ordering across a dump and reload.
1265  */
1266  ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
1267 
1268  /*
1269  * Disable timeouts if supported.
1270  */
1271  ExecuteSqlStatement(AH, "SET statement_timeout = 0");
1272  if (AH->remoteVersion >= 90300)
1273  ExecuteSqlStatement(AH, "SET lock_timeout = 0");
1274  if (AH->remoteVersion >= 90600)
1275  ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
1276  if (AH->remoteVersion >= 170000)
1277  ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
1278 
1279  /*
1280  * Quote all identifiers, if requested.
1281  */
1283  ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
1284 
1285  /*
1286  * Adjust row-security mode, if supported.
1287  */
1288  if (AH->remoteVersion >= 90500)
1289  {
1290  if (dopt->enable_row_security)
1291  ExecuteSqlStatement(AH, "SET row_security = on");
1292  else
1293  ExecuteSqlStatement(AH, "SET row_security = off");
1294  }
1295 
1296  /*
1297  * Initialize prepared-query state to "nothing prepared". We do this here
1298  * so that a parallel dump worker will have its own state.
1299  */
1300  AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
1301 
1302  /*
1303  * Start transaction-snapshot mode transaction to dump consistent data.
1304  */
1305  ExecuteSqlStatement(AH, "BEGIN");
1306 
1307  /*
1308  * To support the combination of serializable_deferrable with the jobs
1309  * option we use REPEATABLE READ for the worker connections that are
1310  * passed a snapshot. As long as the snapshot is acquired in a
1311  * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
1312  * REPEATABLE READ transaction provides the appropriate integrity
1313  * guarantees. This is a kluge, but safe for back-patching.
1314  */
1315  if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
1317  "SET TRANSACTION ISOLATION LEVEL "
1318  "SERIALIZABLE, READ ONLY, DEFERRABLE");
1319  else
1321  "SET TRANSACTION ISOLATION LEVEL "
1322  "REPEATABLE READ, READ ONLY");
1323 
1324  /*
1325  * If user specified a snapshot to use, select that. In a parallel dump
1326  * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
1327  * is already set (if the server can handle it) and we should use that.
1328  */
1329  if (dumpsnapshot)
1330  AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
1331 
1332  if (AH->sync_snapshot_id)
1333  {
1334  PQExpBuffer query = createPQExpBuffer();
1335 
1336  appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
1338  ExecuteSqlStatement(AH, query->data);
1339  destroyPQExpBuffer(query);
1340  }
1341  else if (AH->numWorkers > 1)
1342  {
1343  if (AH->isStandby && AH->remoteVersion < 100000)
1344  pg_fatal("parallel dumps from standby servers are not supported by this server version");
1346  }
1347 }
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7235
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7243
@ NUM_PREP_QUERIES
Definition: pg_backup.h:77
static char * get_synchronized_snapshot(Archive *fout)
Definition: pg_dump.c:1366
char * use_role
Definition: pg_backup.h:234
char * sync_snapshot_id
Definition: pg_backup.h:226

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

1352 {
1353  /*
1354  * We want to re-select all the same values the leader connection is
1355  * using. We'll have inherited directly-usable values in
1356  * AH->sync_snapshot_id and AH->use_role, but we need to translate the
1357  * inherited encoding value back to a string to pass to setup_connection.
1358  */
1359  setup_connection(AH,
1361  NULL,
1362  NULL);
1363 }

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

9438 {
9439  if (dopt->binary_upgrade)
9440  return true;
9441  if (tbinfo->attisdropped[colno])
9442  return false;
9443  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9444 }

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

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

Variable Documentation

◆ comments

CommentItem* comments = NULL
static

◆ compression_algorithm

pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE
static

Definition at line 110 of file pg_dump.c.

Referenced by main().

◆ dosync

bool dosync = true
static

Definition at line 103 of file pg_dump.c.

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

◆ extension_exclude_oids

SimpleOidList extension_exclude_oids = {NULL, NULL}
static

Definition at line 140 of file pg_dump.c.

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

◆ extension_exclude_patterns

SimpleStringList extension_exclude_patterns = {NULL, NULL}
static

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

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

◆ extension_include_patterns

SimpleStringList extension_include_patterns = {NULL, NULL}
static

Definition at line 136 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ extra_float_digits

int extra_float_digits
static

Definition at line 146 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 134 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 133 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 145 of file pg_dump.c.

Referenced by main(), and setup_connection().

◆ ncomments

int ncomments = 0
static

◆ nilCatalogId

◆ nrolenames

int nrolenames = 0
static

Definition at line 150 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ nseclabels

int nseclabels = 0
static

Definition at line 158 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ rolenames

RoleNameItem* rolenames = NULL
static

Definition at line 149 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ schema_exclude_oids

SimpleOidList schema_exclude_oids = {NULL, NULL}
static

Definition at line 121 of file pg_dump.c.

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

◆ schema_exclude_patterns

SimpleStringList schema_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and selectDumpableNamespace().

◆ schema_include_patterns

SimpleStringList schema_include_patterns = {NULL, NULL}
static

Definition at line 118 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ seclabels

SecLabelItem* seclabels = NULL
static

Definition at line 157 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ strict_names

int strict_names = 0
static

◆ table_exclude_oids

SimpleOidList table_exclude_oids = {NULL, NULL}
static

Definition at line 128 of file pg_dump.c.

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

◆ table_exclude_patterns

SimpleStringList table_exclude_patterns = {NULL, NULL}
static

Definition at line 126 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 127 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 123 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 124 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 131 of file pg_dump.c.

Referenced by main(), and makeTableDataInfo().

◆ tabledata_exclude_patterns

SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and read_dump_filters().