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

Go to the source code of this file.

Data Structures

struct  RoleNameItem
 
struct  CommentItem
 
struct  SecLabelItem
 
struct  BinaryUpgradeClassOidItem
 

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 collectBinaryUpgradeClassOids (Archive *fout)
 
static void binary_upgrade_set_pg_class_oids (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid)
 
static void binary_upgrade_extension_member (PQExpBuffer upgrade_buffer, const DumpableObject *dobj, const char *objtype, const char *objname, const char *objnamespace)
 
static const char * getAttrName (int attrnum, const TableInfo *tblInfo)
 
static const char * fmtCopyColumnList (const TableInfo *ti, PQExpBuffer buffer)
 
static bool nonemptyReloptions (const char *reloptions)
 
static void appendReloptionsArrayAH (PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
 
static char * get_synchronized_snapshot (Archive *fout)
 
static void setupDumpWorker (Archive *AH)
 
static TableInfogetRootTableInfo (const TableInfo *tbinfo)
 
static bool forcePartitionRootLoad (const TableInfo *tbinfo)
 
static void read_dump_filters (const char *filename, DumpOptions *dopt)
 
int main (int argc, char **argv)
 
static bool checkExtensionMembership (DumpableObject *dobj, Archive *fout)
 
static void selectDumpableNamespace (NamespaceInfo *nsinfo, Archive *fout)
 
static void selectDumpableTable (TableInfo *tbinfo, Archive *fout)
 
static void selectDumpableType (TypeInfo *tyinfo, Archive *fout)
 
static void selectDumpableDefaultACL (DefaultACLInfo *dinfo, DumpOptions *dopt)
 
static void selectDumpableCast (CastInfo *cast, Archive *fout)
 
static void selectDumpableProcLang (ProcLangInfo *plang, Archive *fout)
 
static void selectDumpableAccessMethod (AccessMethodInfo *method, Archive *fout)
 
static void selectDumpableExtension (ExtensionInfo *extinfo, DumpOptions *dopt)
 
static void selectDumpablePublicationObject (DumpableObject *dobj, Archive *fout)
 
static void selectDumpableStatisticsObject (StatsExtInfo *sobj, Archive *fout)
 
static void selectDumpableObject (DumpableObject *dobj, Archive *fout)
 
static int dumpTableData_copy (Archive *fout, const void *dcontext)
 
static int dumpTableData_insert (Archive *fout, const void *dcontext)
 
void getPolicies (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getPublications (Archive *fout)
 
void getPublicationNamespaces (Archive *fout)
 
void getPublicationTables (Archive *fout, TableInfo tblinfo[], int numTables)
 
static void dumpPublicationNamespace (Archive *fout, const PublicationSchemaInfo *pubsinfo)
 
static bool is_superuser (Archive *fout)
 
void getSubscriptions (Archive *fout)
 
void getSubscriptionTables (Archive *fout)
 
static void append_depends_on_extension (Archive *fout, PQExpBuffer create, const DumpableObject *dobj, const char *catalog, const char *keyword, const char *objname)
 
static Oid get_next_possible_free_pg_type_oid (Archive *fout, PQExpBuffer upgrade_query)
 
static int BinaryUpgradeClassOidItemCmp (const void *p1, const void *p2)
 
void getNamespaces (Archive *fout)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
void getTypes (Archive *fout)
 
void getOperators (Archive *fout)
 
void getCollations (Archive *fout)
 
void getConversions (Archive *fout)
 
void getAccessMethods (Archive *fout)
 
void getOpclasses (Archive *fout)
 
void getOpfamilies (Archive *fout)
 
void getAggregates (Archive *fout)
 
void getFuncs (Archive *fout)
 
TableInfogetTables (Archive *fout, int *numTables)
 
void getOwnedSeqs (Archive *fout, TableInfo tblinfo[], int numTables)
 
InhInfogetInherits (Archive *fout, int *numInherits)
 
void getPartitioningInfo (Archive *fout)
 
void getIndexes (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getExtendedStatistics (Archive *fout)
 
void getConstraints (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getRules (Archive *fout)
 
void getTriggers (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getEventTriggers (Archive *fout)
 
void getProcLangs (Archive *fout)
 
void getCasts (Archive *fout)
 
static char * get_language_name (Archive *fout, Oid langid)
 
void getTransforms (Archive *fout)
 
void getTableAttrs (Archive *fout, TableInfo *tblinfo, int numTables)
 
bool shouldPrintColumn (const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
 
void getTSParsers (Archive *fout)
 
void getTSDictionaries (Archive *fout)
 
void getTSTemplates (Archive *fout)
 
void getTSConfigurations (Archive *fout)
 
void getForeignDataWrappers (Archive *fout)
 
void getForeignServers (Archive *fout)
 
void getDefaultACLs (Archive *fout)
 
static void dumpTableComment (Archive *fout, const TableInfo *tbinfo, const char *reltypename)
 
static char * format_aggregate_signature (const AggInfo *agginfo, Archive *fout, bool honor_quotes)
 
static void dumpTableSecLabel (Archive *fout, const TableInfo *tbinfo, const char *reltypename)
 
static PQExpBuffer createViewAsClause (Archive *fout, const TableInfo *tbinfo)
 
static PQExpBuffer createDummyViewAsClause (Archive *fout, const TableInfo *tbinfo)
 
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
 
static BinaryUpgradeClassOidItembinaryUpgradeClassOids = NULL
 
static int nbinaryUpgradeClassOids = 0
 

Macro Definition Documentation

◆ DUMP_DEFAULT_ROWS_PER_INSERT

#define DUMP_DEFAULT_ROWS_PER_INSERT   1

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

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

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

108 {
109  zeroIsError = 1,
110  zeroAsStar = 2,
111  zeroAsNone = 4,
112 } OidOptions;
OidOptions
Definition: pg_dump.c:108
@ zeroIsError
Definition: pg_dump.c:109
@ zeroAsStar
Definition: pg_dump.c:110
@ zeroAsNone
Definition: pg_dump.c:111

Function Documentation

◆ addBoundaryDependencies()

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

Definition at line 18342 of file pg_dump.c.

18344 {
18345  DumpableObject *preDataBound = boundaryObjs + 0;
18346  DumpableObject *postDataBound = boundaryObjs + 1;
18347  int i;
18348 
18349  for (i = 0; i < numObjs; i++)
18350  {
18351  DumpableObject *dobj = dobjs[i];
18352 
18353  /*
18354  * The classification of object types here must match the SECTION_xxx
18355  * values assigned during subsequent ArchiveEntry calls!
18356  */
18357  switch (dobj->objType)
18358  {
18359  case DO_NAMESPACE:
18360  case DO_EXTENSION:
18361  case DO_TYPE:
18362  case DO_SHELL_TYPE:
18363  case DO_FUNC:
18364  case DO_AGG:
18365  case DO_OPERATOR:
18366  case DO_ACCESS_METHOD:
18367  case DO_OPCLASS:
18368  case DO_OPFAMILY:
18369  case DO_COLLATION:
18370  case DO_CONVERSION:
18371  case DO_TABLE:
18372  case DO_TABLE_ATTACH:
18373  case DO_ATTRDEF:
18374  case DO_PROCLANG:
18375  case DO_CAST:
18376  case DO_DUMMY_TYPE:
18377  case DO_TSPARSER:
18378  case DO_TSDICT:
18379  case DO_TSTEMPLATE:
18380  case DO_TSCONFIG:
18381  case DO_FDW:
18382  case DO_FOREIGN_SERVER:
18383  case DO_TRANSFORM:
18384  /* Pre-data objects: must come before the pre-data boundary */
18385  addObjectDependency(preDataBound, dobj->dumpId);
18386  break;
18387  case DO_TABLE_DATA:
18388  case DO_SEQUENCE_SET:
18389  case DO_LARGE_OBJECT:
18390  case DO_LARGE_OBJECT_DATA:
18391  /* Data objects: must come between the boundaries */
18392  addObjectDependency(dobj, preDataBound->dumpId);
18393  addObjectDependency(postDataBound, dobj->dumpId);
18394  break;
18395  case DO_INDEX:
18396  case DO_INDEX_ATTACH:
18397  case DO_STATSEXT:
18398  case DO_REFRESH_MATVIEW:
18399  case DO_TRIGGER:
18400  case DO_EVENT_TRIGGER:
18401  case DO_DEFAULT_ACL:
18402  case DO_POLICY:
18403  case DO_PUBLICATION:
18404  case DO_PUBLICATION_REL:
18406  case DO_SUBSCRIPTION:
18407  case DO_SUBSCRIPTION_REL:
18408  /* Post-data objects: must come after the post-data boundary */
18409  addObjectDependency(dobj, postDataBound->dumpId);
18410  break;
18411  case DO_RULE:
18412  /* Rules are post-data, but only if dumped separately */
18413  if (((RuleInfo *) dobj)->separate)
18414  addObjectDependency(dobj, postDataBound->dumpId);
18415  break;
18416  case DO_CONSTRAINT:
18417  case DO_FK_CONSTRAINT:
18418  /* Constraints are post-data, but only if dumped separately */
18419  if (((ConstraintInfo *) dobj)->separate)
18420  addObjectDependency(dobj, postDataBound->dumpId);
18421  break;
18422  case DO_PRE_DATA_BOUNDARY:
18423  /* nothing to do */
18424  break;
18425  case DO_POST_DATA_BOUNDARY:
18426  /* must come after the pre-data boundary */
18427  addObjectDependency(dobj, preDataBound->dumpId);
18428  break;
18429  }
18430  }
18431 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:783
int i
Definition: isn.c:73
@ DO_EVENT_TRIGGER
Definition: pg_dump.h:79
@ DO_REFRESH_MATVIEW
Definition: pg_dump.h:80
@ DO_POLICY
Definition: pg_dump.h:81
@ DO_CAST
Definition: pg_dump.h:63
@ DO_FOREIGN_SERVER
Definition: pg_dump.h:72
@ DO_PRE_DATA_BOUNDARY
Definition: pg_dump.h:77
@ DO_PROCLANG
Definition: pg_dump.h:62
@ DO_TYPE
Definition: pg_dump.h:42
@ DO_INDEX
Definition: pg_dump.h:55
@ DO_COLLATION
Definition: pg_dump.h:50
@ DO_LARGE_OBJECT
Definition: pg_dump.h:75
@ DO_TSCONFIG
Definition: pg_dump.h:70
@ DO_OPERATOR
Definition: pg_dump.h:46
@ DO_FK_CONSTRAINT
Definition: pg_dump.h:61
@ DO_CONSTRAINT
Definition: pg_dump.h:60
@ DO_SUBSCRIPTION
Definition: pg_dump.h:85
@ DO_DEFAULT_ACL
Definition: pg_dump.h:73
@ DO_FDW
Definition: pg_dump.h:71
@ DO_SUBSCRIPTION_REL
Definition: pg_dump.h:86
@ DO_SEQUENCE_SET
Definition: pg_dump.h:65
@ DO_ATTRDEF
Definition: pg_dump.h:54
@ DO_PUBLICATION_REL
Definition: pg_dump.h:83
@ DO_TABLE_ATTACH
Definition: pg_dump.h:53
@ DO_OPCLASS
Definition: pg_dump.h:48
@ DO_INDEX_ATTACH
Definition: pg_dump.h:56
@ DO_TSTEMPLATE
Definition: pg_dump.h:69
@ DO_STATSEXT
Definition: pg_dump.h:57
@ DO_FUNC
Definition: pg_dump.h:44
@ DO_POST_DATA_BOUNDARY
Definition: pg_dump.h:78
@ DO_LARGE_OBJECT_DATA
Definition: pg_dump.h:76
@ DO_OPFAMILY
Definition: pg_dump.h:49
@ DO_TRANSFORM
Definition: pg_dump.h:74
@ DO_ACCESS_METHOD
Definition: pg_dump.h:47
@ DO_PUBLICATION_TABLE_IN_SCHEMA
Definition: pg_dump.h:84
@ DO_CONVERSION
Definition: pg_dump.h:51
@ DO_TRIGGER
Definition: pg_dump.h:59
@ DO_RULE
Definition: pg_dump.h:58
@ DO_DUMMY_TYPE
Definition: pg_dump.h:66
@ DO_TSDICT
Definition: pg_dump.h:68
@ DO_TSPARSER
Definition: pg_dump.h:67
@ DO_EXTENSION
Definition: pg_dump.h:41
@ DO_TABLE_DATA
Definition: pg_dump.h:64
@ DO_PUBLICATION
Definition: pg_dump.h:82
@ DO_TABLE
Definition: pg_dump.h:52
@ DO_NAMESPACE
Definition: pg_dump.h:40
@ DO_AGG
Definition: pg_dump.h:45
@ DO_SHELL_TYPE
Definition: pg_dump.h:43
DumpId dumpId
Definition: pg_dump.h:137
DumpableObjectType objType
Definition: pg_dump.h:135

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

Referenced by main().

◆ addConstrChildIdxDeps()

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

Definition at line 7859 of file pg_dump.c.

7860 {
7861  SimplePtrListCell *cell;
7862 
7863  Assert(dobj->objType == DO_FK_CONSTRAINT);
7864 
7865  for (cell = refidx->partattaches.head; cell; cell = cell->next)
7866  {
7867  IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
7868 
7869  addObjectDependency(dobj, attach->dobj.dumpId);
7870 
7871  if (attach->partitionIdx->partattaches.head != NULL)
7872  addConstrChildIdxDeps(dobj, attach->partitionIdx);
7873  }
7874 }
#define Assert(condition)
Definition: c.h:858
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:7859
struct SimplePtrListCell * next
Definition: simple_list.h:48
SimplePtrListCell * head
Definition: simple_list.h:54
IndxInfo * partitionIdx
Definition: pg_dump.h:416
DumpableObject dobj
Definition: pg_dump.h:414
SimplePtrList partattaches
Definition: pg_dump.h:406

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

5247 {
5248  if (dobj->depends_on_ext)
5249  {
5250  char *nm;
5251  PGresult *res;
5252  PQExpBuffer query;
5253  int ntups;
5254  int i_extname;
5255  int i;
5256 
5257  /* dodge fmtId() non-reentrancy */
5258  nm = pg_strdup(objname);
5259 
5260  query = createPQExpBuffer();
5261  appendPQExpBuffer(query,
5262  "SELECT e.extname "
5263  "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5264  "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5265  "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5266  "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5267  catalog,
5268  dobj->catId.oid);
5269  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5270  ntups = PQntuples(res);
5271  i_extname = PQfnumber(res, "extname");
5272  for (i = 0; i < ntups; i++)
5273  {
5274  appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5275  keyword, nm,
5276  fmtId(PQgetvalue(res, i, i_extname)));
5277  }
5278 
5279  PQclear(res);
5280  destroyPQExpBuffer(query);
5281  pg_free(nm);
5282  }
5283 }
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:102
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 18659 of file pg_dump.c.

18661 {
18662  bool res;
18663 
18664  res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
18665  fout->std_strings);
18666  if (!res)
18667  pg_log_warning("could not parse %s array", "reloptions");
18668 }
#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 5557 of file pg_dump.c.

5562 {
5563  DumpableObject *extobj = NULL;
5564  int i;
5565 
5566  if (!dobj->ext_member)
5567  return;
5568 
5569  /*
5570  * Find the parent extension. We could avoid this search if we wanted to
5571  * add a link field to DumpableObject, but the space costs of that would
5572  * be considerable. We assume that member objects could only have a
5573  * direct dependency on their own extension, not any others.
5574  */
5575  for (i = 0; i < dobj->nDeps; i++)
5576  {
5577  extobj = findObjectByDumpId(dobj->dependencies[i]);
5578  if (extobj && extobj->objType == DO_EXTENSION)
5579  break;
5580  extobj = NULL;
5581  }
5582  if (extobj == NULL)
5583  pg_fatal("could not find parent extension for %s %s",
5584  objtype, objname);
5585 
5586  appendPQExpBufferStr(upgrade_buffer,
5587  "\n-- For binary upgrade, handle extension membership the hard way\n");
5588  appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5589  fmtId(extobj->name),
5590  objtype);
5591  if (objnamespace && *objnamespace)
5592  appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5593  appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5594 }
DumpableObject * findObjectByDumpId(DumpId dumpId)
Definition: common.c:730
#define pg_fatal(...)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
char * name
Definition: pg_dump.h:138
DumpId * dependencies
Definition: pg_dump.h:145
bool ext_member
Definition: pg_dump.h:143

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

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

◆ binary_upgrade_set_pg_class_oids()

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

Definition at line 5467 of file pg_dump.c.

5469 {
5472 
5474 
5475  /*
5476  * Preserve the OID and relfilenumber of the table, table's index, table's
5477  * toast table and toast table's index if any.
5478  *
5479  * One complexity is that the current table definition might not require
5480  * the creation of a TOAST table, but the old database might have a TOAST
5481  * table that was created earlier, before some wide columns were dropped.
5482  * By setting the TOAST oid we force creation of the TOAST heap and index
5483  * by the new backend, so we can copy the files during binary upgrade
5484  * without worrying about this case.
5485  */
5486  key.oid = pg_class_oid;
5488  sizeof(BinaryUpgradeClassOidItem),
5490 
5491  appendPQExpBufferStr(upgrade_buffer,
5492  "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5493 
5494  if (entry->relkind != RELKIND_INDEX &&
5495  entry->relkind != RELKIND_PARTITIONED_INDEX)
5496  {
5497  appendPQExpBuffer(upgrade_buffer,
5498  "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5499  pg_class_oid);
5500 
5501  /*
5502  * Not every relation has storage. Also, in a pre-v12 database,
5503  * partitioned tables have a relfilenumber, which should not be
5504  * preserved when upgrading.
5505  */
5506  if (RelFileNumberIsValid(entry->relfilenumber) &&
5507  entry->relkind != RELKIND_PARTITIONED_TABLE)
5508  appendPQExpBuffer(upgrade_buffer,
5509  "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5510  entry->relfilenumber);
5511 
5512  /*
5513  * In a pre-v12 database, partitioned tables might be marked as having
5514  * toast tables, but we should ignore them if so.
5515  */
5516  if (OidIsValid(entry->toast_oid) &&
5517  entry->relkind != RELKIND_PARTITIONED_TABLE)
5518  {
5519  appendPQExpBuffer(upgrade_buffer,
5520  "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5521  entry->toast_oid);
5522  appendPQExpBuffer(upgrade_buffer,
5523  "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5524  entry->toast_relfilenumber);
5525 
5526  /* every toast table has an index */
5527  appendPQExpBuffer(upgrade_buffer,
5528  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5529  entry->toast_index_oid);
5530  appendPQExpBuffer(upgrade_buffer,
5531  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5532  entry->toast_index_relfilenumber);
5533  }
5534  }
5535  else
5536  {
5537  /* Preserve the OID and relfilenumber of the index */
5538  appendPQExpBuffer(upgrade_buffer,
5539  "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5540  pg_class_oid);
5541  appendPQExpBuffer(upgrade_buffer,
5542  "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5543  entry->relfilenumber);
5544  }
5545 
5546  appendPQExpBufferChar(upgrade_buffer, '\n');
5547 }
#define OidIsValid(objectId)
Definition: c.h:775
static int nbinaryUpgradeClassOids
Definition: pg_dump.c:174
static BinaryUpgradeClassOidItem * binaryUpgradeClassOids
Definition: pg_dump.c:173
static int BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:5417
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
#define RelFileNumberIsValid(relnumber)
Definition: relpath.h:27
RelFileNumber toast_index_relfilenumber
Definition: pg_dump.c:104
RelFileNumber toast_relfilenumber
Definition: pg_dump.c:102
RelFileNumber relfilenumber
Definition: pg_dump.c:100

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

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

◆ binary_upgrade_set_type_oids_by_rel()

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

Definition at line 5402 of file pg_dump.c.

5405 {
5406  Oid pg_type_oid = tbinfo->reltype;
5407 
5408  if (OidIsValid(pg_type_oid))
5409  binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5410  pg_type_oid, false, false);
5411 }
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:5317
unsigned int Oid
Definition: postgres_ext.h:31
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 5317 of file pg_dump.c.

5322 {
5323  PQExpBuffer upgrade_query = createPQExpBuffer();
5324  PGresult *res;
5325  Oid pg_type_array_oid;
5326  Oid pg_type_multirange_oid;
5327  Oid pg_type_multirange_array_oid;
5328 
5329  appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5330  appendPQExpBuffer(upgrade_buffer,
5331  "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5332  pg_type_oid);
5333 
5334  appendPQExpBuffer(upgrade_query,
5335  "SELECT typarray "
5336  "FROM pg_catalog.pg_type "
5337  "WHERE oid = '%u'::pg_catalog.oid;",
5338  pg_type_oid);
5339 
5340  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5341 
5342  pg_type_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5343 
5344  PQclear(res);
5345 
5346  if (!OidIsValid(pg_type_array_oid) && force_array_type)
5347  pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5348 
5349  if (OidIsValid(pg_type_array_oid))
5350  {
5351  appendPQExpBufferStr(upgrade_buffer,
5352  "\n-- For binary upgrade, must preserve pg_type array oid\n");
5353  appendPQExpBuffer(upgrade_buffer,
5354  "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5355  pg_type_array_oid);
5356  }
5357 
5358  /*
5359  * Pre-set the multirange type oid and its own array type oid.
5360  */
5361  if (include_multirange_type)
5362  {
5363  if (fout->remoteVersion >= 140000)
5364  {
5365  printfPQExpBuffer(upgrade_query,
5366  "SELECT t.oid, t.typarray "
5367  "FROM pg_catalog.pg_type t "
5368  "JOIN pg_catalog.pg_range r "
5369  "ON t.oid = r.rngmultitypid "
5370  "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5371  pg_type_oid);
5372 
5373  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5374 
5375  pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5376  pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5377 
5378  PQclear(res);
5379  }
5380  else
5381  {
5382  pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5383  pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5384  }
5385 
5386  appendPQExpBufferStr(upgrade_buffer,
5387  "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5388  appendPQExpBuffer(upgrade_buffer,
5389  "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5390  pg_type_multirange_oid);
5391  appendPQExpBufferStr(upgrade_buffer,
5392  "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5393  appendPQExpBuffer(upgrade_buffer,
5394  "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5395  pg_type_multirange_array_oid);
5396  }
5397 
5398  destroyPQExpBuffer(upgrade_query);
5399 }
PGresult * ExecuteSqlQueryForSingleRow(Archive *fout, const char *query)
Definition: pg_backup_db.c:305
static Oid get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
Definition: pg_dump.c:5286
#define atooid(x)
Definition: postgres_ext.h:42
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
int remoteVersion
Definition: pg_backup.h: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().

◆ BinaryUpgradeClassOidItemCmp()

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

Definition at line 5417 of file pg_dump.c.

5418 {
5421 
5422  return pg_cmp_u32(v1.oid, v2.oid);
5423 }
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:489

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

Referenced by binary_upgrade_set_pg_class_oids().

◆ BuildArchiveDependencies()

static void BuildArchiveDependencies ( Archive fout)
static

Definition at line 18458 of file pg_dump.c.

18459 {
18460  ArchiveHandle *AH = (ArchiveHandle *) fout;
18461  TocEntry *te;
18462 
18463  /* Scan all TOC entries in the archive */
18464  for (te = AH->toc->next; te != AH->toc; te = te->next)
18465  {
18466  DumpableObject *dobj;
18467  DumpId *dependencies;
18468  int nDeps;
18469  int allocDeps;
18470 
18471  /* No need to process entries that will not be dumped */
18472  if (te->reqs == 0)
18473  continue;
18474  /* Ignore entries that already have "special" dependencies */
18475  if (te->nDeps > 0)
18476  continue;
18477  /* Otherwise, look up the item's original DumpableObject, if any */
18478  dobj = findObjectByDumpId(te->dumpId);
18479  if (dobj == NULL)
18480  continue;
18481  /* No work if it has no dependencies */
18482  if (dobj->nDeps <= 0)
18483  continue;
18484  /* Set up work array */
18485  allocDeps = 64;
18486  dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
18487  nDeps = 0;
18488  /* Recursively find all dumpable dependencies */
18489  findDumpableDependencies(AH, dobj,
18490  &dependencies, &nDeps, &allocDeps);
18491  /* And save 'em ... */
18492  if (nDeps > 0)
18493  {
18494  dependencies = (DumpId *) pg_realloc(dependencies,
18495  nDeps * sizeof(DumpId));
18496  te->dependencies = dependencies;
18497  te->nDeps = nDeps;
18498  }
18499  else
18500  free(dependencies);
18501  }
18502 }
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:18506
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 2862 of file pg_dump.c.

2863 {
2864  PQExpBuffer query;
2865  PGresult *res;
2866  int ntups,
2867  i;
2868  int i_classid,
2869  i_objid,
2870  i_refobjid;
2871 
2872  /* No Mat Views before 9.3. */
2873  if (fout->remoteVersion < 90300)
2874  return;
2875 
2876  query = createPQExpBuffer();
2877 
2878  appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
2879  "( "
2880  "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
2881  "FROM pg_depend d1 "
2882  "JOIN pg_class c1 ON c1.oid = d1.objid "
2883  "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
2884  " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
2885  "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
2886  "AND d2.objid = r1.oid "
2887  "AND d2.refobjid <> d1.objid "
2888  "JOIN pg_class c2 ON c2.oid = d2.refobjid "
2889  "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
2890  CppAsString2(RELKIND_VIEW) ") "
2891  "WHERE d1.classid = 'pg_class'::regclass "
2892  "UNION "
2893  "SELECT w.objid, d3.refobjid, c3.relkind "
2894  "FROM w "
2895  "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
2896  "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
2897  "AND d3.objid = r3.oid "
2898  "AND d3.refobjid <> w.refobjid "
2899  "JOIN pg_class c3 ON c3.oid = d3.refobjid "
2900  "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
2901  CppAsString2(RELKIND_VIEW) ") "
2902  ") "
2903  "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
2904  "FROM w "
2905  "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
2906 
2907  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
2908 
2909  ntups = PQntuples(res);
2910 
2911  i_classid = PQfnumber(res, "classid");
2912  i_objid = PQfnumber(res, "objid");
2913  i_refobjid = PQfnumber(res, "refobjid");
2914 
2915  for (i = 0; i < ntups; i++)
2916  {
2917  CatalogId objId;
2918  CatalogId refobjId;
2919  DumpableObject *dobj;
2920  DumpableObject *refdobj;
2921  TableInfo *tbinfo;
2922  TableInfo *reftbinfo;
2923 
2924  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
2925  objId.oid = atooid(PQgetvalue(res, i, i_objid));
2926  refobjId.tableoid = objId.tableoid;
2927  refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
2928 
2929  dobj = findObjectByCatalogId(objId);
2930  if (dobj == NULL)
2931  continue;
2932 
2933  Assert(dobj->objType == DO_TABLE);
2934  tbinfo = (TableInfo *) dobj;
2935  Assert(tbinfo->relkind == RELKIND_MATVIEW);
2936  dobj = (DumpableObject *) tbinfo->dataObj;
2937  if (dobj == NULL)
2938  continue;
2939  Assert(dobj->objType == DO_REFRESH_MATVIEW);
2940 
2941  refdobj = findObjectByCatalogId(refobjId);
2942  if (refdobj == NULL)
2943  continue;
2944 
2945  Assert(refdobj->objType == DO_TABLE);
2946  reftbinfo = (TableInfo *) refdobj;
2947  Assert(reftbinfo->relkind == RELKIND_MATVIEW);
2948  refdobj = (DumpableObject *) reftbinfo->dataObj;
2949  if (refdobj == NULL)
2950  continue;
2951  Assert(refdobj->objType == DO_REFRESH_MATVIEW);
2952 
2953  addObjectDependency(dobj, refdobj->dumpId);
2954 
2955  if (!reftbinfo->relispopulated)
2956  tbinfo->relispopulated = false;
2957  }
2958 
2959  PQclear(res);
2960 
2961  destroyPQExpBuffer(query);
2962 }
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:743
#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:361
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 1724 of file pg_dump.c.

1725 {
1726  ExtensionInfo *ext = findOwningExtension(dobj->catId);
1727 
1728  if (ext == NULL)
1729  return false;
1730 
1731  dobj->ext_member = true;
1732 
1733  /* Record dependency so that getDependencies needn't deal with that */
1734  addObjectDependency(dobj, ext->dobj.dumpId);
1735 
1736  /*
1737  * In 9.6 and above, mark the member object to have any non-initial ACLs
1738  * dumped. (Any initial ACLs will be removed later, using data from
1739  * pg_init_privs, so that we'll dump only the delta from the extension's
1740  * initial setup.)
1741  *
1742  * Prior to 9.6, we do not include any extension member components.
1743  *
1744  * In binary upgrades, we still dump all components of the members
1745  * individually, since the idea is to exactly reproduce the database
1746  * contents rather than replace the extension contents with something
1747  * different.
1748  *
1749  * Note: it might be interesting someday to implement storage and delta
1750  * dumping of extension members' RLS policies and/or security labels.
1751  * However there is a pitfall for RLS policies: trying to dump them
1752  * requires getting a lock on their tables, and the calling user might not
1753  * have privileges for that. We need no lock to examine a table's ACLs,
1754  * so the current feature doesn't have a problem of that sort.
1755  */
1756  if (fout->dopt->binary_upgrade)
1757  dobj->dump = ext->dobj.dump;
1758  else
1759  {
1760  if (fout->remoteVersion < 90600)
1761  dobj->dump = DUMP_COMPONENT_NONE;
1762  else
1763  dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
1764  }
1765 
1766  return true;
1767 }
ExtensionInfo * findOwningExtension(CatalogId catalogId)
Definition: common.c:1034
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:101
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:96
DumpOptions * dopt
Definition: pg_backup.h: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().

◆ collectBinaryUpgradeClassOids()

static void collectBinaryUpgradeClassOids ( Archive fout)
static

Definition at line 5433 of file pg_dump.c.

5434 {
5435  PGresult *res;
5436  const char *query;
5437 
5438  query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5439  "ct.relfilenode, i.indexrelid, cti.relfilenode "
5440  "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5441  "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5442  "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5443  "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5444  "ORDER BY c.oid;";
5445 
5446  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5447 
5451 
5452  for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5453  {
5461  }
5462 
5463  PQclear(res);
5464 }

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

Referenced by main().

◆ collectComments()

static void collectComments ( Archive fout)
static

Definition at line 10211 of file pg_dump.c.

10212 {
10213  PGresult *res;
10214  PQExpBuffer query;
10215  int i_description;
10216  int i_classoid;
10217  int i_objoid;
10218  int i_objsubid;
10219  int ntups;
10220  int i;
10221  DumpableObject *dobj;
10222 
10223  query = createPQExpBuffer();
10224 
10225  appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
10226  "FROM pg_catalog.pg_description "
10227  "ORDER BY classoid, objoid, objsubid");
10228 
10229  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10230 
10231  /* Construct lookup table containing OIDs in numeric form */
10232 
10233  i_description = PQfnumber(res, "description");
10234  i_classoid = PQfnumber(res, "classoid");
10235  i_objoid = PQfnumber(res, "objoid");
10236  i_objsubid = PQfnumber(res, "objsubid");
10237 
10238  ntups = PQntuples(res);
10239 
10240  comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
10241  ncomments = 0;
10242  dobj = NULL;
10243 
10244  for (i = 0; i < ntups; i++)
10245  {
10246  CatalogId objId;
10247  int subid;
10248 
10249  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
10250  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
10251  subid = atoi(PQgetvalue(res, i, i_objsubid));
10252 
10253  /* We needn't remember comments that don't match any dumpable object */
10254  if (dobj == NULL ||
10255  dobj->catId.tableoid != objId.tableoid ||
10256  dobj->catId.oid != objId.oid)
10257  dobj = findObjectByCatalogId(objId);
10258  if (dobj == NULL)
10259  continue;
10260 
10261  /*
10262  * Comments on columns of composite types are linked to the type's
10263  * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
10264  * in the type's own DumpableObject.
10265  */
10266  if (subid != 0 && dobj->objType == DO_TABLE &&
10267  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
10268  {
10269  TypeInfo *cTypeInfo;
10270 
10271  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
10272  if (cTypeInfo)
10273  cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
10274  }
10275  else
10276  dobj->components |= DUMP_COMPONENT_COMMENT;
10277 
10278  comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
10280  comments[ncomments].objoid = objId.oid;
10281  comments[ncomments].objsubid = subid;
10282  ncomments++;
10283  }
10284 
10285  PQclear(res);
10286  destroyPQExpBuffer(query);
10287 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:864
static int ncomments
Definition: pg_dump.c:166
static CommentItem * comments
Definition: pg_dump.c:165
#define DUMP_COMPONENT_COMMENT
Definition: pg_dump.h:99
Oid classoid
Definition: pg_dump.c:82
Oid objoid
Definition: pg_dump.c:83
int objsubid
Definition: pg_dump.c:84
const char * descr
Definition: pg_dump.c:81
DumpComponents components
Definition: pg_dump.h:142
DumpableObject dobj
Definition: pg_dump.h:191

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

Referenced by main().

◆ collectRoleNames()

static void collectRoleNames ( Archive fout)
static

Definition at line 9756 of file pg_dump.c.

9757 {
9758  PGresult *res;
9759  const char *query;
9760  int i;
9761 
9762  query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
9763 
9764  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
9765 
9767 
9769 
9770  for (i = 0; i < nrolenames; i++)
9771  {
9774  }
9775 
9776  PQclear(res);
9777 }
static RoleNameItem * rolenames
Definition: pg_dump.c:161
static int nrolenames
Definition: pg_dump.c:162
const char * rolename
Definition: pg_dump.c:76
Oid roleoid
Definition: pg_dump.c:75

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

Referenced by main().

◆ collectSecLabels()

static void collectSecLabels ( Archive fout)
static

Definition at line 15353 of file pg_dump.c.

15354 {
15355  PGresult *res;
15356  PQExpBuffer query;
15357  int i_label;
15358  int i_provider;
15359  int i_classoid;
15360  int i_objoid;
15361  int i_objsubid;
15362  int ntups;
15363  int i;
15364  DumpableObject *dobj;
15365 
15366  query = createPQExpBuffer();
15367 
15368  appendPQExpBufferStr(query,
15369  "SELECT label, provider, classoid, objoid, objsubid "
15370  "FROM pg_catalog.pg_seclabel "
15371  "ORDER BY classoid, objoid, objsubid");
15372 
15373  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15374 
15375  /* Construct lookup table containing OIDs in numeric form */
15376  i_label = PQfnumber(res, "label");
15377  i_provider = PQfnumber(res, "provider");
15378  i_classoid = PQfnumber(res, "classoid");
15379  i_objoid = PQfnumber(res, "objoid");
15380  i_objsubid = PQfnumber(res, "objsubid");
15381 
15382  ntups = PQntuples(res);
15383 
15384  seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
15385  nseclabels = 0;
15386  dobj = NULL;
15387 
15388  for (i = 0; i < ntups; i++)
15389  {
15390  CatalogId objId;
15391  int subid;
15392 
15393  objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
15394  objId.oid = atooid(PQgetvalue(res, i, i_objoid));
15395  subid = atoi(PQgetvalue(res, i, i_objsubid));
15396 
15397  /* We needn't remember labels that don't match any dumpable object */
15398  if (dobj == NULL ||
15399  dobj->catId.tableoid != objId.tableoid ||
15400  dobj->catId.oid != objId.oid)
15401  dobj = findObjectByCatalogId(objId);
15402  if (dobj == NULL)
15403  continue;
15404 
15405  /*
15406  * Labels on columns of composite types are linked to the type's
15407  * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
15408  * in the type's own DumpableObject.
15409  */
15410  if (subid != 0 && dobj->objType == DO_TABLE &&
15411  ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
15412  {
15413  TypeInfo *cTypeInfo;
15414 
15415  cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
15416  if (cTypeInfo)
15417  cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
15418  }
15419  else
15420  dobj->components |= DUMP_COMPONENT_SECLABEL;
15421 
15425  seclabels[nseclabels].objoid = objId.oid;
15426  seclabels[nseclabels].objsubid = subid;
15427  nseclabels++;
15428  }
15429 
15430  PQclear(res);
15431  destroyPQExpBuffer(query);
15432 }
static int nseclabels
Definition: pg_dump.c:170
static SecLabelItem * seclabels
Definition: pg_dump.c:169
#define DUMP_COMPONENT_SECLABEL
Definition: pg_dump.h:100
const char * provider
Definition: pg_dump.c:89
Oid classoid
Definition: pg_dump.c:91
int objsubid
Definition: pg_dump.c:93
const char * label
Definition: pg_dump.c:90
Oid objoid
Definition: pg_dump.c:92

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

Referenced by main().

◆ convertRegProcReference()

static char * convertRegProcReference ( const char *  proc)
static

Definition at line 12903 of file pg_dump.c.

12904 {
12905  char *name;
12906  char *paren;
12907  bool inquote;
12908 
12909  /* In all cases "-" means a null reference */
12910  if (strcmp(proc, "-") == 0)
12911  return NULL;
12912 
12913  name = pg_strdup(proc);
12914  /* find non-double-quoted left paren */
12915  inquote = false;
12916  for (paren = name; *paren; paren++)
12917  {
12918  if (*paren == '(' && !inquote)
12919  {
12920  *paren = '\0';
12921  break;
12922  }
12923  if (*paren == '"')
12924  inquote = !inquote;
12925  }
12926  return name;
12927 }
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 12974 of file pg_dump.c.

12975 {
12976  char *result;
12977  char query[128];
12978  PGresult *res;
12979 
12980  snprintf(query, sizeof(query),
12981  "SELECT '%u'::pg_catalog.regproc", funcOid);
12982  res = ExecuteSqlQueryForSingleRow(fout, query);
12983 
12984  result = pg_strdup(PQgetvalue(res, 0, 0));
12985 
12986  PQclear(res);
12987 
12988  return result;
12989 }
#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 18318 of file pg_dump.c.

18319 {
18320  DumpableObject *dobjs;
18321 
18322  dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
18323 
18324  dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
18325  dobjs[0].catId = nilCatalogId;
18326  AssignDumpId(dobjs + 0);
18327  dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
18328 
18329  dobjs[1].objType = DO_POST_DATA_BOUNDARY;
18330  dobjs[1].catId = nilCatalogId;
18331  AssignDumpId(dobjs + 1);
18332  dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
18333 
18334  return dobjs;
18335 }
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:622
static const CatalogId nilCatalogId
Definition: pg_dump.c:154

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

15629 {
15630  PQExpBuffer result = createPQExpBuffer();
15631  int j;
15632 
15633  appendPQExpBufferStr(result, "SELECT");
15634 
15635  for (j = 0; j < tbinfo->numatts; j++)
15636  {
15637  if (j > 0)
15638  appendPQExpBufferChar(result, ',');
15639  appendPQExpBufferStr(result, "\n ");
15640 
15641  appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
15642 
15643  /*
15644  * Must add collation if not default for the type, because CREATE OR
15645  * REPLACE VIEW won't change it
15646  */
15647  if (OidIsValid(tbinfo->attcollation[j]))
15648  {
15649  CollInfo *coll;
15650 
15651  coll = findCollationByOid(tbinfo->attcollation[j]);
15652  if (coll)
15653  appendPQExpBuffer(result, " COLLATE %s",
15654  fmtQualifiedDumpable(coll));
15655  }
15656 
15657  appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
15658  }
15659 
15660  return result;
15661 }
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:919
int j
Definition: isn.c:74
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:192
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 15579 of file pg_dump.c.

15580 {
15581  PQExpBuffer query = createPQExpBuffer();
15582  PQExpBuffer result = createPQExpBuffer();
15583  PGresult *res;
15584  int len;
15585 
15586  /* Fetch the view definition */
15587  appendPQExpBuffer(query,
15588  "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
15589  tbinfo->dobj.catId.oid);
15590 
15591  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15592 
15593  if (PQntuples(res) != 1)
15594  {
15595  if (PQntuples(res) < 1)
15596  pg_fatal("query to obtain definition of view \"%s\" returned no data",
15597  tbinfo->dobj.name);
15598  else
15599  pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
15600  tbinfo->dobj.name);
15601  }
15602 
15603  len = PQgetlength(res, 0, 0);
15604 
15605  if (len == 0)
15606  pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
15607  tbinfo->dobj.name);
15608 
15609  /* Strip off the trailing semicolon so that other things may follow. */
15610  Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
15611  appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
15612 
15613  PQclear(res);
15614  destroyPQExpBuffer(query);
15615 
15616  return result;
15617 }
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 12996 of file pg_dump.c.

12997 {
12998  DumpOptions *dopt = fout->dopt;
12999  PQExpBuffer q;
13000  PQExpBuffer delq;
13001  char *qamname;
13002 
13003  /* Do nothing in data-only dump */
13004  if (dopt->dataOnly)
13005  return;
13006 
13007  q = createPQExpBuffer();
13008  delq = createPQExpBuffer();
13009 
13010  qamname = pg_strdup(fmtId(aminfo->dobj.name));
13011 
13012  appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
13013 
13014  switch (aminfo->amtype)
13015  {
13016  case AMTYPE_INDEX:
13017  appendPQExpBufferStr(q, "TYPE INDEX ");
13018  break;
13019  case AMTYPE_TABLE:
13020  appendPQExpBufferStr(q, "TYPE TABLE ");
13021  break;
13022  default:
13023  pg_log_warning("invalid type \"%c\" of access method \"%s\"",
13024  aminfo->amtype, qamname);
13025  destroyPQExpBuffer(q);
13026  destroyPQExpBuffer(delq);
13027  free(qamname);
13028  return;
13029  }
13030 
13031  appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
13032 
13033  appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
13034  qamname);
13035 
13036  if (dopt->binary_upgrade)
13038  "ACCESS METHOD", qamname, NULL);
13039 
13040  if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13041  ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
13042  ARCHIVE_OPTS(.tag = aminfo->dobj.name,
13043  .description = "ACCESS METHOD",
13044  .section = SECTION_PRE_DATA,
13045  .createStmt = q->data,
13046  .dropStmt = delq->data));
13047 
13048  /* Dump Access Method Comments */
13049  if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13050  dumpComment(fout, "ACCESS METHOD", qamname,
13051  NULL, "",
13052  aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
13053 
13054  destroyPQExpBuffer(q);
13055  destroyPQExpBuffer(delq);
13056  free(qamname);
13057 }
@ 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:10020
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:5557
#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 14984 of file pg_dump.c.

14988 {
14989  DumpId aclDumpId = InvalidDumpId;
14990  DumpOptions *dopt = fout->dopt;
14991  const char *acls = dacl->acl;
14992  const char *acldefault = dacl->acldefault;
14993  char privtype = dacl->privtype;
14994  const char *initprivs = dacl->initprivs;
14995  const char *baseacls;
14996  PQExpBuffer sql;
14997 
14998  /* Do nothing if ACL dump is not enabled */
14999  if (dopt->aclsSkip)
15000  return InvalidDumpId;
15001 
15002  /* --data-only skips ACLs *except* large object ACLs */
15003  if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15004  return InvalidDumpId;
15005 
15006  sql = createPQExpBuffer();
15007 
15008  /*
15009  * In binary upgrade mode, we don't run an extension's script but instead
15010  * dump out the objects independently and then recreate them. To preserve
15011  * any initial privileges which were set on extension objects, we need to
15012  * compute the set of GRANT and REVOKE commands necessary to get from the
15013  * default privileges of an object to its initial privileges as recorded
15014  * in pg_init_privs.
15015  *
15016  * At restore time, we apply these commands after having called
15017  * binary_upgrade_set_record_init_privs(true). That tells the backend to
15018  * copy the results into pg_init_privs. This is how we preserve the
15019  * contents of that catalog across binary upgrades.
15020  */
15021  if (dopt->binary_upgrade && privtype == 'e' &&
15022  initprivs && *initprivs != '\0')
15023  {
15024  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
15025  if (!buildACLCommands(name, subname, nspname, type,
15026  initprivs, acldefault, owner,
15027  "", fout->remoteVersion, sql))
15028  pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
15029  initprivs, acldefault, name, type);
15030  appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
15031  }
15032 
15033  /*
15034  * Now figure the GRANT and REVOKE commands needed to get to the object's
15035  * actual current ACL, starting from the initprivs if given, else from the
15036  * object-type-specific default. Also, while buildACLCommands will assume
15037  * that a NULL/empty acls string means it needn't do anything, what that
15038  * actually represents is the object-type-specific default; so we need to
15039  * substitute the acldefault string to get the right results in that case.
15040  */
15041  if (initprivs && *initprivs != '\0')
15042  {
15043  baseacls = initprivs;
15044  if (acls == NULL || *acls == '\0')
15045  acls = acldefault;
15046  }
15047  else
15048  baseacls = acldefault;
15049 
15050  if (!buildACLCommands(name, subname, nspname, type,
15051  acls, baseacls, owner,
15052  "", fout->remoteVersion, sql))
15053  pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
15054  acls, baseacls, name, type);
15055 
15056  if (sql->len > 0)
15057  {
15058  PQExpBuffer tagbuf = createPQExpBuffer();
15059  DumpId aclDeps[2];
15060  int nDeps = 0;
15061 
15062  if (tag)
15063  appendPQExpBufferStr(tagbuf, tag);
15064  else if (subname)
15065  appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
15066  else
15067  appendPQExpBuffer(tagbuf, "%s %s", type, name);
15068 
15069  aclDeps[nDeps++] = objDumpId;
15070  if (altDumpId != InvalidDumpId)
15071  aclDeps[nDeps++] = altDumpId;
15072 
15073  aclDumpId = createDumpId();
15074 
15075  ArchiveEntry(fout, nilCatalogId, aclDumpId,
15076  ARCHIVE_OPTS(.tag = tagbuf->data,
15077  .namespace = nspname,
15078  .owner = owner,
15079  .description = "ACL",
15080  .section = SECTION_NONE,
15081  .createStmt = sql->data,
15082  .deps = aclDeps,
15083  .nDeps = nDeps));
15084 
15085  destroyPQExpBuffer(tagbuf);
15086  }
15087 
15088  destroyPQExpBuffer(sql);
15089 
15090  return aclDumpId;
15091 }
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:786
DumpId createDumpId(void)
Definition: common.c:710
bool buildACLCommands(const char *name, const char *subname, const char *nspname, const char *type, const char *acls, const char *baseacls, const char *owner, const char *prefix, int remoteVersion, PQExpBuffer sql)
Definition: dumputils.c:64
@ SECTION_NONE
Definition: pg_backup.h:57
#define InvalidDumpId
Definition: pg_backup.h: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 13949 of file pg_dump.c.

13950 {
13951  DumpOptions *dopt = fout->dopt;
13952  PQExpBuffer query;
13953  PQExpBuffer q;
13954  PQExpBuffer delq;
13955  PQExpBuffer details;
13956  char *aggsig; /* identity signature */
13957  char *aggfullsig = NULL; /* full signature */
13958  char *aggsig_tag;
13959  PGresult *res;
13960  int i_agginitval;
13961  int i_aggminitval;
13962  const char *aggtransfn;
13963  const char *aggfinalfn;
13964  const char *aggcombinefn;
13965  const char *aggserialfn;
13966  const char *aggdeserialfn;
13967  const char *aggmtransfn;
13968  const char *aggminvtransfn;
13969  const char *aggmfinalfn;
13970  bool aggfinalextra;
13971  bool aggmfinalextra;
13972  char aggfinalmodify;
13973  char aggmfinalmodify;
13974  const char *aggsortop;
13975  char *aggsortconvop;
13976  char aggkind;
13977  const char *aggtranstype;
13978  const char *aggtransspace;
13979  const char *aggmtranstype;
13980  const char *aggmtransspace;
13981  const char *agginitval;
13982  const char *aggminitval;
13983  const char *proparallel;
13984  char defaultfinalmodify;
13985 
13986  /* Do nothing in data-only dump */
13987  if (dopt->dataOnly)
13988  return;
13989 
13990  query = createPQExpBuffer();
13991  q = createPQExpBuffer();
13992  delq = createPQExpBuffer();
13993  details = createPQExpBuffer();
13994 
13995  if (!fout->is_prepared[PREPQUERY_DUMPAGG])
13996  {
13997  /* Set up query for aggregate-specific details */
13998  appendPQExpBufferStr(query,
13999  "PREPARE dumpAgg(pg_catalog.oid) AS\n");
14000 
14001  appendPQExpBufferStr(query,
14002  "SELECT "
14003  "aggtransfn,\n"
14004  "aggfinalfn,\n"
14005  "aggtranstype::pg_catalog.regtype,\n"
14006  "agginitval,\n"
14007  "aggsortop,\n"
14008  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
14009  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
14010 
14011  if (fout->remoteVersion >= 90400)
14012  appendPQExpBufferStr(query,
14013  "aggkind,\n"
14014  "aggmtransfn,\n"
14015  "aggminvtransfn,\n"
14016  "aggmfinalfn,\n"
14017  "aggmtranstype::pg_catalog.regtype,\n"
14018  "aggfinalextra,\n"
14019  "aggmfinalextra,\n"
14020  "aggtransspace,\n"
14021  "aggmtransspace,\n"
14022  "aggminitval,\n");
14023  else
14024  appendPQExpBufferStr(query,
14025  "'n' AS aggkind,\n"
14026  "'-' AS aggmtransfn,\n"
14027  "'-' AS aggminvtransfn,\n"
14028  "'-' AS aggmfinalfn,\n"
14029  "0 AS aggmtranstype,\n"
14030  "false AS aggfinalextra,\n"
14031  "false AS aggmfinalextra,\n"
14032  "0 AS aggtransspace,\n"
14033  "0 AS aggmtransspace,\n"
14034  "NULL AS aggminitval,\n");
14035 
14036  if (fout->remoteVersion >= 90600)
14037  appendPQExpBufferStr(query,
14038  "aggcombinefn,\n"
14039  "aggserialfn,\n"
14040  "aggdeserialfn,\n"
14041  "proparallel,\n");
14042  else
14043  appendPQExpBufferStr(query,
14044  "'-' AS aggcombinefn,\n"
14045  "'-' AS aggserialfn,\n"
14046  "'-' AS aggdeserialfn,\n"
14047  "'u' AS proparallel,\n");
14048 
14049  if (fout->remoteVersion >= 110000)
14050  appendPQExpBufferStr(query,
14051  "aggfinalmodify,\n"
14052  "aggmfinalmodify\n");
14053  else
14054  appendPQExpBufferStr(query,
14055  "'0' AS aggfinalmodify,\n"
14056  "'0' AS aggmfinalmodify\n");
14057 
14058  appendPQExpBufferStr(query,
14059  "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
14060  "WHERE a.aggfnoid = p.oid "
14061  "AND p.oid = $1");
14062 
14063  ExecuteSqlStatement(fout, query->data);
14064 
14065  fout->is_prepared[PREPQUERY_DUMPAGG] = true;
14066  }
14067 
14068  printfPQExpBuffer(query,
14069  "EXECUTE dumpAgg('%u')",
14070  agginfo->aggfn.dobj.catId.oid);
14071 
14072  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14073 
14074  i_agginitval = PQfnumber(res, "agginitval");
14075  i_aggminitval = PQfnumber(res, "aggminitval");
14076 
14077  aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
14078  aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
14079  aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
14080  aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
14081  aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
14082  aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
14083  aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
14084  aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
14085  aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
14086  aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
14087  aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
14088  aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
14089  aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
14090  aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
14091  aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
14092  aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
14093  aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
14094  aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
14095  agginitval = PQgetvalue(res, 0, i_agginitval);
14096  aggminitval = PQgetvalue(res, 0, i_aggminitval);
14097  proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
14098 
14099  {
14100  char *funcargs;
14101  char *funciargs;
14102 
14103  funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
14104  funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
14105  aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
14106  aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
14107  }
14108 
14109  aggsig_tag = format_aggregate_signature(agginfo, fout, false);
14110 
14111  /* identify default modify flag for aggkind (must match DefineAggregate) */
14112  defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
14113  /* replace omitted flags for old versions */
14114  if (aggfinalmodify == '0')
14115  aggfinalmodify = defaultfinalmodify;
14116  if (aggmfinalmodify == '0')
14117  aggmfinalmodify = defaultfinalmodify;
14118 
14119  /* regproc and regtype output is already sufficiently quoted */
14120  appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
14121  aggtransfn, aggtranstype);
14122 
14123  if (strcmp(aggtransspace, "0") != 0)
14124  {
14125  appendPQExpBuffer(details, ",\n SSPACE = %s",
14126  aggtransspace);
14127  }
14128 
14129  if (!PQgetisnull(res, 0, i_agginitval))
14130  {
14131  appendPQExpBufferStr(details, ",\n INITCOND = ");
14132  appendStringLiteralAH(details, agginitval, fout);
14133  }
14134 
14135  if (strcmp(aggfinalfn, "-") != 0)
14136  {
14137  appendPQExpBuffer(details, ",\n FINALFUNC = %s",
14138  aggfinalfn);
14139  if (aggfinalextra)
14140  appendPQExpBufferStr(details, ",\n FINALFUNC_EXTRA");
14141  if (aggfinalmodify != defaultfinalmodify)
14142  {
14143  switch (aggfinalmodify)
14144  {
14145  case AGGMODIFY_READ_ONLY:
14146  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_ONLY");
14147  break;
14148  case AGGMODIFY_SHAREABLE:
14149  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHAREABLE");
14150  break;
14151  case AGGMODIFY_READ_WRITE:
14152  appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_WRITE");
14153  break;
14154  default:
14155  pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
14156  agginfo->aggfn.dobj.name);
14157  break;
14158  }
14159  }
14160  }
14161 
14162  if (strcmp(aggcombinefn, "-") != 0)
14163  appendPQExpBuffer(details, ",\n COMBINEFUNC = %s", aggcombinefn);
14164 
14165  if (strcmp(aggserialfn, "-") != 0)
14166  appendPQExpBuffer(details, ",\n SERIALFUNC = %s", aggserialfn);
14167 
14168  if (strcmp(aggdeserialfn, "-") != 0)
14169  appendPQExpBuffer(details, ",\n DESERIALFUNC = %s", aggdeserialfn);
14170 
14171  if (strcmp(aggmtransfn, "-") != 0)
14172  {
14173  appendPQExpBuffer(details, ",\n MSFUNC = %s,\n MINVFUNC = %s,\n MSTYPE = %s",
14174  aggmtransfn,
14175  aggminvtransfn,
14176  aggmtranstype);
14177  }
14178 
14179  if (strcmp(aggmtransspace, "0") != 0)
14180  {
14181  appendPQExpBuffer(details, ",\n MSSPACE = %s",
14182  aggmtransspace);
14183  }
14184 
14185  if (!PQgetisnull(res, 0, i_aggminitval))
14186  {
14187  appendPQExpBufferStr(details, ",\n MINITCOND = ");
14188  appendStringLiteralAH(details, aggminitval, fout);
14189  }
14190 
14191  if (strcmp(aggmfinalfn, "-") != 0)
14192  {
14193  appendPQExpBuffer(details, ",\n MFINALFUNC = %s",
14194  aggmfinalfn);
14195  if (aggmfinalextra)
14196  appendPQExpBufferStr(details, ",\n MFINALFUNC_EXTRA");
14197  if (aggmfinalmodify != defaultfinalmodify)
14198  {
14199  switch (aggmfinalmodify)
14200  {
14201  case AGGMODIFY_READ_ONLY:
14202  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_ONLY");
14203  break;
14204  case AGGMODIFY_SHAREABLE:
14205  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHAREABLE");
14206  break;
14207  case AGGMODIFY_READ_WRITE:
14208  appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_WRITE");
14209  break;
14210  default:
14211  pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
14212  agginfo->aggfn.dobj.name);
14213  break;
14214  }
14215  }
14216  }
14217 
14218  aggsortconvop = getFormattedOperatorName(aggsortop);
14219  if (aggsortconvop)
14220  {
14221  appendPQExpBuffer(details, ",\n SORTOP = %s",
14222  aggsortconvop);
14223  free(aggsortconvop);
14224  }
14225 
14226  if (aggkind == AGGKIND_HYPOTHETICAL)
14227  appendPQExpBufferStr(details, ",\n HYPOTHETICAL");
14228 
14229  if (proparallel[0] != PROPARALLEL_UNSAFE)
14230  {
14231  if (proparallel[0] == PROPARALLEL_SAFE)
14232  appendPQExpBufferStr(details, ",\n PARALLEL = safe");
14233  else if (proparallel[0] == PROPARALLEL_RESTRICTED)
14234  appendPQExpBufferStr(details, ",\n PARALLEL = restricted");
14235  else if (proparallel[0] != PROPARALLEL_UNSAFE)
14236  pg_fatal("unrecognized proparallel value for function \"%s\"",
14237  agginfo->aggfn.dobj.name);
14238  }
14239 
14240  appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
14241  fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
14242  aggsig);
14243 
14244  appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
14245  fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
14246  aggfullsig ? aggfullsig : aggsig, details->data);
14247 
14248  if (dopt->binary_upgrade)
14249  binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
14250  "AGGREGATE", aggsig,
14251  agginfo->aggfn.dobj.namespace->dobj.name);
14252 
14253  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
14254  ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
14255  agginfo->aggfn.dobj.dumpId,
14256  ARCHIVE_OPTS(.tag = aggsig_tag,
14257  .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
14258  .owner = agginfo->aggfn.rolname,
14259  .description = "AGGREGATE",
14260  .section = SECTION_PRE_DATA,
14261  .createStmt = q->data,
14262  .dropStmt = delq->data));
14263 
14264  /* Dump Aggregate Comments */
14265  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
14266  dumpComment(fout, "AGGREGATE", aggsig,
14267  agginfo->aggfn.dobj.namespace->dobj.name,
14268  agginfo->aggfn.rolname,
14269  agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
14270 
14271  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
14272  dumpSecLabel(fout, "AGGREGATE", aggsig,
14273  agginfo->aggfn.dobj.namespace->dobj.name,
14274  agginfo->aggfn.rolname,
14275  agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
14276 
14277  /*
14278  * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
14279  * command look like a function's GRANT; in particular this affects the
14280  * syntax for zero-argument aggregates and ordered-set aggregates.
14281  */
14282  free(aggsig);
14283 
14284  aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14285 
14286  if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14287  dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
14288  "FUNCTION", aggsig, NULL,
14289  agginfo->aggfn.dobj.namespace->dobj.name,
14290  NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
14291 
14292  free(aggsig);
14293  free(aggfullsig);
14294  free(aggsig_tag);
14295 
14296  PQclear(res);
14297 
14298  destroyPQExpBuffer(query);
14299  destroyPQExpBuffer(q);
14300  destroyPQExpBuffer(delq);
14301  destroyPQExpBuffer(details);
14302 }
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:14984
static char * getFormattedOperatorName(const char *oproid)
Definition: pg_dump.c:12944
static char * format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
Definition: pg_dump.c:12005
static char * format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
Definition: pg_dump.c:13917
static char * format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
Definition: pg_dump.c:11982
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:15112
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 16536 of file pg_dump.c.

16537 {
16538  DumpOptions *dopt = fout->dopt;
16539  TableInfo *tbinfo = adinfo->adtable;
16540  int adnum = adinfo->adnum;
16541  PQExpBuffer q;
16542  PQExpBuffer delq;
16543  char *qualrelname;
16544  char *tag;
16545  char *foreign;
16546 
16547  /* Do nothing in data-only dump */
16548  if (dopt->dataOnly)
16549  return;
16550 
16551  /* Skip if not "separate"; it was dumped in the table's definition */
16552  if (!adinfo->separate)
16553  return;
16554 
16555  q = createPQExpBuffer();
16556  delq = createPQExpBuffer();
16557 
16558  qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
16559 
16560  foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
16561 
16563  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
16564  foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
16565  adinfo->adef_expr);
16566 
16567  appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
16568  foreign, qualrelname,
16569  fmtId(tbinfo->attnames[adnum - 1]));
16570 
16571  tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
16572 
16573  if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16574  ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
16575  ARCHIVE_OPTS(.tag = tag,
16576  .namespace = tbinfo->dobj.namespace->dobj.name,
16577  .owner = tbinfo->rolname,
16578  .description = "DEFAULT",
16579  .section = SECTION_PRE_DATA,
16580  .createStmt = q->data,
16581  .dropStmt = delq->data));
16582 
16583  free(tag);
16584  destroyPQExpBuffer(q);
16585  destroyPQExpBuffer(delq);
16586  free(qualrelname);
16587 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
DumpableObject dobj
Definition: pg_dump.h:375
char * adef_expr
Definition: pg_dump.h:378
TableInfo * adtable
Definition: pg_dump.h:376
bool separate
Definition: pg_dump.h:379
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 11087 of file pg_dump.c.

11088 {
11089  DumpOptions *dopt = fout->dopt;
11091  PQExpBuffer delq = createPQExpBuffer();
11092  PQExpBuffer query = createPQExpBuffer();
11093  PGresult *res;
11094  char *qtypname;
11095  char *qualtypname;
11096  char *typlen;
11097  char *typinput;
11098  char *typoutput;
11099  char *typreceive;
11100  char *typsend;
11101  char *typmodin;
11102  char *typmodout;
11103  char *typanalyze;
11104  char *typsubscript;
11105  Oid typreceiveoid;
11106  Oid typsendoid;
11107  Oid typmodinoid;
11108  Oid typmodoutoid;
11109  Oid typanalyzeoid;
11110  Oid typsubscriptoid;
11111  char *typcategory;
11112  char *typispreferred;
11113  char *typdelim;
11114  char *typbyval;
11115  char *typalign;
11116  char *typstorage;
11117  char *typcollatable;
11118  char *typdefault;
11119  bool typdefault_is_literal = false;
11120 
11121  if (!fout->is_prepared[PREPQUERY_DUMPBASETYPE])
11122  {
11123  /* Set up query for type-specific details */
11124  appendPQExpBufferStr(query,
11125  "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
11126  "SELECT typlen, "
11127  "typinput, typoutput, typreceive, typsend, "
11128  "typreceive::pg_catalog.oid AS typreceiveoid, "
11129  "typsend::pg_catalog.oid AS typsendoid, "
11130  "typanalyze, "
11131  "typanalyze::pg_catalog.oid AS typanalyzeoid, "
11132  "typdelim, typbyval, typalign, typstorage, "
11133  "typmodin, typmodout, "
11134  "typmodin::pg_catalog.oid AS typmodinoid, "
11135  "typmodout::pg_catalog.oid AS typmodoutoid, "
11136  "typcategory, typispreferred, "
11137  "(typcollation <> 0) AS typcollatable, "
11138  "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
11139 
11140  if (fout->remoteVersion >= 140000)
11141  appendPQExpBufferStr(query,
11142  "typsubscript, "
11143  "typsubscript::pg_catalog.oid AS typsubscriptoid ");
11144  else
11145  appendPQExpBufferStr(query,
11146  "'-' AS typsubscript, 0 AS typsubscriptoid ");
11147 
11148  appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
11149  "WHERE oid = $1");
11150 
11151  ExecuteSqlStatement(fout, query->data);
11152 
11153  fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
11154  }
11155 
11156  printfPQExpBuffer(query,
11157  "EXECUTE dumpBaseType('%u')",
11158  tyinfo->dobj.catId.oid);
11159 
11160  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11161 
11162  typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
11163  typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
11164  typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
11165  typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
11166  typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
11167  typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
11168  typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
11169  typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
11170  typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
11171  typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
11172  typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
11173  typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
11174  typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
11175  typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
11176  typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
11177  typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
11178  typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
11179  typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
11180  typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
11181  typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
11182  typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
11183  typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
11184  if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
11185  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
11186  else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
11187  {
11188  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
11189  typdefault_is_literal = true; /* it needs quotes */
11190  }
11191  else
11192  typdefault = NULL;
11193 
11194  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11195  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11196 
11197  /*
11198  * The reason we include CASCADE is that the circular dependency between
11199  * the type and its I/O functions makes it impossible to drop the type any
11200  * other way.
11201  */
11202  appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
11203 
11204  /*
11205  * We might already have a shell type, but setting pg_type_oid is
11206  * harmless, and in any case we'd better set the array type OID.
11207  */
11208  if (dopt->binary_upgrade)
11210  tyinfo->dobj.catId.oid,
11211  false, false);
11212 
11214  "CREATE TYPE %s (\n"
11215  " INTERNALLENGTH = %s",
11216  qualtypname,
11217  (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
11218 
11219  /* regproc result is sufficiently quoted already */
11220  appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
11221  appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
11222  if (OidIsValid(typreceiveoid))
11223  appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
11224  if (OidIsValid(typsendoid))
11225  appendPQExpBuffer(q, ",\n SEND = %s", typsend);
11226  if (OidIsValid(typmodinoid))
11227  appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
11228  if (OidIsValid(typmodoutoid))
11229  appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
11230  if (OidIsValid(typanalyzeoid))
11231  appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
11232 
11233  if (strcmp(typcollatable, "t") == 0)
11234  appendPQExpBufferStr(q, ",\n COLLATABLE = true");
11235 
11236  if (typdefault != NULL)
11237  {
11238  appendPQExpBufferStr(q, ",\n DEFAULT = ");
11239  if (typdefault_is_literal)
11240  appendStringLiteralAH(q, typdefault, fout);
11241  else
11242  appendPQExpBufferStr(q, typdefault);
11243  }
11244 
11245  if (OidIsValid(typsubscriptoid))
11246  appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
11247 
11248  if (OidIsValid(tyinfo->typelem))
11249  appendPQExpBuffer(q, ",\n ELEMENT = %s",
11250  getFormattedTypeName(fout, tyinfo->typelem,
11251  zeroIsError));
11252 
11253  if (strcmp(typcategory, "U") != 0)
11254  {
11255  appendPQExpBufferStr(q, ",\n CATEGORY = ");
11256  appendStringLiteralAH(q, typcategory, fout);
11257  }
11258 
11259  if (strcmp(typispreferred, "t") == 0)
11260  appendPQExpBufferStr(q, ",\n PREFERRED = true");
11261 
11262  if (typdelim && strcmp(typdelim, ",") != 0)
11263  {
11264  appendPQExpBufferStr(q, ",\n DELIMITER = ");
11265  appendStringLiteralAH(q, typdelim, fout);
11266  }
11267 
11268  if (*typalign == TYPALIGN_CHAR)
11269  appendPQExpBufferStr(q, ",\n ALIGNMENT = char");
11270  else if (*typalign == TYPALIGN_SHORT)
11271  appendPQExpBufferStr(q, ",\n ALIGNMENT = int2");
11272  else if (*typalign == TYPALIGN_INT)
11273  appendPQExpBufferStr(q, ",\n ALIGNMENT = int4");
11274  else if (*typalign == TYPALIGN_DOUBLE)
11275  appendPQExpBufferStr(q, ",\n ALIGNMENT = double");
11276 
11277  if (*typstorage == TYPSTORAGE_PLAIN)
11278  appendPQExpBufferStr(q, ",\n STORAGE = plain");
11279  else if (*typstorage == TYPSTORAGE_EXTERNAL)
11280  appendPQExpBufferStr(q, ",\n STORAGE = external");
11281  else if (*typstorage == TYPSTORAGE_EXTENDED)
11282  appendPQExpBufferStr(q, ",\n STORAGE = extended");
11283  else if (*typstorage == TYPSTORAGE_MAIN)
11284  appendPQExpBufferStr(q, ",\n STORAGE = main");
11285 
11286  if (strcmp(typbyval, "t") == 0)
11287  appendPQExpBufferStr(q, ",\n PASSEDBYVALUE");
11288 
11289  appendPQExpBufferStr(q, "\n);\n");
11290 
11291  if (dopt->binary_upgrade)
11293  "TYPE", qtypname,
11294  tyinfo->dobj.namespace->dobj.name);
11295 
11296  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11297  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11298  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11299  .namespace = tyinfo->dobj.namespace->dobj.name,
11300  .owner = tyinfo->rolname,
11301  .description = "TYPE",
11302  .section = SECTION_PRE_DATA,
11303  .createStmt = q->data,
11304  .dropStmt = delq->data));
11305 
11306  /* Dump Type Comments and Security Labels */
11307  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11308  dumpComment(fout, "TYPE", qtypname,
11309  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11310  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11311 
11312  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11313  dumpSecLabel(fout, "TYPE", qtypname,
11314  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11315  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11316 
11317  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11318  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11319  qtypname, NULL,
11320  tyinfo->dobj.namespace->dobj.name,
11321  NULL, tyinfo->rolname, &tyinfo->dacl);
11322 
11323  PQclear(res);
11324  destroyPQExpBuffer(q);
11325  destroyPQExpBuffer(delq);
11326  destroyPQExpBuffer(query);
11327  free(qtypname);
11328  free(qualtypname);
11329 }
@ PREPQUERY_DUMPBASETYPE
Definition: pg_backup.h:67
static const char * getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
Definition: pg_dump.c:18562
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 12450 of file pg_dump.c.

12451 {
12452  DumpOptions *dopt = fout->dopt;
12453  PQExpBuffer defqry;
12454  PQExpBuffer delqry;
12455  PQExpBuffer labelq;
12456  PQExpBuffer castargs;
12457  FuncInfo *funcInfo = NULL;
12458  const char *sourceType;
12459  const char *targetType;
12460 
12461  /* Do nothing in data-only dump */
12462  if (dopt->dataOnly)
12463  return;
12464 
12465  /* Cannot dump if we don't have the cast function's info */
12466  if (OidIsValid(cast->castfunc))
12467  {
12468  funcInfo = findFuncByOid(cast->castfunc);
12469  if (funcInfo == NULL)
12470  pg_fatal("could not find function definition for function with OID %u",
12471  cast->castfunc);
12472  }
12473 
12474  defqry = createPQExpBuffer();
12475  delqry = createPQExpBuffer();
12476  labelq = createPQExpBuffer();
12477  castargs = createPQExpBuffer();
12478 
12479  sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
12480  targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
12481  appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
12482  sourceType, targetType);
12483 
12484  appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
12485  sourceType, targetType);
12486 
12487  switch (cast->castmethod)
12488  {
12489  case COERCION_METHOD_BINARY:
12490  appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
12491  break;
12492  case COERCION_METHOD_INOUT:
12493  appendPQExpBufferStr(defqry, "WITH INOUT");
12494  break;
12495  case COERCION_METHOD_FUNCTION:
12496  if (funcInfo)
12497  {
12498  char *fsig = format_function_signature(fout, funcInfo, true);
12499 
12500  /*
12501  * Always qualify the function name (format_function_signature
12502  * won't qualify it).
12503  */
12504  appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
12505  fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
12506  free(fsig);
12507  }
12508  else
12509  pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
12510  break;
12511  default:
12512  pg_log_warning("bogus value in pg_cast.castmethod field");
12513  }
12514 
12515  if (cast->castcontext == 'a')
12516  appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
12517  else if (cast->castcontext == 'i')
12518  appendPQExpBufferStr(defqry, " AS IMPLICIT");
12519  appendPQExpBufferStr(defqry, ";\n");
12520 
12521  appendPQExpBuffer(labelq, "CAST (%s AS %s)",
12522  sourceType, targetType);
12523 
12524  appendPQExpBuffer(castargs, "(%s AS %s)",
12525  sourceType, targetType);
12526 
12527  if (dopt->binary_upgrade)
12528  binary_upgrade_extension_member(defqry, &cast->dobj,
12529  "CAST", castargs->data, NULL);
12530 
12531  if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
12532  ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
12533  ARCHIVE_OPTS(.tag = labelq->data,
12534  .description = "CAST",
12535  .section = SECTION_PRE_DATA,
12536  .createStmt = defqry->data,
12537  .dropStmt = delqry->data));
12538 
12539  /* Dump Cast Comments */
12540  if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
12541  dumpComment(fout, "CAST", castargs->data,
12542  NULL, "",
12543  cast->dobj.catId, 0, cast->dobj.dumpId);
12544 
12545  destroyPQExpBuffer(defqry);
12546  destroyPQExpBuffer(delqry);
12547  destroyPQExpBuffer(labelq);
12548  destroyPQExpBuffer(castargs);
12549 }
FuncInfo * findFuncByOid(Oid oid)
Definition: common.c:883
char castmethod
Definition: pg_dump.h:499
Oid casttarget
Definition: pg_dump.h:496
char castcontext
Definition: pg_dump.h:498
DumpableObject dobj
Definition: pg_dump.h:494
Oid castsource
Definition: pg_dump.h:495
Oid castfunc
Definition: pg_dump.h:497
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 13564 of file pg_dump.c.

13565 {
13566  DumpOptions *dopt = fout->dopt;
13567  PQExpBuffer query;
13568  PQExpBuffer q;
13569  PQExpBuffer delq;
13570  char *qcollname;
13571  PGresult *res;
13572  int i_collprovider;
13573  int i_collisdeterministic;
13574  int i_collcollate;
13575  int i_collctype;
13576  int i_colllocale;
13577  int i_collicurules;
13578  const char *collprovider;
13579  const char *collcollate;
13580  const char *collctype;
13581  const char *colllocale;
13582  const char *collicurules;
13583 
13584  /* Do nothing in data-only dump */
13585  if (dopt->dataOnly)
13586  return;
13587 
13588  query = createPQExpBuffer();
13589  q = createPQExpBuffer();
13590  delq = createPQExpBuffer();
13591 
13592  qcollname = pg_strdup(fmtId(collinfo->dobj.name));
13593 
13594  /* Get collation-specific details */
13595  appendPQExpBufferStr(query, "SELECT ");
13596 
13597  if (fout->remoteVersion >= 100000)
13598  appendPQExpBufferStr(query,
13599  "collprovider, "
13600  "collversion, ");
13601  else
13602  appendPQExpBufferStr(query,
13603  "'c' AS collprovider, "
13604  "NULL AS collversion, ");
13605 
13606  if (fout->remoteVersion >= 120000)
13607  appendPQExpBufferStr(query,
13608  "collisdeterministic, ");
13609  else
13610  appendPQExpBufferStr(query,
13611  "true AS collisdeterministic, ");
13612 
13613  if (fout->remoteVersion >= 170000)
13614  appendPQExpBufferStr(query,
13615  "colllocale, ");
13616  else if (fout->remoteVersion >= 150000)
13617  appendPQExpBufferStr(query,
13618  "colliculocale AS colllocale, ");
13619  else
13620  appendPQExpBufferStr(query,
13621  "NULL AS colllocale, ");
13622 
13623  if (fout->remoteVersion >= 160000)
13624  appendPQExpBufferStr(query,
13625  "collicurules, ");
13626  else
13627  appendPQExpBufferStr(query,
13628  "NULL AS collicurules, ");
13629 
13630  appendPQExpBuffer(query,
13631  "collcollate, "
13632  "collctype "
13633  "FROM pg_catalog.pg_collation c "
13634  "WHERE c.oid = '%u'::pg_catalog.oid",
13635  collinfo->dobj.catId.oid);
13636 
13637  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13638 
13639  i_collprovider = PQfnumber(res, "collprovider");
13640  i_collisdeterministic = PQfnumber(res, "collisdeterministic");
13641  i_collcollate = PQfnumber(res, "collcollate");
13642  i_collctype = PQfnumber(res, "collctype");
13643  i_colllocale = PQfnumber(res, "colllocale");
13644  i_collicurules = PQfnumber(res, "collicurules");
13645 
13646  collprovider = PQgetvalue(res, 0, i_collprovider);
13647 
13648  if (!PQgetisnull(res, 0, i_collcollate))
13649  collcollate = PQgetvalue(res, 0, i_collcollate);
13650  else
13651  collcollate = NULL;
13652 
13653  if (!PQgetisnull(res, 0, i_collctype))
13654  collctype = PQgetvalue(res, 0, i_collctype);
13655  else
13656  collctype = NULL;
13657 
13658  /*
13659  * Before version 15, collcollate and collctype were of type NAME and
13660  * non-nullable. Treat empty strings as NULL for consistency.
13661  */
13662  if (fout->remoteVersion < 150000)
13663  {
13664  if (collcollate[0] == '\0')
13665  collcollate = NULL;
13666  if (collctype[0] == '\0')
13667  collctype = NULL;
13668  }
13669 
13670  if (!PQgetisnull(res, 0, i_colllocale))
13671  colllocale = PQgetvalue(res, 0, i_colllocale);
13672  else
13673  colllocale = NULL;
13674 
13675  if (!PQgetisnull(res, 0, i_collicurules))
13676  collicurules = PQgetvalue(res, 0, i_collicurules);
13677  else
13678  collicurules = NULL;
13679 
13680  appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
13681  fmtQualifiedDumpable(collinfo));
13682 
13683  appendPQExpBuffer(q, "CREATE COLLATION %s (",
13684  fmtQualifiedDumpable(collinfo));
13685 
13686  appendPQExpBufferStr(q, "provider = ");
13687  if (collprovider[0] == 'b')
13688  appendPQExpBufferStr(q, "builtin");
13689  else if (collprovider[0] == 'c')
13690  appendPQExpBufferStr(q, "libc");
13691  else if (collprovider[0] == 'i')
13692  appendPQExpBufferStr(q, "icu");
13693  else if (collprovider[0] == 'd')
13694  /* to allow dumping pg_catalog; not accepted on input */
13695  appendPQExpBufferStr(q, "default");
13696  else
13697  pg_fatal("unrecognized collation provider: %s",
13698  collprovider);
13699 
13700  if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
13701  appendPQExpBufferStr(q, ", deterministic = false");
13702 
13703  if (collprovider[0] == 'd')
13704  {
13705  if (collcollate || collctype || colllocale || collicurules)
13706  pg_log_warning("invalid collation \"%s\"", qcollname);
13707 
13708  /* no locale -- the default collation cannot be reloaded anyway */
13709  }
13710  else if (collprovider[0] == 'b')
13711  {
13712  if (collcollate || collctype || !colllocale || collicurules)
13713  pg_log_warning("invalid collation \"%s\"", qcollname);
13714 
13715  appendPQExpBufferStr(q, ", locale = ");
13716  appendStringLiteralAH(q, colllocale ? colllocale : "",
13717  fout);
13718  }
13719  else if (collprovider[0] == 'i')
13720  {
13721  if (fout->remoteVersion >= 150000)
13722  {
13723  if (collcollate || collctype || !colllocale)
13724  pg_log_warning("invalid collation \"%s\"", qcollname);
13725 
13726  appendPQExpBufferStr(q, ", locale = ");
13727  appendStringLiteralAH(q, colllocale ? colllocale : "",
13728  fout);
13729  }
13730  else
13731  {
13732  if (!collcollate || !collctype || colllocale ||
13733  strcmp(collcollate, collctype) != 0)
13734  pg_log_warning("invalid collation \"%s\"", qcollname);
13735 
13736  appendPQExpBufferStr(q, ", locale = ");
13737  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
13738  }
13739 
13740  if (collicurules)
13741  {
13742  appendPQExpBufferStr(q, ", rules = ");
13743  appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
13744  }
13745  }
13746  else if (collprovider[0] == 'c')
13747  {
13748  if (colllocale || collicurules || !collcollate || !collctype)
13749  pg_log_warning("invalid collation \"%s\"", qcollname);
13750 
13751  if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
13752  {
13753  appendPQExpBufferStr(q, ", locale = ");
13754  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
13755  }
13756  else
13757  {
13758  appendPQExpBufferStr(q, ", lc_collate = ");
13759  appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
13760  appendPQExpBufferStr(q, ", lc_ctype = ");
13761  appendStringLiteralAH(q, collctype ? collctype : "", fout);
13762  }
13763  }
13764  else
13765  pg_fatal("unrecognized collation provider: %s", collprovider);
13766 
13767  /*
13768  * For binary upgrade, carry over the collation version. For normal
13769  * dump/restore, omit the version, so that it is computed upon restore.
13770  */
13771  if (dopt->binary_upgrade)
13772  {
13773  int i_collversion;
13774 
13775  i_collversion = PQfnumber(res, "collversion");
13776  if (!PQgetisnull(res, 0, i_collversion))
13777  {
13778  appendPQExpBufferStr(q, ", version = ");
13780  PQgetvalue(res, 0, i_collversion),
13781  fout);
13782  }
13783  }
13784 
13785  appendPQExpBufferStr(q, ");\n");
13786 
13787  if (dopt->binary_upgrade)
13788  binary_upgrade_extension_member(q, &collinfo->dobj,
13789  "COLLATION", qcollname,
13790  collinfo->dobj.namespace->dobj.name);
13791 
13792  if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13793  ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
13794  ARCHIVE_OPTS(.tag = collinfo->dobj.name,
13795  .namespace = collinfo->dobj.namespace->dobj.name,
13796  .owner = collinfo->rolname,
13797  .description = "COLLATION",
13798  .section = SECTION_PRE_DATA,
13799  .createStmt = q->data,
13800  .dropStmt = delq->data));
13801 
13802  /* Dump Collation Comments */
13803  if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13804  dumpComment(fout, "COLLATION", qcollname,
13805  collinfo->dobj.namespace->dobj.name, collinfo->rolname,
13806  collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
13807 
13808  PQclear(res);
13809 
13810  destroyPQExpBuffer(query);
13811  destroyPQExpBuffer(q);
13812  destroyPQExpBuffer(delq);
13813  free(qcollname);
13814 }
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 10020 of file pg_dump.c.

10024 {
10025  dumpCommentExtended(fout, type, name, namespace, owner,
10026  catalogId, subid, dumpId, NULL);
10027 }
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:9920

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

9925 {
9926  DumpOptions *dopt = fout->dopt;
9928  int ncomments;
9929 
9930  /* do nothing, if --no-comments is supplied */
9931  if (dopt->no_comments)
9932  return;
9933 
9934  /* Comments are schema not data ... except LO comments are data */
9935  if (strcmp(type, "LARGE OBJECT") != 0)
9936  {
9937  if (dopt->dataOnly)
9938  return;
9939  }
9940  else
9941  {
9942  /* We do dump LO comments in binary-upgrade mode */
9943  if (dopt->schemaOnly && !dopt->binary_upgrade)
9944  return;
9945  }
9946 
9947  /* Search for comments associated with catalogId, using table */
9948  ncomments = findComments(catalogId.tableoid, catalogId.oid,
9949  &comments);
9950 
9951  /* Is there one matching the subid? */
9952  while (ncomments > 0)
9953  {
9954  if (comments->objsubid == subid)
9955  break;
9956  comments++;
9957  ncomments--;
9958  }
9959 
9960  if (initdb_comment != NULL)
9961  {
9962  static CommentItem empty_comment = {.descr = ""};
9963 
9964  /*
9965  * initdb creates this object with a comment. Skip dumping the
9966  * initdb-provided comment, which would complicate matters for
9967  * non-superuser use of pg_dump. When the DBA has removed initdb's
9968  * comment, replicate that.
9969  */
9970  if (ncomments == 0)
9971  {
9972  comments = &empty_comment;
9973  ncomments = 1;
9974  }
9975  else if (strcmp(comments->descr, initdb_comment) == 0)
9976  ncomments = 0;
9977  }
9978 
9979  /* If a comment exists, build COMMENT ON statement */
9980  if (ncomments > 0)
9981  {
9982  PQExpBuffer query = createPQExpBuffer();
9984 
9985  appendPQExpBuffer(query, "COMMENT ON %s ", type);
9986  if (namespace && *namespace)
9987  appendPQExpBuffer(query, "%s.", fmtId(namespace));
9988  appendPQExpBuffer(query, "%s IS ", name);
9989  appendStringLiteralAH(query, comments->descr, fout);
9990  appendPQExpBufferStr(query, ";\n");
9991 
9992  appendPQExpBuffer(tag, "%s %s", type, name);
9993 
9994  /*
9995  * We mark comments as SECTION_NONE because they really belong in the
9996  * same section as their parent, whether that is pre-data or
9997  * post-data.
9998  */
10000  ARCHIVE_OPTS(.tag = tag->data,
10001  .namespace = namespace,
10002  .owner = owner,
10003  .description = "COMMENT",
10004  .section = SECTION_NONE,
10005  .createStmt = query->data,
10006  .deps = &dumpId,
10007  .nDeps = 1));
10008 
10009  destroyPQExpBuffer(query);
10010  destroyPQExpBuffer(tag);
10011  }
10012 }
static int findComments(Oid classoid, Oid objoid, CommentItem **items)
Definition: pg_dump.c:10134
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 11509 of file pg_dump.c.

11510 {
11511  DumpOptions *dopt = fout->dopt;
11513  PQExpBuffer dropped = createPQExpBuffer();
11514  PQExpBuffer delq = createPQExpBuffer();
11515  PQExpBuffer query = createPQExpBuffer();
11516  PGresult *res;
11517  char *qtypname;
11518  char *qualtypname;
11519  int ntups;
11520  int i_attname;
11521  int i_atttypdefn;
11522  int i_attlen;
11523  int i_attalign;
11524  int i_attisdropped;
11525  int i_attcollation;
11526  int i;
11527  int actual_atts;
11528 
11530  {
11531  /*
11532  * Set up query for type-specific details.
11533  *
11534  * Since we only want to dump COLLATE clauses for attributes whose
11535  * collation is different from their type's default, we use a CASE
11536  * here to suppress uninteresting attcollations cheaply. atttypid
11537  * will be 0 for dropped columns; collation does not matter for those.
11538  */
11539  appendPQExpBufferStr(query,
11540  "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
11541  "SELECT a.attname, a.attnum, "
11542  "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
11543  "a.attlen, a.attalign, a.attisdropped, "
11544  "CASE WHEN a.attcollation <> at.typcollation "
11545  "THEN a.attcollation ELSE 0 END AS attcollation "
11546  "FROM pg_catalog.pg_type ct "
11547  "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
11548  "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
11549  "WHERE ct.oid = $1 "
11550  "ORDER BY a.attnum");
11551 
11552  ExecuteSqlStatement(fout, query->data);
11553 
11555  }
11556 
11557  printfPQExpBuffer(query,
11558  "EXECUTE dumpCompositeType('%u')",
11559  tyinfo->dobj.catId.oid);
11560 
11561  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11562 
11563  ntups = PQntuples(res);
11564 
11565  i_attname = PQfnumber(res, "attname");
11566  i_atttypdefn = PQfnumber(res, "atttypdefn");
11567  i_attlen = PQfnumber(res, "attlen");
11568  i_attalign = PQfnumber(res, "attalign");
11569  i_attisdropped = PQfnumber(res, "attisdropped");
11570  i_attcollation = PQfnumber(res, "attcollation");
11571 
11572  if (dopt->binary_upgrade)
11573  {
11575  tyinfo->dobj.catId.oid,
11576  false, false);
11577  binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid);
11578  }
11579 
11580  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11581  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11582 
11583  appendPQExpBuffer(q, "CREATE TYPE %s AS (",
11584  qualtypname);
11585 
11586  actual_atts = 0;
11587  for (i = 0; i < ntups; i++)
11588  {
11589  char *attname;
11590  char *atttypdefn;
11591  char *attlen;
11592  char *attalign;
11593  bool attisdropped;
11594  Oid attcollation;
11595 
11596  attname = PQgetvalue(res, i, i_attname);
11597  atttypdefn = PQgetvalue(res, i, i_atttypdefn);
11598  attlen = PQgetvalue(res, i, i_attlen);
11599  attalign = PQgetvalue(res, i, i_attalign);
11600  attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
11601  attcollation = atooid(PQgetvalue(res, i, i_attcollation));
11602 
11603  if (attisdropped && !dopt->binary_upgrade)
11604  continue;
11605 
11606  /* Format properly if not first attr */
11607  if (actual_atts++ > 0)
11608  appendPQExpBufferChar(q, ',');
11609  appendPQExpBufferStr(q, "\n\t");
11610 
11611  if (!attisdropped)
11612  {
11613  appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
11614 
11615  /* Add collation if not default for the column type */
11616  if (OidIsValid(attcollation))
11617  {
11618  CollInfo *coll;
11619 
11620  coll = findCollationByOid(attcollation);
11621  if (coll)
11622  appendPQExpBuffer(q, " COLLATE %s",
11623  fmtQualifiedDumpable(coll));
11624  }
11625  }
11626  else
11627  {
11628  /*
11629  * This is a dropped attribute and we're in binary_upgrade mode.
11630  * Insert a placeholder for it in the CREATE TYPE command, and set
11631  * length and alignment with direct UPDATE to the catalogs
11632  * afterwards. See similar code in dumpTableSchema().
11633  */
11634  appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
11635 
11636  /* stash separately for insertion after the CREATE TYPE */
11637  appendPQExpBufferStr(dropped,
11638  "\n-- For binary upgrade, recreate dropped column.\n");
11639  appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
11640  "SET attlen = %s, "
11641  "attalign = '%s', attbyval = false\n"
11642  "WHERE attname = ", attlen, attalign);
11643  appendStringLiteralAH(dropped, attname, fout);
11644  appendPQExpBufferStr(dropped, "\n AND attrelid = ");
11645  appendStringLiteralAH(dropped, qualtypname, fout);
11646  appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
11647 
11648  appendPQExpBuffer(dropped, "ALTER TYPE %s ",
11649  qualtypname);
11650  appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
11651  fmtId(attname));
11652  }
11653  }
11654  appendPQExpBufferStr(q, "\n);\n");
11655  appendPQExpBufferStr(q, dropped->data);
11656 
11657  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11658 
11659  if (dopt->binary_upgrade)
11661  "TYPE", qtypname,
11662  tyinfo->dobj.namespace->dobj.name);
11663 
11664  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11665  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11666  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11667  .namespace = tyinfo->dobj.namespace->dobj.name,
11668  .owner = tyinfo->rolname,
11669  .description = "TYPE",
11670  .section = SECTION_PRE_DATA,
11671  .createStmt = q->data,
11672  .dropStmt = delq->data));
11673 
11674 
11675  /* Dump Type Comments and Security Labels */
11676  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11677  dumpComment(fout, "TYPE", qtypname,
11678  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11679  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11680 
11681  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11682  dumpSecLabel(fout, "TYPE", qtypname,
11683  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11684  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11685 
11686  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11687  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11688  qtypname, NULL,
11689  tyinfo->dobj.namespace->dobj.name,
11690  NULL, tyinfo->rolname, &tyinfo->dacl);
11691 
11692  /* Dump any per-column comments */
11693  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11694  dumpCompositeTypeColComments(fout, tyinfo, res);
11695 
11696  PQclear(res);
11697  destroyPQExpBuffer(q);
11698  destroyPQExpBuffer(dropped);
11699  destroyPQExpBuffer(delq);
11700  destroyPQExpBuffer(query);
11701  free(qtypname);
11702  free(qualtypname);
11703 }
NameData attname
Definition: pg_attribute.h:41
char attalign
Definition: pg_attribute.h:109
int16 attlen
Definition: pg_attribute.h:59
@ PREPQUERY_DUMPCOMPOSITETYPE
Definition: pg_backup.h:68
static void binary_upgrade_set_pg_class_oids(Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid)
Definition: pg_dump.c:5467
static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo, PGresult *res)
Definition: pg_dump.c:11715
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 11715 of file pg_dump.c.

11717 {
11719  int ncomments;
11720  PQExpBuffer query;
11721  PQExpBuffer target;
11722  int i;
11723  int ntups;
11724  int i_attname;
11725  int i_attnum;
11726  int i_attisdropped;
11727 
11728  /* do nothing, if --no-comments is supplied */
11729  if (fout->dopt->no_comments)
11730  return;
11731 
11732  /* Search for comments associated with type's pg_class OID */
11733  ncomments = findComments(RelationRelationId, tyinfo->typrelid,
11734  &comments);
11735 
11736  /* If no comments exist, we're done */
11737  if (ncomments <= 0)
11738  return;
11739 
11740  /* Build COMMENT ON statements */
11741  query = createPQExpBuffer();
11742  target = createPQExpBuffer();
11743 
11744  ntups = PQntuples(res);
11745  i_attnum = PQfnumber(res, "attnum");
11746  i_attname = PQfnumber(res, "attname");
11747  i_attisdropped = PQfnumber(res, "attisdropped");
11748  while (ncomments > 0)
11749  {
11750  const char *attname;
11751 
11752  attname = NULL;
11753  for (i = 0; i < ntups; i++)
11754  {
11755  if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
11756  PQgetvalue(res, i, i_attisdropped)[0] != 't')
11757  {
11758  attname = PQgetvalue(res, i, i_attname);
11759  break;
11760  }
11761  }
11762  if (attname) /* just in case we don't find it */
11763  {
11764  const char *descr = comments->descr;
11765 
11766  resetPQExpBuffer(target);
11767  appendPQExpBuffer(target, "COLUMN %s.",
11768  fmtId(tyinfo->dobj.name));
11770 
11771  resetPQExpBuffer(query);
11772  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
11773  fmtQualifiedDumpable(tyinfo));
11774  appendPQExpBuffer(query, "%s IS ", fmtId(attname));
11775  appendStringLiteralAH(query, descr, fout);
11776  appendPQExpBufferStr(query, ";\n");
11777 
11779  ARCHIVE_OPTS(.tag = target->data,
11780  .namespace = tyinfo->dobj.namespace->dobj.name,
11781  .owner = tyinfo->rolname,
11782  .description = "COMMENT",
11783  .section = SECTION_NONE,
11784  .createStmt = query->data,
11785  .deps = &(tyinfo->dobj.dumpId),
11786  .nDeps = 1));
11787  }
11788 
11789  comments++;
11790  ncomments--;
11791  }
11792 
11793  destroyPQExpBuffer(query);
11794  destroyPQExpBuffer(target);
11795 }
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 16883 of file pg_dump.c.

16884 {
16885  DumpOptions *dopt = fout->dopt;
16886  TableInfo *tbinfo = coninfo->contable;
16887  PQExpBuffer q;
16888  PQExpBuffer delq;
16889  char *tag = NULL;
16890  char *foreign;
16891 
16892  /* Do nothing in data-only dump */
16893  if (dopt->dataOnly)
16894  return;
16895 
16896  q = createPQExpBuffer();
16897  delq = createPQExpBuffer();
16898 
16899  foreign = tbinfo &&
16900  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
16901 
16902  if (coninfo->contype == 'p' ||
16903  coninfo->contype == 'u' ||
16904  coninfo->contype == 'x')
16905  {
16906  /* Index-related constraint */
16907  IndxInfo *indxinfo;
16908  int k;
16909 
16910  indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
16911 
16912  if (indxinfo == NULL)
16913  pg_fatal("missing index for constraint \"%s\"",
16914  coninfo->dobj.name);
16915 
16916  if (dopt->binary_upgrade)
16918  indxinfo->dobj.catId.oid);
16919 
16920  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
16921  fmtQualifiedDumpable(tbinfo));
16922  appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
16923  fmtId(coninfo->dobj.name));
16924 
16925  if (coninfo->condef)
16926  {
16927  /* pg_get_constraintdef should have provided everything */
16928  appendPQExpBuffer(q, "%s;\n", coninfo->condef);
16929  }
16930  else
16931  {
16933  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
16934 
16935  /*
16936  * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
16937  * indexes. Being able to create this was fixed, but we need to
16938  * make the index distinct in order to be able to restore the
16939  * dump.
16940  */
16941  if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
16942  appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
16943  appendPQExpBufferStr(q, " (");
16944  for (k = 0; k < indxinfo->indnkeyattrs; k++)
16945  {
16946  int indkey = (int) indxinfo->indkeys[k];
16947  const char *attname;
16948 
16949  if (indkey == InvalidAttrNumber)
16950  break;
16951  attname = getAttrName(indkey, tbinfo);
16952 
16953  appendPQExpBuffer(q, "%s%s",
16954  (k == 0) ? "" : ", ",
16955  fmtId(attname));
16956  }
16957 
16958  if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
16959  appendPQExpBufferStr(q, ") INCLUDE (");
16960 
16961  for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
16962  {
16963  int indkey = (int) indxinfo->indkeys[k];
16964  const char *attname;
16965 
16966  if (indkey == InvalidAttrNumber)
16967  break;
16968  attname = getAttrName(indkey, tbinfo);
16969 
16970  appendPQExpBuffer(q, "%s%s",
16971  (k == indxinfo->indnkeyattrs) ? "" : ", ",
16972  fmtId(attname));
16973  }
16974 
16975  appendPQExpBufferChar(q, ')');
16976 
16977  if (nonemptyReloptions(indxinfo->indreloptions))
16978  {
16979  appendPQExpBufferStr(q, " WITH (");
16980  appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
16981  appendPQExpBufferChar(q, ')');
16982  }
16983 
16984  if (coninfo->condeferrable)
16985  {
16986  appendPQExpBufferStr(q, " DEFERRABLE");
16987  if (coninfo->condeferred)
16988  appendPQExpBufferStr(q, " INITIALLY DEFERRED");
16989  }
16990 
16991  appendPQExpBufferStr(q, ";\n");
16992  }
16993 
16994  /*
16995  * Append ALTER TABLE commands as needed to set properties that we
16996  * only have ALTER TABLE syntax for. Keep this in sync with the
16997  * similar code in dumpIndex!
16998  */
16999 
17000  /* If the index is clustered, we need to record that. */
17001  if (indxinfo->indisclustered)
17002  {
17003  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17004  fmtQualifiedDumpable(tbinfo));
17005  /* index name is not qualified in this syntax */
17006  appendPQExpBuffer(q, " ON %s;\n",
17007  fmtId(indxinfo->dobj.name));
17008  }
17009 
17010  /* If the index defines identity, we need to record that. */
17011  if (indxinfo->indisreplident)
17012  {
17013  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17014  fmtQualifiedDumpable(tbinfo));
17015  /* index name is not qualified in this syntax */
17016  appendPQExpBuffer(q, " INDEX %s;\n",
17017  fmtId(indxinfo->dobj.name));
17018  }
17019 
17020  /* Indexes can depend on extensions */
17021  append_depends_on_extension(fout, q, &indxinfo->dobj,
17022  "pg_catalog.pg_class", "INDEX",
17023  fmtQualifiedDumpable(indxinfo));
17024 
17025  appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
17026  fmtQualifiedDumpable(tbinfo));
17027  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17028  fmtId(coninfo->dobj.name));
17029 
17030  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17031 
17032  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17033  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17034  ARCHIVE_OPTS(.tag = tag,
17035  .namespace = tbinfo->dobj.namespace->dobj.name,
17036  .tablespace = indxinfo->tablespace,
17037  .owner = tbinfo->rolname,
17038  .description = "CONSTRAINT",
17039  .section = SECTION_POST_DATA,
17040  .createStmt = q->data,
17041  .dropStmt = delq->data));
17042  }
17043  else if (coninfo->contype == 'f')
17044  {
17045  char *only;
17046 
17047  /*
17048  * Foreign keys on partitioned tables are always declared as
17049  * inheriting to partitions; for all other cases, emit them as
17050  * applying ONLY directly to the named table, because that's how they
17051  * work for regular inherited tables.
17052  */
17053  only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
17054 
17055  /*
17056  * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
17057  * current table data is not processed
17058  */
17059  appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
17060  only, fmtQualifiedDumpable(tbinfo));
17061  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17062  fmtId(coninfo->dobj.name),
17063  coninfo->condef);
17064 
17065  appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
17066  only, fmtQualifiedDumpable(tbinfo));
17067  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17068  fmtId(coninfo->dobj.name));
17069 
17070  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17071 
17072  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17073  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17074  ARCHIVE_OPTS(.tag = tag,
17075  .namespace = tbinfo->dobj.namespace->dobj.name,
17076  .owner = tbinfo->rolname,
17077  .description = "FK CONSTRAINT",
17078  .section = SECTION_POST_DATA,
17079  .createStmt = q->data,
17080  .dropStmt = delq->data));
17081  }
17082  else if (coninfo->contype == 'c' && tbinfo)
17083  {
17084  /* CHECK constraint on a table */
17085 
17086  /* Ignore if not to be dumped separately, or if it was inherited */
17087  if (coninfo->separate && coninfo->conislocal)
17088  {
17089  /* not ONLY since we want it to propagate to children */
17090  appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
17091  fmtQualifiedDumpable(tbinfo));
17092  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17093  fmtId(coninfo->dobj.name),
17094  coninfo->condef);
17095 
17096  appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
17097  fmtQualifiedDumpable(tbinfo));
17098  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17099  fmtId(coninfo->dobj.name));
17100 
17101  tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
17102 
17103  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17104  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17105  ARCHIVE_OPTS(.tag = tag,
17106  .namespace = tbinfo->dobj.namespace->dobj.name,
17107  .owner = tbinfo->rolname,
17108  .description = "CHECK CONSTRAINT",
17109  .section = SECTION_POST_DATA,
17110  .createStmt = q->data,
17111  .dropStmt = delq->data));
17112  }
17113  }
17114  else if (coninfo->contype == 'c' && tbinfo == NULL)
17115  {
17116  /* CHECK constraint on a domain */
17117  TypeInfo *tyinfo = coninfo->condomain;
17118 
17119  /* Ignore if not to be dumped separately */
17120  if (coninfo->separate)
17121  {
17122  appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
17123  fmtQualifiedDumpable(tyinfo));
17124  appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
17125  fmtId(coninfo->dobj.name),
17126  coninfo->condef);
17127 
17128  appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
17129  fmtQualifiedDumpable(tyinfo));
17130  appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
17131  fmtId(coninfo->dobj.name));
17132 
17133  tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
17134 
17135  if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17136  ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
17137  ARCHIVE_OPTS(.tag = tag,
17138  .namespace = tyinfo->dobj.namespace->dobj.name,
17139  .owner = tyinfo->rolname,
17140  .description = "CHECK CONSTRAINT",
17141  .section = SECTION_POST_DATA,
17142  .createStmt = q->data,
17143  .dropStmt = delq->data));
17144  }
17145  }
17146  else
17147  {
17148  pg_fatal("unrecognized constraint type: %c",
17149  coninfo->contype);
17150  }
17151 
17152  /* Dump Constraint Comments --- only works for table constraints */
17153  if (tbinfo && coninfo->separate &&
17154  coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17155  dumpTableConstraintComment(fout, coninfo);
17156 
17157  free(tag);
17158  destroyPQExpBuffer(q);
17159  destroyPQExpBuffer(delq);
17160 }
#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:5241
static const char * getAttrName(int attrnum, const TableInfo *tblInfo)
Definition: pg_dump.c:16597
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
Definition: pg_dump.c:18659
static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:17170
static bool nonemptyReloptions(const char *reloptions)
Definition: pg_dump.c:18647
TypeInfo * condomain
Definition: pg_dump.h:470
TableInfo * contable
Definition: pg_dump.h:469
bool condeferred
Definition: pg_dump.h:476
bool conislocal
Definition: pg_dump.h:477
DumpableObject dobj
Definition: pg_dump.h:468
DumpId conindex
Definition: pg_dump.h:474
bool condeferrable
Definition: pg_dump.h:475
char * condef
Definition: pg_dump.h:472
bool indisreplident
Definition: pg_dump.h:403
int indnkeyattrs
Definition: pg_dump.h:398
int indnattrs
Definition: pg_dump.h:399
Oid * indkeys
Definition: pg_dump.h:400
char * indreloptions
Definition: pg_dump.h:395
bool indisclustered
Definition: pg_dump.h:402
char * tablespace
Definition: pg_dump.h:394
bool indnullsnotdistinct
Definition: pg_dump.h:404
DumpableObject dobj
Definition: pg_dump.h:391

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::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, _dumpOptions::dataOnly, destroyPQExpBuffer(), _typeInfo::dobj, _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, dumpTableConstraintComment(), findObjectByDumpId(), fmtId(), fmtQualifiedDumpable, free, getAttrName(), if(), _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indkeys, _indxInfo::indnattrs, _indxInfo::indnkeyattrs, _indxInfo::indnullsnotdistinct, _indxInfo::indreloptions, InvalidAttrNumber, _dumpableObject::name, nonemptyReloptions(), CatalogId::oid, pg_fatal, psprintf(), _tableInfo::relkind, _typeInfo::rolname, _tableInfo::rolname, SECTION_POST_DATA, _constraintInfo::separate, and _indxInfo::tablespace.

Referenced by dumpDumpableObject().

◆ dumpConversion()

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

Definition at line 13821 of file pg_dump.c.

13822 {
13823  DumpOptions *dopt = fout->dopt;
13824  PQExpBuffer query;
13825  PQExpBuffer q;
13826  PQExpBuffer delq;
13827  char *qconvname;
13828  PGresult *res;
13829  int i_conforencoding;
13830  int i_contoencoding;
13831  int i_conproc;
13832  int i_condefault;
13833  const char *conforencoding;
13834  const char *contoencoding;
13835  const char *conproc;
13836  bool condefault;
13837 
13838  /* Do nothing in data-only dump */
13839  if (dopt->dataOnly)
13840  return;
13841 
13842  query = createPQExpBuffer();
13843  q = createPQExpBuffer();
13844  delq = createPQExpBuffer();
13845 
13846  qconvname = pg_strdup(fmtId(convinfo->dobj.name));
13847 
13848  /* Get conversion-specific details */
13849  appendPQExpBuffer(query, "SELECT "
13850  "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
13851  "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
13852  "conproc, condefault "
13853  "FROM pg_catalog.pg_conversion c "
13854  "WHERE c.oid = '%u'::pg_catalog.oid",
13855  convinfo->dobj.catId.oid);
13856 
13857  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13858 
13859  i_conforencoding = PQfnumber(res, "conforencoding");
13860  i_contoencoding = PQfnumber(res, "contoencoding");
13861  i_conproc = PQfnumber(res, "conproc");
13862  i_condefault = PQfnumber(res, "condefault");
13863 
13864  conforencoding = PQgetvalue(res, 0, i_conforencoding);
13865  contoencoding = PQgetvalue(res, 0, i_contoencoding);
13866  conproc = PQgetvalue(res, 0, i_conproc);
13867  condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
13868 
13869  appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
13870  fmtQualifiedDumpable(convinfo));
13871 
13872  appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
13873  (condefault) ? "DEFAULT " : "",
13874  fmtQualifiedDumpable(convinfo));
13875  appendStringLiteralAH(q, conforencoding, fout);
13876  appendPQExpBufferStr(q, " TO ");
13877  appendStringLiteralAH(q, contoencoding, fout);
13878  /* regproc output is already sufficiently quoted */
13879  appendPQExpBuffer(q, " FROM %s;\n", conproc);
13880 
13881  if (dopt->binary_upgrade)
13882  binary_upgrade_extension_member(q, &convinfo->dobj,
13883  "CONVERSION", qconvname,
13884  convinfo->dobj.namespace->dobj.name);
13885 
13886  if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13887  ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
13888  ARCHIVE_OPTS(.tag = convinfo->dobj.name,
13889  .namespace = convinfo->dobj.namespace->dobj.name,
13890  .owner = convinfo->rolname,
13891  .description = "CONVERSION",
13892  .section = SECTION_PRE_DATA,
13893  .createStmt = q->data,
13894  .dropStmt = delq->data));
13895 
13896  /* Dump Conversion Comments */
13897  if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13898  dumpComment(fout, "CONVERSION", qconvname,
13899  convinfo->dobj.namespace->dobj.name, convinfo->rolname,
13900  convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
13901 
13902  PQclear(res);
13903 
13904  destroyPQExpBuffer(query);
13905  destroyPQExpBuffer(q);
13906  destroyPQExpBuffer(delq);
13907  free(qconvname);
13908 }
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 3018 of file pg_dump.c.

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

3492 {
3493  PGconn *conn = GetConnection(AH);
3495  PGresult *res;
3496 
3497  /* First collect database-specific options */
3498  printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
3499  "WHERE setrole = 0 AND setdatabase = '%u'::oid",
3500  dboid);
3501 
3502  res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3503 
3504  for (int i = 0; i < PQntuples(res); i++)
3506  "DATABASE", dbname, NULL, NULL,
3507  outbuf);
3508 
3509  PQclear(res);
3510 
3511  /* Now look for role-and-database-specific options */
3512  printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
3513  "FROM pg_db_role_setting s, pg_roles r "
3514  "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
3515  dboid);
3516 
3517  res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3518 
3519  for (int i = 0; i < PQntuples(res); i++)
3521  "ROLE", PQgetvalue(res, i, 0),
3522  "DATABASE", dbname,
3523  outbuf);
3524 
3525  PQclear(res);
3526 
3528 }
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 14895 of file pg_dump.c.

14896 {
14897  DumpOptions *dopt = fout->dopt;
14898  PQExpBuffer q;
14899  PQExpBuffer tag;
14900  const char *type;
14901 
14902  /* Do nothing in data-only dump, or if we're skipping ACLs */
14903  if (dopt->dataOnly || dopt->aclsSkip)
14904  return;
14905 
14906  q = createPQExpBuffer();
14907  tag = createPQExpBuffer();
14908 
14909  switch (daclinfo->defaclobjtype)
14910  {
14911  case DEFACLOBJ_RELATION:
14912  type = "TABLES";
14913  break;
14914  case DEFACLOBJ_SEQUENCE:
14915  type = "SEQUENCES";
14916  break;
14917  case DEFACLOBJ_FUNCTION:
14918  type = "FUNCTIONS";
14919  break;
14920  case DEFACLOBJ_TYPE:
14921  type = "TYPES";
14922  break;
14923  case DEFACLOBJ_NAMESPACE:
14924  type = "SCHEMAS";
14925  break;
14926  default:
14927  /* shouldn't get here */
14928  pg_fatal("unrecognized object type in default privileges: %d",
14929  (int) daclinfo->defaclobjtype);
14930  type = ""; /* keep compiler quiet */
14931  }
14932 
14933  appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
14934 
14935  /* build the actual command(s) for this tuple */
14937  daclinfo->dobj.namespace != NULL ?
14938  daclinfo->dobj.namespace->dobj.name : NULL,
14939  daclinfo->dacl.acl,
14940  daclinfo->dacl.acldefault,
14941  daclinfo->defaclrole,
14942  fout->remoteVersion,
14943  q))
14944  pg_fatal("could not parse default ACL list (%s)",
14945  daclinfo->dacl.acl);
14946 
14947  if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
14948  ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
14949  ARCHIVE_OPTS(.tag = tag->data,
14950  .namespace = daclinfo->dobj.namespace ?
14951  daclinfo->dobj.namespace->dobj.name : NULL,
14952  .owner = daclinfo->defaclrole,
14953  .description = "DEFAULT ACL",
14954  .section = SECTION_POST_DATA,
14955  .createStmt = q->data));
14956 
14957  destroyPQExpBuffer(tag);
14958  destroyPQExpBuffer(q);
14959 }
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:573
DumpableAcl dacl
Definition: pg_dump.h:574
const char * defaclrole
Definition: pg_dump.h:575
char defaclobjtype
Definition: pg_dump.h:576

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

11337 {
11338  DumpOptions *dopt = fout->dopt;
11340  PQExpBuffer delq = createPQExpBuffer();
11341  PQExpBuffer query = createPQExpBuffer();
11342  PGresult *res;
11343  int i;
11344  char *qtypname;
11345  char *qualtypname;
11346  char *typnotnull;
11347  char *typdefn;
11348  char *typdefault;
11349  Oid typcollation;
11350  bool typdefault_is_literal = false;
11351 
11352  if (!fout->is_prepared[PREPQUERY_DUMPDOMAIN])
11353  {
11354  /* Set up query for domain-specific details */
11355  appendPQExpBufferStr(query,
11356  "PREPARE dumpDomain(pg_catalog.oid) AS\n");
11357 
11358  appendPQExpBufferStr(query, "SELECT t.typnotnull, "
11359  "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
11360  "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
11361  "t.typdefault, "
11362  "CASE WHEN t.typcollation <> u.typcollation "
11363  "THEN t.typcollation ELSE 0 END AS typcollation "
11364  "FROM pg_catalog.pg_type t "
11365  "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
11366  "WHERE t.oid = $1");
11367 
11368  ExecuteSqlStatement(fout, query->data);
11369 
11370  fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
11371  }
11372 
11373  printfPQExpBuffer(query,
11374  "EXECUTE dumpDomain('%u')",
11375  tyinfo->dobj.catId.oid);
11376 
11377  res = ExecuteSqlQueryForSingleRow(fout, query->data);
11378 
11379  typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
11380  typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
11381  if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
11382  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
11383  else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
11384  {
11385  typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
11386  typdefault_is_literal = true; /* it needs quotes */
11387  }
11388  else
11389  typdefault = NULL;
11390  typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
11391 
11392  if (dopt->binary_upgrade)
11394  tyinfo->dobj.catId.oid,
11395  true, /* force array type */
11396  false); /* force multirange type */
11397 
11398  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11399  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11400 
11402  "CREATE DOMAIN %s AS %s",
11403  qualtypname,
11404  typdefn);
11405 
11406  /* Print collation only if different from base type's collation */
11407  if (OidIsValid(typcollation))
11408  {
11409  CollInfo *coll;
11410 
11411  coll = findCollationByOid(typcollation);
11412  if (coll)
11413  appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
11414  }
11415 
11416  if (typnotnull[0] == 't')
11417  appendPQExpBufferStr(q, " NOT NULL");
11418 
11419  if (typdefault != NULL)
11420  {
11421  appendPQExpBufferStr(q, " DEFAULT ");
11422  if (typdefault_is_literal)
11423  appendStringLiteralAH(q, typdefault, fout);
11424  else
11425  appendPQExpBufferStr(q, typdefault);
11426  }
11427 
11428  PQclear(res);
11429 
11430  /*
11431  * Add any CHECK constraints for the domain
11432  */
11433  for (i = 0; i < tyinfo->nDomChecks; i++)
11434  {
11435  ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
11436 
11437  if (!domcheck->separate)
11438  appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
11439  fmtId(domcheck->dobj.name), domcheck->condef);
11440  }
11441 
11442  appendPQExpBufferStr(q, ";\n");
11443 
11444  appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
11445 
11446  if (dopt->binary_upgrade)
11448  "DOMAIN", qtypname,
11449  tyinfo->dobj.namespace->dobj.name);
11450 
11451  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11452  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11453  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11454  .namespace = tyinfo->dobj.namespace->dobj.name,
11455  .owner = tyinfo->rolname,
11456  .description = "DOMAIN",
11457  .section = SECTION_PRE_DATA,
11458  .createStmt = q->data,
11459  .dropStmt = delq->data));
11460 
11461  /* Dump Domain Comments and Security Labels */
11462  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11463  dumpComment(fout, "DOMAIN", qtypname,
11464  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11465  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11466 
11467  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11468  dumpSecLabel(fout, "DOMAIN", qtypname,
11469  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11470  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11471 
11472  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11473  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11474  qtypname, NULL,
11475  tyinfo->dobj.namespace->dobj.name,
11476  NULL, tyinfo->rolname, &tyinfo->dacl);
11477 
11478  /* Dump any per-constraint comments */
11479  for (i = 0; i < tyinfo->nDomChecks; i++)
11480  {
11481  ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
11482  PQExpBuffer conprefix = createPQExpBuffer();
11483 
11484  appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
11485  fmtId(domcheck->dobj.name));
11486 
11487  if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
11488  dumpComment(fout, conprefix->data, qtypname,
11489  tyinfo->dobj.namespace->dobj.name,
11490  tyinfo->rolname,
11491  domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
11492 
11493  destroyPQExpBuffer(conprefix);
11494  }
11495 
11496  destroyPQExpBuffer(q);
11497  destroyPQExpBuffer(delq);
11498  destroyPQExpBuffer(query);
11499  free(qtypname);
11500  free(qualtypname);
11501 }
@ 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 10296 of file pg_dump.c.

10297 {
10298  /*
10299  * Clear any dump-request bits for components that don't exist for this
10300  * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
10301  * request for every kind of object.)
10302  */
10303  dobj->dump &= dobj->components;
10304 
10305  /* Now, short-circuit if there's nothing to be done here. */
10306  if (dobj->dump == 0)
10307  return;
10308 
10309  switch (dobj->objType)
10310  {
10311  case DO_NAMESPACE:
10312  dumpNamespace(fout, (const NamespaceInfo *) dobj);
10313  break;
10314  case DO_EXTENSION:
10315  dumpExtension(fout, (const ExtensionInfo *) dobj);
10316  break;
10317  case DO_TYPE:
10318  dumpType(fout, (const TypeInfo *) dobj);
10319  break;
10320  case DO_SHELL_TYPE:
10321  dumpShellType(fout, (const ShellTypeInfo *) dobj);
10322  break;
10323  case DO_FUNC:
10324  dumpFunc(fout, (const FuncInfo *) dobj);
10325  break;
10326  case DO_AGG:
10327  dumpAgg(fout, (const AggInfo *) dobj);
10328  break;
10329  case DO_OPERATOR:
10330  dumpOpr(fout, (const OprInfo *) dobj);
10331  break;
10332  case DO_ACCESS_METHOD:
10333  dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
10334  break;
10335  case DO_OPCLASS:
10336  dumpOpclass(fout, (const OpclassInfo *) dobj);
10337  break;
10338  case DO_OPFAMILY:
10339  dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
10340  break;
10341  case DO_COLLATION:
10342  dumpCollation(fout, (const CollInfo *) dobj);
10343  break;
10344  case DO_CONVERSION:
10345  dumpConversion(fout, (const ConvInfo *) dobj);
10346  break;
10347  case DO_TABLE:
10348  dumpTable(fout, (const TableInfo *) dobj);
10349  break;
10350  case DO_TABLE_ATTACH:
10351  dumpTableAttach(fout, (const TableAttachInfo *) dobj);
10352  break;
10353  case DO_ATTRDEF:
10354  dumpAttrDef(fout, (const AttrDefInfo *) dobj);
10355  break;
10356  case DO_INDEX:
10357  dumpIndex(fout, (const IndxInfo *) dobj);
10358  break;
10359  case DO_INDEX_ATTACH:
10360  dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
10361  break;
10362  case DO_STATSEXT:
10363  dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
10364  break;
10365  case DO_REFRESH_MATVIEW:
10366  refreshMatViewData(fout, (const TableDataInfo *) dobj);
10367  break;
10368  case DO_RULE:
10369  dumpRule(fout, (const RuleInfo *) dobj);
10370  break;
10371  case DO_TRIGGER:
10372  dumpTrigger(fout, (const TriggerInfo *) dobj);
10373  break;
10374  case DO_EVENT_TRIGGER:
10375  dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
10376  break;
10377  case DO_CONSTRAINT:
10378  dumpConstraint(fout, (const ConstraintInfo *) dobj);
10379  break;
10380  case DO_FK_CONSTRAINT:
10381  dumpConstraint(fout, (const ConstraintInfo *) dobj);
10382  break;
10383  case DO_PROCLANG:
10384  dumpProcLang(fout, (const ProcLangInfo *) dobj);
10385  break;
10386  case DO_CAST:
10387  dumpCast(fout, (const CastInfo *) dobj);
10388  break;
10389  case DO_TRANSFORM:
10390  dumpTransform(fout, (const TransformInfo *) dobj);
10391  break;
10392  case DO_SEQUENCE_SET:
10393  dumpSequenceData(fout, (const TableDataInfo *) dobj);
10394  break;
10395  case DO_TABLE_DATA:
10396  dumpTableData(fout, (const TableDataInfo *) dobj);
10397  break;
10398  case DO_DUMMY_TYPE:
10399  /* table rowtypes and array types are never dumped separately */
10400  break;
10401  case DO_TSPARSER:
10402  dumpTSParser(fout, (const TSParserInfo *) dobj);
10403  break;
10404  case DO_TSDICT:
10405  dumpTSDictionary(fout, (const TSDictInfo *) dobj);
10406  break;
10407  case DO_TSTEMPLATE:
10408  dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
10409  break;
10410  case DO_TSCONFIG:
10411  dumpTSConfig(fout, (const TSConfigInfo *) dobj);
10412  break;
10413  case DO_FDW:
10414  dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
10415  break;
10416  case DO_FOREIGN_SERVER:
10417  dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
10418  break;
10419  case DO_DEFAULT_ACL:
10420  dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
10421  break;
10422  case DO_LARGE_OBJECT:
10423  dumpLO(fout, (const LoInfo *) dobj);
10424  break;
10425  case DO_LARGE_OBJECT_DATA:
10426  if (dobj->dump & DUMP_COMPONENT_DATA)
10427  {
10428  LoInfo *loinfo;
10429  TocEntry *te;
10430 
10431  loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
10432  if (loinfo == NULL)
10433  pg_fatal("missing metadata for large objects \"%s\"",
10434  dobj->name);
10435 
10436  te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
10437  ARCHIVE_OPTS(.tag = dobj->name,
10438  .owner = loinfo->rolname,
10439  .description = "BLOBS",
10440  .section = SECTION_DATA,
10441  .deps = dobj->dependencies,
10442  .nDeps = dobj->nDeps,
10443  .dumpFn = dumpLOs,
10444  .dumpArg = loinfo));
10445 
10446  /*
10447  * Set the TocEntry's dataLength in case we are doing a
10448  * parallel dump and want to order dump jobs by table size.
10449  * (We need some size estimate for every TocEntry with a
10450  * DataDumper function.) We don't currently have any cheap
10451  * way to estimate the size of LOs, but fortunately it doesn't
10452  * matter too much as long as we get large batches of LOs
10453  * processed reasonably early. Assume 8K per blob.
10454  */
10455  te->dataLength = loinfo->numlos * (pgoff_t) 8192;
10456  }
10457  break;
10458  case DO_POLICY:
10459  dumpPolicy(fout, (const PolicyInfo *) dobj);
10460  break;
10461  case DO_PUBLICATION:
10462  dumpPublication(fout, (const PublicationInfo *) dobj);
10463  break;
10464  case DO_PUBLICATION_REL:
10465  dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
10466  break;
10469  (const PublicationSchemaInfo *) dobj);
10470  break;
10471  case DO_SUBSCRIPTION:
10472  dumpSubscription(fout, (const SubscriptionInfo *) dobj);
10473  break;
10474  case DO_SUBSCRIPTION_REL:
10475  dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
10476  break;
10477  case DO_PRE_DATA_BOUNDARY:
10478  case DO_POST_DATA_BOUNDARY:
10479  /* never dumped, nothing to do */
10480  break;
10481  }
10482 }
@ SECTION_DATA
Definition: pg_backup.h:59
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:16536
static void dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
Definition: pg_dump.c:4617
static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
Definition: pg_dump.c:10489
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:12450
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:16626
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:14373
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:13949
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:17513
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15439
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:16806
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:16883
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:10694
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:16468
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:12996
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:12684
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:17463
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:12034
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:14701
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2622
static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
Definition: pg_dump.c:11804
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2734
static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
Definition: pg_dump.c:4302
static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
Definition: pg_dump.c:4086
static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
Definition: pg_dump.c:13345
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:14895
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:14453
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:16767
static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
Definition: pg_dump.c:5025
static void dumpTransform(Archive *fout, const TransformInfo *transform)
Definition: pg_dump.c:12555
static void dumpLO(Archive *fout, const LoInfo *loinfo)
Definition: pg_dump.c:3783
static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
Definition: pg_dump.c:4660
static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
Definition: pg_dump.c:14309
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:17724
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:10566
static int dumpLOs(Archive *fout, const void *arg)
Definition: pg_dump.c:3873
static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
Definition: pg_dump.c:5094
static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
Definition: pg_dump.c:17639
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:13821
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:14631
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:11850
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:14511
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:13564
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:13064
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:98
const char * rolname
Definition: pg_dump.h:591
int numlos
Definition: pg_dump.h:592
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 3534 of file pg_dump.c.

3535 {
3536  const char *encname = pg_encoding_to_char(AH->encoding);
3538 
3539  pg_log_info("saving encoding = %s", encname);
3540 
3541  appendPQExpBufferStr(qry, "SET client_encoding = ");
3542  appendStringLiteralAH(qry, encname, AH);
3543  appendPQExpBufferStr(qry, ";\n");
3544 
3546  ARCHIVE_OPTS(.tag = "ENCODING",
3547  .description = "ENCODING",
3548  .section = SECTION_PRE_DATA,
3549  .createStmt = qry->data));
3550 
3551  destroyPQExpBuffer(qry);
3552 }
#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 10725 of file pg_dump.c.

10726 {
10727  DumpOptions *dopt = fout->dopt;
10729  PQExpBuffer delq = createPQExpBuffer();
10730  PQExpBuffer query = createPQExpBuffer();
10731  PGresult *res;
10732  int num,
10733  i;
10734  Oid enum_oid;
10735  char *qtypname;
10736  char *qualtypname;
10737  char *label;
10738  int i_enumlabel;
10739  int i_oid;
10740 
10741  if (!fout->is_prepared[PREPQUERY_DUMPENUMTYPE])
10742  {
10743  /* Set up query for enum-specific details */
10744  appendPQExpBufferStr(query,
10745  "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
10746  "SELECT oid, enumlabel "
10747  "FROM pg_catalog.pg_enum "
10748  "WHERE enumtypid = $1 "
10749  "ORDER BY enumsortorder");
10750 
10751  ExecuteSqlStatement(fout, query->data);
10752 
10753  fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
10754  }
10755 
10756  printfPQExpBuffer(query,
10757  "EXECUTE dumpEnumType('%u')",
10758  tyinfo->dobj.catId.oid);
10759 
10760  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10761 
10762  num = PQntuples(res);
10763 
10764  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
10765  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
10766 
10767  /*
10768  * CASCADE shouldn't be required here as for normal types since the I/O
10769  * functions are generic and do not get dropped.
10770  */
10771  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
10772 
10773  if (dopt->binary_upgrade)
10775  tyinfo->dobj.catId.oid,
10776  false, false);
10777 
10778  appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
10779  qualtypname);
10780 
10781  if (!dopt->binary_upgrade)
10782  {
10783  i_enumlabel = PQfnumber(res, "enumlabel");
10784 
10785  /* Labels with server-assigned oids */
10786  for (i = 0; i < num; i++)
10787  {
10788  label = PQgetvalue(res, i, i_enumlabel);
10789  if (i > 0)
10790  appendPQExpBufferChar(q, ',');
10791  appendPQExpBufferStr(q, "\n ");
10792  appendStringLiteralAH(q, label, fout);
10793  }
10794  }
10795 
10796  appendPQExpBufferStr(q, "\n);\n");
10797 
10798  if (dopt->binary_upgrade)
10799  {
10800  i_oid = PQfnumber(res, "oid");
10801  i_enumlabel = PQfnumber(res, "enumlabel");
10802 
10803  /* Labels with dump-assigned (preserved) oids */
10804  for (i = 0; i < num; i++)
10805  {
10806  enum_oid = atooid(PQgetvalue(res, i, i_oid));
10807  label = PQgetvalue(res, i, i_enumlabel);
10808 
10809  if (i == 0)
10810  appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
10812  "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
10813  enum_oid);
10814  appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
10815  appendStringLiteralAH(q, label, fout);
10816  appendPQExpBufferStr(q, ";\n\n");
10817  }
10818  }
10819 
10820  if (dopt->binary_upgrade)
10822  "TYPE", qtypname,
10823  tyinfo->dobj.namespace->dobj.name);
10824 
10825  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10826  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
10827  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
10828  .namespace = tyinfo->dobj.namespace->dobj.name,
10829  .owner = tyinfo->rolname,
10830  .description = "TYPE",
10831  .section = SECTION_PRE_DATA,
10832  .createStmt = q->data,
10833  .dropStmt = delq->data));
10834 
10835  /* Dump Type Comments and Security Labels */
10836  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10837  dumpComment(fout, "TYPE", qtypname,
10838  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
10839  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10840 
10841  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10842  dumpSecLabel(fout, "TYPE", qtypname,
10843  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
10844  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10845 
10846  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10847  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
10848  qtypname, NULL,
10849  tyinfo->dobj.namespace->dobj.name,
10850  NULL, tyinfo->rolname, &tyinfo->dacl);
10851 
10852  PQclear(res);
10853  destroyPQExpBuffer(q);
10854  destroyPQExpBuffer(delq);
10855  destroyPQExpBuffer(query);
10856  free(qtypname);
10857  free(qualtypname);
10858 }
@ 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 17639 of file pg_dump.c.

17640 {
17641  DumpOptions *dopt = fout->dopt;
17642  PQExpBuffer query;
17643  PQExpBuffer delqry;
17644  char *qevtname;
17645 
17646  /* Do nothing in data-only dump */
17647  if (dopt->dataOnly)
17648  return;
17649 
17650  query = createPQExpBuffer();
17651  delqry = createPQExpBuffer();
17652 
17653  qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
17654 
17655  appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
17656  appendPQExpBufferStr(query, qevtname);
17657  appendPQExpBufferStr(query, " ON ");
17658  appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
17659 
17660  if (strcmp("", evtinfo->evttags) != 0)
17661  {
17662  appendPQExpBufferStr(query, "\n WHEN TAG IN (");
17663  appendPQExpBufferStr(query, evtinfo->evttags);
17664  appendPQExpBufferChar(query, ')');
17665  }
17666 
17667  appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
17668  appendPQExpBufferStr(query, evtinfo->evtfname);
17669  appendPQExpBufferStr(query, "();\n");
17670 
17671  if (evtinfo->evtenabled != 'O')
17672  {
17673  appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
17674  qevtname);
17675  switch (evtinfo->evtenabled)
17676  {
17677  case 'D':
17678  appendPQExpBufferStr(query, "DISABLE");
17679  break;
17680  case 'A':
17681  appendPQExpBufferStr(query, "ENABLE ALWAYS");
17682  break;
17683  case 'R':
17684  appendPQExpBufferStr(query, "ENABLE REPLICA");
17685  break;
17686  default:
17687  appendPQExpBufferStr(query, "ENABLE");
17688  break;
17689  }
17690  appendPQExpBufferStr(query, ";\n");
17691  }
17692 
17693  appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
17694  qevtname);
17695 
17696  if (dopt->binary_upgrade)
17697  binary_upgrade_extension_member(query, &evtinfo->dobj,
17698  "EVENT TRIGGER", qevtname, NULL);
17699 
17700  if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17701  ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
17702  ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
17703  .owner = evtinfo->evtowner,
17704  .description = "EVENT TRIGGER",
17705  .section = SECTION_POST_DATA,
17706  .createStmt = query->data,
17707  .dropStmt = delqry->data));
17708 
17709  if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17710  dumpComment(fout, "EVENT TRIGGER", qevtname,
17711  NULL, evtinfo->evtowner,
17712  evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
17713 
17714  destroyPQExpBuffer(query);
17715  destroyPQExpBuffer(delqry);
17716  free(qevtname);
17717 }
char * evtevent
Definition: pg_dump.h:451
char * evtfname
Definition: pg_dump.h:454
char evtenabled
Definition: pg_dump.h:455
const char * evtowner
Definition: pg_dump.h:452
char * evttags
Definition: pg_dump.h:453
DumpableObject dobj
Definition: pg_dump.h:449

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

10567 {
10568  DumpOptions *dopt = fout->dopt;
10569  PQExpBuffer q;
10570  PQExpBuffer delq;
10571  char *qextname;
10572 
10573  /* Do nothing in data-only dump */
10574  if (dopt->dataOnly)
10575  return;
10576 
10577  q = createPQExpBuffer();
10578  delq = createPQExpBuffer();
10579 
10580  qextname = pg_strdup(fmtId(extinfo->dobj.name));
10581 
10582  appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
10583 
10584  if (!dopt->binary_upgrade)
10585  {
10586  /*
10587  * In a regular dump, we simply create the extension, intentionally
10588  * not specifying a version, so that the destination installation's
10589  * default version is used.
10590  *
10591  * Use of IF NOT EXISTS here is unlike our behavior for other object
10592  * types; but there are various scenarios in which it's convenient to
10593  * manually create the desired extension before restoring, so we
10594  * prefer to allow it to exist already.
10595  */
10596  appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
10597  qextname, fmtId(extinfo->namespace));
10598  }
10599  else
10600  {
10601  /*
10602  * In binary-upgrade mode, it's critical to reproduce the state of the
10603  * database exactly, so our procedure is to create an empty extension,
10604  * restore all the contained objects normally, and add them to the
10605  * extension one by one. This function performs just the first of
10606  * those steps. binary_upgrade_extension_member() takes care of
10607  * adding member objects as they're created.
10608  */
10609  int i;
10610  int n;
10611 
10612  appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
10613 
10614  /*
10615  * We unconditionally create the extension, so we must drop it if it
10616  * exists. This could happen if the user deleted 'plpgsql' and then
10617  * readded it, causing its oid to be greater than g_last_builtin_oid.
10618  */
10619  appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
10620 
10622  "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
10623  appendStringLiteralAH(q, extinfo->dobj.name, fout);
10624  appendPQExpBufferStr(q, ", ");
10625  appendStringLiteralAH(q, extinfo->namespace, fout);
10626  appendPQExpBufferStr(q, ", ");
10627  appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
10628  appendStringLiteralAH(q, extinfo->extversion, fout);
10629  appendPQExpBufferStr(q, ", ");
10630 
10631  /*
10632  * Note that we're pushing extconfig (an OID array) back into
10633  * pg_extension exactly as-is. This is OK because pg_class OIDs are
10634  * preserved in binary upgrade.
10635  */
10636  if (strlen(extinfo->extconfig) > 2)
10637  appendStringLiteralAH(q, extinfo->extconfig, fout);
10638  else
10639  appendPQExpBufferStr(q, "NULL");
10640  appendPQExpBufferStr(q, ", ");
10641  if (strlen(extinfo->extcondition) > 2)
10642  appendStringLiteralAH(q, extinfo->extcondition, fout);
10643  else
10644  appendPQExpBufferStr(q, "NULL");
10645  appendPQExpBufferStr(q, ", ");
10646  appendPQExpBufferStr(q, "ARRAY[");
10647  n = 0;
10648  for (i = 0; i < extinfo->dobj.nDeps; i++)
10649  {
10650  DumpableObject *extobj;
10651 
10652  extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
10653  if (extobj && extobj->objType == DO_EXTENSION)
10654  {
10655  if (n++ > 0)
10656  appendPQExpBufferChar(q, ',');
10657  appendStringLiteralAH(q, extobj->name, fout);
10658  }
10659  }
10660  appendPQExpBufferStr(q, "]::pg_catalog.text[]");
10661  appendPQExpBufferStr(q, ");\n");
10662  }
10663 
10664  if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10665  ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
10666  ARCHIVE_OPTS(.tag = extinfo->dobj.name,
10667  .description = "EXTENSION",
10668  .section = SECTION_PRE_DATA,
10669  .createStmt = q->data,
10670  .dropStmt = delq->data));
10671 
10672  /* Dump Extension Comments and Security Labels */
10673  if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10674  dumpComment(fout, "EXTENSION", qextname,
10675  NULL, "",
10676  extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
10677 
10678  if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10679  dumpSecLabel(fout, "EXTENSION", qextname,
10680  NULL, "",
10681  extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
10682 
10683  free(qextname);
10684 
10685  destroyPQExpBuffer(q);
10686  destroyPQExpBuffer(delq);
10687 }
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 14631 of file pg_dump.c.

14632 {
14633  DumpOptions *dopt = fout->dopt;
14634  PQExpBuffer q;
14635  PQExpBuffer delq;
14636  char *qfdwname;
14637 
14638  /* Do nothing in data-only dump */
14639  if (dopt->dataOnly)
14640  return;
14641 
14642  q = createPQExpBuffer();
14643  delq = createPQExpBuffer();
14644 
14645  qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
14646 
14647  appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
14648  qfdwname);
14649 
14650  if (strcmp(fdwinfo->fdwhandler, "-") != 0)
14651  appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
14652 
14653  if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
14654  appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
14655 
14656  if (strlen(fdwinfo->fdwoptions) > 0)
14657  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
14658 
14659  appendPQExpBufferStr(q, ";\n");
14660 
14661  appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
14662  qfdwname);
14663 
14664  if (dopt->binary_upgrade)
14666  "FOREIGN DATA WRAPPER", qfdwname,
14667  NULL);
14668 
14669  if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14670  ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
14671  ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
14672  .owner = fdwinfo->rolname,
14673  .description = "FOREIGN DATA WRAPPER",
14674  .section = SECTION_PRE_DATA,
14675  .createStmt = q->data,
14676  .dropStmt = delq->data));
14677 
14678  /* Dump Foreign Data Wrapper Comments */
14679  if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14680  dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
14681  NULL, fdwinfo->rolname,
14682  fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
14683 
14684  /* Handle the ACL */
14685  if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14686  dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
14687  "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
14688  NULL, fdwinfo->rolname, &fdwinfo->dacl);
14689 
14690  free(qfdwname);
14691 
14692  destroyPQExpBuffer(q);
14693  destroyPQExpBuffer(delq);
14694 }
char * fdwhandler
Definition: pg_dump.h:555
const char * rolname
Definition: pg_dump.h:554
char * fdwvalidator
Definition: pg_dump.h:556
char * fdwoptions
Definition: pg_dump.h:557
DumpableAcl dacl
Definition: pg_dump.h:553
DumpableObject dobj
Definition: pg_dump.h:552

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

14702 {
14703  DumpOptions *dopt = fout->dopt;
14704  PQExpBuffer q;
14705  PQExpBuffer delq;
14706  PQExpBuffer query;
14707  PGresult *res;
14708  char *qsrvname;
14709  char *fdwname;
14710 
14711  /* Do nothing in data-only dump */
14712  if (dopt->dataOnly)
14713  return;
14714 
14715  q = createPQExpBuffer();
14716  delq = createPQExpBuffer();
14717  query = createPQExpBuffer();
14718 
14719  qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
14720 
14721  /* look up the foreign-data wrapper */
14722  appendPQExpBuffer(query, "SELECT fdwname "
14723  "FROM pg_foreign_data_wrapper w "
14724  "WHERE w.oid = '%u'",
14725  srvinfo->srvfdw);
14726  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14727  fdwname = PQgetvalue(res, 0, 0);
14728 
14729  appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
14730  if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
14731  {
14732  appendPQExpBufferStr(q, " TYPE ");
14733  appendStringLiteralAH(q, srvinfo->srvtype, fout);
14734  }
14735  if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
14736  {
14737  appendPQExpBufferStr(q, " VERSION ");
14738  appendStringLiteralAH(q, srvinfo->srvversion, fout);
14739  }
14740 
14741  appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
14742  appendPQExpBufferStr(q, fmtId(fdwname));
14743 
14744  if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
14745  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
14746 
14747  appendPQExpBufferStr(q, ";\n");
14748 
14749  appendPQExpBuffer(delq, "DROP SERVER %s;\n",
14750  qsrvname);
14751 
14752  if (dopt->binary_upgrade)
14754  "SERVER", qsrvname, NULL);
14755 
14756  if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14757  ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
14758  ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
14759  .owner = srvinfo->rolname,
14760  .description = "SERVER",
14761  .section = SECTION_PRE_DATA,
14762  .createStmt = q->data,
14763  .dropStmt = delq->data));
14764 
14765  /* Dump Foreign Server Comments */
14766  if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14767  dumpComment(fout, "SERVER", qsrvname,
14768  NULL, srvinfo->rolname,
14769  srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
14770 
14771  /* Handle the ACL */
14772  if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14773  dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
14774  "FOREIGN SERVER", qsrvname, NULL, NULL,
14775  NULL, srvinfo->rolname, &srvinfo->dacl);
14776 
14777  /* Dump user mappings */
14778  if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
14779  dumpUserMappings(fout,
14780  srvinfo->dobj.name, NULL,
14781  srvinfo->rolname,
14782  srvinfo->dobj.catId, srvinfo->dobj.dumpId);
14783 
14784  PQclear(res);
14785 
14786  free(qsrvname);
14787 
14788  destroyPQExpBuffer(q);
14789  destroyPQExpBuffer(delq);
14790  destroyPQExpBuffer(query);
14791 }
static void dumpUserMappings(Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
Definition: pg_dump.c:14801
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:103
DumpableAcl dacl
Definition: pg_dump.h:563
char * srvoptions
Definition: pg_dump.h:568
DumpableObject dobj
Definition: pg_dump.h:562
const char * rolname
Definition: pg_dump.h:564
char * srvversion
Definition: pg_dump.h:567

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

12035 {
12036  DumpOptions *dopt = fout->dopt;
12037  PQExpBuffer query;
12038  PQExpBuffer q;
12039  PQExpBuffer delqry;
12040  PQExpBuffer asPart;
12041  PGresult *res;
12042  char *funcsig; /* identity signature */
12043  char *funcfullsig = NULL; /* full signature */
12044  char *funcsig_tag;
12045  char *qual_funcsig;
12046  char *proretset;
12047  char *prosrc;
12048  char *probin;
12049  char *prosqlbody;
12050  char *funcargs;
12051  char *funciargs;
12052  char *funcresult;
12053  char *protrftypes;
12054  char *prokind;
12055  char *provolatile;
12056  char *proisstrict;
12057  char *prosecdef;
12058  char *proleakproof;
12059  char *proconfig;
12060  char *procost;
12061  char *prorows;
12062  char *prosupport;
12063  char *proparallel;
12064  char *lanname;
12065  char **configitems = NULL;
12066  int nconfigitems = 0;
12067  const char *keyword;
12068 
12069  /* Do nothing in data-only dump */
12070  if (dopt->dataOnly)
12071  return;
12072 
12073  query = createPQExpBuffer();
12074  q = createPQExpBuffer();
12075  delqry = createPQExpBuffer();
12076  asPart = createPQExpBuffer();
12077 
12078  if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
12079  {
12080  /* Set up query for function-specific details */
12081  appendPQExpBufferStr(query,
12082  "PREPARE dumpFunc(pg_catalog.oid) AS\n");
12083 
12084  appendPQExpBufferStr(query,
12085  "SELECT\n"
12086  "proretset,\n"
12087  "prosrc,\n"
12088  "probin,\n"
12089  "provolatile,\n"
12090  "proisstrict,\n"
12091  "prosecdef,\n"
12092  "lanname,\n"
12093  "proconfig,\n"
12094  "procost,\n"
12095  "prorows,\n"
12096  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
12097  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
12098  "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
12099  "proleakproof,\n");
12100 
12101  if (fout->remoteVersion >= 90500)
12102  appendPQExpBufferStr(query,
12103  "array_to_string(protrftypes, ' ') AS protrftypes,\n");
12104  else
12105  appendPQExpBufferStr(query,
12106  "NULL AS protrftypes,\n");
12107 
12108  if (fout->remoteVersion >= 90600)
12109  appendPQExpBufferStr(query,
12110  "proparallel,\n");
12111  else
12112  appendPQExpBufferStr(query,
12113  "'u' AS proparallel,\n");
12114 
12115  if (fout->remoteVersion >= 110000)
12116  appendPQExpBufferStr(query,
12117  "prokind,\n");
12118  else
12119  appendPQExpBufferStr(query,
12120  "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
12121 
12122  if (fout->remoteVersion >= 120000)
12123  appendPQExpBufferStr(query,
12124  "prosupport,\n");
12125  else
12126  appendPQExpBufferStr(query,
12127  "'-' AS prosupport,\n");
12128 
12129  if (fout->remoteVersion >= 140000)
12130  appendPQExpBufferStr(query,
12131  "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
12132  else
12133  appendPQExpBufferStr(query,
12134  "NULL AS prosqlbody\n");
12135 
12136  appendPQExpBufferStr(query,
12137  "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
12138  "WHERE p.oid = $1 "
12139  "AND l.oid = p.prolang");
12140 
12141  ExecuteSqlStatement(fout, query->data);
12142 
12143  fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
12144  }
12145 
12146  printfPQExpBuffer(query,
12147  "EXECUTE dumpFunc('%u')",
12148  finfo->dobj.catId.oid);
12149 
12150  res = ExecuteSqlQueryForSingleRow(fout, query->data);
12151 
12152  proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
12153  if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
12154  {
12155  prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
12156  probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
12157  prosqlbody = NULL;
12158  }
12159  else
12160  {
12161  prosrc = NULL;
12162  probin = NULL;
12163  prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
12164  }
12165  funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
12166  funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
12167  funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
12168  protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
12169  prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
12170  provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
12171  proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
12172  prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
12173  proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
12174  proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
12175  procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
12176  prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
12177  prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
12178  proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
12179  lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
12180 
12181  /*
12182  * See backend/commands/functioncmds.c for details of how the 'AS' clause
12183  * is used.
12184  */
12185  if (prosqlbody)
12186  {
12187  appendPQExpBufferStr(asPart, prosqlbody);
12188  }
12189  else if (probin[0] != '\0')
12190  {
12191  appendPQExpBufferStr(asPart, "AS ");
12192  appendStringLiteralAH(asPart, probin, fout);
12193  if (prosrc[0] != '\0')
12194  {
12195  appendPQExpBufferStr(asPart, ", ");
12196 
12197  /*
12198  * where we have bin, use dollar quoting if allowed and src
12199  * contains quote or backslash; else use regular quoting.
12200  */
12201  if (dopt->disable_dollar_quoting ||
12202  (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
12203  appendStringLiteralAH(asPart, prosrc, fout);
12204  else
12205  appendStringLiteralDQ(asPart, prosrc, NULL);
12206  }
12207  }
12208  else
12209  {
12210  appendPQExpBufferStr(asPart, "AS ");
12211  /* with no bin, dollar quote src unconditionally if allowed */
12212  if (dopt->disable_dollar_quoting)
12213  appendStringLiteralAH(asPart, prosrc, fout);
12214  else
12215  appendStringLiteralDQ(asPart, prosrc, NULL);
12216  }
12217 
12218  if (*proconfig)
12219  {
12220  if (!parsePGArray(proconfig, &configitems, &nconfigitems))
12221  pg_fatal("could not parse %s array", "proconfig");
12222  }
12223  else
12224  {
12225  configitems = NULL;
12226  nconfigitems = 0;
12227  }
12228 
12229  funcfullsig = format_function_arguments(finfo, funcargs, false);
12230  funcsig = format_function_arguments(finfo, funciargs, false);
12231 
12232  funcsig_tag = format_function_signature(fout, finfo, false);
12233 
12234  qual_funcsig = psprintf("%s.%s",
12235  fmtId(finfo->dobj.namespace->dobj.name),
12236  funcsig);
12237 
12238  if (prokind[0] == PROKIND_PROCEDURE)
12239  keyword = "PROCEDURE";
12240  else
12241  keyword = "FUNCTION"; /* works for window functions too */
12242 
12243  appendPQExpBuffer(delqry, "DROP %s %s;\n",
12244  keyword, qual_funcsig);
12245 
12246  appendPQExpBuffer(q, "CREATE %s %s.%s",
12247  keyword,
12248  fmtId(finfo->dobj.namespace->dobj.name),
12249  funcfullsig ? funcfullsig :
12250  funcsig);
12251 
12252  if (prokind[0] == PROKIND_PROCEDURE)
12253  /* no result type to output */ ;
12254  else if (funcresult)
12255  appendPQExpBuffer(q, " RETURNS %s", funcresult);
12256  else
12257  appendPQExpBuffer(q, " RETURNS %s%s",
12258  (proretset[0] == 't') ? "SETOF " : "",
12259  getFormattedTypeName(fout, finfo->prorettype,
12260  zeroIsError));
12261 
12262  appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
12263 
12264  if (*protrftypes)
12265  {
12266  Oid *typeids = palloc(FUNC_MAX_ARGS * sizeof(Oid));
12267  int i;
12268 
12269  appendPQExpBufferStr(q, " TRANSFORM ");
12270  parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
12271  for (i = 0; typeids[i]; i++)
12272  {
12273  if (i != 0)
12274  appendPQExpBufferStr(q, ", ");
12275  appendPQExpBuffer(q, "FOR TYPE %s",
12276  getFormattedTypeName(fout, typeids[i], zeroAsNone));
12277  }
12278  }
12279 
12280  if (prokind[0] == PROKIND_WINDOW)
12281  appendPQExpBufferStr(q, " WINDOW");
12282 
12283  if (provolatile[0] != PROVOLATILE_VOLATILE)
12284  {
12285  if (provolatile[0] == PROVOLATILE_IMMUTABLE)
12286  appendPQExpBufferStr(q, " IMMUTABLE");
12287  else if (provolatile[0] == PROVOLATILE_STABLE)
12288  appendPQExpBufferStr(q, " STABLE");
12289  else if (provolatile[0] != PROVOLATILE_VOLATILE)
12290  pg_fatal("unrecognized provolatile value for function \"%s\"",
12291  finfo->dobj.name);
12292  }
12293 
12294  if (proisstrict[0] == 't')
12295  appendPQExpBufferStr(q, " STRICT");
12296 
12297  if (prosecdef[0] == 't')
12298  appendPQExpBufferStr(q, " SECURITY DEFINER");
12299 
12300  if (proleakproof[0] == 't')
12301  appendPQExpBufferStr(q, " LEAKPROOF");
12302 
12303  /*
12304  * COST and ROWS are emitted only if present and not default, so as not to
12305  * break backwards-compatibility of the dump without need. Keep this code
12306  * in sync with the defaults in functioncmds.c.
12307  */
12308  if (strcmp(procost, "0") != 0)
12309  {
12310  if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
12311  {
12312  /* default cost is 1 */
12313  if (strcmp(procost, "1") != 0)
12314  appendPQExpBuffer(q, " COST %s", procost);
12315  }
12316  else
12317  {
12318  /* default cost is 100 */
12319  if (strcmp(procost, "100") != 0)
12320  appendPQExpBuffer(q, " COST %s", procost);
12321  }
12322  }
12323  if (proretset[0] == 't' &&
12324  strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
12325  appendPQExpBuffer(q, " ROWS %s", prorows);
12326 
12327  if (strcmp(prosupport, "-") != 0)
12328  {
12329  /* We rely on regprocout to provide quoting and qualification */
12330  appendPQExpBuffer(q, " SUPPORT %s", prosupport);
12331  }
12332 
12333  if (proparallel[0] != PROPARALLEL_UNSAFE)
12334  {
12335  if (proparallel[0] == PROPARALLEL_SAFE)
12336  appendPQExpBufferStr(q, " PARALLEL SAFE");
12337  else if (proparallel[0] == PROPARALLEL_RESTRICTED)
12338  appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
12339  else if (proparallel[0] != PROPARALLEL_UNSAFE)
12340  pg_fatal("unrecognized proparallel value for function \"%s\"",
12341  finfo->dobj.name);
12342  }
12343 
12344  for (int i = 0; i < nconfigitems; i++)
12345  {
12346  /* we feel free to scribble on configitems[] here */
12347  char *configitem = configitems[i];
12348  char *pos;
12349 
12350  pos = strchr(configitem, '=');
12351  if (pos == NULL)
12352  continue;
12353  *pos++ = '\0';
12354  appendPQExpBuffer(q, "\n SET %s TO ", fmtId(configitem));
12355 
12356  /*
12357  * Variables that are marked GUC_LIST_QUOTE were already fully quoted
12358  * by flatten_set_variable_args() before they were put into the
12359  * proconfig array. However, because the quoting rules used there
12360  * aren't exactly like SQL's, we have to break the list value apart
12361  * and then quote the elements as string literals. (The elements may
12362  * be double-quoted as-is, but we can't just feed them to the SQL
12363  * parser; it would do the wrong thing with elements that are
12364  * zero-length or longer than NAMEDATALEN.)
12365  *
12366  * Variables that are not so marked should just be emitted as simple
12367  * string literals. If the variable is not known to
12368  * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
12369  * to use GUC_LIST_QUOTE for extension variables.
12370  */
12371  if (variable_is_guc_list_quote(configitem))
12372  {
12373  char **namelist;
12374  char **nameptr;
12375 
12376  /* Parse string into list of identifiers */
12377  /* this shouldn't fail really */
12378  if (SplitGUCList(pos, ',', &namelist))
12379  {
12380  for (nameptr = namelist; *nameptr; nameptr++)
12381  {
12382  if (nameptr != namelist)
12383  appendPQExpBufferStr(q, ", ");
12384  appendStringLiteralAH(q, *nameptr, fout);
12385  }
12386  }
12387  pg_free(namelist);
12388  }
12389  else
12390  appendStringLiteralAH(q, pos, fout);
12391  }
12392 
12393  appendPQExpBuffer(q, "\n %s;\n", asPart->data);
12394 
12395  append_depends_on_extension(fout, q, &finfo->dobj,
12396  "pg_catalog.pg_proc", keyword,
12397  qual_funcsig);
12398 
12399  if (dopt->binary_upgrade)
12401  keyword, funcsig,
12402  finfo->dobj.namespace->dobj.name);
12403 
12404  if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12405  ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
12406  ARCHIVE_OPTS(.tag = funcsig_tag,
12407  .namespace = finfo->dobj.namespace->dobj.name,
12408  .owner = finfo->rolname,
12409  .description = keyword,
12410  .section = finfo->postponed_def ?
12412  .createStmt = q->data,
12413  .dropStmt = delqry->data));
12414 
12415  /* Dump Function Comments and Security Labels */
12416  if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12417  dumpComment(fout, keyword, funcsig,
12418  finfo->dobj.namespace->dobj.name, finfo->rolname,
12419  finfo->dobj.catId, 0, finfo->dobj.dumpId);
12420 
12421  if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12422  dumpSecLabel(fout, keyword, funcsig,
12423  finfo->dobj.namespace->dobj.name, finfo->rolname,
12424  finfo->dobj.catId, 0, finfo->dobj.dumpId);
12425 
12426  if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
12427  dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
12428  funcsig, NULL,
12429  finfo->dobj.namespace->dobj.name,
12430  NULL, finfo->rolname, &finfo->dacl);
12431 
12432  PQclear(res);
12433 
12434  destroyPQExpBuffer(query);
12435  destroyPQExpBuffer(q);
12436  destroyPQExpBuffer(delqry);
12437  destroyPQExpBuffer(asPart);
12438  free(funcsig);
12439  free(funcfullsig);
12440  free(funcsig_tag);
12441  free(qual_funcsig);
12442  free(configitems);
12443 }
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1058
bool variable_is_guc_list_quote(const char *name)
Definition: dumputils.c:689
void * palloc(Size size)
Definition: mcxt.c:1317
@ PREPQUERY_DUMPFUNC
Definition: pg_backup.h:71
#define FUNC_MAX_ARGS
bool parsePGArray(const char *atext, char ***itemarray, int *nitems)
Definition: string_utils.c:657
void appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
Definition: string_utils.c:331
int disable_dollar_quoting
Definition: pg_backup.h: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 16626 of file pg_dump.c.

16627 {
16628  DumpOptions *dopt = fout->dopt;
16629  TableInfo *tbinfo = indxinfo->indextable;
16630  bool is_constraint = (indxinfo->indexconstraint != 0);
16631  PQExpBuffer q;
16632  PQExpBuffer delq;
16633  char *qindxname;
16634  char *qqindxname;
16635 
16636  /* Do nothing in data-only dump */
16637  if (dopt->dataOnly)
16638  return;
16639 
16640  q = createPQExpBuffer();
16641  delq = createPQExpBuffer();
16642 
16643  qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16644  qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
16645 
16646  /*
16647  * If there's an associated constraint, don't dump the index per se, but
16648  * do dump any comment for it. (This is safe because dependency ordering
16649  * will have ensured the constraint is emitted first.) Note that the
16650  * emitted comment has to be shown as depending on the constraint, not the
16651  * index, in such cases.
16652  */
16653  if (!is_constraint)
16654  {
16655  char *indstatcols = indxinfo->indstatcols;
16656  char *indstatvals = indxinfo->indstatvals;
16657  char **indstatcolsarray = NULL;
16658  char **indstatvalsarray = NULL;
16659  int nstatcols = 0;
16660  int nstatvals = 0;
16661 
16662  if (dopt->binary_upgrade)
16664  indxinfo->dobj.catId.oid);
16665 
16666  /* Plain secondary index */
16667  appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
16668 
16669  /*
16670  * Append ALTER TABLE commands as needed to set properties that we
16671  * only have ALTER TABLE syntax for. Keep this in sync with the
16672  * similar code in dumpConstraint!
16673  */
16674 
16675  /* If the index is clustered, we need to record that. */
16676  if (indxinfo->indisclustered)
16677  {
16678  appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
16679  fmtQualifiedDumpable(tbinfo));
16680  /* index name is not qualified in this syntax */
16681  appendPQExpBuffer(q, " ON %s;\n",
16682  qindxname);
16683  }
16684 
16685  /*
16686  * If the index has any statistics on some of its columns, generate
16687  * the associated ALTER INDEX queries.
16688  */
16689  if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
16690  {
16691  int j;
16692 
16693  if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
16694  pg_fatal("could not parse index statistic columns");
16695  if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
16696  pg_fatal("could not parse index statistic values");
16697  if (nstatcols != nstatvals)
16698  pg_fatal("mismatched number of columns and values for index statistics");
16699 
16700  for (j = 0; j < nstatcols; j++)
16701  {
16702  appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
16703 
16704  /*
16705  * Note that this is a column number, so no quotes should be
16706  * used.
16707  */
16708  appendPQExpBuffer(q, "ALTER COLUMN %s ",
16709  indstatcolsarray[j]);
16710  appendPQExpBuffer(q, "SET STATISTICS %s;\n",
16711  indstatvalsarray[j]);
16712  }
16713  }
16714 
16715  /* Indexes can depend on extensions */
16716  append_depends_on_extension(fout, q, &indxinfo->dobj,
16717  "pg_catalog.pg_class",
16718  "INDEX", qqindxname);
16719 
16720  /* If the index defines identity, we need to record that. */
16721  if (indxinfo->indisreplident)
16722  {
16723  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
16724  fmtQualifiedDumpable(tbinfo));
16725  /* index name is not qualified in this syntax */
16726  appendPQExpBuffer(q, " INDEX %s;\n",
16727  qindxname);
16728  }
16729 
16730  appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
16731 
16732  if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16733  ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
16734  ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
16735  .namespace = tbinfo->dobj.namespace->dobj.name,
16736  .tablespace = indxinfo->tablespace,
16737  .owner = tbinfo->rolname,
16738  .description = "INDEX",
16739  .section = SECTION_POST_DATA,
16740  .createStmt = q->data,
16741  .dropStmt = delq->data));
16742 
16743  free(indstatcolsarray);
16744  free(indstatvalsarray);
16745  }
16746 
16747  /* Dump Index Comments */
16748  if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16749  dumpComment(fout, "INDEX", qindxname,
16750  tbinfo->dobj.namespace->dobj.name,
16751  tbinfo->rolname,
16752  indxinfo->dobj.catId, 0,
16753  is_constraint ? indxinfo->indexconstraint :
16754  indxinfo->dobj.dumpId);
16755 
16756  destroyPQExpBuffer(q);
16757  destroyPQExpBuffer(delq);
16758  free(qindxname);
16759  free(qqindxname);
16760 }
char * indstatvals
Definition: pg_dump.h:397
char * indstatcols
Definition: pg_dump.h:396
TableInfo * indextable
Definition: pg_dump.h:392
DumpId indexconstraint
Definition: pg_dump.h:409
char * indexdef
Definition: pg_dump.h:393

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

16768 {
16769  /* Do nothing in data-only dump */
16770  if (fout->dopt->dataOnly)
16771  return;
16772 
16773  if (attachinfo->partitionIdx->dobj.dump & DUMP_COMPONENT_DEFINITION)
16774  {
16776 
16777  appendPQExpBuffer(q, "ALTER INDEX %s ",
16778  fmtQualifiedDumpable(attachinfo->parentIdx));
16779  appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
16780  fmtQualifiedDumpable(attachinfo->partitionIdx));
16781 
16782  /*
16783  * There is no point in creating a drop query as the drop is done by
16784  * index drop. (If you think to change this, see also
16785  * _printTocEntry().) Although this object doesn't really have
16786  * ownership as such, set the owner field anyway to ensure that the
16787  * command is run by the correct role at restore time.
16788  */
16789  ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
16790  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
16791  .namespace = attachinfo->dobj.namespace->dobj.name,
16792  .owner = attachinfo->parentIdx->indextable->rolname,
16793  .description = "INDEX ATTACH",
16794  .section = SECTION_POST_DATA,
16795  .createStmt = q->data));
16796 
16797  destroyPQExpBuffer(q);
16798  }
16799 }
IndxInfo * parentIdx
Definition: pg_dump.h:415

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

3784 {
3785  PQExpBuffer cquery = createPQExpBuffer();
3786 
3787  /*
3788  * The "definition" is just a newline-separated list of OIDs. We need to
3789  * put something into the dropStmt too, but it can just be a comment.
3790  */
3791  for (int i = 0; i < loinfo->numlos; i++)
3792  appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
3793 
3794  if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
3795  ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
3796  ARCHIVE_OPTS(.tag = loinfo->dobj.name,
3797  .owner = loinfo->rolname,
3798  .description = "BLOB METADATA",
3799  .section = SECTION_DATA,
3800  .createStmt = cquery->data,
3801  .dropStmt = "-- dummy"));
3802 
3803  /*
3804  * Dump per-blob comments and seclabels if any. We assume these are rare
3805  * enough that it's okay to generate retail TOC entries for them.
3806  */
3807  if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
3809  {
3810  for (int i = 0; i < loinfo->numlos; i++)
3811  {
3812  CatalogId catId;
3813  char namebuf[32];
3814 
3815  /* Build identifying info for this blob */
3816  catId.tableoid = loinfo->dobj.catId.tableoid;
3817  catId.oid = loinfo->looids[i];
3818  snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
3819 
3820  if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
3821  dumpComment(fout, "LARGE OBJECT", namebuf,
3822  NULL, loinfo->rolname,
3823  catId, 0, loinfo->dobj.dumpId);
3824 
3825  if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
3826  dumpSecLabel(fout, "LARGE OBJECT", namebuf,
3827  NULL, loinfo->rolname,
3828  catId, 0, loinfo->dobj.dumpId);
3829  }
3830  }
3831 
3832  /*
3833  * Dump the ACLs if any (remember that all blobs in the group will have
3834  * the same ACL). If there's just one blob, dump a simple ACL entry; if
3835  * there's more, make a "LARGE OBJECTS" entry that really contains only
3836  * the ACL for the first blob. _printTocEntry() will be cued by the tag
3837  * string to emit a mutated version for each blob.
3838  */
3839  if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
3840  {
3841  char namebuf[32];
3842 
3843  /* Build identifying info for the first blob */
3844  snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
3845 
3846  if (loinfo->numlos > 1)
3847  {
3848  char tagbuf[64];
3849 
3850  snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
3851  loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
3852 
3853  dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
3854  "LARGE OBJECT", namebuf, NULL, NULL,
3855  tagbuf, loinfo->rolname, &loinfo->dacl);
3856  }
3857  else
3858  {
3859  dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
3860  "LARGE OBJECT", namebuf, NULL, NULL,
3861  NULL, loinfo->rolname, &loinfo->dacl);
3862  }
3863  }
3864 
3865  destroyPQExpBuffer(cquery);
3866 }
DumpableObject dobj
Definition: pg_dump.h:589
DumpableAcl dacl
Definition: pg_dump.h:590
Oid looids[FLEXIBLE_ARRAY_MEMBER]
Definition: pg_dump.h:593

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

3874 {
3875  const LoInfo *loinfo = (const LoInfo *) arg;
3876  PGconn *conn = GetConnection(fout);
3877  char buf[LOBBUFSIZE];
3878 
3879  pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
3880 
3881  for (int i = 0; i < loinfo->numlos; i++)
3882  {
3883  Oid loOid = loinfo->looids[i];
3884  int loFd;
3885  int cnt;
3886 
3887  /* Open the LO */
3888  loFd = lo_open(conn, loOid, INV_READ);
3889  if (loFd == -1)
3890  pg_fatal("could not open large object %u: %s",
3891  loOid, PQerrorMessage(conn));
3892 
3893  StartLO(fout, loOid);
3894 
3895  /* Now read it in chunks, sending data to archive */
3896  do
3897  {
3898  cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
3899  if (cnt < 0)
3900  pg_fatal("error reading large object %u: %s",
3901  loOid, PQerrorMessage(conn));
3902 
3903  WriteData(fout, buf, cnt);
3904  } while (cnt > 0);
3905 
3906  lo_close(conn, loFd);
3907 
3908  EndLO(fout, loOid);
3909  }
3910 
3911  return 1;
3912 }
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:154
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7171
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 10489 of file pg_dump.c.

10490 {
10491  DumpOptions *dopt = fout->dopt;
10492  PQExpBuffer q;
10493  PQExpBuffer delq;
10494  char *qnspname;
10495 
10496  /* Do nothing in data-only dump */
10497  if (dopt->dataOnly)
10498  return;
10499 
10500  q = createPQExpBuffer();
10501  delq = createPQExpBuffer();
10502 
10503  qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
10504 
10505  if (nspinfo->create)
10506  {
10507  appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
10508  appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
10509  }
10510  else
10511  {
10512  /* see selectDumpableNamespace() */
10513  appendPQExpBufferStr(delq,
10514  "-- *not* dropping schema, since initdb creates it\n");
10516  "-- *not* creating schema, since initdb creates it\n");
10517  }
10518 
10519  if (dopt->binary_upgrade)
10521  "SCHEMA", qnspname, NULL);
10522 
10523  if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10524  ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
10525  ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
10526  .owner = nspinfo->rolname,
10527  .description = "SCHEMA",
10528  .section = SECTION_PRE_DATA,
10529  .createStmt = q->data,
10530  .dropStmt = delq->data));
10531 
10532  /* Dump Schema Comments and Security Labels */
10533  if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10534  {
10535  const char *initdb_comment = NULL;
10536 
10537  if (!nspinfo->create && strcmp(qnspname, "public") == 0)
10538  initdb_comment = "standard public schema";
10539  dumpCommentExtended(fout, "SCHEMA", qnspname,
10540  NULL, nspinfo->rolname,
10541  nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
10542  initdb_comment);
10543  }
10544 
10545  if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10546  dumpSecLabel(fout, "SCHEMA", qnspname,
10547  NULL, nspinfo->rolname,
10548  nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10549 
10550  if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10551  dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
10552  qnspname, NULL, NULL,
10553  NULL, nspinfo->rolname, &nspinfo->dacl);
10554 
10555  free(qnspname);
10556 
10557  destroyPQExpBuffer(q);
10558  destroyPQExpBuffer(delq);
10559 }
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 13064 of file pg_dump.c.

13065 {
13066  DumpOptions *dopt = fout->dopt;
13067  PQExpBuffer query;
13068  PQExpBuffer q;
13069  PQExpBuffer delq;
13070  PQExpBuffer nameusing;
13071  PGresult *res;
13072  int ntups;
13073  int i_opcintype;
13074  int i_opckeytype;
13075  int i_opcdefault;
13076  int i_opcfamily;
13077  int i_opcfamilyname;
13078  int i_opcfamilynsp;
13079  int i_amname;
13080  int i_amopstrategy;
13081  int i_amopopr;
13082  int i_sortfamily;
13083  int i_sortfamilynsp;
13084  int i_amprocnum;
13085  int i_amproc;
13086  int i_amproclefttype;
13087  int i_amprocrighttype;
13088  char *opcintype;
13089  char *opckeytype;
13090  char *opcdefault;
13091  char *opcfamily;
13092  char *opcfamilyname;
13093  char *opcfamilynsp;
13094  char *amname;
13095  char *amopstrategy;
13096  char *amopopr;
13097  char *sortfamily;
13098  char *sortfamilynsp;
13099  char *amprocnum;
13100  char *amproc;
13101  char *amproclefttype;
13102  char *amprocrighttype;
13103  bool needComma;
13104  int i;
13105 
13106  /* Do nothing in data-only dump */
13107  if (dopt->dataOnly)
13108  return;
13109 
13110  query = createPQExpBuffer();
13111  q = createPQExpBuffer();
13112  delq = createPQExpBuffer();
13113  nameusing = createPQExpBuffer();
13114 
13115  /* Get additional fields from the pg_opclass row */
13116  appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
13117  "opckeytype::pg_catalog.regtype, "
13118  "opcdefault, opcfamily, "
13119  "opfname AS opcfamilyname, "
13120  "nspname AS opcfamilynsp, "
13121  "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
13122  "FROM pg_catalog.pg_opclass c "
13123  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
13124  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
13125  "WHERE c.oid = '%u'::pg_catalog.oid",
13126  opcinfo->dobj.catId.oid);
13127 
13128  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13129 
13130  i_opcintype = PQfnumber(res, "opcintype");
13131  i_opckeytype = PQfnumber(res, "opckeytype");
13132  i_opcdefault = PQfnumber(res, "opcdefault");
13133  i_opcfamily = PQfnumber(res, "opcfamily");
13134  i_opcfamilyname = PQfnumber(res, "opcfamilyname");
13135  i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
13136  i_amname = PQfnumber(res, "amname");
13137 
13138  /* opcintype may still be needed after we PQclear res */
13139  opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
13140  opckeytype = PQgetvalue(res, 0, i_opckeytype);
13141  opcdefault = PQgetvalue(res, 0, i_opcdefault);
13142  /* opcfamily will still be needed after we PQclear res */
13143  opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
13144  opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
13145  opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
13146  /* amname will still be needed after we PQclear res */
13147  amname = pg_strdup(PQgetvalue(res, 0, i_amname));
13148 
13149  appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
13150  fmtQualifiedDumpable(opcinfo));
13151  appendPQExpBuffer(delq, " USING %s;\n",
13152  fmtId(amname));
13153 
13154  /* Build the fixed portion of the CREATE command */
13155  appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n ",
13156  fmtQualifiedDumpable(opcinfo));
13157  if (strcmp(opcdefault, "t") == 0)
13158  appendPQExpBufferStr(q, "DEFAULT ");
13159  appendPQExpBuffer(q, "FOR TYPE %s USING %s",
13160  opcintype,
13161  fmtId(amname));
13162  if (strlen(opcfamilyname) > 0)
13163  {
13164  appendPQExpBufferStr(q, " FAMILY ");
13165  appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
13166  appendPQExpBufferStr(q, fmtId(opcfamilyname));
13167  }
13168  appendPQExpBufferStr(q, " AS\n ");
13169 
13170  needComma = false;
13171 
13172  if (strcmp(opckeytype, "-") != 0)
13173  {
13174  appendPQExpBuffer(q, "STORAGE %s",
13175  opckeytype);
13176  needComma = true;
13177  }
13178 
13179  PQclear(res);
13180 
13181  /*
13182  * Now fetch and print the OPERATOR entries (pg_amop rows).
13183  *
13184  * Print only those opfamily members that are tied to the opclass by
13185  * pg_depend entries.
13186  */
13187  resetPQExpBuffer(query);
13188  appendPQExpBuffer(query, "SELECT amopstrategy, "
13189  "amopopr::pg_catalog.regoperator, "
13190  "opfname AS sortfamily, "
13191  "nspname AS sortfamilynsp "
13192  "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
13193  "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
13194  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
13195  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
13196  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
13197  "AND refobjid = '%u'::pg_catalog.oid "
13198  "AND amopfamily = '%s'::pg_catalog.oid "
13199  "ORDER BY amopstrategy",
13200  opcinfo->dobj.catId.oid,
13201  opcfamily);
13202 
13203  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13204 
13205  ntups = PQntuples(res);
13206 
13207  i_amopstrategy = PQfnumber(res, "amopstrategy");
13208  i_amopopr = PQfnumber(res, "amopopr");
13209  i_sortfamily = PQfnumber(res, "sortfamily");
13210  i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
13211 
13212  for (i = 0; i < ntups; i++)
13213  {
13214  amopstrategy = PQgetvalue(res, i, i_amopstrategy);
13215  amopopr = PQgetvalue(res, i, i_amopopr);
13216  sortfamily = PQgetvalue(res, i, i_sortfamily);
13217  sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
13218 
13219  if (needComma)
13220  appendPQExpBufferStr(q, " ,\n ");
13221 
13222  appendPQExpBuffer(q, "OPERATOR %s %s",
13223  amopstrategy, amopopr);
13224 
13225  if (strlen(sortfamily) > 0)
13226  {
13227  appendPQExpBufferStr(q, " FOR ORDER BY ");
13228  appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
13229  appendPQExpBufferStr(q, fmtId(sortfamily));
13230  }
13231 
13232  needComma = true;
13233  }
13234 
13235  PQclear(res);
13236 
13237  /*
13238  * Now fetch and print the FUNCTION entries (pg_amproc rows).
13239  *
13240  * Print only those opfamily members that are tied to the opclass by
13241  * pg_depend entries.
13242  *
13243  * We print the amproclefttype/amprocrighttype even though in most cases
13244  * the backend could deduce the right values, because of the corner case
13245  * of a btree sort support function for a cross-type comparison.
13246  */
13247  resetPQExpBuffer(query);
13248 
13249  appendPQExpBuffer(query, "SELECT amprocnum, "
13250  "amproc::pg_catalog.regprocedure, "
13251  "amproclefttype::pg_catalog.regtype, "
13252  "amprocrighttype::pg_catalog.regtype "
13253  "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
13254  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
13255  "AND refobjid = '%u'::pg_catalog.oid "
13256  "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
13257  "AND objid = ap.oid "
13258  "ORDER BY amprocnum",
13259  opcinfo->dobj.catId.oid);
13260 
13261  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13262 
13263  ntups = PQntuples(res);
13264 
13265  i_amprocnum = PQfnumber(res, "amprocnum");
13266  i_amproc = PQfnumber(res, "amproc");
13267  i_amproclefttype = PQfnumber(res, "amproclefttype");
13268  i_amprocrighttype = PQfnumber(res, "amprocrighttype");
13269 
13270  for (i = 0; i < ntups; i++)
13271  {
13272  amprocnum = PQgetvalue(res, i, i_amprocnum);
13273  amproc = PQgetvalue(res, i, i_amproc);
13274  amproclefttype = PQgetvalue(res, i, i_amproclefttype);
13275  amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
13276 
13277  if (needComma)
13278  appendPQExpBufferStr(q, " ,\n ");
13279 
13280  appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
13281 
13282  if (*amproclefttype && *amprocrighttype)
13283  appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
13284 
13285  appendPQExpBuffer(q, " %s", amproc);
13286 
13287  needComma = true;
13288  }
13289 
13290  PQclear(res);
13291 
13292  /*
13293  * If needComma is still false it means we haven't added anything after
13294  * the AS keyword. To avoid printing broken SQL, append a dummy STORAGE
13295  * clause with the same datatype. This isn't sanctioned by the
13296  * documentation, but actually DefineOpClass will treat it as a no-op.
13297  */
13298  if (!needComma)
13299  appendPQExpBuffer(q, "STORAGE %s", opcintype);
13300 
13301  appendPQExpBufferStr(q, ";\n");
13302 
13303  appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
13304  appendPQExpBuffer(nameusing, " USING %s",
13305  fmtId(amname));
13306 
13307  if (dopt->binary_upgrade)
13309  "OPERATOR CLASS", nameusing->data,
13310  opcinfo->dobj.namespace->dobj.name);
13311 
13312  if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13313  ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
13314  ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
13315  .namespace = opcinfo->dobj.namespace->dobj.name,
13316  .owner = opcinfo->rolname,
13317  .description = "OPERATOR CLASS",
13318  .section = SECTION_PRE_DATA,
13319  .createStmt = q->data,
13320  .dropStmt = delq->data));
13321 
13322  /* Dump Operator Class Comments */
13323  if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13324  dumpComment(fout, "OPERATOR CLASS", nameusing->data,
13325  opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
13326  opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
13327 
13328  free(opcintype);
13329  free(opcfamily);
13330  free(amname);
13331  destroyPQExpBuffer(query);
13332  destroyPQExpBuffer(q);
13333  destroyPQExpBuffer(delq);
13334  destroyPQExpBuffer(nameusing);
13335 }
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 13345 of file pg_dump.c.

13346 {
13347  DumpOptions *dopt = fout->dopt;
13348  PQExpBuffer query;
13349  PQExpBuffer q;
13350  PQExpBuffer delq;
13351  PQExpBuffer nameusing;
13352  PGresult *res;
13353  PGresult *res_ops;
13354  PGresult *res_procs;
13355  int ntups;
13356  int i_amname;
13357  int i_amopstrategy;
13358  int i_amopopr;
13359  int i_sortfamily;
13360  int i_sortfamilynsp;
13361  int i_amprocnum;
13362  int i_amproc;
13363  int i_amproclefttype;
13364  int i_amprocrighttype;
13365  char *amname;
13366  char *amopstrategy;
13367  char *amopopr;
13368  char *sortfamily;
13369  char *sortfamilynsp;
13370  char *amprocnum;
13371  char *amproc;
13372  char *amproclefttype;
13373  char *amprocrighttype;
13374  bool needComma;
13375  int i;
13376 
13377  /* Do nothing in data-only dump */
13378  if (dopt->dataOnly)
13379  return;
13380 
13381  query = createPQExpBuffer();
13382  q = createPQExpBuffer();
13383  delq = createPQExpBuffer();
13384  nameusing = createPQExpBuffer();
13385 
13386  /*
13387  * Fetch only those opfamily members that are tied directly to the
13388  * opfamily by pg_depend entries.
13389  */
13390  appendPQExpBuffer(query, "SELECT amopstrategy, "
13391  "amopopr::pg_catalog.regoperator, "
13392  "opfname AS sortfamily, "
13393  "nspname AS sortfamilynsp "
13394  "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
13395  "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
13396  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
13397  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
13398  "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
13399  "AND refobjid = '%u'::pg_catalog.oid "
13400  "AND amopfamily = '%u'::pg_catalog.oid "
13401  "ORDER BY amopstrategy",
13402  opfinfo->dobj.catId.oid,
13403  opfinfo->dobj.catId.oid);
13404 
13405  res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13406 
13407  resetPQExpBuffer(query);
13408 
13409  appendPQExpBuffer(query, "SELECT amprocnum, "
13410  "amproc::pg_catalog.regprocedure, "
13411  "amproclefttype::pg_catalog.regtype, "
13412  "amprocrighttype::pg_catalog.regtype "
13413  "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
13414  "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
13415  "AND refobjid = '%u'::pg_catalog.oid "
13416  "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
13417  "AND objid = ap.oid "
13418  "ORDER BY amprocnum",
13419  opfinfo->dobj.catId.oid);
13420 
13421  res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
13422 
13423  /* Get additional fields from the pg_opfamily row */
13424  resetPQExpBuffer(query);
13425 
13426  appendPQExpBuffer(query, "SELECT "
13427  "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
13428  "FROM pg_catalog.pg_opfamily "
13429  "WHERE oid = '%u'::pg_catalog.oid",
13430  opfinfo->dobj.catId.oid);
13431 
13432  res = ExecuteSqlQueryForSingleRow(fout, query->data);
13433 
13434  i_amname = PQfnumber(res, "amname");
13435 
13436  /* amname will still be needed after we PQclear res */
13437  amname = pg_strdup(PQgetvalue(res, 0, i_amname));
13438 
13439  appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
13440  fmtQualifiedDumpable(opfinfo));
13441  appendPQExpBuffer(delq, " USING %s;\n",
13442  fmtId(amname));
13443 
13444  /* Build the fixed portion of the CREATE command */
13445  appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
13446  fmtQualifiedDumpable(opfinfo));
13447  appendPQExpBuffer(q, " USING %s;\n",
13448  fmtId(amname));
13449 
13450  PQclear(res);
13451 
13452  /* Do we need an ALTER to add loose members? */
13453  if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
13454  {
13455  appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
13456  fmtQualifiedDumpable(opfinfo));
13457  appendPQExpBuffer(q, " USING %s ADD\n ",
13458  fmtId(amname));
13459 
13460  needComma = false;
13461 
13462  /*
13463  * Now fetch and print the OPERATOR entries (pg_amop rows).
13464  */
13465  ntups = PQntuples(res_ops);
13466 
13467  i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
13468  i_amopopr = PQfnumber(res_ops, "amopopr");
13469  i_sortfamily = PQfnumber(res_ops, "sortfamily");
13470  i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
13471 
13472  for (i = 0; i < ntups; i++)
13473  {
13474  amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
13475  amopopr = PQgetvalue(res_ops, i, i_amopopr);
13476  sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
13477  sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
13478 
13479  if (needComma)
13480  appendPQExpBufferStr(q, " ,\n ");
13481 
13482  appendPQExpBuffer(q, "OPERATOR %s %s",
13483  amopstrategy, amopopr);
13484 
13485  if (strlen(sortfamily) > 0)
13486  {
13487  appendPQExpBufferStr(q, " FOR ORDER BY ");
13488  appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
13489  appendPQExpBufferStr(q, fmtId(sortfamily));
13490  }
13491 
13492  needComma = true;
13493  }
13494 
13495  /*
13496  * Now fetch and print the FUNCTION entries (pg_amproc rows).
13497  */
13498  ntups = PQntuples(res_procs);
13499 
13500  i_amprocnum = PQfnumber(res_procs, "amprocnum");
13501  i_amproc = PQfnumber(res_procs, "amproc");
13502  i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
13503  i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
13504 
13505  for (i = 0; i < ntups; i++)
13506  {
13507  amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
13508  amproc = PQgetvalue(res_procs, i, i_amproc);
13509  amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
13510  amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
13511 
13512  if (needComma)
13513  appendPQExpBufferStr(q, " ,\n ");
13514 
13515  appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
13516  amprocnum, amproclefttype, amprocrighttype,
13517  amproc);
13518 
13519  needComma = true;
13520  }
13521 
13522  appendPQExpBufferStr(q, ";\n");
13523  }
13524 
13525  appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
13526  appendPQExpBuffer(nameusing, " USING %s",
13527  fmtId(amname));
13528 
13529  if (dopt->binary_upgrade)
13531  "OPERATOR FAMILY", nameusing->data,
13532  opfinfo->dobj.namespace->dobj.name);
13533 
13534  if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13535  ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
13536  ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
13537  .namespace = opfinfo->dobj.namespace->dobj.name,
13538  .owner = opfinfo->rolname,
13539  .description = "OPERATOR FAMILY",
13540  .section = SECTION_PRE_DATA,
13541  .createStmt = q->data,
13542  .dropStmt = delq->data));
13543 
13544  /* Dump Operator Family Comments */
13545  if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13546  dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
13547  opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
13548  opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
13549 
13550  free(amname);
13551  PQclear(res_ops);
13552  PQclear(res_procs);
13553  destroyPQExpBuffer(query);
13554  destroyPQExpBuffer(q);
13555  destroyPQExpBuffer(delq);
13556  destroyPQExpBuffer(nameusing);
13557 }
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 12684 of file pg_dump.c.

12685 {
12686  DumpOptions *dopt = fout->dopt;
12687  PQExpBuffer query;
12688  PQExpBuffer q;
12689  PQExpBuffer delq;
12691  PQExpBuffer details;
12692  PGresult *res;
12693  int i_oprkind;
12694  int i_oprcode;
12695  int i_oprleft;
12696  int i_oprright;
12697  int i_oprcom;
12698  int i_oprnegate;
12699  int i_oprrest;
12700  int i_oprjoin;
12701  int i_oprcanmerge;
12702  int i_oprcanhash;
12703  char *oprkind;
12704  char *oprcode;
12705  char *oprleft;
12706  char *oprright;
12707  char *oprcom;
12708  char *oprnegate;
12709  char *oprrest;
12710  char *oprjoin;
12711  char *oprcanmerge;
12712  char *oprcanhash;
12713  char *oprregproc;
12714  char *oprref;
12715 
12716  /* Do nothing in data-only dump */
12717  if (dopt->dataOnly)
12718  return;
12719 
12720  /*
12721  * some operators are invalid because they were the result of user
12722  * defining operators before commutators exist
12723  */
12724  if (!OidIsValid(oprinfo->oprcode))
12725  return;
12726 
12727  query = createPQExpBuffer();
12728  q = createPQExpBuffer();
12729  delq = createPQExpBuffer();
12731  details = createPQExpBuffer();
12732 
12733  if (!fout->is_prepared[PREPQUERY_DUMPOPR])
12734  {
12735  /* Set up query for operator-specific details */
12736  appendPQExpBufferStr(query,
12737  "PREPARE dumpOpr(pg_catalog.oid) AS\n"
12738  "SELECT oprkind, "
12739  "oprcode::pg_catalog.regprocedure, "
12740  "oprleft::pg_catalog.regtype, "
12741  "oprright::pg_catalog.regtype, "
12742  "oprcom, "
12743  "oprnegate, "
12744  "oprrest::pg_catalog.regprocedure, "
12745  "oprjoin::pg_catalog.regprocedure, "
12746  "oprcanmerge, oprcanhash "
12747  "FROM pg_catalog.pg_operator "
12748  "WHERE oid = $1");
12749 
12750  ExecuteSqlStatement(fout, query->data);
12751 
12752  fout->is_prepared[PREPQUERY_DUMPOPR] = true;
12753  }
12754 
12755  printfPQExpBuffer(query,
12756  "EXECUTE dumpOpr('%u')",
12757  oprinfo->dobj.catId.oid);
12758 
12759  res = ExecuteSqlQueryForSingleRow(fout, query->data);
12760 
12761  i_oprkind = PQfnumber(res, "oprkind");
12762  i_oprcode = PQfnumber(res, "oprcode");
12763  i_oprleft = PQfnumber(res, "oprleft");
12764  i_oprright = PQfnumber(res, "oprright");
12765  i_oprcom = PQfnumber(res, "oprcom");
12766  i_oprnegate = PQfnumber(res, "oprnegate");
12767  i_oprrest = PQfnumber(res, "oprrest");
12768  i_oprjoin = PQfnumber(res, "oprjoin");
12769  i_oprcanmerge = PQfnumber(res, "oprcanmerge");
12770  i_oprcanhash = PQfnumber(res, "oprcanhash");
12771 
12772  oprkind = PQgetvalue(res, 0, i_oprkind);
12773  oprcode = PQgetvalue(res, 0, i_oprcode);
12774  oprleft = PQgetvalue(res, 0, i_oprleft);
12775  oprright = PQgetvalue(res, 0, i_oprright);
12776  oprcom = PQgetvalue(res, 0, i_oprcom);
12777  oprnegate = PQgetvalue(res, 0, i_oprnegate);
12778  oprrest = PQgetvalue(res, 0, i_oprrest);
12779  oprjoin = PQgetvalue(res, 0, i_oprjoin);
12780  oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
12781  oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
12782 
12783  /* In PG14 upwards postfix operator support does not exist anymore. */
12784  if (strcmp(oprkind, "r") == 0)
12785  pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
12786  oprcode);
12787 
12788  oprregproc = convertRegProcReference(oprcode);
12789  if (oprregproc)
12790  {
12791  appendPQExpBuffer(details, " FUNCTION = %s", oprregproc);
12792  free(oprregproc);
12793  }
12794 
12795  appendPQExpBuffer(oprid, "%s (",
12796  oprinfo->dobj.name);
12797 
12798  /*
12799  * right unary means there's a left arg and left unary means there's a
12800  * right arg. (Although the "r" case is dead code for PG14 and later,
12801  * continue to support it in case we're dumping from an old server.)
12802  */
12803  if (strcmp(oprkind, "r") == 0 ||
12804  strcmp(oprkind, "b") == 0)
12805  {
12806  appendPQExpBuffer(details, ",\n LEFTARG = %s", oprleft);
12807  appendPQExpBufferStr(oprid, oprleft);
12808  }
12809  else
12810  appendPQExpBufferStr(oprid, "NONE");
12811 
12812  if (strcmp(oprkind, "l") == 0 ||
12813  strcmp(oprkind, "b") == 0)
12814  {
12815  appendPQExpBuffer(details, ",\n RIGHTARG = %s", oprright);
12816  appendPQExpBuffer(oprid, ", %s)", oprright);
12817  }
12818  else
12819  appendPQExpBufferStr(oprid, ", NONE)");
12820 
12821  oprref = getFormattedOperatorName(oprcom);
12822  if (oprref)
12823  {
12824  appendPQExpBuffer(details, ",\n COMMUTATOR = %s", oprref);
12825  free(oprref);
12826  }
12827 
12828  oprref = getFormattedOperatorName(oprnegate);
12829  if (oprref)
12830  {
12831  appendPQExpBuffer(details, ",\n NEGATOR = %s", oprref);
12832  free(oprref);
12833  }
12834 
12835  if (strcmp(oprcanmerge, "t") == 0)
12836  appendPQExpBufferStr(details, ",\n MERGES");
12837 
12838  if (strcmp(oprcanhash, "t") == 0)
12839  appendPQExpBufferStr(details, ",\n HASHES");
12840 
12841  oprregproc = convertRegProcReference(oprrest);
12842  if (oprregproc)
12843  {
12844  appendPQExpBuffer(details, ",\n RESTRICT = %s", oprregproc);
12845  free(oprregproc);
12846  }
12847 
12848  oprregproc = convertRegProcReference(oprjoin);
12849  if (oprregproc)
12850  {
12851  appendPQExpBuffer(details, ",\n JOIN = %s", oprregproc);
12852  free(oprregproc);
12853  }
12854 
12855  appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
12856  fmtId(oprinfo->dobj.namespace->dobj.name),
12857  oprid->data);
12858 
12859  appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
12860  fmtId(oprinfo->dobj.namespace->dobj.name),
12861  oprinfo->dobj.name, details->data);
12862 
12863  if (dopt->binary_upgrade)
12865  "OPERATOR", oprid->data,
12866  oprinfo->dobj.namespace->dobj.name);
12867 
12868  if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12869  ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
12870  ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
12871  .namespace = oprinfo->dobj.namespace->dobj.name,
12872  .owner = oprinfo->rolname,
12873  .description = "OPERATOR",
12874  .section = SECTION_PRE_DATA,
12875  .createStmt = q->data,
12876  .dropStmt = delq->data));
12877 
12878  /* Dump Operator Comments */
12879  if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12880  dumpComment(fout, "OPERATOR", oprid->data,
12881  oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
12882  oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
12883 
12884  PQclear(res);
12885 
12886  destroyPQExpBuffer(query);
12887  destroyPQExpBuffer(q);
12888  destroyPQExpBuffer(delq);
12890  destroyPQExpBuffer(details);
12891 }
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:12903
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 4086 of file pg_dump.c.

4087 {
4088  DumpOptions *dopt = fout->dopt;
4089  TableInfo *tbinfo = polinfo->poltable;
4090  PQExpBuffer query;
4091  PQExpBuffer delqry;
4092  PQExpBuffer polprefix;
4093  char *qtabname;
4094  const char *cmd;
4095  char *tag;
4096 
4097  /* Do nothing in data-only dump */
4098  if (dopt->dataOnly)
4099  return;
4100 
4101  /*
4102  * If polname is NULL, then this record is just indicating that ROW LEVEL
4103  * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
4104  * ROW LEVEL SECURITY.
4105  */
4106  if (polinfo->polname == NULL)
4107  {
4108  query = createPQExpBuffer();
4109 
4110  appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
4111  fmtQualifiedDumpable(tbinfo));
4112 
4113  /*
4114  * We must emit the ROW SECURITY object's dependency on its table
4115  * explicitly, because it will not match anything in pg_depend (unlike
4116  * the case for other PolicyInfo objects).
4117  */
4118  if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4119  ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4120  ARCHIVE_OPTS(.tag = polinfo->dobj.name,
4121  .namespace = polinfo->dobj.namespace->dobj.name,
4122  .owner = tbinfo->rolname,
4123  .description = "ROW SECURITY",
4124  .section = SECTION_POST_DATA,
4125  .createStmt = query->data,
4126  .deps = &(tbinfo->dobj.dumpId),
4127  .nDeps = 1));
4128 
4129  destroyPQExpBuffer(query);
4130  return;
4131  }
4132 
4133  if (polinfo->polcmd == '*')
4134  cmd = "";
4135  else if (polinfo->polcmd == 'r')
4136  cmd = " FOR SELECT";
4137  else if (polinfo->polcmd == 'a')
4138  cmd = " FOR INSERT";
4139  else if (polinfo->polcmd == 'w')
4140  cmd = " FOR UPDATE";
4141  else if (polinfo->polcmd == 'd')
4142  cmd = " FOR DELETE";
4143  else
4144  pg_fatal("unexpected policy command type: %c",
4145  polinfo->polcmd);
4146 
4147  query = createPQExpBuffer();
4148  delqry = createPQExpBuffer();
4149  polprefix = createPQExpBuffer();
4150 
4151  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
4152 
4153  appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
4154 
4155  appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
4156  !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
4157 
4158  if (polinfo->polroles != NULL)
4159  appendPQExpBuffer(query, " TO %s", polinfo->polroles);
4160 
4161  if (polinfo->polqual != NULL)
4162  appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
4163 
4164  if (polinfo->polwithcheck != NULL)
4165  appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
4166 
4167  appendPQExpBufferStr(query, ";\n");
4168 
4169  appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
4170  appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
4171 
4172  appendPQExpBuffer(polprefix, "POLICY %s ON",
4173  fmtId(polinfo->polname));
4174 
4175  tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
4176 
4177  if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4178  ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4179  ARCHIVE_OPTS(.tag = tag,
4180  .namespace = polinfo->dobj.namespace->dobj.name,
4181  .owner = tbinfo->rolname,
4182  .description = "POLICY",
4183  .section = SECTION_POST_DATA,
4184  .createStmt = query->data,
4185  .dropStmt = delqry->data));
4186 
4187  if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4188  dumpComment(fout, polprefix->data, qtabname,
4189  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
4190  polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
4191 
4192  free(tag);
4193  destroyPQExpBuffer(query);
4194  destroyPQExpBuffer(delqry);
4195  destroyPQExpBuffer(polprefix);
4196  free(qtabname);
4197 }
TableInfo * poltable
Definition: pg_dump.h:605
char * polqual
Definition: pg_dump.h:610
char polcmd
Definition: pg_dump.h:607
char * polroles
Definition: pg_dump.h:609
char * polwithcheck
Definition: pg_dump.h:611
DumpableObject dobj
Definition: pg_dump.h:604
bool polpermissive
Definition: pg_dump.h:608
char * polname
Definition: pg_dump.h:606

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

11851 {
11852  DumpOptions *dopt = fout->dopt;
11853  PQExpBuffer defqry;
11854  PQExpBuffer delqry;
11855  bool useParams;
11856  char *qlanname;
11857  FuncInfo *funcInfo;
11858  FuncInfo *inlineInfo = NULL;
11859  FuncInfo *validatorInfo = NULL;
11860 
11861  /* Do nothing in data-only dump */
11862  if (dopt->dataOnly)
11863  return;
11864 
11865  /*
11866  * Try to find the support function(s). It is not an error if we don't
11867  * find them --- if the functions are in the pg_catalog schema, as is
11868  * standard in 8.1 and up, then we won't have loaded them. (In this case
11869  * we will emit a parameterless CREATE LANGUAGE command, which will
11870  * require PL template knowledge in the backend to reload.)
11871  */
11872 
11873  funcInfo = findFuncByOid(plang->lanplcallfoid);
11874  if (funcInfo != NULL && !funcInfo->dobj.dump)
11875  funcInfo = NULL; /* treat not-dumped same as not-found */
11876 
11877  if (OidIsValid(plang->laninline))
11878  {
11879  inlineInfo = findFuncByOid(plang->laninline);
11880  if (inlineInfo != NULL && !inlineInfo->dobj.dump)
11881  inlineInfo = NULL;
11882  }
11883 
11884  if (OidIsValid(plang->lanvalidator))
11885  {
11886  validatorInfo = findFuncByOid(plang->lanvalidator);
11887  if (validatorInfo != NULL && !validatorInfo->dobj.dump)
11888  validatorInfo = NULL;
11889  }
11890 
11891  /*
11892  * If the functions are dumpable then emit a complete CREATE LANGUAGE with
11893  * parameters. Otherwise, we'll write a parameterless command, which will
11894  * be interpreted as CREATE EXTENSION.
11895  */
11896  useParams = (funcInfo != NULL &&
11897  (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
11898  (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
11899 
11900  defqry = createPQExpBuffer();
11901  delqry = createPQExpBuffer();
11902 
11903  qlanname = pg_strdup(fmtId(plang->dobj.name));
11904 
11905  appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
11906  qlanname);
11907 
11908  if (useParams)
11909  {
11910  appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
11911  plang->lanpltrusted ? "TRUSTED " : "",
11912  qlanname);
11913  appendPQExpBuffer(defqry, " HANDLER %s",
11914  fmtQualifiedDumpable(funcInfo));
11915  if (OidIsValid(plang->laninline))
11916  appendPQExpBuffer(defqry, " INLINE %s",
11917  fmtQualifiedDumpable(inlineInfo));
11918  if (OidIsValid(plang->lanvalidator))
11919  appendPQExpBuffer(defqry, " VALIDATOR %s",
11920  fmtQualifiedDumpable(validatorInfo));
11921  }
11922  else
11923  {
11924  /*
11925  * If not dumping parameters, then use CREATE OR REPLACE so that the
11926  * command will not fail if the language is preinstalled in the target
11927  * database.
11928  *
11929  * Modern servers will interpret this as CREATE EXTENSION IF NOT
11930  * EXISTS; perhaps we should emit that instead? But it might just add
11931  * confusion.
11932  */
11933  appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
11934  qlanname);
11935  }
11936  appendPQExpBufferStr(defqry, ";\n");
11937 
11938  if (dopt->binary_upgrade)
11939  binary_upgrade_extension_member(defqry, &plang->dobj,
11940  "LANGUAGE", qlanname, NULL);
11941 
11942  if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
11943  ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
11944  ARCHIVE_OPTS(.tag = plang->dobj.name,
11945  .owner = plang->lanowner,
11946  .description = "PROCEDURAL LANGUAGE",
11947  .section = SECTION_PRE_DATA,
11948  .createStmt = defqry->data,
11949  .dropStmt = delqry->data,
11950  ));
11951 
11952  /* Dump Proc Lang Comments and Security Labels */
11953  if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
11954  dumpComment(fout, "LANGUAGE", qlanname,
11955  NULL, plang->lanowner,
11956  plang->dobj.catId, 0, plang->dobj.dumpId);
11957 
11958  if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
11959  dumpSecLabel(fout, "LANGUAGE", qlanname,
11960  NULL, plang->lanowner,
11961  plang->dobj.catId, 0, plang->dobj.dumpId);
11962 
11963  if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
11964  dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
11965  qlanname, NULL, NULL,
11966  NULL, plang->lanowner, &plang->dacl);
11967 
11968  free(qlanname);
11969 
11970  destroyPQExpBuffer(defqry);
11971  destroyPQExpBuffer(delqry);
11972 }
Oid lanvalidator
Definition: pg_dump.h:488
DumpableAcl dacl
Definition: pg_dump.h:484
DumpableObject dobj
Definition: pg_dump.h:483
Oid laninline
Definition: pg_dump.h:487
const char * lanowner
Definition: pg_dump.h:489
Oid lanplcallfoid
Definition: pg_dump.h:486
bool lanpltrusted
Definition: pg_dump.h:485

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

4303 {
4304  DumpOptions *dopt = fout->dopt;
4305  PQExpBuffer delq;
4306  PQExpBuffer query;
4307  char *qpubname;
4308  bool first = true;
4309 
4310  /* Do nothing in data-only dump */
4311  if (dopt->dataOnly)
4312  return;
4313 
4314  delq = createPQExpBuffer();
4315  query = createPQExpBuffer();
4316 
4317  qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
4318 
4319  appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
4320  qpubname);
4321 
4322  appendPQExpBuffer(query, "CREATE PUBLICATION %s",
4323  qpubname);
4324 
4325  if (pubinfo->puballtables)
4326  appendPQExpBufferStr(query, " FOR ALL TABLES");
4327 
4328  appendPQExpBufferStr(query, " WITH (publish = '");
4329  if (pubinfo->pubinsert)
4330  {
4331  appendPQExpBufferStr(query, "insert");
4332  first = false;
4333  }
4334 
4335  if (pubinfo->pubupdate)
4336  {
4337  if (!first)
4338  appendPQExpBufferStr(query, ", ");
4339 
4340  appendPQExpBufferStr(query, "update");
4341  first = false;
4342  }
4343 
4344  if (pubinfo->pubdelete)
4345  {
4346  if (!first)
4347  appendPQExpBufferStr(query, ", ");
4348 
4349  appendPQExpBufferStr(query, "delete");
4350  first = false;
4351  }
4352 
4353  if (pubinfo->pubtruncate)
4354  {
4355  if (!first)
4356  appendPQExpBufferStr(query, ", ");
4357 
4358  appendPQExpBufferStr(query, "truncate");
4359  first = false;
4360  }
4361 
4362  appendPQExpBufferChar(query, '\'');
4363 
4364  if (pubinfo->pubviaroot)
4365  appendPQExpBufferStr(query, ", publish_via_partition_root = true");
4366 
4367  appendPQExpBufferStr(query, ");\n");
4368 
4369  if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4370  ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
4371  ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
4372  .owner = pubinfo->rolname,
4373  .description = "PUBLICATION",
4374  .section = SECTION_POST_DATA,
4375  .createStmt = query->data,
4376  .dropStmt = delq->data));
4377 
4378  if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4379  dumpComment(fout, "PUBLICATION", qpubname,
4380  NULL, pubinfo->rolname,
4381  pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4382 
4383  if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4384  dumpSecLabel(fout, "PUBLICATION", qpubname,
4385  NULL, pubinfo->rolname,
4386  pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4387 
4388  destroyPQExpBuffer(delq);
4389  destroyPQExpBuffer(query);
4390  free(qpubname);
4391 }
const char * rolname
Definition: pg_dump.h:620
bool puballtables
Definition: pg_dump.h:621
bool pubtruncate
Definition: pg_dump.h:625
DumpableObject dobj
Definition: pg_dump.h:619

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

4618 {
4619  DumpOptions *dopt = fout->dopt;
4620  NamespaceInfo *schemainfo = pubsinfo->pubschema;
4621  PublicationInfo *pubinfo = pubsinfo->publication;
4622  PQExpBuffer query;
4623  char *tag;
4624 
4625  /* Do nothing in data-only dump */
4626  if (dopt->dataOnly)
4627  return;
4628 
4629  tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
4630 
4631  query = createPQExpBuffer();
4632 
4633  appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
4634  appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
4635 
4636  /*
4637  * There is no point in creating drop query as the drop is done by schema
4638  * drop.
4639  */
4640  if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4641  ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
4642  ARCHIVE_OPTS(.tag = tag,
4643  .namespace = schemainfo->dobj.name,
4644  .owner = pubinfo->rolname,
4645  .description = "PUBLICATION TABLES IN SCHEMA",
4646  .section = SECTION_POST_DATA,
4647  .createStmt = query->data));
4648 
4649  /* These objects can't currently have comments or seclabels */
4650 
4651  free(tag);
4652  destroyPQExpBuffer(query);
4653 }
NamespaceInfo * pubschema
Definition: pg_dump.h:650
DumpableObject dobj
Definition: pg_dump.h:648
PublicationInfo * publication
Definition: pg_dump.h:649

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

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

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

10866 {
10867  DumpOptions *dopt = fout->dopt;
10869  PQExpBuffer delq = createPQExpBuffer();
10870  PQExpBuffer query = createPQExpBuffer();
10871  PGresult *res;
10872  Oid collationOid;
10873  char *qtypname;
10874  char *qualtypname;
10875  char *procname;
10876 
10878  {
10879  /* Set up query for range-specific details */
10880  appendPQExpBufferStr(query,
10881  "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
10882 
10883  appendPQExpBufferStr(query,
10884  "SELECT ");
10885 
10886  if (fout->remoteVersion >= 140000)
10887  appendPQExpBufferStr(query,
10888  "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
10889  else
10890  appendPQExpBufferStr(query,
10891  "NULL AS rngmultitype, ");
10892 
10893  appendPQExpBufferStr(query,
10894  "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
10895  "opc.opcname AS opcname, "
10896  "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
10897  " WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
10898  "opc.opcdefault, "
10899  "CASE WHEN rngcollation = st.typcollation THEN 0 "
10900  " ELSE rngcollation END AS collation, "
10901  "rngcanonical, rngsubdiff "
10902  "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
10903  " pg_catalog.pg_opclass opc "
10904  "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
10905  "rngtypid = $1");
10906 
10907  ExecuteSqlStatement(fout, query->data);
10908 
10909  fout->is_prepared[PREPQUERY_DUMPRANGETYPE] = true;
10910  }
10911 
10912  printfPQExpBuffer(query,
10913  "EXECUTE dumpRangeType('%u')",
10914  tyinfo->dobj.catId.oid);
10915 
10916  res = ExecuteSqlQueryForSingleRow(fout, query->data);
10917 
10918  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
10919  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
10920 
10921  /*
10922  * CASCADE shouldn't be required here as for normal types since the I/O
10923  * functions are generic and do not get dropped.
10924  */
10925  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
10926 
10927  if (dopt->binary_upgrade)
10929  tyinfo->dobj.catId.oid,
10930  false, true);
10931 
10932  appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
10933  qualtypname);
10934 
10935  appendPQExpBuffer(q, "\n subtype = %s",
10936  PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
10937 
10938  if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
10939  appendPQExpBuffer(q, ",\n multirange_type_name = %s",
10940  PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
10941 
10942  /* print subtype_opclass only if not default for subtype */
10943  if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
10944  {
10945  char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
10946  char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
10947 
10948  appendPQExpBuffer(q, ",\n subtype_opclass = %s.",
10949  fmtId(nspname));
10950  appendPQExpBufferStr(q, fmtId(opcname));
10951  }
10952 
10953  collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
10954  if (OidIsValid(collationOid))
10955  {
10956  CollInfo *coll = findCollationByOid(collationOid);
10957 
10958  if (coll)
10959  appendPQExpBuffer(q, ",\n collation = %s",
10960  fmtQualifiedDumpable(coll));
10961  }
10962 
10963  procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
10964  if (strcmp(procname, "-") != 0)
10965  appendPQExpBuffer(q, ",\n canonical = %s", procname);
10966 
10967  procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
10968  if (strcmp(procname, "-") != 0)
10969  appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
10970 
10971  appendPQExpBufferStr(q, "\n);\n");
10972 
10973  if (dopt->binary_upgrade)
10975  "TYPE", qtypname,
10976  tyinfo->dobj.namespace->dobj.name);
10977 
10978  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
10979  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
10980  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
10981  .namespace = tyinfo->dobj.namespace->dobj.name,
10982  .owner = tyinfo->rolname,
10983  .description = "TYPE",
10984  .section = SECTION_PRE_DATA,
10985  .createStmt = q->data,
10986  .dropStmt = delq->data));
10987 
10988  /* Dump Type Comments and Security Labels */
10989  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10990  dumpComment(fout, "TYPE", qtypname,
10991  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
10992  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10993 
10994  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
10995  dumpSecLabel(fout, "TYPE", qtypname,
10996  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
10997  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10998 
10999  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11000  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11001  qtypname, NULL,
11002  tyinfo->dobj.namespace->dobj.name,
11003  NULL, tyinfo->rolname, &tyinfo->dacl);
11004 
11005  PQclear(res);
11006  destroyPQExpBuffer(q);
11007  destroyPQExpBuffer(delq);
11008  destroyPQExpBuffer(query);
11009  free(qtypname);
11010  free(qualtypname);
11011 }
@ 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 17724 of file pg_dump.c.

17725 {
17726  DumpOptions *dopt = fout->dopt;
17727  TableInfo *tbinfo = rinfo->ruletable;
17728  bool is_view;
17729  PQExpBuffer query;
17730  PQExpBuffer cmd;
17731  PQExpBuffer delcmd;
17732  PQExpBuffer ruleprefix;
17733  char *qtabname;
17734  PGresult *res;
17735  char *tag;
17736 
17737  /* Do nothing in data-only dump */
17738  if (dopt->dataOnly)
17739  return;
17740 
17741  /*
17742  * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
17743  * we do not want to dump it as a separate object.
17744  */
17745  if (!rinfo->separate)
17746  return;
17747 
17748  /*
17749  * If it's an ON SELECT rule, we want to print it as a view definition,
17750  * instead of a rule.
17751  */
17752  is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
17753 
17754  query = createPQExpBuffer();
17755  cmd = createPQExpBuffer();
17756  delcmd = createPQExpBuffer();
17757  ruleprefix = createPQExpBuffer();
17758 
17759  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17760 
17761  if (is_view)
17762  {
17763  PQExpBuffer result;
17764 
17765  /*
17766  * We need OR REPLACE here because we'll be replacing a dummy view.
17767  * Otherwise this should look largely like the regular view dump code.
17768  */
17769  appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
17770  fmtQualifiedDumpable(tbinfo));
17771  if (nonemptyReloptions(tbinfo->reloptions))
17772  {
17773  appendPQExpBufferStr(cmd, " WITH (");
17774  appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
17775  appendPQExpBufferChar(cmd, ')');
17776  }
17777  result = createViewAsClause(fout, tbinfo);
17778  appendPQExpBuffer(cmd, " AS\n%s", result->data);
17779  destroyPQExpBuffer(result);
17780  if (tbinfo->checkoption != NULL)
17781  appendPQExpBuffer(cmd, "\n WITH %s CHECK OPTION",
17782  tbinfo->checkoption);
17783  appendPQExpBufferStr(cmd, ";\n");
17784  }
17785  else
17786  {
17787  /* In the rule case, just print pg_get_ruledef's result verbatim */
17788  appendPQExpBuffer(query,
17789  "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
17790  rinfo->dobj.catId.oid);
17791 
17792  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17793 
17794  if (PQntuples(res) != 1)
17795  pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
17796  rinfo->dobj.name, tbinfo->dobj.name);
17797 
17798  printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
17799 
17800  PQclear(res);
17801  }
17802 
17803  /*
17804  * Add the command to alter the rules replication firing semantics if it
17805  * differs from the default.
17806  */
17807  if (rinfo->ev_enabled != 'O')
17808  {
17809  appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
17810  switch (rinfo->ev_enabled)
17811  {
17812  case 'A':
17813  appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
17814  fmtId(rinfo->dobj.name));
17815  break;
17816  case 'R':
17817  appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
17818  fmtId(rinfo->dobj.name));
17819  break;
17820  case 'D':
17821  appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
17822  fmtId(rinfo->dobj.name));
17823  break;
17824  }
17825  }
17826 
17827  if (is_view)
17828  {
17829  /*
17830  * We can't DROP a view's ON SELECT rule. Instead, use CREATE OR
17831  * REPLACE VIEW to replace the rule with something with minimal
17832  * dependencies.
17833  */
17834  PQExpBuffer result;
17835 
17836  appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
17837  fmtQualifiedDumpable(tbinfo));
17838  result = createDummyViewAsClause(fout, tbinfo);
17839  appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
17840  destroyPQExpBuffer(result);
17841  }
17842  else
17843  {
17844  appendPQExpBuffer(delcmd, "DROP RULE %s ",
17845  fmtId(rinfo->dobj.name));
17846  appendPQExpBuffer(delcmd, "ON %s;\n",
17847  fmtQualifiedDumpable(tbinfo));
17848  }
17849 
17850  appendPQExpBuffer(ruleprefix, "RULE %s ON",
17851  fmtId(rinfo->dobj.name));
17852 
17853  tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
17854 
17855  if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17856  ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
17857  ARCHIVE_OPTS(.tag = tag,
17858  .namespace = tbinfo->dobj.namespace->dobj.name,
17859  .owner = tbinfo->rolname,
17860  .description = "RULE",
17861  .section = SECTION_POST_DATA,
17862  .createStmt = cmd->data,
17863  .dropStmt = delcmd->data));
17864 
17865  /* Dump rule comments */
17866  if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17867  dumpComment(fout, ruleprefix->data, qtabname,
17868  tbinfo->dobj.namespace->dobj.name,
17869  tbinfo->rolname,
17870  rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
17871 
17872  free(tag);
17873  destroyPQExpBuffer(query);
17874  destroyPQExpBuffer(cmd);
17875  destroyPQExpBuffer(delcmd);
17876  destroyPQExpBuffer(ruleprefix);
17877  free(qtabname);
17878 }
static PQExpBuffer createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15628
static PQExpBuffer createViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15579
DumpableObject dobj
Definition: pg_dump.h:429
bool separate
Definition: pg_dump.h:434
char ev_enabled
Definition: pg_dump.h:433
bool is_instead
Definition: pg_dump.h:432
TableInfo * ruletable
Definition: pg_dump.h:430
char ev_type
Definition: pg_dump.h:431
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 3583 of file pg_dump.c.

3584 {
3586  PQExpBuffer path = createPQExpBuffer();
3587  PGresult *res;
3588  char **schemanames = NULL;
3589  int nschemanames = 0;
3590  int i;
3591 
3592  /*
3593  * We use the result of current_schemas(), not the search_path GUC,
3594  * because that might contain wildcards such as "$user", which won't
3595  * necessarily have the same value during restore. Also, this way avoids
3596  * listing schemas that may appear in search_path but not actually exist,
3597  * which seems like a prudent exclusion.
3598  */
3600  "SELECT pg_catalog.current_schemas(false)");
3601 
3602  if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
3603  pg_fatal("could not parse result of current_schemas()");
3604 
3605  /*
3606  * We use set_config(), not a simple "SET search_path" command, because
3607  * the latter has less-clean behavior if the search path is empty. While
3608  * that's likely to get fixed at some point, it seems like a good idea to
3609  * be as backwards-compatible as possible in what we put into archives.
3610  */
3611  for (i = 0; i < nschemanames; i++)
3612  {
3613  if (i > 0)
3614  appendPQExpBufferStr(path, ", ");
3615  appendPQExpBufferStr(path, fmtId(schemanames[i]));
3616  }
3617 
3618  appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
3619  appendStringLiteralAH(qry, path->data, AH);
3620  appendPQExpBufferStr(qry, ", false);\n");
3621 
3622  pg_log_info("saving \"search_path = %s\"", path->data);
3623 
3625  ARCHIVE_OPTS(.tag = "SEARCHPATH",
3626  .description = "SEARCHPATH",
3627  .section = SECTION_PRE_DATA,
3628  .createStmt = qry->data));
3629 
3630  /* Also save it in AH->searchpath, in case we're doing plain text dump */
3631  AH->searchpath = pg_strdup(qry->data);
3632 
3633  free(schemanames);
3634  PQclear(res);
3635  destroyPQExpBuffer(qry);
3636  destroyPQExpBuffer(path);
3637 }
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 15112 of file pg_dump.c.

15115 {
15116  DumpOptions *dopt = fout->dopt;
15117  SecLabelItem *labels;
15118  int nlabels;
15119  int i;
15120  PQExpBuffer query;
15121 
15122  /* do nothing, if --no-security-labels is supplied */
15123  if (dopt->no_security_labels)
15124  return;
15125 
15126  /*
15127  * Security labels are schema not data ... except large object labels are
15128  * data
15129  */
15130  if (strcmp(type, "LARGE OBJECT") != 0)
15131  {
15132  if (dopt->dataOnly)
15133  return;
15134  }
15135  else
15136  {
15137  /* We do dump large object security labels in binary-upgrade mode */
15138  if (dopt->schemaOnly && !dopt->binary_upgrade)
15139  return;
15140  }
15141 
15142  /* Search for security labels associated with catalogId, using table */
15143  nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
15144 
15145  query = createPQExpBuffer();
15146 
15147  for (i = 0; i < nlabels; i++)
15148  {
15149  /*
15150  * Ignore label entries for which the subid doesn't match.
15151  */
15152  if (labels[i].objsubid != subid)
15153  continue;
15154 
15155  appendPQExpBuffer(query,
15156  "SECURITY LABEL FOR %s ON %s ",
15157  fmtId(labels[i].provider), type);
15158  if (namespace && *namespace)
15159  appendPQExpBuffer(query, "%s.", fmtId(namespace));
15160  appendPQExpBuffer(query, "%s IS ", name);
15161  appendStringLiteralAH(query, labels[i].label, fout);
15162  appendPQExpBufferStr(query, ";\n");
15163  }
15164 
15165  if (query->len > 0)
15166  {
15168 
15169  appendPQExpBuffer(tag, "%s %s", type, name);
15171  ARCHIVE_OPTS(.tag = tag->data,
15172  .namespace = namespace,
15173  .owner = owner,
15174  .description = "SECURITY LABEL",
15175  .section = SECTION_NONE,
15176  .createStmt = query->data,
15177  .deps = &dumpId,
15178  .nDeps = 1));
15179  destroyPQExpBuffer(tag);
15180  }
15181 
15182  destroyPQExpBuffer(query);
15183 }
static JitProviderCallbacks provider
Definition: jit.c:43
static int findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
Definition: pg_dump.c:15274

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

17198 {
17199  DumpOptions *dopt = fout->dopt;
17200  PGresult *res;
17201  char *startv,
17202  *incby,
17203  *maxv,
17204  *minv,
17205  *cache,
17206  *seqtype;
17207  bool cycled;
17208  bool is_ascending;
17209  int64 default_minv,
17210  default_maxv;
17211  char bufm[32],
17212  bufx[32];
17213  PQExpBuffer query = createPQExpBuffer();
17214  PQExpBuffer delqry = createPQExpBuffer();
17215  char *qseqname;
17216  TableInfo *owning_tab = NULL;
17217 
17218  qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
17219 
17220  if (fout->remoteVersion >= 100000)
17221  {
17222  appendPQExpBuffer(query,
17223  "SELECT format_type(seqtypid, NULL), "
17224  "seqstart, seqincrement, "
17225  "seqmax, seqmin, "
17226  "seqcache, seqcycle "
17227  "FROM pg_catalog.pg_sequence "
17228  "WHERE seqrelid = '%u'::oid",
17229  tbinfo->dobj.catId.oid);
17230  }
17231  else
17232  {
17233  /*
17234  * Before PostgreSQL 10, sequence metadata is in the sequence itself.
17235  *
17236  * Note: it might seem that 'bigint' potentially needs to be
17237  * schema-qualified, but actually that's a keyword.
17238  */
17239  appendPQExpBuffer(query,
17240  "SELECT 'bigint' AS sequence_type, "
17241  "start_value, increment_by, max_value, min_value, "
17242  "cache_value, is_cycled FROM %s",
17243  fmtQualifiedDumpable(tbinfo));
17244  }
17245 
17246  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17247 
17248  if (PQntuples(res) != 1)
17249  pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
17250  "query to get data of sequence \"%s\" returned %d rows (expected 1)",
17251  PQntuples(res)),
17252  tbinfo->dobj.name, PQntuples(res));
17253 
17254  seqtype = PQgetvalue(res, 0, 0);
17255  startv = PQgetvalue(res, 0, 1);
17256  incby = PQgetvalue(res, 0, 2);
17257  maxv = PQgetvalue(res, 0, 3);
17258  minv = PQgetvalue(res, 0, 4);
17259  cache = PQgetvalue(res, 0, 5);
17260  cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
17261 
17262  /* Calculate default limits for a sequence of this type */
17263  is_ascending = (incby[0] != '-');
17264  if (strcmp(seqtype, "smallint") == 0)
17265  {
17266  default_minv = is_ascending ? 1 : PG_INT16_MIN;
17267  default_maxv = is_ascending ? PG_INT16_MAX : -1;
17268  }
17269  else if (strcmp(seqtype, "integer") == 0)
17270  {
17271  default_minv = is_ascending ? 1 : PG_INT32_MIN;
17272  default_maxv = is_ascending ? PG_INT32_MAX : -1;
17273  }
17274  else if (strcmp(seqtype, "bigint") == 0)
17275  {
17276  default_minv = is_ascending ? 1 : PG_INT64_MIN;
17277  default_maxv = is_ascending ? PG_INT64_MAX : -1;
17278  }
17279  else
17280  {
17281  pg_fatal("unrecognized sequence type: %s", seqtype);
17282  default_minv = default_maxv = 0; /* keep compiler quiet */
17283  }
17284 
17285  /*
17286  * 64-bit strtol() isn't very portable, so convert the limits to strings
17287  * and compare that way.
17288  */
17289  snprintf(bufm, sizeof(bufm), INT64_FORMAT, default_minv);
17290  snprintf(bufx, sizeof(bufx), INT64_FORMAT, default_maxv);
17291 
17292  /* Don't print minv/maxv if they match the respective default limit */
17293  if (strcmp(minv, bufm) == 0)
17294  minv = NULL;
17295  if (strcmp(maxv, bufx) == 0)
17296  maxv = NULL;
17297 
17298  /*
17299  * Identity sequences are not to be dropped separately.
17300  */
17301  if (!tbinfo->is_identity_sequence)
17302  {
17303  appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
17304  fmtQualifiedDumpable(tbinfo));
17305  }
17306 
17307  resetPQExpBuffer(query);
17308 
17309  if (dopt->binary_upgrade)
17310  {
17312  tbinfo->dobj.catId.oid);
17313 
17314  /*
17315  * In older PG versions a sequence will have a pg_type entry, but v14
17316  * and up don't use that, so don't attempt to preserve the type OID.
17317  */
17318  }
17319 
17320  if (tbinfo->is_identity_sequence)
17321  {
17322  owning_tab = findTableByOid(tbinfo->owning_tab);
17323 
17324  appendPQExpBuffer(query,
17325  "ALTER TABLE %s ",
17326  fmtQualifiedDumpable(owning_tab));
17327  appendPQExpBuffer(query,
17328  "ALTER COLUMN %s ADD GENERATED ",
17329  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
17330  if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
17331  appendPQExpBufferStr(query, "ALWAYS");
17332  else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
17333  appendPQExpBufferStr(query, "BY DEFAULT");
17334  appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n",
17335  fmtQualifiedDumpable(tbinfo));
17336  }
17337  else
17338  {
17339  appendPQExpBuffer(query,
17340  "CREATE %sSEQUENCE %s\n",
17341  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
17342  "UNLOGGED " : "",
17343  fmtQualifiedDumpable(tbinfo));
17344 
17345  if (strcmp(seqtype, "bigint") != 0)
17346  appendPQExpBuffer(query, " AS %s\n", seqtype);
17347  }
17348 
17349  appendPQExpBuffer(query, " START WITH %s\n", startv);
17350 
17351  appendPQExpBuffer(query, " INCREMENT BY %s\n", incby);
17352 
17353  if (minv)
17354  appendPQExpBuffer(query, " MINVALUE %s\n", minv);
17355  else
17356  appendPQExpBufferStr(query, " NO MINVALUE\n");
17357 
17358  if (maxv)
17359  appendPQExpBuffer(query, " MAXVALUE %s\n", maxv);
17360  else
17361  appendPQExpBufferStr(query, " NO MAXVALUE\n");
17362 
17363  appendPQExpBuffer(query,
17364  " CACHE %s%s",
17365  cache, (cycled ? "\n CYCLE" : ""));
17366 
17367  if (tbinfo->is_identity_sequence)
17368  {
17369  appendPQExpBufferStr(query, "\n);\n");
17370  if (tbinfo->relpersistence != owning_tab->relpersistence)
17371  appendPQExpBuffer(query,
17372  "ALTER SEQUENCE %s SET %s;\n",
17373  fmtQualifiedDumpable(tbinfo),
17374  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
17375  "UNLOGGED" : "LOGGED");
17376  }
17377  else
17378  appendPQExpBufferStr(query, ";\n");
17379 
17380  /* binary_upgrade: no need to clear TOAST table oid */
17381 
17382  if (dopt->binary_upgrade)
17383  binary_upgrade_extension_member(query, &tbinfo->dobj,
17384  "SEQUENCE", qseqname,
17385  tbinfo->dobj.namespace->dobj.name);
17386 
17387  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17388  ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
17389  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17390  .namespace = tbinfo->dobj.namespace->dobj.name,
17391  .owner = tbinfo->rolname,
17392  .description = "SEQUENCE",
17393  .section = SECTION_PRE_DATA,
17394  .createStmt = query->data,
17395  .dropStmt = delqry->data));
17396 
17397  /*
17398  * If the sequence is owned by a table column, emit the ALTER for it as a
17399  * separate TOC entry immediately following the sequence's own entry. It's
17400  * OK to do this rather than using full sorting logic, because the
17401  * dependency that tells us it's owned will have forced the table to be
17402  * created first. We can't just include the ALTER in the TOC entry
17403  * because it will fail if we haven't reassigned the sequence owner to
17404  * match the table's owner.
17405  *
17406  * We need not schema-qualify the table reference because both sequence
17407  * and table must be in the same schema.
17408  */
17409  if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
17410  {
17411  owning_tab = findTableByOid(tbinfo->owning_tab);
17412 
17413  if (owning_tab == NULL)
17414  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
17415  tbinfo->owning_tab, tbinfo->dobj.catId.oid);
17416 
17417  if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
17418  {
17419  resetPQExpBuffer(query);
17420  appendPQExpBuffer(query, "ALTER SEQUENCE %s",
17421  fmtQualifiedDumpable(tbinfo));
17422  appendPQExpBuffer(query, " OWNED BY %s",
17423  fmtQualifiedDumpable(owning_tab));
17424  appendPQExpBuffer(query, ".%s;\n",
17425  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
17426 
17427  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17429  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17430  .namespace = tbinfo->dobj.namespace->dobj.name,
17431  .owner = tbinfo->rolname,
17432  .description = "SEQUENCE OWNED BY",
17433  .section = SECTION_PRE_DATA,
17434  .createStmt = query->data,
17435  .deps = &(tbinfo->dobj.dumpId),
17436  .nDeps = 1));
17437  }
17438  }
17439 
17440  /* Dump Sequence Comments and Security Labels */
17441  if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17442  dumpComment(fout, "SEQUENCE", qseqname,
17443  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17444  tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
17445 
17446  if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
17447  dumpSecLabel(fout, "SEQUENCE", qseqname,
17448  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17449  tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
17450 
17451  PQclear(res);
17452 
17453  destroyPQExpBuffer(query);
17454  destroyPQExpBuffer(delqry);
17455  free(qseqname);
17456 }
TableInfo * findTableByOid(Oid oid)
Definition: common.c:828
#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 17463 of file pg_dump.c.

17464 {
17465  TableInfo *tbinfo = tdinfo->tdtable;
17466  PGresult *res;
17467  char *last;
17468  bool called;
17469  PQExpBuffer query = createPQExpBuffer();
17470 
17471  appendPQExpBuffer(query,
17472  "SELECT last_value, is_called FROM %s",
17473  fmtQualifiedDumpable(tbinfo));
17474 
17475  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17476 
17477  if (PQntuples(res) != 1)
17478  pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
17479  "query to get data of sequence \"%s\" returned %d rows (expected 1)",
17480  PQntuples(res)),
17481  tbinfo->dobj.name, PQntuples(res));
17482 
17483  last = PQgetvalue(res, 0, 0);
17484  called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
17485 
17486  resetPQExpBuffer(query);
17487  appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
17488  appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
17489  appendPQExpBuffer(query, ", %s, %s);\n",
17490  last, (called ? "true" : "false"));
17491 
17492  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
17494  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17495  .namespace = tbinfo->dobj.namespace->dobj.name,
17496  .owner = tbinfo->rolname,
17497  .description = "SEQUENCE SET",
17498  .section = SECTION_DATA,
17499  .createStmt = query->data,
17500  .deps = &(tbinfo->dobj.dumpId),
17501  .nDeps = 1));
17502 
17503  PQclear(res);
17504 
17505  destroyPQExpBuffer(query);
17506 }
TableInfo * tdtable
Definition: pg_dump.h:385
DumpableObject dobj
Definition: pg_dump.h:384

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

11805 {
11806  DumpOptions *dopt = fout->dopt;
11807  PQExpBuffer q;
11808 
11809  /* Do nothing in data-only dump */
11810  if (dopt->dataOnly)
11811  return;
11812 
11813  q = createPQExpBuffer();
11814 
11815  /*
11816  * Note the lack of a DROP command for the shell type; any required DROP
11817  * is driven off the base type entry, instead. This interacts with
11818  * _printTocEntry()'s use of the presence of a DROP command to decide
11819  * whether an entry needs an ALTER OWNER command. We don't want to alter
11820  * the shell type's owner immediately on creation; that should happen only
11821  * after it's filled in, otherwise the backend complains.
11822  */
11823 
11824  if (dopt->binary_upgrade)
11826  stinfo->baseType->dobj.catId.oid,
11827  false, false);
11828 
11829  appendPQExpBuffer(q, "CREATE TYPE %s;\n",
11830  fmtQualifiedDumpable(stinfo));
11831 
11832  if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11833  ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
11834  ARCHIVE_OPTS(.tag = stinfo->dobj.name,
11835  .namespace = stinfo->dobj.namespace->dobj.name,
11836  .owner = stinfo->baseType->rolname,
11837  .description = "SHELL TYPE",
11838  .section = SECTION_PRE_DATA,
11839  .createStmt = q->data));
11840 
11841  destroyPQExpBuffer(q);
11842 }
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 16806 of file pg_dump.c.

16807 {
16808  DumpOptions *dopt = fout->dopt;
16809  PQExpBuffer q;
16810  PQExpBuffer delq;
16811  PQExpBuffer query;
16812  char *qstatsextname;
16813  PGresult *res;
16814  char *stxdef;
16815 
16816  /* Do nothing in data-only dump */
16817  if (dopt->dataOnly)
16818  return;
16819 
16820  q = createPQExpBuffer();
16821  delq = createPQExpBuffer();
16822  query = createPQExpBuffer();
16823 
16824  qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
16825 
16826  appendPQExpBuffer(query, "SELECT "
16827  "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
16828  statsextinfo->dobj.catId.oid);
16829 
16830  res = ExecuteSqlQueryForSingleRow(fout, query->data);
16831 
16832  stxdef = PQgetvalue(res, 0, 0);
16833 
16834  /* Result of pg_get_statisticsobjdef is complete except for semicolon */
16835  appendPQExpBuffer(q, "%s;\n", stxdef);
16836 
16837  /*
16838  * We only issue an ALTER STATISTICS statement if the stxstattarget entry
16839  * for this statistics object is not the default value.
16840  */
16841  if (statsextinfo->stattarget >= 0)
16842  {
16843  appendPQExpBuffer(q, "ALTER STATISTICS %s ",
16844  fmtQualifiedDumpable(statsextinfo));
16845  appendPQExpBuffer(q, "SET STATISTICS %d;\n",
16846  statsextinfo->stattarget);
16847  }
16848 
16849  appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
16850  fmtQualifiedDumpable(statsextinfo));
16851 
16852  if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16853  ArchiveEntry(fout, statsextinfo->dobj.catId,
16854  statsextinfo->dobj.dumpId,
16855  ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
16856  .namespace = statsextinfo->dobj.namespace->dobj.name,
16857  .owner = statsextinfo->rolname,
16858  .description = "STATISTICS",
16859  .section = SECTION_POST_DATA,
16860  .createStmt = q->data,
16861  .dropStmt = delq->data));
16862 
16863  /* Dump Statistics Comments */
16864  if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16865  dumpComment(fout, "STATISTICS", qstatsextname,
16866  statsextinfo->dobj.namespace->dobj.name,
16867  statsextinfo->rolname,
16868  statsextinfo->dobj.catId, 0,
16869  statsextinfo->dobj.dumpId);
16870 
16871  PQclear(res);
16872  destroyPQExpBuffer(q);
16873  destroyPQExpBuffer(delq);
16874  destroyPQExpBuffer(query);
16875  free(qstatsextname);
16876 }
int stattarget
Definition: pg_dump.h:424
const char * rolname
Definition: pg_dump.h:422
DumpableObject dobj
Definition: pg_dump.h:421

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

3560 {
3561  const char *stdstrings = AH->std_strings ? "on" : "off";
3563 
3564  pg_log_info("saving \"standard_conforming_strings = %s\"",
3565  stdstrings);
3566 
3567  appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
3568  stdstrings);
3569 
3571  ARCHIVE_OPTS(.tag = "STDSTRINGS",
3572  .description = "STDSTRINGS",
3573  .section = SECTION_PRE_DATA,
3574  .createStmt = qry->data));
3575 
3576  destroyPQExpBuffer(qry);
3577 }

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

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

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

5026 {
5027  DumpOptions *dopt = fout->dopt;
5028  SubscriptionInfo *subinfo = subrinfo->subinfo;
5029  PQExpBuffer query;
5030  char *tag;
5031 
5032  /* Do nothing in data-only dump */
5033  if (dopt->dataOnly)
5034  return;
5035 
5036  Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
5037 
5038  tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
5039 
5040  query = createPQExpBuffer();
5041 
5042  if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5043  {
5044  /*
5045  * binary_upgrade_add_sub_rel_state will add the subscription relation
5046  * to pg_subscription_rel table. This will be used only in
5047  * binary-upgrade mode.
5048  */
5049  appendPQExpBufferStr(query,
5050  "\n-- For binary upgrade, must preserve the subscriber table.\n");
5051  appendPQExpBufferStr(query,
5052  "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
5053  appendStringLiteralAH(query, subrinfo->dobj.name, fout);
5054  appendPQExpBuffer(query,
5055  ", %u, '%c'",
5056  subrinfo->tblinfo->dobj.catId.oid,
5057  subrinfo->srsubstate);
5058 
5059  if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
5060  appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
5061  else
5062  appendPQExpBuffer(query, ", NULL");
5063 
5064  appendPQExpBufferStr(query, ");\n");
5065  }
5066 
5067  /*
5068  * There is no point in creating a drop query as the drop is done by table
5069  * drop. (If you think to change this, see also _printTocEntry().)
5070  * Although this object doesn't really have ownership as such, set the
5071  * owner field anyway to ensure that the command is run by the correct
5072  * role at restore time.
5073  */
5074  if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5075  ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
5076  ARCHIVE_OPTS(.tag = tag,
5077  .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
5078  .owner = subinfo->rolname,
5079  .description = "SUBSCRIPTION TABLE",
5080  .section = SECTION_POST_DATA,
5081  .createStmt = query->data));
5082 
5083  /* These objects can't currently have comments or seclabels */
5084 
5085  free(tag);
5086  destroyPQExpBuffer(query);
5087 }
DumpableObject dobj
Definition: pg_dump.h:688
char * srsublsn
Definition: pg_dump.h:692
SubscriptionInfo * subinfo
Definition: pg_dump.h:689
TableInfo * tblinfo
Definition: pg_dump.h:690
char srsubstate
Definition: pg_dump.h:691

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

15440 {
15441  DumpOptions *dopt = fout->dopt;
15442  DumpId tableAclDumpId = InvalidDumpId;
15443  char *namecopy;
15444 
15445  /* Do nothing in data-only dump */
15446  if (dopt->dataOnly)
15447  return;
15448 
15449  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15450  {
15451  if (tbinfo->relkind == RELKIND_SEQUENCE)
15452  dumpSequence(fout, tbinfo);
15453  else
15454  dumpTableSchema(fout, tbinfo);
15455  }
15456 
15457  /* Handle the ACL here */
15458  namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
15459  if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
15460  {
15461  const char *objtype =
15462  (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
15463 
15464  tableAclDumpId =
15465  dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
15466  objtype, namecopy, NULL,
15467  tbinfo->dobj.namespace->dobj.name,
15468  NULL, tbinfo->rolname, &tbinfo->dacl);
15469  }
15470 
15471  /*
15472  * Handle column ACLs, if any. Note: we pull these with a separate query
15473  * rather than trying to fetch them during getTableAttrs, so that we won't
15474  * miss ACLs on system columns. Doing it this way also allows us to dump
15475  * ACLs for catalogs that we didn't mark "interesting" back in getTables.
15476  */
15477  if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
15478  {
15479  PQExpBuffer query = createPQExpBuffer();
15480  PGresult *res;
15481  int i;
15482 
15484  {
15485  /* Set up query for column ACLs */
15486  appendPQExpBufferStr(query,
15487  "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
15488 
15489  if (fout->remoteVersion >= 90600)
15490  {
15491  /*
15492  * In principle we should call acldefault('c', relowner) to
15493  * get the default ACL for a column. However, we don't
15494  * currently store the numeric OID of the relowner in
15495  * TableInfo. We could convert the owner name using regrole,
15496  * but that creates a risk of failure due to concurrent role
15497  * renames. Given that the default ACL for columns is empty
15498  * and is likely to stay that way, it's not worth extra cycles
15499  * and risk to avoid hard-wiring that knowledge here.
15500  */
15501  appendPQExpBufferStr(query,
15502  "SELECT at.attname, "
15503  "at.attacl, "
15504  "'{}' AS acldefault, "
15505  "pip.privtype, pip.initprivs "
15506  "FROM pg_catalog.pg_attribute at "
15507  "LEFT JOIN pg_catalog.pg_init_privs pip ON "
15508  "(at.attrelid = pip.objoid "
15509  "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
15510  "AND at.attnum = pip.objsubid) "
15511  "WHERE at.attrelid = $1 AND "
15512  "NOT at.attisdropped "
15513  "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
15514  "ORDER BY at.attnum");
15515  }
15516  else
15517  {
15518  appendPQExpBufferStr(query,
15519  "SELECT attname, attacl, '{}' AS acldefault, "
15520  "NULL AS privtype, NULL AS initprivs "
15521  "FROM pg_catalog.pg_attribute "
15522  "WHERE attrelid = $1 AND NOT attisdropped "
15523  "AND attacl IS NOT NULL "
15524  "ORDER BY attnum");
15525  }
15526 
15527  ExecuteSqlStatement(fout, query->data);
15528 
15529  fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
15530  }
15531 
15532  printfPQExpBuffer(query,
15533  "EXECUTE getColumnACLs('%u')",
15534  tbinfo->dobj.catId.oid);
15535 
15536  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15537 
15538  for (i = 0; i < PQntuples(res); i++)
15539  {
15540  char *attname = PQgetvalue(res, i, 0);
15541  char *attacl = PQgetvalue(res, i, 1);
15542  char *acldefault = PQgetvalue(res, i, 2);
15543  char privtype = *(PQgetvalue(res, i, 3));
15544  char *initprivs = PQgetvalue(res, i, 4);
15545  DumpableAcl coldacl;
15546  char *attnamecopy;
15547 
15548  coldacl.acl = attacl;
15549  coldacl.acldefault = acldefault;
15550  coldacl.privtype = privtype;
15551  coldacl.initprivs = initprivs;
15552  attnamecopy = pg_strdup(fmtId(attname));
15553 
15554  /*
15555  * Column's GRANT type is always TABLE. Each column ACL depends
15556  * on the table-level ACL, since we can restore column ACLs in
15557  * parallel but the table-level ACL has to be done first.
15558  */
15559  dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
15560  "TABLE", namecopy, attnamecopy,
15561  tbinfo->dobj.namespace->dobj.name,
15562  NULL, tbinfo->rolname, &coldacl);
15563  free(attnamecopy);
15564  }
15565  PQclear(res);
15566  destroyPQExpBuffer(query);
15567  }
15568 
15569  free(namecopy);
15570 }
@ PREPQUERY_GETCOLUMNACLS
Definition: pg_backup.h:75
static void dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:15668
static void dumpSequence(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:17197
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 16468 of file pg_dump.c.

16469 {
16470  DumpOptions *dopt = fout->dopt;
16471  PQExpBuffer q;
16472  PGresult *res;
16473  char *partbound;
16474 
16475  /* Do nothing in data-only dump */
16476  if (dopt->dataOnly)
16477  return;
16478 
16479  q = createPQExpBuffer();
16480 
16482  {
16483  /* Set up query for partbound details */
16485  "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
16486 
16488  "SELECT pg_get_expr(c.relpartbound, c.oid) "
16489  "FROM pg_class c "
16490  "WHERE c.oid = $1");
16491 
16492  ExecuteSqlStatement(fout, q->data);
16493 
16494  fout->is_prepared[PREPQUERY_DUMPTABLEATTACH] = true;
16495  }
16496 
16498  "EXECUTE dumpTableAttach('%u')",
16499  attachinfo->partitionTbl->dobj.catId.oid);
16500 
16501  res = ExecuteSqlQueryForSingleRow(fout, q->data);
16502  partbound = PQgetvalue(res, 0, 0);
16503 
16504  /* Perform ALTER TABLE on the parent */
16506  "ALTER TABLE ONLY %s ",
16507  fmtQualifiedDumpable(attachinfo->parentTbl));
16509  "ATTACH PARTITION %s %s;\n",
16510  fmtQualifiedDumpable(attachinfo->partitionTbl),
16511  partbound);
16512 
16513  /*
16514  * There is no point in creating a drop query as the drop is done by table
16515  * drop. (If you think to change this, see also _printTocEntry().)
16516  * Although this object doesn't really have ownership as such, set the
16517  * owner field anyway to ensure that the command is run by the correct
16518  * role at restore time.
16519  */
16520  ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
16521  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
16522  .namespace = attachinfo->dobj.namespace->dobj.name,
16523  .owner = attachinfo->partitionTbl->rolname,
16524  .description = "TABLE ATTACH",
16525  .section = SECTION_PRE_DATA,
16526  .createStmt = q->data));
16527 
16528  PQclear(res);
16529  destroyPQExpBuffer(q);
16530 }
@ PREPQUERY_DUMPTABLEATTACH
Definition: pg_backup.h:74
TableInfo * partitionTbl
Definition: pg_dump.h:370
DumpableObject dobj
Definition: pg_dump.h:368
TableInfo * parentTbl
Definition: pg_dump.h:369

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

10038 {
10039  DumpOptions *dopt = fout->dopt;
10041  int ncomments;
10042  PQExpBuffer query;
10043  PQExpBuffer tag;
10044 
10045  /* do nothing, if --no-comments is supplied */
10046  if (dopt->no_comments)
10047  return;
10048 
10049  /* Comments are SCHEMA not data */
10050  if (dopt->dataOnly)
10051  return;
10052 
10053  /* Search for comments associated with relation, using table */
10055  tbinfo->dobj.catId.oid,
10056  &comments);
10057 
10058  /* If comments exist, build COMMENT ON statements */
10059  if (ncomments <= 0)
10060  return;
10061 
10062  query = createPQExpBuffer();
10063  tag = createPQExpBuffer();
10064 
10065  while (ncomments > 0)
10066  {
10067  const char *descr = comments->descr;
10068  int objsubid = comments->objsubid;
10069 
10070  if (objsubid == 0)
10071  {
10072  resetPQExpBuffer(tag);
10073  appendPQExpBuffer(tag, "%s %s", reltypename,
10074  fmtId(tbinfo->dobj.name));
10075 
10076  resetPQExpBuffer(query);
10077  appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
10078  fmtQualifiedDumpable(tbinfo));
10079  appendStringLiteralAH(query, descr, fout);
10080  appendPQExpBufferStr(query, ";\n");
10081 
10083  ARCHIVE_OPTS(.tag = tag->data,
10084  .namespace = tbinfo->dobj.namespace->dobj.name,
10085  .owner = tbinfo->rolname,
10086  .description = "COMMENT",
10087  .section = SECTION_NONE,
10088  .createStmt = query->data,
10089  .deps = &(tbinfo->dobj.dumpId),
10090  .nDeps = 1));
10091  }
10092  else if (objsubid > 0 && objsubid <= tbinfo->numatts)
10093  {
10094  resetPQExpBuffer(tag);
10095  appendPQExpBuffer(tag, "COLUMN %s.",
10096  fmtId(tbinfo->dobj.name));
10097  appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
10098 
10099  resetPQExpBuffer(query);
10100  appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
10101  fmtQualifiedDumpable(tbinfo));
10102  appendPQExpBuffer(query, "%s IS ",
10103  fmtId(tbinfo->attnames[objsubid - 1]));
10104  appendStringLiteralAH(query, descr, fout);
10105  appendPQExpBufferStr(query, ";\n");
10106 
10108  ARCHIVE_OPTS(.tag = tag->data,
10109  .namespace = tbinfo->dobj.namespace->dobj.name,
10110  .owner = tbinfo->rolname,
10111  .description = "COMMENT",
10112  .section = SECTION_NONE,
10113  .createStmt = query->data,
10114  .deps = &(tbinfo->dobj.dumpId),
10115  .nDeps = 1));
10116  }
10117 
10118  comments++;
10119  ncomments--;
10120  }
10121 
10122  destroyPQExpBuffer(query);
10123  destroyPQExpBuffer(tag);
10124 }

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

17171 {
17172  TableInfo *tbinfo = coninfo->contable;
17173  PQExpBuffer conprefix = createPQExpBuffer();
17174  char *qtabname;
17175 
17176  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17177 
17178  appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
17179  fmtId(coninfo->dobj.name));
17180 
17181  if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17182  dumpComment(fout, conprefix->data, qtabname,
17183  tbinfo->dobj.namespace->dobj.name,
17184  tbinfo->rolname,
17185  coninfo->dobj.catId, 0,
17186  coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
17187 
17188  destroyPQExpBuffer(conprefix);
17189  free(qtabname);
17190 }

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

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

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

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

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

15669 {
15670  DumpOptions *dopt = fout->dopt;
15672  PQExpBuffer delq = createPQExpBuffer();
15673  char *qrelname;
15674  char *qualrelname;
15675  int numParents;
15676  TableInfo **parents;
15677  int actual_atts; /* number of attrs in this CREATE statement */
15678  const char *reltypename;
15679  char *storage;
15680  int j,
15681  k;
15682 
15683  /* We had better have loaded per-column details about this table */
15684  Assert(tbinfo->interesting);
15685 
15686  qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
15687  qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
15688 
15689  if (tbinfo->hasoids)
15690  pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
15691  qrelname);
15692 
15693  if (dopt->binary_upgrade)
15694  binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
15695 
15696  /* Is it a table or a view? */
15697  if (tbinfo->relkind == RELKIND_VIEW)
15698  {
15699  PQExpBuffer result;
15700 
15701  /*
15702  * Note: keep this code in sync with the is_view case in dumpRule()
15703  */
15704 
15705  reltypename = "VIEW";
15706 
15707  appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
15708 
15709  if (dopt->binary_upgrade)
15711  tbinfo->dobj.catId.oid);
15712 
15713  appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
15714 
15715  if (tbinfo->dummy_view)
15716  result = createDummyViewAsClause(fout, tbinfo);
15717  else
15718  {
15719  if (nonemptyReloptions(tbinfo->reloptions))
15720  {
15721  appendPQExpBufferStr(q, " WITH (");
15722  appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
15723  appendPQExpBufferChar(q, ')');
15724  }
15725  result = createViewAsClause(fout, tbinfo);
15726  }
15727  appendPQExpBuffer(q, " AS\n%s", result->data);
15728  destroyPQExpBuffer(result);
15729 
15730  if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
15731  appendPQExpBuffer(q, "\n WITH %s CHECK OPTION", tbinfo->checkoption);
15732  appendPQExpBufferStr(q, ";\n");
15733  }
15734  else
15735  {
15736  char *partkeydef = NULL;
15737  char *ftoptions = NULL;
15738  char *srvname = NULL;
15739  char *foreign = "";
15740 
15741  /*
15742  * Set reltypename, and collect any relkind-specific data that we
15743  * didn't fetch during getTables().
15744  */
15745  switch (tbinfo->relkind)
15746  {
15747  case RELKIND_PARTITIONED_TABLE:
15748  {
15749  PQExpBuffer query = createPQExpBuffer();
15750  PGresult *res;
15751 
15752  reltypename = "TABLE";
15753 
15754  /* retrieve partition key definition */
15755  appendPQExpBuffer(query,
15756  "SELECT pg_get_partkeydef('%u')",
15757  tbinfo->dobj.catId.oid);
15758  res = ExecuteSqlQueryForSingleRow(fout, query->data);
15759  partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
15760  PQclear(res);
15761  destroyPQExpBuffer(query);
15762  break;
15763  }
15764  case RELKIND_FOREIGN_TABLE:
15765  {
15766  PQExpBuffer query = createPQExpBuffer();
15767  PGresult *res;
15768  int i_srvname;
15769  int i_ftoptions;
15770 
15771  reltypename = "FOREIGN TABLE";
15772 
15773  /* retrieve name of foreign server and generic options */
15774  appendPQExpBuffer(query,
15775  "SELECT fs.srvname, "
15776  "pg_catalog.array_to_string(ARRAY("
15777  "SELECT pg_catalog.quote_ident(option_name) || "
15778  "' ' || pg_catalog.quote_literal(option_value) "
15779  "FROM pg_catalog.pg_options_to_table(ftoptions) "
15780  "ORDER BY option_name"
15781  "), E',\n ') AS ftoptions "
15782  "FROM pg_catalog.pg_foreign_table ft "
15783  "JOIN pg_catalog.pg_foreign_server fs "
15784  "ON (fs.oid = ft.ftserver) "
15785  "WHERE ft.ftrelid = '%u'",
15786  tbinfo->dobj.catId.oid);
15787  res = ExecuteSqlQueryForSingleRow(fout, query->data);
15788  i_srvname = PQfnumber(res, "srvname");
15789  i_ftoptions = PQfnumber(res, "ftoptions");
15790  srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
15791  ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
15792  PQclear(res);
15793  destroyPQExpBuffer(query);
15794 
15795  foreign = "FOREIGN ";
15796  break;
15797  }
15798  case RELKIND_MATVIEW:
15799  reltypename = "MATERIALIZED VIEW";
15800  break;
15801  default:
15802  reltypename = "TABLE";
15803  break;
15804  }
15805 
15806  numParents = tbinfo->numParents;
15807  parents = tbinfo->parents;
15808 
15809  appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
15810 
15811  if (dopt->binary_upgrade)
15813  tbinfo->dobj.catId.oid);
15814 
15815  appendPQExpBuffer(q, "CREATE %s%s %s",
15816  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
15817  "UNLOGGED " : "",
15818  reltypename,
15819  qualrelname);
15820 
15821  /*
15822  * Attach to type, if reloftype; except in case of a binary upgrade,
15823  * we dump the table normally and attach it to the type afterward.
15824  */
15825  if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
15826  appendPQExpBuffer(q, " OF %s",
15827  getFormattedTypeName(fout, tbinfo->reloftype,
15828  zeroIsError));
15829 
15830  if (tbinfo->relkind != RELKIND_MATVIEW)
15831  {
15832  /* Dump the attributes */
15833  actual_atts = 0;
15834  for (j = 0; j < tbinfo->numatts; j++)
15835  {
15836  /*
15837  * Normally, dump if it's locally defined in this table, and
15838  * not dropped. But for binary upgrade, we'll dump all the
15839  * columns, and then fix up the dropped and nonlocal cases
15840  * below.
15841  */
15842  if (shouldPrintColumn(dopt, tbinfo, j))
15843  {
15844  bool print_default;
15845  bool print_notnull;
15846 
15847  /*
15848  * Default value --- suppress if to be printed separately
15849  * or not at all.
15850  */
15851  print_default = (tbinfo->attrdefs[j] != NULL &&
15852  tbinfo->attrdefs[j]->dobj.dump &&
15853  !tbinfo->attrdefs[j]->separate);
15854 
15855  /*
15856  * Not Null constraint --- suppress if inherited, except
15857  * if partition, or in binary-upgrade case where that
15858  * won't work.
15859  */
15860  print_notnull = (tbinfo->notnull[j] &&
15861  (!tbinfo->inhNotNull[j] ||
15862  tbinfo->ispartition || dopt->binary_upgrade));
15863 
15864  /*
15865  * Skip column if fully defined by reloftype, except in
15866  * binary upgrade
15867  */
15868  if (OidIsValid(tbinfo->reloftype) &&
15869  !print_default && !print_notnull &&
15870  !dopt->binary_upgrade)
15871  continue;
15872 
15873  /* Format properly if not first attr */
15874  if (actual_atts == 0)
15875  appendPQExpBufferStr(q, " (");
15876  else
15877  appendPQExpBufferChar(q, ',');
15878  appendPQExpBufferStr(q, "\n ");
15879  actual_atts++;
15880 
15881  /* Attribute name */
15882  appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
15883 
15884  if (tbinfo->attisdropped[j])
15885  {
15886  /*
15887  * ALTER TABLE DROP COLUMN clears
15888  * pg_attribute.atttypid, so we will not have gotten a
15889  * valid type name; insert INTEGER as a stopgap. We'll
15890  * clean things up later.
15891  */
15892  appendPQExpBufferStr(q, " INTEGER /* dummy */");
15893  /* and skip to the next column */
15894  continue;
15895  }
15896 
15897  /*
15898  * Attribute type; print it except when creating a typed
15899  * table ('OF type_name'), but in binary-upgrade mode,
15900  * print it in that case too.
15901  */
15902  if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
15903  {
15904  appendPQExpBuffer(q, " %s",
15905  tbinfo->atttypnames[j]);
15906  }
15907 
15908  if (print_default)
15909  {
15910  if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
15911  appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
15912  tbinfo->attrdefs[j]->adef_expr);
15913  else
15914  appendPQExpBuffer(q, " DEFAULT %s",
15915  tbinfo->attrdefs[j]->adef_expr);
15916  }
15917 
15918 
15919  if (print_notnull)
15920  appendPQExpBufferStr(q, " NOT NULL");
15921 
15922  /* Add collation if not default for the type */
15923  if (OidIsValid(tbinfo->attcollation[j]))
15924  {
15925  CollInfo *coll;
15926 
15927  coll = findCollationByOid(tbinfo->attcollation[j]);
15928  if (coll)
15929  appendPQExpBuffer(q, " COLLATE %s",
15930  fmtQualifiedDumpable(coll));
15931  }
15932  }
15933  }
15934 
15935  /*
15936  * Add non-inherited CHECK constraints, if any.
15937  *
15938  * For partitions, we need to include check constraints even if
15939  * they're not defined locally, because the ALTER TABLE ATTACH
15940  * PARTITION that we'll emit later expects the constraint to be
15941  * there. (No need to fix conislocal: ATTACH PARTITION does that)
15942  */
15943  for (j = 0; j < tbinfo->ncheck; j++)
15944  {
15945  ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
15946 
15947  if (constr->separate ||
15948  (!constr->conislocal && !tbinfo->ispartition))
15949  continue;
15950 
15951  if (actual_atts == 0)
15952  appendPQExpBufferStr(q, " (\n ");
15953  else
15954  appendPQExpBufferStr(q, ",\n ");
15955 
15956  appendPQExpBuffer(q, "CONSTRAINT %s ",
15957  fmtId(constr->dobj.name));
15958  appendPQExpBufferStr(q, constr->condef);
15959 
15960  actual_atts++;
15961  }
15962 
15963  if (actual_atts)
15964  appendPQExpBufferStr(q, "\n)");
15965  else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
15966  {
15967  /*
15968  * No attributes? we must have a parenthesized attribute list,
15969  * even though empty, when not using the OF TYPE syntax.
15970  */
15971  appendPQExpBufferStr(q, " (\n)");
15972  }
15973 
15974  /*
15975  * Emit the INHERITS clause (not for partitions), except in
15976  * binary-upgrade mode.
15977  */
15978  if (numParents > 0 && !tbinfo->ispartition &&
15979  !dopt->binary_upgrade)
15980  {
15981  appendPQExpBufferStr(q, "\nINHERITS (");
15982  for (k = 0; k < numParents; k++)
15983  {
15984  TableInfo *parentRel = parents[k];
15985 
15986  if (k > 0)
15987  appendPQExpBufferStr(q, ", ");
15989  }
15990  appendPQExpBufferChar(q, ')');
15991  }
15992 
15993  if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
15994  appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
15995 
15996  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
15997  appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
15998  }
15999 
16000  if (nonemptyReloptions(tbinfo->reloptions) ||
16002  {
16003  bool addcomma = false;
16004 
16005  appendPQExpBufferStr(q, "\nWITH (");
16006  if (nonemptyReloptions(tbinfo->reloptions))
16007  {
16008  addcomma = true;
16009  appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
16010  }
16011  if (nonemptyReloptions(tbinfo->toast_reloptions))
16012  {
16013  if (addcomma)
16014  appendPQExpBufferStr(q, ", ");
16015  appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
16016  fout);
16017  }
16018  appendPQExpBufferChar(q, ')');
16019  }
16020 
16021  /* Dump generic options if any */
16022  if (ftoptions && ftoptions[0])
16023  appendPQExpBuffer(q, "\nOPTIONS (\n %s\n)", ftoptions);
16024 
16025  /*
16026  * For materialized views, create the AS clause just like a view. At
16027  * this point, we always mark the view as not populated.
16028  */
16029  if (tbinfo->relkind == RELKIND_MATVIEW)
16030  {
16031  PQExpBuffer result;
16032 
16033  result = createViewAsClause(fout, tbinfo);
16034  appendPQExpBuffer(q, " AS\n%s\n WITH NO DATA;\n",
16035  result->data);
16036  destroyPQExpBuffer(result);
16037  }
16038  else
16039  appendPQExpBufferStr(q, ";\n");
16040 
16041  /* Materialized views can depend on extensions */
16042  if (tbinfo->relkind == RELKIND_MATVIEW)
16043  append_depends_on_extension(fout, q, &tbinfo->dobj,
16044  "pg_catalog.pg_class",
16045  "MATERIALIZED VIEW",
16046  qualrelname);
16047 
16048  /*
16049  * in binary upgrade mode, update the catalog with any missing values
16050  * that might be present.
16051  */
16052  if (dopt->binary_upgrade)
16053  {
16054  for (j = 0; j < tbinfo->numatts; j++)
16055  {
16056  if (tbinfo->attmissingval[j][0] != '\0')
16057  {
16058  appendPQExpBufferStr(q, "\n-- set missing value.\n");
16060  "SELECT pg_catalog.binary_upgrade_set_missing_value(");
16061  appendStringLiteralAH(q, qualrelname, fout);
16062  appendPQExpBufferStr(q, "::pg_catalog.regclass,");
16063  appendStringLiteralAH(q, tbinfo->attnames[j], fout);
16064  appendPQExpBufferChar(q, ',');
16065  appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
16066  appendPQExpBufferStr(q, ");\n\n");
16067  }
16068  }
16069  }
16070 
16071  /*
16072  * To create binary-compatible heap files, we have to ensure the same
16073  * physical column order, including dropped columns, as in the
16074  * original. Therefore, we create dropped columns above and drop them
16075  * here, also updating their attlen/attalign values so that the
16076  * dropped column can be skipped properly. (We do not bother with
16077  * restoring the original attbyval setting.) Also, inheritance
16078  * relationships are set up by doing ALTER TABLE INHERIT rather than
16079  * using an INHERITS clause --- the latter would possibly mess up the
16080  * column order. That also means we have to take care about setting
16081  * attislocal correctly, plus fix up any inherited CHECK constraints.
16082  * Analogously, we set up typed tables using ALTER TABLE / OF here.
16083  *
16084  * We process foreign and partitioned tables here, even though they
16085  * lack heap storage, because they can participate in inheritance
16086  * relationships and we want this stuff to be consistent across the
16087  * inheritance tree. We can exclude indexes, toast tables, sequences
16088  * and matviews, even though they have storage, because we don't
16089  * support altering or dropping columns in them, nor can they be part
16090  * of inheritance trees.
16091  */
16092  if (dopt->binary_upgrade &&
16093  (tbinfo->relkind == RELKIND_RELATION ||
16094  tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
16095  tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
16096  {
16097  for (j = 0; j < tbinfo->numatts; j++)
16098  {
16099  if (tbinfo->attisdropped[j])
16100  {
16101  appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped column.\n");
16102  appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
16103  "SET attlen = %d, "
16104  "attalign = '%c', attbyval = false\n"
16105  "WHERE attname = ",
16106  tbinfo->attlen[j],
16107  tbinfo->attalign[j]);
16108  appendStringLiteralAH(q, tbinfo->attnames[j], fout);
16109  appendPQExpBufferStr(q, "\n AND attrelid = ");
16110  appendStringLiteralAH(q, qualrelname, fout);
16111  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16112 
16113  if (tbinfo->relkind == RELKIND_RELATION ||
16114  tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
16115  appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
16116  qualrelname);
16117  else
16118  appendPQExpBuffer(q, "ALTER FOREIGN TABLE ONLY %s ",
16119  qualrelname);
16120  appendPQExpBuffer(q, "DROP COLUMN %s;\n",
16121  fmtId(tbinfo->attnames[j]));
16122  }
16123  else if (!tbinfo->attislocal[j])
16124  {
16125  appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited column.\n");
16126  appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
16127  "SET attislocal = false\n"
16128  "WHERE attname = ");
16129  appendStringLiteralAH(q, tbinfo->attnames[j], fout);
16130  appendPQExpBufferStr(q, "\n AND attrelid = ");
16131  appendStringLiteralAH(q, qualrelname, fout);
16132  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16133  }
16134  }
16135 
16136  /*
16137  * Add inherited CHECK constraints, if any.
16138  *
16139  * For partitions, they were already dumped, and conislocal
16140  * doesn't need fixing.
16141  */
16142  for (k = 0; k < tbinfo->ncheck; k++)
16143  {
16144  ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
16145 
16146  if (constr->separate || constr->conislocal || tbinfo->ispartition)
16147  continue;
16148 
16149  appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
16150  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
16151  foreign, qualrelname,
16152  fmtId(constr->dobj.name),
16153  constr->condef);
16154  appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
16155  "SET conislocal = false\n"
16156  "WHERE contype = 'c' AND conname = ");
16157  appendStringLiteralAH(q, constr->dobj.name, fout);
16158  appendPQExpBufferStr(q, "\n AND conrelid = ");
16159  appendStringLiteralAH(q, qualrelname, fout);
16160  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16161  }
16162 
16163  if (numParents > 0 && !tbinfo->ispartition)
16164  {
16165  appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
16166  for (k = 0; k < numParents; k++)
16167  {
16168  TableInfo *parentRel = parents[k];
16169 
16170  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
16171  qualrelname,
16172  fmtQualifiedDumpable(parentRel));
16173  }
16174  }
16175 
16176  if (OidIsValid(tbinfo->reloftype))
16177  {
16178  appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
16179  appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
16180  qualrelname,
16181  getFormattedTypeName(fout, tbinfo->reloftype,
16182  zeroIsError));
16183  }
16184  }
16185 
16186  /*
16187  * In binary_upgrade mode, arrange to restore the old relfrozenxid and
16188  * relminmxid of all vacuumable relations. (While vacuum.c processes
16189  * TOAST tables semi-independently, here we see them only as children
16190  * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
16191  * child toast table is handled below.)
16192  */
16193  if (dopt->binary_upgrade &&
16194  (tbinfo->relkind == RELKIND_RELATION ||
16195  tbinfo->relkind == RELKIND_MATVIEW))
16196  {
16197  appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
16198  appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
16199  "SET relfrozenxid = '%u', relminmxid = '%u'\n"
16200  "WHERE oid = ",
16201  tbinfo->frozenxid, tbinfo->minmxid);
16202  appendStringLiteralAH(q, qualrelname, fout);
16203  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16204 
16205  if (tbinfo->toast_oid)
16206  {
16207  /*
16208  * The toast table will have the same OID at restore, so we
16209  * can safely target it by OID.
16210  */
16211  appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
16212  appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
16213  "SET relfrozenxid = '%u', relminmxid = '%u'\n"
16214  "WHERE oid = '%u';\n",
16215  tbinfo->toast_frozenxid,
16216  tbinfo->toast_minmxid, tbinfo->toast_oid);
16217  }
16218  }
16219 
16220  /*
16221  * In binary_upgrade mode, restore matviews' populated status by
16222  * poking pg_class directly. This is pretty ugly, but we can't use
16223  * REFRESH MATERIALIZED VIEW since it's possible that some underlying
16224  * matview is not populated even though this matview is; in any case,
16225  * we want to transfer the matview's heap storage, not run REFRESH.
16226  */
16227  if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
16228  tbinfo->relispopulated)
16229  {
16230  appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
16231  appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
16232  "SET relispopulated = 't'\n"
16233  "WHERE oid = ");
16234  appendStringLiteralAH(q, qualrelname, fout);
16235  appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
16236  }
16237 
16238  /*
16239  * Dump additional per-column properties that we can't handle in the
16240  * main CREATE TABLE command.
16241  */
16242  for (j = 0; j < tbinfo->numatts; j++)
16243  {
16244  /* None of this applies to dropped columns */
16245  if (tbinfo->attisdropped[j])
16246  continue;
16247 
16248  /*
16249  * If we didn't dump the column definition explicitly above, and
16250  * it is not-null and did not inherit that property from a parent,
16251  * we have to mark it separately.
16252  */
16253  if (!shouldPrintColumn(dopt, tbinfo, j) &&
16254  tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
16256  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET NOT NULL;\n",
16257  foreign, qualrelname,
16258  fmtId(tbinfo->attnames[j]));
16259 
16260  /*
16261  * Dump per-column statistics information. We only issue an ALTER
16262  * TABLE statement if the attstattarget entry for this column is
16263  * not the default value.
16264  */
16265  if (tbinfo->attstattarget[j] >= 0)
16266  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
16267  foreign, qualrelname,
16268  fmtId(tbinfo->attnames[j]),
16269  tbinfo->attstattarget[j]);
16270 
16271  /*
16272  * Dump per-column storage information. The statement is only
16273  * dumped if the storage has been changed from the type's default.
16274  */
16275  if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
16276  {
16277  switch (tbinfo->attstorage[j])
16278  {
16279  case TYPSTORAGE_PLAIN:
16280  storage = "PLAIN";
16281  break;
16282  case TYPSTORAGE_EXTERNAL:
16283  storage = "EXTERNAL";
16284  break;
16285  case TYPSTORAGE_EXTENDED:
16286  storage = "EXTENDED";
16287  break;
16288  case TYPSTORAGE_MAIN:
16289  storage = "MAIN";
16290  break;
16291  default:
16292  storage = NULL;
16293  }
16294 
16295  /*
16296  * Only dump the statement if it's a storage type we recognize
16297  */
16298  if (storage != NULL)
16299  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
16300  foreign, qualrelname,
16301  fmtId(tbinfo->attnames[j]),
16302  storage);
16303  }
16304 
16305  /*
16306  * Dump per-column compression, if it's been set.
16307  */
16308  if (!dopt->no_toast_compression)
16309  {
16310  const char *cmname;
16311 
16312  switch (tbinfo->attcompression[j])
16313  {
16314  case 'p':
16315  cmname = "pglz";
16316  break;
16317  case 'l':
16318  cmname = "lz4";
16319  break;
16320  default:
16321  cmname = NULL;
16322  break;
16323  }
16324 
16325  if (cmname != NULL)
16326  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
16327  foreign, qualrelname,
16328  fmtId(tbinfo->attnames[j]),
16329  cmname);
16330  }
16331 
16332  /*
16333  * Dump per-column attributes.
16334  */
16335  if (tbinfo->attoptions[j][0] != '\0')
16336  appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
16337  foreign, qualrelname,
16338  fmtId(tbinfo->attnames[j]),
16339  tbinfo->attoptions[j]);
16340 
16341  /*
16342  * Dump per-column fdw options.
16343  */
16344  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
16345  tbinfo->attfdwoptions[j][0] != '\0')
16347  "ALTER FOREIGN TABLE %s ALTER COLUMN %s OPTIONS (\n"
16348  " %s\n"
16349  ");\n",
16350  qualrelname,
16351  fmtId(tbinfo->attnames[j]),
16352  tbinfo->attfdwoptions[j]);
16353  } /* end loop over columns */
16354 
16355  free(partkeydef);
16356  free(ftoptions);
16357  free(srvname);
16358  }
16359 
16360  /*
16361  * dump properties we only have ALTER TABLE syntax for
16362  */
16363  if ((tbinfo->relkind == RELKIND_RELATION ||
16364  tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
16365  tbinfo->relkind == RELKIND_MATVIEW) &&
16366  tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
16367  {
16368  if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
16369  {
16370  /* nothing to do, will be set when the index is dumped */
16371  }
16372  else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
16373  {
16374  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
16375  qualrelname);
16376  }
16377  else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
16378  {
16379  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
16380  qualrelname);
16381  }
16382  }
16383 
16384  if (tbinfo->forcerowsec)
16385  appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
16386  qualrelname);
16387 
16388  if (dopt->binary_upgrade)
16390  reltypename, qrelname,
16391  tbinfo->dobj.namespace->dobj.name);
16392 
16393  if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16394  {
16395  char *tablespace = NULL;
16396  char *tableam = NULL;
16397 
16398  /*
16399  * _selectTablespace() relies on tablespace-enabled objects in the
16400  * default tablespace to have a tablespace of "" (empty string) versus
16401  * non-tablespace-enabled objects to have a tablespace of NULL.
16402  * getTables() sets tbinfo->reltablespace to "" for the default
16403  * tablespace (not NULL).
16404  */
16405  if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
16406  tablespace = tbinfo->reltablespace;
16407 
16408  if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
16409  tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
16410  tableam = tbinfo->amname;
16411 
16412  ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
16413  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
16414  .namespace = tbinfo->dobj.namespace->dobj.name,
16415  .tablespace = tablespace,
16416  .tableam = tableam,
16417  .relkind = tbinfo->relkind,
16418  .owner = tbinfo->rolname,
16419  .description = reltypename,
16420  .section = tbinfo->postponed_def ?
16422  .createStmt = q->data,
16423  .dropStmt = delq->data));
16424  }
16425 
16426  /* Dump Table Comments */
16427  if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16428  dumpTableComment(fout, tbinfo, reltypename);
16429 
16430  /* Dump Table Security Labels */
16431  if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
16432  dumpTableSecLabel(fout, tbinfo, reltypename);
16433 
16434  /* Dump comments on inlined table constraints */
16435  for (j = 0; j < tbinfo->ncheck; j++)
16436  {
16437  ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
16438 
16439  if (constr->separate || !constr->conislocal)
16440  continue;
16441 
16442  if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
16443  dumpTableConstraintComment(fout, constr);
16444  }
16445 
16446  destroyPQExpBuffer(q);
16447  destroyPQExpBuffer(delq);
16448  free(qrelname);
16449  free(qualrelname);
16450 }
#define storage
Definition: indent_codes.h:68
static void dumpTableComment(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:10036
static void binary_upgrade_set_type_oids_by_rel(Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tbinfo)
Definition: pg_dump.c:5402
bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
Definition: pg_dump.c:9178
static void dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:15192
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:352
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:351
char ** attoptions
Definition: pg_dump.h:344
char relreplident
Definition: pg_dump.h:291
uint32 minmxid
Definition: pg_dump.h:304
char * attstorage
Definition: pg_dump.h:336
bool * notnull
Definition: pg_dump.h:349
char * amname
Definition: pg_dump.h:354
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
bool * inhNotNull
Definition: pg_dump.h:350

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::inhNotNull, _tableInfo::interesting, _tableInfo::ispartition, j, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, _dumpOptions::no_toast_compression, nonemptyReloptions(), _tableInfo::notnull, _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 15192 of file pg_dump.c.

15193 {
15194  DumpOptions *dopt = fout->dopt;
15195  SecLabelItem *labels;
15196  int nlabels;
15197  int i;
15198  PQExpBuffer query;
15199  PQExpBuffer target;
15200 
15201  /* do nothing, if --no-security-labels is supplied */
15202  if (dopt->no_security_labels)
15203  return;
15204 
15205  /* SecLabel are SCHEMA not data */
15206  if (dopt->dataOnly)
15207  return;
15208 
15209  /* Search for comments associated with relation, using table */
15210  nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
15211  tbinfo->dobj.catId.oid,
15212  &labels);
15213 
15214  /* If security labels exist, build SECURITY LABEL statements */
15215  if (nlabels <= 0)
15216  return;
15217 
15218  query = createPQExpBuffer();
15219  target = createPQExpBuffer();
15220 
15221  for (i = 0; i < nlabels; i++)
15222  {
15223  const char *colname;
15224  const char *provider = labels[i].provider;
15225  const char *label = labels[i].label;
15226  int objsubid = labels[i].objsubid;
15227 
15228  resetPQExpBuffer(target);
15229  if (objsubid == 0)
15230  {
15231  appendPQExpBuffer(target, "%s %s", reltypename,
15232  fmtQualifiedDumpable(tbinfo));
15233  }
15234  else
15235  {
15236  colname = getAttrName(objsubid, tbinfo);
15237  /* first fmtXXX result must be consumed before calling again */
15238  appendPQExpBuffer(target, "COLUMN %s",
15239  fmtQualifiedDumpable(tbinfo));
15240  appendPQExpBuffer(target, ".%s", fmtId(colname));
15241  }
15242  appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
15243  fmtId(provider), target->data);
15244  appendStringLiteralAH(query, label, fout);
15245  appendPQExpBufferStr(query, ";\n");
15246  }
15247  if (query->len > 0)
15248  {
15249  resetPQExpBuffer(target);
15250  appendPQExpBuffer(target, "%s %s", reltypename,
15251  fmtId(tbinfo->dobj.name));
15253  ARCHIVE_OPTS(.tag = target->data,
15254  .namespace = tbinfo->dobj.namespace->dobj.name,
15255  .owner = tbinfo->rolname,
15256  .description = "SECURITY LABEL",
15257  .section = SECTION_NONE,
15258  .createStmt = query->data,
15259  .deps = &(tbinfo->dobj.dumpId),
15260  .nDeps = 1));
15261  }
15262  destroyPQExpBuffer(query);
15263  destroyPQExpBuffer(target);
15264 }

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

12556 {
12557  DumpOptions *dopt = fout->dopt;
12558  PQExpBuffer defqry;
12559  PQExpBuffer delqry;
12560  PQExpBuffer labelq;
12561  PQExpBuffer transformargs;
12562  FuncInfo *fromsqlFuncInfo = NULL;
12563  FuncInfo *tosqlFuncInfo = NULL;
12564  char *lanname;
12565  const char *transformType;
12566 
12567  /* Do nothing in data-only dump */
12568  if (dopt->dataOnly)
12569  return;
12570 
12571  /* Cannot dump if we don't have the transform functions' info */
12572  if (OidIsValid(transform->trffromsql))
12573  {
12574  fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
12575  if (fromsqlFuncInfo == NULL)
12576  pg_fatal("could not find function definition for function with OID %u",
12577  transform->trffromsql);
12578  }
12579  if (OidIsValid(transform->trftosql))
12580  {
12581  tosqlFuncInfo = findFuncByOid(transform->trftosql);
12582  if (tosqlFuncInfo == NULL)
12583  pg_fatal("could not find function definition for function with OID %u",
12584  transform->trftosql);
12585  }
12586 
12587  defqry = createPQExpBuffer();
12588  delqry = createPQExpBuffer();
12589  labelq = createPQExpBuffer();
12590  transformargs = createPQExpBuffer();
12591 
12592  lanname = get_language_name(fout, transform->trflang);
12593  transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
12594 
12595  appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
12596  transformType, lanname);
12597 
12598  appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
12599  transformType, lanname);
12600 
12601  if (!transform->trffromsql && !transform->trftosql)
12602  pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
12603 
12604  if (transform->trffromsql)
12605  {
12606  if (fromsqlFuncInfo)
12607  {
12608  char *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
12609 
12610  /*
12611  * Always qualify the function name (format_function_signature
12612  * won't qualify it).
12613  */
12614  appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
12615  fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
12616  free(fsig);
12617  }
12618  else
12619  pg_log_warning("bogus value in pg_transform.trffromsql field");
12620  }
12621 
12622  if (transform->trftosql)
12623  {
12624  if (transform->trffromsql)
12625  appendPQExpBufferStr(defqry, ", ");
12626 
12627  if (tosqlFuncInfo)
12628  {
12629  char *fsig = format_function_signature(fout, tosqlFuncInfo, true);
12630 
12631  /*
12632  * Always qualify the function name (format_function_signature
12633  * won't qualify it).
12634  */
12635  appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
12636  fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
12637  free(fsig);
12638  }
12639  else
12640  pg_log_warning("bogus value in pg_transform.trftosql field");
12641  }
12642 
12643  appendPQExpBufferStr(defqry, ");\n");
12644 
12645  appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
12646  transformType, lanname);
12647 
12648  appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
12649  transformType, lanname);
12650 
12651  if (dopt->binary_upgrade)
12652  binary_upgrade_extension_member(defqry, &transform->dobj,
12653  "TRANSFORM", transformargs->data, NULL);
12654 
12655  if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
12656  ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
12657  ARCHIVE_OPTS(.tag = labelq->data,
12658  .description = "TRANSFORM",
12659  .section = SECTION_PRE_DATA,
12660  .createStmt = defqry->data,
12661  .dropStmt = delqry->data,
12662  .deps = transform->dobj.dependencies,
12663  .nDeps = transform->dobj.nDeps));
12664 
12665  /* Dump Transform Comments */
12666  if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
12667  dumpComment(fout, "TRANSFORM", transformargs->data,
12668  NULL, "",
12669  transform->dobj.catId, 0, transform->dobj.dumpId);
12670 
12671  free(lanname);
12672  destroyPQExpBuffer(defqry);
12673  destroyPQExpBuffer(delqry);
12674  destroyPQExpBuffer(labelq);
12675  destroyPQExpBuffer(transformargs);
12676 }
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8516
DumpableObject dobj
Definition: pg_dump.h:504
Oid trffromsql
Definition: pg_dump.h:507

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

17514 {
17515  DumpOptions *dopt = fout->dopt;
17516  TableInfo *tbinfo = tginfo->tgtable;
17517  PQExpBuffer query;
17518  PQExpBuffer delqry;
17519  PQExpBuffer trigprefix;
17520  PQExpBuffer trigidentity;
17521  char *qtabname;
17522  char *tag;
17523 
17524  /* Do nothing in data-only dump */
17525  if (dopt->dataOnly)
17526  return;
17527 
17528  query = createPQExpBuffer();
17529  delqry = createPQExpBuffer();
17530  trigprefix = createPQExpBuffer();
17531  trigidentity = createPQExpBuffer();
17532 
17533  qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17534 
17535  appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
17536  appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
17537 
17538  appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
17539  appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
17540 
17541  /* Triggers can depend on extensions */
17542  append_depends_on_extension(fout, query, &tginfo->dobj,
17543  "pg_catalog.pg_trigger", "TRIGGER",
17544  trigidentity->data);
17545 
17546  if (tginfo->tgispartition)
17547  {
17548  Assert(tbinfo->ispartition);
17549 
17550  /*
17551  * Partition triggers only appear here because their 'tgenabled' flag
17552  * differs from its parent's. The trigger is created already, so
17553  * remove the CREATE and replace it with an ALTER. (Clear out the
17554  * DROP query too, so that pg_dump --create does not cause errors.)
17555  */
17556  resetPQExpBuffer(query);
17557  resetPQExpBuffer(delqry);
17558  appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17559  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17560  fmtQualifiedDumpable(tbinfo));
17561  switch (tginfo->tgenabled)
17562  {
17563  case 'f':
17564  case 'D':
17565  appendPQExpBufferStr(query, "DISABLE");
17566  break;
17567  case 't':
17568  case 'O':
17569  appendPQExpBufferStr(query, "ENABLE");
17570  break;
17571  case 'R':
17572  appendPQExpBufferStr(query, "ENABLE REPLICA");
17573  break;
17574  case 'A':
17575  appendPQExpBufferStr(query, "ENABLE ALWAYS");
17576  break;
17577  }
17578  appendPQExpBuffer(query, " TRIGGER %s;\n",
17579  fmtId(tginfo->dobj.name));
17580  }
17581  else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17582  {
17583  appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17584  tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17585  fmtQualifiedDumpable(tbinfo));
17586  switch (tginfo->tgenabled)
17587  {
17588  case 'D':
17589  case 'f':
17590  appendPQExpBufferStr(query, "DISABLE");
17591  break;
17592  case 'A':
17593  appendPQExpBufferStr(query, "ENABLE ALWAYS");
17594  break;
17595  case 'R':
17596  appendPQExpBufferStr(query, "ENABLE REPLICA");
17597  break;
17598  default:
17599  appendPQExpBufferStr(query, "ENABLE");
17600  break;
17601  }
17602  appendPQExpBuffer(query, " TRIGGER %s;\n",
17603  fmtId(tginfo->dobj.name));
17604  }
17605 
17606  appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
17607  fmtId(tginfo->dobj.name));
17608 
17609  tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
17610 
17611  if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17612  ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
17613  ARCHIVE_OPTS(.tag = tag,
17614  .namespace = tbinfo->dobj.namespace->dobj.name,
17615  .owner = tbinfo->rolname,
17616  .description = "TRIGGER",
17617  .section = SECTION_POST_DATA,
17618  .createStmt = query->data,
17619  .dropStmt = delqry->data));
17620 
17621  if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17622  dumpComment(fout, trigprefix->data, qtabname,
17623  tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
17624  tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
17625 
17626  free(tag);
17627  destroyPQExpBuffer(query);
17628  destroyPQExpBuffer(delqry);
17629  destroyPQExpBuffer(trigprefix);
17630  destroyPQExpBuffer(trigidentity);
17631  free(qtabname);
17632 }
TableInfo * tgtable
Definition: pg_dump.h:441
DumpableObject dobj
Definition: pg_dump.h:440
char tgenabled
Definition: pg_dump.h:442
char * tgdef
Definition: pg_dump.h:444
bool tgispartition
Definition: pg_dump.h:443

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

14512 {
14513  DumpOptions *dopt = fout->dopt;
14514  PQExpBuffer q;
14515  PQExpBuffer delq;
14516  PQExpBuffer query;
14517  char *qcfgname;
14518  PGresult *res;
14519  char *nspname;
14520  char *prsname;
14521  int ntups,
14522  i;
14523  int i_tokenname;
14524  int i_dictname;
14525 
14526  /* Do nothing in data-only dump */
14527  if (dopt->dataOnly)
14528  return;
14529 
14530  q = createPQExpBuffer();
14531  delq = createPQExpBuffer();
14532  query = createPQExpBuffer();
14533 
14534  qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
14535 
14536  /* Fetch name and namespace of the config's parser */
14537  appendPQExpBuffer(query, "SELECT nspname, prsname "
14538  "FROM pg_ts_parser p, pg_namespace n "
14539  "WHERE p.oid = '%u' AND n.oid = prsnamespace",
14540  cfginfo->cfgparser);
14541  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14542  nspname = PQgetvalue(res, 0, 0);
14543  prsname = PQgetvalue(res, 0, 1);
14544 
14545  appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
14546  fmtQualifiedDumpable(cfginfo));
14547 
14548  appendPQExpBuffer(q, " PARSER = %s.", fmtId(nspname));
14549  appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
14550 
14551  PQclear(res);
14552 
14553  resetPQExpBuffer(query);
14554  appendPQExpBuffer(query,
14555  "SELECT\n"
14556  " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
14557  " WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
14558  " m.mapdict::pg_catalog.regdictionary AS dictname\n"
14559  "FROM pg_catalog.pg_ts_config_map AS m\n"
14560  "WHERE m.mapcfg = '%u'\n"
14561  "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
14562  cfginfo->cfgparser, cfginfo->dobj.catId.oid);
14563 
14564  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14565  ntups = PQntuples(res);
14566 
14567  i_tokenname = PQfnumber(res, "tokenname");
14568  i_dictname = PQfnumber(res, "dictname");
14569 
14570  for (i = 0; i < ntups; i++)
14571  {
14572  char *tokenname = PQgetvalue(res, i, i_tokenname);
14573  char *dictname = PQgetvalue(res, i, i_dictname);
14574 
14575  if (i == 0 ||
14576  strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
14577  {
14578  /* starting a new token type, so start a new command */
14579  if (i > 0)
14580  appendPQExpBufferStr(q, ";\n");
14581  appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
14582  fmtQualifiedDumpable(cfginfo));
14583  /* tokenname needs quoting, dictname does NOT */
14584  appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
14585  fmtId(tokenname), dictname);
14586  }
14587  else
14588  appendPQExpBuffer(q, ", %s", dictname);
14589  }
14590 
14591  if (ntups > 0)
14592  appendPQExpBufferStr(q, ";\n");
14593 
14594  PQclear(res);
14595 
14596  appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
14597  fmtQualifiedDumpable(cfginfo));
14598 
14599  if (dopt->binary_upgrade)
14601  "TEXT SEARCH CONFIGURATION", qcfgname,
14602  cfginfo->dobj.namespace->dobj.name);
14603 
14604  if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14605  ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
14606  ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
14607  .namespace = cfginfo->dobj.namespace->dobj.name,
14608  .owner = cfginfo->rolname,
14609  .description = "TEXT SEARCH CONFIGURATION",
14610  .section = SECTION_PRE_DATA,
14611  .createStmt = q->data,
14612  .dropStmt = delq->data));
14613 
14614  /* Dump Configuration Comments */
14615  if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14616  dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
14617  cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
14618  cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
14619 
14620  destroyPQExpBuffer(q);
14621  destroyPQExpBuffer(delq);
14622  destroyPQExpBuffer(query);
14623  free(qcfgname);
14624 }
Oid cfgparser
Definition: pg_dump.h:547
DumpableObject dobj
Definition: pg_dump.h:545
const char * rolname
Definition: pg_dump.h:546

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

14374 {
14375  DumpOptions *dopt = fout->dopt;
14376  PQExpBuffer q;
14377  PQExpBuffer delq;
14378  PQExpBuffer query;
14379  char *qdictname;
14380  PGresult *res;
14381  char *nspname;
14382  char *tmplname;
14383 
14384  /* Do nothing in data-only dump */
14385  if (dopt->dataOnly)
14386  return;
14387 
14388  q = createPQExpBuffer();
14389  delq = createPQExpBuffer();
14390  query = createPQExpBuffer();
14391 
14392  qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
14393 
14394  /* Fetch name and namespace of the dictionary's template */
14395  appendPQExpBuffer(query, "SELECT nspname, tmplname "
14396  "FROM pg_ts_template p, pg_namespace n "
14397  "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
14398  dictinfo->dicttemplate);
14399  res = ExecuteSqlQueryForSingleRow(fout, query->data);
14400  nspname = PQgetvalue(res, 0, 0);
14401  tmplname = PQgetvalue(res, 0, 1);
14402 
14403  appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
14404  fmtQualifiedDumpable(dictinfo));
14405 
14406  appendPQExpBufferStr(q, " TEMPLATE = ");
14407  appendPQExpBuffer(q, "%s.", fmtId(nspname));
14408  appendPQExpBufferStr(q, fmtId(tmplname));
14409 
14410  PQclear(res);
14411 
14412  /* the dictinitoption can be dumped straight into the command */
14413  if (dictinfo->dictinitoption)
14414  appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
14415 
14416  appendPQExpBufferStr(q, " );\n");
14417 
14418  appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
14419  fmtQualifiedDumpable(dictinfo));
14420 
14421  if (dopt->binary_upgrade)
14422  binary_upgrade_extension_member(q, &dictinfo->dobj,
14423  "TEXT SEARCH DICTIONARY", qdictname,
14424  dictinfo->dobj.namespace->dobj.name);
14425 
14426  if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14427  ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
14428  ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
14429  .namespace = dictinfo->dobj.namespace->dobj.name,
14430  .owner = dictinfo->rolname,
14431  .description = "TEXT SEARCH DICTIONARY",
14432  .section = SECTION_PRE_DATA,
14433  .createStmt = q->data,
14434  .dropStmt = delq->data));
14435 
14436  /* Dump Dictionary Comments */
14437  if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14438  dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
14439  dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
14440  dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
14441 
14442  destroyPQExpBuffer(q);
14443  destroyPQExpBuffer(delq);
14444  destroyPQExpBuffer(query);
14445  free(qdictname);
14446 }
char * dictinitoption
Definition: pg_dump.h:533
DumpableObject dobj
Definition: pg_dump.h:530
const char * rolname
Definition: pg_dump.h:531
Oid dicttemplate
Definition: pg_dump.h:532

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

14310 {
14311  DumpOptions *dopt = fout->dopt;
14312  PQExpBuffer q;
14313  PQExpBuffer delq;
14314  char *qprsname;
14315 
14316  /* Do nothing in data-only dump */
14317  if (dopt->dataOnly)
14318  return;
14319 
14320  q = createPQExpBuffer();
14321  delq = createPQExpBuffer();
14322 
14323  qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
14324 
14325  appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
14326  fmtQualifiedDumpable(prsinfo));
14327 
14328  appendPQExpBuffer(q, " START = %s,\n",
14329  convertTSFunction(fout, prsinfo->prsstart));
14330  appendPQExpBuffer(q, " GETTOKEN = %s,\n",
14331  convertTSFunction(fout, prsinfo->prstoken));
14332  appendPQExpBuffer(q, " END = %s,\n",
14333  convertTSFunction(fout, prsinfo->prsend));
14334  if (prsinfo->prsheadline != InvalidOid)
14335  appendPQExpBuffer(q, " HEADLINE = %s,\n",
14336  convertTSFunction(fout, prsinfo->prsheadline));
14337  appendPQExpBuffer(q, " LEXTYPES = %s );\n",
14338  convertTSFunction(fout, prsinfo->prslextype));
14339 
14340  appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
14341  fmtQualifiedDumpable(prsinfo));
14342 
14343  if (dopt->binary_upgrade)
14345  "TEXT SEARCH PARSER", qprsname,
14346  prsinfo->dobj.namespace->dobj.name);
14347 
14348  if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14349  ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
14350  ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
14351  .namespace = prsinfo->dobj.namespace->dobj.name,
14352  .description = "TEXT SEARCH PARSER",
14353  .section = SECTION_PRE_DATA,
14354  .createStmt = q->data,
14355  .dropStmt = delq->data));
14356 
14357  /* Dump Parser Comments */
14358  if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14359  dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
14360  prsinfo->dobj.namespace->dobj.name, "",
14361  prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
14362 
14363  destroyPQExpBuffer(q);
14364  destroyPQExpBuffer(delq);
14365  free(qprsname);
14366 }
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:12974
#define InvalidOid
Definition: postgres_ext.h:36
DumpableObject dobj
Definition: pg_dump.h:520
Oid prstoken
Definition: pg_dump.h:522
Oid prslextype
Definition: pg_dump.h:525
Oid prsheadline
Definition: pg_dump.h:524
Oid prsstart
Definition: pg_dump.h:521
Oid prsend
Definition: pg_dump.h:523

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

14454 {
14455  DumpOptions *dopt = fout->dopt;
14456  PQExpBuffer q;
14457  PQExpBuffer delq;
14458  char *qtmplname;
14459 
14460  /* Do nothing in data-only dump */
14461  if (dopt->dataOnly)
14462  return;
14463 
14464  q = createPQExpBuffer();
14465  delq = createPQExpBuffer();
14466 
14467  qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
14468 
14469  appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
14470  fmtQualifiedDumpable(tmplinfo));
14471 
14472  if (tmplinfo->tmplinit != InvalidOid)
14473  appendPQExpBuffer(q, " INIT = %s,\n",
14474  convertTSFunction(fout, tmplinfo->tmplinit));
14475  appendPQExpBuffer(q, " LEXIZE = %s );\n",
14476  convertTSFunction(fout, tmplinfo->tmpllexize));
14477 
14478  appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
14479  fmtQualifiedDumpable(tmplinfo));
14480 
14481  if (dopt->binary_upgrade)
14482  binary_upgrade_extension_member(q, &tmplinfo->dobj,
14483  "TEXT SEARCH TEMPLATE", qtmplname,
14484  tmplinfo->dobj.namespace->dobj.name);
14485 
14486  if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14487  ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
14488  ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
14489  .namespace = tmplinfo->dobj.namespace->dobj.name,
14490  .description = "TEXT SEARCH TEMPLATE",
14491  .section = SECTION_PRE_DATA,
14492  .createStmt = q->data,
14493  .dropStmt = delq->data));
14494 
14495  /* Dump Template Comments */
14496  if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14497  dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
14498  tmplinfo->dobj.namespace->dobj.name, "",
14499  tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
14500 
14501  destroyPQExpBuffer(q);
14502  destroyPQExpBuffer(delq);
14503  free(qtmplname);
14504 }
Oid tmpllexize
Definition: pg_dump.h:540
Oid tmplinit
Definition: pg_dump.h:539
DumpableObject dobj
Definition: pg_dump.h:538

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

10695 {
10696  DumpOptions *dopt = fout->dopt;
10697 
10698  /* Do nothing in data-only dump */
10699  if (dopt->dataOnly)
10700  return;
10701 
10702  /* Dump out in proper style */
10703  if (tyinfo->typtype == TYPTYPE_BASE)
10704  dumpBaseType(fout, tyinfo);
10705  else if (tyinfo->typtype == TYPTYPE_DOMAIN)
10706  dumpDomain(fout, tyinfo);
10707  else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
10708  dumpCompositeType(fout, tyinfo);
10709  else if (tyinfo->typtype == TYPTYPE_ENUM)
10710  dumpEnumType(fout, tyinfo);
10711  else if (tyinfo->typtype == TYPTYPE_RANGE)
10712  dumpRangeType(fout, tyinfo);
10713  else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
10714  dumpUndefinedType(fout, tyinfo);
10715  else
10716  pg_log_warning("typtype of data type \"%s\" appears to be invalid",
10717  tyinfo->dobj.name);
10718 }
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11087
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:10865
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11336
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11023
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11509
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:10725
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 11023 of file pg_dump.c.

11024 {
11025  DumpOptions *dopt = fout->dopt;
11027  PQExpBuffer delq = createPQExpBuffer();
11028  char *qtypname;
11029  char *qualtypname;
11030 
11031  qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11032  qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11033 
11034  appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11035 
11036  if (dopt->binary_upgrade)
11038  tyinfo->dobj.catId.oid,
11039  false, false);
11040 
11041  appendPQExpBuffer(q, "CREATE TYPE %s;\n",
11042  qualtypname);
11043 
11044  if (dopt->binary_upgrade)
11046  "TYPE", qtypname,
11047  tyinfo->dobj.namespace->dobj.name);
11048 
11049  if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11050  ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11051  ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11052  .namespace = tyinfo->dobj.namespace->dobj.name,
11053  .owner = tyinfo->rolname,
11054  .description = "TYPE",
11055  .section = SECTION_PRE_DATA,
11056  .createStmt = q->data,
11057  .dropStmt = delq->data));
11058 
11059  /* Dump Type Comments and Security Labels */
11060  if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11061  dumpComment(fout, "TYPE", qtypname,
11062  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11063  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11064 
11065  if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11066  dumpSecLabel(fout, "TYPE", qtypname,
11067  tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11068  tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11069 
11070  if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11071  dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11072  qtypname, NULL,
11073  tyinfo->dobj.namespace->dobj.name,
11074  NULL, tyinfo->rolname, &tyinfo->dacl);
11075 
11076  destroyPQExpBuffer(q);
11077  destroyPQExpBuffer(delq);
11078  free(qtypname);
11079  free(qualtypname);
11080 }

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

14805 {
14806  PQExpBuffer q;
14807  PQExpBuffer delq;
14808  PQExpBuffer query;
14809  PQExpBuffer tag;
14810  PGresult *res;
14811  int ntups;
14812  int i_usename;
14813  int i_umoptions;
14814  int i;
14815 
14816  q = createPQExpBuffer();
14817  tag = createPQExpBuffer();
14818  delq = createPQExpBuffer();
14819  query = createPQExpBuffer();
14820 
14821  /*
14822  * We read from the publicly accessible view pg_user_mappings, so as not
14823  * to fail if run by a non-superuser. Note that the view will show
14824  * umoptions as null if the user hasn't got privileges for the associated
14825  * server; this means that pg_dump will dump such a mapping, but with no
14826  * OPTIONS clause. A possible alternative is to skip such mappings
14827  * altogether, but it's not clear that that's an improvement.
14828  */
14829  appendPQExpBuffer(query,
14830  "SELECT usename, "
14831  "array_to_string(ARRAY("
14832  "SELECT quote_ident(option_name) || ' ' || "
14833  "quote_literal(option_value) "
14834  "FROM pg_options_to_table(umoptions) "
14835  "ORDER BY option_name"
14836  "), E',\n ') AS umoptions "
14837  "FROM pg_user_mappings "
14838  "WHERE srvid = '%u' "
14839  "ORDER BY usename",
14840  catalogId.oid);
14841 
14842  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14843 
14844  ntups = PQntuples(res);
14845  i_usename = PQfnumber(res, "usename");
14846  i_umoptions = PQfnumber(res, "umoptions");
14847 
14848  for (i = 0; i < ntups; i++)
14849  {
14850  char *usename;
14851  char *umoptions;
14852 
14853  usename = PQgetvalue(res, i, i_usename);
14854  umoptions = PQgetvalue(res, i, i_umoptions);
14855 
14856  resetPQExpBuffer(q);
14857  appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
14858  appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
14859 
14860  if (umoptions && strlen(umoptions) > 0)
14861  appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions);
14862 
14863  appendPQExpBufferStr(q, ";\n");
14864 
14865  resetPQExpBuffer(delq);
14866  appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
14867  appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
14868 
14869  resetPQExpBuffer(tag);
14870  appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
14871  usename, servername);
14872 
14874  ARCHIVE_OPTS(.tag = tag->data,
14875  .namespace = namespace,
14876  .owner = owner,
14877  .description = "USER MAPPING",
14878  .section = SECTION_PRE_DATA,
14879  .createStmt = q->data,
14880  .dropStmt = delq->data));
14881  }
14882 
14883  PQclear(res);
14884 
14885  destroyPQExpBuffer(query);
14886  destroyPQExpBuffer(delq);
14887  destroyPQExpBuffer(tag);
14888  destroyPQExpBuffer(q);
14889 }

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

1502 {
1503  PQExpBuffer query;
1504  PGresult *res;
1505  SimpleStringListCell *cell;
1506  int i;
1507 
1508  if (patterns->head == NULL)
1509  return; /* nothing to do */
1510 
1511  query = createPQExpBuffer();
1512 
1513  /*
1514  * The loop below runs multiple SELECTs might sometimes result in
1515  * duplicate entries in the OID list, but we don't care.
1516  */
1517  for (cell = patterns->head; cell; cell = cell->next)
1518  {
1519  int dotcnt;
1520 
1521  appendPQExpBufferStr(query,
1522  "SELECT oid FROM pg_catalog.pg_extension e\n");
1523  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1524  false, NULL, "e.extname", NULL, NULL, NULL,
1525  &dotcnt);
1526  if (dotcnt > 0)
1527  pg_fatal("improper qualified name (too many dotted names): %s",
1528  cell->val);
1529 
1530  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1531  if (strict_names && PQntuples(res) == 0)
1532  pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
1533 
1534  for (i = 0; i < PQntuples(res); i++)
1535  {
1537  }
1538 
1539  PQclear(res);
1540  resetPQExpBuffer(query);
1541  }
1542 
1543  destroyPQExpBuffer(query);
1544 }
static int strict_names
Definition: pg_dump.c:120
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 1551 of file pg_dump.c.

1554 {
1555  PQExpBuffer query;
1556  PGresult *res;
1557  SimpleStringListCell *cell;
1558  int i;
1559 
1560  if (patterns->head == NULL)
1561  return; /* nothing to do */
1562 
1563  query = createPQExpBuffer();
1564 
1565  /*
1566  * The loop below runs multiple SELECTs might sometimes result in
1567  * duplicate entries in the OID list, but we don't care.
1568  */
1569 
1570  for (cell = patterns->head; cell; cell = cell->next)
1571  {
1572  int dotcnt;
1573 
1574  appendPQExpBufferStr(query,
1575  "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
1576  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1577  false, NULL, "s.srvname", NULL, NULL, NULL,
1578  &dotcnt);
1579  if (dotcnt > 0)
1580  pg_fatal("improper qualified name (too many dotted names): %s",
1581  cell->val);
1582 
1583  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1584  if (PQntuples(res) == 0)
1585  pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
1586 
1587  for (i = 0; i < PQntuples(res); i++)
1589 
1590  PQclear(res);
1591  resetPQExpBuffer(query);
1592  }
1593 
1594  destroyPQExpBuffer(query);
1595 }

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

1443 {
1444  PQExpBuffer query;
1445  PGresult *res;
1446  SimpleStringListCell *cell;
1447  int i;
1448 
1449  if (patterns->head == NULL)
1450  return; /* nothing to do */
1451 
1452  query = createPQExpBuffer();
1453 
1454  /*
1455  * The loop below runs multiple SELECTs might sometimes result in
1456  * duplicate entries in the OID list, but we don't care.
1457  */
1458 
1459  for (cell = patterns->head; cell; cell = cell->next)
1460  {
1461  PQExpBufferData dbbuf;
1462  int dotcnt;
1463 
1464  appendPQExpBufferStr(query,
1465  "SELECT oid FROM pg_catalog.pg_namespace n\n");
1466  initPQExpBuffer(&dbbuf);
1467  processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1468  false, NULL, "n.nspname", NULL, NULL, &dbbuf,
1469  &dotcnt);
1470  if (dotcnt > 1)
1471  pg_fatal("improper qualified name (too many dotted names): %s",
1472  cell->val);
1473  else if (dotcnt == 1)
1474  prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1475  termPQExpBuffer(&dbbuf);
1476 
1477  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1478  if (strict_names && PQntuples(res) == 0)
1479  pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
1480 
1481  for (i = 0; i < PQntuples(res); i++)
1482  {
1484  }
1485 
1486  PQclear(res);
1487  resetPQExpBuffer(query);
1488  }
1489 
1490  destroyPQExpBuffer(query);
1491 }
static void prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
Definition: pg_dump.c:1699
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 1603 of file pg_dump.c.

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

10135 {
10136  CommentItem *middle = NULL;
10137  CommentItem *low;
10138  CommentItem *high;
10139  int nmatch;
10140 
10141  /*
10142  * Do binary search to find some item matching the object.
10143  */
10144  low = &comments[0];
10145  high = &comments[ncomments - 1];
10146  while (low <= high)
10147  {
10148  middle = low + (high - low) / 2;
10149 
10150  if (classoid < middle->classoid)
10151  high = middle - 1;
10152  else if (classoid > middle->classoid)
10153  low = middle + 1;
10154  else if (objoid < middle->objoid)
10155  high = middle - 1;
10156  else if (objoid > middle->objoid)
10157  low = middle + 1;
10158  else
10159  break; /* found a match */
10160  }
10161 
10162  if (low > high) /* no matches */
10163  {
10164  *items = NULL;
10165  return 0;
10166  }
10167 
10168  /*
10169  * Now determine how many items match the object. The search loop
10170  * invariant still holds: only items between low and high inclusive could
10171  * match.
10172  */
10173  nmatch = 1;
10174  while (middle > low)
10175  {
10176  if (classoid != middle[-1].classoid ||
10177  objoid != middle[-1].objoid)
10178  break;
10179  middle--;
10180  nmatch++;
10181  }
10182 
10183  *items = middle;
10184 
10185  middle += nmatch;
10186  while (middle <= high)
10187  {
10188  if (classoid != middle->classoid ||
10189  objoid != middle->objoid)
10190  break;
10191  middle++;
10192  nmatch++;
10193  }
10194 
10195  return nmatch;
10196 }
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 18506 of file pg_dump.c.

18508 {
18509  int i;
18510 
18511  /*
18512  * Ignore section boundary objects: if we search through them, we'll
18513  * report lots of bogus dependencies.
18514  */
18515  if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
18516  dobj->objType == DO_POST_DATA_BOUNDARY)
18517  return;
18518 
18519  for (i = 0; i < dobj->nDeps; i++)
18520  {
18521  DumpId depid = dobj->dependencies[i];
18522 
18523  if (TocIDRequired(AH, depid) != 0)
18524  {
18525  /* Object will be dumped, so just reference it as a dependency */
18526  if (*nDeps >= *allocDeps)
18527  {
18528  *allocDeps *= 2;
18529  *dependencies = (DumpId *) pg_realloc(*dependencies,
18530  *allocDeps * sizeof(DumpId));
18531  }
18532  (*dependencies)[*nDeps] = depid;
18533  (*nDeps)++;
18534  }
18535  else
18536  {
18537  /*
18538  * Object will not be dumped, so recursively consider its deps. We
18539  * rely on the assumption that sortDumpableObjects already broke
18540  * any dependency loops, else we might recurse infinitely.
18541  */
18542  DumpableObject *otherdobj = findObjectByDumpId(depid);
18543 
18544  if (otherdobj)
18545  findDumpableDependencies(AH, otherdobj,
18546  dependencies, nDeps, allocDeps);
18547  }
18548  }
18549 }
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 5715 of file pg_dump.c.

5716 {
5717  NamespaceInfo *nsinfo;
5718 
5719  nsinfo = findNamespaceByOid(nsoid);
5720  if (nsinfo == NULL)
5721  pg_fatal("schema with OID %u does not exist", nsoid);
5722  return nsinfo;
5723 }
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:937

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

15275 {
15276  SecLabelItem *middle = NULL;
15277  SecLabelItem *low;
15278  SecLabelItem *high;
15279  int nmatch;
15280 
15281  if (nseclabels <= 0) /* no labels, so no match is possible */
15282  {
15283  *items = NULL;
15284  return 0;
15285  }
15286 
15287  /*
15288  * Do binary search to find some item matching the object.
15289  */
15290  low = &seclabels[0];
15291  high = &seclabels[nseclabels - 1];
15292  while (low <= high)
15293  {
15294  middle = low + (high - low) / 2;
15295 
15296  if (classoid < middle->classoid)
15297  high = middle - 1;
15298  else if (classoid > middle->classoid)
15299  low = middle + 1;
15300  else if (objoid < middle->objoid)
15301  high = middle - 1;
15302  else if (objoid > middle->objoid)
15303  low = middle + 1;
15304  else
15305  break; /* found a match */
15306  }
15307 
15308  if (low > high) /* no matches */
15309  {
15310  *items = NULL;
15311  return 0;
15312  }
15313 
15314  /*
15315  * Now determine how many items match the object. The search loop
15316  * invariant still holds: only items between low and high inclusive could
15317  * match.
15318  */
15319  nmatch = 1;
15320  while (middle > low)
15321  {
15322  if (classoid != middle[-1].classoid ||
15323  objoid != middle[-1].objoid)
15324  break;
15325  middle--;
15326  nmatch++;
15327  }
15328 
15329  *items = middle;
15330 
15331  middle += nmatch;
15332  while (middle <= high)
15333  {
15334  if (classoid != middle->classoid ||
15335  objoid != middle->objoid)
15336  break;
15337  middle++;
15338  nmatch++;
15339  }
15340 
15341  return nmatch;
15342 }

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

18614 {
18615  int numatts = ti->numatts;
18616  char **attnames = ti->attnames;
18617  bool *attisdropped = ti->attisdropped;
18618  char *attgenerated = ti->attgenerated;
18619  bool needComma;
18620  int i;
18621 
18622  appendPQExpBufferChar(buffer, '(');
18623  needComma = false;
18624  for (i = 0; i < numatts; i++)
18625  {
18626  if (attisdropped[i])
18627  continue;
18628  if (attgenerated[i])
18629  continue;
18630  if (needComma)
18631  appendPQExpBufferStr(buffer, ", ");
18632  appendPQExpBufferStr(buffer, fmtId(attnames[i]));
18633  needComma = true;
18634  }
18635 
18636  if (!needComma)
18637  return ""; /* no undropped columns */
18638 
18639  appendPQExpBufferChar(buffer, ')');
18640  return buffer->data;
18641 }

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

2595 {
2596  TableInfo *parentTbinfo;
2597 
2598  Assert(tbinfo->ispartition);
2599  Assert(tbinfo->numParents == 1);
2600 
2601  parentTbinfo = tbinfo->parents[0];
2602  if (parentTbinfo->unsafe_partitions)
2603  return true;
2604  while (parentTbinfo->ispartition)
2605  {
2606  Assert(parentTbinfo->numParents == 1);
2607  parentTbinfo = parentTbinfo->parents[0];
2608  if (parentTbinfo->unsafe_partitions)
2609  return true;
2610  }
2611 
2612  return false;
2613 }
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 13917 of file pg_dump.c.

13918 {
13920  int j;
13921 
13922  initPQExpBuffer(&buf);
13923  if (honor_quotes)
13924  appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
13925  else
13926  appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
13927 
13928  if (agginfo->aggfn.nargs == 0)
13929  appendPQExpBufferStr(&buf, "(*)");
13930  else
13931  {
13932  appendPQExpBufferChar(&buf, '(');
13933  for (j = 0; j < agginfo->aggfn.nargs; j++)
13934  appendPQExpBuffer(&buf, "%s%s",
13935  (j > 0) ? ", " : "",
13936  getFormattedTypeName(fout,
13937  agginfo->aggfn.argtypes[j],
13938  zeroIsError));
13939  appendPQExpBufferChar(&buf, ')');
13940  }
13941  return buf.data;
13942 }

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

11983 {
11985 
11986  initPQExpBuffer(&fn);
11987  appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
11988  if (is_agg && finfo->nargs == 0)
11989  appendPQExpBufferStr(&fn, "(*)");
11990  else
11991  appendPQExpBuffer(&fn, "(%s)", funcargs);
11992  return fn.data;
11993 }
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 12005 of file pg_dump.c.

12006 {
12008  int j;
12009 
12010  initPQExpBuffer(&fn);
12011  if (honor_quotes)
12012  appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
12013  else
12014  appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
12015  for (j = 0; j < finfo->nargs; j++)
12016  {
12017  if (j > 0)
12018  appendPQExpBufferStr(&fn, ", ");
12019 
12021  getFormattedTypeName(fout, finfo->argtypes[j],
12022  zeroIsError));
12023  }
12024  appendPQExpBufferChar(&fn, ')');
12025  return fn.data;
12026 }
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 8516 of file pg_dump.c.

8517 {
8518  PQExpBuffer query;
8519  PGresult *res;
8520  char *lanname;
8521 
8522  query = createPQExpBuffer();
8523  appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
8524  res = ExecuteSqlQueryForSingleRow(fout, query->data);
8525  lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
8526  destroyPQExpBuffer(query);
8527  PQclear(res);
8528 
8529  return lanname;
8530 }

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

5287 {
5288  /*
5289  * If the old version didn't assign an array type, but the new version
5290  * does, we must select an unused type OID to assign. This currently only
5291  * happens for domains, when upgrading pre-v11 to v11 and up.
5292  *
5293  * Note: local state here is kind of ugly, but we must have some, since we
5294  * mustn't choose the same unused OID more than once.
5295  */
5296  static Oid next_possible_free_oid = FirstNormalObjectId;
5297  PGresult *res;
5298  bool is_dup;
5299 
5300  do
5301  {
5302  ++next_possible_free_oid;
5303  printfPQExpBuffer(upgrade_query,
5304  "SELECT EXISTS(SELECT 1 "
5305  "FROM pg_catalog.pg_type "
5306  "WHERE oid = '%u'::pg_catalog.oid);",
5307  next_possible_free_oid);
5308  res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5309  is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
5310  PQclear(res);
5311  } while (is_dup);
5312 
5313  return next_possible_free_oid;
5314 }
#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 1387 of file pg_dump.c.

1388 {
1389  char *query = "SELECT pg_catalog.pg_export_snapshot()";
1390  char *result;
1391  PGresult *res;
1392 
1393  res = ExecuteSqlQueryForSingleRow(fout, query);
1394  result = pg_strdup(PQgetvalue(res, 0, 0));
1395  PQclear(res);
1396 
1397  return result;
1398 }

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

Referenced by setup_connection().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6160 of file pg_dump.c.

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

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

9792 {
9793  PQExpBuffer query = createPQExpBuffer();
9794  PGresult *res;
9795  int ntups,
9796  i;
9797 
9798  /* Check for per-column ACLs */
9799  appendPQExpBufferStr(query,
9800  "SELECT DISTINCT attrelid FROM pg_attribute "
9801  "WHERE attacl IS NOT NULL");
9802 
9803  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9804 
9805  ntups = PQntuples(res);
9806  for (i = 0; i < ntups; i++)
9807  {
9808  Oid relid = atooid(PQgetvalue(res, i, 0));
9809  TableInfo *tblinfo;
9810 
9811  tblinfo = findTableByOid(relid);
9812  /* OK to ignore tables we haven't got a DumpableObject for */
9813  if (tblinfo)
9814  {
9815  tblinfo->dobj.components |= DUMP_COMPONENT_ACL;
9816  tblinfo->hascolumnACLs = true;
9817  }
9818  }
9819  PQclear(res);
9820 
9821  /* Fetch initial-privileges data */
9822  if (fout->remoteVersion >= 90600)
9823  {
9824  printfPQExpBuffer(query,
9825  "SELECT objoid, classoid, objsubid, privtype, initprivs "
9826  "FROM pg_init_privs");
9827 
9828  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9829 
9830  ntups = PQntuples(res);
9831  for (i = 0; i < ntups; i++)
9832  {
9833  Oid objoid = atooid(PQgetvalue(res, i, 0));
9834  Oid classoid = atooid(PQgetvalue(res, i, 1));
9835  int objsubid = atoi(PQgetvalue(res, i, 2));
9836  char privtype = *(PQgetvalue(res, i, 3));
9837  char *initprivs = PQgetvalue(res, i, 4);
9838  CatalogId objId;
9839  DumpableObject *dobj;
9840 
9841  objId.tableoid = classoid;
9842  objId.oid = objoid;
9843  dobj = findObjectByCatalogId(objId);
9844  /* OK to ignore entries we haven't got a DumpableObject for */
9845  if (dobj)
9846  {
9847  /* Cope with sub-object initprivs */
9848  if (objsubid != 0)
9849  {
9850  if (dobj->objType == DO_TABLE)
9851  {
9852  /* For a column initprivs, set the table's ACL flags */
9853  dobj->components |= DUMP_COMPONENT_ACL;
9854  ((TableInfo *) dobj)->hascolumnACLs = true;
9855  }
9856  else
9857  pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
9858  classoid, objoid, objsubid);
9859  continue;
9860  }
9861 
9862  /*
9863  * We ignore any pg_init_privs.initprivs entry for the public
9864  * schema, as explained in getNamespaces().
9865  */
9866  if (dobj->objType == DO_NAMESPACE &&
9867  strcmp(dobj->name, "public") == 0)
9868  continue;
9869 
9870  /* Else it had better be of a type we think has ACLs */
9871  if (dobj->objType == DO_NAMESPACE ||
9872  dobj->objType == DO_TYPE ||
9873  dobj->objType == DO_FUNC ||
9874  dobj->objType == DO_AGG ||
9875  dobj->objType == DO_TABLE ||
9876  dobj->objType == DO_PROCLANG ||
9877  dobj->objType == DO_FDW ||
9878  dobj->objType == DO_FOREIGN_SERVER)
9879  {
9880  DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj;
9881 
9882  daobj->dacl.privtype = privtype;
9883  daobj->dacl.initprivs = pstrdup(initprivs);
9884  }
9885  else
9886  pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
9887  classoid, objoid, objsubid);
9888  }
9889  }
9890  PQclear(res);
9891  }
9892 
9893  destroyPQExpBuffer(query);
9894 }
char * pstrdup(const char *in)
Definition: mcxt.c:1696
DumpableAcl dacl
Definition: pg_dump.h:167

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

Referenced by main().

◆ getAggregates()

void getAggregates ( Archive fout)

Definition at line 6344 of file pg_dump.c.

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

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

16598 {
16599  if (attrnum > 0 && attrnum <= tblInfo->numatts)
16600  return tblInfo->attnames[attrnum - 1];
16601  switch (attrnum)
16602  {
16604  return "ctid";
16606  return "xmin";
16608  return "cmin";
16610  return "xmax";
16612  return "cmax";
16614  return "tableoid";
16615  }
16616  pg_fatal("invalid column number %d for table \"%s\"",
16617  attrnum, tblInfo->dobj.name);
16618  return NULL; /* keep compiler quiet */
16619 }
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:22
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:25
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:24
#define TableOidAttributeNumber
Definition: sysattr.h:26
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define MinCommandIdAttributeNumber
Definition: sysattr.h:23

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

Referenced by dumpConstraint(), and dumpTableSecLabel().

◆ getCasts()

void getCasts ( Archive fout)

Definition at line 8427 of file pg_dump.c.

8428 {
8429  PGresult *res;
8430  int ntups;
8431  int i;
8432  PQExpBuffer query = createPQExpBuffer();
8433  CastInfo *castinfo;
8434  int i_tableoid;
8435  int i_oid;
8436  int i_castsource;
8437  int i_casttarget;
8438  int i_castfunc;
8439  int i_castcontext;
8440  int i_castmethod;
8441 
8442  if (fout->remoteVersion >= 140000)
8443  {
8444  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8445  "castsource, casttarget, castfunc, castcontext, "
8446  "castmethod "
8447  "FROM pg_cast c "
8448  "WHERE NOT EXISTS ( "
8449  "SELECT 1 FROM pg_range r "
8450  "WHERE c.castsource = r.rngtypid "
8451  "AND c.casttarget = r.rngmultitypid "
8452  ") "
8453  "ORDER BY 3,4");
8454  }
8455  else
8456  {
8457  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8458  "castsource, casttarget, castfunc, castcontext, "
8459  "castmethod "
8460  "FROM pg_cast ORDER BY 3,4");
8461  }
8462 
8463  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8464 
8465  ntups = PQntuples(res);
8466 
8467  castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8468 
8469  i_tableoid = PQfnumber(res, "tableoid");
8470  i_oid = PQfnumber(res, "oid");
8471  i_castsource = PQfnumber(res, "castsource");
8472  i_casttarget = PQfnumber(res, "casttarget");
8473  i_castfunc = PQfnumber(res, "castfunc");
8474  i_castcontext = PQfnumber(res, "castcontext");
8475  i_castmethod = PQfnumber(res, "castmethod");
8476 
8477  for (i = 0; i < ntups; i++)
8478  {
8479  PQExpBufferData namebuf;
8480  TypeInfo *sTypeInfo;
8481  TypeInfo *tTypeInfo;
8482 
8483  castinfo[i].dobj.objType = DO_CAST;
8484  castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8485  castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8486  AssignDumpId(&castinfo[i].dobj);
8487  castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8488  castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8489  castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8490  castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8491  castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8492 
8493  /*
8494  * Try to name cast as concatenation of typnames. This is only used
8495  * for purposes of sorting. If we fail to find either type, the name
8496  * will be an empty string.
8497  */
8498  initPQExpBuffer(&namebuf);
8499  sTypeInfo = findTypeByOid(castinfo[i].castsource);
8500  tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8501  if (sTypeInfo && tTypeInfo)
8502  appendPQExpBuffer(&namebuf, "%s %s",
8503  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8504  castinfo[i].dobj.name = namebuf.data;
8505 
8506  /* Decide whether we want to dump it */
8507  selectDumpableCast(&(castinfo[i]), fout);
8508  }
8509 
8510  PQclear(res);
8511 
8512  destroyPQExpBuffer(query);
8513 }
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:1966

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

Referenced by getSchemaData().

◆ getCollations()

void getCollations ( Archive fout)

Definition at line 6036 of file pg_dump.c.

6037 {
6038  PGresult *res;
6039  int ntups;
6040  int i;
6041  PQExpBuffer query;
6042  CollInfo *collinfo;
6043  int i_tableoid;
6044  int i_oid;
6045  int i_collname;
6046  int i_collnamespace;
6047  int i_collowner;
6048 
6049  query = createPQExpBuffer();
6050 
6051  /*
6052  * find all collations, including builtin collations; we filter out
6053  * system-defined collations at dump-out time.
6054  */
6055 
6056  appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6057  "collnamespace, "
6058  "collowner "
6059  "FROM pg_collation");
6060 
6061  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6062 
6063  ntups = PQntuples(res);
6064 
6065  collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6066 
6067  i_tableoid = PQfnumber(res, "tableoid");
6068  i_oid = PQfnumber(res, "oid");
6069  i_collname = PQfnumber(res, "collname");
6070  i_collnamespace = PQfnumber(res, "collnamespace");
6071  i_collowner = PQfnumber(res, "collowner");
6072 
6073  for (i = 0; i < ntups; i++)
6074  {
6075  collinfo[i].dobj.objType = DO_COLLATION;
6076  collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6077  collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6078  AssignDumpId(&collinfo[i].dobj);
6079  collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6080  collinfo[i].dobj.namespace =
6081  findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6082  collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6083 
6084  /* Decide whether we want to dump it */
6085  selectDumpableObject(&(collinfo[i].dobj), fout);
6086  }
6087 
6088  PQclear(res);
6089 
6090  destroyPQExpBuffer(query);
6091 }

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

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

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

Referenced by getSchemaData().

◆ getConversions()

void getConversions ( Archive fout)

Definition at line 6098 of file pg_dump.c.

6099 {
6100  PGresult *res;
6101  int ntups;
6102  int i;
6103  PQExpBuffer query;
6104  ConvInfo *convinfo;
6105  int i_tableoid;
6106  int i_oid;
6107  int i_conname;
6108  int i_connamespace;
6109  int i_conowner;
6110 
6111  query = createPQExpBuffer();
6112 
6113  /*
6114  * find all conversions, including builtin conversions; we filter out
6115  * system-defined conversions at dump-out time.
6116  */
6117 
6118  appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6119  "connamespace, "
6120  "conowner "
6121  "FROM pg_conversion");
6122 
6123  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6124 
6125  ntups = PQntuples(res);
6126 
6127  convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6128 
6129  i_tableoid = PQfnumber(res, "tableoid");
6130  i_oid = PQfnumber(res, "oid");
6131  i_conname = PQfnumber(res, "conname");
6132  i_connamespace = PQfnumber(res, "connamespace");
6133  i_conowner = PQfnumber(res, "conowner");
6134 
6135  for (i = 0; i < ntups; i++)
6136  {
6137  convinfo[i].dobj.objType = DO_CONVERSION;
6138  convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6139  convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6140  AssignDumpId(&convinfo[i].dobj);
6141  convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6142  convinfo[i].dobj.namespace =
6143  findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6144  convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6145 
6146  /* Decide whether we want to dump it */
6147  selectDumpableObject(&(convinfo[i].dobj), fout);
6148  }
6149 
6150  PQclear(res);
6151 
6152  destroyPQExpBuffer(query);
6153 }

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

Referenced by getSchemaData().

◆ getDefaultACLs()

void getDefaultACLs ( Archive fout)

Definition at line 9623 of file pg_dump.c.

9624 {
9625  DumpOptions *dopt = fout->dopt;
9626  DefaultACLInfo *daclinfo;
9627  PQExpBuffer query;
9628  PGresult *res;
9629  int i_oid;
9630  int i_tableoid;
9631  int i_defaclrole;
9632  int i_defaclnamespace;
9633  int i_defaclobjtype;
9634  int i_defaclacl;
9635  int i_acldefault;
9636  int i,
9637  ntups;
9638 
9639  query = createPQExpBuffer();
9640 
9641  /*
9642  * Global entries (with defaclnamespace=0) replace the hard-wired default
9643  * ACL for their object type. We should dump them as deltas from the
9644  * default ACL, since that will be used as a starting point for
9645  * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
9646  * non-global entries can only add privileges not revoke them. We must
9647  * dump those as-is (i.e., as deltas from an empty ACL).
9648  *
9649  * We can use defaclobjtype as the object type for acldefault(), except
9650  * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
9651  * 's'.
9652  */
9653  appendPQExpBufferStr(query,
9654  "SELECT oid, tableoid, "
9655  "defaclrole, "
9656  "defaclnamespace, "
9657  "defaclobjtype, "
9658  "defaclacl, "
9659  "CASE WHEN defaclnamespace = 0 THEN "
9660  "acldefault(CASE WHEN defaclobjtype = 'S' "
9661  "THEN 's'::\"char\" ELSE defaclobjtype END, "
9662  "defaclrole) ELSE '{}' END AS acldefault "
9663  "FROM pg_default_acl");
9664 
9665  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9666 
9667  ntups = PQntuples(res);
9668 
9669  daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
9670 
9671  i_oid = PQfnumber(res, "oid");
9672  i_tableoid = PQfnumber(res, "tableoid");
9673  i_defaclrole = PQfnumber(res, "defaclrole");
9674  i_defaclnamespace = PQfnumber(res, "defaclnamespace");
9675  i_defaclobjtype = PQfnumber(res, "defaclobjtype");
9676  i_defaclacl = PQfnumber(res, "defaclacl");
9677  i_acldefault = PQfnumber(res, "acldefault");
9678 
9679  for (i = 0; i < ntups; i++)
9680  {
9681  Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
9682 
9683  daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
9684  daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9685  daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9686  AssignDumpId(&daclinfo[i].dobj);
9687  /* cheesy ... is it worth coming up with a better object name? */
9688  daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
9689 
9690  if (nspid != InvalidOid)
9691  daclinfo[i].dobj.namespace = findNamespace(nspid);
9692  else
9693  daclinfo[i].dobj.namespace = NULL;
9694 
9695  daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9696  daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9697  daclinfo[i].dacl.privtype = 0;
9698  daclinfo[i].dacl.initprivs = NULL;
9699  daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
9700  daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
9701 
9702  /* Default ACLs are ACLs, of course */
9703  daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9704 
9705  /* Decide whether we want to dump it */
9706  selectDumpableDefaultACL(&(daclinfo[i]), dopt);
9707  }
9708 
9709  PQclear(res);
9710 
9711  destroyPQExpBuffer(query);
9712 }
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:1944

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

18166 {
18167  PQExpBuffer query;
18168  PGresult *res;
18169  int ntups,
18170  i;
18171  int i_classid,
18172  i_objid,
18173  i_refclassid,
18174  i_refobjid,
18175  i_deptype;
18176  DumpableObject *dobj,
18177  *refdobj;
18178 
18179  pg_log_info("reading dependency data");
18180 
18181  query = createPQExpBuffer();
18182 
18183  /*
18184  * Messy query to collect the dependency data we need. Note that we
18185  * ignore the sub-object column, so that dependencies of or on a column
18186  * look the same as dependencies of or on a whole table.
18187  *
18188  * PIN dependencies aren't interesting, and EXTENSION dependencies were
18189  * already processed by getExtensionMembership.
18190  */
18191  appendPQExpBufferStr(query, "SELECT "
18192  "classid, objid, refclassid, refobjid, deptype "
18193  "FROM pg_depend "
18194  "WHERE deptype != 'p' AND deptype != 'e'\n");
18195 
18196  /*
18197  * Since we don't treat pg_amop entries as separate DumpableObjects, we
18198  * have to translate their dependencies into dependencies of their parent
18199  * opfamily. Ignore internal dependencies though, as those will point to
18200  * their parent opclass, which we needn't consider here (and if we did,
18201  * it'd just result in circular dependencies). Also, "loose" opfamily
18202  * entries will have dependencies on their parent opfamily, which we
18203  * should drop since they'd likewise become useless self-dependencies.
18204  * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
18205  */
18206  appendPQExpBufferStr(query, "UNION ALL\n"
18207  "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
18208  "FROM pg_depend d, pg_amop o "
18209  "WHERE deptype NOT IN ('p', 'e', 'i') AND "
18210  "classid = 'pg_amop'::regclass AND objid = o.oid "
18211  "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
18212 
18213  /* Likewise for pg_amproc entries */
18214  appendPQExpBufferStr(query, "UNION ALL\n"
18215  "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
18216  "FROM pg_depend d, pg_amproc p "
18217  "WHERE deptype NOT IN ('p', 'e', 'i') AND "
18218  "classid = 'pg_amproc'::regclass AND objid = p.oid "
18219  "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
18220 
18221  /* Sort the output for efficiency below */
18222  appendPQExpBufferStr(query, "ORDER BY 1,2");
18223 
18224  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18225 
18226  ntups = PQntuples(res);
18227 
18228  i_classid = PQfnumber(res, "classid");
18229  i_objid = PQfnumber(res, "objid");
18230  i_refclassid = PQfnumber(res, "refclassid");
18231  i_refobjid = PQfnumber(res, "refobjid");
18232  i_deptype = PQfnumber(res, "deptype");
18233 
18234  /*
18235  * Since we ordered the SELECT by referencing ID, we can expect that
18236  * multiple entries for the same object will appear together; this saves
18237  * on searches.
18238  */
18239  dobj = NULL;
18240 
18241  for (i = 0; i < ntups; i++)
18242  {
18243  CatalogId objId;
18244  CatalogId refobjId;
18245  char deptype;
18246 
18247  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18248  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18249  refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
18250  refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
18251  deptype = *(PQgetvalue(res, i, i_deptype));
18252 
18253  if (dobj == NULL ||
18254  dobj->catId.tableoid != objId.tableoid ||
18255  dobj->catId.oid != objId.oid)
18256  dobj = findObjectByCatalogId(objId);
18257 
18258  /*
18259  * Failure to find objects mentioned in pg_depend is not unexpected,
18260  * since for example we don't collect info about TOAST tables.
18261  */
18262  if (dobj == NULL)
18263  {
18264 #ifdef NOT_USED
18265  pg_log_warning("no referencing object %u %u",
18266  objId.tableoid, objId.oid);
18267 #endif
18268  continue;
18269  }
18270 
18271  refdobj = findObjectByCatalogId(refobjId);
18272 
18273  if (refdobj == NULL)
18274  {
18275 #ifdef NOT_USED
18276  pg_log_warning("no referenced object %u %u",
18277  refobjId.tableoid, refobjId.oid);
18278 #endif
18279  continue;
18280  }
18281 
18282  /*
18283  * For 'x' dependencies, mark the object for later; we still add the
18284  * normal dependency, for possible ordering purposes. Currently
18285  * pg_dump_sort.c knows to put extensions ahead of all object types
18286  * that could possibly depend on them, but this is safer.
18287  */
18288  if (deptype == 'x')
18289  dobj->depends_on_ext = true;
18290 
18291  /*
18292  * Ordinarily, table rowtypes have implicit dependencies on their
18293  * tables. However, for a composite type the implicit dependency goes
18294  * the other way in pg_depend; which is the right thing for DROP but
18295  * it doesn't produce the dependency ordering we need. So in that one
18296  * case, we reverse the direction of the dependency.
18297  */
18298  if (deptype == 'i' &&
18299  dobj->objType == DO_TABLE &&
18300  refdobj->objType == DO_TYPE)
18301  addObjectDependency(refdobj, dobj->dumpId);
18302  else
18303  /* normal case */
18304  addObjectDependency(dobj, refdobj->dumpId);
18305  }
18306 
18307  PQclear(res);
18308 
18309  destroyPQExpBuffer(query);
18310 }

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

7883 {
7884  int i;
7885  ConstraintInfo *constrinfo;
7886  PQExpBuffer query = createPQExpBuffer();
7887  PGresult *res;
7888  int i_tableoid,
7889  i_oid,
7890  i_conname,
7891  i_consrc;
7892  int ntups;
7893 
7895  {
7896  /* Set up query for constraint-specific details */
7897  appendPQExpBufferStr(query,
7898  "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
7899  "SELECT tableoid, oid, conname, "
7900  "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
7901  "convalidated "
7902  "FROM pg_catalog.pg_constraint "
7903  "WHERE contypid = $1 AND contype = 'c' "
7904  "ORDER BY conname");
7905 
7906  ExecuteSqlStatement(fout, query->data);
7907 
7909  }
7910 
7911  printfPQExpBuffer(query,
7912  "EXECUTE getDomainConstraints('%u')",
7913  tyinfo->dobj.catId.oid);
7914 
7915  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7916 
7917  ntups = PQntuples(res);
7918 
7919  i_tableoid = PQfnumber(res, "tableoid");
7920  i_oid = PQfnumber(res, "oid");
7921  i_conname = PQfnumber(res, "conname");
7922  i_consrc = PQfnumber(res, "consrc");
7923 
7924  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
7925 
7926  tyinfo->nDomChecks = ntups;
7927  tyinfo->domChecks = constrinfo;
7928 
7929  for (i = 0; i < ntups; i++)
7930  {
7931  bool validated = PQgetvalue(res, i, 4)[0] == 't';
7932 
7933  constrinfo[i].dobj.objType = DO_CONSTRAINT;
7934  constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7935  constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7936  AssignDumpId(&constrinfo[i].dobj);
7937  constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
7938  constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
7939  constrinfo[i].contable = NULL;
7940  constrinfo[i].condomain = tyinfo;
7941  constrinfo[i].contype = 'c';
7942  constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
7943  constrinfo[i].confrelid = InvalidOid;
7944  constrinfo[i].conindex = 0;
7945  constrinfo[i].condeferrable = false;
7946  constrinfo[i].condeferred = false;
7947  constrinfo[i].conislocal = true;
7948 
7949  constrinfo[i].separate = !validated;
7950 
7951  /*
7952  * Make the domain depend on the constraint, ensuring it won't be
7953  * output till any constraint dependencies are OK. If the constraint
7954  * has not been validated, it's going to be dumped after the domain
7955  * anyway, so this doesn't matter.
7956  */
7957  if (validated)
7958  addObjectDependency(&tyinfo->dobj,
7959  constrinfo[i].dobj.dumpId);
7960  }
7961 
7962  PQclear(res);
7963 
7964  destroyPQExpBuffer(query);
7965 }
@ PREPQUERY_GETDOMAINCONSTRAINTS
Definition: pg_backup.h:76

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

Referenced by getTypes().

◆ getEventTriggers()

void getEventTriggers ( Archive fout)

Definition at line 8265 of file pg_dump.c.

8266 {
8267  int i;
8268  PQExpBuffer query;
8269  PGresult *res;
8270  EventTriggerInfo *evtinfo;
8271  int i_tableoid,
8272  i_oid,
8273  i_evtname,
8274  i_evtevent,
8275  i_evtowner,
8276  i_evttags,
8277  i_evtfname,
8278  i_evtenabled;
8279  int ntups;
8280 
8281  /* Before 9.3, there are no event triggers */
8282  if (fout->remoteVersion < 90300)
8283  return;
8284 
8285  query = createPQExpBuffer();
8286 
8287  appendPQExpBufferStr(query,
8288  "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8289  "evtevent, evtowner, "
8290  "array_to_string(array("
8291  "select quote_literal(x) "
8292  " from unnest(evttags) as t(x)), ', ') as evttags, "
8293  "e.evtfoid::regproc as evtfname "
8294  "FROM pg_event_trigger e "
8295  "ORDER BY e.oid");
8296 
8297  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8298 
8299  ntups = PQntuples(res);
8300 
8301  evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8302 
8303  i_tableoid = PQfnumber(res, "tableoid");
8304  i_oid = PQfnumber(res, "oid");
8305  i_evtname = PQfnumber(res, "evtname");
8306  i_evtevent = PQfnumber(res, "evtevent");
8307  i_evtowner = PQfnumber(res, "evtowner");
8308  i_evttags = PQfnumber(res, "evttags");
8309  i_evtfname = PQfnumber(res, "evtfname");
8310  i_evtenabled = PQfnumber(res, "evtenabled");
8311 
8312  for (i = 0; i < ntups; i++)
8313  {
8314  evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8315  evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8316  evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8317  AssignDumpId(&evtinfo[i].dobj);
8318  evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8319  evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8320  evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8321  evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8322  evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8323  evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8324  evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8325 
8326  /* Decide whether we want to dump it */
8327  selectDumpableObject(&(evtinfo[i].dobj), fout);
8328  }
8329 
8330  PQclear(res);
8331 
8332  destroyPQExpBuffer(query);
8333 }
char * evtname
Definition: pg_dump.h:450

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

7616 {
7617  PQExpBuffer query;
7618  PGresult *res;
7619  StatsExtInfo *statsextinfo;
7620  int ntups;
7621  int i_tableoid;
7622  int i_oid;
7623  int i_stxname;
7624  int i_stxnamespace;
7625  int i_stxowner;
7626  int i_stxrelid;
7627  int i_stattarget;
7628  int i;
7629 
7630  /* Extended statistics were new in v10 */
7631  if (fout->remoteVersion < 100000)
7632  return;
7633 
7634  query = createPQExpBuffer();
7635 
7636  if (fout->remoteVersion < 130000)
7637  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7638  "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
7639  "FROM pg_catalog.pg_statistic_ext");
7640  else
7641  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7642  "stxnamespace, stxowner, stxrelid, stxstattarget "
7643  "FROM pg_catalog.pg_statistic_ext");
7644 
7645  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7646 
7647  ntups = PQntuples(res);
7648 
7649  i_tableoid = PQfnumber(res, "tableoid");
7650  i_oid = PQfnumber(res, "oid");
7651  i_stxname = PQfnumber(res, "stxname");
7652  i_stxnamespace = PQfnumber(res, "stxnamespace");
7653  i_stxowner = PQfnumber(res, "stxowner");
7654  i_stxrelid = PQfnumber(res, "stxrelid");
7655  i_stattarget = PQfnumber(res, "stxstattarget");
7656 
7657  statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
7658 
7659  for (i = 0; i < ntups; i++)
7660  {
7661  statsextinfo[i].dobj.objType = DO_STATSEXT;
7662  statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7663  statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7664  AssignDumpId(&statsextinfo[i].dobj);
7665  statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
7666  statsextinfo[i].dobj.namespace =
7667  findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
7668  statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
7669  statsextinfo[i].stattable =
7670  findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7671  if (PQgetisnull(res, i, i_stattarget))
7672  statsextinfo[i].stattarget = -1;
7673  else
7674  statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7675 
7676  /* Decide whether we want to dump it */
7677  selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
7678  }
7679 
7680  PQclear(res);
7681  destroyPQExpBuffer(query);
7682 }
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2109
TableInfo * stattable
Definition: pg_dump.h:423

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

17893 {
17894  PQExpBuffer query;
17895  PGresult *res;
17896  int ntups,
17897  i;
17898  int i_classid,
17899  i_objid,
17900  i_refobjid;
17901  ExtensionInfo *ext;
17902 
17903  /* Nothing to do if no extensions */
17904  if (numExtensions == 0)
17905  return;
17906 
17907  query = createPQExpBuffer();
17908 
17909  /* refclassid constraint is redundant but may speed the search */
17910  appendPQExpBufferStr(query, "SELECT "
17911  "classid, objid, refobjid "
17912  "FROM pg_depend "
17913  "WHERE refclassid = 'pg_extension'::regclass "
17914  "AND deptype = 'e' "
17915  "ORDER BY 3");
17916 
17917  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17918 
17919  ntups = PQntuples(res);
17920 
17921  i_classid = PQfnumber(res, "classid");
17922  i_objid = PQfnumber(res, "objid");
17923  i_refobjid = PQfnumber(res, "refobjid");
17924 
17925  /*
17926  * Since we ordered the SELECT by referenced ID, we can expect that
17927  * multiple entries for the same extension will appear together; this
17928  * saves on searches.
17929  */
17930  ext = NULL;
17931 
17932  for (i = 0; i < ntups; i++)
17933  {
17934  CatalogId objId;
17935  Oid extId;
17936 
17937  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
17938  objId.oid = atooid(PQgetvalue(res, i, i_objid));
17939  extId = atooid(PQgetvalue(res, i, i_refobjid));
17940 
17941  if (ext == NULL ||
17942  ext->dobj.catId.oid != extId)
17943  ext = findExtensionByOid(extId);
17944 
17945  if (ext == NULL)
17946  {
17947  /* shouldn't happen */
17948  pg_log_warning("could not find referenced extension %u", extId);
17949  continue;
17950  }
17951 
17952  recordExtensionMembership(objId, ext);
17953  }
17954 
17955  PQclear(res);
17956 
17957  destroyPQExpBuffer(query);
17958 }
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1010
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:955

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

5734 {
5735  DumpOptions *dopt = fout->dopt;
5736  PGresult *res;
5737  int ntups;
5738  int i;
5739  PQExpBuffer query;
5740  ExtensionInfo *extinfo;
5741  int i_tableoid;
5742  int i_oid;
5743  int i_extname;
5744  int i_nspname;
5745  int i_extrelocatable;
5746  int i_extversion;
5747  int i_extconfig;
5748  int i_extcondition;
5749 
5750  query = createPQExpBuffer();
5751 
5752  appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5753  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5754  "FROM pg_extension x "
5755  "JOIN pg_namespace n ON n.oid = x.extnamespace");
5756 
5757  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5758 
5759  ntups = PQntuples(res);
5760 
5761  extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5762 
5763  i_tableoid = PQfnumber(res, "tableoid");
5764  i_oid = PQfnumber(res, "oid");
5765  i_extname = PQfnumber(res, "extname");
5766  i_nspname = PQfnumber(res, "nspname");
5767  i_extrelocatable = PQfnumber(res, "extrelocatable");
5768  i_extversion = PQfnumber(res, "extversion");
5769  i_extconfig = PQfnumber(res, "extconfig");
5770  i_extcondition = PQfnumber(res, "extcondition");
5771 
5772  for (i = 0; i < ntups; i++)
5773  {
5774  extinfo[i].dobj.objType = DO_EXTENSION;
5775  extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5776  extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5777  AssignDumpId(&extinfo[i].dobj);
5778  extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5779  extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5780  extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5781  extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5782  extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5783  extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5784 
5785  /* Decide whether we want to dump it */
5786  selectDumpableExtension(&(extinfo[i]), dopt);
5787  }
5788 
5789  PQclear(res);
5790  destroyPQExpBuffer(query);
5791 
5792  *numExtensions = ntups;
5793 
5794  return extinfo;
5795 }
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2052

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

void getForeignDataWrappers ( Archive fout)

Definition at line 9451 of file pg_dump.c.

9452 {
9453  PGresult *res;
9454  int ntups;
9455  int i;
9456  PQExpBuffer query;
9457  FdwInfo *fdwinfo;
9458  int i_tableoid;
9459  int i_oid;
9460  int i_fdwname;
9461  int i_fdwowner;
9462  int i_fdwhandler;
9463  int i_fdwvalidator;
9464  int i_fdwacl;
9465  int i_acldefault;
9466  int i_fdwoptions;
9467 
9468  query = createPQExpBuffer();
9469 
9470  appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
9471  "fdwowner, "
9472  "fdwhandler::pg_catalog.regproc, "
9473  "fdwvalidator::pg_catalog.regproc, "
9474  "fdwacl, "
9475  "acldefault('F', fdwowner) AS acldefault, "
9476  "array_to_string(ARRAY("
9477  "SELECT quote_ident(option_name) || ' ' || "
9478  "quote_literal(option_value) "
9479  "FROM pg_options_to_table(fdwoptions) "
9480  "ORDER BY option_name"
9481  "), E',\n ') AS fdwoptions "
9482  "FROM pg_foreign_data_wrapper");
9483 
9484  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9485 
9486  ntups = PQntuples(res);
9487 
9488  fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
9489 
9490  i_tableoid = PQfnumber(res, "tableoid");
9491  i_oid = PQfnumber(res, "oid");
9492  i_fdwname = PQfnumber(res, "fdwname");
9493  i_fdwowner = PQfnumber(res, "fdwowner");
9494  i_fdwhandler = PQfnumber(res, "fdwhandler");
9495  i_fdwvalidator = PQfnumber(res, "fdwvalidator");
9496  i_fdwacl = PQfnumber(res, "fdwacl");
9497  i_acldefault = PQfnumber(res, "acldefault");
9498  i_fdwoptions = PQfnumber(res, "fdwoptions");
9499 
9500  for (i = 0; i < ntups; i++)
9501  {
9502  fdwinfo[i].dobj.objType = DO_FDW;
9503  fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9504  fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9505  AssignDumpId(&fdwinfo[i].dobj);
9506  fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
9507  fdwinfo[i].dobj.namespace = NULL;
9508  fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
9509  fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9510  fdwinfo[i].dacl.privtype = 0;
9511  fdwinfo[i].dacl.initprivs = NULL;
9512  fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
9513  fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
9514  fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
9515  fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
9516 
9517  /* Decide whether we want to dump it */
9518  selectDumpableObject(&(fdwinfo[i].dobj), fout);
9519 
9520  /* Mark whether FDW has an ACL */
9521  if (!PQgetisnull(res, i, i_fdwacl))
9522  fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9523  }
9524 
9525  PQclear(res);
9526 
9527  destroyPQExpBuffer(query);
9528 }

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

Referenced by getSchemaData().

◆ getForeignServers()

void getForeignServers ( Archive fout)

Definition at line 9535 of file pg_dump.c.

9536 {
9537  PGresult *res;
9538  int ntups;
9539  int i;
9540  PQExpBuffer query;
9541  ForeignServerInfo *srvinfo;
9542  int i_tableoid;
9543  int i_oid;
9544  int i_srvname;
9545  int i_srvowner;
9546  int i_srvfdw;
9547  int i_srvtype;
9548  int i_srvversion;
9549  int i_srvacl;
9550  int i_acldefault;
9551  int i_srvoptions;
9552 
9553  query = createPQExpBuffer();
9554 
9555  appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
9556  "srvowner, "
9557  "srvfdw, srvtype, srvversion, srvacl, "
9558  "acldefault('S', srvowner) AS acldefault, "
9559  "array_to_string(ARRAY("
9560  "SELECT quote_ident(option_name) || ' ' || "
9561  "quote_literal(option_value) "
9562  "FROM pg_options_to_table(srvoptions) "
9563  "ORDER BY option_name"
9564  "), E',\n ') AS srvoptions "
9565  "FROM pg_foreign_server");
9566 
9567  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9568 
9569  ntups = PQntuples(res);
9570 
9571  srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
9572 
9573  i_tableoid = PQfnumber(res, "tableoid");
9574  i_oid = PQfnumber(res, "oid");
9575  i_srvname = PQfnumber(res, "srvname");
9576  i_srvowner = PQfnumber(res, "srvowner");
9577  i_srvfdw = PQfnumber(res, "srvfdw");
9578  i_srvtype = PQfnumber(res, "srvtype");
9579  i_srvversion = PQfnumber(res, "srvversion");
9580  i_srvacl = PQfnumber(res, "srvacl");
9581  i_acldefault = PQfnumber(res, "acldefault");
9582  i_srvoptions = PQfnumber(res, "srvoptions");
9583 
9584  for (i = 0; i < ntups; i++)
9585  {
9586  srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
9587  srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9588  srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9589  AssignDumpId(&srvinfo[i].dobj);
9590  srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
9591  srvinfo[i].dobj.namespace = NULL;
9592  srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
9593  srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9594  srvinfo[i].dacl.privtype = 0;
9595  srvinfo[i].dacl.initprivs = NULL;
9596  srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
9597  srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
9598  srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
9599  srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
9600  srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
9601 
9602  /* Decide whether we want to dump it */
9603  selectDumpableObject(&(srvinfo[i].dobj), fout);
9604 
9605  /* Servers have user mappings */
9607 
9608  /* Mark whether server has an ACL */
9609  if (!PQgetisnull(res, i, i_srvacl))
9610  srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9611  }
9612 
9613  PQclear(res);
9614 
9615  destroyPQExpBuffer(query);
9616 }

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

12945 {
12946  OprInfo *oprInfo;
12947 
12948  /* In all cases "0" means a null reference */
12949  if (strcmp(oproid, "0") == 0)
12950  return NULL;
12951 
12952  oprInfo = findOprByOid(atooid(oproid));
12953  if (oprInfo == NULL)
12954  {
12955  pg_log_warning("could not find operator with OID %s",
12956  oproid);
12957  return NULL;
12958  }
12959 
12960  return psprintf("OPERATOR(%s.%s)",
12961  fmtId(oprInfo->dobj.namespace->dobj.name),
12962  oprInfo->dobj.name);
12963 }
OprInfo * findOprByOid(Oid oid)
Definition: common.c:901

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

18563 {
18564  TypeInfo *typeInfo;
18565  char *result;
18566  PQExpBuffer query;
18567  PGresult *res;
18568 
18569  if (oid == 0)
18570  {
18571  if ((opts & zeroAsStar) != 0)
18572  return "*";
18573  else if ((opts & zeroAsNone) != 0)
18574  return "NONE";
18575  }
18576 
18577  /* see if we have the result cached in the type's TypeInfo record */
18578  typeInfo = findTypeByOid(oid);
18579  if (typeInfo && typeInfo->ftypname)
18580  return typeInfo->ftypname;
18581 
18582  query = createPQExpBuffer();
18583  appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
18584  oid);
18585 
18586  res = ExecuteSqlQueryForSingleRow(fout, query->data);
18587 
18588  /* result of format_type is already quoted */
18589  result = pg_strdup(PQgetvalue(res, 0, 0));
18590 
18591  PQclear(res);
18592  destroyPQExpBuffer(query);
18593 
18594  /*
18595  * Cache the result for re-use in later requests, if possible. If we
18596  * don't have a TypeInfo for the type, the string will be leaked once the
18597  * caller is done with it ... but that case really should not happen, so
18598  * leaking if it does seems acceptable.
18599  */
18600  if (typeInfo)
18601  typeInfo->ftypname = result;
18602 
18603  return result;
18604 }
static AmcheckOptions opts
Definition: pg_amcheck.c:111
char * ftypname
Definition: pg_dump.h:199

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

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

◆ getFuncs()

void getFuncs ( Archive fout)

Definition at line 6485 of file pg_dump.c.

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

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

7190 {
7191  PGresult *res;
7192  int ntups;
7193  int i;
7194  PQExpBuffer query = createPQExpBuffer();
7195  InhInfo *inhinfo;
7196 
7197  int i_inhrelid;
7198  int i_inhparent;
7199 
7200  /* find all the inheritance information */
7201  appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7202 
7203  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7204 
7205  ntups = PQntuples(res);
7206 
7207  *numInherits = ntups;
7208 
7209  inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7210 
7211  i_inhrelid = PQfnumber(res, "inhrelid");
7212  i_inhparent = PQfnumber(res, "inhparent");
7213 
7214  for (i = 0; i < ntups; i++)
7215  {
7216  inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7217  inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7218  }
7219 
7220  PQclear(res);
7221 
7222  destroyPQExpBuffer(query);
7223 
7224  return inhinfo;
7225 }
Oid inhparent
Definition: pg_dump.h:515
Oid inhrelid
Definition: pg_dump.h:514

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

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

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

Referenced by main().

◆ getNamespaces()

void getNamespaces ( Archive fout)

Definition at line 5601 of file pg_dump.c.

5602 {
5603  PGresult *res;
5604  int ntups;
5605  int i;
5606  PQExpBuffer query;
5607  NamespaceInfo *nsinfo;
5608  int i_tableoid;
5609  int i_oid;
5610  int i_nspname;
5611  int i_nspowner;
5612  int i_nspacl;
5613  int i_acldefault;
5614 
5615  query = createPQExpBuffer();
5616 
5617  /*
5618  * we fetch all namespaces including system ones, so that every object we
5619  * read in can be linked to a containing namespace.
5620  */
5621  appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5622  "n.nspowner, "
5623  "n.nspacl, "
5624  "acldefault('n', n.nspowner) AS acldefault "
5625  "FROM pg_namespace n");
5626 
5627  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5628 
5629  ntups = PQntuples(res);
5630 
5631  nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5632 
5633  i_tableoid = PQfnumber(res, "tableoid");
5634  i_oid = PQfnumber(res, "oid");
5635  i_nspname = PQfnumber(res, "nspname");
5636  i_nspowner = PQfnumber(res, "nspowner");
5637  i_nspacl = PQfnumber(res, "nspacl");
5638  i_acldefault = PQfnumber(res, "acldefault");
5639 
5640  for (i = 0; i < ntups; i++)
5641  {
5642  const char *nspowner;
5643 
5644  nsinfo[i].dobj.objType = DO_NAMESPACE;
5645  nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5646  nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5647  AssignDumpId(&nsinfo[i].dobj);
5648  nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5649  nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5650  nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5651  nsinfo[i].dacl.privtype = 0;
5652  nsinfo[i].dacl.initprivs = NULL;
5653  nspowner = PQgetvalue(res, i, i_nspowner);
5654  nsinfo[i].nspowner = atooid(nspowner);
5655  nsinfo[i].rolname = getRoleName(nspowner);
5656 
5657  /* Decide whether to dump this namespace */
5658  selectDumpableNamespace(&nsinfo[i], fout);
5659 
5660  /* Mark whether namespace has an ACL */
5661  if (!PQgetisnull(res, i, i_nspacl))
5662  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5663 
5664  /*
5665  * We ignore any pg_init_privs.initprivs entry for the public schema
5666  * and assume a predetermined default, for several reasons. First,
5667  * dropping and recreating the schema removes its pg_init_privs entry,
5668  * but an empty destination database starts with this ACL nonetheless.
5669  * Second, we support dump/reload of public schema ownership changes.
5670  * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5671  * initprivs continues to reflect the initial owner. Hence,
5672  * synthesize the value that nspacl will have after the restore's
5673  * ALTER SCHEMA OWNER. Third, this makes the destination database
5674  * match the source's ACL, even if the latter was an initdb-default
5675  * ACL, which changed in v15. An upgrade pulls in changes to most
5676  * system object ACLs that the DBA had not customized. We've made the
5677  * public schema depart from that, because changing its ACL so easily
5678  * breaks applications.
5679  */
5680  if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5681  {
5682  PQExpBuffer aclarray = createPQExpBuffer();
5683  PQExpBuffer aclitem = createPQExpBuffer();
5684 
5685  /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5686  appendPQExpBufferChar(aclarray, '{');
5687  quoteAclUserName(aclitem, nsinfo[i].rolname);
5688  appendPQExpBufferStr(aclitem, "=UC/");
5689  quoteAclUserName(aclitem, nsinfo[i].rolname);
5690  appendPGArray(aclarray, aclitem->data);
5691  resetPQExpBuffer(aclitem);
5692  appendPQExpBufferStr(aclitem, "=U/");
5693  quoteAclUserName(aclitem, nsinfo[i].rolname);
5694  appendPGArray(aclarray, aclitem->data);
5695  appendPQExpBufferChar(aclarray, '}');
5696 
5697  nsinfo[i].dacl.privtype = 'i';
5698  nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5699  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5700 
5701  destroyPQExpBuffer(aclarray);
5702  destroyPQExpBuffer(aclitem);
5703  }
5704  }
5705 
5706  PQclear(res);
5707  destroyPQExpBuffer(query);
5708 }
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:1774
void appendPGArray(PQExpBuffer buffer, const char *value)
Definition: string_utils.c:740

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

Referenced by getSchemaData().

◆ getOpclasses()

void getOpclasses ( Archive fout)

Definition at line 6222 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getOperators()

void getOperators ( Archive fout)

Definition at line 5968 of file pg_dump.c.

5969 {
5970  PGresult *res;
5971  int ntups;
5972  int i;
5973  PQExpBuffer query = createPQExpBuffer();
5974  OprInfo *oprinfo;
5975  int i_tableoid;
5976  int i_oid;
5977  int i_oprname;
5978  int i_oprnamespace;
5979  int i_oprowner;
5980  int i_oprkind;
5981  int i_oprcode;
5982 
5983  /*
5984  * find all operators, including builtin operators; we filter out
5985  * system-defined operators at dump-out time.
5986  */
5987 
5988  appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
5989  "oprnamespace, "
5990  "oprowner, "
5991  "oprkind, "
5992  "oprcode::oid AS oprcode "
5993  "FROM pg_operator");
5994 
5995  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5996 
5997  ntups = PQntuples(res);
5998 
5999  oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6000 
6001  i_tableoid = PQfnumber(res, "tableoid");
6002  i_oid = PQfnumber(res, "oid");
6003  i_oprname = PQfnumber(res, "oprname");
6004  i_oprnamespace = PQfnumber(res, "oprnamespace");
6005  i_oprowner = PQfnumber(res, "oprowner");
6006  i_oprkind = PQfnumber(res, "oprkind");
6007  i_oprcode = PQfnumber(res, "oprcode");
6008 
6009  for (i = 0; i < ntups; i++)
6010  {
6011  oprinfo[i].dobj.objType = DO_OPERATOR;
6012  oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6013  oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6014  AssignDumpId(&oprinfo[i].dobj);
6015  oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6016  oprinfo[i].dobj.namespace =
6017  findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6018  oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6019  oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6020  oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6021 
6022  /* Decide whether we want to dump it */
6023  selectDumpableObject(&(oprinfo[i].dobj), fout);
6024  }
6025 
6026  PQclear(res);
6027 
6028  destroyPQExpBuffer(query);
6029 }
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()

void getOpfamilies ( Archive fout)

Definition at line 6282 of file pg_dump.c.

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

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

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

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

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

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

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

void getProcLangs ( Archive fout)

Definition at line 8343 of file pg_dump.c.

8344 {
8345  PGresult *res;
8346  int ntups;
8347  int i;
8348  PQExpBuffer query = createPQExpBuffer();
8349  ProcLangInfo *planginfo;
8350  int i_tableoid;
8351  int i_oid;
8352  int i_lanname;
8353  int i_lanpltrusted;
8354  int i_lanplcallfoid;
8355  int i_laninline;
8356  int i_lanvalidator;
8357  int i_lanacl;
8358  int i_acldefault;
8359  int i_lanowner;
8360 
8361  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8362  "lanname, lanpltrusted, lanplcallfoid, "
8363  "laninline, lanvalidator, "
8364  "lanacl, "
8365  "acldefault('l', lanowner) AS acldefault, "
8366  "lanowner "
8367  "FROM pg_language "
8368  "WHERE lanispl "
8369  "ORDER BY oid");
8370 
8371  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8372 
8373  ntups = PQntuples(res);
8374 
8375  planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8376 
8377  i_tableoid = PQfnumber(res, "tableoid");
8378  i_oid = PQfnumber(res, "oid");
8379  i_lanname = PQfnumber(res, "lanname");
8380  i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8381  i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8382  i_laninline = PQfnumber(res, "laninline");
8383  i_lanvalidator = PQfnumber(res, "lanvalidator");
8384  i_lanacl = PQfnumber(res, "lanacl");
8385  i_acldefault = PQfnumber(res, "acldefault");
8386  i_lanowner = PQfnumber(res, "lanowner");
8387 
8388  for (i = 0; i < ntups; i++)
8389  {
8390  planginfo[i].dobj.objType = DO_PROCLANG;
8391  planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8392  planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8393  AssignDumpId(&planginfo[i].dobj);
8394 
8395  planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8396  planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8397  planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8398  planginfo[i].dacl.privtype = 0;
8399  planginfo[i].dacl.initprivs = NULL;
8400  planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8401  planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8402  planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8403  planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8404  planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8405 
8406  /* Decide whether we want to dump it */
8407  selectDumpableProcLang(&(planginfo[i]), fout);
8408 
8409  /* Mark whether language has an ACL */
8410  if (!PQgetisnull(res, i, i_lanacl))
8411  planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8412  }
8413 
8414  PQclear(res);
8415 
8416  destroyPQExpBuffer(query);
8417 }
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:1991

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

4399 {
4400  PQExpBuffer query;
4401  PGresult *res;
4402  PublicationSchemaInfo *pubsinfo;
4403  DumpOptions *dopt = fout->dopt;
4404  int i_tableoid;
4405  int i_oid;
4406  int i_pnpubid;
4407  int i_pnnspid;
4408  int i,
4409  j,
4410  ntups;
4411 
4412  if (dopt->no_publications || fout->remoteVersion < 150000)
4413  return;
4414 
4415  query = createPQExpBuffer();
4416 
4417  /* Collect all publication membership info. */
4418  appendPQExpBufferStr(query,
4419  "SELECT tableoid, oid, pnpubid, pnnspid "
4420  "FROM pg_catalog.pg_publication_namespace");
4421  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4422 
4423  ntups = PQntuples(res);
4424 
4425  i_tableoid = PQfnumber(res, "tableoid");
4426  i_oid = PQfnumber(res, "oid");
4427  i_pnpubid = PQfnumber(res, "pnpubid");
4428  i_pnnspid = PQfnumber(res, "pnnspid");
4429 
4430  /* this allocation may be more than we need */
4431  pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4432  j = 0;
4433 
4434  for (i = 0; i < ntups; i++)
4435  {
4436  Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4437  Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4438  PublicationInfo *pubinfo;
4439  NamespaceInfo *nspinfo;
4440 
4441  /*
4442  * Ignore any entries for which we aren't interested in either the
4443  * publication or the rel.
4444  */
4445  pubinfo = findPublicationByOid(pnpubid);
4446  if (pubinfo == NULL)
4447  continue;
4448  nspinfo = findNamespaceByOid(pnnspid);
4449  if (nspinfo == NULL)
4450  continue;
4451 
4452  /*
4453  * We always dump publication namespaces unless the corresponding
4454  * namespace is excluded from the dump.
4455  */
4456  if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
4457  continue;
4458 
4459  /* OK, make a DumpableObject for this relationship */
4461  pubsinfo[j].dobj.catId.tableoid =
4462  atooid(PQgetvalue(res, i, i_tableoid));
4463  pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4464  AssignDumpId(&pubsinfo[j].dobj);
4465  pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4466  pubsinfo[j].dobj.name = nspinfo->dobj.name;
4467  pubsinfo[j].publication = pubinfo;
4468  pubsinfo[j].pubschema = nspinfo;
4469 
4470  /* Decide whether we want to dump it */
4471  selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4472 
4473  j++;
4474  }
4475 
4476  PQclear(res);
4477  destroyPQExpBuffer(query);
4478 }
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:973
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2091
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()

void getPublications ( Archive fout)

Definition at line 4204 of file pg_dump.c.

4205 {
4206  DumpOptions *dopt = fout->dopt;
4207  PQExpBuffer query;
4208  PGresult *res;
4209  PublicationInfo *pubinfo;
4210  int i_tableoid;
4211  int i_oid;
4212  int i_pubname;
4213  int i_pubowner;
4214  int i_puballtables;
4215  int i_pubinsert;
4216  int i_pubupdate;
4217  int i_pubdelete;
4218  int i_pubtruncate;
4219  int i_pubviaroot;
4220  int i,
4221  ntups;
4222 
4223  if (dopt->no_publications || fout->remoteVersion < 100000)
4224  return;
4225 
4226  query = createPQExpBuffer();
4227 
4228  resetPQExpBuffer(query);
4229 
4230  /* Get the publications. */
4231  if (fout->remoteVersion >= 130000)
4232  appendPQExpBufferStr(query,
4233  "SELECT p.tableoid, p.oid, p.pubname, "
4234  "p.pubowner, "
4235  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
4236  "FROM pg_publication p");
4237  else if (fout->remoteVersion >= 110000)
4238  appendPQExpBufferStr(query,
4239  "SELECT p.tableoid, p.oid, p.pubname, "
4240  "p.pubowner, "
4241  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
4242  "FROM pg_publication p");
4243  else
4244  appendPQExpBufferStr(query,
4245  "SELECT p.tableoid, p.oid, p.pubname, "
4246  "p.pubowner, "
4247  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot "
4248  "FROM pg_publication p");
4249 
4250  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4251 
4252  ntups = PQntuples(res);
4253 
4254  i_tableoid = PQfnumber(res, "tableoid");
4255  i_oid = PQfnumber(res, "oid");
4256  i_pubname = PQfnumber(res, "pubname");
4257  i_pubowner = PQfnumber(res, "pubowner");
4258  i_puballtables = PQfnumber(res, "puballtables");
4259  i_pubinsert = PQfnumber(res, "pubinsert");
4260  i_pubupdate = PQfnumber(res, "pubupdate");
4261  i_pubdelete = PQfnumber(res, "pubdelete");
4262  i_pubtruncate = PQfnumber(res, "pubtruncate");
4263  i_pubviaroot = PQfnumber(res, "pubviaroot");
4264 
4265  pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4266 
4267  for (i = 0; i < ntups; i++)
4268  {
4269  pubinfo[i].dobj.objType = DO_PUBLICATION;
4270  pubinfo[i].dobj.catId.tableoid =
4271  atooid(PQgetvalue(res, i, i_tableoid));
4272  pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4273  AssignDumpId(&pubinfo[i].dobj);
4274  pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4275  pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4276  pubinfo[i].puballtables =
4277  (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4278  pubinfo[i].pubinsert =
4279  (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4280  pubinfo[i].pubupdate =
4281  (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4282  pubinfo[i].pubdelete =
4283  (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4284  pubinfo[i].pubtruncate =
4285  (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4286  pubinfo[i].pubviaroot =
4287  (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4288 
4289  /* Decide whether we want to dump it */
4290  selectDumpableObject(&(pubinfo[i].dobj), fout);
4291  }
4292  PQclear(res);
4293 
4294  destroyPQExpBuffer(query);
4295 }

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

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

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

9721 {
9722  Oid roleoid = atooid(roleoid_str);
9723 
9724  /*
9725  * Do binary search to find the appropriate item.
9726  */
9727  if (nrolenames > 0)
9728  {
9729  RoleNameItem *low = &rolenames[0];
9730  RoleNameItem *high = &rolenames[nrolenames - 1];
9731 
9732  while (low <= high)
9733  {
9734  RoleNameItem *middle = low + (high - low) / 2;
9735 
9736  if (roleoid < middle->roleoid)
9737  high = middle - 1;
9738  else if (roleoid > middle->roleoid)
9739  low = middle + 1;
9740  else
9741  return middle->rolename; /* found a match */
9742  }
9743  }
9744 
9745  pg_fatal("role with OID %u does not exist", roleoid);
9746  return NULL; /* keep compiler quiet */
9747 }

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

2570 {
2571  TableInfo *parentTbinfo;
2572 
2573  Assert(tbinfo->ispartition);
2574  Assert(tbinfo->numParents == 1);
2575 
2576  parentTbinfo = tbinfo->parents[0];
2577  while (parentTbinfo->ispartition)
2578  {
2579  Assert(parentTbinfo->numParents == 1);
2580  parentTbinfo = parentTbinfo->parents[0];
2581  }
2582 
2583  return parentTbinfo;
2584 }

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

Referenced by dumpTableData(), and dumpTableData_insert().

◆ getRules()

void getRules ( Archive fout)

Definition at line 7972 of file pg_dump.c.

7973 {
7974  PGresult *res;
7975  int ntups;
7976  int i;
7977  PQExpBuffer query = createPQExpBuffer();
7978  RuleInfo *ruleinfo;
7979  int i_tableoid;
7980  int i_oid;
7981  int i_rulename;
7982  int i_ruletable;
7983  int i_ev_type;
7984  int i_is_instead;
7985  int i_ev_enabled;
7986 
7987  appendPQExpBufferStr(query, "SELECT "
7988  "tableoid, oid, rulename, "
7989  "ev_class AS ruletable, ev_type, is_instead, "
7990  "ev_enabled "
7991  "FROM pg_rewrite "
7992  "ORDER BY oid");
7993 
7994  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7995 
7996  ntups = PQntuples(res);
7997 
7998  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
7999 
8000  i_tableoid = PQfnumber(res, "tableoid");
8001  i_oid = PQfnumber(res, "oid");
8002  i_rulename = PQfnumber(res, "rulename");
8003  i_ruletable = PQfnumber(res, "ruletable");
8004  i_ev_type = PQfnumber(res, "ev_type");
8005  i_is_instead = PQfnumber(res, "is_instead");
8006  i_ev_enabled = PQfnumber(res, "ev_enabled");
8007 
8008  for (i = 0; i < ntups; i++)
8009  {
8010  Oid ruletableoid;
8011 
8012  ruleinfo[i].dobj.objType = DO_RULE;
8013  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8014  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8015  AssignDumpId(&ruleinfo[i].dobj);
8016  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8017  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8018  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8019  if (ruleinfo[i].ruletable == NULL)
8020  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8021  ruletableoid, ruleinfo[i].dobj.catId.oid);
8022  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8023  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8024  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8025  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8026  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8027  if (ruleinfo[i].ruletable)
8028  {
8029  /*
8030  * If the table is a view or materialized view, force its ON
8031  * SELECT rule to be sorted before the view itself --- this
8032  * ensures that any dependencies for the rule affect the table's
8033  * positioning. Other rules are forced to appear after their
8034  * table.
8035  */
8036  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8037  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8038  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8039  {
8040  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8041  ruleinfo[i].dobj.dumpId);
8042  /* We'll merge the rule into CREATE VIEW, if possible */
8043  ruleinfo[i].separate = false;
8044  }
8045  else
8046  {
8047  addObjectDependency(&ruleinfo[i].dobj,
8048  ruleinfo[i].ruletable->dobj.dumpId);
8049  ruleinfo[i].separate = true;
8050  }
8051  }
8052  else
8053  ruleinfo[i].separate = true;
8054  }
8055 
8056  PQclear(res);
8057 
8058  destroyPQExpBuffer(query);
8059 }

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

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

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

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

8622 {
8623  DumpOptions *dopt = fout->dopt;
8625  PQExpBuffer tbloids = createPQExpBuffer();
8626  PQExpBuffer checkoids = createPQExpBuffer();
8627  PGresult *res;
8628  int ntups;
8629  int curtblindx;
8630  int i_attrelid;
8631  int i_attnum;
8632  int i_attname;
8633  int i_atttypname;
8634  int i_attstattarget;
8635  int i_attstorage;
8636  int i_typstorage;
8637  int i_attidentity;
8638  int i_attgenerated;
8639  int i_attisdropped;
8640  int i_attlen;
8641  int i_attalign;
8642  int i_attislocal;
8643  int i_attnotnull;
8644  int i_attoptions;
8645  int i_attcollation;
8646  int i_attcompression;
8647  int i_attfdwoptions;
8648  int i_attmissingval;
8649  int i_atthasdef;
8650 
8651  /*
8652  * We want to perform just one query against pg_attribute, and then just
8653  * one against pg_attrdef (for DEFAULTs) and one against pg_constraint
8654  * (for CHECK constraints). However, we mustn't try to select every row
8655  * of those catalogs and then sort it out on the client side, because some
8656  * of the server-side functions we need would be unsafe to apply to tables
8657  * we don't have lock on. Hence, we build an array of the OIDs of tables
8658  * we care about (and now have lock on!), and use a WHERE clause to
8659  * constrain which rows are selected.
8660  */
8661  appendPQExpBufferChar(tbloids, '{');
8662  appendPQExpBufferChar(checkoids, '{');
8663  for (int i = 0; i < numTables; i++)
8664  {
8665  TableInfo *tbinfo = &tblinfo[i];
8666 
8667  /* Don't bother to collect info for sequences */
8668  if (tbinfo->relkind == RELKIND_SEQUENCE)
8669  continue;
8670 
8671  /* Don't bother with uninteresting tables, either */
8672  if (!tbinfo->interesting)
8673  continue;
8674 
8675  /* OK, we need info for this table */
8676  if (tbloids->len > 1) /* do we have more than the '{'? */
8677  appendPQExpBufferChar(tbloids, ',');
8678  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8679 
8680  if (tbinfo->ncheck > 0)
8681  {
8682  /* Also make a list of the ones with check constraints */
8683  if (checkoids->len > 1) /* do we have more than the '{'? */
8684  appendPQExpBufferChar(checkoids, ',');
8685  appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
8686  }
8687  }
8688  appendPQExpBufferChar(tbloids, '}');
8689  appendPQExpBufferChar(checkoids, '}');
8690 
8691  /*
8692  * Find all the user attributes and their types.
8693  *
8694  * Since we only want to dump COLLATE clauses for attributes whose
8695  * collation is different from their type's default, we use a CASE here to
8696  * suppress uninteresting attcollations cheaply.
8697  */
8699  "SELECT\n"
8700  "a.attrelid,\n"
8701  "a.attnum,\n"
8702  "a.attname,\n"
8703  "a.attstattarget,\n"
8704  "a.attstorage,\n"
8705  "t.typstorage,\n"
8706  "a.attnotnull,\n"
8707  "a.atthasdef,\n"
8708  "a.attisdropped,\n"
8709  "a.attlen,\n"
8710  "a.attalign,\n"
8711  "a.attislocal,\n"
8712  "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
8713  "array_to_string(a.attoptions, ', ') AS attoptions,\n"
8714  "CASE WHEN a.attcollation <> t.typcollation "
8715  "THEN a.attcollation ELSE 0 END AS attcollation,\n"
8716  "pg_catalog.array_to_string(ARRAY("
8717  "SELECT pg_catalog.quote_ident(option_name) || "
8718  "' ' || pg_catalog.quote_literal(option_value) "
8719  "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8720  "ORDER BY option_name"
8721  "), E',\n ') AS attfdwoptions,\n");
8722 
8723  if (fout->remoteVersion >= 140000)
8725  "a.attcompression AS attcompression,\n");
8726  else
8728  "'' AS attcompression,\n");
8729 
8730  if (fout->remoteVersion >= 100000)
8732  "a.attidentity,\n");
8733  else
8735  "'' AS attidentity,\n");
8736 
8737  if (fout->remoteVersion >= 110000)
8739  "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8740  "THEN a.attmissingval ELSE null END AS attmissingval,\n");
8741  else
8743  "NULL AS attmissingval,\n");
8744 
8745  if (fout->remoteVersion >= 120000)
8747  "a.attgenerated\n");
8748  else
8750  "'' AS attgenerated\n");
8751 
8752  /* need left join to pg_type to not fail on dropped columns ... */
8754  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8755  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
8756  "LEFT JOIN pg_catalog.pg_type t "
8757  "ON (a.atttypid = t.oid)\n"
8758  "WHERE a.attnum > 0::pg_catalog.int2\n"
8759  "ORDER BY a.attrelid, a.attnum",
8760  tbloids->data);
8761 
8762  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8763 
8764  ntups = PQntuples(res);
8765 
8766  i_attrelid = PQfnumber(res, "attrelid");
8767  i_attnum = PQfnumber(res, "attnum");
8768  i_attname = PQfnumber(res, "attname");
8769  i_atttypname = PQfnumber(res, "atttypname");
8770  i_attstattarget = PQfnumber(res, "attstattarget");
8771  i_attstorage = PQfnumber(res, "attstorage");
8772  i_typstorage = PQfnumber(res, "typstorage");
8773  i_attidentity = PQfnumber(res, "attidentity");
8774  i_attgenerated = PQfnumber(res, "attgenerated");
8775  i_attisdropped = PQfnumber(res, "attisdropped");
8776  i_attlen = PQfnumber(res, "attlen");
8777  i_attalign = PQfnumber(res, "attalign");
8778  i_attislocal = PQfnumber(res, "attislocal");
8779  i_attnotnull = PQfnumber(res, "attnotnull");
8780  i_attoptions = PQfnumber(res, "attoptions");
8781  i_attcollation = PQfnumber(res, "attcollation");
8782  i_attcompression = PQfnumber(res, "attcompression");
8783  i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8784  i_attmissingval = PQfnumber(res, "attmissingval");
8785  i_atthasdef = PQfnumber(res, "atthasdef");
8786 
8787  /* Within the next loop, we'll accumulate OIDs of tables with defaults */
8788  resetPQExpBuffer(tbloids);
8789  appendPQExpBufferChar(tbloids, '{');
8790 
8791  /*
8792  * Outer loop iterates once per table, not once per row. Incrementing of
8793  * r is handled by the inner loop.
8794  */
8795  curtblindx = -1;
8796  for (int r = 0; r < ntups;)
8797  {
8798  Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
8799  TableInfo *tbinfo = NULL;
8800  int numatts;
8801  bool hasdefaults;
8802 
8803  /* Count rows for this table */
8804  for (numatts = 1; numatts < ntups - r; numatts++)
8805  if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
8806  break;
8807 
8808  /*
8809  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8810  * order.
8811  */
8812  while (++curtblindx < numTables)
8813  {
8814  tbinfo = &tblinfo[curtblindx];
8815  if (tbinfo->dobj.catId.oid == attrelid)
8816  break;
8817  }
8818  if (curtblindx >= numTables)
8819  pg_fatal("unrecognized table OID %u", attrelid);
8820  /* cross-check that we only got requested tables */
8821  if (tbinfo->relkind == RELKIND_SEQUENCE ||
8822  !tbinfo->interesting)
8823  pg_fatal("unexpected column data for table \"%s\"",
8824  tbinfo->dobj.name);
8825 
8826  /* Save data for this table */
8827  tbinfo->numatts = numatts;
8828  tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
8829  tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
8830  tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
8831  tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
8832  tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
8833  tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
8834  tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
8835  tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
8836  tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
8837  tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
8838  tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
8839  tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
8840  tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
8841  tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
8842  tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
8843  tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
8844  tbinfo->notnull = (bool *) pg_malloc(numatts * sizeof(bool));
8845  tbinfo->inhNotNull = (bool *) pg_malloc(numatts * sizeof(bool));
8846  tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
8847  hasdefaults = false;
8848 
8849  for (int j = 0; j < numatts; j++, r++)
8850  {
8851  if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
8852  pg_fatal("invalid column numbering in table \"%s\"",
8853  tbinfo->dobj.name);
8854  tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
8855  tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
8856  if (PQgetisnull(res, r, i_attstattarget))
8857  tbinfo->attstattarget[j] = -1;
8858  else
8859  tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
8860  tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
8861  tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
8862  tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
8863  tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
8864  tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
8865  tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
8866  tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
8867  tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
8868  tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
8869  tbinfo->notnull[j] = (PQgetvalue(res, r, i_attnotnull)[0] == 't');
8870  tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
8871  tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
8872  tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
8873  tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
8874  tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
8875  tbinfo->attrdefs[j] = NULL; /* fix below */
8876  if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
8877  hasdefaults = true;
8878  /* these flags will be set in flagInhAttrs() */
8879  tbinfo->inhNotNull[j] = false;
8880  }
8881 
8882  if (hasdefaults)
8883  {
8884  /* Collect OIDs of interesting tables that have defaults */
8885  if (tbloids->len > 1) /* do we have more than the '{'? */
8886  appendPQExpBufferChar(tbloids, ',');
8887  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8888  }
8889  }
8890 
8891  PQclear(res);
8892 
8893  /*
8894  * Now get info about column defaults. This is skipped for a data-only
8895  * dump, as it is only needed for table schemas.
8896  */
8897  if (!dopt->dataOnly && tbloids->len > 1)
8898  {
8899  AttrDefInfo *attrdefs;
8900  int numDefaults;
8901  TableInfo *tbinfo = NULL;
8902 
8903  pg_log_info("finding table default expressions");
8904 
8905  appendPQExpBufferChar(tbloids, '}');
8906 
8907  printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
8908  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
8909  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8910  "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
8911  "ORDER BY a.adrelid, a.adnum",
8912  tbloids->data);
8913 
8914  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8915 
8916  numDefaults = PQntuples(res);
8917  attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
8918 
8919  curtblindx = -1;
8920  for (int j = 0; j < numDefaults; j++)
8921  {
8922  Oid adtableoid = atooid(PQgetvalue(res, j, 0));
8923  Oid adoid = atooid(PQgetvalue(res, j, 1));
8924  Oid adrelid = atooid(PQgetvalue(res, j, 2));
8925  int adnum = atoi(PQgetvalue(res, j, 3));
8926  char *adsrc = PQgetvalue(res, j, 4);
8927 
8928  /*
8929  * Locate the associated TableInfo; we rely on tblinfo[] being in
8930  * OID order.
8931  */
8932  if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
8933  {
8934  while (++curtblindx < numTables)
8935  {
8936  tbinfo = &tblinfo[curtblindx];
8937  if (tbinfo->dobj.catId.oid == adrelid)
8938  break;
8939  }
8940  if (curtblindx >= numTables)
8941  pg_fatal("unrecognized table OID %u", adrelid);
8942  }
8943 
8944  if (adnum <= 0 || adnum > tbinfo->numatts)
8945  pg_fatal("invalid adnum value %d for table \"%s\"",
8946  adnum, tbinfo->dobj.name);
8947 
8948  /*
8949  * dropped columns shouldn't have defaults, but just in case,
8950  * ignore 'em
8951  */
8952  if (tbinfo->attisdropped[adnum - 1])
8953  continue;
8954 
8955  attrdefs[j].dobj.objType = DO_ATTRDEF;
8956  attrdefs[j].dobj.catId.tableoid = adtableoid;
8957  attrdefs[j].dobj.catId.oid = adoid;
8958  AssignDumpId(&attrdefs[j].dobj);
8959  attrdefs[j].adtable = tbinfo;
8960  attrdefs[j].adnum = adnum;
8961  attrdefs[j].adef_expr = pg_strdup(adsrc);
8962 
8963  attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
8964  attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
8965 
8966  attrdefs[j].dobj.dump = tbinfo->dobj.dump;
8967 
8968  /*
8969  * Figure out whether the default/generation expression should be
8970  * dumped as part of the main CREATE TABLE (or similar) command or
8971  * as a separate ALTER TABLE (or similar) command. The preference
8972  * is to put it into the CREATE command, but in some cases that's
8973  * not possible.
8974  */
8975  if (tbinfo->attgenerated[adnum - 1])
8976  {
8977  /*
8978  * Column generation expressions cannot be dumped separately,
8979  * because there is no syntax for it. By setting separate to
8980  * false here we prevent the "default" from being processed as
8981  * its own dumpable object. Later, flagInhAttrs() will mark
8982  * it as not to be dumped at all, if possible (that is, if it
8983  * can be inherited from a parent).
8984  */
8985  attrdefs[j].separate = false;
8986  }
8987  else if (tbinfo->relkind == RELKIND_VIEW)
8988  {
8989  /*
8990  * Defaults on a VIEW must always be dumped as separate ALTER
8991  * TABLE commands.
8992  */
8993  attrdefs[j].separate = true;
8994  }
8995  else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
8996  {
8997  /* column will be suppressed, print default separately */
8998  attrdefs[j].separate = true;
8999  }
9000  else
9001  {
9002  attrdefs[j].separate = false;
9003  }
9004 
9005  if (!attrdefs[j].separate)
9006  {
9007  /*
9008  * Mark the default as needing to appear before the table, so
9009  * that any dependencies it has must be emitted before the
9010  * CREATE TABLE. If this is not possible, we'll change to
9011  * "separate" mode while sorting dependencies.
9012  */
9013  addObjectDependency(&tbinfo->dobj,
9014  attrdefs[j].dobj.dumpId);
9015  }
9016 
9017  tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9018  }
9019 
9020  PQclear(res);
9021  }
9022 
9023  /*
9024  * Get info about table CHECK constraints. This is skipped for a
9025  * data-only dump, as it is only needed for table schemas.
9026  */
9027  if (!dopt->dataOnly && checkoids->len > 2)
9028  {
9029  ConstraintInfo *constrs;
9030  int numConstrs;
9031  int i_tableoid;
9032  int i_oid;
9033  int i_conrelid;
9034  int i_conname;
9035  int i_consrc;
9036  int i_conislocal;
9037  int i_convalidated;
9038 
9039  pg_log_info("finding table check constraints");
9040 
9041  resetPQExpBuffer(q);
9043  "SELECT c.tableoid, c.oid, conrelid, conname, "
9044  "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9045  "conislocal, convalidated "
9046  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9047  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9048  "WHERE contype = 'c' "
9049  "ORDER BY c.conrelid, c.conname",
9050  checkoids->data);
9051 
9052  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9053 
9054  numConstrs = PQntuples(res);
9055  constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9056 
9057  i_tableoid = PQfnumber(res, "tableoid");
9058  i_oid = PQfnumber(res, "oid");
9059  i_conrelid = PQfnumber(res, "conrelid");
9060  i_conname = PQfnumber(res, "conname");
9061  i_consrc = PQfnumber(res, "consrc");
9062  i_conislocal = PQfnumber(res, "conislocal");
9063  i_convalidated = PQfnumber(res, "convalidated");
9064 
9065  /* As above, this loop iterates once per table, not once per row */
9066  curtblindx = -1;
9067  for (int j = 0; j < numConstrs;)
9068  {
9069  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9070  TableInfo *tbinfo = NULL;
9071  int numcons;
9072 
9073  /* Count rows for this table */
9074  for (numcons = 1; numcons < numConstrs - j; numcons++)
9075  if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9076  break;
9077 
9078  /*
9079  * Locate the associated TableInfo; we rely on tblinfo[] being in
9080  * OID order.
9081  */
9082  while (++curtblindx < numTables)
9083  {
9084  tbinfo = &tblinfo[curtblindx];
9085  if (tbinfo->dobj.catId.oid == conrelid)
9086  break;
9087  }
9088  if (curtblindx >= numTables)
9089  pg_fatal("unrecognized table OID %u", conrelid);
9090 
9091  if (numcons != tbinfo->ncheck)
9092  {
9093  pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9094  "expected %d check constraints on table \"%s\" but found %d",
9095  tbinfo->ncheck),
9096  tbinfo->ncheck, tbinfo->dobj.name, numcons);
9097  pg_log_error_hint("The system catalogs might be corrupted.");
9098  exit_nicely(1);
9099  }
9100 
9101  tbinfo->checkexprs = constrs + j;
9102 
9103  for (int c = 0; c < numcons; c++, j++)
9104  {
9105  bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9106 
9107  constrs[j].dobj.objType = DO_CONSTRAINT;
9108  constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9109  constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9110  AssignDumpId(&constrs[j].dobj);
9111  constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9112  constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9113  constrs[j].contable = tbinfo;
9114  constrs[j].condomain = NULL;
9115  constrs[j].contype = 'c';
9116  constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9117  constrs[j].confrelid = InvalidOid;
9118  constrs[j].conindex = 0;
9119  constrs[j].condeferrable = false;
9120  constrs[j].condeferred = false;
9121  constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9122 
9123  /*
9124  * An unvalidated constraint needs to be dumped separately, so
9125  * that potentially-violating existing data is loaded before
9126  * the constraint.
9127  */
9128  constrs[j].separate = !validated;
9129 
9130  constrs[j].dobj.dump = tbinfo->dobj.dump;
9131 
9132  /*
9133  * Mark the constraint as needing to appear before the table
9134  * --- this is so that any other dependencies of the
9135  * constraint will be emitted before we try to create the
9136  * table. If the constraint is to be dumped separately, it
9137  * will be dumped after data is loaded anyway, so don't do it.
9138  * (There's an automatic dependency in the opposite direction
9139  * anyway, so don't need to add one manually here.)
9140  */
9141  if (!constrs[j].separate)
9142  addObjectDependency(&tbinfo->dobj,
9143  constrs[j].dobj.dumpId);
9144 
9145  /*
9146  * We will detect later whether the constraint must be split
9147  * out from the table definition.
9148  */
9149  }
9150  }
9151 
9152  PQclear(res);
9153  }
9154 
9155  destroyPQExpBuffer(q);
9156  destroyPQExpBuffer(tbloids);
9157  destroyPQExpBuffer(checkoids);
9158 }
#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, _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::inhNotNull, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull, _tableInfo::numatts, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, res, resetPQExpBuffer(), _attrDefInfo::separate, _constraintInfo::separate, shouldPrintColumn(), CatalogId::tableoid, and _tableInfo::typstorage.

Referenced by getSchemaData().

◆ getTableData()

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

Definition at line 2769 of file pg_dump.c.

2770 {
2771  int i;
2772 
2773  for (i = 0; i < numTables; i++)
2774  {
2775  if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
2776  (!relkind || tblinfo[i].relkind == relkind))
2777  makeTableDataInfo(dopt, &(tblinfo[i]));
2778  }
2779 }
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2788

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

Referenced by main().

◆ getTableDataFKConstraints()

static void getTableDataFKConstraints ( void  )
static

Definition at line 2977 of file pg_dump.c.

2978 {
2979  DumpableObject **dobjs;
2980  int numObjs;
2981  int i;
2982 
2983  /* Search through all the dumpable objects for FK constraints */
2984  getDumpableObjects(&dobjs, &numObjs);
2985  for (i = 0; i < numObjs; i++)
2986  {
2987  if (dobjs[i]->objType == DO_FK_CONSTRAINT)
2988  {
2989  ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
2990  TableInfo *ftable;
2991 
2992  /* Not interesting unless both tables are to be dumped */
2993  if (cinfo->contable == NULL ||
2994  cinfo->contable->dataObj == NULL)
2995  continue;
2996  ftable = findTableByOid(cinfo->confrelid);
2997  if (ftable == NULL ||
2998  ftable->dataObj == NULL)
2999  continue;
3000 
3001  /*
3002  * Okay, make referencing table's TABLE_DATA object depend on the
3003  * referenced table's TABLE_DATA object.
3004  */
3006  ftable->dataObj->dobj.dumpId);
3007  }
3008  }
3009  free(dobjs);
3010 }
void getDumpableObjects(DumpableObject ***objs, int *numObjs)
Definition: common.c:762

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

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

void getTransforms ( Archive fout)

Definition at line 8537 of file pg_dump.c.

8538 {
8539  PGresult *res;
8540  int ntups;
8541  int i;
8542  PQExpBuffer query;
8543  TransformInfo *transforminfo;
8544  int i_tableoid;
8545  int i_oid;
8546  int i_trftype;
8547  int i_trflang;
8548  int i_trffromsql;
8549  int i_trftosql;
8550 
8551  /* Transforms didn't exist pre-9.5 */
8552  if (fout->remoteVersion < 90500)
8553  return;
8554 
8555  query = createPQExpBuffer();
8556 
8557  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8558  "trftype, trflang, trffromsql::oid, trftosql::oid "
8559  "FROM pg_transform "
8560  "ORDER BY 3,4");
8561 
8562  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8563 
8564  ntups = PQntuples(res);
8565 
8566  transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8567 
8568  i_tableoid = PQfnumber(res, "tableoid");
8569  i_oid = PQfnumber(res, "oid");
8570  i_trftype = PQfnumber(res, "trftype");
8571  i_trflang = PQfnumber(res, "trflang");
8572  i_trffromsql = PQfnumber(res, "trffromsql");
8573  i_trftosql = PQfnumber(res, "trftosql");
8574 
8575  for (i = 0; i < ntups; i++)
8576  {
8577  PQExpBufferData namebuf;
8578  TypeInfo *typeInfo;
8579  char *lanname;
8580 
8581  transforminfo[i].dobj.objType = DO_TRANSFORM;
8582  transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8583  transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8584  AssignDumpId(&transforminfo[i].dobj);
8585  transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8586  transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8587  transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8588  transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8589 
8590  /*
8591  * Try to name transform as concatenation of type and language name.
8592  * This is only used for purposes of sorting. If we fail to find
8593  * either, the name will be an empty string.
8594  */
8595  initPQExpBuffer(&namebuf);
8596  typeInfo = findTypeByOid(transforminfo[i].trftype);
8597  lanname = get_language_name(fout, transforminfo[i].trflang);
8598  if (typeInfo && lanname)
8599  appendPQExpBuffer(&namebuf, "%s %s",
8600  typeInfo->dobj.name, lanname);
8601  transforminfo[i].dobj.name = namebuf.data;
8602  free(lanname);
8603 
8604  /* Decide whether we want to dump it */
8605  selectDumpableObject(&(transforminfo[i].dobj), fout);
8606  }
8607 
8608  PQclear(res);
8609 
8610  destroyPQExpBuffer(query);
8611 }

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

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

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

Referenced by getSchemaData().

◆ getTSConfigurations()

void getTSConfigurations ( Archive fout)

Definition at line 9392 of file pg_dump.c.

9393 {
9394  PGresult *res;
9395  int ntups;
9396  int i;
9397  PQExpBuffer query;
9398  TSConfigInfo *cfginfo;
9399  int i_tableoid;
9400  int i_oid;
9401  int i_cfgname;
9402  int i_cfgnamespace;
9403  int i_cfgowner;
9404  int i_cfgparser;
9405 
9406  query = createPQExpBuffer();
9407 
9408  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9409  "cfgnamespace, cfgowner, cfgparser "
9410  "FROM pg_ts_config");
9411 
9412  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9413 
9414  ntups = PQntuples(res);
9415 
9416  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9417 
9418  i_tableoid = PQfnumber(res, "tableoid");
9419  i_oid = PQfnumber(res, "oid");
9420  i_cfgname = PQfnumber(res, "cfgname");
9421  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9422  i_cfgowner = PQfnumber(res, "cfgowner");
9423  i_cfgparser = PQfnumber(res, "cfgparser");
9424 
9425  for (i = 0; i < ntups; i++)
9426  {
9427  cfginfo[i].dobj.objType = DO_TSCONFIG;
9428  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9429  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9430  AssignDumpId(&cfginfo[i].dobj);
9431  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9432  cfginfo[i].dobj.namespace =
9433  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9434  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9435  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9436 
9437  /* Decide whether we want to dump it */
9438  selectDumpableObject(&(cfginfo[i].dobj), fout);
9439  }
9440 
9441  PQclear(res);
9442 
9443  destroyPQExpBuffer(query);
9444 }

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

Referenced by getSchemaData().

◆ getTSDictionaries()

void getTSDictionaries ( Archive fout)

Definition at line 9267 of file pg_dump.c.

9268 {
9269  PGresult *res;
9270  int ntups;
9271  int i;
9272  PQExpBuffer query;
9273  TSDictInfo *dictinfo;
9274  int i_tableoid;
9275  int i_oid;
9276  int i_dictname;
9277  int i_dictnamespace;
9278  int i_dictowner;
9279  int i_dicttemplate;
9280  int i_dictinitoption;
9281 
9282  query = createPQExpBuffer();
9283 
9284  appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9285  "dictnamespace, dictowner, "
9286  "dicttemplate, dictinitoption "
9287  "FROM pg_ts_dict");
9288 
9289  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9290 
9291  ntups = PQntuples(res);
9292 
9293  dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9294 
9295  i_tableoid = PQfnumber(res, "tableoid");
9296  i_oid = PQfnumber(res, "oid");
9297  i_dictname = PQfnumber(res, "dictname");
9298  i_dictnamespace = PQfnumber(res, "dictnamespace");
9299  i_dictowner = PQfnumber(res, "dictowner");
9300  i_dictinitoption = PQfnumber(res, "dictinitoption");
9301  i_dicttemplate = PQfnumber(res, "dicttemplate");
9302 
9303  for (i = 0; i < ntups; i++)
9304  {
9305  dictinfo[i].dobj.objType = DO_TSDICT;
9306  dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9307  dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9308  AssignDumpId(&dictinfo[i].dobj);
9309  dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9310  dictinfo[i].dobj.namespace =
9311  findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9312  dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9313  dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9314  if (PQgetisnull(res, i, i_dictinitoption))
9315  dictinfo[i].dictinitoption = NULL;
9316  else
9317  dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9318 
9319  /* Decide whether we want to dump it */
9320  selectDumpableObject(&(dictinfo[i].dobj), fout);
9321  }
9322 
9323  PQclear(res);
9324 
9325  destroyPQExpBuffer(query);
9326 }

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

Referenced by getSchemaData().

◆ getTSParsers()

void getTSParsers ( Archive fout)

Definition at line 9193 of file pg_dump.c.

9194 {
9195  PGresult *res;
9196  int ntups;
9197  int i;
9198  PQExpBuffer query;
9199  TSParserInfo *prsinfo;
9200  int i_tableoid;
9201  int i_oid;
9202  int i_prsname;
9203  int i_prsnamespace;
9204  int i_prsstart;
9205  int i_prstoken;
9206  int i_prsend;
9207  int i_prsheadline;
9208  int i_prslextype;
9209 
9210  query = createPQExpBuffer();
9211 
9212  /*
9213  * find all text search objects, including builtin ones; we filter out
9214  * system-defined objects at dump-out time.
9215  */
9216 
9217  appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
9218  "prsstart::oid, prstoken::oid, "
9219  "prsend::oid, prsheadline::oid, prslextype::oid "
9220  "FROM pg_ts_parser");
9221 
9222  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9223 
9224  ntups = PQntuples(res);
9225 
9226  prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
9227 
9228  i_tableoid = PQfnumber(res, "tableoid");
9229  i_oid = PQfnumber(res, "oid");
9230  i_prsname = PQfnumber(res, "prsname");
9231  i_prsnamespace = PQfnumber(res, "prsnamespace");
9232  i_prsstart = PQfnumber(res, "prsstart");
9233  i_prstoken = PQfnumber(res, "prstoken");
9234  i_prsend = PQfnumber(res, "prsend");
9235  i_prsheadline = PQfnumber(res, "prsheadline");
9236  i_prslextype = PQfnumber(res, "prslextype");
9237 
9238  for (i = 0; i < ntups; i++)
9239  {
9240  prsinfo[i].dobj.objType = DO_TSPARSER;
9241  prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9242  prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9243  AssignDumpId(&prsinfo[i].dobj);
9244  prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
9245  prsinfo[i].dobj.namespace =
9246  findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
9247  prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
9248  prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
9249  prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
9250  prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
9251  prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
9252 
9253  /* Decide whether we want to dump it */
9254  selectDumpableObject(&(prsinfo[i].dobj), fout);
9255  }
9256 
9257  PQclear(res);
9258 
9259  destroyPQExpBuffer(query);
9260 }

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

Referenced by getSchemaData().

◆ getTSTemplates()

void getTSTemplates ( Archive fout)

Definition at line 9333 of file pg_dump.c.

9334 {
9335  PGresult *res;
9336  int ntups;
9337  int i;
9338  PQExpBuffer query;
9339  TSTemplateInfo *tmplinfo;
9340  int i_tableoid;
9341  int i_oid;
9342  int i_tmplname;
9343  int i_tmplnamespace;
9344  int i_tmplinit;
9345  int i_tmpllexize;
9346 
9347  query = createPQExpBuffer();
9348 
9349  appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
9350  "tmplnamespace, tmplinit::oid, tmpllexize::oid "
9351  "FROM pg_ts_template");
9352 
9353  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9354 
9355  ntups = PQntuples(res);
9356 
9357  tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
9358 
9359  i_tableoid = PQfnumber(res, "tableoid");
9360  i_oid = PQfnumber(res, "oid");
9361  i_tmplname = PQfnumber(res, "tmplname");
9362  i_tmplnamespace = PQfnumber(res, "tmplnamespace");
9363  i_tmplinit = PQfnumber(res, "tmplinit");
9364  i_tmpllexize = PQfnumber(res, "tmpllexize");
9365 
9366  for (i = 0; i < ntups; i++)
9367  {
9368  tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
9369  tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9370  tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9371  AssignDumpId(&tmplinfo[i].dobj);
9372  tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
9373  tmplinfo[i].dobj.namespace =
9374  findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
9375  tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
9376  tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
9377 
9378  /* Decide whether we want to dump it */
9379  selectDumpableObject(&(tmplinfo[i].dobj), fout);
9380  }
9381 
9382  PQclear(res);
9383 
9384  destroyPQExpBuffer(query);
9385 }

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

Referenced by getSchemaData().

◆ getTypes()

void getTypes ( Archive fout)

Definition at line 5805 of file pg_dump.c.

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

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

4722 {
4723  ArchiveHandle *AH = (ArchiveHandle *) fout;
4724  const char *val;
4725 
4726  val = PQparameterStatus(AH->connection, "is_superuser");
4727 
4728  if (val && strcmp(val, "on") == 0)
4729  return true;
4730 
4731  return false;
4732 }
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7136
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 363 of file pg_dump.c.

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

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

2789 {
2790  TableDataInfo *tdinfo;
2791 
2792  /*
2793  * Nothing to do if we already decided to dump the table. This will
2794  * happen for "config" tables.
2795  */
2796  if (tbinfo->dataObj != NULL)
2797  return;
2798 
2799  /* Skip VIEWs (no data to dump) */
2800  if (tbinfo->relkind == RELKIND_VIEW)
2801  return;
2802  /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
2803  if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
2806  tbinfo->foreign_server)))
2807  return;
2808  /* Skip partitioned tables (data in partitions) */
2809  if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
2810  return;
2811 
2812  /* Don't dump data in unlogged tables, if so requested */
2813  if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
2814  dopt->no_unlogged_table_data)
2815  return;
2816 
2817  /* Check that the data is not explicitly excluded */
2819  tbinfo->dobj.catId.oid))
2820  return;
2821 
2822  /* OK, let's dump it */
2823  tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
2824 
2825  if (tbinfo->relkind == RELKIND_MATVIEW)
2826  tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
2827  else if (tbinfo->relkind == RELKIND_SEQUENCE)
2828  tdinfo->dobj.objType = DO_SEQUENCE_SET;
2829  else
2830  tdinfo->dobj.objType = DO_TABLE_DATA;
2831 
2832  /*
2833  * Note: use tableoid 0 so that this object won't be mistaken for
2834  * something that pg_depend entries apply to.
2835  */
2836  tdinfo->dobj.catId.tableoid = 0;
2837  tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
2838  AssignDumpId(&tdinfo->dobj);
2839  tdinfo->dobj.name = tbinfo->dobj.name;
2840  tdinfo->dobj.namespace = tbinfo->dobj.namespace;
2841  tdinfo->tdtable = tbinfo;
2842  tdinfo->filtercond = NULL; /* might get set later */
2843  addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
2844 
2845  /* A TableDataInfo contains data, of course */
2846  tdinfo->dobj.components |= DUMP_COMPONENT_DATA;
2847 
2848  tbinfo->dataObj = tdinfo;
2849 
2850  /* Make sure that we'll collect per-column info for this table. */
2851  tbinfo->interesting = true;
2852 }
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 18647 of file pg_dump.c.

18648 {
18649  /* Don't want to print it if it's just "{}" */
18650  return (reloptions != NULL && strlen(reloptions) > 2);
18651 }

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

◆ parseArchiveFormat()

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

Definition at line 1401 of file pg_dump.c.

1402 {
1403  ArchiveFormat archiveFormat;
1404 
1405  *mode = archModeWrite;
1406 
1407  if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
1408  {
1409  /* This is used by pg_dumpall, and is not documented */
1410  archiveFormat = archNull;
1411  *mode = archModeAppend;
1412  }
1413  else if (pg_strcasecmp(format, "c") == 0)
1414  archiveFormat = archCustom;
1415  else if (pg_strcasecmp(format, "custom") == 0)
1416  archiveFormat = archCustom;
1417  else if (pg_strcasecmp(format, "d") == 0)
1418  archiveFormat = archDirectory;
1419  else if (pg_strcasecmp(format, "directory") == 0)
1420  archiveFormat = archDirectory;
1421  else if (pg_strcasecmp(format, "p") == 0)
1422  archiveFormat = archNull;
1423  else if (pg_strcasecmp(format, "plain") == 0)
1424  archiveFormat = archNull;
1425  else if (pg_strcasecmp(format, "t") == 0)
1426  archiveFormat = archTar;
1427  else if (pg_strcasecmp(format, "tar") == 0)
1428  archiveFormat = archTar;
1429  else
1430  pg_fatal("invalid output format \"%s\" specified", format);
1431  return archiveFormat;
1432 }
@ 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 17984 of file pg_dump.c.

17986 {
17987  DumpOptions *dopt = fout->dopt;
17988  PQExpBuffer query;
17989  PGresult *res;
17990  int ntups,
17991  i;
17992  int i_conrelid,
17993  i_confrelid;
17994 
17995  /* Nothing to do if no extensions */
17996  if (numExtensions == 0)
17997  return;
17998 
17999  /*
18000  * Identify extension configuration tables and create TableDataInfo
18001  * objects for them, ensuring their data will be dumped even though the
18002  * tables themselves won't be.
18003  *
18004  * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
18005  * user data in a configuration table is treated like schema data. This
18006  * seems appropriate since system data in a config table would get
18007  * reloaded by CREATE EXTENSION. If the extension is not listed in the
18008  * list of extensions to be included, none of its data is dumped.
18009  */
18010  for (i = 0; i < numExtensions; i++)
18011  {
18012  ExtensionInfo *curext = &(extinfo[i]);
18013  char *extconfig = curext->extconfig;
18014  char *extcondition = curext->extcondition;
18015  char **extconfigarray = NULL;
18016  char **extconditionarray = NULL;
18017  int nconfigitems = 0;
18018  int nconditionitems = 0;
18019 
18020  /*
18021  * Check if this extension is listed as to include in the dump. If
18022  * not, any table data associated with it is discarded.
18023  */
18024  if (extension_include_oids.head != NULL &&
18026  curext->dobj.catId.oid))
18027  continue;
18028 
18029  /*
18030  * Check if this extension is listed as to exclude in the dump. If
18031  * yes, any table data associated with it is discarded.
18032  */
18033  if (extension_exclude_oids.head != NULL &&
18035  curext->dobj.catId.oid))
18036  continue;
18037 
18038  if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
18039  {
18040  int j;
18041 
18042  if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
18043  pg_fatal("could not parse %s array", "extconfig");
18044  if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
18045  pg_fatal("could not parse %s array", "extcondition");
18046  if (nconfigitems != nconditionitems)
18047  pg_fatal("mismatched number of configurations and conditions for extension");
18048 
18049  for (j = 0; j < nconfigitems; j++)
18050  {
18051  TableInfo *configtbl;
18052  Oid configtbloid = atooid(extconfigarray[j]);
18053  bool dumpobj =
18055 
18056  configtbl = findTableByOid(configtbloid);
18057  if (configtbl == NULL)
18058  continue;
18059 
18060  /*
18061  * Tables of not-to-be-dumped extensions shouldn't be dumped
18062  * unless the table or its schema is explicitly included
18063  */
18064  if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
18065  {
18066  /* check table explicitly requested */
18067  if (table_include_oids.head != NULL &&
18069  configtbloid))
18070  dumpobj = true;
18071 
18072  /* check table's schema explicitly requested */
18073  if (configtbl->dobj.namespace->dobj.dump &
18075  dumpobj = true;
18076  }
18077 
18078  /* check table excluded by an exclusion switch */
18079  if (table_exclude_oids.head != NULL &&
18081  configtbloid))
18082  dumpobj = false;
18083 
18084  /* check schema excluded by an exclusion switch */
18086  configtbl->dobj.namespace->dobj.catId.oid))
18087  dumpobj = false;
18088 
18089  if (dumpobj)
18090  {
18091  makeTableDataInfo(dopt, configtbl);
18092  if (configtbl->dataObj != NULL)
18093  {
18094  if (strlen(extconditionarray[j]) > 0)
18095  configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
18096  }
18097  }
18098  }
18099  }
18100  if (extconfigarray)
18101  free(extconfigarray);
18102  if (extconditionarray)
18103  free(extconditionarray);
18104  }
18105 
18106  /*
18107  * Now that all the TableDataInfo objects have been created for all the
18108  * extensions, check their FK dependencies and register them to try and
18109  * dump the data out in an order that they can be restored in.
18110  *
18111  * Note that this is not a problem for user tables as their FKs are
18112  * recreated after the data has been loaded.
18113  */
18114 
18115  query = createPQExpBuffer();
18116 
18117  printfPQExpBuffer(query,
18118  "SELECT conrelid, confrelid "
18119  "FROM pg_constraint "
18120  "JOIN pg_depend ON (objid = confrelid) "
18121  "WHERE contype = 'f' "
18122  "AND refclassid = 'pg_extension'::regclass "
18123  "AND classid = 'pg_class'::regclass;");
18124 
18125  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18126  ntups = PQntuples(res);
18127 
18128  i_conrelid = PQfnumber(res, "conrelid");
18129  i_confrelid = PQfnumber(res, "confrelid");
18130 
18131  /* Now get the dependencies and register them */
18132  for (i = 0; i < ntups; i++)
18133  {
18134  Oid conrelid,
18135  confrelid;
18136  TableInfo *reftable,
18137  *contable;
18138 
18139  conrelid = atooid(PQgetvalue(res, i, i_conrelid));
18140  confrelid = atooid(PQgetvalue(res, i, i_confrelid));
18141  contable = findTableByOid(conrelid);
18142  reftable = findTableByOid(confrelid);
18143 
18144  if (reftable == NULL ||
18145  reftable->dataObj == NULL ||
18146  contable == NULL ||
18147  contable->dataObj == NULL)
18148  continue;
18149 
18150  /*
18151  * Make referencing TABLE_DATA object depend on the referenced table's
18152  * TABLE_DATA object.
18153  */
18154  addObjectDependency(&contable->dataObj->dobj,
18155  reftable->dataObj->dobj.dumpId);
18156  }
18157  PQclear(res);
18158  destroyPQExpBuffer(query);
18159 }

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

1700 {
1701  const char *db;
1702 
1703  db = PQdb(conn);
1704  if (db == NULL)
1705  pg_fatal("You are currently not connected to a database.");
1706 
1707  if (strcmp(db, dbname) != 0)
1708  pg_fatal("cross-database references are not implemented: %s",
1709  pattern);
1710 }
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:7017

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

18679 {
18680  FilterStateData fstate;
18681  char *objname;
18682  FilterCommandType comtype;
18683  FilterObjectType objtype;
18684 
18685  filter_init(&fstate, filename, exit_nicely);
18686 
18687  while (filter_read_item(&fstate, &objname, &comtype, &objtype))
18688  {
18689  if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
18690  {
18691  switch (objtype)
18692  {
18694  break;
18701  pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
18702  "include",
18703  filter_object_type_name(objtype));
18704  exit_nicely(1);
18705  break; /* unreachable */
18706 
18709  break;
18712  break;
18715  dopt->include_everything = false;
18716  break;
18719  dopt->include_everything = false;
18720  break;
18723  objname);
18724  dopt->include_everything = false;
18725  break;
18726  }
18727  }
18728  else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
18729  {
18730  switch (objtype)
18731  {
18733  break;
18739  pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
18740  "exclude",
18741  filter_object_type_name(objtype));
18742  exit_nicely(1);
18743  break;
18744 
18747  break;
18750  objname);
18751  break;
18754  objname);
18755  break;
18758  break;
18761  break;
18764  objname);
18765  break;
18766  }
18767  }
18768  else
18769  {
18770  Assert(comtype == FILTER_COMMAND_TYPE_NONE);
18771  Assert(objtype == FILTER_OBJECT_TYPE_NONE);
18772  }
18773 
18774  if (objname)
18775  free(objname);
18776  }
18777 
18778  filter_free(&fstate);
18779 }
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:390
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 2734 of file pg_dump.c.

2735 {
2736  TableInfo *tbinfo = tdinfo->tdtable;
2737  PQExpBuffer q;
2738 
2739  /* If the materialized view is not flagged as populated, skip this. */
2740  if (!tbinfo->relispopulated)
2741  return;
2742 
2743  q = createPQExpBuffer();
2744 
2745  appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
2746  fmtQualifiedDumpable(tbinfo));
2747 
2748  if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2749  ArchiveEntry(fout,
2750  tdinfo->dobj.catId, /* catalog ID */
2751  tdinfo->dobj.dumpId, /* dump ID */
2752  ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2753  .namespace = tbinfo->dobj.namespace->dobj.name,
2754  .owner = tbinfo->rolname,
2755  .description = "MATERIALIZED VIEW DATA",
2756  .section = SECTION_POST_DATA,
2757  .createStmt = q->data,
2758  .deps = tdinfo->dobj.dependencies,
2759  .nDeps = tdinfo->dobj.nDeps));
2760 
2761  destroyPQExpBuffer(q);
2762 }

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

2025 {
2026  if (checkExtensionMembership(&method->dobj, fout))
2027  return; /* extension membership overrides all else */
2028 
2029  /*
2030  * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
2031  * they do not support ACLs currently.
2032  */
2033  if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2034  method->dobj.dump = DUMP_COMPONENT_NONE;
2035  else
2036  method->dobj.dump = fout->dopt->include_everything ?
2038 }
static bool checkExtensionMembership(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:1724
#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 1966 of file pg_dump.c.

1967 {
1968  if (checkExtensionMembership(&cast->dobj, fout))
1969  return; /* extension membership overrides all else */
1970 
1971  /*
1972  * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
1973  * support ACLs currently.
1974  */
1975  if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
1976  cast->dobj.dump = DUMP_COMPONENT_NONE;
1977  else
1978  cast->dobj.dump = fout->dopt->include_everything ?
1980 }

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

1945 {
1946  /* Default ACLs can't be extension members */
1947 
1948  if (dinfo->dobj.namespace)
1949  /* default ACLs are considered part of the namespace */
1950  dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
1951  else
1952  dinfo->dobj.dump = dopt->include_everything ?
1954 }

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

2053 {
2054  /*
2055  * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
2056  * change permissions on their member objects, if they wish to, and have
2057  * those changes preserved.
2058  */
2059  if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2060  extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
2061  else
2062  {
2063  /* check if there is a list of extensions to dump */
2064  if (extension_include_oids.head != NULL)
2065  extinfo->dobj.dump = extinfo->dobj.dump_contains =
2067  extinfo->dobj.catId.oid) ?
2069  else
2070  extinfo->dobj.dump = extinfo->dobj.dump_contains =
2071  dopt->include_everything ?
2073 
2074  /* check that the extension is not explicitly excluded */
2075  if (extinfo->dobj.dump &&
2077  extinfo->dobj.catId.oid))
2078  extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
2079  }
2080 }

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

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

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

2128 {
2129  if (checkExtensionMembership(dobj, fout))
2130  return; /* extension membership overrides all else */
2131 
2132  /*
2133  * Default policy is to dump if parent namespace is dumpable, or for
2134  * non-namespace-associated items, dump if we're dumping "everything".
2135  */
2136  if (dobj->namespace)
2137  dobj->dump = dobj->namespace->dobj.dump_contains;
2138  else
2139  dobj->dump = fout->dopt->include_everything ?
2141 }

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

1992 {
1993  if (checkExtensionMembership(&plang->dobj, fout))
1994  return; /* extension membership overrides all else */
1995 
1996  /*
1997  * Only include procedural languages when we are dumping everything.
1998  *
1999  * For from-initdb procedural languages, only include ACLs, as we do for
2000  * the pg_catalog namespace. We need this because procedural languages do
2001  * not live in any namespace.
2002  */
2003  if (!fout->dopt->include_everything)
2004  plang->dobj.dump = DUMP_COMPONENT_NONE;
2005  else
2006  {
2007  if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2008  plang->dobj.dump = fout->remoteVersion < 90600 ?
2010  else
2011  plang->dobj.dump = DUMP_COMPONENT_ALL;
2012  }
2013 }

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

2092 {
2093  if (checkExtensionMembership(dobj, fout))
2094  return; /* extension membership overrides all else */
2095 
2096  dobj->dump = fout->dopt->include_everything ?
2098 }

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

2110 {
2111  if (checkExtensionMembership(&sobj->dobj, fout))
2112  return; /* extension membership overrides all else */
2113 
2114  sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
2115  if (sobj->stattable == NULL ||
2117  sobj->dobj.dump = DUMP_COMPONENT_NONE;
2118 }

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

1861 {
1862  if (checkExtensionMembership(&tbinfo->dobj, fout))
1863  return; /* extension membership overrides all else */
1864 
1865  /*
1866  * If specific tables are being dumped, dump just those tables; else, dump
1867  * according to the parent namespace's dump flag.
1868  */
1869  if (table_include_oids.head != NULL)
1871  tbinfo->dobj.catId.oid) ?
1873  else
1874  tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
1875 
1876  /*
1877  * In any case, a table can be excluded by an exclusion switch
1878  */
1879  if (tbinfo->dobj.dump &&
1881  tbinfo->dobj.catId.oid))
1882  tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
1883 }

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

1900 {
1901  /* skip complex types, except for standalone composite types */
1902  if (OidIsValid(tyinfo->typrelid) &&
1903  tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
1904  {
1905  TableInfo *tytable = findTableByOid(tyinfo->typrelid);
1906 
1907  tyinfo->dobj.objType = DO_DUMMY_TYPE;
1908  if (tytable != NULL)
1909  tyinfo->dobj.dump = tytable->dobj.dump;
1910  else
1911  tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
1912  return;
1913  }
1914 
1915  /* skip auto-generated array and multirange types */
1916  if (tyinfo->isArray || tyinfo->isMultirange)
1917  {
1918  tyinfo->dobj.objType = DO_DUMMY_TYPE;
1919 
1920  /*
1921  * Fall through to set the dump flag; we assume that the subsequent
1922  * rules will do the same thing as they would for the array's base
1923  * type or multirange's range type. (We cannot reliably look up the
1924  * base type here, since getTypes may not have processed it yet.)
1925  */
1926  }
1927 
1928  if (checkExtensionMembership(&tyinfo->dobj, fout))
1929  return; /* extension membership overrides all else */
1930 
1931  /* Dump based on if the contents of the namespace are being dumped */
1932  tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
1933 }

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

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

1373 {
1374  /*
1375  * We want to re-select all the same values the leader connection is
1376  * using. We'll have inherited directly-usable values in
1377  * AH->sync_snapshot_id and AH->use_role, but we need to translate the
1378  * inherited encoding value back to a string to pass to setup_connection.
1379  */
1380  setup_connection(AH,
1382  NULL,
1383  NULL);
1384 }

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

9179 {
9180  if (dopt->binary_upgrade)
9181  return true;
9182  if (tbinfo->attisdropped[colno])
9183  return false;
9184  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9185 }

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

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

Variable Documentation

◆ binaryUpgradeClassOids

BinaryUpgradeClassOidItem* binaryUpgradeClassOids = NULL
static

Definition at line 173 of file pg_dump.c.

Referenced by binary_upgrade_set_pg_class_oids(), and collectBinaryUpgradeClassOids().

◆ comments

CommentItem* comments = NULL
static

◆ compression_algorithm

pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE
static

Definition at line 122 of file pg_dump.c.

Referenced by main().

◆ dosync

bool dosync = true
static

Definition at line 115 of file pg_dump.c.

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

◆ extension_exclude_oids

SimpleOidList extension_exclude_oids = {NULL, NULL}
static

Definition at line 152 of file pg_dump.c.

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

◆ extension_exclude_patterns

SimpleStringList extension_exclude_patterns = {NULL, NULL}
static

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

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

◆ extension_include_patterns

SimpleStringList extension_include_patterns = {NULL, NULL}
static

Definition at line 148 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ extra_float_digits

int extra_float_digits
static

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

Referenced by main(), and setup_connection().

◆ nbinaryUpgradeClassOids

int nbinaryUpgradeClassOids = 0
static

Definition at line 174 of file pg_dump.c.

Referenced by binary_upgrade_set_pg_class_oids(), and collectBinaryUpgradeClassOids().

◆ ncomments

int ncomments = 0
static

◆ nilCatalogId

◆ nrolenames

int nrolenames = 0
static

Definition at line 162 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ nseclabels

int nseclabels = 0
static

Definition at line 170 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ rolenames

RoleNameItem* rolenames = NULL
static

Definition at line 161 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ schema_exclude_oids

SimpleOidList schema_exclude_oids = {NULL, NULL}
static

Definition at line 133 of file pg_dump.c.

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

◆ schema_exclude_patterns

SimpleStringList schema_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and selectDumpableNamespace().

◆ schema_include_patterns

SimpleStringList schema_include_patterns = {NULL, NULL}
static

Definition at line 130 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ seclabels

SecLabelItem* seclabels = NULL
static

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

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

◆ table_exclude_patterns

SimpleStringList table_exclude_patterns = {NULL, NULL}
static

Definition at line 138 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 139 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 135 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 136 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 143 of file pg_dump.c.

Referenced by main(), and makeTableDataInfo().

◆ tabledata_exclude_patterns

SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and read_dump_filters().