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_constraint_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_publication_d.h"
#include "catalog/pg_shdepend_d.h"
#include "catalog/pg_subscription_d.h"
#include "catalog/pg_type_d.h"
#include "common/connect.h"
#include "common/int.h"
#include "common/relpath.h"
#include "common/shortest_dec.h"
#include "compress_io.h"
#include "dumputils.h"
#include "fe_utils/option_utils.h"
#include "fe_utils/string_utils.h"
#include "filter.h"
#include "getopt_long.h"
#include "libpq/libpq-fs.h"
#include "parallel.h"
#include "pg_backup_db.h"
#include "pg_backup_utils.h"
#include "pg_dump.h"
#include "storage/block.h"
Include dependency graph for pg_dump.c:

Go to the source code of this file.

Data Structures

struct  RoleNameItem
 
struct  CommentItem
 
struct  SecLabelItem
 
struct  BinaryUpgradeClassOidItem
 
struct  SequenceItem
 

Macros

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

Typedefs

typedef enum SeqType SeqType
 
typedef enum OidOptions OidOptions
 

Enumerations

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

Functions

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

Variables

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

Macro Definition Documentation

◆ DUMP_DEFAULT_ROWS_PER_INSERT

#define DUMP_DEFAULT_ROWS_PER_INSERT   1

Definition at line 228 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:296

Definition at line 240 of file pg_dump.c.

◆ MAX_ATTR_STATS_RELS

#define MAX_ATTR_STATS_RELS   64

Definition at line 222 of file pg_dump.c.

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

Definition at line 235 of file pg_dump.c.

Typedef Documentation

◆ OidOptions

typedef enum OidOptions OidOptions

◆ SeqType

typedef enum SeqType SeqType

Enumeration Type Documentation

◆ OidOptions

enum OidOptions
Enumerator
zeroIsError 
zeroAsStar 
zeroAsNone 

Definition at line 142 of file pg_dump.c.

143{
144 zeroIsError = 1,
145 zeroAsStar = 2,
146 zeroAsNone = 4,
147} OidOptions;
OidOptions
Definition: pg_dump.c:143
@ zeroIsError
Definition: pg_dump.c:144
@ zeroAsStar
Definition: pg_dump.c:145
@ zeroAsNone
Definition: pg_dump.c:146

◆ SeqType

enum SeqType
Enumerator
SEQTYPE_SMALLINT 
SEQTYPE_INTEGER 
SEQTYPE_BIGINT 

Definition at line 111 of file pg_dump.c.

112{
116} SeqType;
SeqType
Definition: pg_dump.c:112
@ SEQTYPE_BIGINT
Definition: pg_dump.c:115
@ SEQTYPE_INTEGER
Definition: pg_dump.c:114
@ SEQTYPE_SMALLINT
Definition: pg_dump.c:113

Function Documentation

◆ addBoundaryDependencies()

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

Definition at line 20137 of file pg_dump.c.

20139{
20140 DumpableObject *preDataBound = boundaryObjs + 0;
20141 DumpableObject *postDataBound = boundaryObjs + 1;
20142 int i;
20143
20144 for (i = 0; i < numObjs; i++)
20145 {
20146 DumpableObject *dobj = dobjs[i];
20147
20148 /*
20149 * The classification of object types here must match the SECTION_xxx
20150 * values assigned during subsequent ArchiveEntry calls!
20151 */
20152 switch (dobj->objType)
20153 {
20154 case DO_NAMESPACE:
20155 case DO_EXTENSION:
20156 case DO_TYPE:
20157 case DO_SHELL_TYPE:
20158 case DO_FUNC:
20159 case DO_AGG:
20160 case DO_OPERATOR:
20161 case DO_ACCESS_METHOD:
20162 case DO_OPCLASS:
20163 case DO_OPFAMILY:
20164 case DO_COLLATION:
20165 case DO_CONVERSION:
20166 case DO_TABLE:
20167 case DO_TABLE_ATTACH:
20168 case DO_ATTRDEF:
20169 case DO_PROCLANG:
20170 case DO_CAST:
20171 case DO_DUMMY_TYPE:
20172 case DO_TSPARSER:
20173 case DO_TSDICT:
20174 case DO_TSTEMPLATE:
20175 case DO_TSCONFIG:
20176 case DO_FDW:
20177 case DO_FOREIGN_SERVER:
20178 case DO_TRANSFORM:
20179 /* Pre-data objects: must come before the pre-data boundary */
20180 addObjectDependency(preDataBound, dobj->dumpId);
20181 break;
20182 case DO_TABLE_DATA:
20183 case DO_SEQUENCE_SET:
20184 case DO_LARGE_OBJECT:
20186 /* Data objects: must come between the boundaries */
20187 addObjectDependency(dobj, preDataBound->dumpId);
20188 addObjectDependency(postDataBound, dobj->dumpId);
20189 break;
20190 case DO_INDEX:
20191 case DO_INDEX_ATTACH:
20192 case DO_STATSEXT:
20193 case DO_REFRESH_MATVIEW:
20194 case DO_TRIGGER:
20195 case DO_EVENT_TRIGGER:
20196 case DO_DEFAULT_ACL:
20197 case DO_POLICY:
20198 case DO_PUBLICATION:
20199 case DO_PUBLICATION_REL:
20201 case DO_SUBSCRIPTION:
20203 /* Post-data objects: must come after the post-data boundary */
20204 addObjectDependency(dobj, postDataBound->dumpId);
20205 break;
20206 case DO_RULE:
20207 /* Rules are post-data, but only if dumped separately */
20208 if (((RuleInfo *) dobj)->separate)
20209 addObjectDependency(dobj, postDataBound->dumpId);
20210 break;
20211 case DO_CONSTRAINT:
20212 case DO_FK_CONSTRAINT:
20213 /* Constraints are post-data, but only if dumped separately */
20214 if (((ConstraintInfo *) dobj)->separate)
20215 addObjectDependency(dobj, postDataBound->dumpId);
20216 break;
20218 /* nothing to do */
20219 break;
20221 /* must come after the pre-data boundary */
20222 addObjectDependency(dobj, preDataBound->dumpId);
20223 break;
20224 case DO_REL_STATS:
20225 /* stats section varies by parent object type, DATA or POST */
20226 if (((RelStatsInfo *) dobj)->section == SECTION_DATA)
20227 {
20228 addObjectDependency(dobj, preDataBound->dumpId);
20229 addObjectDependency(postDataBound, dobj->dumpId);
20230 }
20231 else
20232 addObjectDependency(dobj, postDataBound->dumpId);
20233 break;
20234 }
20235 }
20236}
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:818
int i
Definition: isn.c:77
@ SECTION_DATA
Definition: pg_backup.h:59
@ DO_EVENT_TRIGGER
Definition: pg_dump.h:80
@ DO_REFRESH_MATVIEW
Definition: pg_dump.h:81
@ DO_POLICY
Definition: pg_dump.h:82
@ DO_CAST
Definition: pg_dump.h:64
@ DO_FOREIGN_SERVER
Definition: pg_dump.h:73
@ DO_PRE_DATA_BOUNDARY
Definition: pg_dump.h:78
@ DO_PROCLANG
Definition: pg_dump.h:63
@ DO_TYPE
Definition: pg_dump.h:43
@ DO_INDEX
Definition: pg_dump.h:56
@ DO_COLLATION
Definition: pg_dump.h:51
@ DO_LARGE_OBJECT
Definition: pg_dump.h:76
@ DO_TSCONFIG
Definition: pg_dump.h:71
@ DO_OPERATOR
Definition: pg_dump.h:47
@ DO_FK_CONSTRAINT
Definition: pg_dump.h:62
@ DO_CONSTRAINT
Definition: pg_dump.h:61
@ DO_SUBSCRIPTION
Definition: pg_dump.h:87
@ DO_DEFAULT_ACL
Definition: pg_dump.h:74
@ DO_FDW
Definition: pg_dump.h:72
@ DO_SUBSCRIPTION_REL
Definition: pg_dump.h:88
@ DO_REL_STATS
Definition: pg_dump.h:86
@ DO_SEQUENCE_SET
Definition: pg_dump.h:66
@ DO_ATTRDEF
Definition: pg_dump.h:55
@ DO_PUBLICATION_REL
Definition: pg_dump.h:84
@ DO_TABLE_ATTACH
Definition: pg_dump.h:54
@ DO_OPCLASS
Definition: pg_dump.h:49
@ DO_INDEX_ATTACH
Definition: pg_dump.h:57
@ DO_TSTEMPLATE
Definition: pg_dump.h:70
@ DO_STATSEXT
Definition: pg_dump.h:58
@ DO_FUNC
Definition: pg_dump.h:45
@ DO_POST_DATA_BOUNDARY
Definition: pg_dump.h:79
@ DO_LARGE_OBJECT_DATA
Definition: pg_dump.h:77
@ DO_OPFAMILY
Definition: pg_dump.h:50
@ DO_TRANSFORM
Definition: pg_dump.h:75
@ DO_ACCESS_METHOD
Definition: pg_dump.h:48
@ DO_PUBLICATION_TABLE_IN_SCHEMA
Definition: pg_dump.h:85
@ DO_CONVERSION
Definition: pg_dump.h:52
@ DO_TRIGGER
Definition: pg_dump.h:60
@ DO_RULE
Definition: pg_dump.h:59
@ DO_DUMMY_TYPE
Definition: pg_dump.h:67
@ DO_TSDICT
Definition: pg_dump.h:69
@ DO_TSPARSER
Definition: pg_dump.h:68
@ DO_EXTENSION
Definition: pg_dump.h:42
@ DO_TABLE_DATA
Definition: pg_dump.h:65
@ DO_PUBLICATION
Definition: pg_dump.h:83
@ DO_TABLE
Definition: pg_dump.h:53
@ DO_NAMESPACE
Definition: pg_dump.h:41
@ DO_AGG
Definition: pg_dump.h:46
@ DO_SHELL_TYPE
Definition: pg_dump.h:44
DumpId dumpId
Definition: pg_dump.h:151
DumpableObjectType objType
Definition: pg_dump.h:149

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_REL_STATS, 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, _dumpableObject::objType, and SECTION_DATA.

Referenced by main().

◆ addConstrChildIdxDeps()

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

Definition at line 8450 of file pg_dump.c.

8451{
8452 SimplePtrListCell *cell;
8453
8455
8456 for (cell = refidx->partattaches.head; cell; cell = cell->next)
8457 {
8458 IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
8459
8460 addObjectDependency(dobj, attach->dobj.dumpId);
8461
8462 if (attach->partitionIdx->partattaches.head != NULL)
8463 addConstrChildIdxDeps(dobj, attach->partitionIdx);
8464 }
8465}
Assert(PointerIsAligned(start, uint64))
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:8450
struct SimplePtrListCell * next
Definition: simple_list.h:48
SimplePtrListCell * head
Definition: simple_list.h:54
IndxInfo * partitionIdx
Definition: pg_dump.h:445
DumpableObject dobj
Definition: pg_dump.h:443
SimplePtrList partattaches
Definition: pg_dump.h:435

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

Referenced by addConstrChildIdxDeps(), and 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 5636 of file pg_dump.c.

5642{
5643 if (dobj->depends_on_ext)
5644 {
5645 char *nm;
5646 PGresult *res;
5647 PQExpBuffer query;
5648 int ntups;
5649 int i_extname;
5650 int i;
5651
5652 /* dodge fmtId() non-reentrancy */
5653 nm = pg_strdup(objname);
5654
5655 query = createPQExpBuffer();
5656 appendPQExpBuffer(query,
5657 "SELECT e.extname "
5658 "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5659 "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5660 "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5661 "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5662 catalog,
5663 dobj->catId.oid);
5664 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5665 ntups = PQntuples(res);
5666 i_extname = PQfnumber(res, "extname");
5667 for (i = 0; i < ntups; i++)
5668 {
5669 appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5670 keyword, nm,
5671 fmtId(PQgetvalue(res, i, i_extname)));
5672 }
5673
5674 PQclear(res);
5675 destroyPQExpBuffer(query);
5676 pg_free(nm);
5677 }
5678}
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3606
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define PQgetvalue
Definition: libpq-be-fe.h:253
#define PQclear
Definition: libpq-be-fe.h:245
#define PQntuples
Definition: libpq-be-fe.h:251
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:128
PGresult * ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
Definition: pg_backup_db.c:229
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:248
CatalogId catId
Definition: pg_dump.h:150
bool depends_on_ext
Definition: pg_dump.h:158

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, and PQntuples.

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

◆ appendNamedArgument()

static void appendNamedArgument ( PQExpBuffer  out,
Archive fout,
const char *  argname,
const char *  argtype,
const char *  argval 
)
static

Definition at line 10996 of file pg_dump.c.

10998{
10999 appendPQExpBufferStr(out, ",\n\t");
11000
11001 appendStringLiteralAH(out, argname, fout);
11002 appendPQExpBufferStr(out, ", ");
11003
11004 appendStringLiteralAH(out, argval, fout);
11005 appendPQExpBuffer(out, "::%s", argtype);
11006}
#define appendStringLiteralAH(buf, str, AH)
Definition: pg_backup.h:343
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367

References appendPQExpBuffer(), appendPQExpBufferStr(), and appendStringLiteralAH.

Referenced by dumpRelationStats_dumper().

◆ appendReloptionsArrayAH()

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

Definition at line 20464 of file pg_dump.c.

20466{
20467 bool res;
20468
20469 res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
20470 fout->std_strings);
20471 if (!res)
20472 pg_log_warning("could not parse %s array", "reloptions");
20473}
#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:966
bool std_strings
Definition: pg_backup.h:244
int encoding
Definition: pg_backup.h:243

References appendReloptionsArray(), Archive::encoding, pg_log_warning, 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 5947 of file pg_dump.c.

5952{
5953 DumpableObject *extobj = NULL;
5954 int i;
5955
5956 if (!dobj->ext_member)
5957 return;
5958
5959 /*
5960 * Find the parent extension. We could avoid this search if we wanted to
5961 * add a link field to DumpableObject, but the space costs of that would
5962 * be considerable. We assume that member objects could only have a
5963 * direct dependency on their own extension, not any others.
5964 */
5965 for (i = 0; i < dobj->nDeps; i++)
5966 {
5967 extobj = findObjectByDumpId(dobj->dependencies[i]);
5968 if (extobj && extobj->objType == DO_EXTENSION)
5969 break;
5970 extobj = NULL;
5971 }
5972 if (extobj == NULL)
5973 pg_fatal("could not find parent extension for %s %s",
5974 objtype, objname);
5975
5976 appendPQExpBufferStr(upgrade_buffer,
5977 "\n-- For binary upgrade, handle extension membership the hard way\n");
5978 appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5979 fmtId(extobj->name),
5980 objtype);
5981 if (objnamespace && *objnamespace)
5982 appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5983 appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5984}
DumpableObject * findObjectByDumpId(DumpId dumpId)
Definition: common.c:765
#define pg_fatal(...)
char * name
Definition: pg_dump.h:152
DumpId * dependencies
Definition: pg_dump.h:159
bool ext_member
Definition: pg_dump.h:157

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

5859{
5862
5864
5865 /*
5866 * Preserve the OID and relfilenumber of the table, table's index, table's
5867 * toast table and toast table's index if any.
5868 *
5869 * One complexity is that the current table definition might not require
5870 * the creation of a TOAST table, but the old database might have a TOAST
5871 * table that was created earlier, before some wide columns were dropped.
5872 * By setting the TOAST oid we force creation of the TOAST heap and index
5873 * by the new backend, so we can copy the files during binary upgrade
5874 * without worrying about this case.
5875 */
5876 key.oid = pg_class_oid;
5880
5881 appendPQExpBufferStr(upgrade_buffer,
5882 "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5883
5884 if (entry->relkind != RELKIND_INDEX &&
5885 entry->relkind != RELKIND_PARTITIONED_INDEX)
5886 {
5887 appendPQExpBuffer(upgrade_buffer,
5888 "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5889 pg_class_oid);
5890
5891 /*
5892 * Not every relation has storage. Also, in a pre-v12 database,
5893 * partitioned tables have a relfilenumber, which should not be
5894 * preserved when upgrading.
5895 */
5896 if (RelFileNumberIsValid(entry->relfilenumber) &&
5897 entry->relkind != RELKIND_PARTITIONED_TABLE)
5898 appendPQExpBuffer(upgrade_buffer,
5899 "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5900 entry->relfilenumber);
5901
5902 /*
5903 * In a pre-v12 database, partitioned tables might be marked as having
5904 * toast tables, but we should ignore them if so.
5905 */
5906 if (OidIsValid(entry->toast_oid) &&
5907 entry->relkind != RELKIND_PARTITIONED_TABLE)
5908 {
5909 appendPQExpBuffer(upgrade_buffer,
5910 "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5911 entry->toast_oid);
5912 appendPQExpBuffer(upgrade_buffer,
5913 "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5914 entry->toast_relfilenumber);
5915
5916 /* every toast table has an index */
5917 appendPQExpBuffer(upgrade_buffer,
5918 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5919 entry->toast_index_oid);
5920 appendPQExpBuffer(upgrade_buffer,
5921 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5923 }
5924 }
5925 else
5926 {
5927 /* Preserve the OID and relfilenumber of the index */
5928 appendPQExpBuffer(upgrade_buffer,
5929 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5930 pg_class_oid);
5931 appendPQExpBuffer(upgrade_buffer,
5932 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5933 entry->relfilenumber);
5934 }
5935
5936 appendPQExpBufferChar(upgrade_buffer, '\n');
5937}
#define OidIsValid(objectId)
Definition: c.h:788
static int nbinaryUpgradeClassOids
Definition: pg_dump.c:209
static BinaryUpgradeClassOidItem * binaryUpgradeClassOids
Definition: pg_dump.c:208
static int BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:5807
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:107
RelFileNumber toast_relfilenumber
Definition: pg_dump.c:105
RelFileNumber relfilenumber
Definition: pg_dump.c:103

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

5795{
5796 Oid pg_type_oid = tbinfo->reltype;
5797
5798 if (OidIsValid(pg_type_oid))
5799 binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5800 pg_type_oid, false, false);
5801}
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:5712
unsigned int Oid
Definition: postgres_ext.h:32
Oid reltype
Definition: pg_dump.h:331

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

5717{
5718 PQExpBuffer upgrade_query = createPQExpBuffer();
5719 PGresult *res;
5720 Oid pg_type_array_oid;
5721 Oid pg_type_multirange_oid;
5722 Oid pg_type_multirange_array_oid;
5723 TypeInfo *tinfo;
5724
5725 appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5726 appendPQExpBuffer(upgrade_buffer,
5727 "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5728 pg_type_oid);
5729
5730 tinfo = findTypeByOid(pg_type_oid);
5731 if (tinfo)
5732 pg_type_array_oid = tinfo->typarray;
5733 else
5734 pg_type_array_oid = InvalidOid;
5735
5736 if (!OidIsValid(pg_type_array_oid) && force_array_type)
5737 pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5738
5739 if (OidIsValid(pg_type_array_oid))
5740 {
5741 appendPQExpBufferStr(upgrade_buffer,
5742 "\n-- For binary upgrade, must preserve pg_type array oid\n");
5743 appendPQExpBuffer(upgrade_buffer,
5744 "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5745 pg_type_array_oid);
5746 }
5747
5748 /*
5749 * Pre-set the multirange type oid and its own array type oid.
5750 */
5751 if (include_multirange_type)
5752 {
5753 if (fout->remoteVersion >= 140000)
5754 {
5755 printfPQExpBuffer(upgrade_query,
5756 "SELECT t.oid, t.typarray "
5757 "FROM pg_catalog.pg_type t "
5758 "JOIN pg_catalog.pg_range r "
5759 "ON t.oid = r.rngmultitypid "
5760 "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5761 pg_type_oid);
5762
5763 res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5764
5765 pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5766 pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5767
5768 PQclear(res);
5769 }
5770 else
5771 {
5772 pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5773 pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5774 }
5775
5776 appendPQExpBufferStr(upgrade_buffer,
5777 "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5778 appendPQExpBuffer(upgrade_buffer,
5779 "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5780 pg_type_multirange_oid);
5781 appendPQExpBufferStr(upgrade_buffer,
5782 "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5783 appendPQExpBuffer(upgrade_buffer,
5784 "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5785 pg_type_multirange_array_oid);
5786 }
5787
5788 destroyPQExpBuffer(upgrade_query);
5789}
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:899
static const gbtree_vinfo tinfo
Definition: btree_bit.c:109
PGresult * ExecuteSqlQueryForSingleRow(Archive *fout, const char *query)
Definition: pg_backup_db.c:244
static Oid get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
Definition: pg_dump.c:5681
#define InvalidOid
Definition: postgres_ext.h:37
#define atooid(x)
Definition: postgres_ext.h:43
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
int remoteVersion
Definition: pg_backup.h:233

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

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

◆ BinaryUpgradeClassOidItemCmp()

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

Definition at line 5807 of file pg_dump.c.

5808{
5811
5812 return pg_cmp_u32(v1.oid, v2.oid);
5813}
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:719

References BinaryUpgradeClassOidItem::oid, and pg_cmp_u32().

Referenced by binary_upgrade_set_pg_class_oids().

◆ BuildArchiveDependencies()

static void BuildArchiveDependencies ( Archive fout)
static

Definition at line 20263 of file pg_dump.c.

20264{
20265 ArchiveHandle *AH = (ArchiveHandle *) fout;
20266 TocEntry *te;
20267
20268 /* Scan all TOC entries in the archive */
20269 for (te = AH->toc->next; te != AH->toc; te = te->next)
20270 {
20271 DumpableObject *dobj;
20272 DumpId *dependencies;
20273 int nDeps;
20274 int allocDeps;
20275
20276 /* No need to process entries that will not be dumped */
20277 if (te->reqs == 0)
20278 continue;
20279 /* Ignore entries that already have "special" dependencies */
20280 if (te->nDeps > 0)
20281 continue;
20282 /* Otherwise, look up the item's original DumpableObject, if any */
20283 dobj = findObjectByDumpId(te->dumpId);
20284 if (dobj == NULL)
20285 continue;
20286 /* No work if it has no dependencies */
20287 if (dobj->nDeps <= 0)
20288 continue;
20289 /* Set up work array */
20290 allocDeps = 64;
20291 dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
20292 nDeps = 0;
20293 /* Recursively find all dumpable dependencies */
20294 findDumpableDependencies(AH, dobj,
20295 &dependencies, &nDeps, &allocDeps);
20296 /* And save 'em ... */
20297 if (nDeps > 0)
20298 {
20299 dependencies = (DumpId *) pg_realloc(dependencies,
20300 nDeps * sizeof(DumpId));
20301 te->dependencies = dependencies;
20302 te->nDeps = nDeps;
20303 }
20304 else
20305 free(dependencies);
20306 }
20307}
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define free(a)
Definition: header.h:65
int DumpId
Definition: pg_backup.h:284
static void findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
Definition: pg_dump.c:20311
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 3126 of file pg_dump.c.

3127{
3128 PQExpBuffer query;
3129 PGresult *res;
3130 int ntups,
3131 i;
3132 int i_classid,
3133 i_objid,
3134 i_refobjid;
3135
3136 /* No Mat Views before 9.3. */
3137 if (fout->remoteVersion < 90300)
3138 return;
3139
3140 query = createPQExpBuffer();
3141
3142 appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
3143 "( "
3144 "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
3145 "FROM pg_depend d1 "
3146 "JOIN pg_class c1 ON c1.oid = d1.objid "
3147 "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
3148 " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
3149 "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
3150 "AND d2.objid = r1.oid "
3151 "AND d2.refobjid <> d1.objid "
3152 "JOIN pg_class c2 ON c2.oid = d2.refobjid "
3153 "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
3154 CppAsString2(RELKIND_VIEW) ") "
3155 "WHERE d1.classid = 'pg_class'::regclass "
3156 "UNION "
3157 "SELECT w.objid, d3.refobjid, c3.relkind "
3158 "FROM w "
3159 "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
3160 "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
3161 "AND d3.objid = r3.oid "
3162 "AND d3.refobjid <> w.refobjid "
3163 "JOIN pg_class c3 ON c3.oid = d3.refobjid "
3164 "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
3165 CppAsString2(RELKIND_VIEW) ") "
3166 ") "
3167 "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
3168 "FROM w "
3169 "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
3170
3171 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3172
3173 ntups = PQntuples(res);
3174
3175 i_classid = PQfnumber(res, "classid");
3176 i_objid = PQfnumber(res, "objid");
3177 i_refobjid = PQfnumber(res, "refobjid");
3178
3179 for (i = 0; i < ntups; i++)
3180 {
3181 CatalogId objId;
3182 CatalogId refobjId;
3183 DumpableObject *dobj;
3184 DumpableObject *refdobj;
3185 TableInfo *tbinfo;
3186 TableInfo *reftbinfo;
3187
3188 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
3189 objId.oid = atooid(PQgetvalue(res, i, i_objid));
3190 refobjId.tableoid = objId.tableoid;
3191 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
3192
3193 dobj = findObjectByCatalogId(objId);
3194 if (dobj == NULL)
3195 continue;
3196
3197 Assert(dobj->objType == DO_TABLE);
3198 tbinfo = (TableInfo *) dobj;
3199 Assert(tbinfo->relkind == RELKIND_MATVIEW);
3200 dobj = (DumpableObject *) tbinfo->dataObj;
3201 if (dobj == NULL)
3202 continue;
3204
3205 refdobj = findObjectByCatalogId(refobjId);
3206 if (refdobj == NULL)
3207 continue;
3208
3209 Assert(refdobj->objType == DO_TABLE);
3210 reftbinfo = (TableInfo *) refdobj;
3211 Assert(reftbinfo->relkind == RELKIND_MATVIEW);
3212 refdobj = (DumpableObject *) reftbinfo->dataObj;
3213 if (refdobj == NULL)
3214 continue;
3215 Assert(refdobj->objType == DO_REFRESH_MATVIEW);
3216
3217 addObjectDependency(dobj, refdobj->dumpId);
3218
3219 if (!reftbinfo->relispopulated)
3220 tbinfo->relispopulated = false;
3221 }
3222
3223 PQclear(res);
3224
3225 destroyPQExpBuffer(query);
3226}
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:778
#define CppAsString2(x)
Definition: c.h:434
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
Oid tableoid
Definition: pg_backup.h:280
bool relispopulated
Definition: pg_dump.h:312
struct _tableDataInfo * dataObj
Definition: pg_dump.h:390
char relkind
Definition: pg_dump.h:310

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, and CatalogId::tableoid.

Referenced by main().

◆ checkExtensionMembership()

static bool checkExtensionMembership ( DumpableObject dobj,
Archive fout 
)
static

Definition at line 1948 of file pg_dump.c.

1949{
1951
1952 if (ext == NULL)
1953 return false;
1954
1955 dobj->ext_member = true;
1956
1957 /* Record dependency so that getDependencies needn't deal with that */
1958 addObjectDependency(dobj, ext->dobj.dumpId);
1959
1960 /*
1961 * In 9.6 and above, mark the member object to have any non-initial ACLs
1962 * dumped. (Any initial ACLs will be removed later, using data from
1963 * pg_init_privs, so that we'll dump only the delta from the extension's
1964 * initial setup.)
1965 *
1966 * Prior to 9.6, we do not include any extension member components.
1967 *
1968 * In binary upgrades, we still dump all components of the members
1969 * individually, since the idea is to exactly reproduce the database
1970 * contents rather than replace the extension contents with something
1971 * different.
1972 *
1973 * Note: it might be interesting someday to implement storage and delta
1974 * dumping of extension members' RLS policies and/or security labels.
1975 * However there is a pitfall for RLS policies: trying to dump them
1976 * requires getting a lock on their tables, and the calling user might not
1977 * have privileges for that. We need no lock to examine a table's ACLs,
1978 * so the current feature doesn't have a problem of that sort.
1979 */
1980 if (fout->dopt->binary_upgrade)
1981 dobj->dump = ext->dobj.dump;
1982 else
1983 {
1984 if (fout->remoteVersion < 90600)
1985 dobj->dump = DUMP_COMPONENT_NONE;
1986 else
1987 dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
1988 }
1989
1990 return true;
1991}
ExtensionInfo * findOwningExtension(CatalogId catalogId)
Definition: common.c:1087
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:113
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:108
DumpOptions * dopt
Definition: pg_backup.h:228
int binary_upgrade
Definition: pg_backup.h:174
DumpComponents dump
Definition: pg_dump.h:153
DumpComponents dump_contains
Definition: pg_dump.h:155
DumpableObject dobj
Definition: pg_dump.h:195

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

5824{
5825 PGresult *res;
5826 const char *query;
5827
5828 query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5829 "ct.relfilenode, i.indexrelid, cti.relfilenode "
5830 "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5831 "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5832 "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5833 "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5834 "ORDER BY c.oid;";
5835
5836 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5837
5841
5842 for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5843 {
5851 }
5852
5853 PQclear(res);
5854}

References atooid, binaryUpgradeClassOids, ExecuteSqlQuery(), i, nbinaryUpgradeClassOids, BinaryUpgradeClassOidItem::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear, PQgetvalue, PQntuples, BinaryUpgradeClassOidItem::relfilenumber, BinaryUpgradeClassOidItem::relkind, 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 11576 of file pg_dump.c.

11577{
11578 PGresult *res;
11579 PQExpBuffer query;
11580 int i_description;
11581 int i_classoid;
11582 int i_objoid;
11583 int i_objsubid;
11584 int ntups;
11585 int i;
11586 DumpableObject *dobj;
11587
11588 query = createPQExpBuffer();
11589
11590 appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
11591 "FROM pg_catalog.pg_description "
11592 "ORDER BY classoid, objoid, objsubid");
11593
11594 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11595
11596 /* Construct lookup table containing OIDs in numeric form */
11597
11598 i_description = PQfnumber(res, "description");
11599 i_classoid = PQfnumber(res, "classoid");
11600 i_objoid = PQfnumber(res, "objoid");
11601 i_objsubid = PQfnumber(res, "objsubid");
11602
11603 ntups = PQntuples(res);
11604
11605 comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
11606 ncomments = 0;
11607 dobj = NULL;
11608
11609 for (i = 0; i < ntups; i++)
11610 {
11611 CatalogId objId;
11612 int subid;
11613
11614 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
11615 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
11616 subid = atoi(PQgetvalue(res, i, i_objsubid));
11617
11618 /* We needn't remember comments that don't match any dumpable object */
11619 if (dobj == NULL ||
11620 dobj->catId.tableoid != objId.tableoid ||
11621 dobj->catId.oid != objId.oid)
11622 dobj = findObjectByCatalogId(objId);
11623 if (dobj == NULL)
11624 continue;
11625
11626 /*
11627 * Comments on columns of composite types are linked to the type's
11628 * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
11629 * in the type's own DumpableObject.
11630 */
11631 if (subid != 0 && dobj->objType == DO_TABLE &&
11632 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
11633 {
11634 TypeInfo *cTypeInfo;
11635
11636 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
11637 if (cTypeInfo)
11639 }
11640 else
11641 dobj->components |= DUMP_COMPONENT_COMMENT;
11642
11643 comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
11645 comments[ncomments].objoid = objId.oid;
11646 comments[ncomments].objsubid = subid;
11647 ncomments++;
11648 }
11649
11650 PQclear(res);
11651 destroyPQExpBuffer(query);
11652}
static int ncomments
Definition: pg_dump.c:201
static CommentItem * comments
Definition: pg_dump.c:200
#define DUMP_COMPONENT_COMMENT
Definition: pg_dump.h:111
Oid classoid
Definition: pg_dump.c:85
Oid objoid
Definition: pg_dump.c:86
int objsubid
Definition: pg_dump.c:87
const char * descr
Definition: pg_dump.c:84
DumpComponents components
Definition: pg_dump.h:156
DumpableObject dobj
Definition: pg_dump.h:205

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, and CatalogId::tableoid.

Referenced by main().

◆ collectRoleNames()

static void collectRoleNames ( Archive fout)
static

Definition at line 10716 of file pg_dump.c.

10717{
10718 PGresult *res;
10719 const char *query;
10720 int i;
10721
10722 query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
10723
10724 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
10725
10726 nrolenames = PQntuples(res);
10727
10729
10730 for (i = 0; i < nrolenames; i++)
10731 {
10732 rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
10734 }
10735
10736 PQclear(res);
10737}
static RoleNameItem * rolenames
Definition: pg_dump.c:196
static int nrolenames
Definition: pg_dump.c:197
const char * rolename
Definition: pg_dump.c:79
Oid roleoid
Definition: pg_dump.c:78

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

Referenced by main().

◆ collectSecLabels()

static void collectSecLabels ( Archive fout)
static

Definition at line 16777 of file pg_dump.c.

16778{
16779 PGresult *res;
16780 PQExpBuffer query;
16781 int i_label;
16782 int i_provider;
16783 int i_classoid;
16784 int i_objoid;
16785 int i_objsubid;
16786 int ntups;
16787 int i;
16788 DumpableObject *dobj;
16789
16790 query = createPQExpBuffer();
16791
16793 "SELECT label, provider, classoid, objoid, objsubid "
16794 "FROM pg_catalog.pg_seclabels "
16795 "ORDER BY classoid, objoid, objsubid");
16796
16797 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16798
16799 /* Construct lookup table containing OIDs in numeric form */
16800 i_label = PQfnumber(res, "label");
16801 i_provider = PQfnumber(res, "provider");
16802 i_classoid = PQfnumber(res, "classoid");
16803 i_objoid = PQfnumber(res, "objoid");
16804 i_objsubid = PQfnumber(res, "objsubid");
16805
16806 ntups = PQntuples(res);
16807
16808 seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
16809 nseclabels = 0;
16810 dobj = NULL;
16811
16812 for (i = 0; i < ntups; i++)
16813 {
16814 CatalogId objId;
16815 int subid;
16816
16817 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
16818 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
16819 subid = atoi(PQgetvalue(res, i, i_objsubid));
16820
16821 /* We needn't remember labels that don't match any dumpable object */
16822 if (dobj == NULL ||
16823 dobj->catId.tableoid != objId.tableoid ||
16824 dobj->catId.oid != objId.oid)
16825 dobj = findObjectByCatalogId(objId);
16826 if (dobj == NULL)
16827 continue;
16828
16829 /*
16830 * Labels on columns of composite types are linked to the type's
16831 * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
16832 * in the type's own DumpableObject.
16833 */
16834 if (subid != 0 && dobj->objType == DO_TABLE &&
16835 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
16836 {
16837 TypeInfo *cTypeInfo;
16838
16839 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
16840 if (cTypeInfo)
16842 }
16843 else
16844 dobj->components |= DUMP_COMPONENT_SECLABEL;
16845
16846 seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
16847 seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
16849 seclabels[nseclabels].objoid = objId.oid;
16850 seclabels[nseclabels].objsubid = subid;
16851 nseclabels++;
16852 }
16853
16854 PQclear(res);
16855 destroyPQExpBuffer(query);
16856}
static int nseclabels
Definition: pg_dump.c:205
static SecLabelItem * seclabels
Definition: pg_dump.c:204
#define DUMP_COMPONENT_SECLABEL
Definition: pg_dump.h:112
const char * provider
Definition: pg_dump.c:92
Oid classoid
Definition: pg_dump.c:94
int objsubid
Definition: pg_dump.c:96
const char * label
Definition: pg_dump.c:93
Oid objoid
Definition: pg_dump.c:95

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, seclabels, and CatalogId::tableoid.

Referenced by main().

◆ collectSequences()

static void collectSequences ( Archive fout)
static

Definition at line 18911 of file pg_dump.c.

18912{
18913 PGresult *res;
18914 const char *query;
18915
18916 /*
18917 * Before Postgres 10, sequence metadata is in the sequence itself. With
18918 * some extra effort, we might be able to use the sorted table for those
18919 * versions, but for now it seems unlikely to be worth it.
18920 *
18921 * Since version 18, we can gather the sequence data in this query with
18922 * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
18923 */
18924 if (fout->remoteVersion < 100000)
18925 return;
18926 else if (fout->remoteVersion < 180000 ||
18927 (!fout->dopt->dumpData && !fout->dopt->sequence_data))
18928 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18929 "seqstart, seqincrement, "
18930 "seqmax, seqmin, "
18931 "seqcache, seqcycle, "
18932 "NULL, 'f' "
18933 "FROM pg_catalog.pg_sequence "
18934 "ORDER BY seqrelid";
18935 else
18936 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18937 "seqstart, seqincrement, "
18938 "seqmax, seqmin, "
18939 "seqcache, seqcycle, "
18940 "last_value, is_called "
18941 "FROM pg_catalog.pg_sequence, "
18942 "pg_get_sequence_data(seqrelid) "
18943 "ORDER BY seqrelid;";
18944
18945 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
18946
18947 nsequences = PQntuples(res);
18949
18950 for (int i = 0; i < nsequences; i++)
18951 {
18952 sequences[i].oid = atooid(PQgetvalue(res, i, 0));
18954 sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
18955 sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
18956 sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
18957 sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
18958 sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
18959 sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
18960 sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
18961 sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
18962 }
18963
18964 PQclear(res);
18965}
static int nsequences
Definition: pg_dump.c:213
static SeqType parse_sequence_type(const char *name)
Definition: pg_dump.c:18880
static SequenceItem * sequences
Definition: pg_dump.c:212
int64 minv
Definition: pg_dump.c:133
int64 cache
Definition: pg_dump.c:137
int64 startv
Definition: pg_dump.c:135
int64 maxv
Definition: pg_dump.c:134
bool is_called
Definition: pg_dump.c:139
int64 incby
Definition: pg_dump.c:136
int64 last_value
Definition: pg_dump.c:138
SeqType seqtype
Definition: pg_dump.c:131
bool cycled
Definition: pg_dump.c:132
int sequence_data
Definition: pg_backup.h:211
bool dumpData
Definition: pg_backup.h:216

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

Referenced by main().

◆ convertRegProcReference()

static char * convertRegProcReference ( const char *  proc)
static

Definition at line 14324 of file pg_dump.c.

14325{
14326 char *name;
14327 char *paren;
14328 bool inquote;
14329
14330 /* In all cases "-" means a null reference */
14331 if (strcmp(proc, "-") == 0)
14332 return NULL;
14333
14334 name = pg_strdup(proc);
14335 /* find non-double-quoted left paren */
14336 inquote = false;
14337 for (paren = name; *paren; paren++)
14338 {
14339 if (*paren == '(' && !inquote)
14340 {
14341 *paren = '\0';
14342 break;
14343 }
14344 if (*paren == '"')
14345 inquote = !inquote;
14346 }
14347 return name;
14348}
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 14395 of file pg_dump.c.

14396{
14397 char *result;
14398 char query[128];
14399 PGresult *res;
14400
14401 snprintf(query, sizeof(query),
14402 "SELECT '%u'::pg_catalog.regproc", funcOid);
14403 res = ExecuteSqlQueryForSingleRow(fout, query);
14404
14405 result = pg_strdup(PQgetvalue(res, 0, 0));
14406
14407 PQclear(res);
14408
14409 return result;
14410}
#define snprintf
Definition: port.h:260

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

Referenced by dumpTSParser(), and dumpTSTemplate().

◆ createBoundaryObjects()

static DumpableObject * createBoundaryObjects ( void  )
static

Definition at line 20113 of file pg_dump.c.

20114{
20115 DumpableObject *dobjs;
20116
20117 dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
20118
20119 dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
20120 dobjs[0].catId = nilCatalogId;
20121 AssignDumpId(dobjs + 0);
20122 dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
20123
20124 dobjs[1].objType = DO_POST_DATA_BOUNDARY;
20125 dobjs[1].catId = nilCatalogId;
20126 AssignDumpId(dobjs + 1);
20127 dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
20128
20129 return dobjs;
20130}
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:657
static const CatalogId nilCatalogId
Definition: pg_dump.c:189

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

17053{
17054 PQExpBuffer result = createPQExpBuffer();
17055 int j;
17056
17057 appendPQExpBufferStr(result, "SELECT");
17058
17059 for (j = 0; j < tbinfo->numatts; j++)
17060 {
17061 if (j > 0)
17062 appendPQExpBufferChar(result, ',');
17063 appendPQExpBufferStr(result, "\n ");
17064
17065 appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
17066
17067 /*
17068 * Must add collation if not default for the type, because CREATE OR
17069 * REPLACE VIEW won't change it
17070 */
17071 if (OidIsValid(tbinfo->attcollation[j]))
17072 {
17073 CollInfo *coll;
17074
17075 coll = findCollationByOid(tbinfo->attcollation[j]);
17076 if (coll)
17077 appendPQExpBuffer(result, " COLLATE %s",
17078 fmtQualifiedDumpable(coll));
17079 }
17080
17081 appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
17082 }
17083
17084 return result;
17085}
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:972
int j
Definition: isn.c:78
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:240
int numatts
Definition: pg_dump.h:354
Oid * attcollation
Definition: pg_dump.h:367
char ** atttypnames
Definition: pg_dump.h:356
char ** attnames
Definition: pg_dump.h:355

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

17004{
17006 PQExpBuffer result = createPQExpBuffer();
17007 PGresult *res;
17008 int len;
17009
17010 /* Fetch the view definition */
17011 appendPQExpBuffer(query,
17012 "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
17013 tbinfo->dobj.catId.oid);
17014
17015 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17016
17017 if (PQntuples(res) != 1)
17018 {
17019 if (PQntuples(res) < 1)
17020 pg_fatal("query to obtain definition of view \"%s\" returned no data",
17021 tbinfo->dobj.name);
17022 else
17023 pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
17024 tbinfo->dobj.name);
17025 }
17026
17027 len = PQgetlength(res, 0, 0);
17028
17029 if (len == 0)
17030 pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
17031 tbinfo->dobj.name);
17032
17033 /* Strip off the trailing semicolon so that other things may follow. */
17034 Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
17035 appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
17036
17037 PQclear(res);
17038 destroyPQExpBuffer(query);
17039
17040 return result;
17041}
#define PQgetlength
Definition: libpq-be-fe.h:254
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:307

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, and PQntuples.

Referenced by dumpRule(), and dumpTableSchema().

◆ determineNotNullFlags()

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

Definition at line 10011 of file pg_dump.c.

10019{
10020 DumpOptions *dopt = fout->dopt;
10021
10022 /*
10023 * If this not-null constraint is not valid, list its OID in
10024 * invalidnotnulloids and do nothing further. It'll be processed
10025 * elsewhere later.
10026 *
10027 * Because invalid not-null constraints are rare, we don't want to malloc
10028 * invalidnotnulloids until we're sure we're going it need it, which
10029 * happens here.
10030 */
10031 if (!PQgetisnull(res, r, i_notnull_invalidoid))
10032 {
10033 char *constroid = PQgetvalue(res, r, i_notnull_invalidoid);
10034
10035 if (*invalidnotnulloids == NULL)
10036 {
10037 *invalidnotnulloids = createPQExpBuffer();
10038 appendPQExpBufferChar(*invalidnotnulloids, '{');
10039 appendPQExpBufferStr(*invalidnotnulloids, constroid);
10040 }
10041 else
10042 appendPQExpBuffer(*invalidnotnulloids, ",%s", constroid);
10043
10044 /*
10045 * Track when a parent constraint is invalid for the cases where a
10046 * child constraint has been validated independenly.
10047 */
10048 tbinfo->notnull_invalid[j] = true;
10049
10050 /* nothing else to do */
10051 tbinfo->notnull_constrs[j] = NULL;
10052 return;
10053 }
10054
10055 /*
10056 * notnull_noinh is straight from the query result. notnull_islocal also,
10057 * though flagInhAttrs may change that one later.
10058 */
10059 tbinfo->notnull_noinh[j] = PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
10060 tbinfo->notnull_islocal[j] = PQgetvalue(res, r, i_notnull_islocal)[0] == 't';
10061 tbinfo->notnull_invalid[j] = false;
10062
10063 /*
10064 * Determine a constraint name to use. If the column is not marked not-
10065 * null, we set NULL which cues ... to do nothing. An empty string says
10066 * to print an unnamed NOT NULL, and anything else is a constraint name to
10067 * use.
10068 */
10069 if (fout->remoteVersion < 180000)
10070 {
10071 /*
10072 * < 18 doesn't have not-null names, so an unnamed constraint is
10073 * sufficient.
10074 */
10075 if (PQgetisnull(res, r, i_notnull_name))
10076 tbinfo->notnull_constrs[j] = NULL;
10077 else
10078 tbinfo->notnull_constrs[j] = "";
10079 }
10080 else
10081 {
10082 if (PQgetisnull(res, r, i_notnull_name))
10083 tbinfo->notnull_constrs[j] = NULL;
10084 else
10085 {
10086 /*
10087 * In binary upgrade of inheritance child tables, must have a
10088 * constraint name that we can UPDATE later; same if there's a
10089 * comment on the constraint.
10090 */
10091 if ((dopt->binary_upgrade &&
10092 !tbinfo->ispartition &&
10093 !tbinfo->notnull_islocal) ||
10094 !PQgetisnull(res, r, i_notnull_comment))
10095 {
10096 tbinfo->notnull_constrs[j] =
10097 pstrdup(PQgetvalue(res, r, i_notnull_name));
10098 }
10099 else
10100 {
10101 char *default_name;
10102
10103 /* XXX should match ChooseConstraintName better */
10104 default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
10105 tbinfo->attnames[j]);
10106 if (strcmp(default_name,
10107 PQgetvalue(res, r, i_notnull_name)) == 0)
10108 tbinfo->notnull_constrs[j] = "";
10109 else
10110 {
10111 tbinfo->notnull_constrs[j] =
10112 pstrdup(PQgetvalue(res, r, i_notnull_name));
10113 }
10114 free(default_name);
10115 }
10116 }
10117 }
10118}
#define PQgetisnull
Definition: libpq-be-fe.h:255
char * pstrdup(const char *in)
Definition: mcxt.c:1759
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
bool * notnull_invalid
Definition: pg_dump.h:376
char ** notnull_constrs
Definition: pg_dump.h:371
bool ispartition
Definition: pg_dump.h:344
bool * notnull_islocal
Definition: pg_dump.h:378
bool * notnull_noinh
Definition: pg_dump.h:377

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), _tableInfo::attnames, _dumpOptions::binary_upgrade, createPQExpBuffer(), _tableInfo::dobj, Archive::dopt, free, _tableInfo::ispartition, j, _dumpableObject::name, _tableInfo::notnull_constrs, _tableInfo::notnull_invalid, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, PQgetisnull, PQgetvalue, psprintf(), pstrdup(), and Archive::remoteVersion.

Referenced by getTableAttrs().

◆ dumpAccessMethod()

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

Definition at line 14417 of file pg_dump.c.

14418{
14419 DumpOptions *dopt = fout->dopt;
14420 PQExpBuffer q;
14421 PQExpBuffer delq;
14422 char *qamname;
14423
14424 /* Do nothing if not dumping schema */
14425 if (!dopt->dumpSchema)
14426 return;
14427
14428 q = createPQExpBuffer();
14429 delq = createPQExpBuffer();
14430
14431 qamname = pg_strdup(fmtId(aminfo->dobj.name));
14432
14433 appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
14434
14435 switch (aminfo->amtype)
14436 {
14437 case AMTYPE_INDEX:
14438 appendPQExpBufferStr(q, "TYPE INDEX ");
14439 break;
14440 case AMTYPE_TABLE:
14441 appendPQExpBufferStr(q, "TYPE TABLE ");
14442 break;
14443 default:
14444 pg_log_warning("invalid type \"%c\" of access method \"%s\"",
14445 aminfo->amtype, qamname);
14447 destroyPQExpBuffer(delq);
14448 free(qamname);
14449 return;
14450 }
14451
14452 appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
14453
14454 appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
14455 qamname);
14456
14457 if (dopt->binary_upgrade)
14459 "ACCESS METHOD", qamname, NULL);
14460
14461 if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14462 ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
14463 ARCHIVE_OPTS(.tag = aminfo->dobj.name,
14464 .description = "ACCESS METHOD",
14465 .section = SECTION_PRE_DATA,
14466 .createStmt = q->data,
14467 .dropStmt = delq->data));
14468
14469 /* Dump Access Method Comments */
14470 if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14471 dumpComment(fout, "ACCESS METHOD", qamname,
14472 NULL, "",
14473 aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
14474
14476 destroyPQExpBuffer(delq);
14477 free(qamname);
14478}
@ 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:10980
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:5947
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:109
char * amhandler
Definition: pg_dump.h:272
DumpableObject dobj
Definition: pg_dump.h:270
bool dumpSchema
Definition: pg_backup.h:215

References _accessMethodInfo::amhandler, _accessMethodInfo::amtype, appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _accessMethodInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 16408 of file pg_dump.c.

16412{
16413 DumpId aclDumpId = InvalidDumpId;
16414 DumpOptions *dopt = fout->dopt;
16415 const char *acls = dacl->acl;
16416 const char *acldefault = dacl->acldefault;
16417 char privtype = dacl->privtype;
16418 const char *initprivs = dacl->initprivs;
16419 const char *baseacls;
16420 PQExpBuffer sql;
16421
16422 /* Do nothing if ACL dump is not enabled */
16423 if (dopt->aclsSkip)
16424 return InvalidDumpId;
16425
16426 /* --data-only skips ACLs *except* large object ACLs */
16427 if (!dopt->dumpSchema && strcmp(type, "LARGE OBJECT") != 0)
16428 return InvalidDumpId;
16429
16430 sql = createPQExpBuffer();
16431
16432 /*
16433 * In binary upgrade mode, we don't run an extension's script but instead
16434 * dump out the objects independently and then recreate them. To preserve
16435 * any initial privileges which were set on extension objects, we need to
16436 * compute the set of GRANT and REVOKE commands necessary to get from the
16437 * default privileges of an object to its initial privileges as recorded
16438 * in pg_init_privs.
16439 *
16440 * At restore time, we apply these commands after having called
16441 * binary_upgrade_set_record_init_privs(true). That tells the backend to
16442 * copy the results into pg_init_privs. This is how we preserve the
16443 * contents of that catalog across binary upgrades.
16444 */
16445 if (dopt->binary_upgrade && privtype == 'e' &&
16446 initprivs && *initprivs != '\0')
16447 {
16448 appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
16449 if (!buildACLCommands(name, subname, nspname, type,
16450 initprivs, acldefault, owner,
16451 "", fout->remoteVersion, sql))
16452 pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
16453 initprivs, acldefault, name, type);
16454 appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
16455 }
16456
16457 /*
16458 * Now figure the GRANT and REVOKE commands needed to get to the object's
16459 * actual current ACL, starting from the initprivs if given, else from the
16460 * object-type-specific default. Also, while buildACLCommands will assume
16461 * that a NULL/empty acls string means it needn't do anything, what that
16462 * actually represents is the object-type-specific default; so we need to
16463 * substitute the acldefault string to get the right results in that case.
16464 */
16465 if (initprivs && *initprivs != '\0')
16466 {
16467 baseacls = initprivs;
16468 if (acls == NULL || *acls == '\0')
16469 acls = acldefault;
16470 }
16471 else
16472 baseacls = acldefault;
16473
16474 if (!buildACLCommands(name, subname, nspname, type,
16475 acls, baseacls, owner,
16476 "", fout->remoteVersion, sql))
16477 pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
16478 acls, baseacls, name, type);
16479
16480 if (sql->len > 0)
16481 {
16482 PQExpBuffer tagbuf = createPQExpBuffer();
16483 DumpId aclDeps[2];
16484 int nDeps = 0;
16485
16486 if (tag)
16487 appendPQExpBufferStr(tagbuf, tag);
16488 else if (subname)
16489 appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
16490 else
16491 appendPQExpBuffer(tagbuf, "%s %s", type, name);
16492
16493 aclDeps[nDeps++] = objDumpId;
16494 if (altDumpId != InvalidDumpId)
16495 aclDeps[nDeps++] = altDumpId;
16496
16497 aclDumpId = createDumpId();
16498
16499 ArchiveEntry(fout, nilCatalogId, aclDumpId,
16500 ARCHIVE_OPTS(.tag = tagbuf->data,
16501 .namespace = nspname,
16502 .owner = owner,
16503 .description = "ACL",
16504 .section = SECTION_NONE,
16505 .createStmt = sql->data,
16506 .deps = aclDeps,
16507 .nDeps = nDeps));
16508
16509 destroyPQExpBuffer(tagbuf);
16510 }
16511
16512 destroyPQExpBuffer(sql);
16513
16514 return aclDumpId;
16515}
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:803
DumpId createDumpId(void)
Definition: common.c:745
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:104
@ SECTION_NONE
Definition: pg_backup.h:57
#define InvalidDumpId
Definition: pg_backup.h:286
NameData subname
bool aclsSkip
Definition: pg_backup.h:178
char privtype
Definition: pg_dump.h:173
char * acldefault
Definition: pg_dump.h:171
char * acl
Definition: pg_dump.h:170
char * initprivs
Definition: pg_dump.h:174
const char * type

References _dumpableAcl::acl, acldefault(), _dumpableAcl::acldefault, _dumpOptions::aclsSkip, appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, buildACLCommands(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::dopt, _dumpOptions::dumpSchema, _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 15370 of file pg_dump.c.

15371{
15372 DumpOptions *dopt = fout->dopt;
15373 PQExpBuffer query;
15374 PQExpBuffer q;
15375 PQExpBuffer delq;
15376 PQExpBuffer details;
15377 char *aggsig; /* identity signature */
15378 char *aggfullsig = NULL; /* full signature */
15379 char *aggsig_tag;
15380 PGresult *res;
15381 int i_agginitval;
15382 int i_aggminitval;
15383 const char *aggtransfn;
15384 const char *aggfinalfn;
15385 const char *aggcombinefn;
15386 const char *aggserialfn;
15387 const char *aggdeserialfn;
15388 const char *aggmtransfn;
15389 const char *aggminvtransfn;
15390 const char *aggmfinalfn;
15391 bool aggfinalextra;
15392 bool aggmfinalextra;
15393 char aggfinalmodify;
15394 char aggmfinalmodify;
15395 const char *aggsortop;
15396 char *aggsortconvop;
15397 char aggkind;
15398 const char *aggtranstype;
15399 const char *aggtransspace;
15400 const char *aggmtranstype;
15401 const char *aggmtransspace;
15402 const char *agginitval;
15403 const char *aggminitval;
15404 const char *proparallel;
15405 char defaultfinalmodify;
15406
15407 /* Do nothing if not dumping schema */
15408 if (!dopt->dumpSchema)
15409 return;
15410
15411 query = createPQExpBuffer();
15412 q = createPQExpBuffer();
15413 delq = createPQExpBuffer();
15414 details = createPQExpBuffer();
15415
15416 if (!fout->is_prepared[PREPQUERY_DUMPAGG])
15417 {
15418 /* Set up query for aggregate-specific details */
15420 "PREPARE dumpAgg(pg_catalog.oid) AS\n");
15421
15423 "SELECT "
15424 "aggtransfn,\n"
15425 "aggfinalfn,\n"
15426 "aggtranstype::pg_catalog.regtype,\n"
15427 "agginitval,\n"
15428 "aggsortop,\n"
15429 "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
15430 "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
15431
15432 if (fout->remoteVersion >= 90400)
15434 "aggkind,\n"
15435 "aggmtransfn,\n"
15436 "aggminvtransfn,\n"
15437 "aggmfinalfn,\n"
15438 "aggmtranstype::pg_catalog.regtype,\n"
15439 "aggfinalextra,\n"
15440 "aggmfinalextra,\n"
15441 "aggtransspace,\n"
15442 "aggmtransspace,\n"
15443 "aggminitval,\n");
15444 else
15446 "'n' AS aggkind,\n"
15447 "'-' AS aggmtransfn,\n"
15448 "'-' AS aggminvtransfn,\n"
15449 "'-' AS aggmfinalfn,\n"
15450 "0 AS aggmtranstype,\n"
15451 "false AS aggfinalextra,\n"
15452 "false AS aggmfinalextra,\n"
15453 "0 AS aggtransspace,\n"
15454 "0 AS aggmtransspace,\n"
15455 "NULL AS aggminitval,\n");
15456
15457 if (fout->remoteVersion >= 90600)
15459 "aggcombinefn,\n"
15460 "aggserialfn,\n"
15461 "aggdeserialfn,\n"
15462 "proparallel,\n");
15463 else
15465 "'-' AS aggcombinefn,\n"
15466 "'-' AS aggserialfn,\n"
15467 "'-' AS aggdeserialfn,\n"
15468 "'u' AS proparallel,\n");
15469
15470 if (fout->remoteVersion >= 110000)
15472 "aggfinalmodify,\n"
15473 "aggmfinalmodify\n");
15474 else
15476 "'0' AS aggfinalmodify,\n"
15477 "'0' AS aggmfinalmodify\n");
15478
15480 "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
15481 "WHERE a.aggfnoid = p.oid "
15482 "AND p.oid = $1");
15483
15484 ExecuteSqlStatement(fout, query->data);
15485
15486 fout->is_prepared[PREPQUERY_DUMPAGG] = true;
15487 }
15488
15489 printfPQExpBuffer(query,
15490 "EXECUTE dumpAgg('%u')",
15491 agginfo->aggfn.dobj.catId.oid);
15492
15493 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15494
15495 i_agginitval = PQfnumber(res, "agginitval");
15496 i_aggminitval = PQfnumber(res, "aggminitval");
15497
15498 aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
15499 aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
15500 aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
15501 aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
15502 aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
15503 aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
15504 aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
15505 aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
15506 aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
15507 aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
15508 aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
15509 aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
15510 aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
15511 aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
15512 aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
15513 aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
15514 aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
15515 aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
15516 agginitval = PQgetvalue(res, 0, i_agginitval);
15517 aggminitval = PQgetvalue(res, 0, i_aggminitval);
15518 proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
15519
15520 {
15521 char *funcargs;
15522 char *funciargs;
15523
15524 funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
15525 funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
15526 aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
15527 aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
15528 }
15529
15530 aggsig_tag = format_aggregate_signature(agginfo, fout, false);
15531
15532 /* identify default modify flag for aggkind (must match DefineAggregate) */
15533 defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
15534 /* replace omitted flags for old versions */
15535 if (aggfinalmodify == '0')
15536 aggfinalmodify = defaultfinalmodify;
15537 if (aggmfinalmodify == '0')
15538 aggmfinalmodify = defaultfinalmodify;
15539
15540 /* regproc and regtype output is already sufficiently quoted */
15541 appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
15542 aggtransfn, aggtranstype);
15543
15544 if (strcmp(aggtransspace, "0") != 0)
15545 {
15546 appendPQExpBuffer(details, ",\n SSPACE = %s",
15547 aggtransspace);
15548 }
15549
15550 if (!PQgetisnull(res, 0, i_agginitval))
15551 {
15552 appendPQExpBufferStr(details, ",\n INITCOND = ");
15553 appendStringLiteralAH(details, agginitval, fout);
15554 }
15555
15556 if (strcmp(aggfinalfn, "-") != 0)
15557 {
15558 appendPQExpBuffer(details, ",\n FINALFUNC = %s",
15559 aggfinalfn);
15560 if (aggfinalextra)
15561 appendPQExpBufferStr(details, ",\n FINALFUNC_EXTRA");
15562 if (aggfinalmodify != defaultfinalmodify)
15563 {
15564 switch (aggfinalmodify)
15565 {
15566 case AGGMODIFY_READ_ONLY:
15567 appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_ONLY");
15568 break;
15569 case AGGMODIFY_SHAREABLE:
15570 appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHAREABLE");
15571 break;
15572 case AGGMODIFY_READ_WRITE:
15573 appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_WRITE");
15574 break;
15575 default:
15576 pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
15577 agginfo->aggfn.dobj.name);
15578 break;
15579 }
15580 }
15581 }
15582
15583 if (strcmp(aggcombinefn, "-") != 0)
15584 appendPQExpBuffer(details, ",\n COMBINEFUNC = %s", aggcombinefn);
15585
15586 if (strcmp(aggserialfn, "-") != 0)
15587 appendPQExpBuffer(details, ",\n SERIALFUNC = %s", aggserialfn);
15588
15589 if (strcmp(aggdeserialfn, "-") != 0)
15590 appendPQExpBuffer(details, ",\n DESERIALFUNC = %s", aggdeserialfn);
15591
15592 if (strcmp(aggmtransfn, "-") != 0)
15593 {
15594 appendPQExpBuffer(details, ",\n MSFUNC = %s,\n MINVFUNC = %s,\n MSTYPE = %s",
15595 aggmtransfn,
15596 aggminvtransfn,
15597 aggmtranstype);
15598 }
15599
15600 if (strcmp(aggmtransspace, "0") != 0)
15601 {
15602 appendPQExpBuffer(details, ",\n MSSPACE = %s",
15603 aggmtransspace);
15604 }
15605
15606 if (!PQgetisnull(res, 0, i_aggminitval))
15607 {
15608 appendPQExpBufferStr(details, ",\n MINITCOND = ");
15609 appendStringLiteralAH(details, aggminitval, fout);
15610 }
15611
15612 if (strcmp(aggmfinalfn, "-") != 0)
15613 {
15614 appendPQExpBuffer(details, ",\n MFINALFUNC = %s",
15615 aggmfinalfn);
15616 if (aggmfinalextra)
15617 appendPQExpBufferStr(details, ",\n MFINALFUNC_EXTRA");
15618 if (aggmfinalmodify != defaultfinalmodify)
15619 {
15620 switch (aggmfinalmodify)
15621 {
15622 case AGGMODIFY_READ_ONLY:
15623 appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_ONLY");
15624 break;
15625 case AGGMODIFY_SHAREABLE:
15626 appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHAREABLE");
15627 break;
15628 case AGGMODIFY_READ_WRITE:
15629 appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_WRITE");
15630 break;
15631 default:
15632 pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
15633 agginfo->aggfn.dobj.name);
15634 break;
15635 }
15636 }
15637 }
15638
15639 aggsortconvop = getFormattedOperatorName(aggsortop);
15640 if (aggsortconvop)
15641 {
15642 appendPQExpBuffer(details, ",\n SORTOP = %s",
15643 aggsortconvop);
15644 free(aggsortconvop);
15645 }
15646
15647 if (aggkind == AGGKIND_HYPOTHETICAL)
15648 appendPQExpBufferStr(details, ",\n HYPOTHETICAL");
15649
15650 if (proparallel[0] != PROPARALLEL_UNSAFE)
15651 {
15652 if (proparallel[0] == PROPARALLEL_SAFE)
15653 appendPQExpBufferStr(details, ",\n PARALLEL = safe");
15654 else if (proparallel[0] == PROPARALLEL_RESTRICTED)
15655 appendPQExpBufferStr(details, ",\n PARALLEL = restricted");
15656 else if (proparallel[0] != PROPARALLEL_UNSAFE)
15657 pg_fatal("unrecognized proparallel value for function \"%s\"",
15658 agginfo->aggfn.dobj.name);
15659 }
15660
15661 appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
15662 fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
15663 aggsig);
15664
15665 appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
15666 fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
15667 aggfullsig ? aggfullsig : aggsig, details->data);
15668
15669 if (dopt->binary_upgrade)
15670 binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
15671 "AGGREGATE", aggsig,
15672 agginfo->aggfn.dobj.namespace->dobj.name);
15673
15674 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
15675 ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
15676 agginfo->aggfn.dobj.dumpId,
15677 ARCHIVE_OPTS(.tag = aggsig_tag,
15678 .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
15679 .owner = agginfo->aggfn.rolname,
15680 .description = "AGGREGATE",
15681 .section = SECTION_PRE_DATA,
15682 .createStmt = q->data,
15683 .dropStmt = delq->data));
15684
15685 /* Dump Aggregate Comments */
15686 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
15687 dumpComment(fout, "AGGREGATE", aggsig,
15688 agginfo->aggfn.dobj.namespace->dobj.name,
15689 agginfo->aggfn.rolname,
15690 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
15691
15692 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
15693 dumpSecLabel(fout, "AGGREGATE", aggsig,
15694 agginfo->aggfn.dobj.namespace->dobj.name,
15695 agginfo->aggfn.rolname,
15696 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
15697
15698 /*
15699 * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
15700 * command look like a function's GRANT; in particular this affects the
15701 * syntax for zero-argument aggregates and ordered-set aggregates.
15702 */
15703 free(aggsig);
15704
15705 aggsig = format_function_signature(fout, &agginfo->aggfn, true);
15706
15707 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
15708 dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
15709 "FUNCTION", aggsig, NULL,
15710 agginfo->aggfn.dobj.namespace->dobj.name,
15711 NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
15712
15713 free(aggsig);
15714 free(aggfullsig);
15715 free(aggsig_tag);
15716
15717 PQclear(res);
15718
15719 destroyPQExpBuffer(query);
15721 destroyPQExpBuffer(delq);
15722 destroyPQExpBuffer(details);
15723}
@ PREPQUERY_DUMPAGG
Definition: pg_backup.h:66
void ExecuteSqlStatement(Archive *AHX, const char *query)
Definition: pg_backup_db.c:217
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:16408
static char * getFormattedOperatorName(const char *oproid)
Definition: pg_dump.c:14365
static char * format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
Definition: pg_dump.c:13420
static char * format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
Definition: pg_dump.c:13397
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:16536
static char * format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
Definition: pg_dump.c:15338
bool * is_prepared
Definition: pg_backup.h:255

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::dopt, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), _dumpOptions::dumpSchema, 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, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpAttrDef()

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

Definition at line 18175 of file pg_dump.c.

18176{
18177 DumpOptions *dopt = fout->dopt;
18178 TableInfo *tbinfo = adinfo->adtable;
18179 int adnum = adinfo->adnum;
18180 PQExpBuffer q;
18181 PQExpBuffer delq;
18182 char *qualrelname;
18183 char *tag;
18184 char *foreign;
18185
18186 /* Do nothing if not dumping schema */
18187 if (!dopt->dumpSchema)
18188 return;
18189
18190 /* Skip if not "separate"; it was dumped in the table's definition */
18191 if (!adinfo->separate)
18192 return;
18193
18194 q = createPQExpBuffer();
18195 delq = createPQExpBuffer();
18196
18197 qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
18198
18199 foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
18200
18202 "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
18203 foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
18204 adinfo->adef_expr);
18205
18206 appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
18207 foreign, qualrelname,
18208 fmtId(tbinfo->attnames[adnum - 1]));
18209
18210 tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
18211
18212 if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18213 ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
18214 ARCHIVE_OPTS(.tag = tag,
18215 .namespace = tbinfo->dobj.namespace->dobj.name,
18216 .owner = tbinfo->rolname,
18217 .description = "DEFAULT",
18218 .section = SECTION_PRE_DATA,
18219 .createStmt = q->data,
18220 .dropStmt = delq->data));
18221
18222 free(tag);
18224 destroyPQExpBuffer(delq);
18225 free(qualrelname);
18226}
DumpableObject dobj
Definition: pg_dump.h:404
char * adef_expr
Definition: pg_dump.h:407
TableInfo * adtable
Definition: pg_dump.h:405
bool separate
Definition: pg_dump.h:408
const char * rolname
Definition: pg_dump.h:309

References _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _tableInfo::attnames, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _attrDefInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 12450 of file pg_dump.c.

12451{
12452 DumpOptions *dopt = fout->dopt;
12456 PGresult *res;
12457 char *qtypname;
12458 char *qualtypname;
12459 char *typlen;
12460 char *typinput;
12461 char *typoutput;
12462 char *typreceive;
12463 char *typsend;
12464 char *typmodin;
12465 char *typmodout;
12466 char *typanalyze;
12467 char *typsubscript;
12468 Oid typreceiveoid;
12469 Oid typsendoid;
12470 Oid typmodinoid;
12471 Oid typmodoutoid;
12472 Oid typanalyzeoid;
12473 Oid typsubscriptoid;
12474 char *typcategory;
12475 char *typispreferred;
12476 char *typdelim;
12477 char *typbyval;
12478 char *typalign;
12479 char *typstorage;
12480 char *typcollatable;
12481 char *typdefault;
12482 bool typdefault_is_literal = false;
12483
12485 {
12486 /* Set up query for type-specific details */
12488 "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
12489 "SELECT typlen, "
12490 "typinput, typoutput, typreceive, typsend, "
12491 "typreceive::pg_catalog.oid AS typreceiveoid, "
12492 "typsend::pg_catalog.oid AS typsendoid, "
12493 "typanalyze, "
12494 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
12495 "typdelim, typbyval, typalign, typstorage, "
12496 "typmodin, typmodout, "
12497 "typmodin::pg_catalog.oid AS typmodinoid, "
12498 "typmodout::pg_catalog.oid AS typmodoutoid, "
12499 "typcategory, typispreferred, "
12500 "(typcollation <> 0) AS typcollatable, "
12501 "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
12502
12503 if (fout->remoteVersion >= 140000)
12505 "typsubscript, "
12506 "typsubscript::pg_catalog.oid AS typsubscriptoid ");
12507 else
12509 "'-' AS typsubscript, 0 AS typsubscriptoid ");
12510
12511 appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
12512 "WHERE oid = $1");
12513
12514 ExecuteSqlStatement(fout, query->data);
12515
12516 fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
12517 }
12518
12519 printfPQExpBuffer(query,
12520 "EXECUTE dumpBaseType('%u')",
12521 tyinfo->dobj.catId.oid);
12522
12523 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12524
12525 typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
12526 typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
12527 typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
12528 typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
12529 typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
12530 typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
12531 typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
12532 typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
12533 typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
12534 typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
12535 typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
12536 typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
12537 typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
12538 typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
12539 typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
12540 typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
12541 typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
12542 typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
12543 typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
12544 typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
12545 typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
12546 typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
12547 if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
12548 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
12549 else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
12550 {
12551 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
12552 typdefault_is_literal = true; /* it needs quotes */
12553 }
12554 else
12555 typdefault = NULL;
12556
12557 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12558 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12559
12560 /*
12561 * The reason we include CASCADE is that the circular dependency between
12562 * the type and its I/O functions makes it impossible to drop the type any
12563 * other way.
12564 */
12565 appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
12566
12567 /*
12568 * We might already have a shell type, but setting pg_type_oid is
12569 * harmless, and in any case we'd better set the array type OID.
12570 */
12571 if (dopt->binary_upgrade)
12573 tyinfo->dobj.catId.oid,
12574 false, false);
12575
12577 "CREATE TYPE %s (\n"
12578 " INTERNALLENGTH = %s",
12579 qualtypname,
12580 (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
12581
12582 /* regproc result is sufficiently quoted already */
12583 appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
12584 appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
12585 if (OidIsValid(typreceiveoid))
12586 appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
12587 if (OidIsValid(typsendoid))
12588 appendPQExpBuffer(q, ",\n SEND = %s", typsend);
12589 if (OidIsValid(typmodinoid))
12590 appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
12591 if (OidIsValid(typmodoutoid))
12592 appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
12593 if (OidIsValid(typanalyzeoid))
12594 appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
12595
12596 if (strcmp(typcollatable, "t") == 0)
12597 appendPQExpBufferStr(q, ",\n COLLATABLE = true");
12598
12599 if (typdefault != NULL)
12600 {
12601 appendPQExpBufferStr(q, ",\n DEFAULT = ");
12602 if (typdefault_is_literal)
12603 appendStringLiteralAH(q, typdefault, fout);
12604 else
12605 appendPQExpBufferStr(q, typdefault);
12606 }
12607
12608 if (OidIsValid(typsubscriptoid))
12609 appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
12610
12611 if (OidIsValid(tyinfo->typelem))
12612 appendPQExpBuffer(q, ",\n ELEMENT = %s",
12613 getFormattedTypeName(fout, tyinfo->typelem,
12614 zeroIsError));
12615
12616 if (strcmp(typcategory, "U") != 0)
12617 {
12618 appendPQExpBufferStr(q, ",\n CATEGORY = ");
12619 appendStringLiteralAH(q, typcategory, fout);
12620 }
12621
12622 if (strcmp(typispreferred, "t") == 0)
12623 appendPQExpBufferStr(q, ",\n PREFERRED = true");
12624
12625 if (typdelim && strcmp(typdelim, ",") != 0)
12626 {
12627 appendPQExpBufferStr(q, ",\n DELIMITER = ");
12628 appendStringLiteralAH(q, typdelim, fout);
12629 }
12630
12631 if (*typalign == TYPALIGN_CHAR)
12632 appendPQExpBufferStr(q, ",\n ALIGNMENT = char");
12633 else if (*typalign == TYPALIGN_SHORT)
12634 appendPQExpBufferStr(q, ",\n ALIGNMENT = int2");
12635 else if (*typalign == TYPALIGN_INT)
12636 appendPQExpBufferStr(q, ",\n ALIGNMENT = int4");
12637 else if (*typalign == TYPALIGN_DOUBLE)
12638 appendPQExpBufferStr(q, ",\n ALIGNMENT = double");
12639
12640 if (*typstorage == TYPSTORAGE_PLAIN)
12641 appendPQExpBufferStr(q, ",\n STORAGE = plain");
12642 else if (*typstorage == TYPSTORAGE_EXTERNAL)
12643 appendPQExpBufferStr(q, ",\n STORAGE = external");
12644 else if (*typstorage == TYPSTORAGE_EXTENDED)
12645 appendPQExpBufferStr(q, ",\n STORAGE = extended");
12646 else if (*typstorage == TYPSTORAGE_MAIN)
12647 appendPQExpBufferStr(q, ",\n STORAGE = main");
12648
12649 if (strcmp(typbyval, "t") == 0)
12650 appendPQExpBufferStr(q, ",\n PASSEDBYVALUE");
12651
12652 appendPQExpBufferStr(q, "\n);\n");
12653
12654 if (dopt->binary_upgrade)
12656 "TYPE", qtypname,
12657 tyinfo->dobj.namespace->dobj.name);
12658
12659 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12660 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12661 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12662 .namespace = tyinfo->dobj.namespace->dobj.name,
12663 .owner = tyinfo->rolname,
12664 .description = "TYPE",
12665 .section = SECTION_PRE_DATA,
12666 .createStmt = q->data,
12667 .dropStmt = delq->data));
12668
12669 /* Dump Type Comments and Security Labels */
12670 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12671 dumpComment(fout, "TYPE", qtypname,
12672 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12673 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12674
12675 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12676 dumpSecLabel(fout, "TYPE", qtypname,
12677 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12678 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12679
12680 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12681 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12682 qtypname, NULL,
12683 tyinfo->dobj.namespace->dobj.name,
12684 NULL, tyinfo->rolname, &tyinfo->dacl);
12685
12686 PQclear(res);
12688 destroyPQExpBuffer(delq);
12689 destroyPQExpBuffer(query);
12690 free(qtypname);
12691 free(qualtypname);
12692}
@ PREPQUERY_DUMPBASETYPE
Definition: pg_backup.h:67
static const char * getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
Definition: pg_dump.c:20367
char typalign
Definition: pg_type.h:176
DumpableAcl dacl
Definition: pg_dump.h:206
Oid typelem
Definition: pg_dump.h:215
const char * rolname
Definition: pg_dump.h:214

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

13872{
13873 DumpOptions *dopt = fout->dopt;
13874 PQExpBuffer defqry;
13875 PQExpBuffer delqry;
13876 PQExpBuffer labelq;
13877 PQExpBuffer castargs;
13878 FuncInfo *funcInfo = NULL;
13879 const char *sourceType;
13880 const char *targetType;
13881
13882 /* Do nothing if not dumping schema */
13883 if (!dopt->dumpSchema)
13884 return;
13885
13886 /* Cannot dump if we don't have the cast function's info */
13887 if (OidIsValid(cast->castfunc))
13888 {
13889 funcInfo = findFuncByOid(cast->castfunc);
13890 if (funcInfo == NULL)
13891 pg_fatal("could not find function definition for function with OID %u",
13892 cast->castfunc);
13893 }
13894
13895 defqry = createPQExpBuffer();
13896 delqry = createPQExpBuffer();
13897 labelq = createPQExpBuffer();
13898 castargs = createPQExpBuffer();
13899
13900 sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
13901 targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
13902 appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
13903 sourceType, targetType);
13904
13905 appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
13906 sourceType, targetType);
13907
13908 switch (cast->castmethod)
13909 {
13910 case COERCION_METHOD_BINARY:
13911 appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
13912 break;
13913 case COERCION_METHOD_INOUT:
13914 appendPQExpBufferStr(defqry, "WITH INOUT");
13915 break;
13916 case COERCION_METHOD_FUNCTION:
13917 if (funcInfo)
13918 {
13919 char *fsig = format_function_signature(fout, funcInfo, true);
13920
13921 /*
13922 * Always qualify the function name (format_function_signature
13923 * won't qualify it).
13924 */
13925 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
13926 fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
13927 free(fsig);
13928 }
13929 else
13930 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
13931 break;
13932 default:
13933 pg_log_warning("bogus value in pg_cast.castmethod field");
13934 }
13935
13936 if (cast->castcontext == 'a')
13937 appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
13938 else if (cast->castcontext == 'i')
13939 appendPQExpBufferStr(defqry, " AS IMPLICIT");
13940 appendPQExpBufferStr(defqry, ";\n");
13941
13942 appendPQExpBuffer(labelq, "CAST (%s AS %s)",
13943 sourceType, targetType);
13944
13945 appendPQExpBuffer(castargs, "(%s AS %s)",
13946 sourceType, targetType);
13947
13948 if (dopt->binary_upgrade)
13950 "CAST", castargs->data, NULL);
13951
13953 ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
13954 ARCHIVE_OPTS(.tag = labelq->data,
13955 .description = "CAST",
13956 .section = SECTION_PRE_DATA,
13957 .createStmt = defqry->data,
13958 .dropStmt = delqry->data));
13959
13960 /* Dump Cast Comments */
13961 if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
13962 dumpComment(fout, "CAST", castargs->data,
13963 NULL, "",
13964 cast->dobj.catId, 0, cast->dobj.dumpId);
13965
13966 destroyPQExpBuffer(defqry);
13967 destroyPQExpBuffer(delqry);
13968 destroyPQExpBuffer(labelq);
13969 destroyPQExpBuffer(castargs);
13970}
FuncInfo * findFuncByOid(Oid oid)
Definition: common.c:918
char castmethod
Definition: pg_dump.h:549
Oid casttarget
Definition: pg_dump.h:546
char castcontext
Definition: pg_dump.h:548
DumpableObject dobj
Definition: pg_dump.h:544
Oid castsource
Definition: pg_dump.h:545
Oid castfunc
Definition: pg_dump.h:547
DumpableObject dobj
Definition: pg_dump.h:241

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, destroyPQExpBuffer(), _funcInfo::dobj, _castInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 14985 of file pg_dump.c.

14986{
14987 DumpOptions *dopt = fout->dopt;
14988 PQExpBuffer query;
14989 PQExpBuffer q;
14990 PQExpBuffer delq;
14991 char *qcollname;
14992 PGresult *res;
14993 int i_collprovider;
14994 int i_collisdeterministic;
14995 int i_collcollate;
14996 int i_collctype;
14997 int i_colllocale;
14998 int i_collicurules;
14999 const char *collprovider;
15000 const char *collcollate;
15001 const char *collctype;
15002 const char *colllocale;
15003 const char *collicurules;
15004
15005 /* Do nothing if not dumping schema */
15006 if (!dopt->dumpSchema)
15007 return;
15008
15009 query = createPQExpBuffer();
15010 q = createPQExpBuffer();
15011 delq = createPQExpBuffer();
15012
15013 qcollname = pg_strdup(fmtId(collinfo->dobj.name));
15014
15015 /* Get collation-specific details */
15016 appendPQExpBufferStr(query, "SELECT ");
15017
15018 if (fout->remoteVersion >= 100000)
15020 "collprovider, "
15021 "collversion, ");
15022 else
15024 "'c' AS collprovider, "
15025 "NULL AS collversion, ");
15026
15027 if (fout->remoteVersion >= 120000)
15029 "collisdeterministic, ");
15030 else
15032 "true AS collisdeterministic, ");
15033
15034 if (fout->remoteVersion >= 170000)
15036 "colllocale, ");
15037 else if (fout->remoteVersion >= 150000)
15039 "colliculocale AS colllocale, ");
15040 else
15042 "NULL AS colllocale, ");
15043
15044 if (fout->remoteVersion >= 160000)
15046 "collicurules, ");
15047 else
15049 "NULL AS collicurules, ");
15050
15051 appendPQExpBuffer(query,
15052 "collcollate, "
15053 "collctype "
15054 "FROM pg_catalog.pg_collation c "
15055 "WHERE c.oid = '%u'::pg_catalog.oid",
15056 collinfo->dobj.catId.oid);
15057
15058 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15059
15060 i_collprovider = PQfnumber(res, "collprovider");
15061 i_collisdeterministic = PQfnumber(res, "collisdeterministic");
15062 i_collcollate = PQfnumber(res, "collcollate");
15063 i_collctype = PQfnumber(res, "collctype");
15064 i_colllocale = PQfnumber(res, "colllocale");
15065 i_collicurules = PQfnumber(res, "collicurules");
15066
15067 collprovider = PQgetvalue(res, 0, i_collprovider);
15068
15069 if (!PQgetisnull(res, 0, i_collcollate))
15070 collcollate = PQgetvalue(res, 0, i_collcollate);
15071 else
15072 collcollate = NULL;
15073
15074 if (!PQgetisnull(res, 0, i_collctype))
15075 collctype = PQgetvalue(res, 0, i_collctype);
15076 else
15077 collctype = NULL;
15078
15079 /*
15080 * Before version 15, collcollate and collctype were of type NAME and
15081 * non-nullable. Treat empty strings as NULL for consistency.
15082 */
15083 if (fout->remoteVersion < 150000)
15084 {
15085 if (collcollate[0] == '\0')
15086 collcollate = NULL;
15087 if (collctype[0] == '\0')
15088 collctype = NULL;
15089 }
15090
15091 if (!PQgetisnull(res, 0, i_colllocale))
15092 colllocale = PQgetvalue(res, 0, i_colllocale);
15093 else
15094 colllocale = NULL;
15095
15096 if (!PQgetisnull(res, 0, i_collicurules))
15097 collicurules = PQgetvalue(res, 0, i_collicurules);
15098 else
15099 collicurules = NULL;
15100
15101 appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
15102 fmtQualifiedDumpable(collinfo));
15103
15104 appendPQExpBuffer(q, "CREATE COLLATION %s (",
15105 fmtQualifiedDumpable(collinfo));
15106
15107 appendPQExpBufferStr(q, "provider = ");
15108 if (collprovider[0] == 'b')
15109 appendPQExpBufferStr(q, "builtin");
15110 else if (collprovider[0] == 'c')
15111 appendPQExpBufferStr(q, "libc");
15112 else if (collprovider[0] == 'i')
15113 appendPQExpBufferStr(q, "icu");
15114 else if (collprovider[0] == 'd')
15115 /* to allow dumping pg_catalog; not accepted on input */
15116 appendPQExpBufferStr(q, "default");
15117 else
15118 pg_fatal("unrecognized collation provider: %s",
15119 collprovider);
15120
15121 if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
15122 appendPQExpBufferStr(q, ", deterministic = false");
15123
15124 if (collprovider[0] == 'd')
15125 {
15126 if (collcollate || collctype || colllocale || collicurules)
15127 pg_log_warning("invalid collation \"%s\"", qcollname);
15128
15129 /* no locale -- the default collation cannot be reloaded anyway */
15130 }
15131 else if (collprovider[0] == 'b')
15132 {
15133 if (collcollate || collctype || !colllocale || collicurules)
15134 pg_log_warning("invalid collation \"%s\"", qcollname);
15135
15136 appendPQExpBufferStr(q, ", locale = ");
15137 appendStringLiteralAH(q, colllocale ? colllocale : "",
15138 fout);
15139 }
15140 else if (collprovider[0] == 'i')
15141 {
15142 if (fout->remoteVersion >= 150000)
15143 {
15144 if (collcollate || collctype || !colllocale)
15145 pg_log_warning("invalid collation \"%s\"", qcollname);
15146
15147 appendPQExpBufferStr(q, ", locale = ");
15148 appendStringLiteralAH(q, colllocale ? colllocale : "",
15149 fout);
15150 }
15151 else
15152 {
15153 if (!collcollate || !collctype || colllocale ||
15154 strcmp(collcollate, collctype) != 0)
15155 pg_log_warning("invalid collation \"%s\"", qcollname);
15156
15157 appendPQExpBufferStr(q, ", locale = ");
15158 appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
15159 }
15160
15161 if (collicurules)
15162 {
15163 appendPQExpBufferStr(q, ", rules = ");
15164 appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
15165 }
15166 }
15167 else if (collprovider[0] == 'c')
15168 {
15169 if (colllocale || collicurules || !collcollate || !collctype)
15170 pg_log_warning("invalid collation \"%s\"", qcollname);
15171
15172 if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
15173 {
15174 appendPQExpBufferStr(q, ", locale = ");
15175 appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
15176 }
15177 else
15178 {
15179 appendPQExpBufferStr(q, ", lc_collate = ");
15180 appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
15181 appendPQExpBufferStr(q, ", lc_ctype = ");
15182 appendStringLiteralAH(q, collctype ? collctype : "", fout);
15183 }
15184 }
15185 else
15186 pg_fatal("unrecognized collation provider: %s", collprovider);
15187
15188 /*
15189 * For binary upgrade, carry over the collation version. For normal
15190 * dump/restore, omit the version, so that it is computed upon restore.
15191 */
15192 if (dopt->binary_upgrade)
15193 {
15194 int i_collversion;
15195
15196 i_collversion = PQfnumber(res, "collversion");
15197 if (!PQgetisnull(res, 0, i_collversion))
15198 {
15199 appendPQExpBufferStr(q, ", version = ");
15201 PQgetvalue(res, 0, i_collversion),
15202 fout);
15203 }
15204 }
15205
15206 appendPQExpBufferStr(q, ");\n");
15207
15208 if (dopt->binary_upgrade)
15210 "COLLATION", qcollname,
15211 collinfo->dobj.namespace->dobj.name);
15212
15213 if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15214 ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
15215 ARCHIVE_OPTS(.tag = collinfo->dobj.name,
15216 .namespace = collinfo->dobj.namespace->dobj.name,
15217 .owner = collinfo->rolname,
15218 .description = "COLLATION",
15219 .section = SECTION_PRE_DATA,
15220 .createStmt = q->data,
15221 .dropStmt = delq->data));
15222
15223 /* Dump Collation Comments */
15224 if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15225 dumpComment(fout, "COLLATION", qcollname,
15226 collinfo->dobj.namespace->dobj.name, collinfo->rolname,
15227 collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
15228
15229 PQclear(res);
15230
15231 destroyPQExpBuffer(query);
15233 destroyPQExpBuffer(delq);
15234 free(qcollname);
15235}
const char * rolname
Definition: pg_dump.h:292
DumpableObject dobj
Definition: pg_dump.h:291

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _collInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, ExecuteSqlQueryForSingleRow(), fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, CatalogId::oid, pg_fatal, pg_log_warning, pg_strdup(), PQclear, PQfnumber(), PQgetisnull, PQgetvalue, Archive::remoteVersion, _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 10980 of file pg_dump.c.

10984{
10985 dumpCommentExtended(fout, type, name, namespace, owner,
10986 catalogId, subid, dumpId, NULL);
10987}
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:10880

References dumpCommentExtended(), name, and type.

Referenced by dumpAccessMethod(), dumpAgg(), dumpBaseType(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpConstraint(), 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 10880 of file pg_dump.c.

10885{
10886 DumpOptions *dopt = fout->dopt;
10888 int ncomments;
10889
10890 /* do nothing, if --no-comments is supplied */
10891 if (dopt->no_comments)
10892 return;
10893
10894 /* Comments are schema not data ... except LO comments are data */
10895 if (strcmp(type, "LARGE OBJECT") != 0)
10896 {
10897 if (!dopt->dumpSchema)
10898 return;
10899 }
10900 else
10901 {
10902 /* We do dump LO comments in binary-upgrade mode */
10903 if (!dopt->dumpData && !dopt->binary_upgrade)
10904 return;
10905 }
10906
10907 /* Search for comments associated with catalogId, using table */
10908 ncomments = findComments(catalogId.tableoid, catalogId.oid,
10909 &comments);
10910
10911 /* Is there one matching the subid? */
10912 while (ncomments > 0)
10913 {
10914 if (comments->objsubid == subid)
10915 break;
10916 comments++;
10917 ncomments--;
10918 }
10919
10920 if (initdb_comment != NULL)
10921 {
10922 static CommentItem empty_comment = {.descr = ""};
10923
10924 /*
10925 * initdb creates this object with a comment. Skip dumping the
10926 * initdb-provided comment, which would complicate matters for
10927 * non-superuser use of pg_dump. When the DBA has removed initdb's
10928 * comment, replicate that.
10929 */
10930 if (ncomments == 0)
10931 {
10932 comments = &empty_comment;
10933 ncomments = 1;
10934 }
10935 else if (strcmp(comments->descr, initdb_comment) == 0)
10936 ncomments = 0;
10937 }
10938
10939 /* If a comment exists, build COMMENT ON statement */
10940 if (ncomments > 0)
10941 {
10944
10945 appendPQExpBuffer(query, "COMMENT ON %s ", type);
10946 if (namespace && *namespace)
10947 appendPQExpBuffer(query, "%s.", fmtId(namespace));
10948 appendPQExpBuffer(query, "%s IS ", name);
10949 appendStringLiteralAH(query, comments->descr, fout);
10950 appendPQExpBufferStr(query, ";\n");
10951
10952 appendPQExpBuffer(tag, "%s %s", type, name);
10953
10954 /*
10955 * We mark comments as SECTION_NONE because they really belong in the
10956 * same section as their parent, whether that is pre-data or
10957 * post-data.
10958 */
10960 ARCHIVE_OPTS(.tag = tag->data,
10961 .namespace = namespace,
10962 .owner = owner,
10963 .description = "COMMENT",
10964 .section = SECTION_NONE,
10965 .createStmt = query->data,
10966 .deps = &dumpId,
10967 .nDeps = 1));
10968
10969 destroyPQExpBuffer(query);
10970 destroyPQExpBuffer(tag);
10971 }
10972}
static int findComments(Oid classoid, Oid objoid, CommentItem **items)
Definition: pg_dump.c:11499
int no_comments
Definition: pg_backup.h:186

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

Referenced by dumpComment(), and dumpNamespace().

◆ dumpCompositeType()

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

Definition at line 12924 of file pg_dump.c.

12925{
12926 DumpOptions *dopt = fout->dopt;
12928 PQExpBuffer dropped = createPQExpBuffer();
12931 PGresult *res;
12932 char *qtypname;
12933 char *qualtypname;
12934 int ntups;
12935 int i_attname;
12936 int i_atttypdefn;
12937 int i_attlen;
12938 int i_attalign;
12939 int i_attisdropped;
12940 int i_attcollation;
12941 int i;
12942 int actual_atts;
12943
12945 {
12946 /*
12947 * Set up query for type-specific details.
12948 *
12949 * Since we only want to dump COLLATE clauses for attributes whose
12950 * collation is different from their type's default, we use a CASE
12951 * here to suppress uninteresting attcollations cheaply. atttypid
12952 * will be 0 for dropped columns; collation does not matter for those.
12953 */
12955 "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
12956 "SELECT a.attname, a.attnum, "
12957 "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
12958 "a.attlen, a.attalign, a.attisdropped, "
12959 "CASE WHEN a.attcollation <> at.typcollation "
12960 "THEN a.attcollation ELSE 0 END AS attcollation "
12961 "FROM pg_catalog.pg_type ct "
12962 "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
12963 "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
12964 "WHERE ct.oid = $1 "
12965 "ORDER BY a.attnum");
12966
12967 ExecuteSqlStatement(fout, query->data);
12968
12970 }
12971
12972 printfPQExpBuffer(query,
12973 "EXECUTE dumpCompositeType('%u')",
12974 tyinfo->dobj.catId.oid);
12975
12976 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12977
12978 ntups = PQntuples(res);
12979
12980 i_attname = PQfnumber(res, "attname");
12981 i_atttypdefn = PQfnumber(res, "atttypdefn");
12982 i_attlen = PQfnumber(res, "attlen");
12983 i_attalign = PQfnumber(res, "attalign");
12984 i_attisdropped = PQfnumber(res, "attisdropped");
12985 i_attcollation = PQfnumber(res, "attcollation");
12986
12987 if (dopt->binary_upgrade)
12988 {
12990 tyinfo->dobj.catId.oid,
12991 false, false);
12993 }
12994
12995 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12996 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12997
12998 appendPQExpBuffer(q, "CREATE TYPE %s AS (",
12999 qualtypname);
13000
13001 actual_atts = 0;
13002 for (i = 0; i < ntups; i++)
13003 {
13004 char *attname;
13005 char *atttypdefn;
13006 char *attlen;
13007 char *attalign;
13008 bool attisdropped;
13009 Oid attcollation;
13010
13011 attname = PQgetvalue(res, i, i_attname);
13012 atttypdefn = PQgetvalue(res, i, i_atttypdefn);
13013 attlen = PQgetvalue(res, i, i_attlen);
13014 attalign = PQgetvalue(res, i, i_attalign);
13015 attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
13016 attcollation = atooid(PQgetvalue(res, i, i_attcollation));
13017
13018 if (attisdropped && !dopt->binary_upgrade)
13019 continue;
13020
13021 /* Format properly if not first attr */
13022 if (actual_atts++ > 0)
13023 appendPQExpBufferChar(q, ',');
13024 appendPQExpBufferStr(q, "\n\t");
13025
13026 if (!attisdropped)
13027 {
13028 appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
13029
13030 /* Add collation if not default for the column type */
13031 if (OidIsValid(attcollation))
13032 {
13033 CollInfo *coll;
13034
13035 coll = findCollationByOid(attcollation);
13036 if (coll)
13037 appendPQExpBuffer(q, " COLLATE %s",
13038 fmtQualifiedDumpable(coll));
13039 }
13040 }
13041 else
13042 {
13043 /*
13044 * This is a dropped attribute and we're in binary_upgrade mode.
13045 * Insert a placeholder for it in the CREATE TYPE command, and set
13046 * length and alignment with direct UPDATE to the catalogs
13047 * afterwards. See similar code in dumpTableSchema().
13048 */
13049 appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
13050
13051 /* stash separately for insertion after the CREATE TYPE */
13052 appendPQExpBufferStr(dropped,
13053 "\n-- For binary upgrade, recreate dropped column.\n");
13054 appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
13055 "SET attlen = %s, "
13056 "attalign = '%s', attbyval = false\n"
13057 "WHERE attname = ", attlen, attalign);
13058 appendStringLiteralAH(dropped, attname, fout);
13059 appendPQExpBufferStr(dropped, "\n AND attrelid = ");
13060 appendStringLiteralAH(dropped, qualtypname, fout);
13061 appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
13062
13063 appendPQExpBuffer(dropped, "ALTER TYPE %s ",
13064 qualtypname);
13065 appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
13066 fmtId(attname));
13067 }
13068 }
13069 appendPQExpBufferStr(q, "\n);\n");
13070 appendPQExpBufferStr(q, dropped->data);
13071
13072 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
13073
13074 if (dopt->binary_upgrade)
13076 "TYPE", qtypname,
13077 tyinfo->dobj.namespace->dobj.name);
13078
13079 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13080 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
13081 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
13082 .namespace = tyinfo->dobj.namespace->dobj.name,
13083 .owner = tyinfo->rolname,
13084 .description = "TYPE",
13085 .section = SECTION_PRE_DATA,
13086 .createStmt = q->data,
13087 .dropStmt = delq->data));
13088
13089
13090 /* Dump Type Comments and Security Labels */
13091 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13092 dumpComment(fout, "TYPE", qtypname,
13093 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
13094 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
13095
13096 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
13097 dumpSecLabel(fout, "TYPE", qtypname,
13098 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
13099 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
13100
13101 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
13102 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
13103 qtypname, NULL,
13104 tyinfo->dobj.namespace->dobj.name,
13105 NULL, tyinfo->rolname, &tyinfo->dacl);
13106
13107 /* Dump any per-column comments */
13108 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13109 dumpCompositeTypeColComments(fout, tyinfo, res);
13110
13111 PQclear(res);
13113 destroyPQExpBuffer(dropped);
13114 destroyPQExpBuffer(delq);
13115 destroyPQExpBuffer(query);
13116 free(qtypname);
13117 free(qualtypname);
13118}
NameData attname
Definition: pg_attribute.h:41
char attalign
Definition: pg_attribute.h:100
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:5857
static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo, PGresult *res)
Definition: pg_dump.c:13130
Oid typrelid
Definition: pg_dump.h:216

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(), _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 13130 of file pg_dump.c.

13132{
13134 int ncomments;
13135 PQExpBuffer query;
13136 PQExpBuffer target;
13137 int i;
13138 int ntups;
13139 int i_attname;
13140 int i_attnum;
13141 int i_attisdropped;
13142
13143 /* do nothing, if --no-comments is supplied */
13144 if (fout->dopt->no_comments)
13145 return;
13146
13147 /* Search for comments associated with type's pg_class OID */
13148 ncomments = findComments(RelationRelationId, tyinfo->typrelid,
13149 &comments);
13150
13151 /* If no comments exist, we're done */
13152 if (ncomments <= 0)
13153 return;
13154
13155 /* Build COMMENT ON statements */
13156 query = createPQExpBuffer();
13157 target = createPQExpBuffer();
13158
13159 ntups = PQntuples(res);
13160 i_attnum = PQfnumber(res, "attnum");
13161 i_attname = PQfnumber(res, "attname");
13162 i_attisdropped = PQfnumber(res, "attisdropped");
13163 while (ncomments > 0)
13164 {
13165 const char *attname;
13166
13167 attname = NULL;
13168 for (i = 0; i < ntups; i++)
13169 {
13170 if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
13171 PQgetvalue(res, i, i_attisdropped)[0] != 't')
13172 {
13173 attname = PQgetvalue(res, i, i_attname);
13174 break;
13175 }
13176 }
13177 if (attname) /* just in case we don't find it */
13178 {
13179 const char *descr = comments->descr;
13180
13181 resetPQExpBuffer(target);
13182 appendPQExpBuffer(target, "COLUMN %s.",
13183 fmtId(tyinfo->dobj.name));
13185
13186 resetPQExpBuffer(query);
13187 appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
13188 fmtQualifiedDumpable(tyinfo));
13189 appendPQExpBuffer(query, "%s IS ", fmtId(attname));
13190 appendStringLiteralAH(query, descr, fout);
13191 appendPQExpBufferStr(query, ";\n");
13192
13194 ARCHIVE_OPTS(.tag = target->data,
13195 .namespace = tyinfo->dobj.namespace->dobj.name,
13196 .owner = tyinfo->rolname,
13197 .description = "COMMENT",
13198 .section = SECTION_NONE,
13199 .createStmt = query->data,
13200 .deps = &(tyinfo->dobj.dumpId),
13201 .nDeps = 1));
13202 }
13203
13204 comments++;
13205 ncomments--;
13206 }
13207
13208 destroyPQExpBuffer(query);
13209 destroyPQExpBuffer(target);
13210}
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, resetPQExpBuffer(), _typeInfo::rolname, SECTION_NONE, and _typeInfo::typrelid.

Referenced by dumpCompositeType().

◆ dumpConstraint()

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

Definition at line 18536 of file pg_dump.c.

18537{
18538 DumpOptions *dopt = fout->dopt;
18539 TableInfo *tbinfo = coninfo->contable;
18540 PQExpBuffer q;
18541 PQExpBuffer delq;
18542 char *tag = NULL;
18543 char *foreign;
18544
18545 /* Do nothing if not dumping schema */
18546 if (!dopt->dumpSchema)
18547 return;
18548
18549 q = createPQExpBuffer();
18550 delq = createPQExpBuffer();
18551
18552 foreign = tbinfo &&
18553 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
18554
18555 if (coninfo->contype == 'p' ||
18556 coninfo->contype == 'u' ||
18557 coninfo->contype == 'x')
18558 {
18559 /* Index-related constraint */
18560 IndxInfo *indxinfo;
18561 int k;
18562
18563 indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
18564
18565 if (indxinfo == NULL)
18566 pg_fatal("missing index for constraint \"%s\"",
18567 coninfo->dobj.name);
18568
18569 if (dopt->binary_upgrade)
18571 indxinfo->dobj.catId.oid);
18572
18573 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
18574 fmtQualifiedDumpable(tbinfo));
18575 appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
18576 fmtId(coninfo->dobj.name));
18577
18578 if (coninfo->condef)
18579 {
18580 /* pg_get_constraintdef should have provided everything */
18581 appendPQExpBuffer(q, "%s;\n", coninfo->condef);
18582 }
18583 else
18584 {
18586 coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
18587
18588 /*
18589 * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
18590 * indexes. Being able to create this was fixed, but we need to
18591 * make the index distinct in order to be able to restore the
18592 * dump.
18593 */
18594 if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
18595 appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
18596 appendPQExpBufferStr(q, " (");
18597 for (k = 0; k < indxinfo->indnkeyattrs; k++)
18598 {
18599 int indkey = (int) indxinfo->indkeys[k];
18600 const char *attname;
18601
18602 if (indkey == InvalidAttrNumber)
18603 break;
18604 attname = getAttrName(indkey, tbinfo);
18605
18606 appendPQExpBuffer(q, "%s%s",
18607 (k == 0) ? "" : ", ",
18608 fmtId(attname));
18609 }
18610 if (coninfo->conperiod)
18611 appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
18612
18613 if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
18614 appendPQExpBufferStr(q, ") INCLUDE (");
18615
18616 for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
18617 {
18618 int indkey = (int) indxinfo->indkeys[k];
18619 const char *attname;
18620
18621 if (indkey == InvalidAttrNumber)
18622 break;
18623 attname = getAttrName(indkey, tbinfo);
18624
18625 appendPQExpBuffer(q, "%s%s",
18626 (k == indxinfo->indnkeyattrs) ? "" : ", ",
18627 fmtId(attname));
18628 }
18629
18630 appendPQExpBufferChar(q, ')');
18631
18632 if (nonemptyReloptions(indxinfo->indreloptions))
18633 {
18634 appendPQExpBufferStr(q, " WITH (");
18635 appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
18636 appendPQExpBufferChar(q, ')');
18637 }
18638
18639 if (coninfo->condeferrable)
18640 {
18641 appendPQExpBufferStr(q, " DEFERRABLE");
18642 if (coninfo->condeferred)
18643 appendPQExpBufferStr(q, " INITIALLY DEFERRED");
18644 }
18645
18646 appendPQExpBufferStr(q, ";\n");
18647 }
18648
18649 /*
18650 * Append ALTER TABLE commands as needed to set properties that we
18651 * only have ALTER TABLE syntax for. Keep this in sync with the
18652 * similar code in dumpIndex!
18653 */
18654
18655 /* If the index is clustered, we need to record that. */
18656 if (indxinfo->indisclustered)
18657 {
18658 appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
18659 fmtQualifiedDumpable(tbinfo));
18660 /* index name is not qualified in this syntax */
18661 appendPQExpBuffer(q, " ON %s;\n",
18662 fmtId(indxinfo->dobj.name));
18663 }
18664
18665 /* If the index defines identity, we need to record that. */
18666 if (indxinfo->indisreplident)
18667 {
18668 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
18669 fmtQualifiedDumpable(tbinfo));
18670 /* index name is not qualified in this syntax */
18671 appendPQExpBuffer(q, " INDEX %s;\n",
18672 fmtId(indxinfo->dobj.name));
18673 }
18674
18675 /* Indexes can depend on extensions */
18676 append_depends_on_extension(fout, q, &indxinfo->dobj,
18677 "pg_catalog.pg_class", "INDEX",
18678 fmtQualifiedDumpable(indxinfo));
18679
18680 appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
18681 fmtQualifiedDumpable(tbinfo));
18682 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18683 fmtId(coninfo->dobj.name));
18684
18685 tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
18686
18687 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18688 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18689 ARCHIVE_OPTS(.tag = tag,
18690 .namespace = tbinfo->dobj.namespace->dobj.name,
18691 .tablespace = indxinfo->tablespace,
18692 .owner = tbinfo->rolname,
18693 .description = "CONSTRAINT",
18694 .section = SECTION_POST_DATA,
18695 .createStmt = q->data,
18696 .dropStmt = delq->data));
18697 }
18698 else if (coninfo->contype == 'f')
18699 {
18700 char *only;
18701
18702 /*
18703 * Foreign keys on partitioned tables are always declared as
18704 * inheriting to partitions; for all other cases, emit them as
18705 * applying ONLY directly to the named table, because that's how they
18706 * work for regular inherited tables.
18707 */
18708 only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
18709
18710 /*
18711 * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
18712 * current table data is not processed
18713 */
18714 appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
18715 only, fmtQualifiedDumpable(tbinfo));
18716 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
18717 fmtId(coninfo->dobj.name),
18718 coninfo->condef);
18719
18720 appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
18721 only, fmtQualifiedDumpable(tbinfo));
18722 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18723 fmtId(coninfo->dobj.name));
18724
18725 tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
18726
18727 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18728 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18729 ARCHIVE_OPTS(.tag = tag,
18730 .namespace = tbinfo->dobj.namespace->dobj.name,
18731 .owner = tbinfo->rolname,
18732 .description = "FK CONSTRAINT",
18733 .section = SECTION_POST_DATA,
18734 .createStmt = q->data,
18735 .dropStmt = delq->data));
18736 }
18737 else if ((coninfo->contype == 'c' || coninfo->contype == 'n') && tbinfo)
18738 {
18739 /* CHECK or invalid not-null constraint on a table */
18740
18741 /* Ignore if not to be dumped separately, or if it was inherited */
18742 if (coninfo->separate && coninfo->conislocal)
18743 {
18744 const char *keyword;
18745
18746 if (coninfo->contype == 'c')
18747 keyword = "CHECK CONSTRAINT";
18748 else
18749 keyword = "CONSTRAINT";
18750
18751 /* not ONLY since we want it to propagate to children */
18752 appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
18753 fmtQualifiedDumpable(tbinfo));
18754 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
18755 fmtId(coninfo->dobj.name),
18756 coninfo->condef);
18757
18758 appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
18759 fmtQualifiedDumpable(tbinfo));
18760 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18761 fmtId(coninfo->dobj.name));
18762
18763 tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
18764
18765 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18766 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18767 ARCHIVE_OPTS(.tag = tag,
18768 .namespace = tbinfo->dobj.namespace->dobj.name,
18769 .owner = tbinfo->rolname,
18770 .description = keyword,
18771 .section = SECTION_POST_DATA,
18772 .createStmt = q->data,
18773 .dropStmt = delq->data));
18774 }
18775 }
18776 else if (tbinfo == NULL)
18777 {
18778 /* CHECK, NOT NULL constraint on a domain */
18779 TypeInfo *tyinfo = coninfo->condomain;
18780
18781 Assert(coninfo->contype == 'c' || coninfo->contype == 'n');
18782
18783 /* Ignore if not to be dumped separately */
18784 if (coninfo->separate)
18785 {
18786 const char *keyword;
18787
18788 if (coninfo->contype == 'c')
18789 keyword = "CHECK CONSTRAINT";
18790 else
18791 keyword = "CONSTRAINT";
18792
18793 appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
18794 fmtQualifiedDumpable(tyinfo));
18795 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
18796 fmtId(coninfo->dobj.name),
18797 coninfo->condef);
18798
18799 appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
18800 fmtQualifiedDumpable(tyinfo));
18801 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18802 fmtId(coninfo->dobj.name));
18803
18804 tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
18805
18806 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18807 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18808 ARCHIVE_OPTS(.tag = tag,
18809 .namespace = tyinfo->dobj.namespace->dobj.name,
18810 .owner = tyinfo->rolname,
18811 .description = keyword,
18812 .section = SECTION_POST_DATA,
18813 .createStmt = q->data,
18814 .dropStmt = delq->data));
18815
18816 if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18817 {
18818 PQExpBuffer conprefix = createPQExpBuffer();
18819 char *qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
18820
18821 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
18822 fmtId(coninfo->dobj.name));
18823
18824 dumpComment(fout, conprefix->data, qtypname,
18825 tyinfo->dobj.namespace->dobj.name,
18826 tyinfo->rolname,
18827 coninfo->dobj.catId, 0, coninfo->dobj.dumpId);
18828 destroyPQExpBuffer(conprefix);
18829 free(qtypname);
18830 }
18831 }
18832 }
18833 else
18834 {
18835 pg_fatal("unrecognized constraint type: %c",
18836 coninfo->contype);
18837 }
18838
18839 /* Dump Constraint Comments --- only works for table constraints */
18840 if (tbinfo && coninfo->separate &&
18841 coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18842 dumpTableConstraintComment(fout, coninfo);
18843
18844 free(tag);
18846 destroyPQExpBuffer(delq);
18847}
#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:5636
static const char * getAttrName(int attrnum, const TableInfo *tblInfo)
Definition: pg_dump.c:18236
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
Definition: pg_dump.c:20464
static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:18857
static bool nonemptyReloptions(const char *reloptions)
Definition: pg_dump.c:20452
TypeInfo * condomain
Definition: pg_dump.h:519
TableInfo * contable
Definition: pg_dump.h:518
bool condeferred
Definition: pg_dump.h:525
bool conperiod
Definition: pg_dump.h:526
bool conislocal
Definition: pg_dump.h:527
DumpableObject dobj
Definition: pg_dump.h:517
DumpId conindex
Definition: pg_dump.h:523
bool condeferrable
Definition: pg_dump.h:524
char * condef
Definition: pg_dump.h:521
bool indisreplident
Definition: pg_dump.h:432
int indnkeyattrs
Definition: pg_dump.h:427
int indnattrs
Definition: pg_dump.h:428
Oid * indkeys
Definition: pg_dump.h:429
char * indreloptions
Definition: pg_dump.h:424
bool indisclustered
Definition: pg_dump.h:431
char * tablespace
Definition: pg_dump.h:423
bool indnullsnotdistinct
Definition: pg_dump.h:433
DumpableObject dobj
Definition: pg_dump.h:420

References append_depends_on_extension(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArrayAH(), ARCHIVE_OPTS, ArchiveEntry(), Assert(), attname, _dumpOptions::binary_upgrade, binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::conperiod, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _typeInfo::dobj, _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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, pg_strdup(), 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 15242 of file pg_dump.c.

15243{
15244 DumpOptions *dopt = fout->dopt;
15245 PQExpBuffer query;
15246 PQExpBuffer q;
15247 PQExpBuffer delq;
15248 char *qconvname;
15249 PGresult *res;
15250 int i_conforencoding;
15251 int i_contoencoding;
15252 int i_conproc;
15253 int i_condefault;
15254 const char *conforencoding;
15255 const char *contoencoding;
15256 const char *conproc;
15257 bool condefault;
15258
15259 /* Do nothing if not dumping schema */
15260 if (!dopt->dumpSchema)
15261 return;
15262
15263 query = createPQExpBuffer();
15264 q = createPQExpBuffer();
15265 delq = createPQExpBuffer();
15266
15267 qconvname = pg_strdup(fmtId(convinfo->dobj.name));
15268
15269 /* Get conversion-specific details */
15270 appendPQExpBuffer(query, "SELECT "
15271 "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
15272 "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
15273 "conproc, condefault "
15274 "FROM pg_catalog.pg_conversion c "
15275 "WHERE c.oid = '%u'::pg_catalog.oid",
15276 convinfo->dobj.catId.oid);
15277
15278 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15279
15280 i_conforencoding = PQfnumber(res, "conforencoding");
15281 i_contoencoding = PQfnumber(res, "contoencoding");
15282 i_conproc = PQfnumber(res, "conproc");
15283 i_condefault = PQfnumber(res, "condefault");
15284
15285 conforencoding = PQgetvalue(res, 0, i_conforencoding);
15286 contoencoding = PQgetvalue(res, 0, i_contoencoding);
15287 conproc = PQgetvalue(res, 0, i_conproc);
15288 condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
15289
15290 appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
15291 fmtQualifiedDumpable(convinfo));
15292
15293 appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
15294 (condefault) ? "DEFAULT " : "",
15295 fmtQualifiedDumpable(convinfo));
15296 appendStringLiteralAH(q, conforencoding, fout);
15297 appendPQExpBufferStr(q, " TO ");
15298 appendStringLiteralAH(q, contoencoding, fout);
15299 /* regproc output is already sufficiently quoted */
15300 appendPQExpBuffer(q, " FROM %s;\n", conproc);
15301
15302 if (dopt->binary_upgrade)
15304 "CONVERSION", qconvname,
15305 convinfo->dobj.namespace->dobj.name);
15306
15307 if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15308 ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
15309 ARCHIVE_OPTS(.tag = convinfo->dobj.name,
15310 .namespace = convinfo->dobj.namespace->dobj.name,
15311 .owner = convinfo->rolname,
15312 .description = "CONVERSION",
15313 .section = SECTION_PRE_DATA,
15314 .createStmt = q->data,
15315 .dropStmt = delq->data));
15316
15317 /* Dump Conversion Comments */
15318 if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15319 dumpComment(fout, "CONVERSION", qconvname,
15320 convinfo->dobj.namespace->dobj.name, convinfo->rolname,
15321 convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
15322
15323 PQclear(res);
15324
15325 destroyPQExpBuffer(query);
15327 destroyPQExpBuffer(delq);
15328 free(qconvname);
15329}
DumpableObject dobj
Definition: pg_dump.h:298
const char * rolname
Definition: pg_dump.h:299

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

Referenced by dumpDumpableObject().

◆ dumpDatabase()

static void dumpDatabase ( Archive fout)
static

Definition at line 3282 of file pg_dump.c.

3283{
3284 DumpOptions *dopt = fout->dopt;
3286 PQExpBuffer delQry = createPQExpBuffer();
3287 PQExpBuffer creaQry = createPQExpBuffer();
3288 PQExpBuffer labelq = createPQExpBuffer();
3289 PGconn *conn = GetConnection(fout);
3290 PGresult *res;
3291 int i_tableoid,
3292 i_oid,
3293 i_datname,
3294 i_datdba,
3295 i_encoding,
3296 i_datlocprovider,
3297 i_collate,
3298 i_ctype,
3299 i_datlocale,
3300 i_daticurules,
3301 i_frozenxid,
3302 i_minmxid,
3303 i_datacl,
3304 i_acldefault,
3305 i_datistemplate,
3306 i_datconnlimit,
3307 i_datcollversion,
3308 i_tablespace;
3309 CatalogId dbCatId;
3310 DumpId dbDumpId;
3311 DumpableAcl dbdacl;
3312 const char *datname,
3313 *dba,
3314 *encoding,
3316 *collate,
3317 *ctype,
3318 *locale,
3319 *icurules,
3321 *datconnlimit,
3322 *tablespace;
3323 uint32 frozenxid,
3324 minmxid;
3325 char *qdatname;
3326
3327 pg_log_info("saving database definition");
3328
3329 /*
3330 * Fetch the database-level properties for this database.
3331 */
3332 appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
3333 "datdba, "
3334 "pg_encoding_to_char(encoding) AS encoding, "
3335 "datcollate, datctype, datfrozenxid, "
3336 "datacl, acldefault('d', datdba) AS acldefault, "
3337 "datistemplate, datconnlimit, ");
3338 if (fout->remoteVersion >= 90300)
3339 appendPQExpBufferStr(dbQry, "datminmxid, ");
3340 else
3341 appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
3342 if (fout->remoteVersion >= 170000)
3343 appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
3344 else if (fout->remoteVersion >= 150000)
3345 appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
3346 else
3347 appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
3348 if (fout->remoteVersion >= 160000)
3349 appendPQExpBufferStr(dbQry, "daticurules, ");
3350 else
3351 appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
3353 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
3354 "shobj_description(oid, 'pg_database') AS description "
3355 "FROM pg_database "
3356 "WHERE datname = current_database()");
3357
3358 res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
3359
3360 i_tableoid = PQfnumber(res, "tableoid");
3361 i_oid = PQfnumber(res, "oid");
3362 i_datname = PQfnumber(res, "datname");
3363 i_datdba = PQfnumber(res, "datdba");
3364 i_encoding = PQfnumber(res, "encoding");
3365 i_datlocprovider = PQfnumber(res, "datlocprovider");
3366 i_collate = PQfnumber(res, "datcollate");
3367 i_ctype = PQfnumber(res, "datctype");
3368 i_datlocale = PQfnumber(res, "datlocale");
3369 i_daticurules = PQfnumber(res, "daticurules");
3370 i_frozenxid = PQfnumber(res, "datfrozenxid");
3371 i_minmxid = PQfnumber(res, "datminmxid");
3372 i_datacl = PQfnumber(res, "datacl");
3373 i_acldefault = PQfnumber(res, "acldefault");
3374 i_datistemplate = PQfnumber(res, "datistemplate");
3375 i_datconnlimit = PQfnumber(res, "datconnlimit");
3376 i_datcollversion = PQfnumber(res, "datcollversion");
3377 i_tablespace = PQfnumber(res, "tablespace");
3378
3379 dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
3380 dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
3381 datname = PQgetvalue(res, 0, i_datname);
3382 dba = getRoleName(PQgetvalue(res, 0, i_datdba));
3383 encoding = PQgetvalue(res, 0, i_encoding);
3384 datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
3385 collate = PQgetvalue(res, 0, i_collate);
3386 ctype = PQgetvalue(res, 0, i_ctype);
3387 if (!PQgetisnull(res, 0, i_datlocale))
3388 locale = PQgetvalue(res, 0, i_datlocale);
3389 else
3390 locale = NULL;
3391 if (!PQgetisnull(res, 0, i_daticurules))
3392 icurules = PQgetvalue(res, 0, i_daticurules);
3393 else
3394 icurules = NULL;
3395 frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
3396 minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
3397 dbdacl.acl = PQgetvalue(res, 0, i_datacl);
3398 dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
3399 datistemplate = PQgetvalue(res, 0, i_datistemplate);
3400 datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
3401 tablespace = PQgetvalue(res, 0, i_tablespace);
3402
3403 qdatname = pg_strdup(fmtId(datname));
3404
3405 /*
3406 * Prepare the CREATE DATABASE command. We must specify OID (if we want
3407 * to preserve that), as well as the encoding, locale, and tablespace
3408 * since those can't be altered later. Other DB properties are left to
3409 * the DATABASE PROPERTIES entry, so that they can be applied after
3410 * reconnecting to the target DB.
3411 *
3412 * For binary upgrade, we use the FILE_COPY strategy because testing has
3413 * shown it to be faster. When the server is in binary upgrade mode, it
3414 * will also skip the checkpoints this strategy ordinarily performs.
3415 */
3416 if (dopt->binary_upgrade)
3417 {
3418 appendPQExpBuffer(creaQry,
3419 "CREATE DATABASE %s WITH TEMPLATE = template0 "
3420 "OID = %u STRATEGY = FILE_COPY",
3421 qdatname, dbCatId.oid);
3422 }
3423 else
3424 {
3425 appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
3426 qdatname);
3427 }
3428 if (strlen(encoding) > 0)
3429 {
3430 appendPQExpBufferStr(creaQry, " ENCODING = ");
3431 appendStringLiteralAH(creaQry, encoding, fout);
3432 }
3433
3434 appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
3435 if (datlocprovider[0] == 'b')
3436 appendPQExpBufferStr(creaQry, "builtin");
3437 else if (datlocprovider[0] == 'c')
3438 appendPQExpBufferStr(creaQry, "libc");
3439 else if (datlocprovider[0] == 'i')
3440 appendPQExpBufferStr(creaQry, "icu");
3441 else
3442 pg_fatal("unrecognized locale provider: %s",
3444
3445 if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
3446 {
3447 appendPQExpBufferStr(creaQry, " LOCALE = ");
3448 appendStringLiteralAH(creaQry, collate, fout);
3449 }
3450 else
3451 {
3452 if (strlen(collate) > 0)
3453 {
3454 appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
3455 appendStringLiteralAH(creaQry, collate, fout);
3456 }
3457 if (strlen(ctype) > 0)
3458 {
3459 appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
3460 appendStringLiteralAH(creaQry, ctype, fout);
3461 }
3462 }
3463 if (locale)
3464 {
3465 if (datlocprovider[0] == 'b')
3466 appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
3467 else
3468 appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
3469
3470 appendStringLiteralAH(creaQry, locale, fout);
3471 }
3472
3473 if (icurules)
3474 {
3475 appendPQExpBufferStr(creaQry, " ICU_RULES = ");
3476 appendStringLiteralAH(creaQry, icurules, fout);
3477 }
3478
3479 /*
3480 * For binary upgrade, carry over the collation version. For normal
3481 * dump/restore, omit the version, so that it is computed upon restore.
3482 */
3483 if (dopt->binary_upgrade)
3484 {
3485 if (!PQgetisnull(res, 0, i_datcollversion))
3486 {
3487 appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
3488 appendStringLiteralAH(creaQry,
3489 PQgetvalue(res, 0, i_datcollversion),
3490 fout);
3491 }
3492 }
3493
3494 /*
3495 * Note: looking at dopt->outputNoTablespaces here is completely the wrong
3496 * thing; the decision whether to specify a tablespace should be left till
3497 * pg_restore, so that pg_restore --no-tablespaces applies. Ideally we'd
3498 * label the DATABASE entry with the tablespace and let the normal
3499 * tablespace selection logic work ... but CREATE DATABASE doesn't pay
3500 * attention to default_tablespace, so that won't work.
3501 */
3502 if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
3503 !dopt->outputNoTablespaces)
3504 appendPQExpBuffer(creaQry, " TABLESPACE = %s",
3505 fmtId(tablespace));
3506 appendPQExpBufferStr(creaQry, ";\n");
3507
3508 appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
3509 qdatname);
3510
3511 dbDumpId = createDumpId();
3512
3513 ArchiveEntry(fout,
3514 dbCatId, /* catalog ID */
3515 dbDumpId, /* dump ID */
3516 ARCHIVE_OPTS(.tag = datname,
3517 .owner = dba,
3518 .description = "DATABASE",
3519 .section = SECTION_PRE_DATA,
3520 .createStmt = creaQry->data,
3521 .dropStmt = delQry->data));
3522
3523 /* Compute correct tag for archive entry */
3524 appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
3525
3526 /* Dump DB comment if any */
3527 {
3528 /*
3529 * 8.2 and up keep comments on shared objects in a shared table, so we
3530 * cannot use the dumpComment() code used for other database objects.
3531 * Be careful that the ArchiveEntry parameters match that function.
3532 */
3533 char *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
3534
3535 if (comment && *comment && !dopt->no_comments)
3536 {
3537 resetPQExpBuffer(dbQry);
3538
3539 /*
3540 * Generates warning when loaded into a differently-named
3541 * database.
3542 */
3543 appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
3544 appendStringLiteralAH(dbQry, comment, fout);
3545 appendPQExpBufferStr(dbQry, ";\n");
3546
3548 ARCHIVE_OPTS(.tag = labelq->data,
3549 .owner = dba,
3550 .description = "COMMENT",
3551 .section = SECTION_NONE,
3552 .createStmt = dbQry->data,
3553 .deps = &dbDumpId,
3554 .nDeps = 1));
3555 }
3556 }
3557
3558 /* Dump DB security label, if enabled */
3559 if (!dopt->no_security_labels)
3560 {
3561 PGresult *shres;
3562 PQExpBuffer seclabelQry;
3563
3564 seclabelQry = createPQExpBuffer();
3565
3566 buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
3567 shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
3568 resetPQExpBuffer(seclabelQry);
3569 emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
3570 if (seclabelQry->len > 0)
3572 ARCHIVE_OPTS(.tag = labelq->data,
3573 .owner = dba,
3574 .description = "SECURITY LABEL",
3575 .section = SECTION_NONE,
3576 .createStmt = seclabelQry->data,
3577 .deps = &dbDumpId,
3578 .nDeps = 1));
3579 destroyPQExpBuffer(seclabelQry);
3580 PQclear(shres);
3581 }
3582
3583 /*
3584 * Dump ACL if any. Note that we do not support initial privileges
3585 * (pg_init_privs) on databases.
3586 */
3587 dbdacl.privtype = 0;
3588 dbdacl.initprivs = NULL;
3589
3590 dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
3591 qdatname, NULL, NULL,
3592 NULL, dba, &dbdacl);
3593
3594 /*
3595 * Now construct a DATABASE PROPERTIES archive entry to restore any
3596 * non-default database-level properties. (The reason this must be
3597 * separate is that we cannot put any additional commands into the TOC
3598 * entry that has CREATE DATABASE. pg_restore would execute such a group
3599 * in an implicit transaction block, and the backend won't allow CREATE
3600 * DATABASE in that context.)
3601 */
3602 resetPQExpBuffer(creaQry);
3603 resetPQExpBuffer(delQry);
3604
3605 if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
3606 appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
3607 qdatname, datconnlimit);
3608
3609 if (strcmp(datistemplate, "t") == 0)
3610 {
3611 appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
3612 qdatname);
3613
3614 /*
3615 * The backend won't accept DROP DATABASE on a template database. We
3616 * can deal with that by removing the template marking before the DROP
3617 * gets issued. We'd prefer to use ALTER DATABASE IF EXISTS here, but
3618 * since no such command is currently supported, fake it with a direct
3619 * UPDATE on pg_database.
3620 */
3621 appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
3622 "SET datistemplate = false WHERE datname = ");
3623 appendStringLiteralAH(delQry, datname, fout);
3624 appendPQExpBufferStr(delQry, ";\n");
3625 }
3626
3627 /*
3628 * We do not restore pg_database.dathasloginevt because it is set
3629 * automatically on login event trigger creation.
3630 */
3631
3632 /* Add database-specific SET options */
3633 dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
3634
3635 /*
3636 * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
3637 * entry, too, for lack of a better place.
3638 */
3639 if (dopt->binary_upgrade)
3640 {
3641 appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
3642 appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
3643 "SET datfrozenxid = '%u', datminmxid = '%u'\n"
3644 "WHERE datname = ",
3645 frozenxid, minmxid);
3646 appendStringLiteralAH(creaQry, datname, fout);
3647 appendPQExpBufferStr(creaQry, ";\n");
3648 }
3649
3650 if (creaQry->len > 0)
3652 ARCHIVE_OPTS(.tag = datname,
3653 .owner = dba,
3654 .description = "DATABASE PROPERTIES",
3655 .section = SECTION_PRE_DATA,
3656 .createStmt = creaQry->data,
3657 .dropStmt = delQry->data,
3658 .deps = &dbDumpId));
3659
3660 /*
3661 * pg_largeobject comes from the old system intact, so set its
3662 * relfrozenxids, relminmxids and relfilenode.
3663 *
3664 * pg_largeobject_metadata also comes from the old system intact for
3665 * upgrades from v16 and newer, so set its relfrozenxids, relminmxids, and
3666 * relfilenode, too. pg_upgrade can't copy/link the files from older
3667 * versions because aclitem (needed by pg_largeobject_metadata.lomacl)
3668 * changed its storage format in v16.
3669 */
3670 if (dopt->binary_upgrade)
3671 {
3672 PGresult *lo_res;
3673 PQExpBuffer loFrozenQry = createPQExpBuffer();
3674 PQExpBuffer loOutQry = createPQExpBuffer();
3675 PQExpBuffer lomOutQry = createPQExpBuffer();
3676 PQExpBuffer loHorizonQry = createPQExpBuffer();
3677 PQExpBuffer lomHorizonQry = createPQExpBuffer();
3678 int ii_relfrozenxid,
3679 ii_relfilenode,
3680 ii_oid,
3681 ii_relminmxid;
3682
3683 if (fout->remoteVersion >= 90300)
3684 appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
3685 "FROM pg_catalog.pg_class\n"
3686 "WHERE oid IN (%u, %u, %u, %u);\n",
3687 LargeObjectRelationId, LargeObjectLOidPNIndexId,
3688 LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId);
3689 else
3690 appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
3691 "FROM pg_catalog.pg_class\n"
3692 "WHERE oid IN (%u, %u);\n",
3693 LargeObjectRelationId, LargeObjectLOidPNIndexId);
3694
3695 lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
3696
3697 ii_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
3698 ii_relminmxid = PQfnumber(lo_res, "relminmxid");
3699 ii_relfilenode = PQfnumber(lo_res, "relfilenode");
3700 ii_oid = PQfnumber(lo_res, "oid");
3701
3702 appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
3703 appendPQExpBufferStr(lomHorizonQry, "\n-- For binary upgrade, set pg_largeobject_metadata relfrozenxid and relminmxid\n");
3704 appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
3705 appendPQExpBufferStr(lomOutQry, "\n-- For binary upgrade, preserve pg_largeobject_metadata and index relfilenodes\n");
3706 for (int i = 0; i < PQntuples(lo_res); ++i)
3707 {
3708 Oid oid;
3709 RelFileNumber relfilenumber;
3710 PQExpBuffer horizonQry;
3711 PQExpBuffer outQry;
3712
3713 oid = atooid(PQgetvalue(lo_res, i, ii_oid));
3714 relfilenumber = atooid(PQgetvalue(lo_res, i, ii_relfilenode));
3715
3716 if (oid == LargeObjectRelationId ||
3717 oid == LargeObjectLOidPNIndexId)
3718 {
3719 horizonQry = loHorizonQry;
3720 outQry = loOutQry;
3721 }
3722 else
3723 {
3724 horizonQry = lomHorizonQry;
3725 outQry = lomOutQry;
3726 }
3727
3728 appendPQExpBuffer(horizonQry, "UPDATE pg_catalog.pg_class\n"
3729 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
3730 "WHERE oid = %u;\n",
3731 atooid(PQgetvalue(lo_res, i, ii_relfrozenxid)),
3732 atooid(PQgetvalue(lo_res, i, ii_relminmxid)),
3733 atooid(PQgetvalue(lo_res, i, ii_oid)));
3734
3735 if (oid == LargeObjectRelationId ||
3736 oid == LargeObjectMetadataRelationId)
3737 appendPQExpBuffer(outQry,
3738 "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
3739 relfilenumber);
3740 else if (oid == LargeObjectLOidPNIndexId ||
3741 oid == LargeObjectMetadataOidIndexId)
3742 appendPQExpBuffer(outQry,
3743 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
3744 relfilenumber);
3745 }
3746
3747 appendPQExpBufferStr(loOutQry,
3748 "TRUNCATE pg_catalog.pg_largeobject;\n");
3749 appendPQExpBufferStr(lomOutQry,
3750 "TRUNCATE pg_catalog.pg_largeobject_metadata;\n");
3751
3752 appendPQExpBufferStr(loOutQry, loHorizonQry->data);
3753 appendPQExpBufferStr(lomOutQry, lomHorizonQry->data);
3754
3756 ARCHIVE_OPTS(.tag = "pg_largeobject",
3757 .description = "pg_largeobject",
3758 .section = SECTION_PRE_DATA,
3759 .createStmt = loOutQry->data));
3760
3761 if (fout->remoteVersion >= 160000)
3763 ARCHIVE_OPTS(.tag = "pg_largeobject_metadata",
3764 .description = "pg_largeobject_metadata",
3765 .section = SECTION_PRE_DATA,
3766 .createStmt = lomOutQry->data));
3767
3768 PQclear(lo_res);
3769
3770 destroyPQExpBuffer(loFrozenQry);
3771 destroyPQExpBuffer(loHorizonQry);
3772 destroyPQExpBuffer(lomHorizonQry);
3773 destroyPQExpBuffer(loOutQry);
3774 destroyPQExpBuffer(lomOutQry);
3775 }
3776
3777 PQclear(res);
3778
3779 free(qdatname);
3780 destroyPQExpBuffer(dbQry);
3781 destroyPQExpBuffer(delQry);
3782 destroyPQExpBuffer(creaQry);
3783 destroyPQExpBuffer(labelq);
3784}
uint32_t uint32
Definition: c.h:552
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
Definition: connection.c:206
void buildShSecLabelQuery(const char *catalog_name, Oid objectId, PQExpBuffer sql)
Definition: dumputils.c:678
void emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *objtype, const char *objname)
Definition: dumputils.c:696
#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:10680
static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf, const char *dbname, Oid dboid)
Definition: pg_dump.c:3791
static char * tablespace
Definition: pgbench.c:217
Oid RelFileNumber
Definition: relpath.h:25
PGconn * conn
Definition: streamutil.c:52
int no_security_labels
Definition: pg_backup.h:189
int outputNoTablespaces
Definition: pg_backup.h:196
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, 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 3791 of file pg_dump.c.

3793{
3794 PGconn *conn = GetConnection(AH);
3796 PGresult *res;
3797
3798 /* First collect database-specific options */
3799 printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
3800 "WHERE setrole = 0 AND setdatabase = '%u'::oid",
3801 dboid);
3802
3803 res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3804
3805 for (int i = 0; i < PQntuples(res); i++)
3807 "DATABASE", dbname, NULL, NULL,
3808 outbuf);
3809
3810 PQclear(res);
3811
3812 /* Now look for role-and-database-specific options */
3813 printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
3814 "FROM pg_db_role_setting s, pg_roles r "
3815 "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
3816 dboid);
3817
3818 res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3819
3820 for (int i = 0; i < PQntuples(res); i++)
3822 "ROLE", PQgetvalue(res, i, 0),
3823 "DATABASE", dbname,
3824 outbuf);
3825
3826 PQclear(res);
3827
3829}
void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, PQExpBuffer buf)
Definition: dumputils.c:864
static char buf[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
char * dbname
Definition: streamutil.c:49

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

Referenced by dumpDatabase().

◆ dumpDefaultACL()

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

Definition at line 16316 of file pg_dump.c.

16317{
16318 DumpOptions *dopt = fout->dopt;
16319 PQExpBuffer q;
16320 PQExpBuffer tag;
16321 const char *type;
16322
16323 /* Do nothing if not dumping schema, or if we're skipping ACLs */
16324 if (!dopt->dumpSchema || dopt->aclsSkip)
16325 return;
16326
16327 q = createPQExpBuffer();
16328 tag = createPQExpBuffer();
16329
16330 switch (daclinfo->defaclobjtype)
16331 {
16332 case DEFACLOBJ_RELATION:
16333 type = "TABLES";
16334 break;
16335 case DEFACLOBJ_SEQUENCE:
16336 type = "SEQUENCES";
16337 break;
16338 case DEFACLOBJ_FUNCTION:
16339 type = "FUNCTIONS";
16340 break;
16341 case DEFACLOBJ_TYPE:
16342 type = "TYPES";
16343 break;
16344 case DEFACLOBJ_NAMESPACE:
16345 type = "SCHEMAS";
16346 break;
16347 case DEFACLOBJ_LARGEOBJECT:
16348 type = "LARGE OBJECTS";
16349 break;
16350 default:
16351 /* shouldn't get here */
16352 pg_fatal("unrecognized object type in default privileges: %d",
16353 (int) daclinfo->defaclobjtype);
16354 type = ""; /* keep compiler quiet */
16355 }
16356
16357 appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
16358
16359 /* build the actual command(s) for this tuple */
16361 daclinfo->dobj.namespace != NULL ?
16362 daclinfo->dobj.namespace->dobj.name : NULL,
16363 daclinfo->dacl.acl,
16364 daclinfo->dacl.acldefault,
16365 daclinfo->defaclrole,
16366 fout->remoteVersion,
16367 q))
16368 pg_fatal("could not parse default ACL list (%s)",
16369 daclinfo->dacl.acl);
16370
16371 if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
16372 ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
16373 ARCHIVE_OPTS(.tag = tag->data,
16374 .namespace = daclinfo->dobj.namespace ?
16375 daclinfo->dobj.namespace->dobj.name : NULL,
16376 .owner = daclinfo->defaclrole,
16377 .description = "DEFAULT ACL",
16378 .section = SECTION_POST_DATA,
16379 .createStmt = q->data));
16380
16381 destroyPQExpBuffer(tag);
16383}
bool buildDefaultACLCommands(const char *type, const char *nspname, const char *acls, const char *acldefault, const char *owner, int remoteVersion, PQExpBuffer sql)
Definition: dumputils.c:366
DumpableObject dobj
Definition: pg_dump.h:623
DumpableAcl dacl
Definition: pg_dump.h:624
const char * defaclrole
Definition: pg_dump.h:625
char defaclobjtype
Definition: pg_dump.h:626

References _dumpableAcl::acl, _dumpableAcl::acldefault, _dumpOptions::aclsSkip, appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), buildDefaultACLCommands(), _dumpableObject::catId, createPQExpBuffer(), _defaultACLInfo::dacl, PQExpBufferData::data, _defaultACLInfo::defaclobjtype, _defaultACLInfo::defaclrole, destroyPQExpBuffer(), _defaultACLInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, _dumpableObject::dumpId, _dumpOptions::dumpSchema, _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 12699 of file pg_dump.c.

12700{
12701 DumpOptions *dopt = fout->dopt;
12705 PGresult *res;
12706 int i;
12707 char *qtypname;
12708 char *qualtypname;
12709 char *typnotnull;
12710 char *typdefn;
12711 char *typdefault;
12712 Oid typcollation;
12713 bool typdefault_is_literal = false;
12714
12716 {
12717 /* Set up query for domain-specific details */
12719 "PREPARE dumpDomain(pg_catalog.oid) AS\n");
12720
12721 appendPQExpBufferStr(query, "SELECT t.typnotnull, "
12722 "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
12723 "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
12724 "t.typdefault, "
12725 "CASE WHEN t.typcollation <> u.typcollation "
12726 "THEN t.typcollation ELSE 0 END AS typcollation "
12727 "FROM pg_catalog.pg_type t "
12728 "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
12729 "WHERE t.oid = $1");
12730
12731 ExecuteSqlStatement(fout, query->data);
12732
12733 fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
12734 }
12735
12736 printfPQExpBuffer(query,
12737 "EXECUTE dumpDomain('%u')",
12738 tyinfo->dobj.catId.oid);
12739
12740 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12741
12742 typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
12743 typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
12744 if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
12745 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
12746 else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
12747 {
12748 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
12749 typdefault_is_literal = true; /* it needs quotes */
12750 }
12751 else
12752 typdefault = NULL;
12753 typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
12754
12755 if (dopt->binary_upgrade)
12757 tyinfo->dobj.catId.oid,
12758 true, /* force array type */
12759 false); /* force multirange type */
12760
12761 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12762 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12763
12765 "CREATE DOMAIN %s AS %s",
12766 qualtypname,
12767 typdefn);
12768
12769 /* Print collation only if different from base type's collation */
12770 if (OidIsValid(typcollation))
12771 {
12772 CollInfo *coll;
12773
12774 coll = findCollationByOid(typcollation);
12775 if (coll)
12776 appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
12777 }
12778
12779 /*
12780 * Print a not-null constraint if there's one. In servers older than 17
12781 * these don't have names, so just print it unadorned; in newer ones they
12782 * do, but most of the time it's going to be the standard generated one,
12783 * so omit the name in that case also.
12784 */
12785 if (typnotnull[0] == 't')
12786 {
12787 if (fout->remoteVersion < 170000 || tyinfo->notnull == NULL)
12788 appendPQExpBufferStr(q, " NOT NULL");
12789 else
12790 {
12791 ConstraintInfo *notnull = tyinfo->notnull;
12792
12793 if (!notnull->separate)
12794 {
12795 char *default_name;
12796
12797 /* XXX should match ChooseConstraintName better */
12798 default_name = psprintf("%s_not_null", tyinfo->dobj.name);
12799
12800 if (strcmp(default_name, notnull->dobj.name) == 0)
12801 appendPQExpBufferStr(q, " NOT NULL");
12802 else
12803 appendPQExpBuffer(q, " CONSTRAINT %s %s",
12804 fmtId(notnull->dobj.name), notnull->condef);
12805 free(default_name);
12806 }
12807 }
12808 }
12809
12810 if (typdefault != NULL)
12811 {
12812 appendPQExpBufferStr(q, " DEFAULT ");
12813 if (typdefault_is_literal)
12814 appendStringLiteralAH(q, typdefault, fout);
12815 else
12816 appendPQExpBufferStr(q, typdefault);
12817 }
12818
12819 PQclear(res);
12820
12821 /*
12822 * Add any CHECK constraints for the domain
12823 */
12824 for (i = 0; i < tyinfo->nDomChecks; i++)
12825 {
12826 ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
12827
12828 if (!domcheck->separate && domcheck->contype == 'c')
12829 appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
12830 fmtId(domcheck->dobj.name), domcheck->condef);
12831 }
12832
12833 appendPQExpBufferStr(q, ";\n");
12834
12835 appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
12836
12837 if (dopt->binary_upgrade)
12839 "DOMAIN", qtypname,
12840 tyinfo->dobj.namespace->dobj.name);
12841
12842 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12843 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12844 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12845 .namespace = tyinfo->dobj.namespace->dobj.name,
12846 .owner = tyinfo->rolname,
12847 .description = "DOMAIN",
12848 .section = SECTION_PRE_DATA,
12849 .createStmt = q->data,
12850 .dropStmt = delq->data));
12851
12852 /* Dump Domain Comments and Security Labels */
12853 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12854 dumpComment(fout, "DOMAIN", qtypname,
12855 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12856 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12857
12858 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12859 dumpSecLabel(fout, "DOMAIN", qtypname,
12860 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12861 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12862
12863 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12864 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12865 qtypname, NULL,
12866 tyinfo->dobj.namespace->dobj.name,
12867 NULL, tyinfo->rolname, &tyinfo->dacl);
12868
12869 /* Dump any per-constraint comments */
12870 for (i = 0; i < tyinfo->nDomChecks; i++)
12871 {
12872 ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
12873 PQExpBuffer conprefix;
12874
12875 /* but only if the constraint itself was dumped here */
12876 if (domcheck->separate)
12877 continue;
12878
12879 conprefix = createPQExpBuffer();
12880 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
12881 fmtId(domcheck->dobj.name));
12882
12883 if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
12884 dumpComment(fout, conprefix->data, qtypname,
12885 tyinfo->dobj.namespace->dobj.name,
12886 tyinfo->rolname,
12887 domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
12888
12889 destroyPQExpBuffer(conprefix);
12890 }
12891
12892 /*
12893 * And a comment on the not-null constraint, if there's one -- but only if
12894 * the constraint itself was dumped here
12895 */
12896 if (tyinfo->notnull != NULL && !tyinfo->notnull->separate)
12897 {
12898 PQExpBuffer conprefix = createPQExpBuffer();
12899
12900 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
12901 fmtId(tyinfo->notnull->dobj.name));
12902
12903 if (tyinfo->notnull->dobj.dump & DUMP_COMPONENT_COMMENT)
12904 dumpComment(fout, conprefix->data, qtypname,
12905 tyinfo->dobj.namespace->dobj.name,
12906 tyinfo->rolname,
12907 tyinfo->notnull->dobj.catId, 0, tyinfo->dobj.dumpId);
12908 destroyPQExpBuffer(conprefix);
12909 }
12910
12912 destroyPQExpBuffer(delq);
12913 destroyPQExpBuffer(query);
12914 free(qtypname);
12915 free(qualtypname);
12916}
@ PREPQUERY_DUMPDOMAIN
Definition: pg_backup.h:69
struct _constraintInfo * domChecks
Definition: pg_dump.h:229
int nDomChecks
Definition: pg_dump.h:228
struct _constraintInfo * notnull
Definition: pg_dump.h:226

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, _constraintInfo::contype, 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, _typeInfo::notnull, CatalogId::oid, OidIsValid, pg_strdup(), PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PREPQUERY_DUMPDOMAIN, printfPQExpBuffer(), psprintf(), Archive::remoteVersion, _typeInfo::rolname, SECTION_PRE_DATA, and _constraintInfo::separate.

Referenced by dumpType().

◆ dumpDumpableObject()

static void dumpDumpableObject ( Archive fout,
DumpableObject dobj 
)
static

Definition at line 11661 of file pg_dump.c.

11662{
11663 /*
11664 * Clear any dump-request bits for components that don't exist for this
11665 * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
11666 * request for every kind of object.)
11667 */
11668 dobj->dump &= dobj->components;
11669
11670 /* Now, short-circuit if there's nothing to be done here. */
11671 if (dobj->dump == 0)
11672 return;
11673
11674 switch (dobj->objType)
11675 {
11676 case DO_NAMESPACE:
11677 dumpNamespace(fout, (const NamespaceInfo *) dobj);
11678 break;
11679 case DO_EXTENSION:
11680 dumpExtension(fout, (const ExtensionInfo *) dobj);
11681 break;
11682 case DO_TYPE:
11683 dumpType(fout, (const TypeInfo *) dobj);
11684 break;
11685 case DO_SHELL_TYPE:
11686 dumpShellType(fout, (const ShellTypeInfo *) dobj);
11687 break;
11688 case DO_FUNC:
11689 dumpFunc(fout, (const FuncInfo *) dobj);
11690 break;
11691 case DO_AGG:
11692 dumpAgg(fout, (const AggInfo *) dobj);
11693 break;
11694 case DO_OPERATOR:
11695 dumpOpr(fout, (const OprInfo *) dobj);
11696 break;
11697 case DO_ACCESS_METHOD:
11698 dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
11699 break;
11700 case DO_OPCLASS:
11701 dumpOpclass(fout, (const OpclassInfo *) dobj);
11702 break;
11703 case DO_OPFAMILY:
11704 dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
11705 break;
11706 case DO_COLLATION:
11707 dumpCollation(fout, (const CollInfo *) dobj);
11708 break;
11709 case DO_CONVERSION:
11710 dumpConversion(fout, (const ConvInfo *) dobj);
11711 break;
11712 case DO_TABLE:
11713 dumpTable(fout, (const TableInfo *) dobj);
11714 break;
11715 case DO_TABLE_ATTACH:
11716 dumpTableAttach(fout, (const TableAttachInfo *) dobj);
11717 break;
11718 case DO_ATTRDEF:
11719 dumpAttrDef(fout, (const AttrDefInfo *) dobj);
11720 break;
11721 case DO_INDEX:
11722 dumpIndex(fout, (const IndxInfo *) dobj);
11723 break;
11724 case DO_INDEX_ATTACH:
11725 dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
11726 break;
11727 case DO_STATSEXT:
11728 dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
11729 break;
11730 case DO_REFRESH_MATVIEW:
11731 refreshMatViewData(fout, (const TableDataInfo *) dobj);
11732 break;
11733 case DO_RULE:
11734 dumpRule(fout, (const RuleInfo *) dobj);
11735 break;
11736 case DO_TRIGGER:
11737 dumpTrigger(fout, (const TriggerInfo *) dobj);
11738 break;
11739 case DO_EVENT_TRIGGER:
11740 dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
11741 break;
11742 case DO_CONSTRAINT:
11743 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11744 break;
11745 case DO_FK_CONSTRAINT:
11746 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11747 break;
11748 case DO_PROCLANG:
11749 dumpProcLang(fout, (const ProcLangInfo *) dobj);
11750 break;
11751 case DO_CAST:
11752 dumpCast(fout, (const CastInfo *) dobj);
11753 break;
11754 case DO_TRANSFORM:
11755 dumpTransform(fout, (const TransformInfo *) dobj);
11756 break;
11757 case DO_SEQUENCE_SET:
11758 dumpSequenceData(fout, (const TableDataInfo *) dobj);
11759 break;
11760 case DO_TABLE_DATA:
11761 dumpTableData(fout, (const TableDataInfo *) dobj);
11762 break;
11763 case DO_DUMMY_TYPE:
11764 /* table rowtypes and array types are never dumped separately */
11765 break;
11766 case DO_TSPARSER:
11767 dumpTSParser(fout, (const TSParserInfo *) dobj);
11768 break;
11769 case DO_TSDICT:
11770 dumpTSDictionary(fout, (const TSDictInfo *) dobj);
11771 break;
11772 case DO_TSTEMPLATE:
11773 dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
11774 break;
11775 case DO_TSCONFIG:
11776 dumpTSConfig(fout, (const TSConfigInfo *) dobj);
11777 break;
11778 case DO_FDW:
11779 dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
11780 break;
11781 case DO_FOREIGN_SERVER:
11782 dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
11783 break;
11784 case DO_DEFAULT_ACL:
11785 dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
11786 break;
11787 case DO_LARGE_OBJECT:
11788 dumpLO(fout, (const LoInfo *) dobj);
11789 break;
11791 if (dobj->dump & DUMP_COMPONENT_DATA)
11792 {
11793 LoInfo *loinfo;
11794 TocEntry *te;
11795
11796 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
11797 if (loinfo == NULL)
11798 pg_fatal("missing metadata for large objects \"%s\"",
11799 dobj->name);
11800
11801 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
11802 ARCHIVE_OPTS(.tag = dobj->name,
11803 .owner = loinfo->rolname,
11804 .description = "BLOBS",
11805 .section = SECTION_DATA,
11806 .deps = dobj->dependencies,
11807 .nDeps = dobj->nDeps,
11808 .dumpFn = dumpLOs,
11809 .dumpArg = loinfo));
11810
11811 /*
11812 * Set the TocEntry's dataLength in case we are doing a
11813 * parallel dump and want to order dump jobs by table size.
11814 * (We need some size estimate for every TocEntry with a
11815 * DataDumper function.) We don't currently have any cheap
11816 * way to estimate the size of LOs, but fortunately it doesn't
11817 * matter too much as long as we get large batches of LOs
11818 * processed reasonably early. Assume 8K per blob.
11819 */
11820 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
11821 }
11822 break;
11823 case DO_POLICY:
11824 dumpPolicy(fout, (const PolicyInfo *) dobj);
11825 break;
11826 case DO_PUBLICATION:
11827 dumpPublication(fout, (const PublicationInfo *) dobj);
11828 break;
11829 case DO_PUBLICATION_REL:
11830 dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
11831 break;
11834 (const PublicationSchemaInfo *) dobj);
11835 break;
11836 case DO_SUBSCRIPTION:
11837 dumpSubscription(fout, (const SubscriptionInfo *) dobj);
11838 break;
11840 dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
11841 break;
11842 case DO_REL_STATS:
11843 dumpRelationStats(fout, (const RelStatsInfo *) dobj);
11844 break;
11847 /* never dumped, nothing to do */
11848 break;
11849 }
11850}
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:18175
static void dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
Definition: pg_dump.c:4963
static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
Definition: pg_dump.c:11857
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:13871
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:18265
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:15794
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:15370
static void dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
Definition: pg_dump.c:11375
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:19303
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16863
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:18459
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:18536
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12057
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:18107
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:14417
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:14105
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:19226
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:13449
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:16122
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2870
static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
Definition: pg_dump.c:13219
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2985
static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
Definition: pg_dump.c:4653
static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
Definition: pg_dump.c:4419
static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
Definition: pg_dump.c:14766
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:16316
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:15874
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:18416
static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
Definition: pg_dump.c:5413
static void dumpTransform(Archive *fout, const TransformInfo *transform)
Definition: pg_dump.c:13976
static void dumpLO(Archive *fout, const LoInfo *loinfo)
Definition: pg_dump.c:4111
static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
Definition: pg_dump.c:5006
static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
Definition: pg_dump.c:15730
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:19519
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:11934
static int dumpLOs(Archive *fout, const void *arg)
Definition: pg_dump.c:4201
static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
Definition: pg_dump.c:5482
static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
Definition: pg_dump.c:19429
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:15242
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:16052
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:13265
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:15932
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:14985
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:14485
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:110
#define pgoff_t
Definition: port.h:421
const char * rolname
Definition: pg_dump.h:641
int numlos
Definition: pg_dump.h:642
pgoff_t dataLength

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_REL_STATS, 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(), dumpRelationStats(), 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 3835 of file pg_dump.c.

3836{
3837 const char *encname = pg_encoding_to_char(AH->encoding);
3839
3840 pg_log_info("saving encoding = %s", encname);
3841
3842 appendPQExpBufferStr(qry, "SET client_encoding = ");
3843 appendStringLiteralAH(qry, encname, AH);
3844 appendPQExpBufferStr(qry, ";\n");
3845
3847 ARCHIVE_OPTS(.tag = "ENCODING",
3848 .description = "ENCODING",
3849 .section = SECTION_PRE_DATA,
3850 .createStmt = qry->data));
3851
3852 destroyPQExpBuffer(qry);
3853}
#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 12088 of file pg_dump.c.

12089{
12090 DumpOptions *dopt = fout->dopt;
12094 PGresult *res;
12095 int num,
12096 i;
12097 Oid enum_oid;
12098 char *qtypname;
12099 char *qualtypname;
12100 char *label;
12101 int i_enumlabel;
12102 int i_oid;
12103
12105 {
12106 /* Set up query for enum-specific details */
12108 "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
12109 "SELECT oid, enumlabel "
12110 "FROM pg_catalog.pg_enum "
12111 "WHERE enumtypid = $1 "
12112 "ORDER BY enumsortorder");
12113
12114 ExecuteSqlStatement(fout, query->data);
12115
12116 fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
12117 }
12118
12119 printfPQExpBuffer(query,
12120 "EXECUTE dumpEnumType('%u')",
12121 tyinfo->dobj.catId.oid);
12122
12123 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12124
12125 num = PQntuples(res);
12126
12127 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12128 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12129
12130 /*
12131 * CASCADE shouldn't be required here as for normal types since the I/O
12132 * functions are generic and do not get dropped.
12133 */
12134 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12135
12136 if (dopt->binary_upgrade)
12138 tyinfo->dobj.catId.oid,
12139 false, false);
12140
12141 appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
12142 qualtypname);
12143
12144 if (!dopt->binary_upgrade)
12145 {
12146 i_enumlabel = PQfnumber(res, "enumlabel");
12147
12148 /* Labels with server-assigned oids */
12149 for (i = 0; i < num; i++)
12150 {
12151 label = PQgetvalue(res, i, i_enumlabel);
12152 if (i > 0)
12153 appendPQExpBufferChar(q, ',');
12154 appendPQExpBufferStr(q, "\n ");
12155 appendStringLiteralAH(q, label, fout);
12156 }
12157 }
12158
12159 appendPQExpBufferStr(q, "\n);\n");
12160
12161 if (dopt->binary_upgrade)
12162 {
12163 i_oid = PQfnumber(res, "oid");
12164 i_enumlabel = PQfnumber(res, "enumlabel");
12165
12166 /* Labels with dump-assigned (preserved) oids */
12167 for (i = 0; i < num; i++)
12168 {
12169 enum_oid = atooid(PQgetvalue(res, i, i_oid));
12170 label = PQgetvalue(res, i, i_enumlabel);
12171
12172 if (i == 0)
12173 appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
12175 "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
12176 enum_oid);
12177 appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
12178 appendStringLiteralAH(q, label, fout);
12179 appendPQExpBufferStr(q, ";\n\n");
12180 }
12181 }
12182
12183 if (dopt->binary_upgrade)
12185 "TYPE", qtypname,
12186 tyinfo->dobj.namespace->dobj.name);
12187
12188 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12189 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12190 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12191 .namespace = tyinfo->dobj.namespace->dobj.name,
12192 .owner = tyinfo->rolname,
12193 .description = "TYPE",
12194 .section = SECTION_PRE_DATA,
12195 .createStmt = q->data,
12196 .dropStmt = delq->data));
12197
12198 /* Dump Type Comments and Security Labels */
12199 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12200 dumpComment(fout, "TYPE", qtypname,
12201 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12202 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12203
12204 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12205 dumpSecLabel(fout, "TYPE", qtypname,
12206 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12207 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12208
12209 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12210 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12211 qtypname, NULL,
12212 tyinfo->dobj.namespace->dobj.name,
12213 NULL, tyinfo->rolname, &tyinfo->dacl);
12214
12215 PQclear(res);
12217 destroyPQExpBuffer(delq);
12218 destroyPQExpBuffer(query);
12219 free(qtypname);
12220 free(qualtypname);
12221}
@ 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(), _typeInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpType().

◆ dumpEventTrigger()

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

Definition at line 19429 of file pg_dump.c.

19430{
19431 DumpOptions *dopt = fout->dopt;
19432 PQExpBuffer query;
19433 PQExpBuffer delqry;
19434 char *qevtname;
19435
19436 /* Do nothing if not dumping schema */
19437 if (!dopt->dumpSchema)
19438 return;
19439
19440 query = createPQExpBuffer();
19441 delqry = createPQExpBuffer();
19442
19443 qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
19444
19445 appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
19446 appendPQExpBufferStr(query, qevtname);
19447 appendPQExpBufferStr(query, " ON ");
19448 appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
19449
19450 if (strcmp("", evtinfo->evttags) != 0)
19451 {
19452 appendPQExpBufferStr(query, "\n WHEN TAG IN (");
19453 appendPQExpBufferStr(query, evtinfo->evttags);
19454 appendPQExpBufferChar(query, ')');
19455 }
19456
19457 appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
19458 appendPQExpBufferStr(query, evtinfo->evtfname);
19459 appendPQExpBufferStr(query, "();\n");
19460
19461 if (evtinfo->evtenabled != 'O')
19462 {
19463 appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
19464 qevtname);
19465 switch (evtinfo->evtenabled)
19466 {
19467 case 'D':
19468 appendPQExpBufferStr(query, "DISABLE");
19469 break;
19470 case 'A':
19471 appendPQExpBufferStr(query, "ENABLE ALWAYS");
19472 break;
19473 case 'R':
19474 appendPQExpBufferStr(query, "ENABLE REPLICA");
19475 break;
19476 default:
19477 appendPQExpBufferStr(query, "ENABLE");
19478 break;
19479 }
19480 appendPQExpBufferStr(query, ";\n");
19481 }
19482
19483 appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
19484 qevtname);
19485
19486 if (dopt->binary_upgrade)
19487 binary_upgrade_extension_member(query, &evtinfo->dobj,
19488 "EVENT TRIGGER", qevtname, NULL);
19489
19490 if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19491 ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
19492 ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
19493 .owner = evtinfo->evtowner,
19494 .description = "EVENT TRIGGER",
19495 .section = SECTION_POST_DATA,
19496 .createStmt = query->data,
19497 .dropStmt = delqry->data));
19498
19499 if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19500 dumpComment(fout, "EVENT TRIGGER", qevtname,
19501 NULL, evtinfo->evtowner,
19502 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
19503
19504 if (evtinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
19505 dumpSecLabel(fout, "EVENT TRIGGER", qevtname,
19506 NULL, evtinfo->evtowner,
19507 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
19508
19509 destroyPQExpBuffer(query);
19510 destroyPQExpBuffer(delqry);
19511 free(qevtname);
19512}
char * evtevent
Definition: pg_dump.h:498
char * evtfname
Definition: pg_dump.h:501
char evtenabled
Definition: pg_dump.h:502
const char * evtowner
Definition: pg_dump.h:499
char * evttags
Definition: pg_dump.h:500
DumpableObject dobj
Definition: pg_dump.h:496

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _evttriggerInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, dumpSecLabel(), _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 11934 of file pg_dump.c.

11935{
11936 DumpOptions *dopt = fout->dopt;
11937 PQExpBuffer q;
11938 PQExpBuffer delq;
11939 char *qextname;
11940
11941 /* Do nothing if not dumping schema */
11942 if (!dopt->dumpSchema)
11943 return;
11944
11945 q = createPQExpBuffer();
11946 delq = createPQExpBuffer();
11947
11948 qextname = pg_strdup(fmtId(extinfo->dobj.name));
11949
11950 appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
11951
11952 if (!dopt->binary_upgrade)
11953 {
11954 /*
11955 * In a regular dump, we simply create the extension, intentionally
11956 * not specifying a version, so that the destination installation's
11957 * default version is used.
11958 *
11959 * Use of IF NOT EXISTS here is unlike our behavior for other object
11960 * types; but there are various scenarios in which it's convenient to
11961 * manually create the desired extension before restoring, so we
11962 * prefer to allow it to exist already.
11963 */
11964 appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
11965 qextname, fmtId(extinfo->namespace));
11966 }
11967 else
11968 {
11969 /*
11970 * In binary-upgrade mode, it's critical to reproduce the state of the
11971 * database exactly, so our procedure is to create an empty extension,
11972 * restore all the contained objects normally, and add them to the
11973 * extension one by one. This function performs just the first of
11974 * those steps. binary_upgrade_extension_member() takes care of
11975 * adding member objects as they're created.
11976 */
11977 int i;
11978 int n;
11979
11980 appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
11981
11982 /*
11983 * We unconditionally create the extension, so we must drop it if it
11984 * exists. This could happen if the user deleted 'plpgsql' and then
11985 * readded it, causing its oid to be greater than g_last_builtin_oid.
11986 */
11987 appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
11988
11990 "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
11991 appendStringLiteralAH(q, extinfo->dobj.name, fout);
11992 appendPQExpBufferStr(q, ", ");
11993 appendStringLiteralAH(q, extinfo->namespace, fout);
11994 appendPQExpBufferStr(q, ", ");
11995 appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
11996 appendStringLiteralAH(q, extinfo->extversion, fout);
11997 appendPQExpBufferStr(q, ", ");
11998
11999 /*
12000 * Note that we're pushing extconfig (an OID array) back into
12001 * pg_extension exactly as-is. This is OK because pg_class OIDs are
12002 * preserved in binary upgrade.
12003 */
12004 if (strlen(extinfo->extconfig) > 2)
12005 appendStringLiteralAH(q, extinfo->extconfig, fout);
12006 else
12007 appendPQExpBufferStr(q, "NULL");
12008 appendPQExpBufferStr(q, ", ");
12009 if (strlen(extinfo->extcondition) > 2)
12010 appendStringLiteralAH(q, extinfo->extcondition, fout);
12011 else
12012 appendPQExpBufferStr(q, "NULL");
12013 appendPQExpBufferStr(q, ", ");
12014 appendPQExpBufferStr(q, "ARRAY[");
12015 n = 0;
12016 for (i = 0; i < extinfo->dobj.nDeps; i++)
12017 {
12018 DumpableObject *extobj;
12019
12020 extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
12021 if (extobj && extobj->objType == DO_EXTENSION)
12022 {
12023 if (n++ > 0)
12024 appendPQExpBufferChar(q, ',');
12025 appendStringLiteralAH(q, extobj->name, fout);
12026 }
12027 }
12028 appendPQExpBufferStr(q, "]::pg_catalog.text[]");
12029 appendPQExpBufferStr(q, ");\n");
12030 }
12031
12032 if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12033 ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
12034 ARCHIVE_OPTS(.tag = extinfo->dobj.name,
12035 .description = "EXTENSION",
12036 .section = SECTION_PRE_DATA,
12037 .createStmt = q->data,
12038 .dropStmt = delq->data));
12039
12040 /* Dump Extension Comments */
12041 if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12042 dumpComment(fout, "EXTENSION", qextname,
12043 NULL, "",
12044 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
12045
12046 free(qextname);
12047
12049 destroyPQExpBuffer(delq);
12050}
bool relocatable
Definition: pg_dump.h:196
char * extversion
Definition: pg_dump.h:198
char * extcondition
Definition: pg_dump.h:200
char * extconfig
Definition: pg_dump.h:199

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpableObject::dependencies, destroyPQExpBuffer(), DO_EXTENSION, _extensionInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, _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 16052 of file pg_dump.c.

16053{
16054 DumpOptions *dopt = fout->dopt;
16055 PQExpBuffer q;
16056 PQExpBuffer delq;
16057 char *qfdwname;
16058
16059 /* Do nothing if not dumping schema */
16060 if (!dopt->dumpSchema)
16061 return;
16062
16063 q = createPQExpBuffer();
16064 delq = createPQExpBuffer();
16065
16066 qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
16067
16068 appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
16069 qfdwname);
16070
16071 if (strcmp(fdwinfo->fdwhandler, "-") != 0)
16072 appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
16073
16074 if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
16075 appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
16076
16077 if (strlen(fdwinfo->fdwoptions) > 0)
16078 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
16079
16080 appendPQExpBufferStr(q, ";\n");
16081
16082 appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
16083 qfdwname);
16084
16085 if (dopt->binary_upgrade)
16087 "FOREIGN DATA WRAPPER", qfdwname,
16088 NULL);
16089
16090 if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16091 ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
16092 ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
16093 .owner = fdwinfo->rolname,
16094 .description = "FOREIGN DATA WRAPPER",
16095 .section = SECTION_PRE_DATA,
16096 .createStmt = q->data,
16097 .dropStmt = delq->data));
16098
16099 /* Dump Foreign Data Wrapper Comments */
16100 if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16101 dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
16102 NULL, fdwinfo->rolname,
16103 fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
16104
16105 /* Handle the ACL */
16106 if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
16107 dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
16108 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
16109 NULL, fdwinfo->rolname, &fdwinfo->dacl);
16110
16111 free(qfdwname);
16112
16114 destroyPQExpBuffer(delq);
16115}
char * fdwhandler
Definition: pg_dump.h:605
const char * rolname
Definition: pg_dump.h:604
char * fdwvalidator
Definition: pg_dump.h:606
char * fdwoptions
Definition: pg_dump.h:607
DumpableAcl dacl
Definition: pg_dump.h:603
DumpableObject dobj
Definition: pg_dump.h:602

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _fdwInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _fdwInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpACL(), dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, _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 16122 of file pg_dump.c.

16123{
16124 DumpOptions *dopt = fout->dopt;
16125 PQExpBuffer q;
16126 PQExpBuffer delq;
16127 PQExpBuffer query;
16128 PGresult *res;
16129 char *qsrvname;
16130 char *fdwname;
16131
16132 /* Do nothing if not dumping schema */
16133 if (!dopt->dumpSchema)
16134 return;
16135
16136 q = createPQExpBuffer();
16137 delq = createPQExpBuffer();
16138 query = createPQExpBuffer();
16139
16140 qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
16141
16142 /* look up the foreign-data wrapper */
16143 appendPQExpBuffer(query, "SELECT fdwname "
16144 "FROM pg_foreign_data_wrapper w "
16145 "WHERE w.oid = '%u'",
16146 srvinfo->srvfdw);
16147 res = ExecuteSqlQueryForSingleRow(fout, query->data);
16148 fdwname = PQgetvalue(res, 0, 0);
16149
16150 appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
16151 if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
16152 {
16153 appendPQExpBufferStr(q, " TYPE ");
16154 appendStringLiteralAH(q, srvinfo->srvtype, fout);
16155 }
16156 if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
16157 {
16158 appendPQExpBufferStr(q, " VERSION ");
16159 appendStringLiteralAH(q, srvinfo->srvversion, fout);
16160 }
16161
16162 appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
16163 appendPQExpBufferStr(q, fmtId(fdwname));
16164
16165 if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
16166 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
16167
16168 appendPQExpBufferStr(q, ";\n");
16169
16170 appendPQExpBuffer(delq, "DROP SERVER %s;\n",
16171 qsrvname);
16172
16173 if (dopt->binary_upgrade)
16175 "SERVER", qsrvname, NULL);
16176
16177 if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16178 ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
16179 ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
16180 .owner = srvinfo->rolname,
16181 .description = "SERVER",
16182 .section = SECTION_PRE_DATA,
16183 .createStmt = q->data,
16184 .dropStmt = delq->data));
16185
16186 /* Dump Foreign Server Comments */
16187 if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16188 dumpComment(fout, "SERVER", qsrvname,
16189 NULL, srvinfo->rolname,
16190 srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
16191
16192 /* Handle the ACL */
16193 if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
16194 dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
16195 "FOREIGN SERVER", qsrvname, NULL, NULL,
16196 NULL, srvinfo->rolname, &srvinfo->dacl);
16197
16198 /* Dump user mappings */
16199 if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
16200 dumpUserMappings(fout,
16201 srvinfo->dobj.name, NULL,
16202 srvinfo->rolname,
16203 srvinfo->dobj.catId, srvinfo->dobj.dumpId);
16204
16205 PQclear(res);
16206
16207 free(qsrvname);
16208
16210 destroyPQExpBuffer(delq);
16211 destroyPQExpBuffer(query);
16212}
static void dumpUserMappings(Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
Definition: pg_dump.c:16222
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:115
DumpableAcl dacl
Definition: pg_dump.h:613
char * srvoptions
Definition: pg_dump.h:618
DumpableObject dobj
Definition: pg_dump.h:612
const char * rolname
Definition: pg_dump.h:614
char * srvversion
Definition: pg_dump.h:617

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _foreignServerInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _foreignServerInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_USERMAP, dumpACL(), dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, dumpUserMappings(), ExecuteSqlQueryForSingleRow(), fmtId(), free, InvalidDumpId, _dumpableObject::name, pg_strdup(), PQclear, PQgetvalue, _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 13449 of file pg_dump.c.

13450{
13451 DumpOptions *dopt = fout->dopt;
13452 PQExpBuffer query;
13453 PQExpBuffer q;
13454 PQExpBuffer delqry;
13455 PQExpBuffer asPart;
13456 PGresult *res;
13457 char *funcsig; /* identity signature */
13458 char *funcfullsig = NULL; /* full signature */
13459 char *funcsig_tag;
13460 char *qual_funcsig;
13461 char *proretset;
13462 char *prosrc;
13463 char *probin;
13464 char *prosqlbody;
13465 char *funcargs;
13466 char *funciargs;
13467 char *funcresult;
13468 char *protrftypes;
13469 char *prokind;
13470 char *provolatile;
13471 char *proisstrict;
13472 char *prosecdef;
13473 char *proleakproof;
13474 char *proconfig;
13475 char *procost;
13476 char *prorows;
13477 char *prosupport;
13478 char *proparallel;
13479 char *lanname;
13480 char **configitems = NULL;
13481 int nconfigitems = 0;
13482 const char *keyword;
13483
13484 /* Do nothing if not dumping schema */
13485 if (!dopt->dumpSchema)
13486 return;
13487
13488 query = createPQExpBuffer();
13489 q = createPQExpBuffer();
13490 delqry = createPQExpBuffer();
13491 asPart = createPQExpBuffer();
13492
13493 if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
13494 {
13495 /* Set up query for function-specific details */
13497 "PREPARE dumpFunc(pg_catalog.oid) AS\n");
13498
13500 "SELECT\n"
13501 "proretset,\n"
13502 "prosrc,\n"
13503 "probin,\n"
13504 "provolatile,\n"
13505 "proisstrict,\n"
13506 "prosecdef,\n"
13507 "lanname,\n"
13508 "proconfig,\n"
13509 "procost,\n"
13510 "prorows,\n"
13511 "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
13512 "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
13513 "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
13514 "proleakproof,\n");
13515
13516 if (fout->remoteVersion >= 90500)
13518 "array_to_string(protrftypes, ' ') AS protrftypes,\n");
13519 else
13521 "NULL AS protrftypes,\n");
13522
13523 if (fout->remoteVersion >= 90600)
13525 "proparallel,\n");
13526 else
13528 "'u' AS proparallel,\n");
13529
13530 if (fout->remoteVersion >= 110000)
13532 "prokind,\n");
13533 else
13535 "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
13536
13537 if (fout->remoteVersion >= 120000)
13539 "prosupport,\n");
13540 else
13542 "'-' AS prosupport,\n");
13543
13544 if (fout->remoteVersion >= 140000)
13546 "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
13547 else
13549 "NULL AS prosqlbody\n");
13550
13552 "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
13553 "WHERE p.oid = $1 "
13554 "AND l.oid = p.prolang");
13555
13556 ExecuteSqlStatement(fout, query->data);
13557
13558 fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
13559 }
13560
13561 printfPQExpBuffer(query,
13562 "EXECUTE dumpFunc('%u')",
13563 finfo->dobj.catId.oid);
13564
13565 res = ExecuteSqlQueryForSingleRow(fout, query->data);
13566
13567 proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
13568 if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
13569 {
13570 prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
13571 probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
13572 prosqlbody = NULL;
13573 }
13574 else
13575 {
13576 prosrc = NULL;
13577 probin = NULL;
13578 prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
13579 }
13580 funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
13581 funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
13582 funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
13583 protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
13584 prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
13585 provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
13586 proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
13587 prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
13588 proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
13589 proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
13590 procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
13591 prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
13592 prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
13593 proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
13594 lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
13595
13596 /*
13597 * See backend/commands/functioncmds.c for details of how the 'AS' clause
13598 * is used.
13599 */
13600 if (prosqlbody)
13601 {
13602 appendPQExpBufferStr(asPart, prosqlbody);
13603 }
13604 else if (probin[0] != '\0')
13605 {
13606 appendPQExpBufferStr(asPart, "AS ");
13607 appendStringLiteralAH(asPart, probin, fout);
13608 if (prosrc[0] != '\0')
13609 {
13610 appendPQExpBufferStr(asPart, ", ");
13611
13612 /*
13613 * where we have bin, use dollar quoting if allowed and src
13614 * contains quote or backslash; else use regular quoting.
13615 */
13616 if (dopt->disable_dollar_quoting ||
13617 (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
13618 appendStringLiteralAH(asPart, prosrc, fout);
13619 else
13620 appendStringLiteralDQ(asPart, prosrc, NULL);
13621 }
13622 }
13623 else
13624 {
13625 appendPQExpBufferStr(asPart, "AS ");
13626 /* with no bin, dollar quote src unconditionally if allowed */
13627 if (dopt->disable_dollar_quoting)
13628 appendStringLiteralAH(asPart, prosrc, fout);
13629 else
13630 appendStringLiteralDQ(asPart, prosrc, NULL);
13631 }
13632
13633 if (*proconfig)
13634 {
13635 if (!parsePGArray(proconfig, &configitems, &nconfigitems))
13636 pg_fatal("could not parse %s array", "proconfig");
13637 }
13638 else
13639 {
13640 configitems = NULL;
13641 nconfigitems = 0;
13642 }
13643
13644 funcfullsig = format_function_arguments(finfo, funcargs, false);
13645 funcsig = format_function_arguments(finfo, funciargs, false);
13646
13647 funcsig_tag = format_function_signature(fout, finfo, false);
13648
13649 qual_funcsig = psprintf("%s.%s",
13650 fmtId(finfo->dobj.namespace->dobj.name),
13651 funcsig);
13652
13653 if (prokind[0] == PROKIND_PROCEDURE)
13654 keyword = "PROCEDURE";
13655 else
13656 keyword = "FUNCTION"; /* works for window functions too */
13657
13658 appendPQExpBuffer(delqry, "DROP %s %s;\n",
13659 keyword, qual_funcsig);
13660
13661 appendPQExpBuffer(q, "CREATE %s %s.%s",
13662 keyword,
13663 fmtId(finfo->dobj.namespace->dobj.name),
13664 funcfullsig ? funcfullsig :
13665 funcsig);
13666
13667 if (prokind[0] == PROKIND_PROCEDURE)
13668 /* no result type to output */ ;
13669 else if (funcresult)
13670 appendPQExpBuffer(q, " RETURNS %s", funcresult);
13671 else
13672 appendPQExpBuffer(q, " RETURNS %s%s",
13673 (proretset[0] == 't') ? "SETOF " : "",
13674 getFormattedTypeName(fout, finfo->prorettype,
13675 zeroIsError));
13676
13677 appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
13678
13679 if (*protrftypes)
13680 {
13681 Oid *typeids = pg_malloc(FUNC_MAX_ARGS * sizeof(Oid));
13682 int i;
13683
13684 appendPQExpBufferStr(q, " TRANSFORM ");
13685 parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
13686 for (i = 0; typeids[i]; i++)
13687 {
13688 if (i != 0)
13689 appendPQExpBufferStr(q, ", ");
13690 appendPQExpBuffer(q, "FOR TYPE %s",
13691 getFormattedTypeName(fout, typeids[i], zeroAsNone));
13692 }
13693
13694 free(typeids);
13695 }
13696
13697 if (prokind[0] == PROKIND_WINDOW)
13698 appendPQExpBufferStr(q, " WINDOW");
13699
13700 if (provolatile[0] != PROVOLATILE_VOLATILE)
13701 {
13702 if (provolatile[0] == PROVOLATILE_IMMUTABLE)
13703 appendPQExpBufferStr(q, " IMMUTABLE");
13704 else if (provolatile[0] == PROVOLATILE_STABLE)
13705 appendPQExpBufferStr(q, " STABLE");
13706 else if (provolatile[0] != PROVOLATILE_VOLATILE)
13707 pg_fatal("unrecognized provolatile value for function \"%s\"",
13708 finfo->dobj.name);
13709 }
13710
13711 if (proisstrict[0] == 't')
13712 appendPQExpBufferStr(q, " STRICT");
13713
13714 if (prosecdef[0] == 't')
13715 appendPQExpBufferStr(q, " SECURITY DEFINER");
13716
13717 if (proleakproof[0] == 't')
13718 appendPQExpBufferStr(q, " LEAKPROOF");
13719
13720 /*
13721 * COST and ROWS are emitted only if present and not default, so as not to
13722 * break backwards-compatibility of the dump without need. Keep this code
13723 * in sync with the defaults in functioncmds.c.
13724 */
13725 if (strcmp(procost, "0") != 0)
13726 {
13727 if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
13728 {
13729 /* default cost is 1 */
13730 if (strcmp(procost, "1") != 0)
13731 appendPQExpBuffer(q, " COST %s", procost);
13732 }
13733 else
13734 {
13735 /* default cost is 100 */
13736 if (strcmp(procost, "100") != 0)
13737 appendPQExpBuffer(q, " COST %s", procost);
13738 }
13739 }
13740 if (proretset[0] == 't' &&
13741 strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
13742 appendPQExpBuffer(q, " ROWS %s", prorows);
13743
13744 if (strcmp(prosupport, "-") != 0)
13745 {
13746 /* We rely on regprocout to provide quoting and qualification */
13747 appendPQExpBuffer(q, " SUPPORT %s", prosupport);
13748 }
13749
13750 if (proparallel[0] != PROPARALLEL_UNSAFE)
13751 {
13752 if (proparallel[0] == PROPARALLEL_SAFE)
13753 appendPQExpBufferStr(q, " PARALLEL SAFE");
13754 else if (proparallel[0] == PROPARALLEL_RESTRICTED)
13755 appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
13756 else if (proparallel[0] != PROPARALLEL_UNSAFE)
13757 pg_fatal("unrecognized proparallel value for function \"%s\"",
13758 finfo->dobj.name);
13759 }
13760
13761 for (int i = 0; i < nconfigitems; i++)
13762 {
13763 /* we feel free to scribble on configitems[] here */
13764 char *configitem = configitems[i];
13765 char *pos;
13766
13767 pos = strchr(configitem, '=');
13768 if (pos == NULL)
13769 continue;
13770 *pos++ = '\0';
13771 appendPQExpBuffer(q, "\n SET %s TO ", fmtId(configitem));
13772
13773 /*
13774 * Variables that are marked GUC_LIST_QUOTE were already fully quoted
13775 * by flatten_set_variable_args() before they were put into the
13776 * proconfig array. However, because the quoting rules used there
13777 * aren't exactly like SQL's, we have to break the list value apart
13778 * and then quote the elements as string literals. (The elements may
13779 * be double-quoted as-is, but we can't just feed them to the SQL
13780 * parser; it would do the wrong thing with elements that are
13781 * zero-length or longer than NAMEDATALEN.) Also, we need a special
13782 * case for empty lists.
13783 *
13784 * Variables that are not so marked should just be emitted as simple
13785 * string literals. If the variable is not known to
13786 * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
13787 * to use GUC_LIST_QUOTE for extension variables.
13788 */
13789 if (variable_is_guc_list_quote(configitem))
13790 {
13791 char **namelist;
13792 char **nameptr;
13793
13794 /* Parse string into list of identifiers */
13795 /* this shouldn't fail really */
13796 if (SplitGUCList(pos, ',', &namelist))
13797 {
13798 /* Special case: represent an empty list as NULL */
13799 if (*namelist == NULL)
13800 appendPQExpBufferStr(q, "NULL");
13801 for (nameptr = namelist; *nameptr; nameptr++)
13802 {
13803 if (nameptr != namelist)
13804 appendPQExpBufferStr(q, ", ");
13805 appendStringLiteralAH(q, *nameptr, fout);
13806 }
13807 }
13808 pg_free(namelist);
13809 }
13810 else
13811 appendStringLiteralAH(q, pos, fout);
13812 }
13813
13814 appendPQExpBuffer(q, "\n %s;\n", asPart->data);
13815
13816 append_depends_on_extension(fout, q, &finfo->dobj,
13817 "pg_catalog.pg_proc", keyword,
13818 qual_funcsig);
13819
13820 if (dopt->binary_upgrade)
13822 keyword, funcsig,
13823 finfo->dobj.namespace->dobj.name);
13824
13825 if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13826 ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
13827 ARCHIVE_OPTS(.tag = funcsig_tag,
13828 .namespace = finfo->dobj.namespace->dobj.name,
13829 .owner = finfo->rolname,
13830 .description = keyword,
13831 .section = finfo->postponed_def ?
13833 .createStmt = q->data,
13834 .dropStmt = delqry->data));
13835
13836 /* Dump Function Comments and Security Labels */
13837 if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13838 dumpComment(fout, keyword, funcsig,
13839 finfo->dobj.namespace->dobj.name, finfo->rolname,
13840 finfo->dobj.catId, 0, finfo->dobj.dumpId);
13841
13842 if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
13843 dumpSecLabel(fout, keyword, funcsig,
13844 finfo->dobj.namespace->dobj.name, finfo->rolname,
13845 finfo->dobj.catId, 0, finfo->dobj.dumpId);
13846
13847 if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
13848 dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
13849 funcsig, NULL,
13850 finfo->dobj.namespace->dobj.name,
13851 NULL, finfo->rolname, &finfo->dacl);
13852
13853 PQclear(res);
13854
13855 destroyPQExpBuffer(query);
13857 destroyPQExpBuffer(delqry);
13858 destroyPQExpBuffer(asPart);
13859 free(funcsig);
13860 free(funcfullsig);
13861 free(funcsig_tag);
13862 free(qual_funcsig);
13863 free(configitems);
13864}
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1111
bool variable_is_guc_list_quote(const char *name)
Definition: dumputils.c:730
@ PREPQUERY_DUMPFUNC
Definition: pg_backup.h:71
#define FUNC_MAX_ARGS
bool parsePGArray(const char *atext, char ***itemarray, int *nitems)
Definition: string_utils.c:819
void appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
Definition: string_utils.c:484
int disable_dollar_quoting
Definition: pg_backup.h:183
bool postponed_def
Definition: pg_dump.h:248
const char * rolname
Definition: pg_dump.h:243
Oid prorettype
Definition: pg_dump.h:247
DumpableAcl dacl
Definition: pg_dump.h:242
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3003

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, 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, _dumpOptions::dumpSchema, dumpSecLabel(), ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), fmtId(), format_function_arguments(), format_function_signature(), free, FUNC_MAX_ARGS, getFormattedTypeName(), i, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, parseOidArray(), parsePGArray(), pg_fatal, pg_free(), pg_malloc(), _funcInfo::postponed_def, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PREPQUERY_DUMPFUNC, printfPQExpBuffer(), _funcInfo::prorettype, psprintf(), Archive::remoteVersion, _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 18265 of file pg_dump.c.

18266{
18267 DumpOptions *dopt = fout->dopt;
18268 TableInfo *tbinfo = indxinfo->indextable;
18269 bool is_constraint = (indxinfo->indexconstraint != 0);
18270 PQExpBuffer q;
18271 PQExpBuffer delq;
18272 char *qindxname;
18273 char *qqindxname;
18274
18275 /* Do nothing if not dumping schema */
18276 if (!dopt->dumpSchema)
18277 return;
18278
18279 q = createPQExpBuffer();
18280 delq = createPQExpBuffer();
18281
18282 qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
18283 qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
18284
18285 /*
18286 * If there's an associated constraint, don't dump the index per se, but
18287 * do dump any comment for it. (This is safe because dependency ordering
18288 * will have ensured the constraint is emitted first.) Note that the
18289 * emitted comment has to be shown as depending on the constraint, not the
18290 * index, in such cases.
18291 */
18292 if (!is_constraint)
18293 {
18294 char *indstatcols = indxinfo->indstatcols;
18295 char *indstatvals = indxinfo->indstatvals;
18296 char **indstatcolsarray = NULL;
18297 char **indstatvalsarray = NULL;
18298 int nstatcols = 0;
18299 int nstatvals = 0;
18300
18301 if (dopt->binary_upgrade)
18303 indxinfo->dobj.catId.oid);
18304
18305 /* Plain secondary index */
18306 appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
18307
18308 /*
18309 * Append ALTER TABLE commands as needed to set properties that we
18310 * only have ALTER TABLE syntax for. Keep this in sync with the
18311 * similar code in dumpConstraint!
18312 */
18313
18314 /* If the index is clustered, we need to record that. */
18315 if (indxinfo->indisclustered)
18316 {
18317 appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
18318 fmtQualifiedDumpable(tbinfo));
18319 /* index name is not qualified in this syntax */
18320 appendPQExpBuffer(q, " ON %s;\n",
18321 qindxname);
18322 }
18323
18324 /*
18325 * If the index has any statistics on some of its columns, generate
18326 * the associated ALTER INDEX queries.
18327 */
18328 if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
18329 {
18330 int j;
18331
18332 if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
18333 pg_fatal("could not parse index statistic columns");
18334 if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
18335 pg_fatal("could not parse index statistic values");
18336 if (nstatcols != nstatvals)
18337 pg_fatal("mismatched number of columns and values for index statistics");
18338
18339 for (j = 0; j < nstatcols; j++)
18340 {
18341 appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
18342
18343 /*
18344 * Note that this is a column number, so no quotes should be
18345 * used.
18346 */
18347 appendPQExpBuffer(q, "ALTER COLUMN %s ",
18348 indstatcolsarray[j]);
18349 appendPQExpBuffer(q, "SET STATISTICS %s;\n",
18350 indstatvalsarray[j]);
18351 }
18352 }
18353
18354 /* Indexes can depend on extensions */
18355 append_depends_on_extension(fout, q, &indxinfo->dobj,
18356 "pg_catalog.pg_class",
18357 "INDEX", qqindxname);
18358
18359 /* If the index defines identity, we need to record that. */
18360 if (indxinfo->indisreplident)
18361 {
18362 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
18363 fmtQualifiedDumpable(tbinfo));
18364 /* index name is not qualified in this syntax */
18365 appendPQExpBuffer(q, " INDEX %s;\n",
18366 qindxname);
18367 }
18368
18369 /*
18370 * If this index is a member of a partitioned index, the backend will
18371 * not allow us to drop it separately, so don't try. It will go away
18372 * automatically when we drop either the index's table or the
18373 * partitioned index. (If, in a selective restore with --clean, we
18374 * drop neither of those, then this index will not be dropped either.
18375 * But that's fine, and even if you think it's not, the backend won't
18376 * let us do differently.)
18377 */
18378 if (indxinfo->parentidx == 0)
18379 appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
18380
18381 if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18382 ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
18383 ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
18384 .namespace = tbinfo->dobj.namespace->dobj.name,
18385 .tablespace = indxinfo->tablespace,
18386 .owner = tbinfo->rolname,
18387 .description = "INDEX",
18388 .section = SECTION_POST_DATA,
18389 .createStmt = q->data,
18390 .dropStmt = delq->data));
18391
18392 free(indstatcolsarray);
18393 free(indstatvalsarray);
18394 }
18395
18396 /* Dump Index Comments */
18397 if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18398 dumpComment(fout, "INDEX", qindxname,
18399 tbinfo->dobj.namespace->dobj.name,
18400 tbinfo->rolname,
18401 indxinfo->dobj.catId, 0,
18402 is_constraint ? indxinfo->indexconstraint :
18403 indxinfo->dobj.dumpId);
18404
18406 destroyPQExpBuffer(delq);
18407 free(qindxname);
18408 free(qqindxname);
18409}
char * indstatvals
Definition: pg_dump.h:426
char * indstatcols
Definition: pg_dump.h:425
TableInfo * indextable
Definition: pg_dump.h:421
Oid parentidx
Definition: pg_dump.h:434
DumpId indexconstraint
Definition: pg_dump.h:438
char * indexdef
Definition: pg_dump.h:422

References append_depends_on_extension(), appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _indxInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, fmtId(), fmtQualifiedDumpable, free, _indxInfo::indexconstraint, _indxInfo::indexdef, _indxInfo::indextable, _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indstatcols, _indxInfo::indstatvals, j, _dumpableObject::name, CatalogId::oid, _indxInfo::parentidx, 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 18416 of file pg_dump.c.

18417{
18418 /* Do nothing if not dumping schema */
18419 if (!fout->dopt->dumpSchema)
18420 return;
18421
18423 {
18425
18426 appendPQExpBuffer(q, "ALTER INDEX %s ",
18427 fmtQualifiedDumpable(attachinfo->parentIdx));
18428 appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
18429 fmtQualifiedDumpable(attachinfo->partitionIdx));
18430
18431 /*
18432 * There is no need for a dropStmt since the drop is done implicitly
18433 * when we drop either the index's table or the partitioned index.
18434 * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
18435 * there's no way to do it anyway. (If you think to change this,
18436 * consider also what to do with --if-exists.)
18437 *
18438 * Although this object doesn't really have ownership as such, set the
18439 * owner field anyway to ensure that the command is run by the correct
18440 * role at restore time.
18441 */
18442 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18443 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18444 .namespace = attachinfo->dobj.namespace->dobj.name,
18445 .owner = attachinfo->parentIdx->indextable->rolname,
18446 .description = "INDEX ATTACH",
18447 .section = SECTION_POST_DATA,
18448 .createStmt = q->data));
18449
18451 }
18452}
IndxInfo * parentIdx
Definition: pg_dump.h:444

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _indxInfo::dobj, _indexAttachInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 4111 of file pg_dump.c.

4112{
4113 PQExpBuffer cquery = createPQExpBuffer();
4114
4115 /*
4116 * The "definition" is just a newline-separated list of OIDs. We need to
4117 * put something into the dropStmt too, but it can just be a comment.
4118 */
4119 for (int i = 0; i < loinfo->numlos; i++)
4120 appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
4121
4122 if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4123 ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
4124 ARCHIVE_OPTS(.tag = loinfo->dobj.name,
4125 .owner = loinfo->rolname,
4126 .description = "BLOB METADATA",
4127 .section = SECTION_DATA,
4128 .createStmt = cquery->data,
4129 .dropStmt = "-- dummy"));
4130
4131 /*
4132 * Dump per-blob comments and seclabels if any. We assume these are rare
4133 * enough that it's okay to generate retail TOC entries for them.
4134 */
4135 if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
4137 {
4138 for (int i = 0; i < loinfo->numlos; i++)
4139 {
4140 CatalogId catId;
4141 char namebuf[32];
4142
4143 /* Build identifying info for this blob */
4144 catId.tableoid = loinfo->dobj.catId.tableoid;
4145 catId.oid = loinfo->looids[i];
4146 snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
4147
4148 if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4149 dumpComment(fout, "LARGE OBJECT", namebuf,
4150 NULL, loinfo->rolname,
4151 catId, 0, loinfo->dobj.dumpId);
4152
4153 if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4154 dumpSecLabel(fout, "LARGE OBJECT", namebuf,
4155 NULL, loinfo->rolname,
4156 catId, 0, loinfo->dobj.dumpId);
4157 }
4158 }
4159
4160 /*
4161 * Dump the ACLs if any (remember that all blobs in the group will have
4162 * the same ACL). If there's just one blob, dump a simple ACL entry; if
4163 * there's more, make a "LARGE OBJECTS" entry that really contains only
4164 * the ACL for the first blob. _printTocEntry() will be cued by the tag
4165 * string to emit a mutated version for each blob.
4166 */
4167 if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
4168 {
4169 char namebuf[32];
4170
4171 /* Build identifying info for the first blob */
4172 snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
4173
4174 if (loinfo->numlos > 1)
4175 {
4176 char tagbuf[64];
4177
4178 snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
4179 loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
4180
4181 dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
4182 "LARGE OBJECT", namebuf, NULL, NULL,
4183 tagbuf, loinfo->rolname, &loinfo->dacl);
4184 }
4185 else
4186 {
4187 dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
4188 "LARGE OBJECT", namebuf, NULL, NULL,
4189 NULL, loinfo->rolname, &loinfo->dacl);
4190 }
4191 }
4192
4193 destroyPQExpBuffer(cquery);
4194}
DumpableObject dobj
Definition: pg_dump.h:639
DumpableAcl dacl
Definition: pg_dump.h:640
Oid looids[FLEXIBLE_ARRAY_MEMBER]
Definition: pg_dump.h:643

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

4202{
4203 const LoInfo *loinfo = (const LoInfo *) arg;
4204 PGconn *conn = GetConnection(fout);
4205 char buf[LOBBUFSIZE];
4206
4207 pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
4208
4209 for (int i = 0; i < loinfo->numlos; i++)
4210 {
4211 Oid loOid = loinfo->looids[i];
4212 int loFd;
4213 int cnt;
4214
4215 /* Open the LO */
4216 loFd = lo_open(conn, loOid, INV_READ);
4217 if (loFd == -1)
4218 pg_fatal("could not open large object %u: %s",
4219 loOid, PQerrorMessage(conn));
4220
4221 StartLO(fout, loOid);
4222
4223 /* Now read it in chunks, sending data to archive */
4224 do
4225 {
4226 cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
4227 if (cnt < 0)
4228 pg_fatal("error reading large object %u: %s",
4229 loOid, PQerrorMessage(conn));
4230
4231 WriteData(fout, buf, cnt);
4232 } while (cnt > 0);
4233
4234 lo_close(conn, loFd);
4235
4236 EndLO(fout, loOid);
4237 }
4238
4239 return 1;
4240}
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:154
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7704
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 11857 of file pg_dump.c.

11858{
11859 DumpOptions *dopt = fout->dopt;
11860 PQExpBuffer q;
11861 PQExpBuffer delq;
11862 char *qnspname;
11863
11864 /* Do nothing if not dumping schema */
11865 if (!dopt->dumpSchema)
11866 return;
11867
11868 q = createPQExpBuffer();
11869 delq = createPQExpBuffer();
11870
11871 qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
11872
11873 if (nspinfo->create)
11874 {
11875 appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
11876 appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
11877 }
11878 else
11879 {
11880 /* see selectDumpableNamespace() */
11882 "-- *not* dropping schema, since initdb creates it\n");
11884 "-- *not* creating schema, since initdb creates it\n");
11885 }
11886
11887 if (dopt->binary_upgrade)
11889 "SCHEMA", qnspname, NULL);
11890
11891 if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11892 ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
11893 ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
11894 .owner = nspinfo->rolname,
11895 .description = "SCHEMA",
11896 .section = SECTION_PRE_DATA,
11897 .createStmt = q->data,
11898 .dropStmt = delq->data));
11899
11900 /* Dump Schema Comments and Security Labels */
11901 if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11902 {
11903 const char *initdb_comment = NULL;
11904
11905 if (!nspinfo->create && strcmp(qnspname, "public") == 0)
11906 initdb_comment = "standard public schema";
11907 dumpCommentExtended(fout, "SCHEMA", qnspname,
11908 NULL, nspinfo->rolname,
11909 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
11910 initdb_comment);
11911 }
11912
11913 if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11914 dumpSecLabel(fout, "SCHEMA", qnspname,
11915 NULL, nspinfo->rolname,
11916 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
11917
11918 if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
11919 dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
11920 qnspname, NULL, NULL,
11921 NULL, nspinfo->rolname, &nspinfo->dacl);
11922
11923 free(qnspname);
11924
11926 destroyPQExpBuffer(delq);
11927}
DumpableObject dobj
Definition: pg_dump.h:186
DumpableAcl dacl
Definition: pg_dump.h:187
const char * rolname
Definition: pg_dump.h:190

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, _namespaceInfo::create, createPQExpBuffer(), _namespaceInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _namespaceInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpCommentExtended(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 14485 of file pg_dump.c.

14486{
14487 DumpOptions *dopt = fout->dopt;
14488 PQExpBuffer query;
14489 PQExpBuffer q;
14490 PQExpBuffer delq;
14491 PQExpBuffer nameusing;
14492 PGresult *res;
14493 int ntups;
14494 int i_opcintype;
14495 int i_opckeytype;
14496 int i_opcdefault;
14497 int i_opcfamily;
14498 int i_opcfamilyname;
14499 int i_opcfamilynsp;
14500 int i_amname;
14501 int i_amopstrategy;
14502 int i_amopopr;
14503 int i_sortfamily;
14504 int i_sortfamilynsp;
14505 int i_amprocnum;
14506 int i_amproc;
14507 int i_amproclefttype;
14508 int i_amprocrighttype;
14509 char *opcintype;
14510 char *opckeytype;
14511 char *opcdefault;
14512 char *opcfamily;
14513 char *opcfamilyname;
14514 char *opcfamilynsp;
14515 char *amname;
14516 char *amopstrategy;
14517 char *amopopr;
14518 char *sortfamily;
14519 char *sortfamilynsp;
14520 char *amprocnum;
14521 char *amproc;
14522 char *amproclefttype;
14523 char *amprocrighttype;
14524 bool needComma;
14525 int i;
14526
14527 /* Do nothing if not dumping schema */
14528 if (!dopt->dumpSchema)
14529 return;
14530
14531 query = createPQExpBuffer();
14532 q = createPQExpBuffer();
14533 delq = createPQExpBuffer();
14534 nameusing = createPQExpBuffer();
14535
14536 /* Get additional fields from the pg_opclass row */
14537 appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
14538 "opckeytype::pg_catalog.regtype, "
14539 "opcdefault, opcfamily, "
14540 "opfname AS opcfamilyname, "
14541 "nspname AS opcfamilynsp, "
14542 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
14543 "FROM pg_catalog.pg_opclass c "
14544 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
14545 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
14546 "WHERE c.oid = '%u'::pg_catalog.oid",
14547 opcinfo->dobj.catId.oid);
14548
14549 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14550
14551 i_opcintype = PQfnumber(res, "opcintype");
14552 i_opckeytype = PQfnumber(res, "opckeytype");
14553 i_opcdefault = PQfnumber(res, "opcdefault");
14554 i_opcfamily = PQfnumber(res, "opcfamily");
14555 i_opcfamilyname = PQfnumber(res, "opcfamilyname");
14556 i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
14557 i_amname = PQfnumber(res, "amname");
14558
14559 /* opcintype may still be needed after we PQclear res */
14560 opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
14561 opckeytype = PQgetvalue(res, 0, i_opckeytype);
14562 opcdefault = PQgetvalue(res, 0, i_opcdefault);
14563 /* opcfamily will still be needed after we PQclear res */
14564 opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
14565 opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
14566 opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
14567 /* amname will still be needed after we PQclear res */
14568 amname = pg_strdup(PQgetvalue(res, 0, i_amname));
14569
14570 appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
14571 fmtQualifiedDumpable(opcinfo));
14572 appendPQExpBuffer(delq, " USING %s;\n",
14573 fmtId(amname));
14574
14575 /* Build the fixed portion of the CREATE command */
14576 appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n ",
14577 fmtQualifiedDumpable(opcinfo));
14578 if (strcmp(opcdefault, "t") == 0)
14579 appendPQExpBufferStr(q, "DEFAULT ");
14580 appendPQExpBuffer(q, "FOR TYPE %s USING %s",
14581 opcintype,
14582 fmtId(amname));
14583 if (strlen(opcfamilyname) > 0)
14584 {
14585 appendPQExpBufferStr(q, " FAMILY ");
14586 appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
14587 appendPQExpBufferStr(q, fmtId(opcfamilyname));
14588 }
14589 appendPQExpBufferStr(q, " AS\n ");
14590
14591 needComma = false;
14592
14593 if (strcmp(opckeytype, "-") != 0)
14594 {
14595 appendPQExpBuffer(q, "STORAGE %s",
14596 opckeytype);
14597 needComma = true;
14598 }
14599
14600 PQclear(res);
14601
14602 /*
14603 * Now fetch and print the OPERATOR entries (pg_amop rows).
14604 *
14605 * Print only those opfamily members that are tied to the opclass by
14606 * pg_depend entries.
14607 */
14608 resetPQExpBuffer(query);
14609 appendPQExpBuffer(query, "SELECT amopstrategy, "
14610 "amopopr::pg_catalog.regoperator, "
14611 "opfname AS sortfamily, "
14612 "nspname AS sortfamilynsp "
14613 "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
14614 "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
14615 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
14616 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
14617 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
14618 "AND refobjid = '%u'::pg_catalog.oid "
14619 "AND amopfamily = '%s'::pg_catalog.oid "
14620 "ORDER BY amopstrategy",
14621 opcinfo->dobj.catId.oid,
14622 opcfamily);
14623
14624 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14625
14626 ntups = PQntuples(res);
14627
14628 i_amopstrategy = PQfnumber(res, "amopstrategy");
14629 i_amopopr = PQfnumber(res, "amopopr");
14630 i_sortfamily = PQfnumber(res, "sortfamily");
14631 i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
14632
14633 for (i = 0; i < ntups; i++)
14634 {
14635 amopstrategy = PQgetvalue(res, i, i_amopstrategy);
14636 amopopr = PQgetvalue(res, i, i_amopopr);
14637 sortfamily = PQgetvalue(res, i, i_sortfamily);
14638 sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
14639
14640 if (needComma)
14641 appendPQExpBufferStr(q, " ,\n ");
14642
14643 appendPQExpBuffer(q, "OPERATOR %s %s",
14644 amopstrategy, amopopr);
14645
14646 if (strlen(sortfamily) > 0)
14647 {
14648 appendPQExpBufferStr(q, " FOR ORDER BY ");
14649 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
14650 appendPQExpBufferStr(q, fmtId(sortfamily));
14651 }
14652
14653 needComma = true;
14654 }
14655
14656 PQclear(res);
14657
14658 /*
14659 * Now fetch and print the FUNCTION entries (pg_amproc rows).
14660 *
14661 * Print only those opfamily members that are tied to the opclass by
14662 * pg_depend entries.
14663 *
14664 * We print the amproclefttype/amprocrighttype even though in most cases
14665 * the backend could deduce the right values, because of the corner case
14666 * of a btree sort support function for a cross-type comparison.
14667 */
14668 resetPQExpBuffer(query);
14669
14670 appendPQExpBuffer(query, "SELECT amprocnum, "
14671 "amproc::pg_catalog.regprocedure, "
14672 "amproclefttype::pg_catalog.regtype, "
14673 "amprocrighttype::pg_catalog.regtype "
14674 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
14675 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
14676 "AND refobjid = '%u'::pg_catalog.oid "
14677 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
14678 "AND objid = ap.oid "
14679 "ORDER BY amprocnum",
14680 opcinfo->dobj.catId.oid);
14681
14682 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14683
14684 ntups = PQntuples(res);
14685
14686 i_amprocnum = PQfnumber(res, "amprocnum");
14687 i_amproc = PQfnumber(res, "amproc");
14688 i_amproclefttype = PQfnumber(res, "amproclefttype");
14689 i_amprocrighttype = PQfnumber(res, "amprocrighttype");
14690
14691 for (i = 0; i < ntups; i++)
14692 {
14693 amprocnum = PQgetvalue(res, i, i_amprocnum);
14694 amproc = PQgetvalue(res, i, i_amproc);
14695 amproclefttype = PQgetvalue(res, i, i_amproclefttype);
14696 amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
14697
14698 if (needComma)
14699 appendPQExpBufferStr(q, " ,\n ");
14700
14701 appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
14702
14703 if (*amproclefttype && *amprocrighttype)
14704 appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
14705
14706 appendPQExpBuffer(q, " %s", amproc);
14707
14708 needComma = true;
14709 }
14710
14711 PQclear(res);
14712
14713 /*
14714 * If needComma is still false it means we haven't added anything after
14715 * the AS keyword. To avoid printing broken SQL, append a dummy STORAGE
14716 * clause with the same datatype. This isn't sanctioned by the
14717 * documentation, but actually DefineOpClass will treat it as a no-op.
14718 */
14719 if (!needComma)
14720 appendPQExpBuffer(q, "STORAGE %s", opcintype);
14721
14722 appendPQExpBufferStr(q, ";\n");
14723
14724 appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
14725 appendPQExpBuffer(nameusing, " USING %s",
14726 fmtId(amname));
14727
14728 if (dopt->binary_upgrade)
14730 "OPERATOR CLASS", nameusing->data,
14731 opcinfo->dobj.namespace->dobj.name);
14732
14733 if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14734 ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
14735 ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
14736 .namespace = opcinfo->dobj.namespace->dobj.name,
14737 .owner = opcinfo->rolname,
14738 .description = "OPERATOR CLASS",
14739 .section = SECTION_PRE_DATA,
14740 .createStmt = q->data,
14741 .dropStmt = delq->data));
14742
14743 /* Dump Operator Class Comments */
14744 if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14745 dumpComment(fout, "OPERATOR CLASS", nameusing->data,
14746 opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
14747 opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
14748
14749 free(opcintype);
14750 free(opcfamily);
14751 free(amname);
14752 destroyPQExpBuffer(query);
14754 destroyPQExpBuffer(delq);
14755 destroyPQExpBuffer(nameusing);
14756}
DumpableObject dobj
Definition: pg_dump.h:277
const char * rolname
Definition: pg_dump.h:279

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

Referenced by dumpDumpableObject().

◆ dumpOpfamily()

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

Definition at line 14766 of file pg_dump.c.

14767{
14768 DumpOptions *dopt = fout->dopt;
14769 PQExpBuffer query;
14770 PQExpBuffer q;
14771 PQExpBuffer delq;
14772 PQExpBuffer nameusing;
14773 PGresult *res;
14774 PGresult *res_ops;
14775 PGresult *res_procs;
14776 int ntups;
14777 int i_amname;
14778 int i_amopstrategy;
14779 int i_amopopr;
14780 int i_sortfamily;
14781 int i_sortfamilynsp;
14782 int i_amprocnum;
14783 int i_amproc;
14784 int i_amproclefttype;
14785 int i_amprocrighttype;
14786 char *amname;
14787 char *amopstrategy;
14788 char *amopopr;
14789 char *sortfamily;
14790 char *sortfamilynsp;
14791 char *amprocnum;
14792 char *amproc;
14793 char *amproclefttype;
14794 char *amprocrighttype;
14795 bool needComma;
14796 int i;
14797
14798 /* Do nothing if not dumping schema */
14799 if (!dopt->dumpSchema)
14800 return;
14801
14802 query = createPQExpBuffer();
14803 q = createPQExpBuffer();
14804 delq = createPQExpBuffer();
14805 nameusing = createPQExpBuffer();
14806
14807 /*
14808 * Fetch only those opfamily members that are tied directly to the
14809 * opfamily by pg_depend entries.
14810 */
14811 appendPQExpBuffer(query, "SELECT amopstrategy, "
14812 "amopopr::pg_catalog.regoperator, "
14813 "opfname AS sortfamily, "
14814 "nspname AS sortfamilynsp "
14815 "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
14816 "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
14817 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
14818 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
14819 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
14820 "AND refobjid = '%u'::pg_catalog.oid "
14821 "AND amopfamily = '%u'::pg_catalog.oid "
14822 "ORDER BY amopstrategy",
14823 opfinfo->dobj.catId.oid,
14824 opfinfo->dobj.catId.oid);
14825
14826 res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14827
14828 resetPQExpBuffer(query);
14829
14830 appendPQExpBuffer(query, "SELECT amprocnum, "
14831 "amproc::pg_catalog.regprocedure, "
14832 "amproclefttype::pg_catalog.regtype, "
14833 "amprocrighttype::pg_catalog.regtype "
14834 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
14835 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
14836 "AND refobjid = '%u'::pg_catalog.oid "
14837 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
14838 "AND objid = ap.oid "
14839 "ORDER BY amprocnum",
14840 opfinfo->dobj.catId.oid);
14841
14842 res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14843
14844 /* Get additional fields from the pg_opfamily row */
14845 resetPQExpBuffer(query);
14846
14847 appendPQExpBuffer(query, "SELECT "
14848 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
14849 "FROM pg_catalog.pg_opfamily "
14850 "WHERE oid = '%u'::pg_catalog.oid",
14851 opfinfo->dobj.catId.oid);
14852
14853 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14854
14855 i_amname = PQfnumber(res, "amname");
14856
14857 /* amname will still be needed after we PQclear res */
14858 amname = pg_strdup(PQgetvalue(res, 0, i_amname));
14859
14860 appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
14861 fmtQualifiedDumpable(opfinfo));
14862 appendPQExpBuffer(delq, " USING %s;\n",
14863 fmtId(amname));
14864
14865 /* Build the fixed portion of the CREATE command */
14866 appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
14867 fmtQualifiedDumpable(opfinfo));
14868 appendPQExpBuffer(q, " USING %s;\n",
14869 fmtId(amname));
14870
14871 PQclear(res);
14872
14873 /* Do we need an ALTER to add loose members? */
14874 if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
14875 {
14876 appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
14877 fmtQualifiedDumpable(opfinfo));
14878 appendPQExpBuffer(q, " USING %s ADD\n ",
14879 fmtId(amname));
14880
14881 needComma = false;
14882
14883 /*
14884 * Now fetch and print the OPERATOR entries (pg_amop rows).
14885 */
14886 ntups = PQntuples(res_ops);
14887
14888 i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
14889 i_amopopr = PQfnumber(res_ops, "amopopr");
14890 i_sortfamily = PQfnumber(res_ops, "sortfamily");
14891 i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
14892
14893 for (i = 0; i < ntups; i++)
14894 {
14895 amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
14896 amopopr = PQgetvalue(res_ops, i, i_amopopr);
14897 sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
14898 sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
14899
14900 if (needComma)
14901 appendPQExpBufferStr(q, " ,\n ");
14902
14903 appendPQExpBuffer(q, "OPERATOR %s %s",
14904 amopstrategy, amopopr);
14905
14906 if (strlen(sortfamily) > 0)
14907 {
14908 appendPQExpBufferStr(q, " FOR ORDER BY ");
14909 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
14910 appendPQExpBufferStr(q, fmtId(sortfamily));
14911 }
14912
14913 needComma = true;
14914 }
14915
14916 /*
14917 * Now fetch and print the FUNCTION entries (pg_amproc rows).
14918 */
14919 ntups = PQntuples(res_procs);
14920
14921 i_amprocnum = PQfnumber(res_procs, "amprocnum");
14922 i_amproc = PQfnumber(res_procs, "amproc");
14923 i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
14924 i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
14925
14926 for (i = 0; i < ntups; i++)
14927 {
14928 amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
14929 amproc = PQgetvalue(res_procs, i, i_amproc);
14930 amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
14931 amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
14932
14933 if (needComma)
14934 appendPQExpBufferStr(q, " ,\n ");
14935
14936 appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
14937 amprocnum, amproclefttype, amprocrighttype,
14938 amproc);
14939
14940 needComma = true;
14941 }
14942
14943 appendPQExpBufferStr(q, ";\n");
14944 }
14945
14946 appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
14947 appendPQExpBuffer(nameusing, " USING %s",
14948 fmtId(amname));
14949
14950 if (dopt->binary_upgrade)
14952 "OPERATOR FAMILY", nameusing->data,
14953 opfinfo->dobj.namespace->dobj.name);
14954
14955 if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14956 ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
14957 ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
14958 .namespace = opfinfo->dobj.namespace->dobj.name,
14959 .owner = opfinfo->rolname,
14960 .description = "OPERATOR FAMILY",
14961 .section = SECTION_PRE_DATA,
14962 .createStmt = q->data,
14963 .dropStmt = delq->data));
14964
14965 /* Dump Operator Family Comments */
14966 if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14967 dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
14968 opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
14969 opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
14970
14971 free(amname);
14972 PQclear(res_ops);
14973 PQclear(res_procs);
14974 destroyPQExpBuffer(query);
14976 destroyPQExpBuffer(delq);
14977 destroyPQExpBuffer(nameusing);
14978}
const char * rolname
Definition: pg_dump.h:286
DumpableObject dobj
Definition: pg_dump.h:284

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

Referenced by dumpDumpableObject().

◆ dumpOpr()

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

Definition at line 14105 of file pg_dump.c.

14106{
14107 DumpOptions *dopt = fout->dopt;
14108 PQExpBuffer query;
14109 PQExpBuffer q;
14110 PQExpBuffer delq;
14112 PQExpBuffer details;
14113 PGresult *res;
14114 int i_oprkind;
14115 int i_oprcode;
14116 int i_oprleft;
14117 int i_oprright;
14118 int i_oprcom;
14119 int i_oprnegate;
14120 int i_oprrest;
14121 int i_oprjoin;
14122 int i_oprcanmerge;
14123 int i_oprcanhash;
14124 char *oprkind;
14125 char *oprcode;
14126 char *oprleft;
14127 char *oprright;
14128 char *oprcom;
14129 char *oprnegate;
14130 char *oprrest;
14131 char *oprjoin;
14132 char *oprcanmerge;
14133 char *oprcanhash;
14134 char *oprregproc;
14135 char *oprref;
14136
14137 /* Do nothing if not dumping schema */
14138 if (!dopt->dumpSchema)
14139 return;
14140
14141 /*
14142 * some operators are invalid because they were the result of user
14143 * defining operators before commutators exist
14144 */
14145 if (!OidIsValid(oprinfo->oprcode))
14146 return;
14147
14148 query = createPQExpBuffer();
14149 q = createPQExpBuffer();
14150 delq = createPQExpBuffer();
14152 details = createPQExpBuffer();
14153
14154 if (!fout->is_prepared[PREPQUERY_DUMPOPR])
14155 {
14156 /* Set up query for operator-specific details */
14158 "PREPARE dumpOpr(pg_catalog.oid) AS\n"
14159 "SELECT oprkind, "
14160 "oprcode::pg_catalog.regprocedure, "
14161 "oprleft::pg_catalog.regtype, "
14162 "oprright::pg_catalog.regtype, "
14163 "oprcom, "
14164 "oprnegate, "
14165 "oprrest::pg_catalog.regprocedure, "
14166 "oprjoin::pg_catalog.regprocedure, "
14167 "oprcanmerge, oprcanhash "
14168 "FROM pg_catalog.pg_operator "
14169 "WHERE oid = $1");
14170
14171 ExecuteSqlStatement(fout, query->data);
14172
14173 fout->is_prepared[PREPQUERY_DUMPOPR] = true;
14174 }
14175
14176 printfPQExpBuffer(query,
14177 "EXECUTE dumpOpr('%u')",
14178 oprinfo->dobj.catId.oid);
14179
14180 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14181
14182 i_oprkind = PQfnumber(res, "oprkind");
14183 i_oprcode = PQfnumber(res, "oprcode");
14184 i_oprleft = PQfnumber(res, "oprleft");
14185 i_oprright = PQfnumber(res, "oprright");
14186 i_oprcom = PQfnumber(res, "oprcom");
14187 i_oprnegate = PQfnumber(res, "oprnegate");
14188 i_oprrest = PQfnumber(res, "oprrest");
14189 i_oprjoin = PQfnumber(res, "oprjoin");
14190 i_oprcanmerge = PQfnumber(res, "oprcanmerge");
14191 i_oprcanhash = PQfnumber(res, "oprcanhash");
14192
14193 oprkind = PQgetvalue(res, 0, i_oprkind);
14194 oprcode = PQgetvalue(res, 0, i_oprcode);
14195 oprleft = PQgetvalue(res, 0, i_oprleft);
14196 oprright = PQgetvalue(res, 0, i_oprright);
14197 oprcom = PQgetvalue(res, 0, i_oprcom);
14198 oprnegate = PQgetvalue(res, 0, i_oprnegate);
14199 oprrest = PQgetvalue(res, 0, i_oprrest);
14200 oprjoin = PQgetvalue(res, 0, i_oprjoin);
14201 oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
14202 oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
14203
14204 /* In PG14 upwards postfix operator support does not exist anymore. */
14205 if (strcmp(oprkind, "r") == 0)
14206 pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
14207 oprcode);
14208
14209 oprregproc = convertRegProcReference(oprcode);
14210 if (oprregproc)
14211 {
14212 appendPQExpBuffer(details, " FUNCTION = %s", oprregproc);
14213 free(oprregproc);
14214 }
14215
14216 appendPQExpBuffer(oprid, "%s (",
14217 oprinfo->dobj.name);
14218
14219 /*
14220 * right unary means there's a left arg and left unary means there's a
14221 * right arg. (Although the "r" case is dead code for PG14 and later,
14222 * continue to support it in case we're dumping from an old server.)
14223 */
14224 if (strcmp(oprkind, "r") == 0 ||
14225 strcmp(oprkind, "b") == 0)
14226 {
14227 appendPQExpBuffer(details, ",\n LEFTARG = %s", oprleft);
14228 appendPQExpBufferStr(oprid, oprleft);
14229 }
14230 else
14231 appendPQExpBufferStr(oprid, "NONE");
14232
14233 if (strcmp(oprkind, "l") == 0 ||
14234 strcmp(oprkind, "b") == 0)
14235 {
14236 appendPQExpBuffer(details, ",\n RIGHTARG = %s", oprright);
14237 appendPQExpBuffer(oprid, ", %s)", oprright);
14238 }
14239 else
14240 appendPQExpBufferStr(oprid, ", NONE)");
14241
14242 oprref = getFormattedOperatorName(oprcom);
14243 if (oprref)
14244 {
14245 appendPQExpBuffer(details, ",\n COMMUTATOR = %s", oprref);
14246 free(oprref);
14247 }
14248
14249 oprref = getFormattedOperatorName(oprnegate);
14250 if (oprref)
14251 {
14252 appendPQExpBuffer(details, ",\n NEGATOR = %s", oprref);
14253 free(oprref);
14254 }
14255
14256 if (strcmp(oprcanmerge, "t") == 0)
14257 appendPQExpBufferStr(details, ",\n MERGES");
14258
14259 if (strcmp(oprcanhash, "t") == 0)
14260 appendPQExpBufferStr(details, ",\n HASHES");
14261
14262 oprregproc = convertRegProcReference(oprrest);
14263 if (oprregproc)
14264 {
14265 appendPQExpBuffer(details, ",\n RESTRICT = %s", oprregproc);
14266 free(oprregproc);
14267 }
14268
14269 oprregproc = convertRegProcReference(oprjoin);
14270 if (oprregproc)
14271 {
14272 appendPQExpBuffer(details, ",\n JOIN = %s", oprregproc);
14273 free(oprregproc);
14274 }
14275
14276 appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
14277 fmtId(oprinfo->dobj.namespace->dobj.name),
14278 oprid->data);
14279
14280 appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
14281 fmtId(oprinfo->dobj.namespace->dobj.name),
14282 oprinfo->dobj.name, details->data);
14283
14284 if (dopt->binary_upgrade)
14286 "OPERATOR", oprid->data,
14287 oprinfo->dobj.namespace->dobj.name);
14288
14289 if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14290 ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
14291 ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
14292 .namespace = oprinfo->dobj.namespace->dobj.name,
14293 .owner = oprinfo->rolname,
14294 .description = "OPERATOR",
14295 .section = SECTION_PRE_DATA,
14296 .createStmt = q->data,
14297 .dropStmt = delq->data));
14298
14299 /* Dump Operator Comments */
14300 if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14301 dumpComment(fout, "OPERATOR", oprid->data,
14302 oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
14303 oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
14304
14305 PQclear(res);
14306
14307 destroyPQExpBuffer(query);
14309 destroyPQExpBuffer(delq);
14311 destroyPQExpBuffer(details);
14312}
Oid oprid(Operator op)
Definition: parse_oper.c:239
@ PREPQUERY_DUMPOPR
Definition: pg_backup.h:72
static char * convertRegProcReference(const char *proc)
Definition: pg_dump.c:14324
DumpableObject dobj
Definition: pg_dump.h:260
Oid oprcode
Definition: pg_dump.h:265
const char * rolname
Definition: pg_dump.h:261

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertRegProcReference(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _oprInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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(), _oprInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpPolicy()

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

Definition at line 4419 of file pg_dump.c.

4420{
4421 DumpOptions *dopt = fout->dopt;
4422 TableInfo *tbinfo = polinfo->poltable;
4423 PQExpBuffer query;
4424 PQExpBuffer delqry;
4425 PQExpBuffer polprefix;
4426 char *qtabname;
4427 const char *cmd;
4428 char *tag;
4429
4430 /* Do nothing if not dumping schema */
4431 if (!dopt->dumpSchema)
4432 return;
4433
4434 /*
4435 * If polname is NULL, then this record is just indicating that ROW LEVEL
4436 * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
4437 * ROW LEVEL SECURITY.
4438 */
4439 if (polinfo->polname == NULL)
4440 {
4441 query = createPQExpBuffer();
4442
4443 appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
4444 fmtQualifiedDumpable(tbinfo));
4445
4446 /*
4447 * We must emit the ROW SECURITY object's dependency on its table
4448 * explicitly, because it will not match anything in pg_depend (unlike
4449 * the case for other PolicyInfo objects).
4450 */
4451 if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4452 ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4453 ARCHIVE_OPTS(.tag = polinfo->dobj.name,
4454 .namespace = polinfo->dobj.namespace->dobj.name,
4455 .owner = tbinfo->rolname,
4456 .description = "ROW SECURITY",
4457 .section = SECTION_POST_DATA,
4458 .createStmt = query->data,
4459 .deps = &(tbinfo->dobj.dumpId),
4460 .nDeps = 1));
4461
4462 destroyPQExpBuffer(query);
4463 return;
4464 }
4465
4466 if (polinfo->polcmd == '*')
4467 cmd = "";
4468 else if (polinfo->polcmd == 'r')
4469 cmd = " FOR SELECT";
4470 else if (polinfo->polcmd == 'a')
4471 cmd = " FOR INSERT";
4472 else if (polinfo->polcmd == 'w')
4473 cmd = " FOR UPDATE";
4474 else if (polinfo->polcmd == 'd')
4475 cmd = " FOR DELETE";
4476 else
4477 pg_fatal("unexpected policy command type: %c",
4478 polinfo->polcmd);
4479
4480 query = createPQExpBuffer();
4481 delqry = createPQExpBuffer();
4482 polprefix = createPQExpBuffer();
4483
4484 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
4485
4486 appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
4487
4488 appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
4489 !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
4490
4491 if (polinfo->polroles != NULL)
4492 appendPQExpBuffer(query, " TO %s", polinfo->polroles);
4493
4494 if (polinfo->polqual != NULL)
4495 appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
4496
4497 if (polinfo->polwithcheck != NULL)
4498 appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
4499
4500 appendPQExpBufferStr(query, ";\n");
4501
4502 appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
4503 appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
4504
4505 appendPQExpBuffer(polprefix, "POLICY %s ON",
4506 fmtId(polinfo->polname));
4507
4508 tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
4509
4510 if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4511 ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4512 ARCHIVE_OPTS(.tag = tag,
4513 .namespace = polinfo->dobj.namespace->dobj.name,
4514 .owner = tbinfo->rolname,
4515 .description = "POLICY",
4516 .section = SECTION_POST_DATA,
4517 .createStmt = query->data,
4518 .dropStmt = delqry->data));
4519
4520 if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4521 dumpComment(fout, polprefix->data, qtabname,
4522 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
4523 polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
4524
4525 free(tag);
4526 destroyPQExpBuffer(query);
4527 destroyPQExpBuffer(delqry);
4528 destroyPQExpBuffer(polprefix);
4529 free(qtabname);
4530}
TableInfo * poltable
Definition: pg_dump.h:655
char * polqual
Definition: pg_dump.h:660
char polcmd
Definition: pg_dump.h:657
char * polroles
Definition: pg_dump.h:659
char * polwithcheck
Definition: pg_dump.h:661
DumpableObject dobj
Definition: pg_dump.h:654
bool polpermissive
Definition: pg_dump.h:658
char * polname
Definition: pg_dump.h:656

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _policyInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 13265 of file pg_dump.c.

13266{
13267 DumpOptions *dopt = fout->dopt;
13268 PQExpBuffer defqry;
13269 PQExpBuffer delqry;
13270 bool useParams;
13271 char *qlanname;
13272 FuncInfo *funcInfo;
13273 FuncInfo *inlineInfo = NULL;
13274 FuncInfo *validatorInfo = NULL;
13275
13276 /* Do nothing if not dumping schema */
13277 if (!dopt->dumpSchema)
13278 return;
13279
13280 /*
13281 * Try to find the support function(s). It is not an error if we don't
13282 * find them --- if the functions are in the pg_catalog schema, as is
13283 * standard in 8.1 and up, then we won't have loaded them. (In this case
13284 * we will emit a parameterless CREATE LANGUAGE command, which will
13285 * require PL template knowledge in the backend to reload.)
13286 */
13287
13288 funcInfo = findFuncByOid(plang->lanplcallfoid);
13289 if (funcInfo != NULL && !funcInfo->dobj.dump)
13290 funcInfo = NULL; /* treat not-dumped same as not-found */
13291
13292 if (OidIsValid(plang->laninline))
13293 {
13294 inlineInfo = findFuncByOid(plang->laninline);
13295 if (inlineInfo != NULL && !inlineInfo->dobj.dump)
13296 inlineInfo = NULL;
13297 }
13298
13299 if (OidIsValid(plang->lanvalidator))
13300 {
13301 validatorInfo = findFuncByOid(plang->lanvalidator);
13302 if (validatorInfo != NULL && !validatorInfo->dobj.dump)
13303 validatorInfo = NULL;
13304 }
13305
13306 /*
13307 * If the functions are dumpable then emit a complete CREATE LANGUAGE with
13308 * parameters. Otherwise, we'll write a parameterless command, which will
13309 * be interpreted as CREATE EXTENSION.
13310 */
13311 useParams = (funcInfo != NULL &&
13312 (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
13313 (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
13314
13315 defqry = createPQExpBuffer();
13316 delqry = createPQExpBuffer();
13317
13318 qlanname = pg_strdup(fmtId(plang->dobj.name));
13319
13320 appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
13321 qlanname);
13322
13323 if (useParams)
13324 {
13325 appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
13326 plang->lanpltrusted ? "TRUSTED " : "",
13327 qlanname);
13328 appendPQExpBuffer(defqry, " HANDLER %s",
13329 fmtQualifiedDumpable(funcInfo));
13330 if (OidIsValid(plang->laninline))
13331 appendPQExpBuffer(defqry, " INLINE %s",
13332 fmtQualifiedDumpable(inlineInfo));
13333 if (OidIsValid(plang->lanvalidator))
13334 appendPQExpBuffer(defqry, " VALIDATOR %s",
13335 fmtQualifiedDumpable(validatorInfo));
13336 }
13337 else
13338 {
13339 /*
13340 * If not dumping parameters, then use CREATE OR REPLACE so that the
13341 * command will not fail if the language is preinstalled in the target
13342 * database.
13343 *
13344 * Modern servers will interpret this as CREATE EXTENSION IF NOT
13345 * EXISTS; perhaps we should emit that instead? But it might just add
13346 * confusion.
13347 */
13348 appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
13349 qlanname);
13350 }
13351 appendPQExpBufferStr(defqry, ";\n");
13352
13353 if (dopt->binary_upgrade)
13354 binary_upgrade_extension_member(defqry, &plang->dobj,
13355 "LANGUAGE", qlanname, NULL);
13356
13357 if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
13358 ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
13359 ARCHIVE_OPTS(.tag = plang->dobj.name,
13360 .owner = plang->lanowner,
13361 .description = "PROCEDURAL LANGUAGE",
13362 .section = SECTION_PRE_DATA,
13363 .createStmt = defqry->data,
13364 .dropStmt = delqry->data,
13365 ));
13366
13367 /* Dump Proc Lang Comments and Security Labels */
13368 if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
13369 dumpComment(fout, "LANGUAGE", qlanname,
13370 NULL, plang->lanowner,
13371 plang->dobj.catId, 0, plang->dobj.dumpId);
13372
13373 if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
13374 dumpSecLabel(fout, "LANGUAGE", qlanname,
13375 NULL, plang->lanowner,
13376 plang->dobj.catId, 0, plang->dobj.dumpId);
13377
13378 if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
13379 dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
13380 qlanname, NULL, NULL,
13381 NULL, plang->lanowner, &plang->dacl);
13382
13383 free(qlanname);
13384
13385 destroyPQExpBuffer(defqry);
13386 destroyPQExpBuffer(delqry);
13387}
Oid lanvalidator
Definition: pg_dump.h:538
DumpableAcl dacl
Definition: pg_dump.h:534
DumpableObject dobj
Definition: pg_dump.h:533
Oid laninline
Definition: pg_dump.h:537
const char * lanowner
Definition: pg_dump.h:539
Oid lanplcallfoid
Definition: pg_dump.h:536
bool lanpltrusted
Definition: pg_dump.h:535

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), _procLangInfo::dacl, PQExpBufferData::data, 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, _dumpOptions::dumpSchema, 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 4653 of file pg_dump.c.

4654{
4655 DumpOptions *dopt = fout->dopt;
4656 PQExpBuffer delq;
4657 PQExpBuffer query;
4658 char *qpubname;
4659 bool first = true;
4660
4661 /* Do nothing if not dumping schema */
4662 if (!dopt->dumpSchema)
4663 return;
4664
4665 delq = createPQExpBuffer();
4666 query = createPQExpBuffer();
4667
4668 qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
4669
4670 appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
4671 qpubname);
4672
4673 appendPQExpBuffer(query, "CREATE PUBLICATION %s",
4674 qpubname);
4675
4676 if (pubinfo->puballtables && pubinfo->puballsequences)
4677 appendPQExpBufferStr(query, " FOR ALL TABLES, ALL SEQUENCES");
4678 else if (pubinfo->puballtables)
4679 appendPQExpBufferStr(query, " FOR ALL TABLES");
4680 else if (pubinfo->puballsequences)
4681 appendPQExpBufferStr(query, " FOR ALL SEQUENCES");
4682
4683 appendPQExpBufferStr(query, " WITH (publish = '");
4684 if (pubinfo->pubinsert)
4685 {
4686 appendPQExpBufferStr(query, "insert");
4687 first = false;
4688 }
4689
4690 if (pubinfo->pubupdate)
4691 {
4692 if (!first)
4693 appendPQExpBufferStr(query, ", ");
4694
4695 appendPQExpBufferStr(query, "update");
4696 first = false;
4697 }
4698
4699 if (pubinfo->pubdelete)
4700 {
4701 if (!first)
4702 appendPQExpBufferStr(query, ", ");
4703
4704 appendPQExpBufferStr(query, "delete");
4705 first = false;
4706 }
4707
4708 if (pubinfo->pubtruncate)
4709 {
4710 if (!first)
4711 appendPQExpBufferStr(query, ", ");
4712
4713 appendPQExpBufferStr(query, "truncate");
4714 first = false;
4715 }
4716
4717 appendPQExpBufferChar(query, '\'');
4718
4719 if (pubinfo->pubviaroot)
4720 appendPQExpBufferStr(query, ", publish_via_partition_root = true");
4721
4722 if (pubinfo->pubgencols_type == PUBLISH_GENCOLS_STORED)
4723 appendPQExpBufferStr(query, ", publish_generated_columns = stored");
4724
4725 appendPQExpBufferStr(query, ");\n");
4726
4727 if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4728 ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
4729 ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
4730 .owner = pubinfo->rolname,
4731 .description = "PUBLICATION",
4732 .section = SECTION_POST_DATA,
4733 .createStmt = query->data,
4734 .dropStmt = delq->data));
4735
4736 if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4737 dumpComment(fout, "PUBLICATION", qpubname,
4738 NULL, pubinfo->rolname,
4739 pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4740
4741 if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4742 dumpSecLabel(fout, "PUBLICATION", qpubname,
4743 NULL, pubinfo->rolname,
4744 pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4745
4746 destroyPQExpBuffer(delq);
4747 destroyPQExpBuffer(query);
4748 free(qpubname);
4749}
const char * rolname
Definition: pg_dump.h:670
bool puballsequences
Definition: pg_dump.h:672
bool puballtables
Definition: pg_dump.h:671
bool pubtruncate
Definition: pg_dump.h:676
PublishGencolsType pubgencols_type
Definition: pg_dump.h:678
DumpableObject dobj
Definition: pg_dump.h:669

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _PublicationInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, dumpSecLabel(), fmtId(), free, _dumpableObject::name, pg_strdup(), _PublicationInfo::puballsequences, _PublicationInfo::puballtables, _PublicationInfo::pubdelete, _PublicationInfo::pubgencols_type, _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 4963 of file pg_dump.c.

4964{
4965 DumpOptions *dopt = fout->dopt;
4966 NamespaceInfo *schemainfo = pubsinfo->pubschema;
4967 PublicationInfo *pubinfo = pubsinfo->publication;
4968 PQExpBuffer query;
4969 char *tag;
4970
4971 /* Do nothing if not dumping schema */
4972 if (!dopt->dumpSchema)
4973 return;
4974
4975 tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
4976
4977 query = createPQExpBuffer();
4978
4979 appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
4980 appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
4981
4982 /*
4983 * There is no point in creating drop query as the drop is done by schema
4984 * drop.
4985 */
4986 if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4987 ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
4988 ARCHIVE_OPTS(.tag = tag,
4989 .namespace = schemainfo->dobj.name,
4990 .owner = pubinfo->rolname,
4991 .description = "PUBLICATION TABLES IN SCHEMA",
4992 .section = SECTION_POST_DATA,
4993 .createStmt = query->data));
4994
4995 /* These objects can't currently have comments or seclabels */
4996
4997 free(tag);
4998 destroyPQExpBuffer(query);
4999}
NamespaceInfo * pubschema
Definition: pg_dump.h:702
DumpableObject dobj
Definition: pg_dump.h:700
PublicationInfo * publication
Definition: pg_dump.h:701

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _namespaceInfo::dobj, _PublicationInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 5006 of file pg_dump.c.

5007{
5008 DumpOptions *dopt = fout->dopt;
5009 PublicationInfo *pubinfo = pubrinfo->publication;
5010 TableInfo *tbinfo = pubrinfo->pubtable;
5011 PQExpBuffer query;
5012 char *tag;
5013
5014 /* Do nothing if not dumping schema */
5015 if (!dopt->dumpSchema)
5016 return;
5017
5018 tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
5019
5020 query = createPQExpBuffer();
5021
5022 appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
5023 fmtId(pubinfo->dobj.name));
5024 appendPQExpBuffer(query, " %s",
5025 fmtQualifiedDumpable(tbinfo));
5026
5027 if (pubrinfo->pubrattrs)
5028 appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
5029
5030 if (pubrinfo->pubrelqual)
5031 {
5032 /*
5033 * It's necessary to add parentheses around the expression because
5034 * pg_get_expr won't supply the parentheses for things like WHERE
5035 * TRUE.
5036 */
5037 appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
5038 }
5039 appendPQExpBufferStr(query, ";\n");
5040
5041 /*
5042 * There is no point in creating a drop query as the drop is done by table
5043 * drop. (If you think to change this, see also _printTocEntry().)
5044 * Although this object doesn't really have ownership as such, set the
5045 * owner field anyway to ensure that the command is run by the correct
5046 * role at restore time.
5047 */
5048 if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5049 ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
5050 ARCHIVE_OPTS(.tag = tag,
5051 .namespace = tbinfo->dobj.namespace->dobj.name,
5052 .owner = pubinfo->rolname,
5053 .description = "PUBLICATION TABLE",
5054 .section = SECTION_POST_DATA,
5055 .createStmt = query->data));
5056
5057 /* These objects can't currently have comments or seclabels */
5058
5059 free(tag);
5060 destroyPQExpBuffer(query);
5061}

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _PublicationInfo::dobj, Archive::dopt, DUMP_COMPONENT_DEFINITION, _dumpOptions::dumpSchema, 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 12228 of file pg_dump.c.

12229{
12230 DumpOptions *dopt = fout->dopt;
12234 PGresult *res;
12235 Oid collationOid;
12236 char *qtypname;
12237 char *qualtypname;
12238 char *procname;
12239
12241 {
12242 /* Set up query for range-specific details */
12244 "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
12245
12247 "SELECT ");
12248
12249 if (fout->remoteVersion >= 140000)
12251 "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
12252 else
12254 "NULL AS rngmultitype, ");
12255
12257 "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
12258 "opc.opcname AS opcname, "
12259 "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
12260 " WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
12261 "opc.opcdefault, "
12262 "CASE WHEN rngcollation = st.typcollation THEN 0 "
12263 " ELSE rngcollation END AS collation, "
12264 "rngcanonical, rngsubdiff "
12265 "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
12266 " pg_catalog.pg_opclass opc "
12267 "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
12268 "rngtypid = $1");
12269
12270 ExecuteSqlStatement(fout, query->data);
12271
12273 }
12274
12275 printfPQExpBuffer(query,
12276 "EXECUTE dumpRangeType('%u')",
12277 tyinfo->dobj.catId.oid);
12278
12279 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12280
12281 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12282 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12283
12284 /*
12285 * CASCADE shouldn't be required here as for normal types since the I/O
12286 * functions are generic and do not get dropped.
12287 */
12288 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12289
12290 if (dopt->binary_upgrade)
12292 tyinfo->dobj.catId.oid,
12293 false, true);
12294
12295 appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
12296 qualtypname);
12297
12298 appendPQExpBuffer(q, "\n subtype = %s",
12299 PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
12300
12301 if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
12302 appendPQExpBuffer(q, ",\n multirange_type_name = %s",
12303 PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
12304
12305 /* print subtype_opclass only if not default for subtype */
12306 if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
12307 {
12308 char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
12309 char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
12310
12311 appendPQExpBuffer(q, ",\n subtype_opclass = %s.",
12312 fmtId(nspname));
12313 appendPQExpBufferStr(q, fmtId(opcname));
12314 }
12315
12316 collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
12317 if (OidIsValid(collationOid))
12318 {
12319 CollInfo *coll = findCollationByOid(collationOid);
12320
12321 if (coll)
12322 appendPQExpBuffer(q, ",\n collation = %s",
12323 fmtQualifiedDumpable(coll));
12324 }
12325
12326 procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
12327 if (strcmp(procname, "-") != 0)
12328 appendPQExpBuffer(q, ",\n canonical = %s", procname);
12329
12330 procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
12331 if (strcmp(procname, "-") != 0)
12332 appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
12333
12334 appendPQExpBufferStr(q, "\n);\n");
12335
12336 if (dopt->binary_upgrade)
12338 "TYPE", qtypname,
12339 tyinfo->dobj.namespace->dobj.name);
12340
12341 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12342 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12343 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12344 .namespace = tyinfo->dobj.namespace->dobj.name,
12345 .owner = tyinfo->rolname,
12346 .description = "TYPE",
12347 .section = SECTION_PRE_DATA,
12348 .createStmt = q->data,
12349 .dropStmt = delq->data));
12350
12351 /* Dump Type Comments and Security Labels */
12352 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12353 dumpComment(fout, "TYPE", qtypname,
12354 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12355 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12356
12357 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12358 dumpSecLabel(fout, "TYPE", qtypname,
12359 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12360 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12361
12362 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12363 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12364 qtypname, NULL,
12365 tyinfo->dobj.namespace->dobj.name,
12366 NULL, tyinfo->rolname, &tyinfo->dacl);
12367
12368 PQclear(res);
12370 destroyPQExpBuffer(delq);
12371 destroyPQExpBuffer(query);
12372 free(qtypname);
12373 free(qualtypname);
12374}
@ 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, _typeInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpType().

◆ dumpRelationStats()

static void dumpRelationStats ( Archive fout,
const RelStatsInfo rsinfo 
)
static

Definition at line 11375 of file pg_dump.c.

11376{
11377 const DumpableObject *dobj = &rsinfo->dobj;
11378
11379 /* nothing to do if we are not dumping statistics */
11380 if (!fout->dopt->dumpStatistics)
11381 return;
11382
11384 ARCHIVE_OPTS(.tag = dobj->name,
11385 .namespace = dobj->namespace->dobj.name,
11386 .description = "STATISTICS DATA",
11387 .section = rsinfo->section,
11388 .defnFn = dumpRelationStats_dumper,
11389 .defnArg = rsinfo,
11390 .deps = dobj->dependencies,
11391 .nDeps = dobj->nDeps));
11392}
static char * dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
Definition: pg_dump.c:11102
bool dumpStatistics
Definition: pg_backup.h:217
teSection section
Definition: pg_dump.h:463
DumpableObject dobj
Definition: pg_dump.h:450

References ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), _dumpableObject::dependencies, _relStatsInfo::dobj, Archive::dopt, dumpRelationStats_dumper(), _dumpOptions::dumpStatistics, _dumpableObject::name, _dumpableObject::nDeps, nilCatalogId, and _relStatsInfo::section.

Referenced by dumpDumpableObject().

◆ dumpRelationStats_dumper()

static char * dumpRelationStats_dumper ( Archive fout,
const void *  userArg,
const TocEntry te 
)
static

Definition at line 11102 of file pg_dump.c.

11103{
11104 const RelStatsInfo *rsinfo = (RelStatsInfo *) userArg;
11105 static PGresult *res;
11106 static int rownum;
11107 PQExpBuffer query;
11108 PQExpBufferData out_data;
11109 PQExpBuffer out = &out_data;
11110 int i_schemaname;
11111 int i_tablename;
11112 int i_attname;
11113 int i_inherited;
11114 int i_null_frac;
11115 int i_avg_width;
11116 int i_n_distinct;
11117 int i_most_common_vals;
11118 int i_most_common_freqs;
11119 int i_histogram_bounds;
11120 int i_correlation;
11121 int i_most_common_elems;
11122 int i_most_common_elem_freqs;
11123 int i_elem_count_histogram;
11124 int i_range_length_histogram;
11125 int i_range_empty_frac;
11126 int i_range_bounds_histogram;
11127 static TocEntry *expected_te;
11128
11129 /*
11130 * fetchAttributeStats() assumes that the statistics are dumped in the
11131 * order they are listed in the TOC. We verify that here for safety.
11132 */
11133 if (!expected_te)
11134 expected_te = ((ArchiveHandle *) fout)->toc;
11135
11136 expected_te = expected_te->next;
11137 while ((expected_te->reqs & REQ_STATS) == 0 ||
11138 strcmp(expected_te->desc, "STATISTICS DATA") != 0)
11139 expected_te = expected_te->next;
11140
11141 if (te != expected_te)
11142 pg_fatal("statistics dumped out of order (current: %d %s %s, expected: %d %s %s)",
11143 te->dumpId, te->desc, te->tag,
11144 expected_te->dumpId, expected_te->desc, expected_te->tag);
11145
11146 query = createPQExpBuffer();
11148 {
11150 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
11151 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
11152 "s.null_frac, s.avg_width, s.n_distinct, "
11153 "s.most_common_vals, s.most_common_freqs, "
11154 "s.histogram_bounds, s.correlation, "
11155 "s.most_common_elems, s.most_common_elem_freqs, "
11156 "s.elem_count_histogram, ");
11157
11158 if (fout->remoteVersion >= 170000)
11160 "s.range_length_histogram, "
11161 "s.range_empty_frac, "
11162 "s.range_bounds_histogram ");
11163 else
11165 "NULL AS range_length_histogram,"
11166 "NULL AS range_empty_frac,"
11167 "NULL AS range_bounds_histogram ");
11168
11169 /*
11170 * The results must be in the order of the relations supplied in the
11171 * parameters to ensure we remain in sync as we walk through the TOC.
11172 * The redundant filter clause on s.tablename = ANY(...) seems
11173 * sufficient to convince the planner to use
11174 * pg_class_relname_nsp_index, which avoids a full scan of pg_stats.
11175 * This may not work for all versions.
11176 *
11177 * Our query for retrieving statistics for multiple relations uses
11178 * WITH ORDINALITY and multi-argument UNNEST(), both of which were
11179 * introduced in v9.4. For older versions, we resort to gathering
11180 * statistics for a single relation at a time.
11181 */
11182 if (fout->remoteVersion >= 90400)
11184 "FROM pg_catalog.pg_stats s "
11185 "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) "
11186 "ON s.schemaname = u.schemaname "
11187 "AND s.tablename = u.tablename "
11188 "WHERE s.tablename = ANY($2) "
11189 "ORDER BY u.ord, s.attname, s.inherited");
11190 else
11192 "FROM pg_catalog.pg_stats s "
11193 "WHERE s.schemaname = $1[1] "
11194 "AND s.tablename = $2[1] "
11195 "ORDER BY s.attname, s.inherited");
11196
11197 ExecuteSqlStatement(fout, query->data);
11198
11200 resetPQExpBuffer(query);
11201 }
11202
11203 initPQExpBuffer(out);
11204
11205 /* restore relation stats */
11206 appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
11207 appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
11208 fout->remoteVersion);
11209 appendPQExpBufferStr(out, "\t'schemaname', ");
11210 appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
11211 appendPQExpBufferStr(out, ",\n");
11212 appendPQExpBufferStr(out, "\t'relname', ");
11213 appendStringLiteralAH(out, rsinfo->dobj.name, fout);
11214 appendPQExpBufferStr(out, ",\n");
11215 appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
11216
11217 /*
11218 * Before v14, a reltuples value of 0 was ambiguous: it could either mean
11219 * the relation is empty, or it could mean that it hadn't yet been
11220 * vacuumed or analyzed. (Newer versions use -1 for the latter case.)
11221 * This ambiguity allegedly can cause the planner to choose inefficient
11222 * plans after restoring to v18 or newer. To deal with this, let's just
11223 * set reltuples to -1 in that case.
11224 */
11225 if (fout->remoteVersion < 140000 && strcmp("0", rsinfo->reltuples) == 0)
11226 appendPQExpBufferStr(out, "\t'reltuples', '-1'::real,\n");
11227 else
11228 appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", rsinfo->reltuples);
11229
11230 appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer",
11231 rsinfo->relallvisible);
11232
11233 if (fout->remoteVersion >= 180000)
11234 appendPQExpBuffer(out, ",\n\t'relallfrozen', '%d'::integer", rsinfo->relallfrozen);
11235
11236 appendPQExpBufferStr(out, "\n);\n");
11237
11238 /* Fetch the next batch of attribute statistics if needed. */
11239 if (rownum >= PQntuples(res))
11240 {
11241 PQclear(res);
11242 res = fetchAttributeStats(fout);
11243 rownum = 0;
11244 }
11245
11246 i_schemaname = PQfnumber(res, "schemaname");
11247 i_tablename = PQfnumber(res, "tablename");
11248 i_attname = PQfnumber(res, "attname");
11249 i_inherited = PQfnumber(res, "inherited");
11250 i_null_frac = PQfnumber(res, "null_frac");
11251 i_avg_width = PQfnumber(res, "avg_width");
11252 i_n_distinct = PQfnumber(res, "n_distinct");
11253 i_most_common_vals = PQfnumber(res, "most_common_vals");
11254 i_most_common_freqs = PQfnumber(res, "most_common_freqs");
11255 i_histogram_bounds = PQfnumber(res, "histogram_bounds");
11256 i_correlation = PQfnumber(res, "correlation");
11257 i_most_common_elems = PQfnumber(res, "most_common_elems");
11258 i_most_common_elem_freqs = PQfnumber(res, "most_common_elem_freqs");
11259 i_elem_count_histogram = PQfnumber(res, "elem_count_histogram");
11260 i_range_length_histogram = PQfnumber(res, "range_length_histogram");
11261 i_range_empty_frac = PQfnumber(res, "range_empty_frac");
11262 i_range_bounds_histogram = PQfnumber(res, "range_bounds_histogram");
11263
11264 /* restore attribute stats */
11265 for (; rownum < PQntuples(res); rownum++)
11266 {
11267 const char *attname;
11268
11269 /* Stop if the next stat row in our cache isn't for this relation. */
11270 if (strcmp(te->tag, PQgetvalue(res, rownum, i_tablename)) != 0 ||
11271 strcmp(te->namespace, PQgetvalue(res, rownum, i_schemaname)) != 0)
11272 break;
11273
11274 appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n");
11275 appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
11276 fout->remoteVersion);
11277 appendPQExpBufferStr(out, "\t'schemaname', ");
11278 appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
11279 appendPQExpBufferStr(out, ",\n\t'relname', ");
11280 appendStringLiteralAH(out, rsinfo->dobj.name, fout);
11281
11282 if (PQgetisnull(res, rownum, i_attname))
11283 pg_fatal("unexpected null attname");
11284 attname = PQgetvalue(res, rownum, i_attname);
11285
11286 /*
11287 * Indexes look up attname in indAttNames to derive attnum, all others
11288 * use attname directly. We must specify attnum for indexes, since
11289 * their attnames are not necessarily stable across dump/reload.
11290 */
11291 if (rsinfo->nindAttNames == 0)
11292 {
11293 appendPQExpBufferStr(out, ",\n\t'attname', ");
11294 appendStringLiteralAH(out, attname, fout);
11295 }
11296 else
11297 {
11298 bool found = false;
11299
11300 for (int i = 0; i < rsinfo->nindAttNames; i++)
11301 {
11302 if (strcmp(attname, rsinfo->indAttNames[i]) == 0)
11303 {
11304 appendPQExpBuffer(out, ",\n\t'attnum', '%d'::smallint",
11305 i + 1);
11306 found = true;
11307 break;
11308 }
11309 }
11310
11311 if (!found)
11312 pg_fatal("could not find index attname \"%s\"", attname);
11313 }
11314
11315 if (!PQgetisnull(res, rownum, i_inherited))
11316 appendNamedArgument(out, fout, "inherited", "boolean",
11317 PQgetvalue(res, rownum, i_inherited));
11318 if (!PQgetisnull(res, rownum, i_null_frac))
11319 appendNamedArgument(out, fout, "null_frac", "real",
11320 PQgetvalue(res, rownum, i_null_frac));
11321 if (!PQgetisnull(res, rownum, i_avg_width))
11322 appendNamedArgument(out, fout, "avg_width", "integer",
11323 PQgetvalue(res, rownum, i_avg_width));
11324 if (!PQgetisnull(res, rownum, i_n_distinct))
11325 appendNamedArgument(out, fout, "n_distinct", "real",
11326 PQgetvalue(res, rownum, i_n_distinct));
11327 if (!PQgetisnull(res, rownum, i_most_common_vals))
11328 appendNamedArgument(out, fout, "most_common_vals", "text",
11329 PQgetvalue(res, rownum, i_most_common_vals));
11330 if (!PQgetisnull(res, rownum, i_most_common_freqs))
11331 appendNamedArgument(out, fout, "most_common_freqs", "real[]",
11332 PQgetvalue(res, rownum, i_most_common_freqs));
11333 if (!PQgetisnull(res, rownum, i_histogram_bounds))
11334 appendNamedArgument(out, fout, "histogram_bounds", "text",
11335 PQgetvalue(res, rownum, i_histogram_bounds));
11336 if (!PQgetisnull(res, rownum, i_correlation))
11337 appendNamedArgument(out, fout, "correlation", "real",
11338 PQgetvalue(res, rownum, i_correlation));
11339 if (!PQgetisnull(res, rownum, i_most_common_elems))
11340 appendNamedArgument(out, fout, "most_common_elems", "text",
11341 PQgetvalue(res, rownum, i_most_common_elems));
11342 if (!PQgetisnull(res, rownum, i_most_common_elem_freqs))
11343 appendNamedArgument(out, fout, "most_common_elem_freqs", "real[]",
11344 PQgetvalue(res, rownum, i_most_common_elem_freqs));
11345 if (!PQgetisnull(res, rownum, i_elem_count_histogram))
11346 appendNamedArgument(out, fout, "elem_count_histogram", "real[]",
11347 PQgetvalue(res, rownum, i_elem_count_histogram));
11348 if (fout->remoteVersion >= 170000)
11349 {
11350 if (!PQgetisnull(res, rownum, i_range_length_histogram))
11351 appendNamedArgument(out, fout, "range_length_histogram", "text",
11352 PQgetvalue(res, rownum, i_range_length_histogram));
11353 if (!PQgetisnull(res, rownum, i_range_empty_frac))
11354 appendNamedArgument(out, fout, "range_empty_frac", "real",
11355 PQgetvalue(res, rownum, i_range_empty_frac));
11356 if (!PQgetisnull(res, rownum, i_range_bounds_histogram))
11357 appendNamedArgument(out, fout, "range_bounds_histogram", "text",
11358 PQgetvalue(res, rownum, i_range_bounds_histogram));
11359 }
11360 appendPQExpBufferStr(out, "\n);\n");
11361 }
11362
11363 destroyPQExpBuffer(query);
11364 return out->data;
11365}
@ PREPQUERY_GETATTRIBUTESTATS
Definition: pg_backup.h:75
#define REQ_STATS
static PGresult * fetchAttributeStats(Archive *fout)
Definition: pg_dump.c:11014
static void appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname, const char *argtype, const char *argval)
Definition: pg_dump.c:10996
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
int32 nindAttNames
Definition: pg_dump.h:462
char ** indAttNames
Definition: pg_dump.h:461
int32 relpages
Definition: pg_dump.h:451
int32 relallfrozen
Definition: pg_dump.h:454
char * reltuples
Definition: pg_dump.h:452
int32 relallvisible
Definition: pg_dump.h:453

References appendNamedArgument(), appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, attname, createPQExpBuffer(), PQExpBufferData::data, _tocEntry::desc, destroyPQExpBuffer(), _relStatsInfo::dobj, _tocEntry::dumpId, ExecuteSqlStatement(), fetchAttributeStats(), i, if(), _relStatsInfo::indAttNames, initPQExpBuffer(), Archive::is_prepared, _dumpableObject::name, _tocEntry::next, _relStatsInfo::nindAttNames, pg_fatal, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, PREPQUERY_GETATTRIBUTESTATS, _relStatsInfo::relallfrozen, _relStatsInfo::relallvisible, _relStatsInfo::relpages, _relStatsInfo::reltuples, Archive::remoteVersion, REQ_STATS, _tocEntry::reqs, resetPQExpBuffer(), and _tocEntry::tag.

Referenced by dumpRelationStats().

◆ dumpRule()

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

Definition at line 19519 of file pg_dump.c.

19520{
19521 DumpOptions *dopt = fout->dopt;
19522 TableInfo *tbinfo = rinfo->ruletable;
19523 bool is_view;
19524 PQExpBuffer query;
19525 PQExpBuffer cmd;
19526 PQExpBuffer delcmd;
19527 PQExpBuffer ruleprefix;
19528 char *qtabname;
19529 PGresult *res;
19530 char *tag;
19531
19532 /* Do nothing if not dumping schema */
19533 if (!dopt->dumpSchema)
19534 return;
19535
19536 /*
19537 * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
19538 * we do not want to dump it as a separate object.
19539 */
19540 if (!rinfo->separate)
19541 return;
19542
19543 /*
19544 * If it's an ON SELECT rule, we want to print it as a view definition,
19545 * instead of a rule.
19546 */
19547 is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
19548
19549 query = createPQExpBuffer();
19550 cmd = createPQExpBuffer();
19551 delcmd = createPQExpBuffer();
19552 ruleprefix = createPQExpBuffer();
19553
19554 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
19555
19556 if (is_view)
19557 {
19558 PQExpBuffer result;
19559
19560 /*
19561 * We need OR REPLACE here because we'll be replacing a dummy view.
19562 * Otherwise this should look largely like the regular view dump code.
19563 */
19564 appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
19565 fmtQualifiedDumpable(tbinfo));
19566 if (nonemptyReloptions(tbinfo->reloptions))
19567 {
19568 appendPQExpBufferStr(cmd, " WITH (");
19569 appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
19570 appendPQExpBufferChar(cmd, ')');
19571 }
19572 result = createViewAsClause(fout, tbinfo);
19573 appendPQExpBuffer(cmd, " AS\n%s", result->data);
19574 destroyPQExpBuffer(result);
19575 if (tbinfo->checkoption != NULL)
19576 appendPQExpBuffer(cmd, "\n WITH %s CHECK OPTION",
19577 tbinfo->checkoption);
19578 appendPQExpBufferStr(cmd, ";\n");
19579 }
19580 else
19581 {
19582 /* In the rule case, just print pg_get_ruledef's result verbatim */
19583 appendPQExpBuffer(query,
19584 "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
19585 rinfo->dobj.catId.oid);
19586
19587 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19588
19589 if (PQntuples(res) != 1)
19590 pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
19591 rinfo->dobj.name, tbinfo->dobj.name);
19592
19593 printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
19594
19595 PQclear(res);
19596 }
19597
19598 /*
19599 * Add the command to alter the rules replication firing semantics if it
19600 * differs from the default.
19601 */
19602 if (rinfo->ev_enabled != 'O')
19603 {
19604 appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
19605 switch (rinfo->ev_enabled)
19606 {
19607 case 'A':
19608 appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
19609 fmtId(rinfo->dobj.name));
19610 break;
19611 case 'R':
19612 appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
19613 fmtId(rinfo->dobj.name));
19614 break;
19615 case 'D':
19616 appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
19617 fmtId(rinfo->dobj.name));
19618 break;
19619 }
19620 }
19621
19622 if (is_view)
19623 {
19624 /*
19625 * We can't DROP a view's ON SELECT rule. Instead, use CREATE OR
19626 * REPLACE VIEW to replace the rule with something with minimal
19627 * dependencies.
19628 */
19629 PQExpBuffer result;
19630
19631 appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
19632 fmtQualifiedDumpable(tbinfo));
19633 result = createDummyViewAsClause(fout, tbinfo);
19634 appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
19635 destroyPQExpBuffer(result);
19636 }
19637 else
19638 {
19639 appendPQExpBuffer(delcmd, "DROP RULE %s ",
19640 fmtId(rinfo->dobj.name));
19641 appendPQExpBuffer(delcmd, "ON %s;\n",
19642 fmtQualifiedDumpable(tbinfo));
19643 }
19644
19645 appendPQExpBuffer(ruleprefix, "RULE %s ON",
19646 fmtId(rinfo->dobj.name));
19647
19648 tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
19649
19650 if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19651 ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
19652 ARCHIVE_OPTS(.tag = tag,
19653 .namespace = tbinfo->dobj.namespace->dobj.name,
19654 .owner = tbinfo->rolname,
19655 .description = "RULE",
19656 .section = SECTION_POST_DATA,
19657 .createStmt = cmd->data,
19658 .dropStmt = delcmd->data));
19659
19660 /* Dump rule comments */
19661 if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19662 dumpComment(fout, ruleprefix->data, qtabname,
19663 tbinfo->dobj.namespace->dobj.name,
19664 tbinfo->rolname,
19665 rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
19666
19667 free(tag);
19668 destroyPQExpBuffer(query);
19669 destroyPQExpBuffer(cmd);
19670 destroyPQExpBuffer(delcmd);
19671 destroyPQExpBuffer(ruleprefix);
19672 free(qtabname);
19673}
static PQExpBuffer createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:17052
static PQExpBuffer createViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:17003
DumpableObject dobj
Definition: pg_dump.h:476
bool separate
Definition: pg_dump.h:481
char ev_enabled
Definition: pg_dump.h:480
bool is_instead
Definition: pg_dump.h:479
TableInfo * ruletable
Definition: pg_dump.h:477
char ev_type
Definition: pg_dump.h:478
char * checkoption
Definition: pg_dump.h:316
char * reloptions
Definition: pg_dump.h:315

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArrayAH(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, _tableInfo::checkoption, createDummyViewAsClause(), createPQExpBuffer(), createViewAsClause(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _ruleInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, _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, _tableInfo::rolname, _ruleInfo::ruletable, SECTION_POST_DATA, and _ruleInfo::separate.

Referenced by dumpDumpableObject().

◆ dumpSearchPath()

static void dumpSearchPath ( Archive AH)
static

Definition at line 3884 of file pg_dump.c.

3885{
3888 PGresult *res;
3889 char **schemanames = NULL;
3890 int nschemanames = 0;
3891 int i;
3892
3893 /*
3894 * We use the result of current_schemas(), not the search_path GUC,
3895 * because that might contain wildcards such as "$user", which won't
3896 * necessarily have the same value during restore. Also, this way avoids
3897 * listing schemas that may appear in search_path but not actually exist,
3898 * which seems like a prudent exclusion.
3899 */
3901 "SELECT pg_catalog.current_schemas(false)");
3902
3903 if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
3904 pg_fatal("could not parse result of current_schemas()");
3905
3906 /*
3907 * We use set_config(), not a simple "SET search_path" command, because
3908 * the latter has less-clean behavior if the search path is empty. While
3909 * that's likely to get fixed at some point, it seems like a good idea to
3910 * be as backwards-compatible as possible in what we put into archives.
3911 */
3912 for (i = 0; i < nschemanames; i++)
3913 {
3914 if (i > 0)
3915 appendPQExpBufferStr(path, ", ");
3916 appendPQExpBufferStr(path, fmtId(schemanames[i]));
3917 }
3918
3919 appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
3920 appendStringLiteralAH(qry, path->data, AH);
3921 appendPQExpBufferStr(qry, ", false);\n");
3922
3923 pg_log_info("saving \"search_path = %s\"", path->data);
3924
3926 ARCHIVE_OPTS(.tag = "SEARCHPATH",
3927 .description = "SEARCHPATH",
3928 .section = SECTION_PRE_DATA,
3929 .createStmt = qry->data));
3930
3931 /* Also save it in AH->searchpath, in case we're doing plain text dump */
3932 AH->searchpath = pg_strdup(qry->data);
3933
3934 free(schemanames);
3935 PQclear(res);
3936 destroyPQExpBuffer(qry);
3937 destroyPQExpBuffer(path);
3938}
char * searchpath
Definition: pg_backup.h:247

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

16539{
16540 DumpOptions *dopt = fout->dopt;
16541 SecLabelItem *labels;
16542 int nlabels;
16543 int i;
16544 PQExpBuffer query;
16545
16546 /* do nothing, if --no-security-labels is supplied */
16547 if (dopt->no_security_labels)
16548 return;
16549
16550 /*
16551 * Security labels are schema not data ... except large object labels are
16552 * data
16553 */
16554 if (strcmp(type, "LARGE OBJECT") != 0)
16555 {
16556 if (!dopt->dumpSchema)
16557 return;
16558 }
16559 else
16560 {
16561 /* We do dump large object security labels in binary-upgrade mode */
16562 if (!dopt->dumpData && !dopt->binary_upgrade)
16563 return;
16564 }
16565
16566 /* Search for security labels associated with catalogId, using table */
16567 nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
16568
16569 query = createPQExpBuffer();
16570
16571 for (i = 0; i < nlabels; i++)
16572 {
16573 /*
16574 * Ignore label entries for which the subid doesn't match.
16575 */
16576 if (labels[i].objsubid != subid)
16577 continue;
16578
16579 appendPQExpBuffer(query,
16580 "SECURITY LABEL FOR %s ON %s ",
16581 fmtId(labels[i].provider), type);
16582 if (namespace && *namespace)
16583 appendPQExpBuffer(query, "%s.", fmtId(namespace));
16584 appendPQExpBuffer(query, "%s IS ", name);
16585 appendStringLiteralAH(query, labels[i].label, fout);
16586 appendPQExpBufferStr(query, ";\n");
16587 }
16588
16589 if (query->len > 0)
16590 {
16592
16593 appendPQExpBuffer(tag, "%s %s", type, name);
16595 ARCHIVE_OPTS(.tag = tag->data,
16596 .namespace = namespace,
16597 .owner = owner,
16598 .description = "SECURITY LABEL",
16599 .section = SECTION_NONE,
16600 .createStmt = query->data,
16601 .deps = &dumpId,
16602 .nDeps = 1));
16603 destroyPQExpBuffer(tag);
16604 }
16605
16606 destroyPQExpBuffer(query);
16607}
static int findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
Definition: pg_dump.c:16698

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

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

◆ dumpSequence()

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

Definition at line 18972 of file pg_dump.c.

18973{
18974 DumpOptions *dopt = fout->dopt;
18975 SequenceItem *seq;
18976 bool is_ascending;
18977 int64 default_minv,
18978 default_maxv;
18980 PQExpBuffer delqry = createPQExpBuffer();
18981 char *qseqname;
18982 TableInfo *owning_tab = NULL;
18983
18984 qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
18985
18986 /*
18987 * For versions >= 10, the sequence information is gathered in a sorted
18988 * table before any calls to dumpSequence(). See collectSequences() for
18989 * more information.
18990 */
18991 if (fout->remoteVersion >= 100000)
18992 {
18993 SequenceItem key = {0};
18994
18996
18997 key.oid = tbinfo->dobj.catId.oid;
18998 seq = bsearch(&key, sequences, nsequences,
18999 sizeof(SequenceItem), SequenceItemCmp);
19000 }
19001 else
19002 {
19003 PGresult *res;
19004
19005 /*
19006 * Before PostgreSQL 10, sequence metadata is in the sequence itself.
19007 *
19008 * Note: it might seem that 'bigint' potentially needs to be
19009 * schema-qualified, but actually that's a keyword.
19010 */
19011 appendPQExpBuffer(query,
19012 "SELECT 'bigint' AS sequence_type, "
19013 "start_value, increment_by, max_value, min_value, "
19014 "cache_value, is_cycled FROM %s",
19015 fmtQualifiedDumpable(tbinfo));
19016
19017 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19018
19019 if (PQntuples(res) != 1)
19020 pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
19021 "query to get data of sequence \"%s\" returned %d rows (expected 1)",
19022 PQntuples(res)),
19023 tbinfo->dobj.name, PQntuples(res));
19024
19025 seq = pg_malloc0(sizeof(SequenceItem));
19026 seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0));
19027 seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10);
19028 seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10);
19029 seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10);
19030 seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10);
19031 seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10);
19032 seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
19033
19034 PQclear(res);
19035 }
19036
19037 /* Calculate default limits for a sequence of this type */
19038 is_ascending = (seq->incby >= 0);
19039 if (seq->seqtype == SEQTYPE_SMALLINT)
19040 {
19041 default_minv = is_ascending ? 1 : PG_INT16_MIN;
19042 default_maxv = is_ascending ? PG_INT16_MAX : -1;
19043 }
19044 else if (seq->seqtype == SEQTYPE_INTEGER)
19045 {
19046 default_minv = is_ascending ? 1 : PG_INT32_MIN;
19047 default_maxv = is_ascending ? PG_INT32_MAX : -1;
19048 }
19049 else if (seq->seqtype == SEQTYPE_BIGINT)
19050 {
19051 default_minv = is_ascending ? 1 : PG_INT64_MIN;
19052 default_maxv = is_ascending ? PG_INT64_MAX : -1;
19053 }
19054 else
19055 {
19056 pg_fatal("unrecognized sequence type: %d", seq->seqtype);
19057 default_minv = default_maxv = 0; /* keep compiler quiet */
19058 }
19059
19060 /*
19061 * Identity sequences are not to be dropped separately.
19062 */
19063 if (!tbinfo->is_identity_sequence)
19064 {
19065 appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
19066 fmtQualifiedDumpable(tbinfo));
19067 }
19068
19069 resetPQExpBuffer(query);
19070
19071 if (dopt->binary_upgrade)
19072 {
19074 tbinfo->dobj.catId.oid);
19075
19076 /*
19077 * In older PG versions a sequence will have a pg_type entry, but v14
19078 * and up don't use that, so don't attempt to preserve the type OID.
19079 */
19080 }
19081
19082 if (tbinfo->is_identity_sequence)
19083 {
19084 owning_tab = findTableByOid(tbinfo->owning_tab);
19085
19086 appendPQExpBuffer(query,
19087 "ALTER TABLE %s ",
19088 fmtQualifiedDumpable(owning_tab));
19089 appendPQExpBuffer(query,
19090 "ALTER COLUMN %s ADD GENERATED ",
19091 fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
19092 if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
19093 appendPQExpBufferStr(query, "ALWAYS");
19094 else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
19095 appendPQExpBufferStr(query, "BY DEFAULT");
19096 appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n",
19097 fmtQualifiedDumpable(tbinfo));
19098
19099 /*
19100 * Emit persistence option only if it's different from the owning
19101 * table's. This avoids using this new syntax unnecessarily.
19102 */
19103 if (tbinfo->relpersistence != owning_tab->relpersistence)
19104 appendPQExpBuffer(query, " %s\n",
19105 tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
19106 "UNLOGGED" : "LOGGED");
19107 }
19108 else
19109 {
19110 appendPQExpBuffer(query,
19111 "CREATE %sSEQUENCE %s\n",
19112 tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
19113 "UNLOGGED " : "",
19114 fmtQualifiedDumpable(tbinfo));
19115
19116 if (seq->seqtype != SEQTYPE_BIGINT)
19117 appendPQExpBuffer(query, " AS %s\n", SeqTypeNames[seq->seqtype]);
19118 }
19119
19120 appendPQExpBuffer(query, " START WITH " INT64_FORMAT "\n", seq->startv);
19121
19122 appendPQExpBuffer(query, " INCREMENT BY " INT64_FORMAT "\n", seq->incby);
19123
19124 if (seq->minv != default_minv)
19125 appendPQExpBuffer(query, " MINVALUE " INT64_FORMAT "\n", seq->minv);
19126 else
19127 appendPQExpBufferStr(query, " NO MINVALUE\n");
19128
19129 if (seq->maxv != default_maxv)
19130 appendPQExpBuffer(query, " MAXVALUE " INT64_FORMAT "\n", seq->maxv);
19131 else
19132 appendPQExpBufferStr(query, " NO MAXVALUE\n");
19133
19134 appendPQExpBuffer(query,
19135 " CACHE " INT64_FORMAT "%s",
19136 seq->cache, (seq->cycled ? "\n CYCLE" : ""));
19137
19138 if (tbinfo->is_identity_sequence)
19139 appendPQExpBufferStr(query, "\n);\n");
19140 else
19141 appendPQExpBufferStr(query, ";\n");
19142
19143 /* binary_upgrade: no need to clear TOAST table oid */
19144
19145 if (dopt->binary_upgrade)
19146 binary_upgrade_extension_member(query, &tbinfo->dobj,
19147 "SEQUENCE", qseqname,
19148 tbinfo->dobj.namespace->dobj.name);
19149
19150 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19151 ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
19152 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
19153 .namespace = tbinfo->dobj.namespace->dobj.name,
19154 .owner = tbinfo->rolname,
19155 .description = "SEQUENCE",
19156 .section = SECTION_PRE_DATA,
19157 .createStmt = query->data,
19158 .dropStmt = delqry->data));
19159
19160 /*
19161 * If the sequence is owned by a table column, emit the ALTER for it as a
19162 * separate TOC entry immediately following the sequence's own entry. It's
19163 * OK to do this rather than using full sorting logic, because the
19164 * dependency that tells us it's owned will have forced the table to be
19165 * created first. We can't just include the ALTER in the TOC entry
19166 * because it will fail if we haven't reassigned the sequence owner to
19167 * match the table's owner.
19168 *
19169 * We need not schema-qualify the table reference because both sequence
19170 * and table must be in the same schema.
19171 */
19172 if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
19173 {
19174 owning_tab = findTableByOid(tbinfo->owning_tab);
19175
19176 if (owning_tab == NULL)
19177 pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
19178 tbinfo->owning_tab, tbinfo->dobj.catId.oid);
19179
19180 if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
19181 {
19182 resetPQExpBuffer(query);
19183 appendPQExpBuffer(query, "ALTER SEQUENCE %s",
19184 fmtQualifiedDumpable(tbinfo));
19185 appendPQExpBuffer(query, " OWNED BY %s",
19186 fmtQualifiedDumpable(owning_tab));
19187 appendPQExpBuffer(query, ".%s;\n",
19188 fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
19189
19190 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19192 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
19193 .namespace = tbinfo->dobj.namespace->dobj.name,
19194 .owner = tbinfo->rolname,
19195 .description = "SEQUENCE OWNED BY",
19196 .section = SECTION_PRE_DATA,
19197 .createStmt = query->data,
19198 .deps = &(tbinfo->dobj.dumpId),
19199 .nDeps = 1));
19200 }
19201 }
19202
19203 /* Dump Sequence Comments and Security Labels */
19204 if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19205 dumpComment(fout, "SEQUENCE", qseqname,
19206 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
19207 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
19208
19209 if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
19210 dumpSecLabel(fout, "SEQUENCE", qseqname,
19211 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
19212 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
19213
19214 if (fout->remoteVersion < 100000)
19215 pg_free(seq);
19216 destroyPQExpBuffer(query);
19217 destroyPQExpBuffer(delqry);
19218 free(qseqname);
19219}
TableInfo * findTableByOid(Oid oid)
Definition: common.c:863
#define PG_INT32_MAX
Definition: c.h:608
#define ngettext(s, p, n)
Definition: c.h:1179
#define INT64_FORMAT
Definition: c.h:570
int64_t int64
Definition: c.h:549
#define PG_INT16_MIN
Definition: c.h:604
#define PG_INT64_MAX
Definition: c.h:611
#define PG_INT64_MIN
Definition: c.h:610
#define PG_INT32_MIN
Definition: c.h:607
#define PG_INT16_MAX
Definition: c.h:605
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static int SequenceItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:18896
static const char *const SeqTypeNames[]
Definition: pg_dump.c:118
char * attidentity
Definition: pg_dump.h:361
bool is_identity_sequence
Definition: pg_dump.h:337
int owning_col
Definition: pg_dump.h:336
Oid owning_tab
Definition: pg_dump.h:335
char relpersistence
Definition: pg_dump.h:311

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

Referenced by dumpTable().

◆ dumpSequenceData()

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

Definition at line 19226 of file pg_dump.c.

19227{
19228 TableInfo *tbinfo = tdinfo->tdtable;
19229 int64 last;
19230 bool called;
19232
19233 /*
19234 * For versions >= 18, the sequence information is gathered in the sorted
19235 * array before any calls to dumpSequenceData(). See collectSequences()
19236 * for more information.
19237 *
19238 * For older versions, we have to query the sequence relations
19239 * individually.
19240 */
19241 if (fout->remoteVersion < 180000)
19242 {
19243 PGresult *res;
19244
19245 appendPQExpBuffer(query,
19246 "SELECT last_value, is_called FROM %s",
19247 fmtQualifiedDumpable(tbinfo));
19248
19249 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19250
19251 if (PQntuples(res) != 1)
19252 pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
19253 "query to get data of sequence \"%s\" returned %d rows (expected 1)",
19254 PQntuples(res)),
19255 tbinfo->dobj.name, PQntuples(res));
19256
19257 last = strtoi64(PQgetvalue(res, 0, 0), NULL, 10);
19258 called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
19259
19260 PQclear(res);
19261 }
19262 else
19263 {
19264 SequenceItem key = {0};
19265 SequenceItem *entry;
19266
19268 Assert(tbinfo->dobj.catId.oid);
19269
19270 key.oid = tbinfo->dobj.catId.oid;
19271 entry = bsearch(&key, sequences, nsequences,
19272 sizeof(SequenceItem), SequenceItemCmp);
19273
19274 last = entry->last_value;
19275 called = entry->is_called;
19276 }
19277
19278 resetPQExpBuffer(query);
19279 appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
19280 appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
19281 appendPQExpBuffer(query, ", " INT64_FORMAT ", %s);\n",
19282 last, (called ? "true" : "false"));
19283
19284 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
19286 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
19287 .namespace = tbinfo->dobj.namespace->dobj.name,
19288 .owner = tbinfo->rolname,
19289 .description = "SEQUENCE SET",
19290 .section = SECTION_DATA,
19291 .createStmt = query->data,
19292 .deps = &(tbinfo->dobj.dumpId),
19293 .nDeps = 1));
19294
19295 destroyPQExpBuffer(query);
19296}
TableInfo * tdtable
Definition: pg_dump.h:414
DumpableObject dobj
Definition: pg_dump.h:413

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

Referenced by dumpDumpableObject().

◆ dumpShellType()

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

Definition at line 13219 of file pg_dump.c.

13220{
13221 DumpOptions *dopt = fout->dopt;
13222 PQExpBuffer q;
13223
13224 /* Do nothing if not dumping schema */
13225 if (!dopt->dumpSchema)
13226 return;
13227
13228 q = createPQExpBuffer();
13229
13230 /*
13231 * Note the lack of a DROP command for the shell type; any required DROP
13232 * is driven off the base type entry, instead. This interacts with
13233 * _printTocEntry()'s use of the presence of a DROP command to decide
13234 * whether an entry needs an ALTER OWNER command. We don't want to alter
13235 * the shell type's owner immediately on creation; that should happen only
13236 * after it's filled in, otherwise the backend complains.
13237 */
13238
13239 if (dopt->binary_upgrade)
13241 stinfo->baseType->dobj.catId.oid,
13242 false, false);
13243
13244 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
13245 fmtQualifiedDumpable(stinfo));
13246
13247 if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13248 ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
13249 ARCHIVE_OPTS(.tag = stinfo->dobj.name,
13250 .namespace = stinfo->dobj.namespace->dobj.name,
13251 .owner = stinfo->baseType->rolname,
13252 .description = "SHELL TYPE",
13253 .section = SECTION_PRE_DATA,
13254 .createStmt = q->data));
13255
13257}
TypeInfo * baseType
Definition: pg_dump.h:236
DumpableObject dobj
Definition: pg_dump.h:234

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _shellTypeInfo::baseType, _dumpOptions::binary_upgrade, binary_upgrade_set_type_oids_by_type_oid(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _typeInfo::dobj, _shellTypeInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 18459 of file pg_dump.c.

18460{
18461 DumpOptions *dopt = fout->dopt;
18462 PQExpBuffer q;
18463 PQExpBuffer delq;
18464 PQExpBuffer query;
18465 char *qstatsextname;
18466 PGresult *res;
18467 char *stxdef;
18468
18469 /* Do nothing if not dumping schema */
18470 if (!dopt->dumpSchema)
18471 return;
18472
18473 q = createPQExpBuffer();
18474 delq = createPQExpBuffer();
18475 query = createPQExpBuffer();
18476
18477 qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
18478
18479 appendPQExpBuffer(query, "SELECT "
18480 "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
18481 statsextinfo->dobj.catId.oid);
18482
18483 res = ExecuteSqlQueryForSingleRow(fout, query->data);
18484
18485 stxdef = PQgetvalue(res, 0, 0);
18486
18487 /* Result of pg_get_statisticsobjdef is complete except for semicolon */
18488 appendPQExpBuffer(q, "%s;\n", stxdef);
18489
18490 /*
18491 * We only issue an ALTER STATISTICS statement if the stxstattarget entry
18492 * for this statistics object is not the default value.
18493 */
18494 if (statsextinfo->stattarget >= 0)
18495 {
18496 appendPQExpBuffer(q, "ALTER STATISTICS %s ",
18497 fmtQualifiedDumpable(statsextinfo));
18498 appendPQExpBuffer(q, "SET STATISTICS %d;\n",
18499 statsextinfo->stattarget);
18500 }
18501
18502 appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
18503 fmtQualifiedDumpable(statsextinfo));
18504
18505 if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18506 ArchiveEntry(fout, statsextinfo->dobj.catId,
18507 statsextinfo->dobj.dumpId,
18508 ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
18509 .namespace = statsextinfo->dobj.namespace->dobj.name,
18510 .owner = statsextinfo->rolname,
18511 .description = "STATISTICS",
18512 .section = SECTION_POST_DATA,
18513 .createStmt = q->data,
18514 .dropStmt = delq->data));
18515
18516 /* Dump Statistics Comments */
18517 if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18518 dumpComment(fout, "STATISTICS", qstatsextname,
18519 statsextinfo->dobj.namespace->dobj.name,
18520 statsextinfo->rolname,
18521 statsextinfo->dobj.catId, 0,
18522 statsextinfo->dobj.dumpId);
18523
18524 PQclear(res);
18526 destroyPQExpBuffer(delq);
18527 destroyPQExpBuffer(query);
18528 free(qstatsextname);
18529}
int stattarget
Definition: pg_dump.h:471
const char * rolname
Definition: pg_dump.h:469
DumpableObject dobj
Definition: pg_dump.h:468

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _statsExtInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, ExecuteSqlQueryForSingleRow(), fmtId(), fmtQualifiedDumpable, free, _dumpableObject::name, CatalogId::oid, pg_strdup(), PQclear, PQgetvalue, _statsExtInfo::rolname, SECTION_POST_DATA, and _statsExtInfo::stattarget.

Referenced by dumpDumpableObject().

◆ dumpStdStrings()

static void dumpStdStrings ( Archive AH)
static

Definition at line 3860 of file pg_dump.c.

3861{
3862 const char *stdstrings = AH->std_strings ? "on" : "off";
3864
3865 pg_log_info("saving \"standard_conforming_strings = %s\"",
3866 stdstrings);
3867
3868 appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
3869 stdstrings);
3870
3872 ARCHIVE_OPTS(.tag = "STDSTRINGS",
3873 .description = "STDSTRINGS",
3874 .section = SECTION_PRE_DATA,
3875 .createStmt = qry->data));
3876
3877 destroyPQExpBuffer(qry);
3878}

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

5483{
5484 DumpOptions *dopt = fout->dopt;
5485 PQExpBuffer delq;
5486 PQExpBuffer query;
5487 PQExpBuffer publications;
5488 char *qsubname;
5489 char **pubnames = NULL;
5490 int npubnames = 0;
5491 int i;
5492
5493 /* Do nothing if not dumping schema */
5494 if (!dopt->dumpSchema)
5495 return;
5496
5497 delq = createPQExpBuffer();
5498 query = createPQExpBuffer();
5499
5500 qsubname = pg_strdup(fmtId(subinfo->dobj.name));
5501
5502 appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
5503 qsubname);
5504
5505 appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
5506 qsubname);
5507 appendStringLiteralAH(query, subinfo->subconninfo, fout);
5508
5509 /* Build list of quoted publications and append them to query. */
5510 if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
5511 pg_fatal("could not parse %s array", "subpublications");
5512
5513 publications = createPQExpBuffer();
5514 for (i = 0; i < npubnames; i++)
5515 {
5516 if (i > 0)
5517 appendPQExpBufferStr(publications, ", ");
5518
5519 appendPQExpBufferStr(publications, fmtId(pubnames[i]));
5520 }
5521
5522 appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
5523 if (subinfo->subslotname)
5524 appendStringLiteralAH(query, subinfo->subslotname, fout);
5525 else
5526 appendPQExpBufferStr(query, "NONE");
5527
5528 if (subinfo->subbinary)
5529 appendPQExpBufferStr(query, ", binary = true");
5530
5531 if (subinfo->substream == LOGICALREP_STREAM_ON)
5532 appendPQExpBufferStr(query, ", streaming = on");
5533 else if (subinfo->substream == LOGICALREP_STREAM_PARALLEL)
5534 appendPQExpBufferStr(query, ", streaming = parallel");
5535 else
5536 appendPQExpBufferStr(query, ", streaming = off");
5537
5538 if (subinfo->subtwophasestate != LOGICALREP_TWOPHASE_STATE_DISABLED)
5539 appendPQExpBufferStr(query, ", two_phase = on");
5540
5541 if (subinfo->subdisableonerr)
5542 appendPQExpBufferStr(query, ", disable_on_error = true");
5543
5544 if (!subinfo->subpasswordrequired)
5545 appendPQExpBufferStr(query, ", password_required = false");
5546
5547 if (subinfo->subrunasowner)
5548 appendPQExpBufferStr(query, ", run_as_owner = true");
5549
5550 if (subinfo->subfailover)
5551 appendPQExpBufferStr(query, ", failover = true");
5552
5553 if (subinfo->subretaindeadtuples)
5554 appendPQExpBufferStr(query, ", retain_dead_tuples = true");
5555
5556 if (subinfo->submaxretention)
5557 appendPQExpBuffer(query, ", max_retention_duration = %d", subinfo->submaxretention);
5558
5559 if (strcmp(subinfo->subsynccommit, "off") != 0)
5560 appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
5561
5562 if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
5563 appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
5564
5565 appendPQExpBufferStr(query, ");\n");
5566
5567 /*
5568 * In binary-upgrade mode, we allow the replication to continue after the
5569 * upgrade.
5570 */
5571 if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5572 {
5573 if (subinfo->suboriginremotelsn)
5574 {
5575 /*
5576 * Preserve the remote_lsn for the subscriber's replication
5577 * origin. This value is required to start the replication from
5578 * the position before the upgrade. This value will be stale if
5579 * the publisher gets upgraded before the subscriber node.
5580 * However, this shouldn't be a problem as the upgrade of the
5581 * publisher ensures that all the transactions were replicated
5582 * before upgrading it.
5583 */
5585 "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
5587 "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
5588 appendStringLiteralAH(query, subinfo->dobj.name, fout);
5589 appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
5590 }
5591
5592 if (subinfo->subenabled)
5593 {
5594 /*
5595 * Enable the subscription to allow the replication to continue
5596 * after the upgrade.
5597 */
5599 "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
5600 appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
5601 }
5602 }
5603
5604 if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5605 ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
5606 ARCHIVE_OPTS(.tag = subinfo->dobj.name,
5607 .owner = subinfo->rolname,
5608 .description = "SUBSCRIPTION",
5609 .section = SECTION_POST_DATA,
5610 .createStmt = query->data,
5611 .dropStmt = delq->data));
5612
5613 if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
5614 dumpComment(fout, "SUBSCRIPTION", qsubname,
5615 NULL, subinfo->rolname,
5616 subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5617
5618 if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
5619 dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
5620 NULL, subinfo->rolname,
5621 subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5622
5623 destroyPQExpBuffer(publications);
5624 free(pubnames);
5625
5626 destroyPQExpBuffer(delq);
5627 destroyPQExpBuffer(query);
5628 free(qsubname);
5629}
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:32
char * suboriginremotelsn
Definition: pg_dump.h:727
bool subpasswordrequired
Definition: pg_dump.h:717
char * suborigin
Definition: pg_dump.h:726
const char * rolname
Definition: pg_dump.h:711
char * subsynccommit
Definition: pg_dump.h:724
char * subpublications
Definition: pg_dump.h:725
bool subdisableonerr
Definition: pg_dump.h:716
bool subrunasowner
Definition: pg_dump.h:718
char * subslotname
Definition: pg_dump.h:723
char subtwophasestate
Definition: pg_dump.h:715
bool subretaindeadtuples
Definition: pg_dump.h:720
char * subconninfo
Definition: pg_dump.h:722
DumpableObject dobj
Definition: pg_dump.h:710

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _SubscriptionInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, dumpSecLabel(), fmtId(), free, i, _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::submaxretention, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subretaindeadtuples, _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 5413 of file pg_dump.c.

5414{
5415 DumpOptions *dopt = fout->dopt;
5416 SubscriptionInfo *subinfo = subrinfo->subinfo;
5417 PQExpBuffer query;
5418 char *tag;
5419
5420 /* Do nothing if not dumping schema */
5421 if (!dopt->dumpSchema)
5422 return;
5423
5424 Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
5425
5426 tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
5427
5428 query = createPQExpBuffer();
5429
5430 if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5431 {
5432 /*
5433 * binary_upgrade_add_sub_rel_state will add the subscription relation
5434 * to pg_subscription_rel table. This will be used only in
5435 * binary-upgrade mode.
5436 */
5438 "\n-- For binary upgrade, must preserve the subscriber table.\n");
5440 "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
5441 appendStringLiteralAH(query, subrinfo->dobj.name, fout);
5442 appendPQExpBuffer(query,
5443 ", %u, '%c'",
5444 subrinfo->tblinfo->dobj.catId.oid,
5445 subrinfo->srsubstate);
5446
5447 if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
5448 appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
5449 else
5450 appendPQExpBufferStr(query, ", NULL");
5451
5452 appendPQExpBufferStr(query, ");\n");
5453 }
5454
5455 /*
5456 * There is no point in creating a drop query as the drop is done by table
5457 * drop. (If you think to change this, see also _printTocEntry().)
5458 * Although this object doesn't really have ownership as such, set the
5459 * owner field anyway to ensure that the command is run by the correct
5460 * role at restore time.
5461 */
5462 if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5463 ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
5464 ARCHIVE_OPTS(.tag = tag,
5465 .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
5466 .owner = subinfo->rolname,
5467 .description = "SUBSCRIPTION TABLE",
5468 .section = SECTION_POST_DATA,
5469 .createStmt = query->data));
5470
5471 /* These objects can't currently have comments or seclabels */
5472
5473 free(tag);
5474 destroyPQExpBuffer(query);
5475}
DumpableObject dobj
Definition: pg_dump.h:742
char * srsublsn
Definition: pg_dump.h:746
SubscriptionInfo * subinfo
Definition: pg_dump.h:743
TableInfo * tblinfo
Definition: pg_dump.h:744
char srsubstate
Definition: pg_dump.h:745

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), Assert(), _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _SubscriptionInfo::dobj, _SubRelInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 16863 of file pg_dump.c.

16864{
16865 DumpOptions *dopt = fout->dopt;
16866 DumpId tableAclDumpId = InvalidDumpId;
16867 char *namecopy;
16868
16869 /* Do nothing if not dumping schema */
16870 if (!dopt->dumpSchema)
16871 return;
16872
16873 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16874 {
16875 if (tbinfo->relkind == RELKIND_SEQUENCE)
16876 dumpSequence(fout, tbinfo);
16877 else
16878 dumpTableSchema(fout, tbinfo);
16879 }
16880
16881 /* Handle the ACL here */
16882 namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
16883 if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
16884 {
16885 const char *objtype =
16886 (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
16887
16888 tableAclDumpId =
16889 dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
16890 objtype, namecopy, NULL,
16891 tbinfo->dobj.namespace->dobj.name,
16892 NULL, tbinfo->rolname, &tbinfo->dacl);
16893 }
16894
16895 /*
16896 * Handle column ACLs, if any. Note: we pull these with a separate query
16897 * rather than trying to fetch them during getTableAttrs, so that we won't
16898 * miss ACLs on system columns. Doing it this way also allows us to dump
16899 * ACLs for catalogs that we didn't mark "interesting" back in getTables.
16900 */
16901 if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
16902 {
16904 PGresult *res;
16905 int i;
16906
16908 {
16909 /* Set up query for column ACLs */
16911 "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
16912
16913 if (fout->remoteVersion >= 90600)
16914 {
16915 /*
16916 * In principle we should call acldefault('c', relowner) to
16917 * get the default ACL for a column. However, we don't
16918 * currently store the numeric OID of the relowner in
16919 * TableInfo. We could convert the owner name using regrole,
16920 * but that creates a risk of failure due to concurrent role
16921 * renames. Given that the default ACL for columns is empty
16922 * and is likely to stay that way, it's not worth extra cycles
16923 * and risk to avoid hard-wiring that knowledge here.
16924 */
16926 "SELECT at.attname, "
16927 "at.attacl, "
16928 "'{}' AS acldefault, "
16929 "pip.privtype, pip.initprivs "
16930 "FROM pg_catalog.pg_attribute at "
16931 "LEFT JOIN pg_catalog.pg_init_privs pip ON "
16932 "(at.attrelid = pip.objoid "
16933 "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
16934 "AND at.attnum = pip.objsubid) "
16935 "WHERE at.attrelid = $1 AND "
16936 "NOT at.attisdropped "
16937 "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
16938 "ORDER BY at.attnum");
16939 }
16940 else
16941 {
16943 "SELECT attname, attacl, '{}' AS acldefault, "
16944 "NULL AS privtype, NULL AS initprivs "
16945 "FROM pg_catalog.pg_attribute "
16946 "WHERE attrelid = $1 AND NOT attisdropped "
16947 "AND attacl IS NOT NULL "
16948 "ORDER BY attnum");
16949 }
16950
16951 ExecuteSqlStatement(fout, query->data);
16952
16954 }
16955
16956 printfPQExpBuffer(query,
16957 "EXECUTE getColumnACLs('%u')",
16958 tbinfo->dobj.catId.oid);
16959
16960 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16961
16962 for (i = 0; i < PQntuples(res); i++)
16963 {
16964 char *attname = PQgetvalue(res, i, 0);
16965 char *attacl = PQgetvalue(res, i, 1);
16966 char *acldefault = PQgetvalue(res, i, 2);
16967 char privtype = *(PQgetvalue(res, i, 3));
16968 char *initprivs = PQgetvalue(res, i, 4);
16969 DumpableAcl coldacl;
16970 char *attnamecopy;
16971
16972 coldacl.acl = attacl;
16973 coldacl.acldefault = acldefault;
16974 coldacl.privtype = privtype;
16975 coldacl.initprivs = initprivs;
16976 attnamecopy = pg_strdup(fmtId(attname));
16977
16978 /*
16979 * Column's GRANT type is always TABLE. Each column ACL depends
16980 * on the table-level ACL, since we can restore column ACLs in
16981 * parallel but the table-level ACL has to be done first.
16982 */
16983 dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
16984 "TABLE", namecopy, attnamecopy,
16985 tbinfo->dobj.namespace->dobj.name,
16986 NULL, tbinfo->rolname, &coldacl);
16987 free(attnamecopy);
16988 }
16989 PQclear(res);
16990 destroyPQExpBuffer(query);
16991 }
16992
16993 free(namecopy);
16994}
@ PREPQUERY_GETCOLUMNACLS
Definition: pg_backup.h:76
static void dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:17092
static void dumpSequence(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:18972
DumpableAcl dacl
Definition: pg_dump.h:308
bool hascolumnACLs
Definition: pg_dump.h:321

References _dumpableAcl::acl, acldefault(), _dumpableAcl::acldefault, appendPQExpBufferStr(), attname, _dumpableObject::catId, createPQExpBuffer(), _tableInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DEFINITION, dumpACL(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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, and _tableInfo::rolname.

Referenced by dumpDumpableObject().

◆ dumpTableAttach()

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

Definition at line 18107 of file pg_dump.c.

18108{
18109 DumpOptions *dopt = fout->dopt;
18110 PQExpBuffer q;
18111 PGresult *res;
18112 char *partbound;
18113
18114 /* Do nothing if not dumping schema */
18115 if (!dopt->dumpSchema)
18116 return;
18117
18118 q = createPQExpBuffer();
18119
18121 {
18122 /* Set up query for partbound details */
18124 "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
18125
18127 "SELECT pg_get_expr(c.relpartbound, c.oid) "
18128 "FROM pg_class c "
18129 "WHERE c.oid = $1");
18130
18131 ExecuteSqlStatement(fout, q->data);
18132
18134 }
18135
18137 "EXECUTE dumpTableAttach('%u')",
18138 attachinfo->partitionTbl->dobj.catId.oid);
18139
18140 res = ExecuteSqlQueryForSingleRow(fout, q->data);
18141 partbound = PQgetvalue(res, 0, 0);
18142
18143 /* Perform ALTER TABLE on the parent */
18145 "ALTER TABLE ONLY %s ",
18146 fmtQualifiedDumpable(attachinfo->parentTbl));
18148 "ATTACH PARTITION %s %s;\n",
18150 partbound);
18151
18152 /*
18153 * There is no point in creating a drop query as the drop is done by table
18154 * drop. (If you think to change this, see also _printTocEntry().)
18155 * Although this object doesn't really have ownership as such, set the
18156 * owner field anyway to ensure that the command is run by the correct
18157 * role at restore time.
18158 */
18159 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18160 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18161 .namespace = attachinfo->dobj.namespace->dobj.name,
18162 .owner = attachinfo->partitionTbl->rolname,
18163 .description = "TABLE ATTACH",
18164 .section = SECTION_PRE_DATA,
18165 .createStmt = q->data));
18166
18167 PQclear(res);
18169}
@ PREPQUERY_DUMPTABLEATTACH
Definition: pg_backup.h:74
TableInfo * partitionTbl
Definition: pg_dump.h:399
DumpableObject dobj
Definition: pg_dump.h:397
TableInfo * parentTbl
Definition: pg_dump.h:398

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _tableAttachInfo::dobj, Archive::dopt, _dumpableObject::dumpId, _dumpOptions::dumpSchema, ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), fmtQualifiedDumpable, Archive::is_prepared, _dumpableObject::name, CatalogId::oid, _tableAttachInfo::parentTbl, _tableAttachInfo::partitionTbl, PQclear, PQgetvalue, PREPQUERY_DUMPTABLEATTACH, printfPQExpBuffer(), _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 11401 of file pg_dump.c.

11403{
11404 DumpOptions *dopt = fout->dopt;
11406 int ncomments;
11407 PQExpBuffer query;
11408 PQExpBuffer tag;
11409
11410 /* do nothing, if --no-comments is supplied */
11411 if (dopt->no_comments)
11412 return;
11413
11414 /* Comments are SCHEMA not data */
11415 if (!dopt->dumpSchema)
11416 return;
11417
11418 /* Search for comments associated with relation, using table */
11420 tbinfo->dobj.catId.oid,
11421 &comments);
11422
11423 /* If comments exist, build COMMENT ON statements */
11424 if (ncomments <= 0)
11425 return;
11426
11427 query = createPQExpBuffer();
11428 tag = createPQExpBuffer();
11429
11430 while (ncomments > 0)
11431 {
11432 const char *descr = comments->descr;
11433 int objsubid = comments->objsubid;
11434
11435 if (objsubid == 0)
11436 {
11437 resetPQExpBuffer(tag);
11438 appendPQExpBuffer(tag, "%s %s", reltypename,
11439 fmtId(tbinfo->dobj.name));
11440
11441 resetPQExpBuffer(query);
11442 appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
11443 fmtQualifiedDumpable(tbinfo));
11444 appendStringLiteralAH(query, descr, fout);
11445 appendPQExpBufferStr(query, ";\n");
11446
11448 ARCHIVE_OPTS(.tag = tag->data,
11449 .namespace = tbinfo->dobj.namespace->dobj.name,
11450 .owner = tbinfo->rolname,
11451 .description = "COMMENT",
11452 .section = SECTION_NONE,
11453 .createStmt = query->data,
11454 .deps = &(tbinfo->dobj.dumpId),
11455 .nDeps = 1));
11456 }
11457 else if (objsubid > 0 && objsubid <= tbinfo->numatts)
11458 {
11459 resetPQExpBuffer(tag);
11460 appendPQExpBuffer(tag, "COLUMN %s.",
11461 fmtId(tbinfo->dobj.name));
11462 appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
11463
11464 resetPQExpBuffer(query);
11465 appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
11466 fmtQualifiedDumpable(tbinfo));
11467 appendPQExpBuffer(query, "%s IS ",
11468 fmtId(tbinfo->attnames[objsubid - 1]));
11469 appendStringLiteralAH(query, descr, fout);
11470 appendPQExpBufferStr(query, ";\n");
11471
11473 ARCHIVE_OPTS(.tag = tag->data,
11474 .namespace = tbinfo->dobj.namespace->dobj.name,
11475 .owner = tbinfo->rolname,
11476 .description = "COMMENT",
11477 .section = SECTION_NONE,
11478 .createStmt = query->data,
11479 .deps = &(tbinfo->dobj.dumpId),
11480 .nDeps = 1));
11481 }
11482
11483 comments++;
11484 ncomments--;
11485 }
11486
11487 destroyPQExpBuffer(query);
11488 destroyPQExpBuffer(tag);
11489}

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _tableInfo::attnames, _dumpableObject::catId, comments, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, CommentItem::descr, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 18857 of file pg_dump.c.

18858{
18859 TableInfo *tbinfo = coninfo->contable;
18860 PQExpBuffer conprefix = createPQExpBuffer();
18861 char *qtabname;
18862
18863 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18864
18865 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
18866 fmtId(coninfo->dobj.name));
18867
18868 if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18869 dumpComment(fout, conprefix->data, qtabname,
18870 tbinfo->dobj.namespace->dobj.name,
18871 tbinfo->rolname,
18872 coninfo->dobj.catId, 0,
18873 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
18874
18875 destroyPQExpBuffer(conprefix);
18876 free(qtabname);
18877}

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

2871{
2872 DumpOptions *dopt = fout->dopt;
2873 TableInfo *tbinfo = tdinfo->tdtable;
2874 PQExpBuffer copyBuf = createPQExpBuffer();
2875 PQExpBuffer clistBuf = createPQExpBuffer();
2876 DataDumperPtr dumpFn;
2877 char *tdDefn = NULL;
2878 char *copyStmt;
2879 const char *copyFrom;
2880
2881 /* We had better have loaded per-column details about this table */
2882 Assert(tbinfo->interesting);
2883
2884 /*
2885 * When load-via-partition-root is set or forced, get the root table name
2886 * for the partition table, so that we can reload data through the root
2887 * table. Then construct a comment to be inserted into the TOC entry's
2888 * defn field, so that such cases can be identified reliably.
2889 */
2890 if (tbinfo->ispartition &&
2891 (dopt->load_via_partition_root ||
2892 forcePartitionRootLoad(tbinfo)))
2893 {
2894 TableInfo *parentTbinfo;
2895 char *sanitized;
2896
2897 parentTbinfo = getRootTableInfo(tbinfo);
2898 copyFrom = fmtQualifiedDumpable(parentTbinfo);
2899 sanitized = sanitize_line(copyFrom, true);
2900 printfPQExpBuffer(copyBuf, "-- load via partition root %s",
2901 sanitized);
2902 free(sanitized);
2903 tdDefn = pg_strdup(copyBuf->data);
2904 }
2905 else
2906 copyFrom = fmtQualifiedDumpable(tbinfo);
2907
2908 if (dopt->dump_inserts == 0)
2909 {
2910 /* Dump/restore using COPY */
2911 dumpFn = dumpTableData_copy;
2912 /* must use 2 steps here 'cause fmtId is nonreentrant */
2913 printfPQExpBuffer(copyBuf, "COPY %s ",
2914 copyFrom);
2915 appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
2916 fmtCopyColumnList(tbinfo, clistBuf));
2917 copyStmt = copyBuf->data;
2918 }
2919 else
2920 {
2921 /* Restore using INSERT */
2922 dumpFn = dumpTableData_insert;
2923 copyStmt = NULL;
2924 }
2925
2926 /*
2927 * Note: although the TableDataInfo is a full DumpableObject, we treat its
2928 * dependency on its table as "special" and pass it to ArchiveEntry now.
2929 * See comments for BuildArchiveDependencies.
2930 */
2931 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2932 {
2933 TocEntry *te;
2934
2935 te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
2936 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2937 .namespace = tbinfo->dobj.namespace->dobj.name,
2938 .owner = tbinfo->rolname,
2939 .description = "TABLE DATA",
2940 .section = SECTION_DATA,
2941 .createStmt = tdDefn,
2942 .copyStmt = copyStmt,
2943 .deps = &(tbinfo->dobj.dumpId),
2944 .nDeps = 1,
2945 .dumpFn = dumpFn,
2946 .dumpArg = tdinfo));
2947
2948 /*
2949 * Set the TocEntry's dataLength in case we are doing a parallel dump
2950 * and want to order dump jobs by table size. We choose to measure
2951 * dataLength in table pages (including TOAST pages) during dump, so
2952 * no scaling is needed.
2953 *
2954 * However, relpages is declared as "integer" in pg_class, and hence
2955 * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
2956 * Cast so that we get the right interpretation of table sizes
2957 * exceeding INT_MAX pages.
2958 */
2959 te->dataLength = (BlockNumber) tbinfo->relpages;
2960 te->dataLength += (BlockNumber) tbinfo->toastpages;
2961
2962 /*
2963 * If pgoff_t is only 32 bits wide, the above refinement is useless,
2964 * and instead we'd better worry about integer overflow. Clamp to
2965 * INT_MAX if the correct result exceeds that.
2966 */
2967 if (sizeof(te->dataLength) == 4 &&
2968 (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
2969 te->dataLength < 0))
2970 te->dataLength = INT_MAX;
2971 }
2972
2973 destroyPQExpBuffer(copyBuf);
2974 destroyPQExpBuffer(clistBuf);
2975}
uint32 BlockNumber
Definition: block.h:31
char * sanitize_line(const char *str, bool want_hyphen)
Definition: dumputils.c:52
int(* DataDumperPtr)(Archive *AH, const void *userArg)
static bool forcePartitionRootLoad(const TableInfo *tbinfo)
Definition: pg_dump.c:2842
static int dumpTableData_copy(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2380
static const char * fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
Definition: pg_dump.c:20418
static int dumpTableData_insert(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2548
static TableInfo * getRootTableInfo(const TableInfo *tbinfo)
Definition: pg_dump.c:2817
int dump_inserts
Definition: pg_backup.h:180
int load_via_partition_root
Definition: pg_backup.h:199
bool interesting
Definition: pg_dump.h:341
int toastpages
Definition: pg_dump.h:339
int32 relpages
Definition: pg_dump.h:338

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(), free, getRootTableInfo(), _tableInfo::interesting, _tableInfo::ispartition, _dumpOptions::load_via_partition_root, _dumpableObject::name, pg_strdup(), printfPQExpBuffer(), _tableInfo::relpages, _tableInfo::rolname, sanitize_line(), 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 2380 of file pg_dump.c.

2381{
2382 TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2383 TableInfo *tbinfo = tdinfo->tdtable;
2384 const char *classname = tbinfo->dobj.name;
2386
2387 /*
2388 * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
2389 * which uses it already.
2390 */
2391 PQExpBuffer clistBuf = createPQExpBuffer();
2392 PGconn *conn = GetConnection(fout);
2393 PGresult *res;
2394 int ret;
2395 char *copybuf;
2396 const char *column_list;
2397
2398 pg_log_info("dumping contents of table \"%s.%s\"",
2399 tbinfo->dobj.namespace->dobj.name, classname);
2400
2401 /*
2402 * Specify the column list explicitly so that we have no possibility of
2403 * retrieving data in the wrong column order. (The default column
2404 * ordering of COPY will not be what we want in certain corner cases
2405 * involving ADD COLUMN and inheritance.)
2406 */
2407 column_list = fmtCopyColumnList(tbinfo, clistBuf);
2408
2409 /*
2410 * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
2411 * a filter condition was specified. For other cases a simple COPY
2412 * suffices.
2413 */
2414 if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2415 {
2416 /* Temporary allows to access to foreign tables to dump data */
2417 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2418 set_restrict_relation_kind(fout, "view");
2419
2420 appendPQExpBufferStr(q, "COPY (SELECT ");
2421 /* klugery to get rid of parens in column list */
2422 if (strlen(column_list) > 2)
2423 {
2424 appendPQExpBufferStr(q, column_list + 1);
2425 q->data[q->len - 1] = ' ';
2426 }
2427 else
2428 appendPQExpBufferStr(q, "* ");
2429
2430 appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
2431 fmtQualifiedDumpable(tbinfo),
2432 tdinfo->filtercond ? tdinfo->filtercond : "");
2433 }
2434 else
2435 {
2436 appendPQExpBuffer(q, "COPY %s %s TO stdout;",
2437 fmtQualifiedDumpable(tbinfo),
2438 column_list);
2439 }
2440 res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
2441 PQclear(res);
2442 destroyPQExpBuffer(clistBuf);
2443
2444 for (;;)
2445 {
2446 ret = PQgetCopyData(conn, &copybuf, 0);
2447
2448 if (ret < 0)
2449 break; /* done or error */
2450
2451 if (copybuf)
2452 {
2453 WriteData(fout, copybuf, ret);
2455 }
2456
2457 /* ----------
2458 * THROTTLE:
2459 *
2460 * There was considerable discussion in late July, 2000 regarding
2461 * slowing down pg_dump when backing up large tables. Users with both
2462 * slow & fast (multi-processor) machines experienced performance
2463 * degradation when doing a backup.
2464 *
2465 * Initial attempts based on sleeping for a number of ms for each ms
2466 * of work were deemed too complex, then a simple 'sleep in each loop'
2467 * implementation was suggested. The latter failed because the loop
2468 * was too tight. Finally, the following was implemented:
2469 *
2470 * If throttle is non-zero, then
2471 * See how long since the last sleep.
2472 * Work out how long to sleep (based on ratio).
2473 * If sleep is more than 100ms, then
2474 * sleep
2475 * reset timer
2476 * EndIf
2477 * EndIf
2478 *
2479 * where the throttle value was the number of ms to sleep per ms of
2480 * work. The calculation was done in each loop.
2481 *
2482 * Most of the hard work is done in the backend, and this solution
2483 * still did not work particularly well: on slow machines, the ratio
2484 * was 50:1, and on medium paced machines, 1:1, and on fast
2485 * multi-processor machines, it had little or no effect, for reasons
2486 * that were unclear.
2487 *
2488 * Further discussion ensued, and the proposal was dropped.
2489 *
2490 * For those people who want this feature, it can be implemented using
2491 * gettimeofday in each loop, calculating the time since last sleep,
2492 * multiplying that by the sleep ratio, then if the result is more
2493 * than a preset 'minimum sleep time' (say 100ms), call the 'select'
2494 * function to sleep for a subsecond period ie.
2495 *
2496 * select(0, NULL, NULL, NULL, &tvi);
2497 *
2498 * This will return after the interval specified in the structure tvi.
2499 * Finally, call gettimeofday again to save the 'last sleep time'.
2500 * ----------
2501 */
2502 }
2503 archprintf(fout, "\\.\n\n\n");
2504
2505 if (ret == -2)
2506 {
2507 /* copy data transfer failed */
2508 pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
2509 pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2510 pg_log_error_detail("Command was: %s", q->data);
2511 exit_nicely(1);
2512 }
2513
2514 /* Check command status and return to normal libpq state */
2515 res = PQgetResult(conn);
2516 if (PQresultStatus(res) != PGRES_COMMAND_OK)
2517 {
2518 pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
2519 pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2520 pg_log_error_detail("Command was: %s", q->data);
2521 exit_nicely(1);
2522 }
2523 PQclear(res);
2524
2525 /* Do this to ensure we've pumped libpq back to idle state */
2526 if (PQgetResult(conn) != NULL)
2527 pg_log_warning("unexpected extra results during COPY of table \"%s\"",
2528 classname);
2529
2531
2532 /* Revert back the setting */
2533 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2534 set_restrict_relation_kind(fout, "view, foreign-table");
2535
2536 return 1;
2537}
void PQfreemem(void *ptr)
Definition: fe-exec.c:4049
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2833
#define PQgetResult
Definition: libpq-be-fe.h:246
#define PQresultStatus
Definition: libpq-be-fe.h:247
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:125
@ PGRES_COPY_OUT
Definition: libpq-fe.h:131
#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
void exit_nicely(int code)
static void set_restrict_relation_kind(Archive *AH, const char *value)
Definition: pg_dump.c:5086
char * filtercond
Definition: pg_dump.h:415
static StringInfo copybuf
Definition: tablesync.c:127

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, set_restrict_relation_kind(), _tableDataInfo::tdtable, and WriteData().

Referenced by dumpTableData().

◆ dumpTableData_insert()

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

Definition at line 2548 of file pg_dump.c.

2549{
2550 TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2551 TableInfo *tbinfo = tdinfo->tdtable;
2552 DumpOptions *dopt = fout->dopt;
2554 PQExpBuffer insertStmt = NULL;
2555 char *attgenerated;
2556 PGresult *res;
2557 int nfields,
2558 i;
2559 int rows_per_statement = dopt->dump_inserts;
2560 int rows_this_statement = 0;
2561
2562 /* Temporary allows to access to foreign tables to dump data */
2563 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2564 set_restrict_relation_kind(fout, "view");
2565
2566 /*
2567 * If we're going to emit INSERTs with column names, the most efficient
2568 * way to deal with generated columns is to exclude them entirely. For
2569 * INSERTs without column names, we have to emit DEFAULT rather than the
2570 * actual column value --- but we can save a few cycles by fetching nulls
2571 * rather than the uninteresting-to-us value.
2572 */
2573 attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
2574 appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
2575 nfields = 0;
2576 for (i = 0; i < tbinfo->numatts; i++)
2577 {
2578 if (tbinfo->attisdropped[i])
2579 continue;
2580 if (tbinfo->attgenerated[i] && dopt->column_inserts)
2581 continue;
2582 if (nfields > 0)
2583 appendPQExpBufferStr(q, ", ");
2584 if (tbinfo->attgenerated[i])
2585 appendPQExpBufferStr(q, "NULL");
2586 else
2587 appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
2588 attgenerated[nfields] = tbinfo->attgenerated[i];
2589 nfields++;
2590 }
2591 /* Servers before 9.4 will complain about zero-column SELECT */
2592 if (nfields == 0)
2593 appendPQExpBufferStr(q, "NULL");
2594 appendPQExpBuffer(q, " FROM ONLY %s",
2595 fmtQualifiedDumpable(tbinfo));
2596 if (tdinfo->filtercond)
2597 appendPQExpBuffer(q, " %s", tdinfo->filtercond);
2598
2599 ExecuteSqlStatement(fout, q->data);
2600
2601 while (1)
2602 {
2603 res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
2605
2606 /* cross-check field count, allowing for dummy NULL if any */
2607 if (nfields != PQnfields(res) &&
2608 !(nfields == 0 && PQnfields(res) == 1))
2609 pg_fatal("wrong number of fields retrieved from table \"%s\"",
2610 tbinfo->dobj.name);
2611
2612 /*
2613 * First time through, we build as much of the INSERT statement as
2614 * possible in "insertStmt", which we can then just print for each
2615 * statement. If the table happens to have zero dumpable columns then
2616 * this will be a complete statement, otherwise it will end in
2617 * "VALUES" and be ready to have the row's column values printed.
2618 */
2619 if (insertStmt == NULL)
2620 {
2621 TableInfo *targettab;
2622
2623 insertStmt = createPQExpBuffer();
2624
2625 /*
2626 * When load-via-partition-root is set or forced, get the root
2627 * table name for the partition table, so that we can reload data
2628 * through the root table.
2629 */
2630 if (tbinfo->ispartition &&
2631 (dopt->load_via_partition_root ||
2632 forcePartitionRootLoad(tbinfo)))
2633 targettab = getRootTableInfo(tbinfo);
2634 else
2635 targettab = tbinfo;
2636
2637 appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
2638 fmtQualifiedDumpable(targettab));
2639
2640 /* corner case for zero-column table */
2641 if (nfields == 0)
2642 {
2643 appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
2644 }
2645 else
2646 {
2647 /* append the list of column names if required */
2648 if (dopt->column_inserts)
2649 {
2650 appendPQExpBufferChar(insertStmt, '(');
2651 for (int field = 0; field < nfields; field++)
2652 {
2653 if (field > 0)
2654 appendPQExpBufferStr(insertStmt, ", ");
2655 appendPQExpBufferStr(insertStmt,
2656 fmtId(PQfname(res, field)));
2657 }
2658 appendPQExpBufferStr(insertStmt, ") ");
2659 }
2660
2661 if (tbinfo->needs_override)
2662 appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
2663
2664 appendPQExpBufferStr(insertStmt, "VALUES");
2665 }
2666 }
2667
2668 for (int tuple = 0; tuple < PQntuples(res); tuple++)
2669 {
2670 /* Write the INSERT if not in the middle of a multi-row INSERT. */
2671 if (rows_this_statement == 0)
2672 archputs(insertStmt->data, fout);
2673
2674 /*
2675 * If it is zero-column table then we've already written the
2676 * complete statement, which will mean we've disobeyed
2677 * --rows-per-insert when it's set greater than 1. We do support
2678 * a way to make this multi-row with: SELECT UNION ALL SELECT
2679 * UNION ALL ... but that's non-standard so we should avoid it
2680 * given that using INSERTs is mostly only ever needed for
2681 * cross-database exports.
2682 */
2683 if (nfields == 0)
2684 continue;
2685
2686 /* Emit a row heading */
2687 if (rows_per_statement == 1)
2688 archputs(" (", fout);
2689 else if (rows_this_statement > 0)
2690 archputs(",\n\t(", fout);
2691 else
2692 archputs("\n\t(", fout);
2693
2694 for (int field = 0; field < nfields; field++)
2695 {
2696 if (field > 0)
2697 archputs(", ", fout);
2698 if (attgenerated[field])
2699 {
2700 archputs("DEFAULT", fout);
2701 continue;
2702 }
2703 if (PQgetisnull(res, tuple, field))
2704 {
2705 archputs("NULL", fout);
2706 continue;
2707 }
2708
2709 /* XXX This code is partially duplicated in ruleutils.c */
2710 switch (PQftype(res, field))
2711 {
2712 case INT2OID:
2713 case INT4OID:
2714 case INT8OID:
2715 case OIDOID:
2716 case FLOAT4OID:
2717 case FLOAT8OID:
2718 case NUMERICOID:
2719 {
2720 /*
2721 * These types are printed without quotes unless
2722 * they contain values that aren't accepted by the
2723 * scanner unquoted (e.g., 'NaN'). Note that
2724 * strtod() and friends might accept NaN, so we
2725 * can't use that to test.
2726 *
2727 * In reality we only need to defend against
2728 * infinity and NaN, so we need not get too crazy
2729 * about pattern matching here.
2730 */
2731 const char *s = PQgetvalue(res, tuple, field);
2732
2733 if (strspn(s, "0123456789 +-eE.") == strlen(s))
2734 archputs(s, fout);
2735 else
2736 archprintf(fout, "'%s'", s);
2737 }
2738 break;
2739
2740 case BITOID:
2741 case VARBITOID:
2742 archprintf(fout, "B'%s'",
2743 PQgetvalue(res, tuple, field));
2744 break;
2745
2746 case BOOLOID:
2747 if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
2748 archputs("true", fout);
2749 else
2750 archputs("false", fout);
2751 break;
2752
2753 default:
2754 /* All other types are printed as string literals. */
2757 PQgetvalue(res, tuple, field),
2758 fout);
2759 archputs(q->data, fout);
2760 break;
2761 }
2762 }
2763
2764 /* Terminate the row ... */
2765 archputs(")", fout);
2766
2767 /* ... and the statement, if the target no. of rows is reached */
2768 if (++rows_this_statement >= rows_per_statement)
2769 {
2770 if (dopt->do_nothing)
2771 archputs(" ON CONFLICT DO NOTHING;\n", fout);
2772 else
2773 archputs(";\n", fout);
2774 /* Reset the row counter */
2775 rows_this_statement = 0;
2776 }
2777 }
2778
2779 if (PQntuples(res) <= 0)
2780 {
2781 PQclear(res);
2782 break;
2783 }
2784 PQclear(res);
2785 }
2786
2787 /* Terminate any statements that didn't make the row count. */
2788 if (rows_this_statement > 0)
2789 {
2790 if (dopt->do_nothing)
2791 archputs(" ON CONFLICT DO NOTHING;\n", fout);
2792 else
2793 archputs(";\n", fout);
2794 }
2795
2796 archputs("\n\n", fout);
2797
2798 ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
2799
2801 if (insertStmt != NULL)
2802 destroyPQExpBuffer(insertStmt);
2803 free(attgenerated);
2804
2805 /* Revert back the setting */
2806 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2807 set_restrict_relation_kind(fout, "view, foreign-table");
2808
2809 return 1;
2810}
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3736
#define PQnfields
Definition: libpq-be-fe.h:252
#define PQfname
Definition: libpq-be-fe.h:256
void archputs(const char *s, Archive *AH)
int column_inserts
Definition: pg_backup.h:184
int do_nothing
Definition: pg_backup.h:212
char * attgenerated
Definition: pg_dump.h:362
bool * attisdropped
Definition: pg_dump.h:360
bool needs_override
Definition: pg_dump.h:382

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

Referenced by dumpTableData().

◆ dumpTableSchema()

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

Definition at line 17092 of file pg_dump.c.

17093{
17094 DumpOptions *dopt = fout->dopt;
17098 char *qrelname;
17099 char *qualrelname;
17100 int numParents;
17101 TableInfo **parents;
17102 int actual_atts; /* number of attrs in this CREATE statement */
17103 const char *reltypename;
17104 char *storage;
17105 int j,
17106 k;
17107
17108 /* We had better have loaded per-column details about this table */
17109 Assert(tbinfo->interesting);
17110
17111 qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
17112 qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
17113
17114 if (tbinfo->hasoids)
17115 pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
17116 qrelname);
17117
17118 if (dopt->binary_upgrade)
17119 binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
17120
17121 /* Is it a table or a view? */
17122 if (tbinfo->relkind == RELKIND_VIEW)
17123 {
17124 PQExpBuffer result;
17125
17126 /*
17127 * Note: keep this code in sync with the is_view case in dumpRule()
17128 */
17129
17130 reltypename = "VIEW";
17131
17132 appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
17133
17134 if (dopt->binary_upgrade)
17136 tbinfo->dobj.catId.oid);
17137
17138 appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
17139
17140 if (tbinfo->dummy_view)
17141 result = createDummyViewAsClause(fout, tbinfo);
17142 else
17143 {
17144 if (nonemptyReloptions(tbinfo->reloptions))
17145 {
17146 appendPQExpBufferStr(q, " WITH (");
17147 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
17148 appendPQExpBufferChar(q, ')');
17149 }
17150 result = createViewAsClause(fout, tbinfo);
17151 }
17152 appendPQExpBuffer(q, " AS\n%s", result->data);
17153 destroyPQExpBuffer(result);
17154
17155 if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
17156 appendPQExpBuffer(q, "\n WITH %s CHECK OPTION", tbinfo->checkoption);
17157 appendPQExpBufferStr(q, ";\n");
17158 }
17159 else
17160 {
17161 char *partkeydef = NULL;
17162 char *ftoptions = NULL;
17163 char *srvname = NULL;
17164 const char *foreign = "";
17165
17166 /*
17167 * Set reltypename, and collect any relkind-specific data that we
17168 * didn't fetch during getTables().
17169 */
17170 switch (tbinfo->relkind)
17171 {
17172 case RELKIND_PARTITIONED_TABLE:
17173 {
17175 PGresult *res;
17176
17177 reltypename = "TABLE";
17178
17179 /* retrieve partition key definition */
17180 appendPQExpBuffer(query,
17181 "SELECT pg_get_partkeydef('%u')",
17182 tbinfo->dobj.catId.oid);
17183 res = ExecuteSqlQueryForSingleRow(fout, query->data);
17184 partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
17185 PQclear(res);
17186 destroyPQExpBuffer(query);
17187 break;
17188 }
17189 case RELKIND_FOREIGN_TABLE:
17190 {
17192 PGresult *res;
17193 int i_srvname;
17194 int i_ftoptions;
17195
17196 reltypename = "FOREIGN TABLE";
17197
17198 /* retrieve name of foreign server and generic options */
17199 appendPQExpBuffer(query,
17200 "SELECT fs.srvname, "
17201 "pg_catalog.array_to_string(ARRAY("
17202 "SELECT pg_catalog.quote_ident(option_name) || "
17203 "' ' || pg_catalog.quote_literal(option_value) "
17204 "FROM pg_catalog.pg_options_to_table(ftoptions) "
17205 "ORDER BY option_name"
17206 "), E',\n ') AS ftoptions "
17207 "FROM pg_catalog.pg_foreign_table ft "
17208 "JOIN pg_catalog.pg_foreign_server fs "
17209 "ON (fs.oid = ft.ftserver) "
17210 "WHERE ft.ftrelid = '%u'",
17211 tbinfo->dobj.catId.oid);
17212 res = ExecuteSqlQueryForSingleRow(fout, query->data);
17213 i_srvname = PQfnumber(res, "srvname");
17214 i_ftoptions = PQfnumber(res, "ftoptions");
17215 srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
17216 ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
17217 PQclear(res);
17218 destroyPQExpBuffer(query);
17219
17220 foreign = "FOREIGN ";
17221 break;
17222 }
17223 case RELKIND_MATVIEW:
17224 reltypename = "MATERIALIZED VIEW";
17225 break;
17226 default:
17227 reltypename = "TABLE";
17228 break;
17229 }
17230
17231 numParents = tbinfo->numParents;
17232 parents = tbinfo->parents;
17233
17234 appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
17235
17236 if (dopt->binary_upgrade)
17238 tbinfo->dobj.catId.oid);
17239
17240 /*
17241 * PostgreSQL 18 has disabled UNLOGGED for partitioned tables, so
17242 * ignore it when dumping if it was set in this case.
17243 */
17244 appendPQExpBuffer(q, "CREATE %s%s %s",
17245 (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
17246 tbinfo->relkind != RELKIND_PARTITIONED_TABLE) ?
17247 "UNLOGGED " : "",
17248 reltypename,
17249 qualrelname);
17250
17251 /*
17252 * Attach to type, if reloftype; except in case of a binary upgrade,
17253 * we dump the table normally and attach it to the type afterward.
17254 */
17255 if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
17256 appendPQExpBuffer(q, " OF %s",
17257 getFormattedTypeName(fout, tbinfo->reloftype,
17258 zeroIsError));
17259
17260 if (tbinfo->relkind != RELKIND_MATVIEW)
17261 {
17262 /* Dump the attributes */
17263 actual_atts = 0;
17264 for (j = 0; j < tbinfo->numatts; j++)
17265 {
17266 /*
17267 * Normally, dump if it's locally defined in this table, and
17268 * not dropped. But for binary upgrade, we'll dump all the
17269 * columns, and then fix up the dropped and nonlocal cases
17270 * below.
17271 */
17272 if (shouldPrintColumn(dopt, tbinfo, j))
17273 {
17274 bool print_default;
17275 bool print_notnull;
17276
17277 /*
17278 * Default value --- suppress if to be printed separately
17279 * or not at all.
17280 */
17281 print_default = (tbinfo->attrdefs[j] != NULL &&
17282 tbinfo->attrdefs[j]->dobj.dump &&
17283 !tbinfo->attrdefs[j]->separate);
17284
17285 /*
17286 * Not Null constraint --- print it if it is locally
17287 * defined, or if binary upgrade. (In the latter case, we
17288 * reset conislocal below.)
17289 */
17290 print_notnull = (tbinfo->notnull_constrs[j] != NULL &&
17291 (tbinfo->notnull_islocal[j] ||
17292 dopt->binary_upgrade ||
17293 tbinfo->ispartition));
17294
17295 /*
17296 * Skip column if fully defined by reloftype, except in
17297 * binary upgrade
17298 */
17299 if (OidIsValid(tbinfo->reloftype) &&
17300 !print_default && !print_notnull &&
17301 !dopt->binary_upgrade)
17302 continue;
17303
17304 /* Format properly if not first attr */
17305 if (actual_atts == 0)
17306 appendPQExpBufferStr(q, " (");
17307 else
17308 appendPQExpBufferChar(q, ',');
17309 appendPQExpBufferStr(q, "\n ");
17310 actual_atts++;
17311
17312 /* Attribute name */
17313 appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
17314
17315 if (tbinfo->attisdropped[j])
17316 {
17317 /*
17318 * ALTER TABLE DROP COLUMN clears
17319 * pg_attribute.atttypid, so we will not have gotten a
17320 * valid type name; insert INTEGER as a stopgap. We'll
17321 * clean things up later.
17322 */
17323 appendPQExpBufferStr(q, " INTEGER /* dummy */");
17324 /* and skip to the next column */
17325 continue;
17326 }
17327
17328 /*
17329 * Attribute type; print it except when creating a typed
17330 * table ('OF type_name'), but in binary-upgrade mode,
17331 * print it in that case too.
17332 */
17333 if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
17334 {
17335 appendPQExpBuffer(q, " %s",
17336 tbinfo->atttypnames[j]);
17337 }
17338
17339 if (print_default)
17340 {
17341 if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
17342 appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
17343 tbinfo->attrdefs[j]->adef_expr);
17344 else if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_VIRTUAL)
17345 appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s)",
17346 tbinfo->attrdefs[j]->adef_expr);
17347 else
17348 appendPQExpBuffer(q, " DEFAULT %s",
17349 tbinfo->attrdefs[j]->adef_expr);
17350 }
17351
17352 if (print_notnull)
17353 {
17354 if (tbinfo->notnull_constrs[j][0] == '\0')
17355 appendPQExpBufferStr(q, " NOT NULL");
17356 else
17357 appendPQExpBuffer(q, " CONSTRAINT %s NOT NULL",
17358 fmtId(tbinfo->notnull_constrs[j]));
17359
17360 if (tbinfo->notnull_noinh[j])
17361 appendPQExpBufferStr(q, " NO INHERIT");
17362 }
17363
17364 /* Add collation if not default for the type */
17365 if (OidIsValid(tbinfo->attcollation[j]))
17366 {
17367 CollInfo *coll;
17368
17369 coll = findCollationByOid(tbinfo->attcollation[j]);
17370 if (coll)
17371 appendPQExpBuffer(q, " COLLATE %s",
17372 fmtQualifiedDumpable(coll));
17373 }
17374 }
17375
17376 /*
17377 * On the other hand, if we choose not to print a column
17378 * (likely because it is created by inheritance), but the
17379 * column has a locally-defined not-null constraint, we need
17380 * to dump the constraint as a standalone object.
17381 *
17382 * This syntax isn't SQL-conforming, but if you wanted
17383 * standard output you wouldn't be creating non-standard
17384 * objects to begin with.
17385 */
17386 if (!shouldPrintColumn(dopt, tbinfo, j) &&
17387 !tbinfo->attisdropped[j] &&
17388 tbinfo->notnull_constrs[j] != NULL &&
17389 tbinfo->notnull_islocal[j])
17390 {
17391 /* Format properly if not first attr */
17392 if (actual_atts == 0)
17393 appendPQExpBufferStr(q, " (");
17394 else
17395 appendPQExpBufferChar(q, ',');
17396 appendPQExpBufferStr(q, "\n ");
17397 actual_atts++;
17398
17399 if (tbinfo->notnull_constrs[j][0] == '\0')
17400 appendPQExpBuffer(q, "NOT NULL %s",
17401 fmtId(tbinfo->attnames[j]));
17402 else
17403 appendPQExpBuffer(q, "CONSTRAINT %s NOT NULL %s",
17404 tbinfo->notnull_constrs[j],
17405 fmtId(tbinfo->attnames[j]));
17406 }
17407 }
17408
17409 /*
17410 * Add non-inherited CHECK constraints, if any.
17411 *
17412 * For partitions, we need to include check constraints even if
17413 * they're not defined locally, because the ALTER TABLE ATTACH
17414 * PARTITION that we'll emit later expects the constraint to be
17415 * there. (No need to fix conislocal: ATTACH PARTITION does that)
17416 */
17417 for (j = 0; j < tbinfo->ncheck; j++)
17418 {
17419 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
17420
17421 if (constr->separate ||
17422 (!constr->conislocal && !tbinfo->ispartition))
17423 continue;
17424
17425 if (actual_atts == 0)
17426 appendPQExpBufferStr(q, " (\n ");
17427 else
17428 appendPQExpBufferStr(q, ",\n ");
17429
17430 appendPQExpBuffer(q, "CONSTRAINT %s ",
17431 fmtId(constr->dobj.name));
17432 appendPQExpBufferStr(q, constr->condef);
17433
17434 actual_atts++;
17435 }
17436
17437 if (actual_atts)
17438 appendPQExpBufferStr(q, "\n)");
17439 else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
17440 {
17441 /*
17442 * No attributes? we must have a parenthesized attribute list,
17443 * even though empty, when not using the OF TYPE syntax.
17444 */
17445 appendPQExpBufferStr(q, " (\n)");
17446 }
17447
17448 /*
17449 * Emit the INHERITS clause (not for partitions), except in
17450 * binary-upgrade mode.
17451 */
17452 if (numParents > 0 && !tbinfo->ispartition &&
17453 !dopt->binary_upgrade)
17454 {
17455 appendPQExpBufferStr(q, "\nINHERITS (");
17456 for (k = 0; k < numParents; k++)
17457 {
17458 TableInfo *parentRel = parents[k];
17459
17460 if (k > 0)
17461 appendPQExpBufferStr(q, ", ");
17463 }
17464 appendPQExpBufferChar(q, ')');
17465 }
17466
17467 if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
17468 appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
17469
17470 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
17471 appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
17472 }
17473
17474 if (nonemptyReloptions(tbinfo->reloptions) ||
17476 {
17477 bool addcomma = false;
17478
17479 appendPQExpBufferStr(q, "\nWITH (");
17480 if (nonemptyReloptions(tbinfo->reloptions))
17481 {
17482 addcomma = true;
17483 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
17484 }
17486 {
17487 if (addcomma)
17488 appendPQExpBufferStr(q, ", ");
17489 appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
17490 fout);
17491 }
17492 appendPQExpBufferChar(q, ')');
17493 }
17494
17495 /* Dump generic options if any */
17496 if (ftoptions && ftoptions[0])
17497 appendPQExpBuffer(q, "\nOPTIONS (\n %s\n)", ftoptions);
17498
17499 /*
17500 * For materialized views, create the AS clause just like a view. At
17501 * this point, we always mark the view as not populated.
17502 */
17503 if (tbinfo->relkind == RELKIND_MATVIEW)
17504 {
17505 PQExpBuffer result;
17506
17507 result = createViewAsClause(fout, tbinfo);
17508 appendPQExpBuffer(q, " AS\n%s\n WITH NO DATA;\n",
17509 result->data);
17510 destroyPQExpBuffer(result);
17511 }
17512 else
17513 appendPQExpBufferStr(q, ";\n");
17514
17515 /* Materialized views can depend on extensions */
17516 if (tbinfo->relkind == RELKIND_MATVIEW)
17517 append_depends_on_extension(fout, q, &tbinfo->dobj,
17518 "pg_catalog.pg_class",
17519 "MATERIALIZED VIEW",
17520 qualrelname);
17521
17522 /*
17523 * in binary upgrade mode, update the catalog with any missing values
17524 * that might be present.
17525 */
17526 if (dopt->binary_upgrade)
17527 {
17528 for (j = 0; j < tbinfo->numatts; j++)
17529 {
17530 if (tbinfo->attmissingval[j][0] != '\0')
17531 {
17532 appendPQExpBufferStr(q, "\n-- set missing value.\n");
17534 "SELECT pg_catalog.binary_upgrade_set_missing_value(");
17535 appendStringLiteralAH(q, qualrelname, fout);
17536 appendPQExpBufferStr(q, "::pg_catalog.regclass,");
17537 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
17538 appendPQExpBufferChar(q, ',');
17539 appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
17540 appendPQExpBufferStr(q, ");\n\n");
17541 }
17542 }
17543 }
17544
17545 /*
17546 * To create binary-compatible heap files, we have to ensure the same
17547 * physical column order, including dropped columns, as in the
17548 * original. Therefore, we create dropped columns above and drop them
17549 * here, also updating their attlen/attalign values so that the
17550 * dropped column can be skipped properly. (We do not bother with
17551 * restoring the original attbyval setting.) Also, inheritance
17552 * relationships are set up by doing ALTER TABLE INHERIT rather than
17553 * using an INHERITS clause --- the latter would possibly mess up the
17554 * column order. That also means we have to take care about setting
17555 * attislocal correctly, plus fix up any inherited CHECK constraints.
17556 * Analogously, we set up typed tables using ALTER TABLE / OF here.
17557 *
17558 * We process foreign and partitioned tables here, even though they
17559 * lack heap storage, because they can participate in inheritance
17560 * relationships and we want this stuff to be consistent across the
17561 * inheritance tree. We can exclude indexes, toast tables, sequences
17562 * and matviews, even though they have storage, because we don't
17563 * support altering or dropping columns in them, nor can they be part
17564 * of inheritance trees.
17565 */
17566 if (dopt->binary_upgrade &&
17567 (tbinfo->relkind == RELKIND_RELATION ||
17568 tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
17569 tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
17570 {
17571 bool firstitem;
17572 bool firstitem_extra;
17573
17574 /*
17575 * Drop any dropped columns. Merge the pg_attribute manipulations
17576 * into a single SQL command, so that we don't cause repeated
17577 * relcache flushes on the target table. Otherwise we risk O(N^2)
17578 * relcache bloat while dropping N columns.
17579 */
17580 resetPQExpBuffer(extra);
17581 firstitem = true;
17582 for (j = 0; j < tbinfo->numatts; j++)
17583 {
17584 if (tbinfo->attisdropped[j])
17585 {
17586 if (firstitem)
17587 {
17588 appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped columns.\n"
17589 "UPDATE pg_catalog.pg_attribute\n"
17590 "SET attlen = v.dlen, "
17591 "attalign = v.dalign, "
17592 "attbyval = false\n"
17593 "FROM (VALUES ");
17594 firstitem = false;
17595 }
17596 else
17597 appendPQExpBufferStr(q, ",\n ");
17598 appendPQExpBufferChar(q, '(');
17599 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
17600 appendPQExpBuffer(q, ", %d, '%c')",
17601 tbinfo->attlen[j],
17602 tbinfo->attalign[j]);
17603 /* The ALTER ... DROP COLUMN commands must come after */
17604 appendPQExpBuffer(extra, "ALTER %sTABLE ONLY %s ",
17605 foreign, qualrelname);
17606 appendPQExpBuffer(extra, "DROP COLUMN %s;\n",
17607 fmtId(tbinfo->attnames[j]));
17608 }
17609 }
17610 if (!firstitem)
17611 {
17612 appendPQExpBufferStr(q, ") v(dname, dlen, dalign)\n"
17613 "WHERE attrelid = ");
17614 appendStringLiteralAH(q, qualrelname, fout);
17615 appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
17616 " AND attname = v.dname;\n");
17617 /* Now we can issue the actual DROP COLUMN commands */
17618 appendBinaryPQExpBuffer(q, extra->data, extra->len);
17619 }
17620
17621 /*
17622 * Fix up inherited columns. As above, do the pg_attribute
17623 * manipulations in a single SQL command.
17624 */
17625 firstitem = true;
17626 for (j = 0; j < tbinfo->numatts; j++)
17627 {
17628 if (!tbinfo->attisdropped[j] &&
17629 !tbinfo->attislocal[j])
17630 {
17631 if (firstitem)
17632 {
17633 appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited columns.\n");
17634 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
17635 "SET attislocal = false\n"
17636 "WHERE attrelid = ");
17637 appendStringLiteralAH(q, qualrelname, fout);
17638 appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
17639 " AND attname IN (");
17640 firstitem = false;
17641 }
17642 else
17643 appendPQExpBufferStr(q, ", ");
17644 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
17645 }
17646 }
17647 if (!firstitem)
17648 appendPQExpBufferStr(q, ");\n");
17649
17650 /*
17651 * Fix up not-null constraints that come from inheritance. As
17652 * above, do the pg_constraint manipulations in a single SQL
17653 * command. (Actually, two in special cases, if we're doing an
17654 * upgrade from < 18).
17655 */
17656 firstitem = true;
17657 firstitem_extra = true;
17658 resetPQExpBuffer(extra);
17659 for (j = 0; j < tbinfo->numatts; j++)
17660 {
17661 /*
17662 * If a not-null constraint comes from inheritance, reset
17663 * conislocal. The inhcount is fixed by ALTER TABLE INHERIT,
17664 * below. Special hack: in versions < 18, columns with no
17665 * local definition need their constraint to be matched by
17666 * column number in conkeys instead of by constraint name,
17667 * because the latter is not available. (We distinguish the
17668 * case because the constraint name is the empty string.)
17669 */
17670 if (tbinfo->notnull_constrs[j] != NULL &&
17671 !tbinfo->notnull_islocal[j])
17672 {
17673 if (tbinfo->notnull_constrs[j][0] != '\0')
17674 {
17675 if (firstitem)
17676 {
17677 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
17678 "SET conislocal = false\n"
17679 "WHERE contype = 'n' AND conrelid = ");
17680 appendStringLiteralAH(q, qualrelname, fout);
17681 appendPQExpBufferStr(q, "::pg_catalog.regclass AND\n"
17682 "conname IN (");
17683 firstitem = false;
17684 }
17685 else
17686 appendPQExpBufferStr(q, ", ");
17687 appendStringLiteralAH(q, tbinfo->notnull_constrs[j], fout);
17688 }
17689 else
17690 {
17691 if (firstitem_extra)
17692 {
17693 appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
17694 "SET conislocal = false\n"
17695 "WHERE contype = 'n' AND conrelid = ");
17696 appendStringLiteralAH(extra, qualrelname, fout);
17697 appendPQExpBufferStr(extra, "::pg_catalog.regclass AND\n"
17698 "conkey IN (");
17699 firstitem_extra = false;
17700 }
17701 else
17702 appendPQExpBufferStr(extra, ", ");
17703 appendPQExpBuffer(extra, "'{%d}'", j + 1);
17704 }
17705 }
17706 }
17707 if (!firstitem)
17708 appendPQExpBufferStr(q, ");\n");
17709 if (!firstitem_extra)
17710 appendPQExpBufferStr(extra, ");\n");
17711
17712 if (extra->len > 0)
17713 appendBinaryPQExpBuffer(q, extra->data, extra->len);
17714
17715 /*
17716 * Add inherited CHECK constraints, if any.
17717 *
17718 * For partitions, they were already dumped, and conislocal
17719 * doesn't need fixing.
17720 *
17721 * As above, issue only one direct manipulation of pg_constraint.
17722 * Although it is tempting to merge the ALTER ADD CONSTRAINT
17723 * commands into one as well, refrain for now due to concern about
17724 * possible backend memory bloat if there are many such
17725 * constraints.
17726 */
17727 resetPQExpBuffer(extra);
17728 firstitem = true;
17729 for (k = 0; k < tbinfo->ncheck; k++)
17730 {
17731 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
17732
17733 if (constr->separate || constr->conislocal || tbinfo->ispartition)
17734 continue;
17735
17736 if (firstitem)
17737 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraints.\n");
17738 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
17739 foreign, qualrelname,
17740 fmtId(constr->dobj.name),
17741 constr->condef);
17742 /* Update pg_constraint after all the ALTER TABLEs */
17743 if (firstitem)
17744 {
17745 appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
17746 "SET conislocal = false\n"
17747 "WHERE contype = 'c' AND conrelid = ");
17748 appendStringLiteralAH(extra, qualrelname, fout);
17749 appendPQExpBufferStr(extra, "::pg_catalog.regclass\n");
17750 appendPQExpBufferStr(extra, " AND conname IN (");
17751 firstitem = false;
17752 }
17753 else
17754 appendPQExpBufferStr(extra, ", ");
17755 appendStringLiteralAH(extra, constr->dobj.name, fout);
17756 }
17757 if (!firstitem)
17758 {
17759 appendPQExpBufferStr(extra, ");\n");
17760 appendBinaryPQExpBuffer(q, extra->data, extra->len);
17761 }
17762
17763 if (numParents > 0 && !tbinfo->ispartition)
17764 {
17765 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
17766 for (k = 0; k < numParents; k++)
17767 {
17768 TableInfo *parentRel = parents[k];
17769
17770 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
17771 qualrelname,
17772 fmtQualifiedDumpable(parentRel));
17773 }
17774 }
17775
17776 if (OidIsValid(tbinfo->reloftype))
17777 {
17778 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
17779 appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
17780 qualrelname,
17781 getFormattedTypeName(fout, tbinfo->reloftype,
17782 zeroIsError));
17783 }
17784 }
17785
17786 /*
17787 * In binary_upgrade mode, arrange to restore the old relfrozenxid and
17788 * relminmxid of all vacuumable relations. (While vacuum.c processes
17789 * TOAST tables semi-independently, here we see them only as children
17790 * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
17791 * child toast table is handled below.)
17792 */
17793 if (dopt->binary_upgrade &&
17794 (tbinfo->relkind == RELKIND_RELATION ||
17795 tbinfo->relkind == RELKIND_MATVIEW))
17796 {
17797 appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
17798 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
17799 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
17800 "WHERE oid = ",
17801 tbinfo->frozenxid, tbinfo->minmxid);
17802 appendStringLiteralAH(q, qualrelname, fout);
17803 appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
17804
17805 if (tbinfo->toast_oid)
17806 {
17807 /*
17808 * The toast table will have the same OID at restore, so we
17809 * can safely target it by OID.
17810 */
17811 appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
17812 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
17813 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
17814 "WHERE oid = '%u';\n",
17815 tbinfo->toast_frozenxid,
17816 tbinfo->toast_minmxid, tbinfo->toast_oid);
17817 }
17818 }
17819
17820 /*
17821 * In binary_upgrade mode, restore matviews' populated status by
17822 * poking pg_class directly. This is pretty ugly, but we can't use
17823 * REFRESH MATERIALIZED VIEW since it's possible that some underlying
17824 * matview is not populated even though this matview is; in any case,
17825 * we want to transfer the matview's heap storage, not run REFRESH.
17826 */
17827 if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
17828 tbinfo->relispopulated)
17829 {
17830 appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
17831 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
17832 "SET relispopulated = 't'\n"
17833 "WHERE oid = ");
17834 appendStringLiteralAH(q, qualrelname, fout);
17835 appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
17836 }
17837
17838 /*
17839 * Dump additional per-column properties that we can't handle in the
17840 * main CREATE TABLE command.
17841 */
17842 for (j = 0; j < tbinfo->numatts; j++)
17843 {
17844 /* None of this applies to dropped columns */
17845 if (tbinfo->attisdropped[j])
17846 continue;
17847
17848 /*
17849 * Dump per-column statistics information. We only issue an ALTER
17850 * TABLE statement if the attstattarget entry for this column is
17851 * not the default value.
17852 */
17853 if (tbinfo->attstattarget[j] >= 0)
17854 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
17855 foreign, qualrelname,
17856 fmtId(tbinfo->attnames[j]),
17857 tbinfo->attstattarget[j]);
17858
17859 /*
17860 * Dump per-column storage information. The statement is only
17861 * dumped if the storage has been changed from the type's default.
17862 */
17863 if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
17864 {
17865 switch (tbinfo->attstorage[j])
17866 {
17867 case TYPSTORAGE_PLAIN:
17868 storage = "PLAIN";
17869 break;
17870 case TYPSTORAGE_EXTERNAL:
17871 storage = "EXTERNAL";
17872 break;
17873 case TYPSTORAGE_EXTENDED:
17874 storage = "EXTENDED";
17875 break;
17876 case TYPSTORAGE_MAIN:
17877 storage = "MAIN";
17878 break;
17879 default:
17880 storage = NULL;
17881 }
17882
17883 /*
17884 * Only dump the statement if it's a storage type we recognize
17885 */
17886 if (storage != NULL)
17887 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
17888 foreign, qualrelname,
17889 fmtId(tbinfo->attnames[j]),
17890 storage);
17891 }
17892
17893 /*
17894 * Dump per-column compression, if it's been set.
17895 */
17896 if (!dopt->no_toast_compression)
17897 {
17898 const char *cmname;
17899
17900 switch (tbinfo->attcompression[j])
17901 {
17902 case 'p':
17903 cmname = "pglz";
17904 break;
17905 case 'l':
17906 cmname = "lz4";
17907 break;
17908 default:
17909 cmname = NULL;
17910 break;
17911 }
17912
17913 if (cmname != NULL)
17914 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
17915 foreign, qualrelname,
17916 fmtId(tbinfo->attnames[j]),
17917 cmname);
17918 }
17919
17920 /*
17921 * Dump per-column attributes.
17922 */
17923 if (tbinfo->attoptions[j][0] != '\0')
17924 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
17925 foreign, qualrelname,
17926 fmtId(tbinfo->attnames[j]),
17927 tbinfo->attoptions[j]);
17928
17929 /*
17930 * Dump per-column fdw options.
17931 */
17932 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
17933 tbinfo->attfdwoptions[j][0] != '\0')
17935 "ALTER FOREIGN TABLE ONLY %s ALTER COLUMN %s OPTIONS (\n"
17936 " %s\n"
17937 ");\n",
17938 qualrelname,
17939 fmtId(tbinfo->attnames[j]),
17940 tbinfo->attfdwoptions[j]);
17941 } /* end loop over columns */
17942
17943 free(partkeydef);
17944 free(ftoptions);
17945 free(srvname);
17946 }
17947
17948 /*
17949 * dump properties we only have ALTER TABLE syntax for
17950 */
17951 if ((tbinfo->relkind == RELKIND_RELATION ||
17952 tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
17953 tbinfo->relkind == RELKIND_MATVIEW) &&
17954 tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
17955 {
17956 if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
17957 {
17958 /* nothing to do, will be set when the index is dumped */
17959 }
17960 else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
17961 {
17962 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
17963 qualrelname);
17964 }
17965 else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
17966 {
17967 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
17968 qualrelname);
17969 }
17970 }
17971
17972 if (tbinfo->forcerowsec)
17973 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
17974 qualrelname);
17975
17976 if (dopt->binary_upgrade)
17978 reltypename, qrelname,
17979 tbinfo->dobj.namespace->dobj.name);
17980
17981 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17982 {
17983 char *tablespace = NULL;
17984 char *tableam = NULL;
17985
17986 /*
17987 * _selectTablespace() relies on tablespace-enabled objects in the
17988 * default tablespace to have a tablespace of "" (empty string) versus
17989 * non-tablespace-enabled objects to have a tablespace of NULL.
17990 * getTables() sets tbinfo->reltablespace to "" for the default
17991 * tablespace (not NULL).
17992 */
17993 if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
17994 tablespace = tbinfo->reltablespace;
17995
17996 if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
17997 tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
17998 tableam = tbinfo->amname;
17999
18000 ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
18001 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
18002 .namespace = tbinfo->dobj.namespace->dobj.name,
18003 .tablespace = tablespace,
18004 .tableam = tableam,
18005 .relkind = tbinfo->relkind,
18006 .owner = tbinfo->rolname,
18007 .description = reltypename,
18008 .section = tbinfo->postponed_def ?
18010 .createStmt = q->data,
18011 .dropStmt = delq->data));
18012 }
18013
18014 /* Dump Table Comments */
18015 if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18016 dumpTableComment(fout, tbinfo, reltypename);
18017
18018 /* Dump Table Security Labels */
18019 if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
18020 dumpTableSecLabel(fout, tbinfo, reltypename);
18021
18022 /*
18023 * Dump comments for not-null constraints that aren't to be dumped
18024 * separately (those are processed by collectComments/dumpComment).
18025 */
18026 if (!fout->dopt->no_comments && dopt->dumpSchema &&
18027 fout->remoteVersion >= 180000)
18028 {
18029 PQExpBuffer comment = NULL;
18030 PQExpBuffer tag = NULL;
18031
18032 for (j = 0; j < tbinfo->numatts; j++)
18033 {
18034 if (tbinfo->notnull_constrs[j] != NULL &&
18035 tbinfo->notnull_comment[j] != NULL)
18036 {
18037 if (comment == NULL)
18038 {
18040 tag = createPQExpBuffer();
18041 }
18042 else
18043 {
18045 resetPQExpBuffer(tag);
18046 }
18047
18048 appendPQExpBuffer(comment, "COMMENT ON CONSTRAINT %s ON %s IS ",
18049 fmtId(tbinfo->notnull_constrs[j]), qualrelname);
18052
18053 appendPQExpBuffer(tag, "CONSTRAINT %s ON %s",
18054 fmtId(tbinfo->notnull_constrs[j]), qrelname);
18055
18057 ARCHIVE_OPTS(.tag = tag->data,
18058 .namespace = tbinfo->dobj.namespace->dobj.name,
18059 .owner = tbinfo->rolname,
18060 .description = "COMMENT",
18061 .section = SECTION_NONE,
18062 .createStmt = comment->data,
18063 .deps = &(tbinfo->dobj.dumpId),
18064 .nDeps = 1));
18065 }
18066 }
18067
18069 destroyPQExpBuffer(tag);
18070 }
18071
18072 /* Dump comments on inlined table constraints */
18073 for (j = 0; j < tbinfo->ncheck; j++)
18074 {
18075 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
18076
18077 if (constr->separate || !constr->conislocal)
18078 continue;
18079
18080 if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
18081 dumpTableConstraintComment(fout, constr);
18082 }
18083
18085 destroyPQExpBuffer(delq);
18086 destroyPQExpBuffer(extra);
18087 free(qrelname);
18088 free(qualrelname);
18089}
#define storage
Definition: indent_codes.h:68
static void dumpTableComment(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:11401
static void binary_upgrade_set_type_oids_by_rel(Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tbinfo)
Definition: pg_dump.c:5792
bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
Definition: pg_dump.c:10138
static void dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:16616
int no_toast_compression
Definition: pg_backup.h:191
char * reltablespace
Definition: pg_dump.h:314
int ncheck
Definition: pg_dump.h:330
bool * attislocal
Definition: pg_dump.h:365
Oid reloftype
Definition: pg_dump.h:332
int numParents
Definition: pg_dump.h:347
char * toast_reloptions
Definition: pg_dump.h:317
struct _tableInfo ** parents
Definition: pg_dump.h:348
int * attlen
Definition: pg_dump.h:363
char ** attfdwoptions
Definition: pg_dump.h:369
bool hasoids
Definition: pg_dump.h:324
Oid toast_oid
Definition: pg_dump.h:327
char ** notnull_comment
Definition: pg_dump.h:375
struct _constraintInfo * checkexprs
Definition: pg_dump.h:380
int * attstattarget
Definition: pg_dump.h:357
uint32 frozenxid
Definition: pg_dump.h:325
char * typstorage
Definition: pg_dump.h:359
struct _attrDefInfo ** attrdefs
Definition: pg_dump.h:379
char ** attoptions
Definition: pg_dump.h:366
char relreplident
Definition: pg_dump.h:313
uint32 minmxid
Definition: pg_dump.h:326
char * attstorage
Definition: pg_dump.h:358
char * amname
Definition: pg_dump.h:383
bool dummy_view
Definition: pg_dump.h:342
bool forcerowsec
Definition: pg_dump.h:323
char ** attmissingval
Definition: pg_dump.h:370
uint32 toast_frozenxid
Definition: pg_dump.h:328
uint32 toast_minmxid
Definition: pg_dump.h:329
char * attalign
Definition: pg_dump.h:364
char * attcompression
Definition: pg_dump.h:368
bool postponed_def
Definition: pg_dump.h:343

References _attrDefInfo::adef_expr, _tableInfo::amname, append_depends_on_extension(), appendBinaryPQExpBuffer(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArrayAH(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), Assert(), _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attcompression, _tableInfo::attfdwoptions, _tableInfo::attgenerated, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attmissingval, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypnames, _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel(), _dumpableObject::catId, _tableInfo::checkexprs, _tableInfo::checkoption, comment, _constraintInfo::condef, _constraintInfo::conislocal, createDummyViewAsClause(), createDumpId(), 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, _dumpOptions::dumpSchema, dumpTableComment(), dumpTableConstraintComment(), dumpTableSecLabel(), ExecuteSqlQueryForSingleRow(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, _tableInfo::forcerowsec, free, _tableInfo::frozenxid, getFormattedTypeName(), _tableInfo::hasoids, _tableInfo::interesting, _tableInfo::ispartition, j, PQExpBufferData::len, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, nilCatalogId, _dumpOptions::no_comments, _dumpOptions::no_toast_compression, nonemptyReloptions(), _tableInfo::notnull_comment, _tableInfo::notnull_constrs, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, _tableInfo::numatts, _tableInfo::numParents, CatalogId::oid, OidIsValid, _tableInfo::parents, pg_log_warning, pg_strdup(), _tableInfo::postponed_def, PQclear, PQfnumber(), PQgetvalue, _tableInfo::relispopulated, _tableInfo::relkind, _tableInfo::reloftype, _tableInfo::reloptions, _tableInfo::relpersistence, _tableInfo::relreplident, _tableInfo::reltablespace, Archive::remoteVersion, resetPQExpBuffer(), _tableInfo::rolname, SECTION_NONE, 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 16616 of file pg_dump.c.

16617{
16618 DumpOptions *dopt = fout->dopt;
16619 SecLabelItem *labels;
16620 int nlabels;
16621 int i;
16622 PQExpBuffer query;
16623 PQExpBuffer target;
16624
16625 /* do nothing, if --no-security-labels is supplied */
16626 if (dopt->no_security_labels)
16627 return;
16628
16629 /* SecLabel are SCHEMA not data */
16630 if (!dopt->dumpSchema)
16631 return;
16632
16633 /* Search for comments associated with relation, using table */
16634 nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
16635 tbinfo->dobj.catId.oid,
16636 &labels);
16637
16638 /* If security labels exist, build SECURITY LABEL statements */
16639 if (nlabels <= 0)
16640 return;
16641
16642 query = createPQExpBuffer();
16643 target = createPQExpBuffer();
16644
16645 for (i = 0; i < nlabels; i++)
16646 {
16647 const char *colname;
16648 const char *provider = labels[i].provider;
16649 const char *label = labels[i].label;
16650 int objsubid = labels[i].objsubid;
16651
16652 resetPQExpBuffer(target);
16653 if (objsubid == 0)
16654 {
16655 appendPQExpBuffer(target, "%s %s", reltypename,
16656 fmtQualifiedDumpable(tbinfo));
16657 }
16658 else
16659 {
16660 colname = getAttrName(objsubid, tbinfo);
16661 /* first fmtXXX result must be consumed before calling again */
16662 appendPQExpBuffer(target, "COLUMN %s",
16663 fmtQualifiedDumpable(tbinfo));
16664 appendPQExpBuffer(target, ".%s", fmtId(colname));
16665 }
16666 appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
16667 fmtId(provider), target->data);
16668 appendStringLiteralAH(query, label, fout);
16669 appendPQExpBufferStr(query, ";\n");
16670 }
16671 if (query->len > 0)
16672 {
16673 resetPQExpBuffer(target);
16674 appendPQExpBuffer(target, "%s %s", reltypename,
16675 fmtId(tbinfo->dobj.name));
16677 ARCHIVE_OPTS(.tag = target->data,
16678 .namespace = tbinfo->dobj.namespace->dobj.name,
16679 .owner = tbinfo->rolname,
16680 .description = "SECURITY LABEL",
16681 .section = SECTION_NONE,
16682 .createStmt = query->data,
16683 .deps = &(tbinfo->dobj.dumpId),
16684 .nDeps = 1));
16685 }
16686 destroyPQExpBuffer(query);
16687 destroyPQExpBuffer(target);
16688}

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ARCHIVE_OPTS, ArchiveEntry(), _dumpableObject::catId, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, Archive::dopt, _dumpableObject::dumpId, _dumpOptions::dumpSchema, findSecLabels(), fmtId(), fmtQualifiedDumpable, getAttrName(), i, label, SecLabelItem::label, PQExpBufferData::len, _dumpableObject::name, nilCatalogId, _dumpOptions::no_security_labels, SecLabelItem::objsubid, CatalogId::oid, 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 13976 of file pg_dump.c.

13977{
13978 DumpOptions *dopt = fout->dopt;
13979 PQExpBuffer defqry;
13980 PQExpBuffer delqry;
13981 PQExpBuffer labelq;
13982 PQExpBuffer transformargs;
13983 FuncInfo *fromsqlFuncInfo = NULL;
13984 FuncInfo *tosqlFuncInfo = NULL;
13985 char *lanname;
13986 const char *transformType;
13987
13988 /* Do nothing if not dumping schema */
13989 if (!dopt->dumpSchema)
13990 return;
13991
13992 /* Cannot dump if we don't have the transform functions' info */
13993 if (OidIsValid(transform->trffromsql))
13994 {
13995 fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
13996 if (fromsqlFuncInfo == NULL)
13997 pg_fatal("could not find function definition for function with OID %u",
13998 transform->trffromsql);
13999 }
14000 if (OidIsValid(transform->trftosql))
14001 {
14002 tosqlFuncInfo = findFuncByOid(transform->trftosql);
14003 if (tosqlFuncInfo == NULL)
14004 pg_fatal("could not find function definition for function with OID %u",
14005 transform->trftosql);
14006 }
14007
14008 defqry = createPQExpBuffer();
14009 delqry = createPQExpBuffer();
14010 labelq = createPQExpBuffer();
14011 transformargs = createPQExpBuffer();
14012
14013 lanname = get_language_name(fout, transform->trflang);
14014 transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
14015
14016 appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
14017 transformType, lanname);
14018
14019 appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
14020 transformType, lanname);
14021
14022 if (!transform->trffromsql && !transform->trftosql)
14023 pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
14024
14025 if (transform->trffromsql)
14026 {
14027 if (fromsqlFuncInfo)
14028 {
14029 char *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
14030
14031 /*
14032 * Always qualify the function name (format_function_signature
14033 * won't qualify it).
14034 */
14035 appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
14036 fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
14037 free(fsig);
14038 }
14039 else
14040 pg_log_warning("bogus value in pg_transform.trffromsql field");
14041 }
14042
14043 if (transform->trftosql)
14044 {
14045 if (transform->trffromsql)
14046 appendPQExpBufferStr(defqry, ", ");
14047
14048 if (tosqlFuncInfo)
14049 {
14050 char *fsig = format_function_signature(fout, tosqlFuncInfo, true);
14051
14052 /*
14053 * Always qualify the function name (format_function_signature
14054 * won't qualify it).
14055 */
14056 appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
14057 fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
14058 free(fsig);
14059 }
14060 else
14061 pg_log_warning("bogus value in pg_transform.trftosql field");
14062 }
14063
14064 appendPQExpBufferStr(defqry, ");\n");
14065
14066 appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
14067 transformType, lanname);
14068
14069 appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
14070 transformType, lanname);
14071
14072 if (dopt->binary_upgrade)
14073 binary_upgrade_extension_member(defqry, &transform->dobj,
14074 "TRANSFORM", transformargs->data, NULL);
14075
14076 if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
14077 ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
14078 ARCHIVE_OPTS(.tag = labelq->data,
14079 .description = "TRANSFORM",
14080 .section = SECTION_PRE_DATA,
14081 .createStmt = defqry->data,
14082 .dropStmt = delqry->data,
14083 .deps = transform->dobj.dependencies,
14084 .nDeps = transform->dobj.nDeps));
14085
14086 /* Dump Transform Comments */
14087 if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
14088 dumpComment(fout, "TRANSFORM", transformargs->data,
14089 NULL, "",
14090 transform->dobj.catId, 0, transform->dobj.dumpId);
14091
14092 free(lanname);
14093 destroyPQExpBuffer(defqry);
14094 destroyPQExpBuffer(delqry);
14095 destroyPQExpBuffer(labelq);
14096 destroyPQExpBuffer(transformargs);
14097}
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:9129
DumpableObject dobj
Definition: pg_dump.h:554
Oid trffromsql
Definition: pg_dump.h:557

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, _dumpableObject::dependencies, destroyPQExpBuffer(), _funcInfo::dobj, _transformInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 19303 of file pg_dump.c.

19304{
19305 DumpOptions *dopt = fout->dopt;
19306 TableInfo *tbinfo = tginfo->tgtable;
19307 PQExpBuffer query;
19308 PQExpBuffer delqry;
19309 PQExpBuffer trigprefix;
19310 PQExpBuffer trigidentity;
19311 char *qtabname;
19312 char *tag;
19313
19314 /* Do nothing if not dumping schema */
19315 if (!dopt->dumpSchema)
19316 return;
19317
19318 query = createPQExpBuffer();
19319 delqry = createPQExpBuffer();
19320 trigprefix = createPQExpBuffer();
19321 trigidentity = createPQExpBuffer();
19322
19323 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
19324
19325 appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
19326 appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
19327
19328 appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
19329 appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
19330
19331 /* Triggers can depend on extensions */
19332 append_depends_on_extension(fout, query, &tginfo->dobj,
19333 "pg_catalog.pg_trigger", "TRIGGER",
19334 trigidentity->data);
19335
19336 if (tginfo->tgispartition)
19337 {
19338 Assert(tbinfo->ispartition);
19339
19340 /*
19341 * Partition triggers only appear here because their 'tgenabled' flag
19342 * differs from its parent's. The trigger is created already, so
19343 * remove the CREATE and replace it with an ALTER. (Clear out the
19344 * DROP query too, so that pg_dump --create does not cause errors.)
19345 */
19346 resetPQExpBuffer(query);
19347 resetPQExpBuffer(delqry);
19348 appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
19349 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
19350 fmtQualifiedDumpable(tbinfo));
19351 switch (tginfo->tgenabled)
19352 {
19353 case 'f':
19354 case 'D':
19355 appendPQExpBufferStr(query, "DISABLE");
19356 break;
19357 case 't':
19358 case 'O':
19359 appendPQExpBufferStr(query, "ENABLE");
19360 break;
19361 case 'R':
19362 appendPQExpBufferStr(query, "ENABLE REPLICA");
19363 break;
19364 case 'A':
19365 appendPQExpBufferStr(query, "ENABLE ALWAYS");
19366 break;
19367 }
19368 appendPQExpBuffer(query, " TRIGGER %s;\n",
19369 fmtId(tginfo->dobj.name));
19370 }
19371 else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
19372 {
19373 appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
19374 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
19375 fmtQualifiedDumpable(tbinfo));
19376 switch (tginfo->tgenabled)
19377 {
19378 case 'D':
19379 case 'f':
19380 appendPQExpBufferStr(query, "DISABLE");
19381 break;
19382 case 'A':
19383 appendPQExpBufferStr(query, "ENABLE ALWAYS");
19384 break;
19385 case 'R':
19386 appendPQExpBufferStr(query, "ENABLE REPLICA");
19387 break;
19388 default:
19389 appendPQExpBufferStr(query, "ENABLE");
19390 break;
19391 }
19392 appendPQExpBuffer(query, " TRIGGER %s;\n",
19393 fmtId(tginfo->dobj.name));
19394 }
19395
19396 appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
19397 fmtId(tginfo->dobj.name));
19398
19399 tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
19400
19401 if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19402 ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
19403 ARCHIVE_OPTS(.tag = tag,
19404 .namespace = tbinfo->dobj.namespace->dobj.name,
19405 .owner = tbinfo->rolname,
19406 .description = "TRIGGER",
19407 .section = SECTION_POST_DATA,
19408 .createStmt = query->data,
19409 .dropStmt = delqry->data));
19410
19411 if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19412 dumpComment(fout, trigprefix->data, qtabname,
19413 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
19414 tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
19415
19416 free(tag);
19417 destroyPQExpBuffer(query);
19418 destroyPQExpBuffer(delqry);
19419 destroyPQExpBuffer(trigprefix);
19420 destroyPQExpBuffer(trigidentity);
19421 free(qtabname);
19422}
TableInfo * tgtable
Definition: pg_dump.h:488
DumpableObject dobj
Definition: pg_dump.h:487
char tgenabled
Definition: pg_dump.h:489
char * tgdef
Definition: pg_dump.h:491
bool tgispartition
Definition: pg_dump.h:490

References append_depends_on_extension(), appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), Assert(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _triggerInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 15932 of file pg_dump.c.

15933{
15934 DumpOptions *dopt = fout->dopt;
15935 PQExpBuffer q;
15936 PQExpBuffer delq;
15937 PQExpBuffer query;
15938 char *qcfgname;
15939 PGresult *res;
15940 char *nspname;
15941 char *prsname;
15942 int ntups,
15943 i;
15944 int i_tokenname;
15945 int i_dictname;
15946
15947 /* Do nothing if not dumping schema */
15948 if (!dopt->dumpSchema)
15949 return;
15950
15951 q = createPQExpBuffer();
15952 delq = createPQExpBuffer();
15953 query = createPQExpBuffer();
15954
15955 qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
15956
15957 /* Fetch name and namespace of the config's parser */
15958 appendPQExpBuffer(query, "SELECT nspname, prsname "
15959 "FROM pg_ts_parser p, pg_namespace n "
15960 "WHERE p.oid = '%u' AND n.oid = prsnamespace",
15961 cfginfo->cfgparser);
15962 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15963 nspname = PQgetvalue(res, 0, 0);
15964 prsname = PQgetvalue(res, 0, 1);
15965
15966 appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
15967 fmtQualifiedDumpable(cfginfo));
15968
15969 appendPQExpBuffer(q, " PARSER = %s.", fmtId(nspname));
15970 appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
15971
15972 PQclear(res);
15973
15974 resetPQExpBuffer(query);
15975 appendPQExpBuffer(query,
15976 "SELECT\n"
15977 " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
15978 " WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
15979 " m.mapdict::pg_catalog.regdictionary AS dictname\n"
15980 "FROM pg_catalog.pg_ts_config_map AS m\n"
15981 "WHERE m.mapcfg = '%u'\n"
15982 "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
15983 cfginfo->cfgparser, cfginfo->dobj.catId.oid);
15984
15985 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15986 ntups = PQntuples(res);
15987
15988 i_tokenname = PQfnumber(res, "tokenname");
15989 i_dictname = PQfnumber(res, "dictname");
15990
15991 for (i = 0; i < ntups; i++)
15992 {
15993 char *tokenname = PQgetvalue(res, i, i_tokenname);
15994 char *dictname = PQgetvalue(res, i, i_dictname);
15995
15996 if (i == 0 ||
15997 strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
15998 {
15999 /* starting a new token type, so start a new command */
16000 if (i > 0)
16001 appendPQExpBufferStr(q, ";\n");
16002 appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
16003 fmtQualifiedDumpable(cfginfo));
16004 /* tokenname needs quoting, dictname does NOT */
16005 appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
16006 fmtId(tokenname), dictname);
16007 }
16008 else
16009 appendPQExpBuffer(q, ", %s", dictname);
16010 }
16011
16012 if (ntups > 0)
16013 appendPQExpBufferStr(q, ";\n");
16014
16015 PQclear(res);
16016
16017 appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
16018 fmtQualifiedDumpable(cfginfo));
16019
16020 if (dopt->binary_upgrade)
16022 "TEXT SEARCH CONFIGURATION", qcfgname,
16023 cfginfo->dobj.namespace->dobj.name);
16024
16025 if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16026 ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
16027 ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
16028 .namespace = cfginfo->dobj.namespace->dobj.name,
16029 .owner = cfginfo->rolname,
16030 .description = "TEXT SEARCH CONFIGURATION",
16031 .section = SECTION_PRE_DATA,
16032 .createStmt = q->data,
16033 .dropStmt = delq->data));
16034
16035 /* Dump Configuration Comments */
16036 if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16037 dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
16038 cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
16039 cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
16040
16042 destroyPQExpBuffer(delq);
16043 destroyPQExpBuffer(query);
16044 free(qcfgname);
16045}
Oid cfgparser
Definition: pg_dump.h:597
DumpableObject dobj
Definition: pg_dump.h:595
const char * rolname
Definition: pg_dump.h:596

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

Referenced by dumpDumpableObject().

◆ dumpTSDictionary()

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

Definition at line 15794 of file pg_dump.c.

15795{
15796 DumpOptions *dopt = fout->dopt;
15797 PQExpBuffer q;
15798 PQExpBuffer delq;
15799 PQExpBuffer query;
15800 char *qdictname;
15801 PGresult *res;
15802 char *nspname;
15803 char *tmplname;
15804
15805 /* Do nothing if not dumping schema */
15806 if (!dopt->dumpSchema)
15807 return;
15808
15809 q = createPQExpBuffer();
15810 delq = createPQExpBuffer();
15811 query = createPQExpBuffer();
15812
15813 qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
15814
15815 /* Fetch name and namespace of the dictionary's template */
15816 appendPQExpBuffer(query, "SELECT nspname, tmplname "
15817 "FROM pg_ts_template p, pg_namespace n "
15818 "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
15819 dictinfo->dicttemplate);
15820 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15821 nspname = PQgetvalue(res, 0, 0);
15822 tmplname = PQgetvalue(res, 0, 1);
15823
15824 appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
15825 fmtQualifiedDumpable(dictinfo));
15826
15827 appendPQExpBufferStr(q, " TEMPLATE = ");
15828 appendPQExpBuffer(q, "%s.", fmtId(nspname));
15829 appendPQExpBufferStr(q, fmtId(tmplname));
15830
15831 PQclear(res);
15832
15833 /* the dictinitoption can be dumped straight into the command */
15834 if (dictinfo->dictinitoption)
15835 appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
15836
15837 appendPQExpBufferStr(q, " );\n");
15838
15839 appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
15840 fmtQualifiedDumpable(dictinfo));
15841
15842 if (dopt->binary_upgrade)
15844 "TEXT SEARCH DICTIONARY", qdictname,
15845 dictinfo->dobj.namespace->dobj.name);
15846
15847 if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15848 ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
15849 ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
15850 .namespace = dictinfo->dobj.namespace->dobj.name,
15851 .owner = dictinfo->rolname,
15852 .description = "TEXT SEARCH DICTIONARY",
15853 .section = SECTION_PRE_DATA,
15854 .createStmt = q->data,
15855 .dropStmt = delq->data));
15856
15857 /* Dump Dictionary Comments */
15858 if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15859 dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
15860 dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
15861 dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
15862
15864 destroyPQExpBuffer(delq);
15865 destroyPQExpBuffer(query);
15866 free(qdictname);
15867}
char * dictinitoption
Definition: pg_dump.h:583
DumpableObject dobj
Definition: pg_dump.h:580
const char * rolname
Definition: pg_dump.h:581
Oid dicttemplate
Definition: pg_dump.h:582

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

Referenced by dumpDumpableObject().

◆ dumpTSParser()

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

Definition at line 15730 of file pg_dump.c.

15731{
15732 DumpOptions *dopt = fout->dopt;
15733 PQExpBuffer q;
15734 PQExpBuffer delq;
15735 char *qprsname;
15736
15737 /* Do nothing if not dumping schema */
15738 if (!dopt->dumpSchema)
15739 return;
15740
15741 q = createPQExpBuffer();
15742 delq = createPQExpBuffer();
15743
15744 qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
15745
15746 appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
15747 fmtQualifiedDumpable(prsinfo));
15748
15749 appendPQExpBuffer(q, " START = %s,\n",
15750 convertTSFunction(fout, prsinfo->prsstart));
15751 appendPQExpBuffer(q, " GETTOKEN = %s,\n",
15752 convertTSFunction(fout, prsinfo->prstoken));
15753 appendPQExpBuffer(q, " END = %s,\n",
15754 convertTSFunction(fout, prsinfo->prsend));
15755 if (prsinfo->prsheadline != InvalidOid)
15756 appendPQExpBuffer(q, " HEADLINE = %s,\n",
15757 convertTSFunction(fout, prsinfo->prsheadline));
15758 appendPQExpBuffer(q, " LEXTYPES = %s );\n",
15759 convertTSFunction(fout, prsinfo->prslextype));
15760
15761 appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
15762 fmtQualifiedDumpable(prsinfo));
15763
15764 if (dopt->binary_upgrade)
15766 "TEXT SEARCH PARSER", qprsname,
15767 prsinfo->dobj.namespace->dobj.name);
15768
15769 if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15770 ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
15771 ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
15772 .namespace = prsinfo->dobj.namespace->dobj.name,
15773 .description = "TEXT SEARCH PARSER",
15774 .section = SECTION_PRE_DATA,
15775 .createStmt = q->data,
15776 .dropStmt = delq->data));
15777
15778 /* Dump Parser Comments */
15779 if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15780 dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
15781 prsinfo->dobj.namespace->dobj.name, "",
15782 prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
15783
15785 destroyPQExpBuffer(delq);
15786 free(qprsname);
15787}
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:14395
DumpableObject dobj
Definition: pg_dump.h:570
Oid prstoken
Definition: pg_dump.h:572
Oid prslextype
Definition: pg_dump.h:575
Oid prsheadline
Definition: pg_dump.h:574
Oid prsstart
Definition: pg_dump.h:571
Oid prsend
Definition: pg_dump.h:573

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertTSFunction(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _prsInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 15874 of file pg_dump.c.

15875{
15876 DumpOptions *dopt = fout->dopt;
15877 PQExpBuffer q;
15878 PQExpBuffer delq;
15879 char *qtmplname;
15880
15881 /* Do nothing if not dumping schema */
15882 if (!dopt->dumpSchema)
15883 return;
15884
15885 q = createPQExpBuffer();
15886 delq = createPQExpBuffer();
15887
15888 qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
15889
15890 appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
15891 fmtQualifiedDumpable(tmplinfo));
15892
15893 if (tmplinfo->tmplinit != InvalidOid)
15894 appendPQExpBuffer(q, " INIT = %s,\n",
15895 convertTSFunction(fout, tmplinfo->tmplinit));
15896 appendPQExpBuffer(q, " LEXIZE = %s );\n",
15897 convertTSFunction(fout, tmplinfo->tmpllexize));
15898
15899 appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
15900 fmtQualifiedDumpable(tmplinfo));
15901
15902 if (dopt->binary_upgrade)
15904 "TEXT SEARCH TEMPLATE", qtmplname,
15905 tmplinfo->dobj.namespace->dobj.name);
15906
15907 if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15908 ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
15909 ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
15910 .namespace = tmplinfo->dobj.namespace->dobj.name,
15911 .description = "TEXT SEARCH TEMPLATE",
15912 .section = SECTION_PRE_DATA,
15913 .createStmt = q->data,
15914 .dropStmt = delq->data));
15915
15916 /* Dump Template Comments */
15917 if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15918 dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
15919 tmplinfo->dobj.namespace->dobj.name, "",
15920 tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
15921
15923 destroyPQExpBuffer(delq);
15924 free(qtmplname);
15925}
Oid tmpllexize
Definition: pg_dump.h:590
Oid tmplinit
Definition: pg_dump.h:589
DumpableObject dobj
Definition: pg_dump.h:588

References appendPQExpBuffer(), ARCHIVE_OPTS, ArchiveEntry(), _dumpOptions::binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertTSFunction(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tmplInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, 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 12057 of file pg_dump.c.

12058{
12059 DumpOptions *dopt = fout->dopt;
12060
12061 /* Do nothing if not dumping schema */
12062 if (!dopt->dumpSchema)
12063 return;
12064
12065 /* Dump out in proper style */
12066 if (tyinfo->typtype == TYPTYPE_BASE)
12067 dumpBaseType(fout, tyinfo);
12068 else if (tyinfo->typtype == TYPTYPE_DOMAIN)
12069 dumpDomain(fout, tyinfo);
12070 else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
12071 dumpCompositeType(fout, tyinfo);
12072 else if (tyinfo->typtype == TYPTYPE_ENUM)
12073 dumpEnumType(fout, tyinfo);
12074 else if (tyinfo->typtype == TYPTYPE_RANGE)
12075 dumpRangeType(fout, tyinfo);
12076 else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
12077 dumpUndefinedType(fout, tyinfo);
12078 else
12079 pg_log_warning("typtype of data type \"%s\" appears to be invalid",
12080 tyinfo->dobj.name);
12081}
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12450
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12228
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12699
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12386
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12924
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12088
bool isDefined
Definition: pg_dump.h:222
char typtype
Definition: pg_dump.h:219

References _typeInfo::dobj, Archive::dopt, dumpBaseType(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpRangeType(), _dumpOptions::dumpSchema, 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 12386 of file pg_dump.c.

12387{
12388 DumpOptions *dopt = fout->dopt;
12391 char *qtypname;
12392 char *qualtypname;
12393
12394 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12395 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12396
12397 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12398
12399 if (dopt->binary_upgrade)
12401 tyinfo->dobj.catId.oid,
12402 false, false);
12403
12404 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12405 qualtypname);
12406
12407 if (dopt->binary_upgrade)
12409 "TYPE", qtypname,
12410 tyinfo->dobj.namespace->dobj.name);
12411
12412 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12413 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12414 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12415 .namespace = tyinfo->dobj.namespace->dobj.name,
12416 .owner = tyinfo->rolname,
12417 .description = "TYPE",
12418 .section = SECTION_PRE_DATA,
12419 .createStmt = q->data,
12420 .dropStmt = delq->data));
12421
12422 /* Dump Type Comments and Security Labels */
12423 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12424 dumpComment(fout, "TYPE", qtypname,
12425 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12426 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12427
12428 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12429 dumpSecLabel(fout, "TYPE", qtypname,
12430 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12431 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12432
12433 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12434 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12435 qtypname, NULL,
12436 tyinfo->dobj.namespace->dobj.name,
12437 NULL, tyinfo->rolname, &tyinfo->dacl);
12438
12440 destroyPQExpBuffer(delq);
12441 free(qtypname);
12442 free(qualtypname);
12443}

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

16226{
16227 PQExpBuffer q;
16228 PQExpBuffer delq;
16229 PQExpBuffer query;
16230 PQExpBuffer tag;
16231 PGresult *res;
16232 int ntups;
16233 int i_usename;
16234 int i_umoptions;
16235 int i;
16236
16237 q = createPQExpBuffer();
16238 tag = createPQExpBuffer();
16239 delq = createPQExpBuffer();
16240 query = createPQExpBuffer();
16241
16242 /*
16243 * We read from the publicly accessible view pg_user_mappings, so as not
16244 * to fail if run by a non-superuser. Note that the view will show
16245 * umoptions as null if the user hasn't got privileges for the associated
16246 * server; this means that pg_dump will dump such a mapping, but with no
16247 * OPTIONS clause. A possible alternative is to skip such mappings
16248 * altogether, but it's not clear that that's an improvement.
16249 */
16250 appendPQExpBuffer(query,
16251 "SELECT usename, "
16252 "array_to_string(ARRAY("
16253 "SELECT quote_ident(option_name) || ' ' || "
16254 "quote_literal(option_value) "
16255 "FROM pg_options_to_table(umoptions) "
16256 "ORDER BY option_name"
16257 "), E',\n ') AS umoptions "
16258 "FROM pg_user_mappings "
16259 "WHERE srvid = '%u' "
16260 "ORDER BY usename",
16261 catalogId.oid);
16262
16263 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16264
16265 ntups = PQntuples(res);
16266 i_usename = PQfnumber(res, "usename");
16267 i_umoptions = PQfnumber(res, "umoptions");
16268
16269 for (i = 0; i < ntups; i++)
16270 {
16271 char *usename;
16272 char *umoptions;
16273
16274 usename = PQgetvalue(res, i, i_usename);
16275 umoptions = PQgetvalue(res, i, i_umoptions);
16276
16278 appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
16279 appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
16280
16281 if (umoptions && strlen(umoptions) > 0)
16282 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions);
16283
16284 appendPQExpBufferStr(q, ";\n");
16285
16286 resetPQExpBuffer(delq);
16287 appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
16288 appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
16289
16290 resetPQExpBuffer(tag);
16291 appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
16292 usename, servername);
16293
16295 ARCHIVE_OPTS(.tag = tag->data,
16296 .namespace = namespace,
16297 .owner = owner,
16298 .description = "USER MAPPING",
16299 .section = SECTION_PRE_DATA,
16300 .createStmt = q->data,
16301 .dropStmt = delq->data));
16302 }
16303
16304 PQclear(res);
16305
16306 destroyPQExpBuffer(query);
16307 destroyPQExpBuffer(delq);
16308 destroyPQExpBuffer(tag);
16310}

References appendPQExpBuffer(), appendPQExpBufferStr(), ARCHIVE_OPTS, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), fmtId(), i, nilCatalogId, CatalogId::oid, PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, 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 1722 of file pg_dump.c.

1726{
1727 PQExpBuffer query;
1728 PGresult *res;
1730 int i;
1731
1732 if (patterns->head == NULL)
1733 return; /* nothing to do */
1734
1735 query = createPQExpBuffer();
1736
1737 /*
1738 * The loop below runs multiple SELECTs might sometimes result in
1739 * duplicate entries in the OID list, but we don't care.
1740 */
1741 for (cell = patterns->head; cell; cell = cell->next)
1742 {
1743 int dotcnt;
1744
1746 "SELECT oid FROM pg_catalog.pg_extension e\n");
1747 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1748 false, NULL, "e.extname", NULL, NULL, NULL,
1749 &dotcnt);
1750 if (dotcnt > 0)
1751 pg_fatal("improper qualified name (too many dotted names): %s",
1752 cell->val);
1753
1754 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1755 if (strict_names && PQntuples(res) == 0)
1756 pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
1757
1758 for (i = 0; i < PQntuples(res); i++)
1759 {
1760 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1761 }
1762
1763 PQclear(res);
1764 resetPQExpBuffer(query);
1765 }
1766
1767 destroyPQExpBuffer(query);
1768}
static int strict_names
Definition: pg_dump.c:155
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)
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(), 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 1775 of file pg_dump.c.

1778{
1779 PQExpBuffer query;
1780 PGresult *res;
1782 int i;
1783
1784 if (patterns->head == NULL)
1785 return; /* nothing to do */
1786
1787 query = createPQExpBuffer();
1788
1789 /*
1790 * The loop below runs multiple SELECTs might sometimes result in
1791 * duplicate entries in the OID list, but we don't care.
1792 */
1793
1794 for (cell = patterns->head; cell; cell = cell->next)
1795 {
1796 int dotcnt;
1797
1799 "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
1800 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1801 false, NULL, "s.srvname", NULL, NULL, NULL,
1802 &dotcnt);
1803 if (dotcnt > 0)
1804 pg_fatal("improper qualified name (too many dotted names): %s",
1805 cell->val);
1806
1807 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1808 if (PQntuples(res) == 0)
1809 pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
1810
1811 for (i = 0; i < PQntuples(res); i++)
1812 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1813
1814 PQclear(res);
1815 resetPQExpBuffer(query);
1816 }
1817
1818 destroyPQExpBuffer(query);
1819}

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), GetConnection(), SimpleStringList::head, i, SimpleStringListCell::next, pg_fatal, PGRES_TUPLES_OK, PQclear, PQgetvalue, PQntuples, processSQLNamePattern(), 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 1663 of file pg_dump.c.

1667{
1668 PQExpBuffer query;
1669 PGresult *res;
1671 int i;
1672
1673 if (patterns->head == NULL)
1674 return; /* nothing to do */
1675
1676 query = createPQExpBuffer();
1677
1678 /*
1679 * The loop below runs multiple SELECTs might sometimes result in
1680 * duplicate entries in the OID list, but we don't care.
1681 */
1682
1683 for (cell = patterns->head; cell; cell = cell->next)
1684 {
1685 PQExpBufferData dbbuf;
1686 int dotcnt;
1687
1689 "SELECT oid FROM pg_catalog.pg_namespace n\n");
1690 initPQExpBuffer(&dbbuf);
1691 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1692 false, NULL, "n.nspname", NULL, NULL, &dbbuf,
1693 &dotcnt);
1694 if (dotcnt > 1)
1695 pg_fatal("improper qualified name (too many dotted names): %s",
1696 cell->val);
1697 else if (dotcnt == 1)
1698 prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1699 termPQExpBuffer(&dbbuf);
1700
1701 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1702 if (strict_names && PQntuples(res) == 0)
1703 pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
1704
1705 for (i = 0; i < PQntuples(res); i++)
1706 {
1707 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1708 }
1709
1710 PQclear(res);
1711 resetPQExpBuffer(query);
1712 }
1713
1714 destroyPQExpBuffer(query);
1715}
static void prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
Definition: pg_dump.c:1923
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(), 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 1827 of file pg_dump.c.

1830{
1831 PQExpBuffer query;
1832 PGresult *res;
1834 int i;
1835
1836 if (patterns->head == NULL)
1837 return; /* nothing to do */
1838
1839 query = createPQExpBuffer();
1840
1841 /*
1842 * this might sometimes result in duplicate entries in the OID list, but
1843 * we don't care.
1844 */
1845
1846 for (cell = patterns->head; cell; cell = cell->next)
1847 {
1848 PQExpBufferData dbbuf;
1849 int dotcnt;
1850
1851 /*
1852 * Query must remain ABSOLUTELY devoid of unqualified names. This
1853 * would be unnecessary given a pg_table_is_visible() variant taking a
1854 * search_path argument.
1855 *
1856 * For with_child_tables, we start with the basic query's results and
1857 * recursively search the inheritance tree to add child tables.
1858 */
1859 if (with_child_tables)
1860 {
1861 appendPQExpBufferStr(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
1862 }
1863
1864 appendPQExpBuffer(query,
1865 "SELECT c.oid"
1866 "\nFROM pg_catalog.pg_class c"
1867 "\n LEFT JOIN pg_catalog.pg_namespace n"
1868 "\n ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
1869 "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
1870 "\n (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
1871 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
1872 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
1873 RELKIND_PARTITIONED_TABLE);
1874 initPQExpBuffer(&dbbuf);
1875 processSQLNamePattern(GetConnection(fout), query, cell->val, true,
1876 false, "n.nspname", "c.relname", NULL,
1877 "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
1878 &dotcnt);
1879 if (dotcnt > 2)
1880 pg_fatal("improper relation name (too many dotted names): %s",
1881 cell->val);
1882 else if (dotcnt == 2)
1883 prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1884 termPQExpBuffer(&dbbuf);
1885
1886 if (with_child_tables)
1887 {
1888 appendPQExpBufferStr(query, "UNION"
1889 "\nSELECT i.inhrelid"
1890 "\nFROM partition_tree p"
1891 "\n JOIN pg_catalog.pg_inherits i"
1892 "\n ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
1893 "\n)"
1894 "\nSELECT relid FROM partition_tree");
1895 }
1896
1897 ExecuteSqlStatement(fout, "RESET search_path");
1898 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1901 if (strict_names && PQntuples(res) == 0)
1902 pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
1903
1904 for (i = 0; i < PQntuples(res); i++)
1905 {
1906 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1907 }
1908
1909 PQclear(res);
1910 resetPQExpBuffer(query);
1911 }
1912
1913 destroyPQExpBuffer(query);
1914}
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25

References ALWAYS_SECURE_SEARCH_PATH_SQL, appendPQExpBuffer(), appendPQExpBufferStr(), 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(), resetPQExpBuffer(), simple_oid_list_append(), strict_names, termPQExpBuffer(), and SimpleStringListCell::val.

Referenced by main().

◆ fetchAttributeStats()

static PGresult * fetchAttributeStats ( Archive fout)
static

Definition at line 11014 of file pg_dump.c.

11015{
11016 ArchiveHandle *AH = (ArchiveHandle *) fout;
11017 PQExpBuffer nspnames = createPQExpBuffer();
11018 PQExpBuffer relnames = createPQExpBuffer();
11019 int count = 0;
11020 PGresult *res = NULL;
11021 static TocEntry *te;
11022 static bool restarted;
11023 int max_rels = MAX_ATTR_STATS_RELS;
11024
11025 /*
11026 * Our query for retrieving statistics for multiple relations uses WITH
11027 * ORDINALITY and multi-argument UNNEST(), both of which were introduced
11028 * in v9.4. For older versions, we resort to gathering statistics for a
11029 * single relation at a time.
11030 */
11031 if (fout->remoteVersion < 90400)
11032 max_rels = 1;
11033
11034 /* If we're just starting, set our TOC pointer. */
11035 if (!te)
11036 te = AH->toc->next;
11037
11038 /*
11039 * We can't easily avoid a second TOC scan for the tar format because it
11040 * writes restore.sql separately, which means we must execute the queries
11041 * twice. This feels risky, but there is no known reason it should
11042 * generate different output than the first pass. Even if it does, the
11043 * worst-case scenario is that restore.sql might have different statistics
11044 * data than the archive.
11045 */
11046 if (!restarted && te == AH->toc && AH->format == archTar)
11047 {
11048 te = AH->toc->next;
11049 restarted = true;
11050 }
11051
11052 appendPQExpBufferChar(nspnames, '{');
11053 appendPQExpBufferChar(relnames, '{');
11054
11055 /*
11056 * Scan the TOC for the next set of relevant stats entries. We assume
11057 * that statistics are dumped in the order they are listed in the TOC.
11058 * This is perhaps not the sturdiest assumption, so we verify it matches
11059 * reality in dumpRelationStats_dumper().
11060 */
11061 for (; te != AH->toc && count < max_rels; te = te->next)
11062 {
11063 if ((te->reqs & REQ_STATS) != 0 &&
11064 strcmp(te->desc, "STATISTICS DATA") == 0)
11065 {
11066 appendPGArray(nspnames, te->namespace);
11067 appendPGArray(relnames, te->tag);
11068 count++;
11069 }
11070 }
11071
11072 appendPQExpBufferChar(nspnames, '}');
11073 appendPQExpBufferChar(relnames, '}');
11074
11075 /* Execute the query for the next batch of relations. */
11076 if (count > 0)
11077 {
11079
11080 appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
11081 appendStringLiteralAH(query, nspnames->data, fout);
11082 appendPQExpBufferStr(query, "::pg_catalog.name[],");
11083 appendStringLiteralAH(query, relnames->data, fout);
11084 appendPQExpBufferStr(query, "::pg_catalog.name[])");
11085 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11086 destroyPQExpBuffer(query);
11087 }
11088
11089 destroyPQExpBuffer(nspnames);
11090 destroyPQExpBuffer(relnames);
11091 return res;
11092}
@ archTar
Definition: pg_backup.h:43
#define MAX_ATTR_STATS_RELS
Definition: pg_dump.c:222
void appendPGArray(PQExpBuffer buffer, const char *value)
Definition: string_utils.c:902
ArchiveFormat format

References appendPGArray(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAH, archTar, createPQExpBuffer(), PQExpBufferData::data, _tocEntry::desc, destroyPQExpBuffer(), ExecuteSqlQuery(), _archiveHandle::format, MAX_ATTR_STATS_RELS, _tocEntry::next, PGRES_TUPLES_OK, Archive::remoteVersion, REQ_STATS, _tocEntry::reqs, _tocEntry::tag, and _archiveHandle::toc.

Referenced by dumpRelationStats_dumper().

◆ findComments()

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

Definition at line 11499 of file pg_dump.c.

11500{
11501 CommentItem *middle = NULL;
11502 CommentItem *low;
11503 CommentItem *high;
11504 int nmatch;
11505
11506 /*
11507 * Do binary search to find some item matching the object.
11508 */
11509 low = &comments[0];
11510 high = &comments[ncomments - 1];
11511 while (low <= high)
11512 {
11513 middle = low + (high - low) / 2;
11514
11515 if (classoid < middle->classoid)
11516 high = middle - 1;
11517 else if (classoid > middle->classoid)
11518 low = middle + 1;
11519 else if (objoid < middle->objoid)
11520 high = middle - 1;
11521 else if (objoid > middle->objoid)
11522 low = middle + 1;
11523 else
11524 break; /* found a match */
11525 }
11526
11527 if (low > high) /* no matches */
11528 {
11529 *items = NULL;
11530 return 0;
11531 }
11532
11533 /*
11534 * Now determine how many items match the object. The search loop
11535 * invariant still holds: only items between low and high inclusive could
11536 * match.
11537 */
11538 nmatch = 1;
11539 while (middle > low)
11540 {
11541 if (classoid != middle[-1].classoid ||
11542 objoid != middle[-1].objoid)
11543 break;
11544 middle--;
11545 nmatch++;
11546 }
11547
11548 *items = middle;
11549
11550 middle += nmatch;
11551 while (middle <= high)
11552 {
11553 if (classoid != middle->classoid ||
11554 objoid != middle->objoid)
11555 break;
11556 middle++;
11557 nmatch++;
11558 }
11559
11560 return nmatch;
11561}
static ItemArray items
Definition: test_tidstore.c:48

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

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

◆ findDumpableDependencies()

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

Definition at line 20311 of file pg_dump.c.

20313{
20314 int i;
20315
20316 /*
20317 * Ignore section boundary objects: if we search through them, we'll
20318 * report lots of bogus dependencies.
20319 */
20320 if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
20322 return;
20323
20324 for (i = 0; i < dobj->nDeps; i++)
20325 {
20326 DumpId depid = dobj->dependencies[i];
20327
20328 if (TocIDRequired(AH, depid) != 0)
20329 {
20330 /* Object will be dumped, so just reference it as a dependency */
20331 if (*nDeps >= *allocDeps)
20332 {
20333 *allocDeps *= 2;
20334 *dependencies = (DumpId *) pg_realloc(*dependencies,
20335 *allocDeps * sizeof(DumpId));
20336 }
20337 (*dependencies)[*nDeps] = depid;
20338 (*nDeps)++;
20339 }
20340 else
20341 {
20342 /*
20343 * Object will not be dumped, so recursively consider its deps. We
20344 * rely on the assumption that sortDumpableObjects already broke
20345 * any dependency loops, else we might recurse infinitely.
20346 */
20347 DumpableObject *otherdobj = findObjectByDumpId(depid);
20348
20349 if (otherdobj)
20350 findDumpableDependencies(AH, otherdobj,
20351 dependencies, nDeps, allocDeps);
20352 }
20353 }
20354}
int TocIDRequired(ArchiveHandle *AH, DumpId id)

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

Referenced by BuildArchiveDependencies(), and findDumpableDependencies().

◆ findNamespace()

static NamespaceInfo * findNamespace ( Oid  nsoid)
static

Definition at line 6105 of file pg_dump.c.

6106{
6107 NamespaceInfo *nsinfo;
6108
6109 nsinfo = findNamespaceByOid(nsoid);
6110 if (nsinfo == NULL)
6111 pg_fatal("schema with OID %u does not exist", nsoid);
6112 return nsinfo;
6113}
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:990

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

16699{
16700 SecLabelItem *middle = NULL;
16701 SecLabelItem *low;
16702 SecLabelItem *high;
16703 int nmatch;
16704
16705 if (nseclabels <= 0) /* no labels, so no match is possible */
16706 {
16707 *items = NULL;
16708 return 0;
16709 }
16710
16711 /*
16712 * Do binary search to find some item matching the object.
16713 */
16714 low = &seclabels[0];
16715 high = &seclabels[nseclabels - 1];
16716 while (low <= high)
16717 {
16718 middle = low + (high - low) / 2;
16719
16720 if (classoid < middle->classoid)
16721 high = middle - 1;
16722 else if (classoid > middle->classoid)
16723 low = middle + 1;
16724 else if (objoid < middle->objoid)
16725 high = middle - 1;
16726 else if (objoid > middle->objoid)
16727 low = middle + 1;
16728 else
16729 break; /* found a match */
16730 }
16731
16732 if (low > high) /* no matches */
16733 {
16734 *items = NULL;
16735 return 0;
16736 }
16737
16738 /*
16739 * Now determine how many items match the object. The search loop
16740 * invariant still holds: only items between low and high inclusive could
16741 * match.
16742 */
16743 nmatch = 1;
16744 while (middle > low)
16745 {
16746 if (classoid != middle[-1].classoid ||
16747 objoid != middle[-1].objoid)
16748 break;
16749 middle--;
16750 nmatch++;
16751 }
16752
16753 *items = middle;
16754
16755 middle += nmatch;
16756 while (middle <= high)
16757 {
16758 if (classoid != middle->classoid ||
16759 objoid != middle->objoid)
16760 break;
16761 middle++;
16762 nmatch++;
16763 }
16764
16765 return nmatch;
16766}

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

20419{
20420 int numatts = ti->numatts;
20421 char **attnames = ti->attnames;
20422 bool *attisdropped = ti->attisdropped;
20423 char *attgenerated = ti->attgenerated;
20424 bool needComma;
20425 int i;
20426
20427 appendPQExpBufferChar(buffer, '(');
20428 needComma = false;
20429 for (i = 0; i < numatts; i++)
20430 {
20431 if (attisdropped[i])
20432 continue;
20433 if (attgenerated[i])
20434 continue;
20435 if (needComma)
20436 appendPQExpBufferStr(buffer, ", ");
20437 appendPQExpBufferStr(buffer, fmtId(attnames[i]));
20438 needComma = true;
20439 }
20440
20441 if (!needComma)
20442 return ""; /* no undropped columns */
20443
20444 appendPQExpBufferChar(buffer, ')');
20445 return buffer->data;
20446}

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

2843{
2844 TableInfo *parentTbinfo;
2845
2846 Assert(tbinfo->ispartition);
2847 Assert(tbinfo->numParents == 1);
2848
2849 parentTbinfo = tbinfo->parents[0];
2850 if (parentTbinfo->unsafe_partitions)
2851 return true;
2852 while (parentTbinfo->ispartition)
2853 {
2854 Assert(parentTbinfo->numParents == 1);
2855 parentTbinfo = parentTbinfo->parents[0];
2856 if (parentTbinfo->unsafe_partitions)
2857 return true;
2858 }
2859
2860 return false;
2861}
bool unsafe_partitions
Definition: pg_dump.h:345

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

15339{
15341 int j;
15342
15344 if (honor_quotes)
15345 appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
15346 else
15347 appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
15348
15349 if (agginfo->aggfn.nargs == 0)
15350 appendPQExpBufferStr(&buf, "(*)");
15351 else
15352 {
15354 for (j = 0; j < agginfo->aggfn.nargs; j++)
15355 appendPQExpBuffer(&buf, "%s%s",
15356 (j > 0) ? ", " : "",
15358 agginfo->aggfn.argtypes[j],
15359 zeroIsError));
15361 }
15362 return buf.data;
15363}

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

13398{
13400
13403 if (is_agg && finfo->nargs == 0)
13404 appendPQExpBufferStr(&fn, "(*)");
13405 else
13406 appendPQExpBuffer(&fn, "(%s)", funcargs);
13407 return fn.data;
13408}
int nargs
Definition: pg_dump.h:245
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 13420 of file pg_dump.c.

13421{
13423 int j;
13424
13426 if (honor_quotes)
13427 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
13428 else
13429 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
13430 for (j = 0; j < finfo->nargs; j++)
13431 {
13432 if (j > 0)
13433 appendPQExpBufferStr(&fn, ", ");
13434
13436 getFormattedTypeName(fout, finfo->argtypes[j],
13437 zeroIsError));
13438 }
13440 return fn.data;
13441}
Oid * argtypes
Definition: pg_dump.h:246

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

9130{
9131 PQExpBuffer query;
9132 PGresult *res;
9133 char *lanname;
9134
9135 query = createPQExpBuffer();
9136 appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
9137 res = ExecuteSqlQueryForSingleRow(fout, query->data);
9138 lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
9139 destroyPQExpBuffer(query);
9140 PQclear(res);
9141
9142 return lanname;
9143}

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

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

5682{
5683 /*
5684 * If the old version didn't assign an array type, but the new version
5685 * does, we must select an unused type OID to assign. This currently only
5686 * happens for domains, when upgrading pre-v11 to v11 and up.
5687 *
5688 * Note: local state here is kind of ugly, but we must have some, since we
5689 * mustn't choose the same unused OID more than once.
5690 */
5691 static Oid next_possible_free_oid = FirstNormalObjectId;
5692 PGresult *res;
5693 bool is_dup;
5694
5695 do
5696 {
5697 ++next_possible_free_oid;
5698 printfPQExpBuffer(upgrade_query,
5699 "SELECT EXISTS(SELECT 1 "
5700 "FROM pg_catalog.pg_type "
5701 "WHERE oid = '%u'::pg_catalog.oid);",
5702 next_possible_free_oid);
5703 res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5704 is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
5705 PQclear(res);
5706 } while (is_dup);
5707
5708 return next_possible_free_oid;
5709}
#define FirstNormalObjectId
Definition: transam.h:197

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

Referenced by binary_upgrade_set_type_oids_by_type_oid().

◆ get_synchronized_snapshot()

static char * get_synchronized_snapshot ( Archive fout)
static

Definition at line 1611 of file pg_dump.c.

1612{
1613 char *query = "SELECT pg_catalog.pg_export_snapshot()";
1614 char *result;
1615 PGresult *res;
1616
1617 res = ExecuteSqlQueryForSingleRow(fout, query);
1618 result = pg_strdup(PQgetvalue(res, 0, 0));
1619 PQclear(res);
1620
1621 return result;
1622}

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

Referenced by setup_connection().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6570 of file pg_dump.c.

6571{
6572 PGresult *res;
6573 int ntups;
6574 int i;
6575 PQExpBuffer query;
6576 AccessMethodInfo *aminfo;
6577 int i_tableoid;
6578 int i_oid;
6579 int i_amname;
6580 int i_amhandler;
6581 int i_amtype;
6582
6583 query = createPQExpBuffer();
6584
6585 /*
6586 * Select all access methods from pg_am table. v9.6 introduced CREATE
6587 * ACCESS METHOD, so earlier versions usually have only built-in access
6588 * methods. v9.6 also changed the access method API, replacing dozens of
6589 * pg_am columns with amhandler. Even if a user created an access method
6590 * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am
6591 * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read
6592 * pg_am just to facilitate findAccessMethodByOid() providing the
6593 * OID-to-name mapping.
6594 */
6595 appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, ");
6596 if (fout->remoteVersion >= 90600)
6598 "amtype, "
6599 "amhandler::pg_catalog.regproc AS amhandler ");
6600 else
6602 "'i'::pg_catalog.\"char\" AS amtype, "
6603 "'-'::pg_catalog.regproc AS amhandler ");
6604 appendPQExpBufferStr(query, "FROM pg_am");
6605
6606 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6607
6608 ntups = PQntuples(res);
6609
6610 aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6611
6612 i_tableoid = PQfnumber(res, "tableoid");
6613 i_oid = PQfnumber(res, "oid");
6614 i_amname = PQfnumber(res, "amname");
6615 i_amhandler = PQfnumber(res, "amhandler");
6616 i_amtype = PQfnumber(res, "amtype");
6617
6618 for (i = 0; i < ntups; i++)
6619 {
6620 aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6621 aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6622 aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6623 AssignDumpId(&aminfo[i].dobj);
6624 aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6625 aminfo[i].dobj.namespace = NULL;
6626 aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6627 aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6628
6629 /* Decide whether we want to dump it */
6630 selectDumpableAccessMethod(&(aminfo[i]), fout);
6631 }
6632
6633 PQclear(res);
6634
6635 destroyPQExpBuffer(query);
6636}
static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
Definition: pg_dump.c:2248

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, selectDumpableAccessMethod(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getAdditionalACLs()

static void getAdditionalACLs ( Archive fout)
static

Definition at line 10751 of file pg_dump.c.

10752{
10754 PGresult *res;
10755 int ntups,
10756 i;
10757
10758 /* Check for per-column ACLs */
10760 "SELECT DISTINCT attrelid FROM pg_attribute "
10761 "WHERE attacl IS NOT NULL");
10762
10763 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10764
10765 ntups = PQntuples(res);
10766 for (i = 0; i < ntups; i++)
10767 {
10768 Oid relid = atooid(PQgetvalue(res, i, 0));
10769 TableInfo *tblinfo;
10770
10771 tblinfo = findTableByOid(relid);
10772 /* OK to ignore tables we haven't got a DumpableObject for */
10773 if (tblinfo)
10774 {
10776 tblinfo->hascolumnACLs = true;
10777 }
10778 }
10779 PQclear(res);
10780
10781 /* Fetch initial-privileges data */
10782 if (fout->remoteVersion >= 90600)
10783 {
10784 printfPQExpBuffer(query,
10785 "SELECT objoid, classoid, objsubid, privtype, initprivs "
10786 "FROM pg_init_privs");
10787
10788 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10789
10790 ntups = PQntuples(res);
10791 for (i = 0; i < ntups; i++)
10792 {
10793 Oid objoid = atooid(PQgetvalue(res, i, 0));
10794 Oid classoid = atooid(PQgetvalue(res, i, 1));
10795 int objsubid = atoi(PQgetvalue(res, i, 2));
10796 char privtype = *(PQgetvalue(res, i, 3));
10797 char *initprivs = PQgetvalue(res, i, 4);
10798 CatalogId objId;
10799 DumpableObject *dobj;
10800
10801 objId.tableoid = classoid;
10802 objId.oid = objoid;
10803 dobj = findObjectByCatalogId(objId);
10804 /* OK to ignore entries we haven't got a DumpableObject for */
10805 if (dobj)
10806 {
10807 /* Cope with sub-object initprivs */
10808 if (objsubid != 0)
10809 {
10810 if (dobj->objType == DO_TABLE)
10811 {
10812 /* For a column initprivs, set the table's ACL flags */
10814 ((TableInfo *) dobj)->hascolumnACLs = true;
10815 }
10816 else
10817 pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10818 classoid, objoid, objsubid);
10819 continue;
10820 }
10821
10822 /*
10823 * We ignore any pg_init_privs.initprivs entry for the public
10824 * schema, as explained in getNamespaces().
10825 */
10826 if (dobj->objType == DO_NAMESPACE &&
10827 strcmp(dobj->name, "public") == 0)
10828 continue;
10829
10830 /* Else it had better be of a type we think has ACLs */
10831 if (dobj->objType == DO_NAMESPACE ||
10832 dobj->objType == DO_TYPE ||
10833 dobj->objType == DO_FUNC ||
10834 dobj->objType == DO_AGG ||
10835 dobj->objType == DO_TABLE ||
10836 dobj->objType == DO_PROCLANG ||
10837 dobj->objType == DO_FDW ||
10838 dobj->objType == DO_FOREIGN_SERVER)
10839 {
10841
10842 daobj->dacl.privtype = privtype;
10843 daobj->dacl.initprivs = pstrdup(initprivs);
10844 }
10845 else
10846 pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10847 classoid, objoid, objsubid);
10848 }
10849 }
10850 PQclear(res);
10851 }
10852
10853 destroyPQExpBuffer(query);
10854}
DumpableAcl dacl
Definition: pg_dump.h:181

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, and CatalogId::tableoid.

Referenced by main().

◆ getAggregates()

void getAggregates ( Archive fout)

Definition at line 6772 of file pg_dump.c.

6773{
6774 DumpOptions *dopt = fout->dopt;
6775 PGresult *res;
6776 int ntups;
6777 int i;
6779 AggInfo *agginfo;
6780 int i_tableoid;
6781 int i_oid;
6782 int i_aggname;
6783 int i_aggnamespace;
6784 int i_pronargs;
6785 int i_proargtypes;
6786 int i_proowner;
6787 int i_aggacl;
6788 int i_acldefault;
6789
6790 /*
6791 * Find all interesting aggregates. See comment in getFuncs() for the
6792 * rationale behind the filtering logic.
6793 */
6794 if (fout->remoteVersion >= 90600)
6795 {
6796 const char *agg_check;
6797
6798 agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
6799 : "p.proisagg");
6800
6801 appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
6802 "p.proname AS aggname, "
6803 "p.pronamespace AS aggnamespace, "
6804 "p.pronargs, p.proargtypes, "
6805 "p.proowner, "
6806 "p.proacl AS aggacl, "
6807 "acldefault('f', p.proowner) AS acldefault "
6808 "FROM pg_proc p "
6809 "LEFT JOIN pg_init_privs pip ON "
6810 "(p.oid = pip.objoid "
6811 "AND pip.classoid = 'pg_proc'::regclass "
6812 "AND pip.objsubid = 0) "
6813 "WHERE %s AND ("
6814 "p.pronamespace != "
6815 "(SELECT oid FROM pg_namespace "
6816 "WHERE nspname = 'pg_catalog') OR "
6817 "p.proacl IS DISTINCT FROM pip.initprivs",
6818 agg_check);
6819 if (dopt->binary_upgrade)
6821 " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6822 "classid = 'pg_proc'::regclass AND "
6823 "objid = p.oid AND "
6824 "refclassid = 'pg_extension'::regclass AND "
6825 "deptype = 'e')");
6826 appendPQExpBufferChar(query, ')');
6827 }
6828 else
6829 {
6830 appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
6831 "pronamespace AS aggnamespace, "
6832 "pronargs, proargtypes, "
6833 "proowner, "
6834 "proacl AS aggacl, "
6835 "acldefault('f', proowner) AS acldefault "
6836 "FROM pg_proc p "
6837 "WHERE proisagg AND ("
6838 "pronamespace != "
6839 "(SELECT oid FROM pg_namespace "
6840 "WHERE nspname = 'pg_catalog')");
6841 if (dopt->binary_upgrade)
6843 " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6844 "classid = 'pg_proc'::regclass AND "
6845 "objid = p.oid AND "
6846 "refclassid = 'pg_extension'::regclass AND "
6847 "deptype = 'e')");
6848 appendPQExpBufferChar(query, ')');
6849 }
6850
6851 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6852
6853 ntups = PQntuples(res);
6854
6855 agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
6856
6857 i_tableoid = PQfnumber(res, "tableoid");
6858 i_oid = PQfnumber(res, "oid");
6859 i_aggname = PQfnumber(res, "aggname");
6860 i_aggnamespace = PQfnumber(res, "aggnamespace");
6861 i_pronargs = PQfnumber(res, "pronargs");
6862 i_proargtypes = PQfnumber(res, "proargtypes");
6863 i_proowner = PQfnumber(res, "proowner");
6864 i_aggacl = PQfnumber(res, "aggacl");
6865 i_acldefault = PQfnumber(res, "acldefault");
6866
6867 for (i = 0; i < ntups; i++)
6868 {
6869 agginfo[i].aggfn.dobj.objType = DO_AGG;
6870 agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6871 agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6872 AssignDumpId(&agginfo[i].aggfn.dobj);
6873 agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
6874 agginfo[i].aggfn.dobj.namespace =
6875 findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
6876 agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
6877 agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6878 agginfo[i].aggfn.dacl.privtype = 0;
6879 agginfo[i].aggfn.dacl.initprivs = NULL;
6880 agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6881 agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
6882 agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
6883 agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
6884 if (agginfo[i].aggfn.nargs == 0)
6885 agginfo[i].aggfn.argtypes = NULL;
6886 else
6887 {
6888 agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
6889 parseOidArray(PQgetvalue(res, i, i_proargtypes),
6890 agginfo[i].aggfn.argtypes,
6891 agginfo[i].aggfn.nargs);
6892 }
6893 agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
6894
6895 /* Decide whether we want to dump it */
6896 selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
6897
6898 /* Mark whether aggregate has an ACL */
6899 if (!PQgetisnull(res, i, i_aggacl))
6900 agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
6901 }
6902
6903 PQclear(res);
6904
6905 destroyPQExpBuffer(query);
6906}
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2358
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:6105

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, and selectDumpableObject().

Referenced by getSchemaData().

◆ getAttrName()

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

Definition at line 18236 of file pg_dump.c.

18237{
18238 if (attrnum > 0 && attrnum <= tblInfo->numatts)
18239 return tblInfo->attnames[attrnum - 1];
18240 switch (attrnum)
18241 {
18243 return "ctid";
18245 return "xmin";
18247 return "cmin";
18249 return "xmax";
18251 return "cmax";
18253 return "tableoid";
18254 }
18255 pg_fatal("invalid column number %d for table \"%s\"",
18256 attrnum, tblInfo->dobj.name);
18257 return NULL; /* keep compiler quiet */
18258}
#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 9040 of file pg_dump.c.

9041{
9042 PGresult *res;
9043 int ntups;
9044 int i;
9046 CastInfo *castinfo;
9047 int i_tableoid;
9048 int i_oid;
9049 int i_castsource;
9050 int i_casttarget;
9051 int i_castfunc;
9052 int i_castcontext;
9053 int i_castmethod;
9054
9055 if (fout->remoteVersion >= 140000)
9056 {
9057 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
9058 "castsource, casttarget, castfunc, castcontext, "
9059 "castmethod "
9060 "FROM pg_cast c "
9061 "WHERE NOT EXISTS ( "
9062 "SELECT 1 FROM pg_range r "
9063 "WHERE c.castsource = r.rngtypid "
9064 "AND c.casttarget = r.rngmultitypid "
9065 ") "
9066 "ORDER BY 3,4");
9067 }
9068 else
9069 {
9070 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
9071 "castsource, casttarget, castfunc, castcontext, "
9072 "castmethod "
9073 "FROM pg_cast ORDER BY 3,4");
9074 }
9075
9076 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9077
9078 ntups = PQntuples(res);
9079
9080 castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
9081
9082 i_tableoid = PQfnumber(res, "tableoid");
9083 i_oid = PQfnumber(res, "oid");
9084 i_castsource = PQfnumber(res, "castsource");
9085 i_casttarget = PQfnumber(res, "casttarget");
9086 i_castfunc = PQfnumber(res, "castfunc");
9087 i_castcontext = PQfnumber(res, "castcontext");
9088 i_castmethod = PQfnumber(res, "castmethod");
9089
9090 for (i = 0; i < ntups; i++)
9091 {
9092 PQExpBufferData namebuf;
9093 TypeInfo *sTypeInfo;
9094 TypeInfo *tTypeInfo;
9095
9096 castinfo[i].dobj.objType = DO_CAST;
9097 castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9098 castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9099 AssignDumpId(&castinfo[i].dobj);
9100 castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
9101 castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
9102 castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
9103 castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
9104 castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
9105
9106 /*
9107 * Try to name cast as concatenation of typnames. This is only used
9108 * for purposes of sorting. If we fail to find either type, the name
9109 * will be an empty string.
9110 */
9111 initPQExpBuffer(&namebuf);
9112 sTypeInfo = findTypeByOid(castinfo[i].castsource);
9113 tTypeInfo = findTypeByOid(castinfo[i].casttarget);
9114 if (sTypeInfo && tTypeInfo)
9115 appendPQExpBuffer(&namebuf, "%s %s",
9116 sTypeInfo->dobj.name, tTypeInfo->dobj.name);
9117 castinfo[i].dobj.name = namebuf.data;
9118
9119 /* Decide whether we want to dump it */
9120 selectDumpableCast(&(castinfo[i]), fout);
9121 }
9122
9123 PQclear(res);
9124
9125 destroyPQExpBuffer(query);
9126}
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:2190

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, selectDumpableCast(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getCollations()

void getCollations ( Archive fout)

Definition at line 6442 of file pg_dump.c.

6443{
6444 PGresult *res;
6445 int ntups;
6446 int i;
6447 PQExpBuffer query;
6448 CollInfo *collinfo;
6449 int i_tableoid;
6450 int i_oid;
6451 int i_collname;
6452 int i_collnamespace;
6453 int i_collowner;
6454 int i_collencoding;
6455
6456 query = createPQExpBuffer();
6457
6458 /*
6459 * find all collations, including builtin collations; we filter out
6460 * system-defined collations at dump-out time.
6461 */
6462
6463 appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6464 "collnamespace, "
6465 "collowner, "
6466 "collencoding "
6467 "FROM pg_collation");
6468
6469 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6470
6471 ntups = PQntuples(res);
6472
6473 collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6474
6475 i_tableoid = PQfnumber(res, "tableoid");
6476 i_oid = PQfnumber(res, "oid");
6477 i_collname = PQfnumber(res, "collname");
6478 i_collnamespace = PQfnumber(res, "collnamespace");
6479 i_collowner = PQfnumber(res, "collowner");
6480 i_collencoding = PQfnumber(res, "collencoding");
6481
6482 for (i = 0; i < ntups; i++)
6483 {
6484 collinfo[i].dobj.objType = DO_COLLATION;
6485 collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6486 collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6487 AssignDumpId(&collinfo[i].dobj);
6488 collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6489 collinfo[i].dobj.namespace =
6490 findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6491 collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6492 collinfo[i].collencoding = atoi(PQgetvalue(res, i, i_collencoding));
6493
6494 /* Decide whether we want to dump it */
6495 selectDumpableObject(&(collinfo[i].dobj), fout);
6496 }
6497
6498 PQclear(res);
6499
6500 destroyPQExpBuffer(query);
6501}
int collencoding
Definition: pg_dump.h:293

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _collInfo::collencoding, 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, _collInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getConstraints()

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

Definition at line 8291 of file pg_dump.c.

8292{
8294 PQExpBuffer tbloids = createPQExpBuffer();
8295 PGresult *res;
8296 int ntups;
8297 int curtblindx;
8298 TableInfo *tbinfo = NULL;
8299 ConstraintInfo *constrinfo;
8300 int i_contableoid,
8301 i_conoid,
8302 i_conrelid,
8303 i_conname,
8304 i_confrelid,
8305 i_conindid,
8306 i_condef;
8307
8308 /*
8309 * We want to perform just one query against pg_constraint. However, we
8310 * mustn't try to select every row of the catalog and then sort it out on
8311 * the client side, because some of the server-side functions we need
8312 * would be unsafe to apply to tables we don't have lock on. Hence, we
8313 * build an array of the OIDs of tables we care about (and now have lock
8314 * on!), and use a WHERE clause to constrain which rows are selected.
8315 */
8316 appendPQExpBufferChar(tbloids, '{');
8317 for (int i = 0; i < numTables; i++)
8318 {
8319 TableInfo *tinfo = &tblinfo[i];
8320
8321 if (!(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8322 continue;
8323
8324 /* OK, we need info for this table */
8325 if (tbloids->len > 1) /* do we have more than the '{'? */
8326 appendPQExpBufferChar(tbloids, ',');
8327 appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
8328 }
8329 appendPQExpBufferChar(tbloids, '}');
8330
8332 "SELECT c.tableoid, c.oid, "
8333 "conrelid, conname, confrelid, ");
8334 if (fout->remoteVersion >= 110000)
8335 appendPQExpBufferStr(query, "conindid, ");
8336 else
8337 appendPQExpBufferStr(query, "0 AS conindid, ");
8338 appendPQExpBuffer(query,
8339 "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
8340 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8341 "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
8342 "WHERE contype = 'f' ",
8343 tbloids->data);
8344 if (fout->remoteVersion >= 110000)
8346 "AND conparentid = 0 ");
8348 "ORDER BY conrelid, conname");
8349
8350 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8351
8352 ntups = PQntuples(res);
8353
8354 i_contableoid = PQfnumber(res, "tableoid");
8355 i_conoid = PQfnumber(res, "oid");
8356 i_conrelid = PQfnumber(res, "conrelid");
8357 i_conname = PQfnumber(res, "conname");
8358 i_confrelid = PQfnumber(res, "confrelid");
8359 i_conindid = PQfnumber(res, "conindid");
8360 i_condef = PQfnumber(res, "condef");
8361
8362 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
8363
8364 curtblindx = -1;
8365 for (int j = 0; j < ntups; j++)
8366 {
8367 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
8368 TableInfo *reftable;
8369
8370 /*
8371 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8372 * order.
8373 */
8374 if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
8375 {
8376 while (++curtblindx < numTables)
8377 {
8378 tbinfo = &tblinfo[curtblindx];
8379 if (tbinfo->dobj.catId.oid == conrelid)
8380 break;
8381 }
8382 if (curtblindx >= numTables)
8383 pg_fatal("unrecognized table OID %u", conrelid);
8384 }
8385
8386 constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
8387 constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
8388 constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
8389 AssignDumpId(&constrinfo[j].dobj);
8390 constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
8391 constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
8392 constrinfo[j].contable = tbinfo;
8393 constrinfo[j].condomain = NULL;
8394 constrinfo[j].contype = 'f';
8395 constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
8396 constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
8397 constrinfo[j].conindex = 0;
8398 constrinfo[j].condeferrable = false;
8399 constrinfo[j].condeferred = false;
8400 constrinfo[j].conislocal = true;
8401 constrinfo[j].separate = true;
8402
8403 /*
8404 * Restoring an FK that points to a partitioned table requires that
8405 * all partition indexes have been attached beforehand. Ensure that
8406 * happens by making the constraint depend on each index partition
8407 * attach object.
8408 */
8409 reftable = findTableByOid(constrinfo[j].confrelid);
8410 if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
8411 {
8412 Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
8413
8414 if (indexOid != InvalidOid)
8415 {
8416 for (int k = 0; k < reftable->numIndexes; k++)
8417 {
8418 IndxInfo *refidx;
8419
8420 /* not our index? */
8421 if (reftable->indexes[k].dobj.catId.oid != indexOid)
8422 continue;
8423
8424 refidx = &reftable->indexes[k];
8425 addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
8426 break;
8427 }
8428 }
8429 }
8430 }
8431
8432 PQclear(res);
8433
8434 destroyPQExpBuffer(query);
8435 destroyPQExpBuffer(tbloids);
8436}
struct _indxInfo * indexes
Definition: pg_dump.h:389
int numIndexes
Definition: pg_dump.h:388

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, _constraintInfo::separate, CatalogId::tableoid, and tinfo.

Referenced by getSchemaData().

◆ getConversions()

void getConversions ( Archive fout)

Definition at line 6508 of file pg_dump.c.

6509{
6510 PGresult *res;
6511 int ntups;
6512 int i;
6513 PQExpBuffer query;
6514 ConvInfo *convinfo;
6515 int i_tableoid;
6516 int i_oid;
6517 int i_conname;
6518 int i_connamespace;
6519 int i_conowner;
6520
6521 query = createPQExpBuffer();
6522
6523 /*
6524 * find all conversions, including builtin conversions; we filter out
6525 * system-defined conversions at dump-out time.
6526 */
6527
6528 appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6529 "connamespace, "
6530 "conowner "
6531 "FROM pg_conversion");
6532
6533 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6534
6535 ntups = PQntuples(res);
6536
6537 convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6538
6539 i_tableoid = PQfnumber(res, "tableoid");
6540 i_oid = PQfnumber(res, "oid");
6541 i_conname = PQfnumber(res, "conname");
6542 i_connamespace = PQfnumber(res, "connamespace");
6543 i_conowner = PQfnumber(res, "conowner");
6544
6545 for (i = 0; i < ntups; i++)
6546 {
6547 convinfo[i].dobj.objType = DO_CONVERSION;
6548 convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6549 convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6550 AssignDumpId(&convinfo[i].dobj);
6551 convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6552 convinfo[i].dobj.namespace =
6553 findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6554 convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6555
6556 /* Decide whether we want to dump it */
6557 selectDumpableObject(&(convinfo[i].dobj), fout);
6558 }
6559
6560 PQclear(res);
6561
6562 destroyPQExpBuffer(query);
6563}

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, _convInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getDefaultACLs()

void getDefaultACLs ( Archive fout)

Definition at line 10583 of file pg_dump.c.

10584{
10585 DumpOptions *dopt = fout->dopt;
10586 DefaultACLInfo *daclinfo;
10587 PQExpBuffer query;
10588 PGresult *res;
10589 int i_oid;
10590 int i_tableoid;
10591 int i_defaclrole;
10592 int i_defaclnamespace;
10593 int i_defaclobjtype;
10594 int i_defaclacl;
10595 int i_acldefault;
10596 int i,
10597 ntups;
10598
10599 query = createPQExpBuffer();
10600
10601 /*
10602 * Global entries (with defaclnamespace=0) replace the hard-wired default
10603 * ACL for their object type. We should dump them as deltas from the
10604 * default ACL, since that will be used as a starting point for
10605 * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
10606 * non-global entries can only add privileges not revoke them. We must
10607 * dump those as-is (i.e., as deltas from an empty ACL).
10608 *
10609 * We can use defaclobjtype as the object type for acldefault(), except
10610 * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
10611 * 's'.
10612 */
10614 "SELECT oid, tableoid, "
10615 "defaclrole, "
10616 "defaclnamespace, "
10617 "defaclobjtype, "
10618 "defaclacl, "
10619 "CASE WHEN defaclnamespace = 0 THEN "
10620 "acldefault(CASE WHEN defaclobjtype = 'S' "
10621 "THEN 's'::\"char\" ELSE defaclobjtype END, "
10622 "defaclrole) ELSE '{}' END AS acldefault "
10623 "FROM pg_default_acl");
10624
10625 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10626
10627 ntups = PQntuples(res);
10628
10629 daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
10630
10631 i_oid = PQfnumber(res, "oid");
10632 i_tableoid = PQfnumber(res, "tableoid");
10633 i_defaclrole = PQfnumber(res, "defaclrole");
10634 i_defaclnamespace = PQfnumber(res, "defaclnamespace");
10635 i_defaclobjtype = PQfnumber(res, "defaclobjtype");
10636 i_defaclacl = PQfnumber(res, "defaclacl");
10637 i_acldefault = PQfnumber(res, "acldefault");
10638
10639 for (i = 0; i < ntups; i++)
10640 {
10641 Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
10642
10643 daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
10644 daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10645 daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10646 AssignDumpId(&daclinfo[i].dobj);
10647 /* cheesy ... is it worth coming up with a better object name? */
10648 daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
10649
10650 if (nspid != InvalidOid)
10651 daclinfo[i].dobj.namespace = findNamespace(nspid);
10652 else
10653 daclinfo[i].dobj.namespace = NULL;
10654
10655 daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
10656 daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10657 daclinfo[i].dacl.privtype = 0;
10658 daclinfo[i].dacl.initprivs = NULL;
10659 daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
10660 daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
10661
10662 /* Default ACLs are ACLs, of course */
10663 daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10664
10665 /* Decide whether we want to dump it */
10666 selectDumpableDefaultACL(&(daclinfo[i]), dopt);
10667 }
10668
10669 PQclear(res);
10670
10671 destroyPQExpBuffer(query);
10672}
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:2168

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, selectDumpableDefaultACL(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getDependencies()

static void getDependencies ( Archive fout)
static

Definition at line 19960 of file pg_dump.c.

19961{
19962 PQExpBuffer query;
19963 PGresult *res;
19964 int ntups,
19965 i;
19966 int i_classid,
19967 i_objid,
19968 i_refclassid,
19969 i_refobjid,
19970 i_deptype;
19971 DumpableObject *dobj,
19972 *refdobj;
19973
19974 pg_log_info("reading dependency data");
19975
19976 query = createPQExpBuffer();
19977
19978 /*
19979 * Messy query to collect the dependency data we need. Note that we
19980 * ignore the sub-object column, so that dependencies of or on a column
19981 * look the same as dependencies of or on a whole table.
19982 *
19983 * PIN dependencies aren't interesting, and EXTENSION dependencies were
19984 * already processed by getExtensionMembership.
19985 */
19986 appendPQExpBufferStr(query, "SELECT "
19987 "classid, objid, refclassid, refobjid, deptype "
19988 "FROM pg_depend "
19989 "WHERE deptype != 'p' AND deptype != 'e'\n");
19990
19991 /*
19992 * Since we don't treat pg_amop entries as separate DumpableObjects, we
19993 * have to translate their dependencies into dependencies of their parent
19994 * opfamily. Ignore internal dependencies though, as those will point to
19995 * their parent opclass, which we needn't consider here (and if we did,
19996 * it'd just result in circular dependencies). Also, "loose" opfamily
19997 * entries will have dependencies on their parent opfamily, which we
19998 * should drop since they'd likewise become useless self-dependencies.
19999 * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
20000 */
20001 appendPQExpBufferStr(query, "UNION ALL\n"
20002 "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
20003 "FROM pg_depend d, pg_amop o "
20004 "WHERE deptype NOT IN ('p', 'e', 'i') AND "
20005 "classid = 'pg_amop'::regclass AND objid = o.oid "
20006 "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
20007
20008 /* Likewise for pg_amproc entries */
20009 appendPQExpBufferStr(query, "UNION ALL\n"
20010 "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
20011 "FROM pg_depend d, pg_amproc p "
20012 "WHERE deptype NOT IN ('p', 'e', 'i') AND "
20013 "classid = 'pg_amproc'::regclass AND objid = p.oid "
20014 "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
20015
20016 /* Sort the output for efficiency below */
20017 appendPQExpBufferStr(query, "ORDER BY 1,2");
20018
20019 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
20020
20021 ntups = PQntuples(res);
20022
20023 i_classid = PQfnumber(res, "classid");
20024 i_objid = PQfnumber(res, "objid");
20025 i_refclassid = PQfnumber(res, "refclassid");
20026 i_refobjid = PQfnumber(res, "refobjid");
20027 i_deptype = PQfnumber(res, "deptype");
20028
20029 /*
20030 * Since we ordered the SELECT by referencing ID, we can expect that
20031 * multiple entries for the same object will appear together; this saves
20032 * on searches.
20033 */
20034 dobj = NULL;
20035
20036 for (i = 0; i < ntups; i++)
20037 {
20038 CatalogId objId;
20039 CatalogId refobjId;
20040 char deptype;
20041
20042 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
20043 objId.oid = atooid(PQgetvalue(res, i, i_objid));
20044 refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
20045 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
20046 deptype = *(PQgetvalue(res, i, i_deptype));
20047
20048 if (dobj == NULL ||
20049 dobj->catId.tableoid != objId.tableoid ||
20050 dobj->catId.oid != objId.oid)
20051 dobj = findObjectByCatalogId(objId);
20052
20053 /*
20054 * Failure to find objects mentioned in pg_depend is not unexpected,
20055 * since for example we don't collect info about TOAST tables.
20056 */
20057 if (dobj == NULL)
20058 {
20059#ifdef NOT_USED
20060 pg_log_warning("no referencing object %u %u",
20061 objId.tableoid, objId.oid);
20062#endif
20063 continue;
20064 }
20065
20066 refdobj = findObjectByCatalogId(refobjId);
20067
20068 if (refdobj == NULL)
20069 {
20070#ifdef NOT_USED
20071 pg_log_warning("no referenced object %u %u",
20072 refobjId.tableoid, refobjId.oid);
20073#endif
20074 continue;
20075 }
20076
20077 /*
20078 * For 'x' dependencies, mark the object for later; we still add the
20079 * normal dependency, for possible ordering purposes. Currently
20080 * pg_dump_sort.c knows to put extensions ahead of all object types
20081 * that could possibly depend on them, but this is safer.
20082 */
20083 if (deptype == 'x')
20084 dobj->depends_on_ext = true;
20085
20086 /*
20087 * Ordinarily, table rowtypes have implicit dependencies on their
20088 * tables. However, for a composite type the implicit dependency goes
20089 * the other way in pg_depend; which is the right thing for DROP but
20090 * it doesn't produce the dependency ordering we need. So in that one
20091 * case, we reverse the direction of the dependency.
20092 */
20093 if (deptype == 'i' &&
20094 dobj->objType == DO_TABLE &&
20095 refdobj->objType == DO_TYPE)
20096 addObjectDependency(refdobj, dobj->dumpId);
20097 else
20098 /* normal case */
20099 addObjectDependency(dobj, refdobj->dumpId);
20100 }
20101
20102 PQclear(res);
20103
20104 destroyPQExpBuffer(query);
20105}

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, and CatalogId::tableoid.

Referenced by main().

◆ getDomainConstraints()

static void getDomainConstraints ( Archive fout,
TypeInfo tyinfo 
)
static

Definition at line 8473 of file pg_dump.c.

8474{
8475 ConstraintInfo *constrinfo;
8477 PGresult *res;
8478 int i_tableoid,
8479 i_oid,
8480 i_conname,
8481 i_consrc,
8482 i_convalidated,
8483 i_contype;
8484 int ntups;
8485
8487 {
8488 /*
8489 * Set up query for constraint-specific details. For servers 17 and
8490 * up, domains have constraints of type 'n' as well as 'c', otherwise
8491 * just the latter.
8492 */
8493 appendPQExpBuffer(query,
8494 "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
8495 "SELECT tableoid, oid, conname, "
8496 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
8497 "convalidated, contype "
8498 "FROM pg_catalog.pg_constraint "
8499 "WHERE contypid = $1 AND contype IN (%s) "
8500 "ORDER BY conname",
8501 fout->remoteVersion < 170000 ? "'c'" : "'c', 'n'");
8502
8503 ExecuteSqlStatement(fout, query->data);
8504
8506 }
8507
8508 printfPQExpBuffer(query,
8509 "EXECUTE getDomainConstraints('%u')",
8510 tyinfo->dobj.catId.oid);
8511
8512 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8513
8514 ntups = PQntuples(res);
8515
8516 i_tableoid = PQfnumber(res, "tableoid");
8517 i_oid = PQfnumber(res, "oid");
8518 i_conname = PQfnumber(res, "conname");
8519 i_consrc = PQfnumber(res, "consrc");
8520 i_convalidated = PQfnumber(res, "convalidated");
8521 i_contype = PQfnumber(res, "contype");
8522
8523 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
8524 tyinfo->domChecks = constrinfo;
8525
8526 /* 'i' tracks result rows; 'j' counts CHECK constraints */
8527 for (int i = 0, j = 0; i < ntups; i++)
8528 {
8529 bool validated = PQgetvalue(res, i, i_convalidated)[0] == 't';
8530 char contype = (PQgetvalue(res, i, i_contype))[0];
8531 ConstraintInfo *constraint;
8532
8533 if (contype == CONSTRAINT_CHECK)
8534 {
8535 constraint = &constrinfo[j++];
8536 tyinfo->nDomChecks++;
8537 }
8538 else
8539 {
8540 Assert(contype == CONSTRAINT_NOTNULL);
8541 Assert(tyinfo->notnull == NULL);
8542 /* use last item in array for the not-null constraint */
8543 tyinfo->notnull = &(constrinfo[ntups - 1]);
8544 constraint = tyinfo->notnull;
8545 }
8546
8547 constraint->dobj.objType = DO_CONSTRAINT;
8548 constraint->dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8549 constraint->dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8550 AssignDumpId(&(constraint->dobj));
8551 constraint->dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
8552 constraint->dobj.namespace = tyinfo->dobj.namespace;
8553 constraint->contable = NULL;
8554 constraint->condomain = tyinfo;
8555 constraint->contype = contype;
8556 constraint->condef = pg_strdup(PQgetvalue(res, i, i_consrc));
8557 constraint->confrelid = InvalidOid;
8558 constraint->conindex = 0;
8559 constraint->condeferrable = false;
8560 constraint->condeferred = false;
8561 constraint->conislocal = true;
8562
8563 constraint->separate = !validated;
8564
8565 /*
8566 * Make the domain depend on the constraint, ensuring it won't be
8567 * output till any constraint dependencies are OK. If the constraint
8568 * has not been validated, it's going to be dumped after the domain
8569 * anyway, so this doesn't matter.
8570 */
8571 if (validated)
8572 addObjectDependency(&tyinfo->dobj, constraint->dobj.dumpId);
8573 }
8574
8575 PQclear(res);
8576
8577 destroyPQExpBuffer(query);
8578}
@ PREPQUERY_GETDOMAINCONSTRAINTS
Definition: pg_backup.h:77

References addObjectDependency(), appendPQExpBuffer(), Assert(), 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, j, _dumpableObject::name, _typeInfo::nDomChecks, _typeInfo::notnull, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, PREPQUERY_GETDOMAINCONSTRAINTS, printfPQExpBuffer(), Archive::remoteVersion, _constraintInfo::separate, and CatalogId::tableoid.

Referenced by getTypes().

◆ getEventTriggers()

void getEventTriggers ( Archive fout)

Definition at line 8878 of file pg_dump.c.

8879{
8880 int i;
8881 PQExpBuffer query;
8882 PGresult *res;
8883 EventTriggerInfo *evtinfo;
8884 int i_tableoid,
8885 i_oid,
8886 i_evtname,
8887 i_evtevent,
8888 i_evtowner,
8889 i_evttags,
8890 i_evtfname,
8891 i_evtenabled;
8892 int ntups;
8893
8894 /* Before 9.3, there are no event triggers */
8895 if (fout->remoteVersion < 90300)
8896 return;
8897
8898 query = createPQExpBuffer();
8899
8901 "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8902 "evtevent, evtowner, "
8903 "array_to_string(array("
8904 "select quote_literal(x) "
8905 " from unnest(evttags) as t(x)), ', ') as evttags, "
8906 "e.evtfoid::regproc as evtfname "
8907 "FROM pg_event_trigger e "
8908 "ORDER BY e.oid");
8909
8910 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8911
8912 ntups = PQntuples(res);
8913
8914 evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8915
8916 i_tableoid = PQfnumber(res, "tableoid");
8917 i_oid = PQfnumber(res, "oid");
8918 i_evtname = PQfnumber(res, "evtname");
8919 i_evtevent = PQfnumber(res, "evtevent");
8920 i_evtowner = PQfnumber(res, "evtowner");
8921 i_evttags = PQfnumber(res, "evttags");
8922 i_evtfname = PQfnumber(res, "evtfname");
8923 i_evtenabled = PQfnumber(res, "evtenabled");
8924
8925 for (i = 0; i < ntups; i++)
8926 {
8927 evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8928 evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8929 evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8930 AssignDumpId(&evtinfo[i].dobj);
8931 evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8932 evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8933 evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8934 evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8935 evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8936 evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8937 evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8938
8939 /* Decide whether we want to dump it */
8940 selectDumpableObject(&(evtinfo[i].dobj), fout);
8941 }
8942
8943 PQclear(res);
8944
8945 destroyPQExpBuffer(query);
8946}
char * evtname
Definition: pg_dump.h:497

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, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtendedStatistics()

void getExtendedStatistics ( Archive fout)

Definition at line 8212 of file pg_dump.c.

8213{
8214 PQExpBuffer query;
8215 PGresult *res;
8216 StatsExtInfo *statsextinfo;
8217 int ntups;
8218 int i_tableoid;
8219 int i_oid;
8220 int i_stxname;
8221 int i_stxnamespace;
8222 int i_stxowner;
8223 int i_stxrelid;
8224 int i_stattarget;
8225 int i;
8226
8227 /* Extended statistics were new in v10 */
8228 if (fout->remoteVersion < 100000)
8229 return;
8230
8231 query = createPQExpBuffer();
8232
8233 if (fout->remoteVersion < 130000)
8234 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8235 "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
8236 "FROM pg_catalog.pg_statistic_ext");
8237 else
8238 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8239 "stxnamespace, stxowner, stxrelid, stxstattarget "
8240 "FROM pg_catalog.pg_statistic_ext");
8241
8242 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8243
8244 ntups = PQntuples(res);
8245
8246 i_tableoid = PQfnumber(res, "tableoid");
8247 i_oid = PQfnumber(res, "oid");
8248 i_stxname = PQfnumber(res, "stxname");
8249 i_stxnamespace = PQfnumber(res, "stxnamespace");
8250 i_stxowner = PQfnumber(res, "stxowner");
8251 i_stxrelid = PQfnumber(res, "stxrelid");
8252 i_stattarget = PQfnumber(res, "stxstattarget");
8253
8254 statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
8255
8256 for (i = 0; i < ntups; i++)
8257 {
8258 statsextinfo[i].dobj.objType = DO_STATSEXT;
8259 statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8260 statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8261 AssignDumpId(&statsextinfo[i].dobj);
8262 statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
8263 statsextinfo[i].dobj.namespace =
8264 findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
8265 statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
8266 statsextinfo[i].stattable =
8267 findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
8268 if (PQgetisnull(res, i, i_stattarget))
8269 statsextinfo[i].stattarget = -1;
8270 else
8271 statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
8272
8273 /* Decide whether we want to dump it */
8274 selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
8275 }
8276
8277 PQclear(res);
8278 destroyPQExpBuffer(query);
8279}
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2340
TableInfo * stattable
Definition: pg_dump.h:470

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

19688{
19689 PQExpBuffer query;
19690 PGresult *res;
19691 int ntups,
19692 i;
19693 int i_classid,
19694 i_objid,
19695 i_refobjid;
19696 ExtensionInfo *ext;
19697
19698 /* Nothing to do if no extensions */
19699 if (numExtensions == 0)
19700 return;
19701
19702 query = createPQExpBuffer();
19703
19704 /* refclassid constraint is redundant but may speed the search */
19705 appendPQExpBufferStr(query, "SELECT "
19706 "classid, objid, refobjid "
19707 "FROM pg_depend "
19708 "WHERE refclassid = 'pg_extension'::regclass "
19709 "AND deptype = 'e' "
19710 "ORDER BY 3");
19711
19712 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19713
19714 ntups = PQntuples(res);
19715
19716 i_classid = PQfnumber(res, "classid");
19717 i_objid = PQfnumber(res, "objid");
19718 i_refobjid = PQfnumber(res, "refobjid");
19719
19720 /*
19721 * Since we ordered the SELECT by referenced ID, we can expect that
19722 * multiple entries for the same extension will appear together; this
19723 * saves on searches.
19724 */
19725 ext = NULL;
19726
19727 for (i = 0; i < ntups; i++)
19728 {
19729 CatalogId objId;
19730 Oid extId;
19731
19732 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
19733 objId.oid = atooid(PQgetvalue(res, i, i_objid));
19734 extId = atooid(PQgetvalue(res, i, i_refobjid));
19735
19736 if (ext == NULL ||
19737 ext->dobj.catId.oid != extId)
19738 ext = findExtensionByOid(extId);
19739
19740 if (ext == NULL)
19741 {
19742 /* shouldn't happen */
19743 pg_log_warning("could not find referenced extension %u", extId);
19744 continue;
19745 }
19746
19747 recordExtensionMembership(objId, ext);
19748 }
19749
19750 PQclear(res);
19751
19752 destroyPQExpBuffer(query);
19753}
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1063
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:1008

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(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtensions()

ExtensionInfo * getExtensions ( Archive fout,
int *  numExtensions 
)

Definition at line 6123 of file pg_dump.c.

6124{
6125 DumpOptions *dopt = fout->dopt;
6126 PGresult *res;
6127 int ntups;
6128 int i;
6129 PQExpBuffer query;
6130 ExtensionInfo *extinfo = NULL;
6131 int i_tableoid;
6132 int i_oid;
6133 int i_extname;
6134 int i_nspname;
6135 int i_extrelocatable;
6136 int i_extversion;
6137 int i_extconfig;
6138 int i_extcondition;
6139
6140 query = createPQExpBuffer();
6141
6142 appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
6143 "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
6144 "FROM pg_extension x "
6145 "JOIN pg_namespace n ON n.oid = x.extnamespace");
6146
6147 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6148
6149 ntups = PQntuples(res);
6150 if (ntups == 0)
6151 goto cleanup;
6152
6153 extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
6154
6155 i_tableoid = PQfnumber(res, "tableoid");
6156 i_oid = PQfnumber(res, "oid");
6157 i_extname = PQfnumber(res, "extname");
6158 i_nspname = PQfnumber(res, "nspname");
6159 i_extrelocatable = PQfnumber(res, "extrelocatable");
6160 i_extversion = PQfnumber(res, "extversion");
6161 i_extconfig = PQfnumber(res, "extconfig");
6162 i_extcondition = PQfnumber(res, "extcondition");
6163
6164 for (i = 0; i < ntups; i++)
6165 {
6166 extinfo[i].dobj.objType = DO_EXTENSION;
6167 extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6168 extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6169 AssignDumpId(&extinfo[i].dobj);
6170 extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
6171 extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
6172 extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
6173 extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
6174 extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
6175 extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
6176
6177 /* Decide whether we want to dump it */
6178 selectDumpableExtension(&(extinfo[i]), dopt);
6179 }
6180
6181cleanup:
6182 PQclear(res);
6183 destroyPQExpBuffer(query);
6184
6185 *numExtensions = ntups;
6186
6187 return extinfo;
6188}
static void cleanup(void)
Definition: bootstrap.c:715
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2283

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

Referenced by getSchemaData().

◆ getForeignDataWrappers()

void getForeignDataWrappers ( Archive fout)

Definition at line 10411 of file pg_dump.c.

10412{
10413 PGresult *res;
10414 int ntups;
10415 int i;
10416 PQExpBuffer query;
10417 FdwInfo *fdwinfo;
10418 int i_tableoid;
10419 int i_oid;
10420 int i_fdwname;
10421 int i_fdwowner;
10422 int i_fdwhandler;
10423 int i_fdwvalidator;
10424 int i_fdwacl;
10425 int i_acldefault;
10426 int i_fdwoptions;
10427
10428 query = createPQExpBuffer();
10429
10430 appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
10431 "fdwowner, "
10432 "fdwhandler::pg_catalog.regproc, "
10433 "fdwvalidator::pg_catalog.regproc, "
10434 "fdwacl, "
10435 "acldefault('F', fdwowner) AS acldefault, "
10436 "array_to_string(ARRAY("
10437 "SELECT quote_ident(option_name) || ' ' || "
10438 "quote_literal(option_value) "
10439 "FROM pg_options_to_table(fdwoptions) "
10440 "ORDER BY option_name"
10441 "), E',\n ') AS fdwoptions "
10442 "FROM pg_foreign_data_wrapper");
10443
10444 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10445
10446 ntups = PQntuples(res);
10447
10448 fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
10449
10450 i_tableoid = PQfnumber(res, "tableoid");
10451 i_oid = PQfnumber(res, "oid");
10452 i_fdwname = PQfnumber(res, "fdwname");
10453 i_fdwowner = PQfnumber(res, "fdwowner");
10454 i_fdwhandler = PQfnumber(res, "fdwhandler");
10455 i_fdwvalidator = PQfnumber(res, "fdwvalidator");
10456 i_fdwacl = PQfnumber(res, "fdwacl");
10457 i_acldefault = PQfnumber(res, "acldefault");
10458 i_fdwoptions = PQfnumber(res, "fdwoptions");
10459
10460 for (i = 0; i < ntups; i++)
10461 {
10462 fdwinfo[i].dobj.objType = DO_FDW;
10463 fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10464 fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10465 AssignDumpId(&fdwinfo[i].dobj);
10466 fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
10467 fdwinfo[i].dobj.namespace = NULL;
10468 fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
10469 fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10470 fdwinfo[i].dacl.privtype = 0;
10471 fdwinfo[i].dacl.initprivs = NULL;
10472 fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
10473 fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
10474 fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
10475 fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
10476
10477 /* Decide whether we want to dump it */
10478 selectDumpableObject(&(fdwinfo[i].dobj), fout);
10479
10480 /* Mark whether FDW has an ACL */
10481 if (!PQgetisnull(res, i, i_fdwacl))
10482 fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10483 }
10484
10485 PQclear(res);
10486
10487 destroyPQExpBuffer(query);
10488}

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, _fdwInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignServers()

void getForeignServers ( Archive fout)

Definition at line 10495 of file pg_dump.c.

10496{
10497 PGresult *res;
10498 int ntups;
10499 int i;
10500 PQExpBuffer query;
10501 ForeignServerInfo *srvinfo;
10502 int i_tableoid;
10503 int i_oid;
10504 int i_srvname;
10505 int i_srvowner;
10506 int i_srvfdw;
10507 int i_srvtype;
10508 int i_srvversion;
10509 int i_srvacl;
10510 int i_acldefault;
10511 int i_srvoptions;
10512
10513 query = createPQExpBuffer();
10514
10515 appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
10516 "srvowner, "
10517 "srvfdw, srvtype, srvversion, srvacl, "
10518 "acldefault('S', srvowner) AS acldefault, "
10519 "array_to_string(ARRAY("
10520 "SELECT quote_ident(option_name) || ' ' || "
10521 "quote_literal(option_value) "
10522 "FROM pg_options_to_table(srvoptions) "
10523 "ORDER BY option_name"
10524 "), E',\n ') AS srvoptions "
10525 "FROM pg_foreign_server");
10526
10527 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10528
10529 ntups = PQntuples(res);
10530
10531 srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
10532
10533 i_tableoid = PQfnumber(res, "tableoid");
10534 i_oid = PQfnumber(res, "oid");
10535 i_srvname = PQfnumber(res, "srvname");
10536 i_srvowner = PQfnumber(res, "srvowner");
10537 i_srvfdw = PQfnumber(res, "srvfdw");
10538 i_srvtype = PQfnumber(res, "srvtype");
10539 i_srvversion = PQfnumber(res, "srvversion");
10540 i_srvacl = PQfnumber(res, "srvacl");
10541 i_acldefault = PQfnumber(res, "acldefault");
10542 i_srvoptions = PQfnumber(res, "srvoptions");
10543
10544 for (i = 0; i < ntups; i++)
10545 {
10546 srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
10547 srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10548 srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10549 AssignDumpId(&srvinfo[i].dobj);
10550 srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
10551 srvinfo[i].dobj.namespace = NULL;
10552 srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
10553 srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10554 srvinfo[i].dacl.privtype = 0;
10555 srvinfo[i].dacl.initprivs = NULL;
10556 srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
10557 srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
10558 srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
10559 srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
10560 srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
10561
10562 /* Decide whether we want to dump it */
10563 selectDumpableObject(&(srvinfo[i].dobj), fout);
10564
10565 /* Servers have user mappings */
10567
10568 /* Mark whether server has an ACL */
10569 if (!PQgetisnull(res, i, i_srvacl))
10570 srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10571 }
10572
10573 PQclear(res);
10574
10575 destroyPQExpBuffer(query);
10576}

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

14366{
14367 OprInfo *oprInfo;
14368
14369 /* In all cases "0" means a null reference */
14370 if (strcmp(oproid, "0") == 0)
14371 return NULL;
14372
14373 oprInfo = findOprByOid(atooid(oproid));
14374 if (oprInfo == NULL)
14375 {
14376 pg_log_warning("could not find operator with OID %s",
14377 oproid);
14378 return NULL;
14379 }
14380
14381 return psprintf("OPERATOR(%s.%s)",
14382 fmtId(oprInfo->dobj.namespace->dobj.name),
14383 oprInfo->dobj.name);
14384}
OprInfo * findOprByOid(Oid oid)
Definition: common.c:936

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

20368{
20369 TypeInfo *typeInfo;
20370 char *result;
20371 PQExpBuffer query;
20372 PGresult *res;
20373
20374 if (oid == 0)
20375 {
20376 if ((opts & zeroAsStar) != 0)
20377 return "*";
20378 else if ((opts & zeroAsNone) != 0)
20379 return "NONE";
20380 }
20381
20382 /* see if we have the result cached in the type's TypeInfo record */
20383 typeInfo = findTypeByOid(oid);
20384 if (typeInfo && typeInfo->ftypname)
20385 return typeInfo->ftypname;
20386
20387 query = createPQExpBuffer();
20388 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
20389 oid);
20390
20391 res = ExecuteSqlQueryForSingleRow(fout, query->data);
20392
20393 /* result of format_type is already quoted */
20394 result = pg_strdup(PQgetvalue(res, 0, 0));
20395
20396 PQclear(res);
20397 destroyPQExpBuffer(query);
20398
20399 /*
20400 * Cache the result for re-use in later requests, if possible. If we
20401 * don't have a TypeInfo for the type, the string will be leaked once the
20402 * caller is done with it ... but that case really should not happen, so
20403 * leaking if it does seems acceptable.
20404 */
20405 if (typeInfo)
20406 typeInfo->ftypname = result;
20407
20408 return result;
20409}
static AmcheckOptions opts
Definition: pg_amcheck.c:112
char * ftypname
Definition: pg_dump.h:213

References appendPQExpBuffer(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), findTypeByOid(), _typeInfo::ftypname, opts, pg_strdup(), PQclear, PQgetvalue, 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 6913 of file pg_dump.c.

6914{
6915 DumpOptions *dopt = fout->dopt;
6916 PGresult *res;
6917 int ntups;
6918 int i;
6920 FuncInfo *finfo;
6921 int i_tableoid;
6922 int i_oid;
6923 int i_proname;
6924 int i_pronamespace;
6925 int i_proowner;
6926 int i_prolang;
6927 int i_pronargs;
6928 int i_proargtypes;
6929 int i_prorettype;
6930 int i_proacl;
6931 int i_acldefault;
6932
6933 /*
6934 * Find all interesting functions. This is a bit complicated:
6935 *
6936 * 1. Always exclude aggregates; those are handled elsewhere.
6937 *
6938 * 2. Always exclude functions that are internally dependent on something
6939 * else, since presumably those will be created as a result of creating
6940 * the something else. This currently acts only to suppress constructor
6941 * functions for range types. Note this is OK only because the
6942 * constructors don't have any dependencies the range type doesn't have;
6943 * otherwise we might not get creation ordering correct.
6944 *
6945 * 3. Otherwise, we normally exclude functions in pg_catalog. However, if
6946 * they're members of extensions and we are in binary-upgrade mode then
6947 * include them, since we want to dump extension members individually in
6948 * that mode. Also, if they are used by casts or transforms then we need
6949 * to gather the information about them, though they won't be dumped if
6950 * they are built-in. Also, in 9.6 and up, include functions in
6951 * pg_catalog if they have an ACL different from what's shown in
6952 * pg_init_privs (so we have to join to pg_init_privs; annoying).
6953 */
6954 if (fout->remoteVersion >= 90600)
6955 {
6956 const char *not_agg_check;
6957
6958 not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
6959 : "NOT p.proisagg");
6960
6961 appendPQExpBuffer(query,
6962 "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
6963 "p.pronargs, p.proargtypes, p.prorettype, "
6964 "p.proacl, "
6965 "acldefault('f', p.proowner) AS acldefault, "
6966 "p.pronamespace, "
6967 "p.proowner "
6968 "FROM pg_proc p "
6969 "LEFT JOIN pg_init_privs pip ON "
6970 "(p.oid = pip.objoid "
6971 "AND pip.classoid = 'pg_proc'::regclass "
6972 "AND pip.objsubid = 0) "
6973 "WHERE %s"
6974 "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6975 "WHERE classid = 'pg_proc'::regclass AND "
6976 "objid = p.oid AND deptype = 'i')"
6977 "\n AND ("
6978 "\n pronamespace != "
6979 "(SELECT oid FROM pg_namespace "
6980 "WHERE nspname = 'pg_catalog')"
6981 "\n OR EXISTS (SELECT 1 FROM pg_cast"
6982 "\n WHERE pg_cast.oid > %u "
6983 "\n AND p.oid = pg_cast.castfunc)"
6984 "\n OR EXISTS (SELECT 1 FROM pg_transform"
6985 "\n WHERE pg_transform.oid > %u AND "
6986 "\n (p.oid = pg_transform.trffromsql"
6987 "\n OR p.oid = pg_transform.trftosql))",
6988 not_agg_check,
6991 if (dopt->binary_upgrade)
6993 "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6994 "classid = 'pg_proc'::regclass AND "
6995 "objid = p.oid AND "
6996 "refclassid = 'pg_extension'::regclass AND "
6997 "deptype = 'e')");
6999 "\n OR p.proacl IS DISTINCT FROM pip.initprivs");
7000 appendPQExpBufferChar(query, ')');
7001 }
7002 else
7003 {
7004 appendPQExpBuffer(query,
7005 "SELECT tableoid, oid, proname, prolang, "
7006 "pronargs, proargtypes, prorettype, proacl, "
7007 "acldefault('f', proowner) AS acldefault, "
7008 "pronamespace, "
7009 "proowner "
7010 "FROM pg_proc p "
7011 "WHERE NOT proisagg"
7012 "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
7013 "WHERE classid = 'pg_proc'::regclass AND "
7014 "objid = p.oid AND deptype = 'i')"
7015 "\n AND ("
7016 "\n pronamespace != "
7017 "(SELECT oid FROM pg_namespace "
7018 "WHERE nspname = 'pg_catalog')"
7019 "\n OR EXISTS (SELECT 1 FROM pg_cast"
7020 "\n WHERE pg_cast.oid > '%u'::oid"
7021 "\n AND p.oid = pg_cast.castfunc)",
7023
7024 if (fout->remoteVersion >= 90500)
7025 appendPQExpBuffer(query,
7026 "\n OR EXISTS (SELECT 1 FROM pg_transform"
7027 "\n WHERE pg_transform.oid > '%u'::oid"
7028 "\n AND (p.oid = pg_transform.trffromsql"
7029 "\n OR p.oid = pg_transform.trftosql))",
7031
7032 if (dopt->binary_upgrade)
7034 "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
7035 "classid = 'pg_proc'::regclass AND "
7036 "objid = p.oid AND "
7037 "refclassid = 'pg_extension'::regclass AND "
7038 "deptype = 'e')");
7039 appendPQExpBufferChar(query, ')');
7040 }
7041
7042 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7043
7044 ntups = PQntuples(res);
7045
7046 finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
7047
7048 i_tableoid = PQfnumber(res, "tableoid");
7049 i_oid = PQfnumber(res, "oid");
7050 i_proname = PQfnumber(res, "proname");
7051 i_pronamespace = PQfnumber(res, "pronamespace");
7052 i_proowner = PQfnumber(res, "proowner");
7053 i_prolang = PQfnumber(res, "prolang");
7054 i_pronargs = PQfnumber(res, "pronargs");
7055 i_proargtypes = PQfnumber(res, "proargtypes");
7056 i_prorettype = PQfnumber(res, "prorettype");
7057 i_proacl = PQfnumber(res, "proacl");
7058 i_acldefault = PQfnumber(res, "acldefault");
7059
7060 for (i = 0; i < ntups; i++)
7061 {
7062 finfo[i].dobj.objType = DO_FUNC;
7063 finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7064 finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7065 AssignDumpId(&finfo[i].dobj);
7066 finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
7067 finfo[i].dobj.namespace =
7068 findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
7069 finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
7070 finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
7071 finfo[i].dacl.privtype = 0;
7072 finfo[i].dacl.initprivs = NULL;
7073 finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
7074 finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
7075 finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
7076 finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
7077 if (finfo[i].nargs == 0)
7078 finfo[i].argtypes = NULL;
7079 else
7080 {
7081 finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
7082 parseOidArray(PQgetvalue(res, i, i_proargtypes),
7083 finfo[i].argtypes, finfo[i].nargs);
7084 }
7085 finfo[i].postponed_def = false; /* might get set during sort */
7086
7087 /* Decide whether we want to dump it */
7088 selectDumpableObject(&(finfo[i].dobj), fout);
7089
7090 /* Mark whether function has an ACL */
7091 if (!PQgetisnull(res, i, i_proacl))
7093 }
7094
7095 PQclear(res);
7096
7097 destroyPQExpBuffer(query);
7098}
static Oid g_last_builtin_oid
Definition: pg_dump.c:152
Oid lang
Definition: pg_dump.h:244

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, _funcInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getIndexes()

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

Definition at line 7843 of file pg_dump.c.

7844{
7846 PQExpBuffer tbloids = createPQExpBuffer();
7847 PGresult *res;
7848 int ntups;
7849 int curtblindx;
7850 IndxInfo *indxinfo;
7851 int i_tableoid,
7852 i_oid,
7853 i_indrelid,
7854 i_indexname,
7855 i_relpages,
7856 i_reltuples,
7857 i_relallvisible,
7858 i_relallfrozen,
7859 i_parentidx,
7860 i_indexdef,
7861 i_indnkeyatts,
7862 i_indnatts,
7863 i_indkey,
7864 i_indisclustered,
7865 i_indisreplident,
7866 i_indnullsnotdistinct,
7867 i_contype,
7868 i_conname,
7869 i_condeferrable,
7870 i_condeferred,
7871 i_conperiod,
7872 i_contableoid,
7873 i_conoid,
7874 i_condef,
7875 i_indattnames,
7876 i_tablespace,
7877 i_indreloptions,
7878 i_indstatcols,
7879 i_indstatvals;
7880
7881 /*
7882 * We want to perform just one query against pg_index. However, we
7883 * mustn't try to select every row of the catalog and then sort it out on
7884 * the client side, because some of the server-side functions we need
7885 * would be unsafe to apply to tables we don't have lock on. Hence, we
7886 * build an array of the OIDs of tables we care about (and now have lock
7887 * on!), and use a WHERE clause to constrain which rows are selected.
7888 */
7889 appendPQExpBufferChar(tbloids, '{');
7890 for (int i = 0; i < numTables; i++)
7891 {
7892 TableInfo *tbinfo = &tblinfo[i];
7893
7894 if (!tbinfo->hasindex)
7895 continue;
7896
7897 /*
7898 * We can ignore indexes of uninteresting tables.
7899 */
7900 if (!tbinfo->interesting)
7901 continue;
7902
7903 /* OK, we need info for this table */
7904 if (tbloids->len > 1) /* do we have more than the '{'? */
7905 appendPQExpBufferChar(tbloids, ',');
7906 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
7907 }
7908 appendPQExpBufferChar(tbloids, '}');
7909
7911 "SELECT t.tableoid, t.oid, i.indrelid, "
7912 "t.relname AS indexname, "
7913 "t.relpages, t.reltuples, t.relallvisible, ");
7914
7915 if (fout->remoteVersion >= 180000)
7916 appendPQExpBufferStr(query, "t.relallfrozen, ");
7917 else
7918 appendPQExpBufferStr(query, "0 AS relallfrozen, ");
7919
7921 "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7922 "i.indkey, i.indisclustered, "
7923 "c.contype, c.conname, "
7924 "c.condeferrable, c.condeferred, "
7925 "c.tableoid AS contableoid, "
7926 "c.oid AS conoid, "
7927 "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
7928 "CASE WHEN i.indexprs IS NOT NULL THEN "
7929 "(SELECT pg_catalog.array_agg(attname ORDER BY attnum)"
7930 " FROM pg_catalog.pg_attribute "
7931 " WHERE attrelid = i.indexrelid) "
7932 "ELSE NULL END AS indattnames, "
7933 "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
7934 "t.reloptions AS indreloptions, ");
7935
7936
7937 if (fout->remoteVersion >= 90400)
7939 "i.indisreplident, ");
7940 else
7942 "false AS indisreplident, ");
7943
7944 if (fout->remoteVersion >= 110000)
7946 "inh.inhparent AS parentidx, "
7947 "i.indnkeyatts AS indnkeyatts, "
7948 "i.indnatts AS indnatts, "
7949 "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
7950 " FROM pg_catalog.pg_attribute "
7951 " WHERE attrelid = i.indexrelid AND "
7952 " attstattarget >= 0) AS indstatcols, "
7953 "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
7954 " FROM pg_catalog.pg_attribute "
7955 " WHERE attrelid = i.indexrelid AND "
7956 " attstattarget >= 0) AS indstatvals, ");
7957 else
7959 "0 AS parentidx, "
7960 "i.indnatts AS indnkeyatts, "
7961 "i.indnatts AS indnatts, "
7962 "'' AS indstatcols, "
7963 "'' AS indstatvals, ");
7964
7965 if (fout->remoteVersion >= 150000)
7967 "i.indnullsnotdistinct, ");
7968 else
7970 "false AS indnullsnotdistinct, ");
7971
7972 if (fout->remoteVersion >= 180000)
7974 "c.conperiod ");
7975 else
7977 "NULL AS conperiod ");
7978
7979 /*
7980 * The point of the messy-looking outer join is to find a constraint that
7981 * is related by an internal dependency link to the index. If we find one,
7982 * create a CONSTRAINT entry linked to the INDEX entry. We assume an
7983 * index won't have more than one internal dependency.
7984 *
7985 * Note: the check on conrelid is redundant, but useful because that
7986 * column is indexed while conindid is not.
7987 */
7988 if (fout->remoteVersion >= 110000)
7989 {
7990 appendPQExpBuffer(query,
7991 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7992 "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7993 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7994 "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
7995 "LEFT JOIN pg_catalog.pg_constraint c "
7996 "ON (i.indrelid = c.conrelid AND "
7997 "i.indexrelid = c.conindid AND "
7998 "c.contype IN ('p','u','x')) "
7999 "LEFT JOIN pg_catalog.pg_inherits inh "
8000 "ON (inh.inhrelid = indexrelid) "
8001 "WHERE (i.indisvalid OR t2.relkind = 'p') "
8002 "AND i.indisready "
8003 "ORDER BY i.indrelid, indexname",
8004 tbloids->data);
8005 }
8006 else
8007 {
8008 /*
8009 * the test on indisready is necessary in 9.2, and harmless in
8010 * earlier/later versions
8011 */
8012 appendPQExpBuffer(query,
8013 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8014 "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
8015 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
8016 "LEFT JOIN pg_catalog.pg_constraint c "
8017 "ON (i.indrelid = c.conrelid AND "
8018 "i.indexrelid = c.conindid AND "
8019 "c.contype IN ('p','u','x')) "
8020 "WHERE i.indisvalid AND i.indisready "
8021 "ORDER BY i.indrelid, indexname",
8022 tbloids->data);
8023 }
8024
8025 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8026
8027 ntups = PQntuples(res);
8028
8029 i_tableoid = PQfnumber(res, "tableoid");
8030 i_oid = PQfnumber(res, "oid");
8031 i_indrelid = PQfnumber(res, "indrelid");
8032 i_indexname = PQfnumber(res, "indexname");
8033 i_relpages = PQfnumber(res, "relpages");
8034 i_reltuples = PQfnumber(res, "reltuples");
8035 i_relallvisible = PQfnumber(res, "relallvisible");
8036 i_relallfrozen = PQfnumber(res, "relallfrozen");
8037 i_parentidx = PQfnumber(res, "parentidx");
8038 i_indexdef = PQfnumber(res, "indexdef");
8039 i_indnkeyatts = PQfnumber(res, "indnkeyatts");
8040 i_indnatts = PQfnumber(res, "indnatts");
8041 i_indkey = PQfnumber(res, "indkey");
8042 i_indisclustered = PQfnumber(res, "indisclustered");
8043 i_indisreplident = PQfnumber(res, "indisreplident");
8044 i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
8045 i_contype = PQfnumber(res, "contype");
8046 i_conname = PQfnumber(res, "conname");
8047 i_condeferrable = PQfnumber(res, "condeferrable");
8048 i_condeferred = PQfnumber(res, "condeferred");
8049 i_conperiod = PQfnumber(res, "conperiod");
8050 i_contableoid = PQfnumber(res, "contableoid");
8051 i_conoid = PQfnumber(res, "conoid");
8052 i_condef = PQfnumber(res, "condef");
8053 i_indattnames = PQfnumber(res, "indattnames");
8054 i_tablespace = PQfnumber(res, "tablespace");
8055 i_indreloptions = PQfnumber(res, "indreloptions");
8056 i_indstatcols = PQfnumber(res, "indstatcols");
8057 i_indstatvals = PQfnumber(res, "indstatvals");
8058
8059 indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
8060
8061 /*
8062 * Outer loop iterates once per table, not once per row. Incrementing of
8063 * j is handled by the inner loop.
8064 */
8065 curtblindx = -1;
8066 for (int j = 0; j < ntups;)
8067 {
8068 Oid indrelid = atooid(PQgetvalue(res, j, i_indrelid));
8069 TableInfo *tbinfo = NULL;
8070 char **indAttNames = NULL;
8071 int nindAttNames = 0;
8072 int numinds;
8073
8074 /* Count rows for this table */
8075 for (numinds = 1; numinds < ntups - j; numinds++)
8076 if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
8077 break;
8078
8079 /*
8080 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8081 * order.
8082 */
8083 while (++curtblindx < numTables)
8084 {
8085 tbinfo = &tblinfo[curtblindx];
8086 if (tbinfo->dobj.catId.oid == indrelid)
8087 break;
8088 }
8089 if (curtblindx >= numTables)
8090 pg_fatal("unrecognized table OID %u", indrelid);
8091 /* cross-check that we only got requested tables */
8092 if (!tbinfo->hasindex ||
8093 !tbinfo->interesting)
8094 pg_fatal("unexpected index data for table \"%s\"",
8095 tbinfo->dobj.name);
8096
8097 /* Save data for this table */
8098 tbinfo->indexes = indxinfo + j;
8099 tbinfo->numIndexes = numinds;
8100
8101 for (int c = 0; c < numinds; c++, j++)
8102 {
8103 char contype;
8104 char indexkind;
8105 RelStatsInfo *relstats;
8106 int32 relpages = atoi(PQgetvalue(res, j, i_relpages));
8107 int32 relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
8108 int32 relallfrozen = atoi(PQgetvalue(res, j, i_relallfrozen));
8109
8110 indxinfo[j].dobj.objType = DO_INDEX;
8111 indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8112 indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8113 AssignDumpId(&indxinfo[j].dobj);
8114 indxinfo[j].dobj.dump = tbinfo->dobj.dump;
8115 indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
8116 indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
8117 indxinfo[j].indextable = tbinfo;
8118 indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
8119 indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
8120 indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
8121 indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
8122 indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
8123 indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
8124 indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
8125 indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
8126 parseOidArray(PQgetvalue(res, j, i_indkey),
8127 indxinfo[j].indkeys, indxinfo[j].indnattrs);
8128 indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
8129 indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
8130 indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
8131 indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
8132 indxinfo[j].partattaches = (SimplePtrList)
8133 {
8134 NULL, NULL
8135 };
8136
8137 if (indxinfo[j].parentidx == 0)
8138 indexkind = RELKIND_INDEX;
8139 else
8140 indexkind = RELKIND_PARTITIONED_INDEX;
8141
8142 if (!PQgetisnull(res, j, i_indattnames))
8143 {
8144 if (!parsePGArray(PQgetvalue(res, j, i_indattnames),
8145 &indAttNames, &nindAttNames))
8146 pg_fatal("could not parse %s array", "indattnames");
8147 }
8148
8149 relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
8150 PQgetvalue(res, j, i_reltuples),
8151 relallvisible, relallfrozen, indexkind,
8152 indAttNames, nindAttNames);
8153
8154 contype = *(PQgetvalue(res, j, i_contype));
8155 if (contype == 'p' || contype == 'u' || contype == 'x')
8156 {
8157 /*
8158 * If we found a constraint matching the index, create an
8159 * entry for it.
8160 */
8161 ConstraintInfo *constrinfo;
8162
8163 constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
8164 constrinfo->dobj.objType = DO_CONSTRAINT;
8165 constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
8166 constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
8167 AssignDumpId(&constrinfo->dobj);
8168 constrinfo->dobj.dump = tbinfo->dobj.dump;
8169 constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
8170 constrinfo->dobj.namespace = tbinfo->dobj.namespace;
8171 constrinfo->contable = tbinfo;
8172 constrinfo->condomain = NULL;
8173 constrinfo->contype = contype;
8174 if (contype == 'x')
8175 constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
8176 else
8177 constrinfo->condef = NULL;
8178 constrinfo->confrelid = InvalidOid;
8179 constrinfo->conindex = indxinfo[j].dobj.dumpId;
8180 constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
8181 constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
8182 constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
8183 constrinfo->conislocal = true;
8184 constrinfo->separate = true;
8185
8186 indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
8187 if (relstats != NULL)
8188 addObjectDependency(&relstats->dobj, constrinfo->dobj.dumpId);
8189 }
8190 else
8191 {
8192 /* Plain secondary index */
8193 indxinfo[j].indexconstraint = 0;
8194 }
8195 }
8196 }
8197
8198 PQclear(res);
8199
8200 destroyPQExpBuffer(query);
8201 destroyPQExpBuffer(tbloids);
8202}
int32_t int32
Definition: c.h:548
static RelStatsInfo * getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages, char *reltuples, int32 relallvisible, int32 relallfrozen, char relkind, char **indAttNames, int nindAttNames)
Definition: pg_dump.c:7108
char * c
struct SimplePtrList SimplePtrList
bool hasindex
Definition: pg_dump.h:318

References addObjectDependency(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::conperiod, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_CONSTRAINT, DO_INDEX, _tableInfo::dobj, _indxInfo::dobj, _relStatsInfo::dobj, _constraintInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), getRelationStatistics(), _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(), parsePGArray(), _indxInfo::partattaches, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, Archive::remoteVersion, _constraintInfo::separate, CatalogId::tableoid, and _indxInfo::tablespace.

Referenced by getSchemaData().

◆ getInherits()

InhInfo * getInherits ( Archive fout,
int *  numInherits 
)

Definition at line 7727 of file pg_dump.c.

7728{
7729 PGresult *res;
7730 int ntups;
7731 int i;
7733 InhInfo *inhinfo;
7734
7735 int i_inhrelid;
7736 int i_inhparent;
7737
7738 /* find all the inheritance information */
7739 appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7740
7741 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7742
7743 ntups = PQntuples(res);
7744
7745 *numInherits = ntups;
7746
7747 inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7748
7749 i_inhrelid = PQfnumber(res, "inhrelid");
7750 i_inhparent = PQfnumber(res, "inhparent");
7751
7752 for (i = 0; i < ntups; i++)
7753 {
7754 inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7755 inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7756 }
7757
7758 PQclear(res);
7759
7760 destroyPQExpBuffer(query);
7761
7762 return inhinfo;
7763}
Oid inhparent
Definition: pg_dump.h:565
Oid inhrelid
Definition: pg_dump.h:564

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

Referenced by getSchemaData().

◆ getLOs()

static void getLOs ( Archive fout)
static

Definition at line 3946 of file pg_dump.c.

3947{
3948 DumpOptions *dopt = fout->dopt;
3950 PGresult *res;
3951 int ntups;
3952 int i;
3953 int n;
3954 int i_oid;
3955 int i_lomowner;
3956 int i_lomacl;
3957 int i_acldefault;
3958
3959 pg_log_info("reading large objects");
3960
3961 /*
3962 * Fetch LO OIDs and owner/ACL data. Order the data so that all the blobs
3963 * with the same owner/ACL appear together.
3964 */
3966 "SELECT oid, lomowner, lomacl, "
3967 "acldefault('L', lomowner) AS acldefault "
3968 "FROM pg_largeobject_metadata "
3969 "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
3970
3971 res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
3972
3973 i_oid = PQfnumber(res, "oid");
3974 i_lomowner = PQfnumber(res, "lomowner");
3975 i_lomacl = PQfnumber(res, "lomacl");
3976 i_acldefault = PQfnumber(res, "acldefault");
3977
3978 ntups = PQntuples(res);
3979
3980 /*
3981 * Group the blobs into suitably-sized groups that have the same owner and
3982 * ACL setting, and build a metadata and a data DumpableObject for each
3983 * group. (If we supported initprivs for blobs, we'd have to insist that
3984 * groups also share initprivs settings, since the DumpableObject only has
3985 * room for one.) i is the index of the first tuple in the current group,
3986 * and n is the number of tuples we include in the group.
3987 */
3988 for (i = 0; i < ntups; i += n)
3989 {
3990 Oid thisoid = atooid(PQgetvalue(res, i, i_oid));
3991 char *thisowner = PQgetvalue(res, i, i_lomowner);
3992 char *thisacl = PQgetvalue(res, i, i_lomacl);
3993 LoInfo *loinfo;
3994 DumpableObject *lodata;
3995 char namebuf[64];
3996
3997 /* Scan to find first tuple not to be included in group */
3998 n = 1;
3999 while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
4000 {
4001 if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
4002 strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
4003 break;
4004 n++;
4005 }
4006
4007 /* Build the metadata DumpableObject */
4008 loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
4009
4010 loinfo->dobj.objType = DO_LARGE_OBJECT;
4011 loinfo->dobj.catId.tableoid = LargeObjectRelationId;
4012 loinfo->dobj.catId.oid = thisoid;
4013 AssignDumpId(&loinfo->dobj);
4014
4015 if (n > 1)
4016 snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
4017 atooid(PQgetvalue(res, i + n - 1, i_oid)));
4018 else
4019 snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
4020 loinfo->dobj.name = pg_strdup(namebuf);
4021 loinfo->dacl.acl = pg_strdup(thisacl);
4022 loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
4023 loinfo->dacl.privtype = 0;
4024 loinfo->dacl.initprivs = NULL;
4025 loinfo->rolname = getRoleName(thisowner);
4026 loinfo->numlos = n;
4027 loinfo->looids[0] = thisoid;
4028 /* Collect OIDs of the remaining blobs in this group */
4029 for (int k = 1; k < n; k++)
4030 {
4031 CatalogId extraID;
4032
4033 loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
4034
4035 /* Make sure we can look up loinfo by any of the blobs' OIDs */
4036 extraID.tableoid = LargeObjectRelationId;
4037 extraID.oid = loinfo->looids[k];
4038 recordAdditionalCatalogID(extraID, &loinfo->dobj);
4039 }
4040
4041 /* LOs have data */
4043
4044 /* Mark whether LO group has a non-empty ACL */
4045 if (!PQgetisnull(res, i, i_lomacl))
4047
4048 /*
4049 * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
4050 * as it will be copied by pg_upgrade, which simply copies the
4051 * pg_largeobject table. We *do* however dump out anything but the
4052 * data, as pg_upgrade copies just pg_largeobject, but not
4053 * pg_largeobject_metadata, after the dump is restored. In versions
4054 * before v12, this is done via proper large object commands. In
4055 * newer versions, we dump the content of pg_largeobject_metadata and
4056 * any associated pg_shdepend rows, which is faster to restore. (On
4057 * <v12, pg_largeobject_metadata was created WITH OIDS, so the OID
4058 * column is hidden and won't be dumped.)
4059 */
4060 if (dopt->binary_upgrade)
4061 {
4062 if (fout->remoteVersion >= 120000)
4063 {
4064 /*
4065 * We should've saved pg_largeobject_metadata's dump ID before
4066 * this point.
4067 */
4069
4071
4072 /*
4073 * Mark the large object as dependent on
4074 * pg_largeobject_metadata so that any large object
4075 * comments/seclables are dumped after it.
4076 */
4077 loinfo->dobj.dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4079 loinfo->dobj.nDeps = loinfo->dobj.allocDeps = 1;
4080 }
4081 else
4082 loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
4083 }
4084
4085 /*
4086 * Create a "BLOBS" data item for the group, too. This is just a
4087 * placeholder for sorting; it carries no data now.
4088 */
4089 lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
4090 lodata->objType = DO_LARGE_OBJECT_DATA;
4091 lodata->catId = nilCatalogId;
4092 AssignDumpId(lodata);
4093 lodata->name = pg_strdup(namebuf);
4095 /* Set up explicit dependency from data to metadata */
4096 lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4097 lodata->dependencies[0] = loinfo->dobj.dumpId;
4098 lodata->nDeps = lodata->allocDeps = 1;
4099 }
4100
4101 PQclear(res);
4102 destroyPQExpBuffer(loQry);
4103}
void recordAdditionalCatalogID(CatalogId catId, DumpableObject *dobj)
Definition: common.c:719
#define MAX_BLOBS_PER_ARCHIVE_ENTRY
Definition: pg_dump.c:235
static DumpId lo_metadata_dumpId
Definition: pg_dump.c:219

References _dumpableAcl::acl, _dumpableAcl::acldefault, _dumpableObject::allocDeps, appendPQExpBufferStr(), Assert(), 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, DUMP_COMPONENT_DEFINITION, _dumpableObject::dumpId, ExecuteSqlQuery(), getRoleName(), i, _dumpableAcl::initprivs, lo_metadata_dumpId, _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(), Archive::remoteVersion, _loInfo::rolname, snprintf, and CatalogId::tableoid.

Referenced by main().

◆ getNamespaces()

void getNamespaces ( Archive fout)

Definition at line 5991 of file pg_dump.c.

5992{
5993 PGresult *res;
5994 int ntups;
5995 int i;
5996 PQExpBuffer query;
5997 NamespaceInfo *nsinfo;
5998 int i_tableoid;
5999 int i_oid;
6000 int i_nspname;
6001 int i_nspowner;
6002 int i_nspacl;
6003 int i_acldefault;
6004
6005 query = createPQExpBuffer();
6006
6007 /*
6008 * we fetch all namespaces including system ones, so that every object we
6009 * read in can be linked to a containing namespace.
6010 */
6011 appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
6012 "n.nspowner, "
6013 "n.nspacl, "
6014 "acldefault('n', n.nspowner) AS acldefault "
6015 "FROM pg_namespace n");
6016
6017 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6018
6019 ntups = PQntuples(res);
6020
6021 nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
6022
6023 i_tableoid = PQfnumber(res, "tableoid");
6024 i_oid = PQfnumber(res, "oid");
6025 i_nspname = PQfnumber(res, "nspname");
6026 i_nspowner = PQfnumber(res, "nspowner");
6027 i_nspacl = PQfnumber(res, "nspacl");
6028 i_acldefault = PQfnumber(res, "acldefault");
6029
6030 for (i = 0; i < ntups; i++)
6031 {
6032 const char *nspowner;
6033
6034 nsinfo[i].dobj.objType = DO_NAMESPACE;
6035 nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6036 nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6037 AssignDumpId(&nsinfo[i].dobj);
6038 nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
6039 nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
6040 nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6041 nsinfo[i].dacl.privtype = 0;
6042 nsinfo[i].dacl.initprivs = NULL;
6043 nspowner = PQgetvalue(res, i, i_nspowner);
6044 nsinfo[i].nspowner = atooid(nspowner);
6045 nsinfo[i].rolname = getRoleName(nspowner);
6046
6047 /* Decide whether to dump this namespace */
6048 selectDumpableNamespace(&nsinfo[i], fout);
6049
6050 /* Mark whether namespace has an ACL */
6051 if (!PQgetisnull(res, i, i_nspacl))
6053
6054 /*
6055 * We ignore any pg_init_privs.initprivs entry for the public schema
6056 * and assume a predetermined default, for several reasons. First,
6057 * dropping and recreating the schema removes its pg_init_privs entry,
6058 * but an empty destination database starts with this ACL nonetheless.
6059 * Second, we support dump/reload of public schema ownership changes.
6060 * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
6061 * initprivs continues to reflect the initial owner. Hence,
6062 * synthesize the value that nspacl will have after the restore's
6063 * ALTER SCHEMA OWNER. Third, this makes the destination database
6064 * match the source's ACL, even if the latter was an initdb-default
6065 * ACL, which changed in v15. An upgrade pulls in changes to most
6066 * system object ACLs that the DBA had not customized. We've made the
6067 * public schema depart from that, because changing its ACL so easily
6068 * breaks applications.
6069 */
6070 if (strcmp(nsinfo[i].dobj.name, "public") == 0)
6071 {
6072 PQExpBuffer aclarray = createPQExpBuffer();
6073 PQExpBuffer aclitem = createPQExpBuffer();
6074
6075 /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
6076 appendPQExpBufferChar(aclarray, '{');
6077 quoteAclUserName(aclitem, nsinfo[i].rolname);
6078 appendPQExpBufferStr(aclitem, "=UC/");
6079 quoteAclUserName(aclitem, nsinfo[i].rolname);
6080 appendPGArray(aclarray, aclitem->data);
6081 resetPQExpBuffer(aclitem);
6082 appendPQExpBufferStr(aclitem, "=U/");
6083 quoteAclUserName(aclitem, nsinfo[i].rolname);
6084 appendPGArray(aclarray, aclitem->data);
6085 appendPQExpBufferChar(aclarray, '}');
6086
6087 nsinfo[i].dacl.privtype = 'i';
6088 nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
6090
6091 destroyPQExpBuffer(aclarray);
6092 destroyPQExpBuffer(aclitem);
6093 }
6094 }
6095
6096 PQclear(res);
6097 destroyPQExpBuffer(query);
6098}
void quoteAclUserName(PQExpBuffer output, const char *input)
Definition: dumputils.c:585
NameData rolname
Definition: pg_authid.h:34
static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
Definition: pg_dump.c:1998

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(), resetPQExpBuffer(), _namespaceInfo::rolname, rolname, selectDumpableNamespace(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOpclasses()

void getOpclasses ( Archive fout)

Definition at line 6644 of file pg_dump.c.

6645{
6646 PGresult *res;
6647 int ntups;
6648 int i;
6650 OpclassInfo *opcinfo;
6651 int i_tableoid;
6652 int i_oid;
6653 int i_opcmethod;
6654 int i_opcname;
6655 int i_opcnamespace;
6656 int i_opcowner;
6657
6658 /*
6659 * find all opclasses, including builtin opclasses; we filter out
6660 * system-defined opclasses at dump-out time.
6661 */
6662
6663 appendPQExpBufferStr(query, "SELECT tableoid, oid, opcmethod, opcname, "
6664 "opcnamespace, "
6665 "opcowner "
6666 "FROM pg_opclass");
6667
6668 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6669
6670 ntups = PQntuples(res);
6671
6672 opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6673
6674 i_tableoid = PQfnumber(res, "tableoid");
6675 i_oid = PQfnumber(res, "oid");
6676 i_opcmethod = PQfnumber(res, "opcmethod");
6677 i_opcname = PQfnumber(res, "opcname");
6678 i_opcnamespace = PQfnumber(res, "opcnamespace");
6679 i_opcowner = PQfnumber(res, "opcowner");
6680
6681 for (i = 0; i < ntups; i++)
6682 {
6683 opcinfo[i].dobj.objType = DO_OPCLASS;
6684 opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6685 opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6686 AssignDumpId(&opcinfo[i].dobj);
6687 opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6688 opcinfo[i].dobj.namespace =
6689 findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6690 opcinfo[i].opcmethod = atooid(PQgetvalue(res, i, i_opcmethod));
6691 opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6692
6693 /* Decide whether we want to dump it */
6694 selectDumpableObject(&(opcinfo[i].dobj), fout);
6695 }
6696
6697 PQclear(res);
6698
6699 destroyPQExpBuffer(query);
6700}
Oid opcmethod
Definition: pg_dump.h:278

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

Referenced by getSchemaData().

◆ getOperators()

void getOperators ( Archive fout)

Definition at line 6366 of file pg_dump.c.

6367{
6368 PGresult *res;
6369 int ntups;
6370 int i;
6372 OprInfo *oprinfo;
6373 int i_tableoid;
6374 int i_oid;
6375 int i_oprname;
6376 int i_oprnamespace;
6377 int i_oprowner;
6378 int i_oprkind;
6379 int i_oprleft;
6380 int i_oprright;
6381 int i_oprcode;
6382
6383 /*
6384 * find all operators, including builtin operators; we filter out
6385 * system-defined operators at dump-out time.
6386 */
6387
6388 appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
6389 "oprnamespace, "
6390 "oprowner, "
6391 "oprkind, "
6392 "oprleft, "
6393 "oprright, "
6394 "oprcode::oid AS oprcode "
6395 "FROM pg_operator");
6396
6397 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6398
6399 ntups = PQntuples(res);
6400
6401 oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6402
6403 i_tableoid = PQfnumber(res, "tableoid");
6404 i_oid = PQfnumber(res, "oid");
6405 i_oprname = PQfnumber(res, "oprname");
6406 i_oprnamespace = PQfnumber(res, "oprnamespace");
6407 i_oprowner = PQfnumber(res, "oprowner");
6408 i_oprkind = PQfnumber(res, "oprkind");
6409 i_oprleft = PQfnumber(res, "oprleft");
6410 i_oprright = PQfnumber(res, "oprright");
6411 i_oprcode = PQfnumber(res, "oprcode");
6412
6413 for (i = 0; i < ntups; i++)
6414 {
6415 oprinfo[i].dobj.objType = DO_OPERATOR;
6416 oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6417 oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6418 AssignDumpId(&oprinfo[i].dobj);
6419 oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6420 oprinfo[i].dobj.namespace =
6421 findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6422 oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6423 oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6424 oprinfo[i].oprleft = atooid(PQgetvalue(res, i, i_oprleft));
6425 oprinfo[i].oprright = atooid(PQgetvalue(res, i, i_oprright));
6426 oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6427
6428 /* Decide whether we want to dump it */
6429 selectDumpableObject(&(oprinfo[i].dobj), fout);
6430 }
6431
6432 PQclear(res);
6433
6434 destroyPQExpBuffer(query);
6435}
Oid oprleft
Definition: pg_dump.h:263
char oprkind
Definition: pg_dump.h:262
Oid oprright
Definition: pg_dump.h:264

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, _oprInfo::oprleft, _oprInfo::oprright, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, _oprInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOpfamilies()

void getOpfamilies ( Archive fout)

Definition at line 6707 of file pg_dump.c.

6708{
6709 PGresult *res;
6710 int ntups;
6711 int i;
6712 PQExpBuffer query;
6713 OpfamilyInfo *opfinfo;
6714 int i_tableoid;
6715 int i_oid;
6716 int i_opfmethod;
6717 int i_opfname;
6718 int i_opfnamespace;
6719 int i_opfowner;
6720
6721 query = createPQExpBuffer();
6722
6723 /*
6724 * find all opfamilies, including builtin opfamilies; we filter out
6725 * system-defined opfamilies at dump-out time.
6726 */
6727
6728 appendPQExpBufferStr(query, "SELECT tableoid, oid, opfmethod, opfname, "
6729 "opfnamespace, "
6730 "opfowner "
6731 "FROM pg_opfamily");
6732
6733 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6734
6735 ntups = PQntuples(res);
6736
6737 opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6738
6739 i_tableoid = PQfnumber(res, "tableoid");
6740 i_oid = PQfnumber(res, "oid");
6741 i_opfname = PQfnumber(res, "opfname");
6742 i_opfmethod = PQfnumber(res, "opfmethod");
6743 i_opfnamespace = PQfnumber(res, "opfnamespace");
6744 i_opfowner = PQfnumber(res, "opfowner");
6745
6746 for (i = 0; i < ntups; i++)
6747 {
6748 opfinfo[i].dobj.objType = DO_OPFAMILY;
6749 opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6750 opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6751 AssignDumpId(&opfinfo[i].dobj);
6752 opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6753 opfinfo[i].dobj.namespace =
6754 findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6755 opfinfo[i].opfmethod = atooid(PQgetvalue(res, i, i_opfmethod));
6756 opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6757
6758 /* Decide whether we want to dump it */
6759 selectDumpableObject(&(opfinfo[i].dobj), fout);
6760 }
6761
6762 PQclear(res);
6763
6764 destroyPQExpBuffer(query);
6765}
Oid opfmethod
Definition: pg_dump.h:285

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

Referenced by getSchemaData().

◆ getOwnedSeqs()

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

Definition at line 7662 of file pg_dump.c.

7663{
7664 int i;
7665
7666 /*
7667 * Force sequences that are "owned" by table columns to be dumped whenever
7668 * their owning table is being dumped.
7669 */
7670 for (i = 0; i < numTables; i++)
7671 {
7672 TableInfo *seqinfo = &tblinfo[i];
7673 TableInfo *owning_tab;
7674
7675 if (!OidIsValid(seqinfo->owning_tab))
7676 continue; /* not an owned sequence */
7677
7678 owning_tab = findTableByOid(seqinfo->owning_tab);
7679 if (owning_tab == NULL)
7680 pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7681 seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7682
7683 /*
7684 * For an identity sequence, dump exactly the same components for the
7685 * sequence as for the owning table. This is important because we
7686 * treat the identity sequence as an integral part of the table. For
7687 * example, there is not any DDL command that allows creation of such
7688 * a sequence independently of the table.
7689 *
7690 * For other owned sequences such as serial sequences, we need to dump
7691 * the components that are being dumped for the table and any
7692 * components that the sequence is explicitly marked with.
7693 *
7694 * We can't simply use the set of components which are being dumped
7695 * for the table as the table might be in an extension (and only the
7696 * non-extension components, eg: ACLs if changed, security labels, and
7697 * policies, are being dumped) while the sequence is not (and
7698 * therefore the definition and other components should also be
7699 * dumped).
7700 *
7701 * If the sequence is part of the extension then it should be properly
7702 * marked by checkExtensionMembership() and this will be a no-op as
7703 * the table will be equivalently marked.
7704 */
7705 if (seqinfo->is_identity_sequence)
7706 seqinfo->dobj.dump = owning_tab->dobj.dump;
7707 else
7708 seqinfo->dobj.dump |= owning_tab->dobj.dump;
7709
7710 /* Make sure that necessary data is available if we're dumping it */
7711 if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7712 {
7713 seqinfo->interesting = true;
7714 owning_tab->interesting = true;
7715 }
7716 }
7717}

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

7784{
7785 PQExpBuffer query;
7786 PGresult *res;
7787 int ntups;
7788
7789 /* hash partitioning didn't exist before v11 */
7790 if (fout->remoteVersion < 110000)
7791 return;
7792 /* needn't bother if not dumping data */
7793 if (!fout->dopt->dumpData)
7794 return;
7795
7796 query = createPQExpBuffer();
7797
7798 /*
7799 * Unsafe partitioning schemes are exactly those for which hash enum_ops
7800 * appears among the partition opclasses. We needn't check partstrat.
7801 *
7802 * Note that this query may well retrieve info about tables we aren't
7803 * going to dump and hence have no lock on. That's okay since we need not
7804 * invoke any unsafe server-side functions.
7805 */
7807 "SELECT partrelid FROM pg_partitioned_table WHERE\n"
7808 "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
7809 "ON c.opcmethod = a.oid\n"
7810 "WHERE opcname = 'enum_ops' "
7811 "AND opcnamespace = 'pg_catalog'::regnamespace "
7812 "AND amname = 'hash') = ANY(partclass)");
7813
7814 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7815
7816 ntups = PQntuples(res);
7817
7818 for (int i = 0; i < ntups; i++)
7819 {
7820 Oid tabrelid = atooid(PQgetvalue(res, i, 0));
7821 TableInfo *tbinfo;
7822
7823 tbinfo = findTableByOid(tabrelid);
7824 if (tbinfo == NULL)
7825 pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
7826 tabrelid);
7827 tbinfo->unsafe_partitions = true;
7828 }
7829
7830 PQclear(res);
7831
7832 destroyPQExpBuffer(query);
7833}

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

Referenced by getSchemaData().

◆ getPolicies()

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

Definition at line 4247 of file pg_dump.c.

4248{
4249 DumpOptions *dopt = fout->dopt;
4250 PQExpBuffer query;
4251 PQExpBuffer tbloids;
4252 PGresult *res;
4253 PolicyInfo *polinfo;
4254 int i_oid;
4255 int i_tableoid;
4256 int i_polrelid;
4257 int i_polname;
4258 int i_polcmd;
4259 int i_polpermissive;
4260 int i_polroles;
4261 int i_polqual;
4262 int i_polwithcheck;
4263 int i,
4264 j,
4265 ntups;
4266
4267 /* No policies before 9.5 */
4268 if (fout->remoteVersion < 90500)
4269 return;
4270
4271 /* Skip if --no-policies was specified */
4272 if (dopt->no_policies)
4273 return;
4274
4275 query = createPQExpBuffer();
4276 tbloids = createPQExpBuffer();
4277
4278 /*
4279 * Identify tables of interest, and check which ones have RLS enabled.
4280 */
4281 appendPQExpBufferChar(tbloids, '{');
4282 for (i = 0; i < numTables; i++)
4283 {
4284 TableInfo *tbinfo = &tblinfo[i];
4285
4286 /* Ignore row security on tables not to be dumped */
4287 if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
4288 continue;
4289
4290 /* It can't have RLS or policies if it's not a table */
4291 if (tbinfo->relkind != RELKIND_RELATION &&
4292 tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
4293 continue;
4294
4295 /* Add it to the list of table OIDs to be probed below */
4296 if (tbloids->len > 1) /* do we have more than the '{'? */
4297 appendPQExpBufferChar(tbloids, ',');
4298 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
4299
4300 /* Is RLS enabled? (That's separate from whether it has policies) */
4301 if (tbinfo->rowsec)
4302 {
4304
4305 /*
4306 * We represent RLS being enabled on a table by creating a
4307 * PolicyInfo object with null polname.
4308 *
4309 * Note: use tableoid 0 so that this object won't be mistaken for
4310 * something that pg_depend entries apply to.
4311 */
4312 polinfo = pg_malloc(sizeof(PolicyInfo));
4313 polinfo->dobj.objType = DO_POLICY;
4314 polinfo->dobj.catId.tableoid = 0;
4315 polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
4316 AssignDumpId(&polinfo->dobj);
4317 polinfo->dobj.namespace = tbinfo->dobj.namespace;
4318 polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
4319 polinfo->poltable = tbinfo;
4320 polinfo->polname = NULL;
4321 polinfo->polcmd = '\0';
4322 polinfo->polpermissive = 0;
4323 polinfo->polroles = NULL;
4324 polinfo->polqual = NULL;
4325 polinfo->polwithcheck = NULL;
4326 }
4327 }
4328 appendPQExpBufferChar(tbloids, '}');
4329
4330 /*
4331 * Now, read all RLS policies belonging to the tables of interest, and
4332 * create PolicyInfo objects for them. (Note that we must filter the
4333 * results server-side not locally, because we dare not apply pg_get_expr
4334 * to tables we don't have lock on.)
4335 */
4336 pg_log_info("reading row-level security policies");
4337
4338 printfPQExpBuffer(query,
4339 "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
4340 if (fout->remoteVersion >= 100000)
4341 appendPQExpBufferStr(query, "pol.polpermissive, ");
4342 else
4343 appendPQExpBufferStr(query, "'t' as polpermissive, ");
4344 appendPQExpBuffer(query,
4345 "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
4346 " 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, "
4347 "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
4348 "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
4349 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
4350 "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
4351 tbloids->data);
4352
4353 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4354
4355 ntups = PQntuples(res);
4356 if (ntups > 0)
4357 {
4358 i_oid = PQfnumber(res, "oid");
4359 i_tableoid = PQfnumber(res, "tableoid");
4360 i_polrelid = PQfnumber(res, "polrelid");
4361 i_polname = PQfnumber(res, "polname");
4362 i_polcmd = PQfnumber(res, "polcmd");
4363 i_polpermissive = PQfnumber(res, "polpermissive");
4364 i_polroles = PQfnumber(res, "polroles");
4365 i_polqual = PQfnumber(res, "polqual");
4366 i_polwithcheck = PQfnumber(res, "polwithcheck");
4367
4368 polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
4369
4370 for (j = 0; j < ntups; j++)
4371 {
4372 Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
4373 TableInfo *tbinfo = findTableByOid(polrelid);
4374
4376
4377 polinfo[j].dobj.objType = DO_POLICY;
4378 polinfo[j].dobj.catId.tableoid =
4379 atooid(PQgetvalue(res, j, i_tableoid));
4380 polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4381 AssignDumpId(&polinfo[j].dobj);
4382 polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4383 polinfo[j].poltable = tbinfo;
4384 polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
4385 polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
4386
4387 polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
4388 polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
4389
4390 if (PQgetisnull(res, j, i_polroles))
4391 polinfo[j].polroles = NULL;
4392 else
4393 polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
4394
4395 if (PQgetisnull(res, j, i_polqual))
4396 polinfo[j].polqual = NULL;
4397 else
4398 polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
4399
4400 if (PQgetisnull(res, j, i_polwithcheck))
4401 polinfo[j].polwithcheck = NULL;
4402 else
4403 polinfo[j].polwithcheck
4404 = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
4405 }
4406 }
4407
4408 PQclear(res);
4409
4410 destroyPQExpBuffer(query);
4411 destroyPQExpBuffer(tbloids);
4412}
#define DUMP_COMPONENT_POLICY
Definition: pg_dump.h:114
int no_policies
Definition: pg_backup.h:187
bool rowsec
Definition: pg_dump.h:322

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_POLICY, _tableInfo::dobj, _policyInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_POLICY, ExecuteSqlQuery(), findTableByOid(), i, j, PQExpBufferData::len, _dumpableObject::name, _dumpOptions::no_policies, _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, _tableInfo::rowsec, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getProcLangs()

void getProcLangs ( Archive fout)

Definition at line 8956 of file pg_dump.c.

8957{
8958 PGresult *res;
8959 int ntups;
8960 int i;
8962 ProcLangInfo *planginfo;
8963 int i_tableoid;
8964 int i_oid;
8965 int i_lanname;
8966 int i_lanpltrusted;
8967 int i_lanplcallfoid;
8968 int i_laninline;
8969 int i_lanvalidator;
8970 int i_lanacl;
8971 int i_acldefault;
8972 int i_lanowner;
8973
8974 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8975 "lanname, lanpltrusted, lanplcallfoid, "
8976 "laninline, lanvalidator, "
8977 "lanacl, "
8978 "acldefault('l', lanowner) AS acldefault, "
8979 "lanowner "
8980 "FROM pg_language "
8981 "WHERE lanispl "
8982 "ORDER BY oid");
8983
8984 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8985
8986 ntups = PQntuples(res);
8987
8988 planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8989
8990 i_tableoid = PQfnumber(res, "tableoid");
8991 i_oid = PQfnumber(res, "oid");
8992 i_lanname = PQfnumber(res, "lanname");
8993 i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8994 i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8995 i_laninline = PQfnumber(res, "laninline");
8996 i_lanvalidator = PQfnumber(res, "lanvalidator");
8997 i_lanacl = PQfnumber(res, "lanacl");
8998 i_acldefault = PQfnumber(res, "acldefault");
8999 i_lanowner = PQfnumber(res, "lanowner");
9000
9001 for (i = 0; i < ntups; i++)
9002 {
9003 planginfo[i].dobj.objType = DO_PROCLANG;
9004 planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9005 planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9006 AssignDumpId(&planginfo[i].dobj);
9007
9008 planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
9009 planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
9010 planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9011 planginfo[i].dacl.privtype = 0;
9012 planginfo[i].dacl.initprivs = NULL;
9013 planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
9014 planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
9015 planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
9016 planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
9017 planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
9018
9019 /* Decide whether we want to dump it */
9020 selectDumpableProcLang(&(planginfo[i]), fout);
9021
9022 /* Mark whether language has an ACL */
9023 if (!PQgetisnull(res, i, i_lanacl))
9024 planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9025 }
9026
9027 PQclear(res);
9028
9029 destroyPQExpBuffer(query);
9030}
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:2215

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, selectDumpableProcLang(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationNamespaces()

void getPublicationNamespaces ( Archive fout)

Definition at line 4756 of file pg_dump.c.

4757{
4758 PQExpBuffer query;
4759 PGresult *res;
4760 PublicationSchemaInfo *pubsinfo;
4761 DumpOptions *dopt = fout->dopt;
4762 int i_tableoid;
4763 int i_oid;
4764 int i_pnpubid;
4765 int i_pnnspid;
4766 int i,
4767 j,
4768 ntups;
4769
4770 if (dopt->no_publications || fout->remoteVersion < 150000)
4771 return;
4772
4773 query = createPQExpBuffer();
4774
4775 /* Collect all publication membership info. */
4777 "SELECT tableoid, oid, pnpubid, pnnspid "
4778 "FROM pg_catalog.pg_publication_namespace");
4779 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4780
4781 ntups = PQntuples(res);
4782
4783 i_tableoid = PQfnumber(res, "tableoid");
4784 i_oid = PQfnumber(res, "oid");
4785 i_pnpubid = PQfnumber(res, "pnpubid");
4786 i_pnnspid = PQfnumber(res, "pnnspid");
4787
4788 /* this allocation may be more than we need */
4789 pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4790 j = 0;
4791
4792 for (i = 0; i < ntups; i++)
4793 {
4794 Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4795 Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4796 PublicationInfo *pubinfo;
4797 NamespaceInfo *nspinfo;
4798
4799 /*
4800 * Ignore any entries for which we aren't interested in either the
4801 * publication or the rel.
4802 */
4803 pubinfo = findPublicationByOid(pnpubid);
4804 if (pubinfo == NULL)
4805 continue;
4806 nspinfo = findNamespaceByOid(pnnspid);
4807 if (nspinfo == NULL)
4808 continue;
4809
4810 /* OK, make a DumpableObject for this relationship */
4812 pubsinfo[j].dobj.catId.tableoid =
4813 atooid(PQgetvalue(res, i, i_tableoid));
4814 pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4815 AssignDumpId(&pubsinfo[j].dobj);
4816 pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4817 pubsinfo[j].dobj.name = nspinfo->dobj.name;
4818 pubsinfo[j].publication = pubinfo;
4819 pubsinfo[j].pubschema = nspinfo;
4820
4821 /* Decide whether we want to dump it */
4822 selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4823
4824 j++;
4825 }
4826
4827 PQclear(res);
4828 destroyPQExpBuffer(query);
4829}
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:1026
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2322
int no_publications
Definition: pg_backup.h:188

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_TABLE_IN_SCHEMA, _namespaceInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, 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, selectDumpablePublicationObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublications()

void getPublications ( Archive fout)

Definition at line 4537 of file pg_dump.c.

4538{
4539 DumpOptions *dopt = fout->dopt;
4540 PQExpBuffer query;
4541 PGresult *res;
4542 PublicationInfo *pubinfo;
4543 int i_tableoid;
4544 int i_oid;
4545 int i_pubname;
4546 int i_pubowner;
4547 int i_puballtables;
4548 int i_puballsequences;
4549 int i_pubinsert;
4550 int i_pubupdate;
4551 int i_pubdelete;
4552 int i_pubtruncate;
4553 int i_pubviaroot;
4554 int i_pubgencols;
4555 int i,
4556 ntups;
4557
4558 if (dopt->no_publications || fout->remoteVersion < 100000)
4559 return;
4560
4561 query = createPQExpBuffer();
4562
4563 /* Get the publications. */
4564 appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, "
4565 "p.pubowner, p.puballtables, p.pubinsert, "
4566 "p.pubupdate, p.pubdelete, ");
4567
4568 if (fout->remoteVersion >= 110000)
4569 appendPQExpBufferStr(query, "p.pubtruncate, ");
4570 else
4571 appendPQExpBufferStr(query, "false AS pubtruncate, ");
4572
4573 if (fout->remoteVersion >= 130000)
4574 appendPQExpBufferStr(query, "p.pubviaroot, ");
4575 else
4576 appendPQExpBufferStr(query, "false AS pubviaroot, ");
4577
4578 if (fout->remoteVersion >= 180000)
4579 appendPQExpBufferStr(query, "p.pubgencols, ");
4580 else
4581 appendPQExpBuffer(query, "'%c' AS pubgencols, ", PUBLISH_GENCOLS_NONE);
4582
4583 if (fout->remoteVersion >= 190000)
4584 appendPQExpBufferStr(query, "p.puballsequences ");
4585 else
4586 appendPQExpBufferStr(query, "false AS puballsequences ");
4587
4588 appendPQExpBufferStr(query, "FROM pg_publication p");
4589
4590 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4591
4592 ntups = PQntuples(res);
4593
4594 if (ntups == 0)
4595 goto cleanup;
4596
4597 i_tableoid = PQfnumber(res, "tableoid");
4598 i_oid = PQfnumber(res, "oid");
4599 i_pubname = PQfnumber(res, "pubname");
4600 i_pubowner = PQfnumber(res, "pubowner");
4601 i_puballtables = PQfnumber(res, "puballtables");
4602 i_puballsequences = PQfnumber(res, "puballsequences");
4603 i_pubinsert = PQfnumber(res, "pubinsert");
4604 i_pubupdate = PQfnumber(res, "pubupdate");
4605 i_pubdelete = PQfnumber(res, "pubdelete");
4606 i_pubtruncate = PQfnumber(res, "pubtruncate");
4607 i_pubviaroot = PQfnumber(res, "pubviaroot");
4608 i_pubgencols = PQfnumber(res, "pubgencols");
4609
4610 pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4611
4612 for (i = 0; i < ntups; i++)
4613 {
4614 pubinfo[i].dobj.objType = DO_PUBLICATION;
4615 pubinfo[i].dobj.catId.tableoid =
4616 atooid(PQgetvalue(res, i, i_tableoid));
4617 pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4618 AssignDumpId(&pubinfo[i].dobj);
4619 pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4620 pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4621 pubinfo[i].puballtables =
4622 (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4623 pubinfo[i].puballsequences =
4624 (strcmp(PQgetvalue(res, i, i_puballsequences), "t") == 0);
4625 pubinfo[i].pubinsert =
4626 (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4627 pubinfo[i].pubupdate =
4628 (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4629 pubinfo[i].pubdelete =
4630 (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4631 pubinfo[i].pubtruncate =
4632 (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4633 pubinfo[i].pubviaroot =
4634 (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4635 pubinfo[i].pubgencols_type =
4636 *(PQgetvalue(res, i, i_pubgencols));
4637
4638 /* Decide whether we want to dump it */
4639 selectDumpableObject(&(pubinfo[i].dobj), fout);
4640 }
4641
4642cleanup:
4643 PQclear(res);
4644
4645 destroyPQExpBuffer(query);
4646}

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

Referenced by getSchemaData().

◆ getPublicationTables()

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

Definition at line 4836 of file pg_dump.c.

4837{
4838 PQExpBuffer query;
4839 PGresult *res;
4840 PublicationRelInfo *pubrinfo;
4841 DumpOptions *dopt = fout->dopt;
4842 int i_tableoid;
4843 int i_oid;
4844 int i_prpubid;
4845 int i_prrelid;
4846 int i_prrelqual;
4847 int i_prattrs;
4848 int i,
4849 j,
4850 ntups;
4851
4852 if (dopt->no_publications || fout->remoteVersion < 100000)
4853 return;
4854
4855 query = createPQExpBuffer();
4856
4857 /* Collect all publication membership info. */
4858 if (fout->remoteVersion >= 150000)
4860 "SELECT tableoid, oid, prpubid, prrelid, "
4861 "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
4862 "(CASE\n"
4863 " WHEN pr.prattrs IS NOT NULL THEN\n"
4864 " (SELECT array_agg(attname)\n"
4865 " FROM\n"
4866 " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
4867 " pg_catalog.pg_attribute\n"
4868 " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
4869 " ELSE NULL END) prattrs "
4870 "FROM pg_catalog.pg_publication_rel pr");
4871 else
4873 "SELECT tableoid, oid, prpubid, prrelid, "
4874 "NULL AS prrelqual, NULL AS prattrs "
4875 "FROM pg_catalog.pg_publication_rel");
4876 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4877
4878 ntups = PQntuples(res);
4879
4880 i_tableoid = PQfnumber(res, "tableoid");
4881 i_oid = PQfnumber(res, "oid");
4882 i_prpubid = PQfnumber(res, "prpubid");
4883 i_prrelid = PQfnumber(res, "prrelid");
4884 i_prrelqual = PQfnumber(res, "prrelqual");
4885 i_prattrs = PQfnumber(res, "prattrs");
4886
4887 /* this allocation may be more than we need */
4888 pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4889 j = 0;
4890
4891 for (i = 0; i < ntups; i++)
4892 {
4893 Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4894 Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4895 PublicationInfo *pubinfo;
4896 TableInfo *tbinfo;
4897
4898 /*
4899 * Ignore any entries for which we aren't interested in either the
4900 * publication or the rel.
4901 */
4902 pubinfo = findPublicationByOid(prpubid);
4903 if (pubinfo == NULL)
4904 continue;
4905 tbinfo = findTableByOid(prrelid);
4906 if (tbinfo == NULL)
4907 continue;
4908
4909 /* OK, make a DumpableObject for this relationship */
4910 pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4911 pubrinfo[j].dobj.catId.tableoid =
4912 atooid(PQgetvalue(res, i, i_tableoid));
4913 pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4914 AssignDumpId(&pubrinfo[j].dobj);
4915 pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4916 pubrinfo[j].dobj.name = tbinfo->dobj.name;
4917 pubrinfo[j].publication = pubinfo;
4918 pubrinfo[j].pubtable = tbinfo;
4919 if (PQgetisnull(res, i, i_prrelqual))
4920 pubrinfo[j].pubrelqual = NULL;
4921 else
4922 pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
4923
4924 if (!PQgetisnull(res, i, i_prattrs))
4925 {
4926 char **attnames;
4927 int nattnames;
4928 PQExpBuffer attribs;
4929
4930 if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
4931 &attnames, &nattnames))
4932 pg_fatal("could not parse %s array", "prattrs");
4933 attribs = createPQExpBuffer();
4934 for (int k = 0; k < nattnames; k++)
4935 {
4936 if (k > 0)
4937 appendPQExpBufferStr(attribs, ", ");
4938
4939 appendPQExpBufferStr(attribs, fmtId(attnames[k]));
4940 }
4941 pubrinfo[j].pubrattrs = attribs->data;
4942 free(attribs); /* but not attribs->data */
4943 free(attnames);
4944 }
4945 else
4946 pubrinfo[j].pubrattrs = NULL;
4947
4948 /* Decide whether we want to dump it */
4949 selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
4950
4951 j++;
4952 }
4953
4954 PQclear(res);
4955 destroyPQExpBuffer(query);
4956}

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

Referenced by getSchemaData().

◆ getRelationStatistics()

static RelStatsInfo * getRelationStatistics ( Archive fout,
DumpableObject rel,
int32  relpages,
char *  reltuples,
int32  relallvisible,
int32  relallfrozen,
char  relkind,
char **  indAttNames,
int  nindAttNames 
)
static

Definition at line 7108 of file pg_dump.c.

7112{
7113 if (!fout->dopt->dumpStatistics)
7114 return NULL;
7115
7116 if ((relkind == RELKIND_RELATION) ||
7117 (relkind == RELKIND_PARTITIONED_TABLE) ||
7118 (relkind == RELKIND_INDEX) ||
7119 (relkind == RELKIND_PARTITIONED_INDEX) ||
7120 (relkind == RELKIND_MATVIEW ||
7121 relkind == RELKIND_FOREIGN_TABLE))
7122 {
7123 RelStatsInfo *info = pg_malloc0(sizeof(RelStatsInfo));
7124 DumpableObject *dobj = &info->dobj;
7125
7126 dobj->objType = DO_REL_STATS;
7127 dobj->catId.tableoid = 0;
7128 dobj->catId.oid = 0;
7129 AssignDumpId(dobj);
7130 dobj->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
7131 dobj->dependencies[0] = rel->dumpId;
7132 dobj->nDeps = 1;
7133 dobj->allocDeps = 1;
7135 dobj->name = pg_strdup(rel->name);
7136 dobj->namespace = rel->namespace;
7137 info->relpages = relpages;
7138 info->reltuples = pstrdup(reltuples);
7139 info->relallvisible = relallvisible;
7140 info->relallfrozen = relallfrozen;
7141 info->relkind = relkind;
7142 info->indAttNames = indAttNames;
7143 info->nindAttNames = nindAttNames;
7144
7145 /*
7146 * Ordinarily, stats go in SECTION_DATA for tables and
7147 * SECTION_POST_DATA for indexes.
7148 *
7149 * However, the section may be updated later for materialized view
7150 * stats. REFRESH MATERIALIZED VIEW replaces the storage and resets
7151 * the stats, so the stats must be restored after the data. Also, the
7152 * materialized view definition may be postponed to SECTION_POST_DATA
7153 * (see repairMatViewBoundaryMultiLoop()).
7154 */
7155 switch (info->relkind)
7156 {
7157 case RELKIND_RELATION:
7158 case RELKIND_PARTITIONED_TABLE:
7159 case RELKIND_MATVIEW:
7160 case RELKIND_FOREIGN_TABLE:
7161 info->section = SECTION_DATA;
7162 break;
7163 case RELKIND_INDEX:
7164 case RELKIND_PARTITIONED_INDEX:
7165 info->section = SECTION_POST_DATA;
7166 break;
7167 default:
7168 pg_fatal("cannot dump statistics for relation kind \"%c\"",
7169 info->relkind);
7170 }
7171
7172 return info;
7173 }
7174 return NULL;
7175}
#define DUMP_COMPONENT_STATISTICS
Definition: pg_dump.h:116
char relkind
Definition: pg_dump.h:455

References _dumpableObject::allocDeps, AssignDumpId(), _dumpableObject::catId, _dumpableObject::components, _dumpableObject::dependencies, DO_REL_STATS, _relStatsInfo::dobj, Archive::dopt, DUMP_COMPONENT_STATISTICS, _dumpableObject::dumpId, _dumpOptions::dumpStatistics, _relStatsInfo::indAttNames, _dumpableObject::name, _dumpableObject::nDeps, _relStatsInfo::nindAttNames, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_malloc0(), pg_strdup(), pstrdup(), _relStatsInfo::relallfrozen, _relStatsInfo::relallvisible, _relStatsInfo::relkind, _relStatsInfo::relpages, _relStatsInfo::reltuples, _relStatsInfo::section, SECTION_DATA, SECTION_POST_DATA, and CatalogId::tableoid.

Referenced by getIndexes(), and getTables().

◆ getRoleName()

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

Definition at line 10680 of file pg_dump.c.

10681{
10682 Oid roleoid = atooid(roleoid_str);
10683
10684 /*
10685 * Do binary search to find the appropriate item.
10686 */
10687 if (nrolenames > 0)
10688 {
10689 RoleNameItem *low = &rolenames[0];
10690 RoleNameItem *high = &rolenames[nrolenames - 1];
10691
10692 while (low <= high)
10693 {
10694 RoleNameItem *middle = low + (high - low) / 2;
10695
10696 if (roleoid < middle->roleoid)
10697 high = middle - 1;
10698 else if (roleoid > middle->roleoid)
10699 low = middle + 1;
10700 else
10701 return middle->rolename; /* found a match */
10702 }
10703 }
10704
10705 pg_fatal("role with OID %u does not exist", roleoid);
10706 return NULL; /* keep compiler quiet */
10707}

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

2818{
2819 TableInfo *parentTbinfo;
2820
2821 Assert(tbinfo->ispartition);
2822 Assert(tbinfo->numParents == 1);
2823
2824 parentTbinfo = tbinfo->parents[0];
2825 while (parentTbinfo->ispartition)
2826 {
2827 Assert(parentTbinfo->numParents == 1);
2828 parentTbinfo = parentTbinfo->parents[0];
2829 }
2830
2831 return parentTbinfo;
2832}

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

Referenced by dumpTableData(), and dumpTableData_insert().

◆ getRules()

void getRules ( Archive fout)

Definition at line 8585 of file pg_dump.c.

8586{
8587 PGresult *res;
8588 int ntups;
8589 int i;
8591 RuleInfo *ruleinfo;
8592 int i_tableoid;
8593 int i_oid;
8594 int i_rulename;
8595 int i_ruletable;
8596 int i_ev_type;
8597 int i_is_instead;
8598 int i_ev_enabled;
8599
8600 appendPQExpBufferStr(query, "SELECT "
8601 "tableoid, oid, rulename, "
8602 "ev_class AS ruletable, ev_type, is_instead, "
8603 "ev_enabled "
8604 "FROM pg_rewrite "
8605 "ORDER BY oid");
8606
8607 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8608
8609 ntups = PQntuples(res);
8610
8611 ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8612
8613 i_tableoid = PQfnumber(res, "tableoid");
8614 i_oid = PQfnumber(res, "oid");
8615 i_rulename = PQfnumber(res, "rulename");
8616 i_ruletable = PQfnumber(res, "ruletable");
8617 i_ev_type = PQfnumber(res, "ev_type");
8618 i_is_instead = PQfnumber(res, "is_instead");
8619 i_ev_enabled = PQfnumber(res, "ev_enabled");
8620
8621 for (i = 0; i < ntups; i++)
8622 {
8623 Oid ruletableoid;
8624
8625 ruleinfo[i].dobj.objType = DO_RULE;
8626 ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8627 ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8628 AssignDumpId(&ruleinfo[i].dobj);
8629 ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8630 ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8631 ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8632 if (ruleinfo[i].ruletable == NULL)
8633 pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8634 ruletableoid, ruleinfo[i].dobj.catId.oid);
8635 ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8636 ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8637 ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8638 ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8639 ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8640 if (ruleinfo[i].ruletable)
8641 {
8642 /*
8643 * If the table is a view or materialized view, force its ON
8644 * SELECT rule to be sorted before the view itself --- this
8645 * ensures that any dependencies for the rule affect the table's
8646 * positioning. Other rules are forced to appear after their
8647 * table.
8648 */
8649 if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8650 ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8651 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8652 {
8653 addObjectDependency(&ruleinfo[i].ruletable->dobj,
8654 ruleinfo[i].dobj.dumpId);
8655 /* We'll merge the rule into CREATE VIEW, if possible */
8656 ruleinfo[i].separate = false;
8657 }
8658 else
8659 {
8660 addObjectDependency(&ruleinfo[i].dobj,
8661 ruleinfo[i].ruletable->dobj.dumpId);
8662 ruleinfo[i].separate = true;
8663 }
8664 }
8665 else
8666 ruleinfo[i].separate = true;
8667 }
8668
8669 PQclear(res);
8670
8671 destroyPQExpBuffer(query);
8672}

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, _ruleInfo::ruletable, _ruleInfo::separate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSubscriptionRelations()

void getSubscriptionRelations ( Archive fout)

Definition at line 5327 of file pg_dump.c.

5328{
5329 DumpOptions *dopt = fout->dopt;
5330 SubscriptionInfo *subinfo = NULL;
5331 SubRelInfo *subrinfo;
5332 PGresult *res;
5333 int i_srsubid;
5334 int i_srrelid;
5335 int i_srsubstate;
5336 int i_srsublsn;
5337 int ntups;
5338 Oid last_srsubid = InvalidOid;
5339
5340 if (dopt->no_subscriptions || !dopt->binary_upgrade ||
5341 fout->remoteVersion < 170000)
5342 return;
5343
5344 res = ExecuteSqlQuery(fout,
5345 "SELECT srsubid, srrelid, srsubstate, srsublsn "
5346 "FROM pg_catalog.pg_subscription_rel "
5347 "ORDER BY srsubid",
5349 ntups = PQntuples(res);
5350 if (ntups == 0)
5351 goto cleanup;
5352
5353 /* Get pg_subscription_rel attributes */
5354 i_srsubid = PQfnumber(res, "srsubid");
5355 i_srrelid = PQfnumber(res, "srrelid");
5356 i_srsubstate = PQfnumber(res, "srsubstate");
5357 i_srsublsn = PQfnumber(res, "srsublsn");
5358
5359 subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
5360 for (int i = 0; i < ntups; i++)
5361 {
5362 Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
5363 Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
5364 TableInfo *tblinfo;
5365
5366 /*
5367 * If we switched to a new subscription, check if the subscription
5368 * exists.
5369 */
5370 if (cur_srsubid != last_srsubid)
5371 {
5372 subinfo = findSubscriptionByOid(cur_srsubid);
5373 if (subinfo == NULL)
5374 pg_fatal("subscription with OID %u does not exist", cur_srsubid);
5375
5376 last_srsubid = cur_srsubid;
5377 }
5378
5379 tblinfo = findTableByOid(relid);
5380 if (tblinfo == NULL)
5381 pg_fatal("failed sanity check, relation with OID %u not found",
5382 relid);
5383
5384 /* OK, make a DumpableObject for this relationship */
5385 subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
5386 subrinfo[i].dobj.catId.tableoid = relid;
5387 subrinfo[i].dobj.catId.oid = cur_srsubid;
5388 AssignDumpId(&subrinfo[i].dobj);
5389 subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
5390 subrinfo[i].tblinfo = tblinfo;
5391 subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
5392 if (PQgetisnull(res, i, i_srsublsn))
5393 subrinfo[i].srsublsn = NULL;
5394 else
5395 subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
5396
5397 subrinfo[i].subinfo = subinfo;
5398
5399 /* Decide whether we want to dump it */
5400 selectDumpableObject(&(subrinfo[i].dobj), fout);
5401 }
5402
5403cleanup:
5404 PQclear(res);
5405}
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:1044
int no_subscriptions
Definition: pg_backup.h:190

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, selectDumpableObject(), _SubRelInfo::srsublsn, _SubRelInfo::srsubstate, _SubRelInfo::subinfo, CatalogId::tableoid, and _SubRelInfo::tblinfo.

Referenced by getSchemaData().

◆ getSubscriptions()

void getSubscriptions ( Archive fout)

Definition at line 5107 of file pg_dump.c.

5108{
5109 DumpOptions *dopt = fout->dopt;
5110 PQExpBuffer query;
5111 PGresult *res;
5112 SubscriptionInfo *subinfo;
5113 int i_tableoid;
5114 int i_oid;
5115 int i_subname;
5116 int i_subowner;
5117 int i_subbinary;
5118 int i_substream;
5119 int i_subtwophasestate;
5120 int i_subdisableonerr;
5121 int i_subpasswordrequired;
5122 int i_subrunasowner;
5123 int i_subconninfo;
5124 int i_subslotname;
5125 int i_subsynccommit;
5126 int i_subpublications;
5127 int i_suborigin;
5128 int i_suboriginremotelsn;
5129 int i_subenabled;
5130 int i_subfailover;
5131 int i_subretaindeadtuples;
5132 int i_submaxretention;
5133 int i,
5134 ntups;
5135
5136 if (dopt->no_subscriptions || fout->remoteVersion < 100000)
5137 return;
5138
5139 if (!is_superuser(fout))
5140 {
5141 int n;
5142
5143 res = ExecuteSqlQuery(fout,
5144 "SELECT count(*) FROM pg_subscription "
5145 "WHERE subdbid = (SELECT oid FROM pg_database"
5146 " WHERE datname = current_database())",
5148 n = atoi(PQgetvalue(res, 0, 0));
5149 if (n > 0)
5150 pg_log_warning("subscriptions not dumped because current user is not a superuser");
5151 PQclear(res);
5152 return;
5153 }
5154
5155 query = createPQExpBuffer();
5156
5157 /* Get the subscriptions in current database. */
5159 "SELECT s.tableoid, s.oid, s.subname,\n"
5160 " s.subowner,\n"
5161 " s.subconninfo, s.subslotname, s.subsynccommit,\n"
5162 " s.subpublications,\n");
5163
5164 if (fout->remoteVersion >= 140000)
5165 appendPQExpBufferStr(query, " s.subbinary,\n");
5166 else
5167 appendPQExpBufferStr(query, " false AS subbinary,\n");
5168
5169 if (fout->remoteVersion >= 140000)
5170 appendPQExpBufferStr(query, " s.substream,\n");
5171 else
5172 appendPQExpBufferStr(query, " 'f' AS substream,\n");
5173
5174 if (fout->remoteVersion >= 150000)
5176 " s.subtwophasestate,\n"
5177 " s.subdisableonerr,\n");
5178 else
5179 appendPQExpBuffer(query,
5180 " '%c' AS subtwophasestate,\n"
5181 " false AS subdisableonerr,\n",
5182 LOGICALREP_TWOPHASE_STATE_DISABLED);
5183
5184 if (fout->remoteVersion >= 160000)
5186 " s.subpasswordrequired,\n"
5187 " s.subrunasowner,\n"
5188 " s.suborigin,\n");
5189 else
5190 appendPQExpBuffer(query,
5191 " 't' AS subpasswordrequired,\n"
5192 " 't' AS subrunasowner,\n"
5193 " '%s' AS suborigin,\n",
5194 LOGICALREP_ORIGIN_ANY);
5195
5196 if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5197 appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
5198 " s.subenabled,\n");
5199 else
5200 appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
5201 " false AS subenabled,\n");
5202
5203 if (fout->remoteVersion >= 170000)
5205 " s.subfailover,\n");
5206 else
5208 " false AS subfailover,\n");
5209
5210 if (fout->remoteVersion >= 190000)
5212 " s.subretaindeadtuples,\n");
5213 else
5215 " false AS subretaindeadtuples,\n");
5216
5217 if (fout->remoteVersion >= 190000)
5219 " s.submaxretention\n");
5220 else
5221 appendPQExpBuffer(query,
5222 " 0 AS submaxretention\n");
5223
5225 "FROM pg_subscription s\n");
5226
5227 if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5229 "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
5230 " ON o.external_id = 'pg_' || s.oid::text \n");
5231
5233 "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
5234 " WHERE datname = current_database())");
5235
5236 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5237
5238 ntups = PQntuples(res);
5239
5240 /*
5241 * Get subscription fields. We don't include subskiplsn in the dump as
5242 * after restoring the dump this value may no longer be relevant.
5243 */
5244 i_tableoid = PQfnumber(res, "tableoid");
5245 i_oid = PQfnumber(res, "oid");
5246 i_subname = PQfnumber(res, "subname");
5247 i_subowner = PQfnumber(res, "subowner");
5248 i_subenabled = PQfnumber(res, "subenabled");
5249 i_subbinary = PQfnumber(res, "subbinary");
5250 i_substream = PQfnumber(res, "substream");
5251 i_subtwophasestate = PQfnumber(res, "subtwophasestate");
5252 i_subdisableonerr = PQfnumber(res, "subdisableonerr");
5253 i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
5254 i_subrunasowner = PQfnumber(res, "subrunasowner");
5255 i_subfailover = PQfnumber(res, "subfailover");
5256 i_subretaindeadtuples = PQfnumber(res, "subretaindeadtuples");
5257 i_submaxretention = PQfnumber(res, "submaxretention");
5258 i_subconninfo = PQfnumber(res, "subconninfo");
5259 i_subslotname = PQfnumber(res, "subslotname");
5260 i_subsynccommit = PQfnumber(res, "subsynccommit");
5261 i_subpublications = PQfnumber(res, "subpublications");
5262 i_suborigin = PQfnumber(res, "suborigin");
5263 i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
5264
5265 subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
5266
5267 for (i = 0; i < ntups; i++)
5268 {
5269 subinfo[i].dobj.objType = DO_SUBSCRIPTION;
5270 subinfo[i].dobj.catId.tableoid =
5271 atooid(PQgetvalue(res, i, i_tableoid));
5272 subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5273 AssignDumpId(&subinfo[i].dobj);
5274 subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
5275 subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
5276
5277 subinfo[i].subenabled =
5278 (strcmp(PQgetvalue(res, i, i_subenabled), "t") == 0);
5279 subinfo[i].subbinary =
5280 (strcmp(PQgetvalue(res, i, i_subbinary), "t") == 0);
5281 subinfo[i].substream = *(PQgetvalue(res, i, i_substream));
5282 subinfo[i].subtwophasestate = *(PQgetvalue(res, i, i_subtwophasestate));
5283 subinfo[i].subdisableonerr =
5284 (strcmp(PQgetvalue(res, i, i_subdisableonerr), "t") == 0);
5285 subinfo[i].subpasswordrequired =
5286 (strcmp(PQgetvalue(res, i, i_subpasswordrequired), "t") == 0);
5287 subinfo[i].subrunasowner =
5288 (strcmp(PQgetvalue(res, i, i_subrunasowner), "t") == 0);
5289 subinfo[i].subfailover =
5290 (strcmp(PQgetvalue(res, i, i_subfailover), "t") == 0);
5291 subinfo[i].subretaindeadtuples =
5292 (strcmp(PQgetvalue(res, i, i_subretaindeadtuples), "t") == 0);
5293 subinfo[i].submaxretention =
5294 atoi(PQgetvalue(res, i, i_submaxretention));
5295 subinfo[i].subconninfo =
5296 pg_strdup(PQgetvalue(res, i, i_subconninfo));
5297 if (PQgetisnull(res, i, i_subslotname))
5298 subinfo[i].subslotname = NULL;
5299 else
5300 subinfo[i].subslotname =
5301 pg_strdup(PQgetvalue(res, i, i_subslotname));
5302 subinfo[i].subsynccommit =
5303 pg_strdup(PQgetvalue(res, i, i_subsynccommit));
5304 subinfo[i].subpublications =
5305 pg_strdup(PQgetvalue(res, i, i_subpublications));
5306 subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
5307 if (PQgetisnull(res, i, i_suboriginremotelsn))
5308 subinfo[i].suboriginremotelsn = NULL;
5309 else
5310 subinfo[i].suboriginremotelsn =
5311 pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
5312
5313 /* Decide whether we want to dump it */
5314 selectDumpableObject(&(subinfo[i].dobj), fout);
5315 }
5316 PQclear(res);
5317
5318 destroyPQExpBuffer(query);
5319}
static bool is_superuser(Archive *fout)
Definition: pg_dump.c:5067

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(), _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, _SubscriptionInfo::rolname, selectDumpableObject(), _SubscriptionInfo::subbinary, _SubscriptionInfo::subconninfo, _SubscriptionInfo::subdisableonerr, _SubscriptionInfo::subenabled, _SubscriptionInfo::subfailover, _SubscriptionInfo::submaxretention, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subretaindeadtuples, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, _SubscriptionInfo::subtwophasestate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTableAttrs()

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

Definition at line 9234 of file pg_dump.c.

9235{
9236 DumpOptions *dopt = fout->dopt;
9238 PQExpBuffer tbloids = createPQExpBuffer();
9239 PQExpBuffer checkoids = createPQExpBuffer();
9240 PQExpBuffer invalidnotnulloids = NULL;
9241 PGresult *res;
9242 int ntups;
9243 int curtblindx;
9244 int i_attrelid;
9245 int i_attnum;
9246 int i_attname;
9247 int i_atttypname;
9248 int i_attstattarget;
9249 int i_attstorage;
9250 int i_typstorage;
9251 int i_attidentity;
9252 int i_attgenerated;
9253 int i_attisdropped;
9254 int i_attlen;
9255 int i_attalign;
9256 int i_attislocal;
9257 int i_notnull_name;
9258 int i_notnull_comment;
9259 int i_notnull_noinherit;
9260 int i_notnull_islocal;
9261 int i_notnull_invalidoid;
9262 int i_attoptions;
9263 int i_attcollation;
9264 int i_attcompression;
9265 int i_attfdwoptions;
9266 int i_attmissingval;
9267 int i_atthasdef;
9268
9269 /*
9270 * We want to perform just one query against pg_attribute, and then just
9271 * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
9272 * (for CHECK constraints and for NOT NULL constraints). However, we
9273 * mustn't try to select every row of those catalogs and then sort it out
9274 * on the client side, because some of the server-side functions we need
9275 * would be unsafe to apply to tables we don't have lock on. Hence, we
9276 * build an array of the OIDs of tables we care about (and now have lock
9277 * on!), and use a WHERE clause to constrain which rows are selected.
9278 */
9279 appendPQExpBufferChar(tbloids, '{');
9280 appendPQExpBufferChar(checkoids, '{');
9281 for (int i = 0; i < numTables; i++)
9282 {
9283 TableInfo *tbinfo = &tblinfo[i];
9284
9285 /* Don't bother to collect info for sequences */
9286 if (tbinfo->relkind == RELKIND_SEQUENCE)
9287 continue;
9288
9289 /*
9290 * Don't bother with uninteresting tables, either. For binary
9291 * upgrades, this is bypassed for pg_largeobject_metadata and
9292 * pg_shdepend so that the columns names are collected for the
9293 * corresponding COPY commands. Restoring the data for those catalogs
9294 * is faster than restoring the equivalent set of large object
9295 * commands. We can only do this for upgrades from v12 and newer; in
9296 * older versions, pg_largeobject_metadata was created WITH OIDS, so
9297 * the OID column is hidden and won't be dumped.
9298 */
9299 if (!tbinfo->interesting &&
9300 !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 &&
9301 (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId ||
9302 tbinfo->dobj.catId.oid == SharedDependRelationId)))
9303 continue;
9304
9305 /* OK, we need info for this table */
9306 if (tbloids->len > 1) /* do we have more than the '{'? */
9307 appendPQExpBufferChar(tbloids, ',');
9308 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9309
9310 if (tbinfo->ncheck > 0)
9311 {
9312 /* Also make a list of the ones with check constraints */
9313 if (checkoids->len > 1) /* do we have more than the '{'? */
9314 appendPQExpBufferChar(checkoids, ',');
9315 appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
9316 }
9317 }
9318 appendPQExpBufferChar(tbloids, '}');
9319 appendPQExpBufferChar(checkoids, '}');
9320
9321 /*
9322 * Find all the user attributes and their types.
9323 *
9324 * Since we only want to dump COLLATE clauses for attributes whose
9325 * collation is different from their type's default, we use a CASE here to
9326 * suppress uninteresting attcollations cheaply.
9327 */
9329 "SELECT\n"
9330 "a.attrelid,\n"
9331 "a.attnum,\n"
9332 "a.attname,\n"
9333 "a.attstattarget,\n"
9334 "a.attstorage,\n"
9335 "t.typstorage,\n"
9336 "a.atthasdef,\n"
9337 "a.attisdropped,\n"
9338 "a.attlen,\n"
9339 "a.attalign,\n"
9340 "a.attislocal,\n"
9341 "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
9342 "array_to_string(a.attoptions, ', ') AS attoptions,\n"
9343 "CASE WHEN a.attcollation <> t.typcollation "
9344 "THEN a.attcollation ELSE 0 END AS attcollation,\n"
9345 "pg_catalog.array_to_string(ARRAY("
9346 "SELECT pg_catalog.quote_ident(option_name) || "
9347 "' ' || pg_catalog.quote_literal(option_value) "
9348 "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
9349 "ORDER BY option_name"
9350 "), E',\n ') AS attfdwoptions,\n");
9351
9352 /*
9353 * Find out any NOT NULL markings for each column. In 18 and up we read
9354 * pg_constraint to obtain the constraint name, and for valid constraints
9355 * also pg_description to obtain its comment. notnull_noinherit is set
9356 * according to the NO INHERIT property. For versions prior to 18, we
9357 * store an empty string as the name when a constraint is marked as
9358 * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
9359 * without a name); also, such cases are never NO INHERIT.
9360 *
9361 * For invalid constraints, we need to store their OIDs for processing
9362 * elsewhere, so we bring the pg_constraint.oid value when the constraint
9363 * is invalid, and NULL otherwise. Their comments are handled not here
9364 * but by collectComments, because they're their own dumpable object.
9365 *
9366 * We track in notnull_islocal whether the constraint was defined directly
9367 * in this table or via an ancestor, for binary upgrade. flagInhAttrs
9368 * might modify this later.
9369 */
9370 if (fout->remoteVersion >= 180000)
9372 "co.conname AS notnull_name,\n"
9373 "CASE WHEN co.convalidated THEN pt.description"
9374 " ELSE NULL END AS notnull_comment,\n"
9375 "CASE WHEN NOT co.convalidated THEN co.oid "
9376 "ELSE NULL END AS notnull_invalidoid,\n"
9377 "co.connoinherit AS notnull_noinherit,\n"
9378 "co.conislocal AS notnull_islocal,\n");
9379 else
9381 "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
9382 "NULL AS notnull_comment,\n"
9383 "NULL AS notnull_invalidoid,\n"
9384 "false AS notnull_noinherit,\n"
9385 "CASE WHEN a.attislocal THEN true\n"
9386 " WHEN a.attnotnull AND NOT a.attislocal THEN true\n"
9387 " ELSE false\n"
9388 "END AS notnull_islocal,\n");
9389
9390 if (fout->remoteVersion >= 140000)
9392 "a.attcompression AS attcompression,\n");
9393 else
9395 "'' AS attcompression,\n");
9396
9397 if (fout->remoteVersion >= 100000)
9399 "a.attidentity,\n");
9400 else
9402 "'' AS attidentity,\n");
9403
9404 if (fout->remoteVersion >= 110000)
9406 "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
9407 "THEN a.attmissingval ELSE null END AS attmissingval,\n");
9408 else
9410 "NULL AS attmissingval,\n");
9411
9412 if (fout->remoteVersion >= 120000)
9414 "a.attgenerated\n");
9415 else
9417 "'' AS attgenerated\n");
9418
9419 /* need left join to pg_type to not fail on dropped columns ... */
9421 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9422 "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
9423 "LEFT JOIN pg_catalog.pg_type t "
9424 "ON (a.atttypid = t.oid)\n",
9425 tbloids->data);
9426
9427 /*
9428 * In versions 18 and up, we need pg_constraint for explicit NOT NULL
9429 * entries and pg_description to get their comments.
9430 */
9431 if (fout->remoteVersion >= 180000)
9433 " LEFT JOIN pg_catalog.pg_constraint co ON "
9434 "(a.attrelid = co.conrelid\n"
9435 " AND co.contype = 'n' AND "
9436 "co.conkey = array[a.attnum])\n"
9437 " LEFT JOIN pg_catalog.pg_description pt ON "
9438 "(pt.classoid = co.tableoid AND pt.objoid = co.oid)\n");
9439
9441 "WHERE a.attnum > 0::pg_catalog.int2\n"
9442 "ORDER BY a.attrelid, a.attnum");
9443
9444 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9445
9446 ntups = PQntuples(res);
9447
9448 i_attrelid = PQfnumber(res, "attrelid");
9449 i_attnum = PQfnumber(res, "attnum");
9450 i_attname = PQfnumber(res, "attname");
9451 i_atttypname = PQfnumber(res, "atttypname");
9452 i_attstattarget = PQfnumber(res, "attstattarget");
9453 i_attstorage = PQfnumber(res, "attstorage");
9454 i_typstorage = PQfnumber(res, "typstorage");
9455 i_attidentity = PQfnumber(res, "attidentity");
9456 i_attgenerated = PQfnumber(res, "attgenerated");
9457 i_attisdropped = PQfnumber(res, "attisdropped");
9458 i_attlen = PQfnumber(res, "attlen");
9459 i_attalign = PQfnumber(res, "attalign");
9460 i_attislocal = PQfnumber(res, "attislocal");
9461 i_notnull_name = PQfnumber(res, "notnull_name");
9462 i_notnull_comment = PQfnumber(res, "notnull_comment");
9463 i_notnull_invalidoid = PQfnumber(res, "notnull_invalidoid");
9464 i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
9465 i_notnull_islocal = PQfnumber(res, "notnull_islocal");
9466 i_attoptions = PQfnumber(res, "attoptions");
9467 i_attcollation = PQfnumber(res, "attcollation");
9468 i_attcompression = PQfnumber(res, "attcompression");
9469 i_attfdwoptions = PQfnumber(res, "attfdwoptions");
9470 i_attmissingval = PQfnumber(res, "attmissingval");
9471 i_atthasdef = PQfnumber(res, "atthasdef");
9472
9473 /* Within the next loop, we'll accumulate OIDs of tables with defaults */
9474 resetPQExpBuffer(tbloids);
9475 appendPQExpBufferChar(tbloids, '{');
9476
9477 /*
9478 * Outer loop iterates once per table, not once per row. Incrementing of
9479 * r is handled by the inner loop.
9480 */
9481 curtblindx = -1;
9482 for (int r = 0; r < ntups;)
9483 {
9484 Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
9485 TableInfo *tbinfo = NULL;
9486 int numatts;
9487 bool hasdefaults;
9488
9489 /* Count rows for this table */
9490 for (numatts = 1; numatts < ntups - r; numatts++)
9491 if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
9492 break;
9493
9494 /*
9495 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
9496 * order.
9497 */
9498 while (++curtblindx < numTables)
9499 {
9500 tbinfo = &tblinfo[curtblindx];
9501 if (tbinfo->dobj.catId.oid == attrelid)
9502 break;
9503 }
9504 if (curtblindx >= numTables)
9505 pg_fatal("unrecognized table OID %u", attrelid);
9506 /* cross-check that we only got requested tables */
9507 if (tbinfo->relkind == RELKIND_SEQUENCE ||
9508 (!tbinfo->interesting &&
9509 !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 &&
9510 (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId ||
9511 tbinfo->dobj.catId.oid == SharedDependRelationId))))
9512 pg_fatal("unexpected column data for table \"%s\"",
9513 tbinfo->dobj.name);
9514
9515 /* Save data for this table */
9516 tbinfo->numatts = numatts;
9517 tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
9518 tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
9519 tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
9520 tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
9521 tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
9522 tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
9523 tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
9524 tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
9525 tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
9526 tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
9527 tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
9528 tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
9529 tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
9530 tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
9531 tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
9532 tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
9533 tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
9534 tbinfo->notnull_comment = (char **) pg_malloc(numatts * sizeof(char *));
9535 tbinfo->notnull_invalid = (bool *) pg_malloc(numatts * sizeof(bool));
9536 tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
9537 tbinfo->notnull_islocal = (bool *) pg_malloc(numatts * sizeof(bool));
9538 tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
9539 hasdefaults = false;
9540
9541 for (int j = 0; j < numatts; j++, r++)
9542 {
9543 if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
9544 pg_fatal("invalid column numbering in table \"%s\"",
9545 tbinfo->dobj.name);
9546 tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
9547 tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
9548 if (PQgetisnull(res, r, i_attstattarget))
9549 tbinfo->attstattarget[j] = -1;
9550 else
9551 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
9552 tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
9553 tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
9554 tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
9555 tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
9556 tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
9557 tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
9558 tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
9559 tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
9560 tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
9561
9562 /* Handle not-null constraint name and flags */
9563 determineNotNullFlags(fout, res, r,
9564 tbinfo, j,
9565 i_notnull_name,
9566 i_notnull_comment,
9567 i_notnull_invalidoid,
9568 i_notnull_noinherit,
9569 i_notnull_islocal,
9570 &invalidnotnulloids);
9571
9572 tbinfo->notnull_comment[j] = PQgetisnull(res, r, i_notnull_comment) ?
9573 NULL : pg_strdup(PQgetvalue(res, r, i_notnull_comment));
9574 tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
9575 tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
9576 tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
9577 tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
9578 tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
9579 tbinfo->attrdefs[j] = NULL; /* fix below */
9580 if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
9581 hasdefaults = true;
9582 }
9583
9584 if (hasdefaults)
9585 {
9586 /* Collect OIDs of interesting tables that have defaults */
9587 if (tbloids->len > 1) /* do we have more than the '{'? */
9588 appendPQExpBufferChar(tbloids, ',');
9589 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9590 }
9591 }
9592
9593 /* If invalidnotnulloids has any data, finalize it */
9594 if (invalidnotnulloids != NULL)
9595 appendPQExpBufferChar(invalidnotnulloids, '}');
9596
9597 PQclear(res);
9598
9599 /*
9600 * Now get info about column defaults. This is skipped for a data-only
9601 * dump, as it is only needed for table schemas.
9602 */
9603 if (dopt->dumpSchema && tbloids->len > 1)
9604 {
9605 AttrDefInfo *attrdefs;
9606 int numDefaults;
9607 TableInfo *tbinfo = NULL;
9608
9609 pg_log_info("finding table default expressions");
9610
9611 appendPQExpBufferChar(tbloids, '}');
9612
9613 printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9614 "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9615 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9616 "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9617 "ORDER BY a.adrelid, a.adnum",
9618 tbloids->data);
9619
9620 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9621
9622 numDefaults = PQntuples(res);
9623 attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9624
9625 curtblindx = -1;
9626 for (int j = 0; j < numDefaults; j++)
9627 {
9628 Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9629 Oid adoid = atooid(PQgetvalue(res, j, 1));
9630 Oid adrelid = atooid(PQgetvalue(res, j, 2));
9631 int adnum = atoi(PQgetvalue(res, j, 3));
9632 char *adsrc = PQgetvalue(res, j, 4);
9633
9634 /*
9635 * Locate the associated TableInfo; we rely on tblinfo[] being in
9636 * OID order.
9637 */
9638 if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9639 {
9640 while (++curtblindx < numTables)
9641 {
9642 tbinfo = &tblinfo[curtblindx];
9643 if (tbinfo->dobj.catId.oid == adrelid)
9644 break;
9645 }
9646 if (curtblindx >= numTables)
9647 pg_fatal("unrecognized table OID %u", adrelid);
9648 }
9649
9650 if (adnum <= 0 || adnum > tbinfo->numatts)
9651 pg_fatal("invalid adnum value %d for table \"%s\"",
9652 adnum, tbinfo->dobj.name);
9653
9654 /*
9655 * dropped columns shouldn't have defaults, but just in case,
9656 * ignore 'em
9657 */
9658 if (tbinfo->attisdropped[adnum - 1])
9659 continue;
9660
9661 attrdefs[j].dobj.objType = DO_ATTRDEF;
9662 attrdefs[j].dobj.catId.tableoid = adtableoid;
9663 attrdefs[j].dobj.catId.oid = adoid;
9664 AssignDumpId(&attrdefs[j].dobj);
9665 attrdefs[j].adtable = tbinfo;
9666 attrdefs[j].adnum = adnum;
9667 attrdefs[j].adef_expr = pg_strdup(adsrc);
9668
9669 attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9670 attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9671
9672 attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9673
9674 /*
9675 * Figure out whether the default/generation expression should be
9676 * dumped as part of the main CREATE TABLE (or similar) command or
9677 * as a separate ALTER TABLE (or similar) command. The preference
9678 * is to put it into the CREATE command, but in some cases that's
9679 * not possible.
9680 */
9681 if (tbinfo->attgenerated[adnum - 1])
9682 {
9683 /*
9684 * Column generation expressions cannot be dumped separately,
9685 * because there is no syntax for it. By setting separate to
9686 * false here we prevent the "default" from being processed as
9687 * its own dumpable object. Later, flagInhAttrs() will mark
9688 * it as not to be dumped at all, if possible (that is, if it
9689 * can be inherited from a parent).
9690 */
9691 attrdefs[j].separate = false;
9692 }
9693 else if (tbinfo->relkind == RELKIND_VIEW)
9694 {
9695 /*
9696 * Defaults on a VIEW must always be dumped as separate ALTER
9697 * TABLE commands.
9698 */
9699 attrdefs[j].separate = true;
9700 }
9701 else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9702 {
9703 /* column will be suppressed, print default separately */
9704 attrdefs[j].separate = true;
9705 }
9706 else
9707 {
9708 attrdefs[j].separate = false;
9709 }
9710
9711 if (!attrdefs[j].separate)
9712 {
9713 /*
9714 * Mark the default as needing to appear before the table, so
9715 * that any dependencies it has must be emitted before the
9716 * CREATE TABLE. If this is not possible, we'll change to
9717 * "separate" mode while sorting dependencies.
9718 */
9719 addObjectDependency(&tbinfo->dobj,
9720 attrdefs[j].dobj.dumpId);
9721 }
9722
9723 tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9724 }
9725
9726 PQclear(res);
9727 }
9728
9729 /*
9730 * Get info about NOT NULL NOT VALID constraints. This is skipped for a
9731 * data-only dump, as it is only needed for table schemas.
9732 */
9733 if (dopt->dumpSchema && invalidnotnulloids)
9734 {
9735 ConstraintInfo *constrs;
9736 int numConstrs;
9737 int i_tableoid;
9738 int i_oid;
9739 int i_conrelid;
9740 int i_conname;
9741 int i_consrc;
9742 int i_conislocal;
9743
9744 pg_log_info("finding invalid not-null constraints");
9745
9748 "SELECT c.tableoid, c.oid, conrelid, conname, "
9749 "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9750 "conislocal, convalidated "
9751 "FROM unnest('%s'::pg_catalog.oid[]) AS src(conoid)\n"
9752 "JOIN pg_catalog.pg_constraint c ON (src.conoid = c.oid)\n"
9753 "ORDER BY c.conrelid, c.conname",
9754 invalidnotnulloids->data);
9755
9756 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9757
9758 numConstrs = PQntuples(res);
9759 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9760
9761 i_tableoid = PQfnumber(res, "tableoid");
9762 i_oid = PQfnumber(res, "oid");
9763 i_conrelid = PQfnumber(res, "conrelid");
9764 i_conname = PQfnumber(res, "conname");
9765 i_consrc = PQfnumber(res, "consrc");
9766 i_conislocal = PQfnumber(res, "conislocal");
9767
9768 /* As above, this loop iterates once per table, not once per row */
9769 curtblindx = -1;
9770 for (int j = 0; j < numConstrs;)
9771 {
9772 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9773 TableInfo *tbinfo = NULL;
9774 int numcons;
9775
9776 /* Count rows for this table */
9777 for (numcons = 1; numcons < numConstrs - j; numcons++)
9778 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9779 break;
9780
9781 /*
9782 * Locate the associated TableInfo; we rely on tblinfo[] being in
9783 * OID order.
9784 */
9785 while (++curtblindx < numTables)
9786 {
9787 tbinfo = &tblinfo[curtblindx];
9788 if (tbinfo->dobj.catId.oid == conrelid)
9789 break;
9790 }
9791 if (curtblindx >= numTables)
9792 pg_fatal("unrecognized table OID %u", conrelid);
9793
9794 for (int c = 0; c < numcons; c++, j++)
9795 {
9796 constrs[j].dobj.objType = DO_CONSTRAINT;
9797 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9798 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9799 AssignDumpId(&constrs[j].dobj);
9800 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9801 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9802 constrs[j].contable = tbinfo;
9803 constrs[j].condomain = NULL;
9804 constrs[j].contype = 'n';
9805 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9806 constrs[j].confrelid = InvalidOid;
9807 constrs[j].conindex = 0;
9808 constrs[j].condeferrable = false;
9809 constrs[j].condeferred = false;
9810 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9811
9812 /*
9813 * All invalid not-null constraints must be dumped separately,
9814 * because CREATE TABLE would not create them as invalid, and
9815 * also because they must be created after potentially
9816 * violating data has been loaded.
9817 */
9818 constrs[j].separate = true;
9819
9820 constrs[j].dobj.dump = tbinfo->dobj.dump;
9821 }
9822 }
9823 PQclear(res);
9824 }
9825
9826 /*
9827 * Get info about table CHECK constraints. This is skipped for a
9828 * data-only dump, as it is only needed for table schemas.
9829 */
9830 if (dopt->dumpSchema && checkoids->len > 2)
9831 {
9832 ConstraintInfo *constrs;
9833 int numConstrs;
9834 int i_tableoid;
9835 int i_oid;
9836 int i_conrelid;
9837 int i_conname;
9838 int i_consrc;
9839 int i_conislocal;
9840 int i_convalidated;
9841
9842 pg_log_info("finding table check constraints");
9843
9846 "SELECT c.tableoid, c.oid, conrelid, conname, "
9847 "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9848 "conislocal, convalidated "
9849 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9850 "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9851 "WHERE contype = 'c' "
9852 "ORDER BY c.conrelid, c.conname",
9853 checkoids->data);
9854
9855 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9856
9857 numConstrs = PQntuples(res);
9858 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9859
9860 i_tableoid = PQfnumber(res, "tableoid");
9861 i_oid = PQfnumber(res, "oid");
9862 i_conrelid = PQfnumber(res, "conrelid");
9863 i_conname = PQfnumber(res, "conname");
9864 i_consrc = PQfnumber(res, "consrc");
9865 i_conislocal = PQfnumber(res, "conislocal");
9866 i_convalidated = PQfnumber(res, "convalidated");
9867
9868 /* As above, this loop iterates once per table, not once per row */
9869 curtblindx = -1;
9870 for (int j = 0; j < numConstrs;)
9871 {
9872 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9873 TableInfo *tbinfo = NULL;
9874 int numcons;
9875
9876 /* Count rows for this table */
9877 for (numcons = 1; numcons < numConstrs - j; numcons++)
9878 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9879 break;
9880
9881 /*
9882 * Locate the associated TableInfo; we rely on tblinfo[] being in
9883 * OID order.
9884 */
9885 while (++curtblindx < numTables)
9886 {
9887 tbinfo = &tblinfo[curtblindx];
9888 if (tbinfo->dobj.catId.oid == conrelid)
9889 break;
9890 }
9891 if (curtblindx >= numTables)
9892 pg_fatal("unrecognized table OID %u", conrelid);
9893
9894 if (numcons != tbinfo->ncheck)
9895 {
9896 pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9897 "expected %d check constraints on table \"%s\" but found %d",
9898 tbinfo->ncheck),
9899 tbinfo->ncheck, tbinfo->dobj.name, numcons);
9900 pg_log_error_hint("The system catalogs might be corrupted.");
9901 exit_nicely(1);
9902 }
9903
9904 tbinfo->checkexprs = constrs + j;
9905
9906 for (int c = 0; c < numcons; c++, j++)
9907 {
9908 bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9909
9910 constrs[j].dobj.objType = DO_CONSTRAINT;
9911 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9912 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9913 AssignDumpId(&constrs[j].dobj);
9914 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9915 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9916 constrs[j].contable = tbinfo;
9917 constrs[j].condomain = NULL;
9918 constrs[j].contype = 'c';
9919 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9920 constrs[j].confrelid = InvalidOid;
9921 constrs[j].conindex = 0;
9922 constrs[j].condeferrable = false;
9923 constrs[j].condeferred = false;
9924 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9925
9926 /*
9927 * An unvalidated constraint needs to be dumped separately, so
9928 * that potentially-violating existing data is loaded before
9929 * the constraint.
9930 */
9931 constrs[j].separate = !validated;
9932
9933 constrs[j].dobj.dump = tbinfo->dobj.dump;
9934
9935 /*
9936 * Mark the constraint as needing to appear before the table
9937 * --- this is so that any other dependencies of the
9938 * constraint will be emitted before we try to create the
9939 * table. If the constraint is to be dumped separately, it
9940 * will be dumped after data is loaded anyway, so don't do it.
9941 * (There's an automatic dependency in the opposite direction
9942 * anyway, so don't need to add one manually here.)
9943 */
9944 if (!constrs[j].separate)
9945 addObjectDependency(&tbinfo->dobj,
9946 constrs[j].dobj.dumpId);
9947
9948 /*
9949 * We will detect later whether the constraint must be split
9950 * out from the table definition.
9951 */
9952 }
9953 }
9954
9955 PQclear(res);
9956 }
9957
9959 destroyPQExpBuffer(tbloids);
9960 destroyPQExpBuffer(checkoids);
9961}
#define pg_log_error_hint(...)
Definition: logging.h:112
static void determineNotNullFlags(Archive *fout, PGresult *res, int r, TableInfo *tbinfo, int j, int i_notnull_name, int i_notnull_comment, int i_notnull_invalidoid, int i_notnull_noinherit, int i_notnull_islocal, PQExpBuffer *invalidnotnulloids)
Definition: pg_dump.c:10011

References addObjectDependency(), _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attcompression, _tableInfo::attfdwoptions, _tableInfo::attgenerated, _tableInfo::attidentity, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attmissingval, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypnames, _dumpOptions::binary_upgrade, _dumpableObject::catId, _tableInfo::checkexprs, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), determineNotNullFlags(), DO_ATTRDEF, DO_CONSTRAINT, _tableInfo::dobj, _attrDefInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, _dumpableObject::dumpId, _dumpOptions::dumpSchema, ExecuteSqlQuery(), exit_nicely(), i, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull_comment, _tableInfo::notnull_constrs, _tableInfo::notnull_invalid, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, _tableInfo::numatts, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, 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 3020 of file pg_dump.c.

3021{
3022 int i;
3023
3024 for (i = 0; i < numTables; i++)
3025 {
3026 if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
3027 (!relkind || tblinfo[i].relkind == relkind))
3028 makeTableDataInfo(dopt, &(tblinfo[i]));
3029 }
3030}
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:3039

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

Referenced by main().

◆ getTableDataFKConstraints()

static void getTableDataFKConstraints ( void  )
static

Definition at line 3241 of file pg_dump.c.

3242{
3243 DumpableObject **dobjs;
3244 int numObjs;
3245 int i;
3246
3247 /* Search through all the dumpable objects for FK constraints */
3248 getDumpableObjects(&dobjs, &numObjs);
3249 for (i = 0; i < numObjs; i++)
3250 {
3251 if (dobjs[i]->objType == DO_FK_CONSTRAINT)
3252 {
3253 ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
3254 TableInfo *ftable;
3255
3256 /* Not interesting unless both tables are to be dumped */
3257 if (cinfo->contable == NULL ||
3258 cinfo->contable->dataObj == NULL)
3259 continue;
3260 ftable = findTableByOid(cinfo->confrelid);
3261 if (ftable == NULL ||
3262 ftable->dataObj == NULL)
3263 continue;
3264
3265 /*
3266 * Okay, make referencing table's TABLE_DATA object depend on the
3267 * referenced table's TABLE_DATA object.
3268 */
3270 ftable->dataObj->dobj.dumpId);
3271 }
3272 }
3273 free(dobjs);
3274}
void getDumpableObjects(DumpableObject ***objs, int *numObjs)
Definition: common.c:797

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

7186{
7187 DumpOptions *dopt = fout->dopt;
7188 PGresult *res;
7189 int ntups;
7190 int i;
7192 TableInfo *tblinfo;
7193 int i_reltableoid;
7194 int i_reloid;
7195 int i_relname;
7196 int i_relnamespace;
7197 int i_relkind;
7198 int i_reltype;
7199 int i_relowner;
7200 int i_relchecks;
7201 int i_relhasindex;
7202 int i_relhasrules;
7203 int i_relpages;
7204 int i_reltuples;
7205 int i_relallvisible;
7206 int i_relallfrozen;
7207 int i_toastpages;
7208 int i_owning_tab;
7209 int i_owning_col;
7210 int i_reltablespace;
7211 int i_relhasoids;
7212 int i_relhastriggers;
7213 int i_relpersistence;
7214 int i_relispopulated;
7215 int i_relreplident;
7216 int i_relrowsec;
7217 int i_relforcerowsec;
7218 int i_relfrozenxid;
7219 int i_toastfrozenxid;
7220 int i_toastoid;
7221 int i_relminmxid;
7222 int i_toastminmxid;
7223 int i_reloptions;
7224 int i_checkoption;
7225 int i_toastreloptions;
7226 int i_reloftype;
7227 int i_foreignserver;
7228 int i_amname;
7229 int i_is_identity_sequence;
7230 int i_relacl;
7231 int i_acldefault;
7232 int i_ispartition;
7233
7234 /*
7235 * Find all the tables and table-like objects.
7236 *
7237 * We must fetch all tables in this phase because otherwise we cannot
7238 * correctly identify inherited columns, owned sequences, etc.
7239 *
7240 * We include system catalogs, so that we can work if a user table is
7241 * defined to inherit from a system catalog (pretty weird, but...)
7242 *
7243 * Note: in this phase we should collect only a minimal amount of
7244 * information about each table, basically just enough to decide if it is
7245 * interesting. In particular, since we do not yet have lock on any user
7246 * table, we MUST NOT invoke any server-side data collection functions
7247 * (for instance, pg_get_partkeydef()). Those are likely to fail or give
7248 * wrong answers if any concurrent DDL is happening.
7249 */
7250
7252 "SELECT c.tableoid, c.oid, c.relname, "
7253 "c.relnamespace, c.relkind, c.reltype, "
7254 "c.relowner, "
7255 "c.relchecks, "
7256 "c.relhasindex, c.relhasrules, c.relpages, "
7257 "c.reltuples, c.relallvisible, ");
7258
7259 if (fout->remoteVersion >= 180000)
7260 appendPQExpBufferStr(query, "c.relallfrozen, ");
7261 else
7262 appendPQExpBufferStr(query, "0 AS relallfrozen, ");
7263
7265 "c.relhastriggers, c.relpersistence, "
7266 "c.reloftype, "
7267 "c.relacl, "
7268 "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
7269 " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
7270 "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
7271 "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
7272 "ELSE 0 END AS foreignserver, "
7273 "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
7274 "tc.oid AS toid, "
7275 "tc.relpages AS toastpages, "
7276 "tc.reloptions AS toast_reloptions, "
7277 "d.refobjid AS owning_tab, "
7278 "d.refobjsubid AS owning_col, "
7279 "tsp.spcname AS reltablespace, ");
7280
7281 if (fout->remoteVersion >= 120000)
7283 "false AS relhasoids, ");
7284 else
7286 "c.relhasoids, ");
7287
7288 if (fout->remoteVersion >= 90300)
7290 "c.relispopulated, ");
7291 else
7293 "'t' as relispopulated, ");
7294
7295 if (fout->remoteVersion >= 90400)
7297 "c.relreplident, ");
7298 else
7300 "'d' AS relreplident, ");
7301
7302 if (fout->remoteVersion >= 90500)
7304 "c.relrowsecurity, c.relforcerowsecurity, ");
7305 else
7307 "false AS relrowsecurity, "
7308 "false AS relforcerowsecurity, ");
7309
7310 if (fout->remoteVersion >= 90300)
7312 "c.relminmxid, tc.relminmxid AS tminmxid, ");
7313 else
7315 "0 AS relminmxid, 0 AS tminmxid, ");
7316
7317 if (fout->remoteVersion >= 90300)
7319 "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
7320 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
7321 "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
7322 else
7324 "c.reloptions, NULL AS checkoption, ");
7325
7326 if (fout->remoteVersion >= 90600)
7328 "am.amname, ");
7329 else
7331 "NULL AS amname, ");
7332
7333 if (fout->remoteVersion >= 90600)
7335 "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
7336 else
7338 "false AS is_identity_sequence, ");
7339
7340 if (fout->remoteVersion >= 100000)
7342 "c.relispartition AS ispartition ");
7343 else
7345 "false AS ispartition ");
7346
7347 /*
7348 * Left join to pg_depend to pick up dependency info linking sequences to
7349 * their owning column, if any (note this dependency is AUTO except for
7350 * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
7351 * collect the spcname.
7352 */
7354 "\nFROM pg_class c\n"
7355 "LEFT JOIN pg_depend d ON "
7356 "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
7357 "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
7358 "d.objsubid = 0 AND "
7359 "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
7360 "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
7361
7362 /*
7363 * In 9.6 and up, left join to pg_am to pick up the amname.
7364 */
7365 if (fout->remoteVersion >= 90600)
7367 "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
7368
7369 /*
7370 * We purposefully ignore toast OIDs for partitioned tables; the reason is
7371 * that versions 10 and 11 have them, but later versions do not, so
7372 * emitting them causes the upgrade to fail.
7373 */
7375 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
7376 " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
7377 " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
7378
7379 /*
7380 * Restrict to interesting relkinds (in particular, not indexes). Not all
7381 * relkinds are possible in older servers, but it's not worth the trouble
7382 * to emit a version-dependent list.
7383 *
7384 * Composite-type table entries won't be dumped as such, but we have to
7385 * make a DumpableObject for them so that we can track dependencies of the
7386 * composite type (pg_depend entries for columns of the composite type
7387 * link to the pg_class entry not the pg_type entry).
7388 */
7390 "WHERE c.relkind IN ("
7391 CppAsString2(RELKIND_RELATION) ", "
7392 CppAsString2(RELKIND_SEQUENCE) ", "
7393 CppAsString2(RELKIND_VIEW) ", "
7394 CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
7395 CppAsString2(RELKIND_MATVIEW) ", "
7396 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
7397 CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
7398 "ORDER BY c.oid");
7399
7400 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7401
7402 ntups = PQntuples(res);
7403
7404 *numTables = ntups;
7405
7406 /*
7407 * Extract data from result and lock dumpable tables. We do the locking
7408 * before anything else, to minimize the window wherein a table could
7409 * disappear under us.
7410 *
7411 * Note that we have to save info about all tables here, even when dumping
7412 * only one, because we don't yet know which tables might be inheritance
7413 * ancestors of the target table.
7414 */
7415 tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
7416
7417 i_reltableoid = PQfnumber(res, "tableoid");
7418 i_reloid = PQfnumber(res, "oid");
7419 i_relname = PQfnumber(res, "relname");
7420 i_relnamespace = PQfnumber(res, "relnamespace");
7421 i_relkind = PQfnumber(res, "relkind");
7422 i_reltype = PQfnumber(res, "reltype");
7423 i_relowner = PQfnumber(res, "relowner");
7424 i_relchecks = PQfnumber(res, "relchecks");
7425 i_relhasindex = PQfnumber(res, "relhasindex");
7426 i_relhasrules = PQfnumber(res, "relhasrules");
7427 i_relpages = PQfnumber(res, "relpages");
7428 i_reltuples = PQfnumber(res, "reltuples");
7429 i_relallvisible = PQfnumber(res, "relallvisible");
7430 i_relallfrozen = PQfnumber(res, "relallfrozen");
7431 i_toastpages = PQfnumber(res, "toastpages");
7432 i_owning_tab = PQfnumber(res, "owning_tab");
7433 i_owning_col = PQfnumber(res, "owning_col");
7434 i_reltablespace = PQfnumber(res, "reltablespace");
7435 i_relhasoids = PQfnumber(res, "relhasoids");
7436 i_relhastriggers = PQfnumber(res, "relhastriggers");
7437 i_relpersistence = PQfnumber(res, "relpersistence");
7438 i_relispopulated = PQfnumber(res, "relispopulated");
7439 i_relreplident = PQfnumber(res, "relreplident");
7440 i_relrowsec = PQfnumber(res, "relrowsecurity");
7441 i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
7442 i_relfrozenxid = PQfnumber(res, "relfrozenxid");
7443 i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
7444 i_toastoid = PQfnumber(res, "toid");
7445 i_relminmxid = PQfnumber(res, "relminmxid");
7446 i_toastminmxid = PQfnumber(res, "tminmxid");
7447 i_reloptions = PQfnumber(res, "reloptions");
7448 i_checkoption = PQfnumber(res, "checkoption");
7449 i_toastreloptions = PQfnumber(res, "toast_reloptions");
7450 i_reloftype = PQfnumber(res, "reloftype");
7451 i_foreignserver = PQfnumber(res, "foreignserver");
7452 i_amname = PQfnumber(res, "amname");
7453 i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
7454 i_relacl = PQfnumber(res, "relacl");
7455 i_acldefault = PQfnumber(res, "acldefault");
7456 i_ispartition = PQfnumber(res, "ispartition");
7457
7458 if (dopt->lockWaitTimeout)
7459 {
7460 /*
7461 * Arrange to fail instead of waiting forever for a table lock.
7462 *
7463 * NB: this coding assumes that the only queries issued within the
7464 * following loop are LOCK TABLEs; else the timeout may be undesirably
7465 * applied to other things too.
7466 */
7467 resetPQExpBuffer(query);
7468 appendPQExpBufferStr(query, "SET statement_timeout = ");
7470 ExecuteSqlStatement(fout, query->data);
7471 }
7472
7473 resetPQExpBuffer(query);
7474
7475 for (i = 0; i < ntups; i++)
7476 {
7477 int32 relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
7478 int32 relallfrozen = atoi(PQgetvalue(res, i, i_relallfrozen));
7479
7480 tblinfo[i].dobj.objType = DO_TABLE;
7481 tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
7482 tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
7483 AssignDumpId(&tblinfo[i].dobj);
7484 tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
7485 tblinfo[i].dobj.namespace =
7486 findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
7487 tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
7488 tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
7489 tblinfo[i].dacl.privtype = 0;
7490 tblinfo[i].dacl.initprivs = NULL;
7491 tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
7492 tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
7493 tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
7494 tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
7495 tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
7496 tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
7497 tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
7498 if (PQgetisnull(res, i, i_toastpages))
7499 tblinfo[i].toastpages = 0;
7500 else
7501 tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
7502 if (PQgetisnull(res, i, i_owning_tab))
7503 {
7504 tblinfo[i].owning_tab = InvalidOid;
7505 tblinfo[i].owning_col = 0;
7506 }
7507 else
7508 {
7509 tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
7510 tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
7511 }
7512 tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
7513 tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
7514 tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
7515 tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
7516 tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
7517 tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
7518 tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
7519 tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
7520 tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
7521 tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
7522 tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
7523 tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
7524 tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
7525 tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
7526 if (PQgetisnull(res, i, i_checkoption))
7527 tblinfo[i].checkoption = NULL;
7528 else
7529 tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
7530 tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
7531 tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
7532 tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
7533 if (PQgetisnull(res, i, i_amname))
7534 tblinfo[i].amname = NULL;
7535 else
7536 tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
7537 tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
7538 tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
7539
7540 /* other fields were zeroed above */
7541
7542 /*
7543 * Decide whether we want to dump this table.
7544 */
7545 if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
7546 tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
7547 else
7548 selectDumpableTable(&tblinfo[i], fout);
7549
7550 /*
7551 * Now, consider the table "interesting" if we need to dump its
7552 * definition, data or its statistics. Later on, we'll skip a lot of
7553 * data collection for uninteresting tables.
7554 *
7555 * Note: the "interesting" flag will also be set by flagInhTables for
7556 * parents of interesting tables, so that we collect necessary
7557 * inheritance info even when the parents are not themselves being
7558 * dumped. This is the main reason why we need an "interesting" flag
7559 * that's separate from the components-to-dump bitmask.
7560 */
7561 tblinfo[i].interesting = (tblinfo[i].dobj.dump &
7565
7566 tblinfo[i].dummy_view = false; /* might get set during sort */
7567 tblinfo[i].postponed_def = false; /* might get set during sort */
7568
7569 /* Tables have data */
7571
7572 /* Mark whether table has an ACL */
7573 if (!PQgetisnull(res, i, i_relacl))
7574 tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
7575 tblinfo[i].hascolumnACLs = false; /* may get set later */
7576
7577 /* Add statistics */
7578 if (tblinfo[i].interesting)
7579 {
7580 RelStatsInfo *stats;
7581
7582 stats = getRelationStatistics(fout, &tblinfo[i].dobj,
7583 tblinfo[i].relpages,
7584 PQgetvalue(res, i, i_reltuples),
7585 relallvisible, relallfrozen,
7586 tblinfo[i].relkind, NULL, 0);
7587 if (tblinfo[i].relkind == RELKIND_MATVIEW)
7588 tblinfo[i].stats = stats;
7589 }
7590
7591 /*
7592 * Read-lock target tables to make sure they aren't DROPPED or altered
7593 * in schema before we get around to dumping them.
7594 *
7595 * Note that we don't explicitly lock parents of the target tables; we
7596 * assume our lock on the child is enough to prevent schema
7597 * alterations to parent tables.
7598 *
7599 * NOTE: it'd be kinda nice to lock other relations too, not only
7600 * plain or partitioned tables, but the backend doesn't presently
7601 * allow that.
7602 *
7603 * We only need to lock the table for certain components; see
7604 * pg_dump.h
7605 */
7606 if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
7607 (tblinfo[i].relkind == RELKIND_RELATION ||
7608 tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
7609 {
7610 /*
7611 * Tables are locked in batches. When dumping from a remote
7612 * server this can save a significant amount of time by reducing
7613 * the number of round trips.
7614 */
7615 if (query->len == 0)
7616 appendPQExpBuffer(query, "LOCK TABLE %s",
7617 fmtQualifiedDumpable(&tblinfo[i]));
7618 else
7619 {
7620 appendPQExpBuffer(query, ", %s",
7621 fmtQualifiedDumpable(&tblinfo[i]));
7622
7623 /* Arbitrarily end a batch when query length reaches 100K. */
7624 if (query->len >= 100000)
7625 {
7626 /* Lock another batch of tables. */
7627 appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7628 ExecuteSqlStatement(fout, query->data);
7629 resetPQExpBuffer(query);
7630 }
7631 }
7632 }
7633 }
7634
7635 if (query->len != 0)
7636 {
7637 /* Lock the tables in the last batch. */
7638 appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7639 ExecuteSqlStatement(fout, query->data);
7640 }
7641
7642 if (dopt->lockWaitTimeout)
7643 {
7644 ExecuteSqlStatement(fout, "SET statement_timeout = 0");
7645 }
7646
7647 PQclear(res);
7648
7649 destroyPQExpBuffer(query);
7650
7651 return tblinfo;
7652}
static void selectDumpableTable(TableInfo *tbinfo, Archive *fout)
Definition: pg_dump.c:2084
#define DUMP_COMPONENTS_REQUIRING_LOCK
Definition: pg_dump.h:141
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:446
const char * lockWaitTimeout
Definition: pg_backup.h:179
struct _relStatsInfo * stats
Definition: pg_dump.h:381
Oid foreign_server
Definition: pg_dump.h:333
bool hasrules
Definition: pg_dump.h:319
bool hastriggers
Definition: pg_dump.h:320

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_COMPONENT_STATISTICS, DUMP_COMPONENTS_REQUIRING_LOCK, ExecuteSqlQuery(), ExecuteSqlStatement(), findNamespace(), fmtQualifiedDumpable, _tableInfo::forcerowsec, _tableInfo::foreign_server, _tableInfo::frozenxid, GetConnection(), getRelationStatistics(), 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, resetPQExpBuffer(), _tableInfo::rolname, _tableInfo::rowsec, selectDumpableTable(), _tableInfo::stats, 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 9150 of file pg_dump.c.

9151{
9152 PGresult *res;
9153 int ntups;
9154 int i;
9155 PQExpBuffer query;
9156 TransformInfo *transforminfo;
9157 int i_tableoid;
9158 int i_oid;
9159 int i_trftype;
9160 int i_trflang;
9161 int i_trffromsql;
9162 int i_trftosql;
9163
9164 /* Transforms didn't exist pre-9.5 */
9165 if (fout->remoteVersion < 90500)
9166 return;
9167
9168 query = createPQExpBuffer();
9169
9170 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
9171 "trftype, trflang, trffromsql::oid, trftosql::oid "
9172 "FROM pg_transform "
9173 "ORDER BY 3,4");
9174
9175 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9176
9177 ntups = PQntuples(res);
9178
9179 transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
9180
9181 i_tableoid = PQfnumber(res, "tableoid");
9182 i_oid = PQfnumber(res, "oid");
9183 i_trftype = PQfnumber(res, "trftype");
9184 i_trflang = PQfnumber(res, "trflang");
9185 i_trffromsql = PQfnumber(res, "trffromsql");
9186 i_trftosql = PQfnumber(res, "trftosql");
9187
9188 for (i = 0; i < ntups; i++)
9189 {
9190 PQExpBufferData namebuf;
9191 TypeInfo *typeInfo;
9192 char *lanname;
9193
9194 transforminfo[i].dobj.objType = DO_TRANSFORM;
9195 transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9196 transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9197 AssignDumpId(&transforminfo[i].dobj);
9198 transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
9199 transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
9200 transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
9201 transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
9202
9203 /*
9204 * Try to name transform as concatenation of type and language name.
9205 * This is only used for purposes of sorting. If we fail to find
9206 * either, the name will be an empty string.
9207 */
9208 initPQExpBuffer(&namebuf);
9209 typeInfo = findTypeByOid(transforminfo[i].trftype);
9210 lanname = get_language_name(fout, transforminfo[i].trflang);
9211 if (typeInfo && lanname)
9212 appendPQExpBuffer(&namebuf, "%s %s",
9213 typeInfo->dobj.name, lanname);
9214 transforminfo[i].dobj.name = namebuf.data;
9215 free(lanname);
9216
9217 /* Decide whether we want to dump it */
9218 selectDumpableObject(&(transforminfo[i].dobj), fout);
9219 }
9220
9221 PQclear(res);
9222
9223 destroyPQExpBuffer(query);
9224}

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

8683{
8685 PQExpBuffer tbloids = createPQExpBuffer();
8686 PGresult *res;
8687 int ntups;
8688 int curtblindx;
8689 TriggerInfo *tginfo;
8690 int i_tableoid,
8691 i_oid,
8692 i_tgrelid,
8693 i_tgname,
8694 i_tgenabled,
8695 i_tgispartition,
8696 i_tgdef;
8697
8698 /*
8699 * We want to perform just one query against pg_trigger. However, we
8700 * mustn't try to select every row of the catalog and then sort it out on
8701 * the client side, because some of the server-side functions we need
8702 * would be unsafe to apply to tables we don't have lock on. Hence, we
8703 * build an array of the OIDs of tables we care about (and now have lock
8704 * on!), and use a WHERE clause to constrain which rows are selected.
8705 */
8706 appendPQExpBufferChar(tbloids, '{');
8707 for (int i = 0; i < numTables; i++)
8708 {
8709 TableInfo *tbinfo = &tblinfo[i];
8710
8711 if (!tbinfo->hastriggers ||
8712 !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8713 continue;
8714
8715 /* OK, we need info for this table */
8716 if (tbloids->len > 1) /* do we have more than the '{'? */
8717 appendPQExpBufferChar(tbloids, ',');
8718 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8719 }
8720 appendPQExpBufferChar(tbloids, '}');
8721
8722 if (fout->remoteVersion >= 150000)
8723 {
8724 /*
8725 * NB: think not to use pretty=true in pg_get_triggerdef. It could
8726 * result in non-forward-compatible dumps of WHEN clauses due to
8727 * under-parenthesization.
8728 *
8729 * NB: We need to see partition triggers in case the tgenabled flag
8730 * has been changed from the parent.
8731 */
8732 appendPQExpBuffer(query,
8733 "SELECT t.tgrelid, t.tgname, "
8734 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8735 "t.tgenabled, t.tableoid, t.oid, "
8736 "t.tgparentid <> 0 AS tgispartition\n"
8737 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8738 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8739 "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8740 "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
8741 "OR t.tgenabled != u.tgenabled) "
8742 "ORDER BY t.tgrelid, t.tgname",
8743 tbloids->data);
8744 }
8745 else if (fout->remoteVersion >= 130000)
8746 {
8747 /*
8748 * NB: think not to use pretty=true in pg_get_triggerdef. It could
8749 * result in non-forward-compatible dumps of WHEN clauses due to
8750 * under-parenthesization.
8751 *
8752 * NB: We need to see tgisinternal triggers in partitions, in case the
8753 * tgenabled flag has been changed from the parent.
8754 */
8755 appendPQExpBuffer(query,
8756 "SELECT t.tgrelid, t.tgname, "
8757 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8758 "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
8759 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8760 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8761 "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8762 "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
8763 "ORDER BY t.tgrelid, t.tgname",
8764 tbloids->data);
8765 }
8766 else if (fout->remoteVersion >= 110000)
8767 {
8768 /*
8769 * NB: We need to see tgisinternal triggers in partitions, in case the
8770 * tgenabled flag has been changed from the parent. No tgparentid in
8771 * version 11-12, so we have to match them via pg_depend.
8772 *
8773 * See above about pretty=true in pg_get_triggerdef.
8774 */
8775 appendPQExpBuffer(query,
8776 "SELECT t.tgrelid, t.tgname, "
8777 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8778 "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
8779 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8780 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8781 "LEFT JOIN pg_catalog.pg_depend AS d ON "
8782 " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8783 " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8784 " d.objid = t.oid "
8785 "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8786 "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
8787 "ORDER BY t.tgrelid, t.tgname",
8788 tbloids->data);
8789 }
8790 else
8791 {
8792 /* See above about pretty=true in pg_get_triggerdef */
8793 appendPQExpBuffer(query,
8794 "SELECT t.tgrelid, t.tgname, "
8795 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8796 "t.tgenabled, false as tgispartition, "
8797 "t.tableoid, t.oid "
8798 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8799 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8800 "WHERE NOT tgisinternal "
8801 "ORDER BY t.tgrelid, t.tgname",
8802 tbloids->data);
8803 }
8804
8805 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8806
8807 ntups = PQntuples(res);
8808
8809 i_tableoid = PQfnumber(res, "tableoid");
8810 i_oid = PQfnumber(res, "oid");
8811 i_tgrelid = PQfnumber(res, "tgrelid");
8812 i_tgname = PQfnumber(res, "tgname");
8813 i_tgenabled = PQfnumber(res, "tgenabled");
8814 i_tgispartition = PQfnumber(res, "tgispartition");
8815 i_tgdef = PQfnumber(res, "tgdef");
8816
8817 tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
8818
8819 /*
8820 * Outer loop iterates once per table, not once per row. Incrementing of
8821 * j is handled by the inner loop.
8822 */
8823 curtblindx = -1;
8824 for (int j = 0; j < ntups;)
8825 {
8826 Oid tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
8827 TableInfo *tbinfo = NULL;
8828 int numtrigs;
8829
8830 /* Count rows for this table */
8831 for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
8832 if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
8833 break;
8834
8835 /*
8836 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8837 * order.
8838 */
8839 while (++curtblindx < numTables)
8840 {
8841 tbinfo = &tblinfo[curtblindx];
8842 if (tbinfo->dobj.catId.oid == tgrelid)
8843 break;
8844 }
8845 if (curtblindx >= numTables)
8846 pg_fatal("unrecognized table OID %u", tgrelid);
8847
8848 /* Save data for this table */
8849 tbinfo->triggers = tginfo + j;
8850 tbinfo->numTriggers = numtrigs;
8851
8852 for (int c = 0; c < numtrigs; c++, j++)
8853 {
8854 tginfo[j].dobj.objType = DO_TRIGGER;
8855 tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8856 tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8857 AssignDumpId(&tginfo[j].dobj);
8858 tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
8859 tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8860 tginfo[j].tgtable = tbinfo;
8861 tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8862 tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
8863 tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
8864 }
8865 }
8866
8867 PQclear(res);
8868
8869 destroyPQExpBuffer(query);
8870 destroyPQExpBuffer(tbloids);
8871}
struct _triggerInfo * triggers
Definition: pg_dump.h:392
int numTriggers
Definition: pg_dump.h:391

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, CatalogId::tableoid, _triggerInfo::tgdef, _triggerInfo::tgenabled, _triggerInfo::tgispartition, _triggerInfo::tgtable, and _tableInfo::triggers.

Referenced by getSchemaData().

◆ getTSConfigurations()

void getTSConfigurations ( Archive fout)

Definition at line 10352 of file pg_dump.c.

10353{
10354 PGresult *res;
10355 int ntups;
10356 int i;
10357 PQExpBuffer query;
10358 TSConfigInfo *cfginfo;
10359 int i_tableoid;
10360 int i_oid;
10361 int i_cfgname;
10362 int i_cfgnamespace;
10363 int i_cfgowner;
10364 int i_cfgparser;
10365
10366 query = createPQExpBuffer();
10367
10368 appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
10369 "cfgnamespace, cfgowner, cfgparser "
10370 "FROM pg_ts_config");
10371
10372 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10373
10374 ntups = PQntuples(res);
10375
10376 cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
10377
10378 i_tableoid = PQfnumber(res, "tableoid");
10379 i_oid = PQfnumber(res, "oid");
10380 i_cfgname = PQfnumber(res, "cfgname");
10381 i_cfgnamespace = PQfnumber(res, "cfgnamespace");
10382 i_cfgowner = PQfnumber(res, "cfgowner");
10383 i_cfgparser = PQfnumber(res, "cfgparser");
10384
10385 for (i = 0; i < ntups; i++)
10386 {
10387 cfginfo[i].dobj.objType = DO_TSCONFIG;
10388 cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10389 cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10390 AssignDumpId(&cfginfo[i].dobj);
10391 cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
10392 cfginfo[i].dobj.namespace =
10393 findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
10394 cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
10395 cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
10396
10397 /* Decide whether we want to dump it */
10398 selectDumpableObject(&(cfginfo[i].dobj), fout);
10399 }
10400
10401 PQclear(res);
10402
10403 destroyPQExpBuffer(query);
10404}

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, _cfgInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSDictionaries()

void getTSDictionaries ( Archive fout)

Definition at line 10227 of file pg_dump.c.

10228{
10229 PGresult *res;
10230 int ntups;
10231 int i;
10232 PQExpBuffer query;
10233 TSDictInfo *dictinfo;
10234 int i_tableoid;
10235 int i_oid;
10236 int i_dictname;
10237 int i_dictnamespace;
10238 int i_dictowner;
10239 int i_dicttemplate;
10240 int i_dictinitoption;
10241
10242 query = createPQExpBuffer();
10243
10244 appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
10245 "dictnamespace, dictowner, "
10246 "dicttemplate, dictinitoption "
10247 "FROM pg_ts_dict");
10248
10249 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10250
10251 ntups = PQntuples(res);
10252
10253 dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
10254
10255 i_tableoid = PQfnumber(res, "tableoid");
10256 i_oid = PQfnumber(res, "oid");
10257 i_dictname = PQfnumber(res, "dictname");
10258 i_dictnamespace = PQfnumber(res, "dictnamespace");
10259 i_dictowner = PQfnumber(res, "dictowner");
10260 i_dictinitoption = PQfnumber(res, "dictinitoption");
10261 i_dicttemplate = PQfnumber(res, "dicttemplate");
10262
10263 for (i = 0; i < ntups; i++)
10264 {
10265 dictinfo[i].dobj.objType = DO_TSDICT;
10266 dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10267 dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10268 AssignDumpId(&dictinfo[i].dobj);
10269 dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
10270 dictinfo[i].dobj.namespace =
10271 findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
10272 dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
10273 dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
10274 if (PQgetisnull(res, i, i_dictinitoption))
10275 dictinfo[i].dictinitoption = NULL;
10276 else
10277 dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
10278
10279 /* Decide whether we want to dump it */
10280 selectDumpableObject(&(dictinfo[i].dobj), fout);
10281 }
10282
10283 PQclear(res);
10284
10285 destroyPQExpBuffer(query);
10286}

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, _dictInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSParsers()

void getTSParsers ( Archive fout)

Definition at line 10153 of file pg_dump.c.

10154{
10155 PGresult *res;
10156 int ntups;
10157 int i;
10158 PQExpBuffer query;
10159 TSParserInfo *prsinfo;
10160 int i_tableoid;
10161 int i_oid;
10162 int i_prsname;
10163 int i_prsnamespace;
10164 int i_prsstart;
10165 int i_prstoken;
10166 int i_prsend;
10167 int i_prsheadline;
10168 int i_prslextype;
10169
10170 query = createPQExpBuffer();
10171
10172 /*
10173 * find all text search objects, including builtin ones; we filter out
10174 * system-defined objects at dump-out time.
10175 */
10176
10177 appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
10178 "prsstart::oid, prstoken::oid, "
10179 "prsend::oid, prsheadline::oid, prslextype::oid "
10180 "FROM pg_ts_parser");
10181
10182 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10183
10184 ntups = PQntuples(res);
10185
10186 prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
10187
10188 i_tableoid = PQfnumber(res, "tableoid");
10189 i_oid = PQfnumber(res, "oid");
10190 i_prsname = PQfnumber(res, "prsname");
10191 i_prsnamespace = PQfnumber(res, "prsnamespace");
10192 i_prsstart = PQfnumber(res, "prsstart");
10193 i_prstoken = PQfnumber(res, "prstoken");
10194 i_prsend = PQfnumber(res, "prsend");
10195 i_prsheadline = PQfnumber(res, "prsheadline");
10196 i_prslextype = PQfnumber(res, "prslextype");
10197
10198 for (i = 0; i < ntups; i++)
10199 {
10200 prsinfo[i].dobj.objType = DO_TSPARSER;
10201 prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10202 prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10203 AssignDumpId(&prsinfo[i].dobj);
10204 prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
10205 prsinfo[i].dobj.namespace =
10206 findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
10207 prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
10208 prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
10209 prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
10210 prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
10211 prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
10212
10213 /* Decide whether we want to dump it */
10214 selectDumpableObject(&(prsinfo[i].dobj), fout);
10215 }
10216
10217 PQclear(res);
10218
10219 destroyPQExpBuffer(query);
10220}

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, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSTemplates()

void getTSTemplates ( Archive fout)

Definition at line 10293 of file pg_dump.c.

10294{
10295 PGresult *res;
10296 int ntups;
10297 int i;
10298 PQExpBuffer query;
10299 TSTemplateInfo *tmplinfo;
10300 int i_tableoid;
10301 int i_oid;
10302 int i_tmplname;
10303 int i_tmplnamespace;
10304 int i_tmplinit;
10305 int i_tmpllexize;
10306
10307 query = createPQExpBuffer();
10308
10309 appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
10310 "tmplnamespace, tmplinit::oid, tmpllexize::oid "
10311 "FROM pg_ts_template");
10312
10313 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10314
10315 ntups = PQntuples(res);
10316
10317 tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
10318
10319 i_tableoid = PQfnumber(res, "tableoid");
10320 i_oid = PQfnumber(res, "oid");
10321 i_tmplname = PQfnumber(res, "tmplname");
10322 i_tmplnamespace = PQfnumber(res, "tmplnamespace");
10323 i_tmplinit = PQfnumber(res, "tmplinit");
10324 i_tmpllexize = PQfnumber(res, "tmpllexize");
10325
10326 for (i = 0; i < ntups; i++)
10327 {
10328 tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
10329 tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10330 tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10331 AssignDumpId(&tmplinfo[i].dobj);
10332 tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
10333 tmplinfo[i].dobj.namespace =
10334 findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
10335 tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
10336 tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
10337
10338 /* Decide whether we want to dump it */
10339 selectDumpableObject(&(tmplinfo[i].dobj), fout);
10340 }
10341
10342 PQclear(res);
10343
10344 destroyPQExpBuffer(query);
10345}

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, selectDumpableObject(), CatalogId::tableoid, _tmplInfo::tmplinit, and _tmplInfo::tmpllexize.

Referenced by getSchemaData().

◆ getTypes()

void getTypes ( Archive fout)

Definition at line 6198 of file pg_dump.c.

6199{
6200 PGresult *res;
6201 int ntups;
6202 int i;
6204 TypeInfo *tyinfo;
6205 ShellTypeInfo *stinfo;
6206 int i_tableoid;
6207 int i_oid;
6208 int i_typname;
6209 int i_typnamespace;
6210 int i_typacl;
6211 int i_acldefault;
6212 int i_typowner;
6213 int i_typelem;
6214 int i_typrelid;
6215 int i_typrelkind;
6216 int i_typtype;
6217 int i_typisdefined;
6218 int i_isarray;
6219 int i_typarray;
6220
6221 /*
6222 * we include even the built-in types because those may be used as array
6223 * elements by user-defined types
6224 *
6225 * we filter out the built-in types when we dump out the types
6226 *
6227 * same approach for undefined (shell) types and array types
6228 *
6229 * Note: as of 8.3 we can reliably detect whether a type is an
6230 * auto-generated array type by checking the element type's typarray.
6231 * (Before that the test is capable of generating false positives.) We
6232 * still check for name beginning with '_', though, so as to avoid the
6233 * cost of the subselect probe for all standard types. This would have to
6234 * be revisited if the backend ever allows renaming of array types.
6235 */
6236 appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
6237 "typnamespace, typacl, "
6238 "acldefault('T', typowner) AS acldefault, "
6239 "typowner, "
6240 "typelem, typrelid, typarray, "
6241 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
6242 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
6243 "typtype, typisdefined, "
6244 "typname[0] = '_' AND typelem != 0 AND "
6245 "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
6246 "FROM pg_type");
6247
6248 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6249
6250 ntups = PQntuples(res);
6251
6252 tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
6253
6254 i_tableoid = PQfnumber(res, "tableoid");
6255 i_oid = PQfnumber(res, "oid");
6256 i_typname = PQfnumber(res, "typname");
6257 i_typnamespace = PQfnumber(res, "typnamespace");
6258 i_typacl = PQfnumber(res, "typacl");
6259 i_acldefault = PQfnumber(res, "acldefault");
6260 i_typowner = PQfnumber(res, "typowner");
6261 i_typelem = PQfnumber(res, "typelem");
6262 i_typrelid = PQfnumber(res, "typrelid");
6263 i_typrelkind = PQfnumber(res, "typrelkind");
6264 i_typtype = PQfnumber(res, "typtype");
6265 i_typisdefined = PQfnumber(res, "typisdefined");
6266 i_isarray = PQfnumber(res, "isarray");
6267 i_typarray = PQfnumber(res, "typarray");
6268
6269 for (i = 0; i < ntups; i++)
6270 {
6271 tyinfo[i].dobj.objType = DO_TYPE;
6272 tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6273 tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6274 AssignDumpId(&tyinfo[i].dobj);
6275 tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
6276 tyinfo[i].dobj.namespace =
6277 findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
6278 tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
6279 tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6280 tyinfo[i].dacl.privtype = 0;
6281 tyinfo[i].dacl.initprivs = NULL;
6282 tyinfo[i].ftypname = NULL; /* may get filled later */
6283 tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
6284 tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
6285 tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
6286 tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
6287 tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
6288 tyinfo[i].shellType = NULL;
6289
6290 if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
6291 tyinfo[i].isDefined = true;
6292 else
6293 tyinfo[i].isDefined = false;
6294
6295 if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
6296 tyinfo[i].isArray = true;
6297 else
6298 tyinfo[i].isArray = false;
6299
6300 tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
6301
6302 if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
6303 tyinfo[i].isMultirange = true;
6304 else
6305 tyinfo[i].isMultirange = false;
6306
6307 /* Decide whether we want to dump it */
6308 selectDumpableType(&tyinfo[i], fout);
6309
6310 /* Mark whether type has an ACL */
6311 if (!PQgetisnull(res, i, i_typacl))
6313
6314 /*
6315 * If it's a domain, fetch info about its constraints, if any
6316 */
6317 tyinfo[i].nDomChecks = 0;
6318 tyinfo[i].domChecks = NULL;
6319 tyinfo[i].notnull = NULL;
6320 if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6321 tyinfo[i].typtype == TYPTYPE_DOMAIN)
6322 getDomainConstraints(fout, &(tyinfo[i]));
6323
6324 /*
6325 * If it's a base type, make a DumpableObject representing a shell
6326 * definition of the type. We will need to dump that ahead of the I/O
6327 * functions for the type. Similarly, range types need a shell
6328 * definition in case they have a canonicalize function.
6329 *
6330 * Note: the shell type doesn't have a catId. You might think it
6331 * should copy the base type's catId, but then it might capture the
6332 * pg_depend entries for the type, which we don't want.
6333 */
6334 if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6335 (tyinfo[i].typtype == TYPTYPE_BASE ||
6336 tyinfo[i].typtype == TYPTYPE_RANGE))
6337 {
6338 stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
6339 stinfo->dobj.objType = DO_SHELL_TYPE;
6340 stinfo->dobj.catId = nilCatalogId;
6341 AssignDumpId(&stinfo->dobj);
6342 stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
6343 stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
6344 stinfo->baseType = &(tyinfo[i]);
6345 tyinfo[i].shellType = stinfo;
6346
6347 /*
6348 * Initially mark the shell type as not to be dumped. We'll only
6349 * dump it if the I/O or canonicalize functions need to be dumped;
6350 * this is taken care of while sorting dependencies.
6351 */
6352 stinfo->dobj.dump = DUMP_COMPONENT_NONE;
6353 }
6354 }
6355
6356 PQclear(res);
6357
6358 destroyPQExpBuffer(query);
6359}
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:8473
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:2123
bool isMultirange
Definition: pg_dump.h:221
char typrelkind
Definition: pg_dump.h:218
Oid typarray
Definition: pg_dump.h:217
struct _shellTypeInfo * shellType
Definition: pg_dump.h:224
bool isArray
Definition: pg_dump.h:220

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, _typeInfo::notnull, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, _dumpableAcl::privtype, _typeInfo::rolname, selectDumpableType(), _typeInfo::shellType, CatalogId::tableoid, _typeInfo::typarray, _typeInfo::typelem, _typeInfo::typrelid, _typeInfo::typrelkind, and _typeInfo::typtype.

Referenced by getSchemaData().

◆ help()

static void help ( const char *  progname)
static

Definition at line 1318 of file pg_dump.c.

1319{
1320 printf(_("%s exports a PostgreSQL database as an SQL script or to other formats.\n\n"), progname);
1321 printf(_("Usage:\n"));
1322 printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
1323
1324 printf(_("\nGeneral options:\n"));
1325 printf(_(" -f, --file=FILENAME output file or directory name\n"));
1326 printf(_(" -F, --format=c|d|t|p output file format (custom, directory, tar,\n"
1327 " plain text (default))\n"));
1328 printf(_(" -j, --jobs=NUM use this many parallel jobs to dump\n"));
1329 printf(_(" -v, --verbose verbose mode\n"));
1330 printf(_(" -V, --version output version information, then exit\n"));
1331 printf(_(" -Z, --compress=METHOD[:DETAIL]\n"
1332 " compress as specified\n"));
1333 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
1334 printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
1335 printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
1336 printf(_(" -?, --help show this help, then exit\n"));
1337
1338 printf(_("\nOptions controlling the output content:\n"));
1339 printf(_(" -a, --data-only dump only the data, not the schema or statistics\n"));
1340 printf(_(" -b, --large-objects include large objects in dump\n"));
1341 printf(_(" --blobs (same as --large-objects, deprecated)\n"));
1342 printf(_(" -B, --no-large-objects exclude large objects in dump\n"));
1343 printf(_(" --no-blobs (same as --no-large-objects, deprecated)\n"));
1344 printf(_(" -c, --clean clean (drop) database objects before recreating\n"));
1345 printf(_(" -C, --create include commands to create database in dump\n"));
1346 printf(_(" -e, --extension=PATTERN dump the specified extension(s) only\n"));
1347 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
1348 printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n"));
1349 printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
1350 printf(_(" -O, --no-owner skip restoration of object ownership in\n"
1351 " plain-text format\n"));
1352 printf(_(" -s, --schema-only dump only the schema, no data or statistics\n"));
1353 printf(_(" -S, --superuser=NAME superuser user name to use in plain-text format\n"));
1354 printf(_(" -t, --table=PATTERN dump only the specified table(s)\n"));
1355 printf(_(" -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n"));
1356 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
1357 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
1358 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
1359 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
1360 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
1361 printf(_(" --enable-row-security enable row security (dump only content user has\n"
1362 " access to)\n"));
1363 printf(_(" --exclude-extension=PATTERN do NOT dump the specified extension(s)\n"));
1364 printf(_(" --exclude-table-and-children=PATTERN\n"
1365 " do NOT dump the specified table(s), including\n"
1366 " child and partition tables\n"));
1367 printf(_(" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
1368 printf(_(" --exclude-table-data-and-children=PATTERN\n"
1369 " do NOT dump data for the specified table(s),\n"
1370 " including child and partition tables\n"));
1371 printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
1372 printf(_(" --filter=FILENAME include or exclude objects and data from dump\n"
1373 " based on expressions in FILENAME\n"));
1374 printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
1375 printf(_(" --include-foreign-data=PATTERN\n"
1376 " include data of foreign tables on foreign\n"
1377 " servers matching PATTERN\n"));
1378 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
1379 printf(_(" --load-via-partition-root load partitions via the root table\n"));
1380 printf(_(" --no-comments do not dump comment commands\n"));
1381 printf(_(" --no-data do not dump data\n"));
1382 printf(_(" --no-policies do not dump row security policies\n"));
1383 printf(_(" --no-publications do not dump publications\n"));
1384 printf(_(" --no-schema do not dump schema\n"));
1385 printf(_(" --no-security-labels do not dump security label assignments\n"));
1386 printf(_(" --no-statistics do not dump statistics\n"));
1387 printf(_(" --no-subscriptions do not dump subscriptions\n"));
1388 printf(_(" --no-table-access-method do not dump table access methods\n"));
1389 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
1390 printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
1391 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
1392 printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
1393 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
1394 printf(_(" --restrict-key=RESTRICT_KEY use provided string as psql \\restrict key\n"));
1395 printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
1396 printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
1397 printf(_(" --sequence-data include sequence data in dump\n"));
1398 printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
1399 printf(_(" --snapshot=SNAPSHOT use given snapshot for the dump\n"));
1400 printf(_(" --statistics dump the statistics\n"));
1401 printf(_(" --statistics-only dump only the statistics, not schema or data\n"));
1402 printf(_(" --strict-names require table and/or schema include patterns to\n"
1403 " match at least one entity each\n"));
1404 printf(_(" --table-and-children=PATTERN dump only the specified table(s), including\n"
1405 " child and partition tables\n"));
1406 printf(_(" --use-set-session-authorization\n"
1407 " use SET SESSION AUTHORIZATION commands instead of\n"
1408 " ALTER OWNER commands to set ownership\n"));
1409
1410 printf(_("\nConnection options:\n"));
1411 printf(_(" -d, --dbname=DBNAME database to dump\n"));
1412 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
1413 printf(_(" -p, --port=PORT database server port number\n"));
1414 printf(_(" -U, --username=NAME connect as specified database user\n"));
1415 printf(_(" -w, --no-password never prompt for password\n"));
1416 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
1417 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
1418
1419 printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
1420 "variable value is used.\n\n"));
1421 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1422 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1423}
#define _(x)
Definition: elog.c:91
const char * progname
Definition: main.c:44
#define printf(...)
Definition: port.h:266

References _, printf, and progname.

Referenced by main().

◆ is_superuser()

static bool is_superuser ( Archive fout)
static

Definition at line 5067 of file pg_dump.c.

5068{
5069 ArchiveHandle *AH = (ArchiveHandle *) fout;
5070 const char *val;
5071
5072 val = PQparameterStatus(AH->connection, "is_superuser");
5073
5074 if (val && strcmp(val, "on") == 0)
5075 return true;
5076
5077 return false;
5078}
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7659
long val
Definition: informix.c:689

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

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

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 421 of file pg_dump.c.

422{
423 int c;
424 const char *filename = NULL;
425 const char *format = "p";
426 TableInfo *tblinfo;
427 int numTables;
428 DumpableObject **dobjs;
429 int numObjs;
430 DumpableObject *boundaryObjs;
431 int i;
432 int optindex;
433 RestoreOptions *ropt;
434 Archive *fout; /* the script file */
435 bool g_verbose = false;
436 const char *dumpencoding = NULL;
437 const char *dumpsnapshot = NULL;
438 char *use_role = NULL;
439 int numWorkers = 1;
440 int plainText = 0;
441 ArchiveFormat archiveFormat = archUnknown;
442 ArchiveMode archiveMode;
443 pg_compress_specification compression_spec = {0};
444 char *compression_detail = NULL;
445 char *compression_algorithm_str = "none";
446 char *error_detail = NULL;
447 bool user_compression_defined = false;
449 bool data_only = false;
450 bool schema_only = false;
451 bool statistics_only = false;
452 bool with_statistics = false;
453 bool no_data = false;
454 bool no_schema = false;
455 bool no_statistics = false;
456
457 static DumpOptions dopt;
458
459 static struct option long_options[] = {
460 {"data-only", no_argument, NULL, 'a'},
461 {"blobs", no_argument, NULL, 'b'},
462 {"large-objects", no_argument, NULL, 'b'},
463 {"no-blobs", no_argument, NULL, 'B'},
464 {"no-large-objects", no_argument, NULL, 'B'},
465 {"clean", no_argument, NULL, 'c'},
466 {"create", no_argument, NULL, 'C'},
467 {"dbname", required_argument, NULL, 'd'},
468 {"extension", required_argument, NULL, 'e'},
469 {"file", required_argument, NULL, 'f'},
470 {"format", required_argument, NULL, 'F'},
471 {"host", required_argument, NULL, 'h'},
472 {"jobs", 1, NULL, 'j'},
473 {"no-reconnect", no_argument, NULL, 'R'},
474 {"no-owner", no_argument, NULL, 'O'},
475 {"port", required_argument, NULL, 'p'},
476 {"schema", required_argument, NULL, 'n'},
477 {"exclude-schema", required_argument, NULL, 'N'},
478 {"schema-only", no_argument, NULL, 's'},
479 {"superuser", required_argument, NULL, 'S'},
480 {"table", required_argument, NULL, 't'},
481 {"exclude-table", required_argument, NULL, 'T'},
482 {"no-password", no_argument, NULL, 'w'},
483 {"password", no_argument, NULL, 'W'},
484 {"username", required_argument, NULL, 'U'},
485 {"verbose", no_argument, NULL, 'v'},
486 {"no-privileges", no_argument, NULL, 'x'},
487 {"no-acl", no_argument, NULL, 'x'},
488 {"compress", required_argument, NULL, 'Z'},
489 {"encoding", required_argument, NULL, 'E'},
490 {"help", no_argument, NULL, '?'},
491 {"version", no_argument, NULL, 'V'},
492
493 /*
494 * the following options don't have an equivalent short option letter
495 */
496 {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
497 {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
498 {"column-inserts", no_argument, &dopt.column_inserts, 1},
499 {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
500 {"disable-triggers", no_argument, &dopt.disable_triggers, 1},
501 {"enable-row-security", no_argument, &dopt.enable_row_security, 1},
502 {"exclude-table-data", required_argument, NULL, 4},
503 {"extra-float-digits", required_argument, NULL, 8},
504 {"if-exists", no_argument, &dopt.if_exists, 1},
505 {"inserts", no_argument, NULL, 9},
506 {"lock-wait-timeout", required_argument, NULL, 2},
507 {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1},
508 {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
509 {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
510 {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1},
511 {"role", required_argument, NULL, 3},
512 {"section", required_argument, NULL, 5},
513 {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
514 {"snapshot", required_argument, NULL, 6},
515 {"statistics", no_argument, NULL, 22},
516 {"statistics-only", no_argument, NULL, 18},
517 {"strict-names", no_argument, &strict_names, 1},
518 {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
519 {"no-comments", no_argument, &dopt.no_comments, 1},
520 {"no-data", no_argument, NULL, 19},
521 {"no-policies", no_argument, &dopt.no_policies, 1},
522 {"no-publications", no_argument, &dopt.no_publications, 1},
523 {"no-schema", no_argument, NULL, 20},
524 {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
525 {"no-statistics", no_argument, NULL, 21},
526 {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
527 {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
528 {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
529 {"no-sync", no_argument, NULL, 7},
530 {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
531 {"rows-per-insert", required_argument, NULL, 10},
532 {"include-foreign-data", required_argument, NULL, 11},
533 {"table-and-children", required_argument, NULL, 12},
534 {"exclude-table-and-children", required_argument, NULL, 13},
535 {"exclude-table-data-and-children", required_argument, NULL, 14},
536 {"sync-method", required_argument, NULL, 15},
537 {"filter", required_argument, NULL, 16},
538 {"exclude-extension", required_argument, NULL, 17},
539 {"sequence-data", no_argument, &dopt.sequence_data, 1},
540 {"restrict-key", required_argument, NULL, 25},
541
542 {NULL, 0, NULL, 0}
543 };
544
545 pg_logging_init(argv[0]);
547 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
548
549 /*
550 * Initialize what we need for parallel execution, especially for thread
551 * support on Windows.
552 */
554
555 progname = get_progname(argv[0]);
556
557 if (argc > 1)
558 {
559 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
560 {
561 help(progname);
562 exit_nicely(0);
563 }
564 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
565 {
566 puts("pg_dump (PostgreSQL) " PG_VERSION);
567 exit_nicely(0);
568 }
569 }
570
571 InitDumpOptions(&dopt);
572
573 while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxXZ:",
574 long_options, &optindex)) != -1)
575 {
576 switch (c)
577 {
578 case 'a': /* Dump data only */
579 data_only = true;
580 break;
581
582 case 'b': /* Dump LOs */
583 dopt.outputLOs = true;
584 break;
585
586 case 'B': /* Don't dump LOs */
587 dopt.dontOutputLOs = true;
588 break;
589
590 case 'c': /* clean (i.e., drop) schema prior to create */
591 dopt.outputClean = 1;
592 break;
593
594 case 'C': /* Create DB */
595 dopt.outputCreateDB = 1;
596 break;
597
598 case 'd': /* database name */
600 break;
601
602 case 'e': /* include extension(s) */
604 dopt.include_everything = false;
605 break;
606
607 case 'E': /* Dump encoding */
608 dumpencoding = pg_strdup(optarg);
609 break;
610
611 case 'f':
613 break;
614
615 case 'F':
617 break;
618
619 case 'h': /* server host */
621 break;
622
623 case 'j': /* number of dump jobs */
624 if (!option_parse_int(optarg, "-j/--jobs", 1,
626 &numWorkers))
627 exit_nicely(1);
628 break;
629
630 case 'n': /* include schema(s) */
632 dopt.include_everything = false;
633 break;
634
635 case 'N': /* exclude schema(s) */
637 break;
638
639 case 'O': /* Don't reconnect to match owner */
640 dopt.outputNoOwner = 1;
641 break;
642
643 case 'p': /* server port */
645 break;
646
647 case 'R':
648 /* no-op, still accepted for backwards compatibility */
649 break;
650
651 case 's': /* dump schema only */
652 schema_only = true;
653 break;
654
655 case 'S': /* Username for superuser in plain text output */
657 break;
658
659 case 't': /* include table(s) */
661 dopt.include_everything = false;
662 break;
663
664 case 'T': /* exclude table(s) */
666 break;
667
668 case 'U':
670 break;
671
672 case 'v': /* verbose */
673 g_verbose = true;
675 break;
676
677 case 'w':
679 break;
680
681 case 'W':
683 break;
684
685 case 'x': /* skip ACL dump */
686 dopt.aclsSkip = true;
687 break;
688
689 case 'Z': /* Compression */
690 parse_compress_options(optarg, &compression_algorithm_str,
691 &compression_detail);
692 user_compression_defined = true;
693 break;
694
695 case 0:
696 /* This covers the long options. */
697 break;
698
699 case 2: /* lock-wait-timeout */
701 break;
702
703 case 3: /* SET ROLE */
704 use_role = pg_strdup(optarg);
705 break;
706
707 case 4: /* exclude table(s) data */
709 break;
710
711 case 5: /* section */
713 break;
714
715 case 6: /* snapshot */
716 dumpsnapshot = pg_strdup(optarg);
717 break;
718
719 case 7: /* no-sync */
720 dosync = false;
721 break;
722
723 case 8:
725 if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
727 exit_nicely(1);
728 break;
729
730 case 9: /* inserts */
731
732 /*
733 * dump_inserts also stores --rows-per-insert, careful not to
734 * overwrite that.
735 */
736 if (dopt.dump_inserts == 0)
738 break;
739
740 case 10: /* rows per insert */
741 if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
742 &dopt.dump_inserts))
743 exit_nicely(1);
744 break;
745
746 case 11: /* include foreign data */
748 optarg);
749 break;
750
751 case 12: /* include table(s) and their children */
753 optarg);
754 dopt.include_everything = false;
755 break;
756
757 case 13: /* exclude table(s) and their children */
759 optarg);
760 break;
761
762 case 14: /* exclude data of table(s) and children */
764 optarg);
765 break;
766
767 case 15:
769 exit_nicely(1);
770 break;
771
772 case 16: /* read object filters from file */
774 break;
775
776 case 17: /* exclude extension(s) */
778 optarg);
779 break;
780
781 case 18:
782 statistics_only = true;
783 break;
784
785 case 19:
786 no_data = true;
787 break;
788
789 case 20:
790 no_schema = true;
791 break;
792
793 case 21:
794 no_statistics = true;
795 break;
796
797 case 22:
798 with_statistics = true;
799 break;
800
801 case 25:
803 break;
804
805 default:
806 /* getopt_long already emitted a complaint */
807 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
808 exit_nicely(1);
809 }
810 }
811
812 /*
813 * Non-option argument specifies database name as long as it wasn't
814 * already specified with -d / --dbname
815 */
816 if (optind < argc && dopt.cparams.dbname == NULL)
817 dopt.cparams.dbname = argv[optind++];
818
819 /* Complain if any arguments remain */
820 if (optind < argc)
821 {
822 pg_log_error("too many command-line arguments (first is \"%s\")",
823 argv[optind]);
824 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
825 exit_nicely(1);
826 }
827
828 /* --column-inserts implies --inserts */
829 if (dopt.column_inserts && dopt.dump_inserts == 0)
831
832 /* reject conflicting "-only" options */
833 if (data_only && schema_only)
834 pg_fatal("options %s and %s cannot be used together",
835 "-s/--schema-only", "-a/--data-only");
836 if (schema_only && statistics_only)
837 pg_fatal("options %s and %s cannot be used together",
838 "-s/--schema-only", "--statistics-only");
839 if (data_only && statistics_only)
840 pg_fatal("options %s and %s cannot be used together",
841 "-a/--data-only", "--statistics-only");
842
843 /* reject conflicting "-only" and "no-" options */
844 if (data_only && no_data)
845 pg_fatal("options %s and %s cannot be used together",
846 "-a/--data-only", "--no-data");
847 if (schema_only && no_schema)
848 pg_fatal("options %s and %s cannot be used together",
849 "-s/--schema-only", "--no-schema");
851 pg_fatal("options %s and %s cannot be used together",
852 "--statistics-only", "--no-statistics");
853
854 /* reject conflicting "no-" options */
856 pg_fatal("options %s and %s cannot be used together",
857 "--statistics", "--no-statistics");
858
859 /* reject conflicting "-only" options */
860 if (data_only && with_statistics)
861 pg_fatal("options %s and %s cannot be used together",
862 "-a/--data-only", "--statistics");
863 if (schema_only && with_statistics)
864 pg_fatal("options %s and %s cannot be used together",
865 "-s/--schema-only", "--statistics");
866
867 if (schema_only && foreign_servers_include_patterns.head != NULL)
868 pg_fatal("options %s and %s cannot be used together",
869 "-s/--schema-only", "--include-foreign-data");
870
871 if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
872 pg_fatal("option %s is not supported with parallel backup",
873 "--include-foreign-data");
874
875 if (data_only && dopt.outputClean)
876 pg_fatal("options %s and %s cannot be used together",
877 "-c/--clean", "-a/--data-only");
878
879 if (dopt.if_exists && !dopt.outputClean)
880 pg_fatal("option %s requires option %s",
881 "--if-exists", "-c/--clean");
882
883 /*
884 * Set derivative flags. Ambiguous or nonsensical combinations, e.g.
885 * "--schema-only --no-schema", will have already caused an error in one
886 * of the checks above.
887 */
888 dopt.dumpData = ((dopt.dumpData && !schema_only && !statistics_only) ||
889 data_only) && !no_data;
890 dopt.dumpSchema = ((dopt.dumpSchema && !data_only && !statistics_only) ||
891 schema_only) && !no_schema;
892 dopt.dumpStatistics = ((dopt.dumpStatistics && !schema_only && !data_only) ||
894
895
896 /*
897 * --inserts are already implied above if --column-inserts or
898 * --rows-per-insert were specified.
899 */
900 if (dopt.do_nothing && dopt.dump_inserts == 0)
901 pg_fatal("option %s requires option %s, %s, or %s",
902 "--on-conflict-do-nothing",
903 "--inserts", "--rows-per-insert", "--column-inserts");
904
905 /* Identify archive format to emit */
906 archiveFormat = parseArchiveFormat(format, &archiveMode);
907
908 /* archiveFormat specific setup */
909 if (archiveFormat == archNull)
910 {
911 plainText = 1;
912
913 /*
914 * If you don't provide a restrict key, one will be appointed for you.
915 */
916 if (!dopt.restrict_key)
918 if (!dopt.restrict_key)
919 pg_fatal("could not generate restrict key");
921 pg_fatal("invalid restrict key");
922 }
923 else if (dopt.restrict_key)
924 pg_fatal("option %s can only be used with %s",
925 "--restrict-key", "--format=plain");
926
927 /*
928 * Custom and directory formats are compressed by default with gzip when
929 * available, not the others. If gzip is not available, no compression is
930 * done by default.
931 */
932 if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
933 !user_compression_defined)
934 {
935#ifdef HAVE_LIBZ
936 compression_algorithm_str = "gzip";
937#else
938 compression_algorithm_str = "none";
939#endif
940 }
941
942 /*
943 * Compression options
944 */
945 if (!parse_compress_algorithm(compression_algorithm_str,
947 pg_fatal("unrecognized compression algorithm: \"%s\"",
948 compression_algorithm_str);
949
951 &compression_spec);
952 error_detail = validate_compress_specification(&compression_spec);
953 if (error_detail != NULL)
954 pg_fatal("invalid compression specification: %s",
955 error_detail);
956
957 error_detail = supports_compression(compression_spec);
958 if (error_detail != NULL)
959 pg_fatal("%s", error_detail);
960
961 /*
962 * Disable support for zstd workers for now - these are based on
963 * threading, and it's unclear how it interacts with parallel dumps on
964 * platforms where that relies on threads too (e.g. Windows).
965 */
966 if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
967 pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
968 "workers");
969
970 /*
971 * If emitting an archive format, we always want to emit a DATABASE item,
972 * in case --create is specified at pg_restore time.
973 */
974 if (!plainText)
975 dopt.outputCreateDB = 1;
976
977 /* Parallel backup only in the directory archive format so far */
978 if (archiveFormat != archDirectory && numWorkers > 1)
979 pg_fatal("parallel backup only supported by the directory format");
980
981 /* Open the output file */
982 fout = CreateArchive(filename, archiveFormat, compression_spec,
983 dosync, archiveMode, setupDumpWorker, sync_method);
984
985 /* Make dump options accessible right away */
986 SetArchiveOptions(fout, &dopt, NULL);
987
988 /* Register the cleanup hook */
990
991 /* Let the archiver know how noisy to be */
992 fout->verbose = g_verbose;
993
994
995 /*
996 * We allow the server to be back to 9.2, and up to any minor release of
997 * our own major version. (See also version check in pg_dumpall.c.)
998 */
999 fout->minRemoteVersion = 90200;
1000 fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
1001
1002 fout->numWorkers = numWorkers;
1003
1004 /*
1005 * Open the database using the Archiver, so it knows about it. Errors mean
1006 * death.
1007 */
1008 ConnectDatabaseAhx(fout, &dopt.cparams, false);
1009 setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
1010
1011 /*
1012 * On hot standbys, never try to dump unlogged table data, since it will
1013 * just throw an error.
1014 */
1015 if (fout->isStandby)
1016 dopt.no_unlogged_table_data = true;
1017
1018 /*
1019 * Find the last built-in OID, if needed (prior to 8.1)
1020 *
1021 * With 8.1 and above, we can just use FirstNormalObjectId - 1.
1022 */
1024
1025 pg_log_info("last built-in OID is %u", g_last_builtin_oid);
1026
1027 /* Expand schema selection patterns into OID lists */
1028 if (schema_include_patterns.head != NULL)
1029 {
1032 strict_names);
1033 if (schema_include_oids.head == NULL)
1034 pg_fatal("no matching schemas were found");
1035 }
1038 false);
1039 /* non-matching exclusion patterns aren't an error */
1040
1041 /* Expand table selection patterns into OID lists */
1044 strict_names, false);
1047 strict_names, true);
1048 if ((table_include_patterns.head != NULL ||
1050 table_include_oids.head == NULL)
1051 pg_fatal("no matching tables were found");
1052
1055 false, false);
1058 false, true);
1059
1062 false, false);
1065 false, true);
1066
1069
1070 /* non-matching exclusion patterns aren't an error */
1071
1072 /* Expand extension selection patterns into OID lists */
1073 if (extension_include_patterns.head != NULL)
1074 {
1077 strict_names);
1078 if (extension_include_oids.head == NULL)
1079 pg_fatal("no matching extensions were found");
1080 }
1083 false);
1084 /* non-matching exclusion patterns aren't an error */
1085
1086 /*
1087 * Dumping LOs is the default for dumps where an inclusion switch is not
1088 * used (an "include everything" dump). -B can be used to exclude LOs
1089 * from those dumps. -b can be used to include LOs even when an inclusion
1090 * switch is used.
1091 *
1092 * -s means "schema only" and LOs are data, not schema, so we never
1093 * include LOs when -s is used.
1094 */
1095 if (dopt.include_everything && dopt.dumpData && !dopt.dontOutputLOs)
1096 dopt.outputLOs = true;
1097
1098 /*
1099 * Collect role names so we can map object owner OIDs to names.
1100 */
1101 collectRoleNames(fout);
1102
1103 /*
1104 * Now scan the database and create DumpableObject structs for all the
1105 * objects we intend to dump.
1106 */
1107 tblinfo = getSchemaData(fout, &numTables);
1108
1109 if (dopt.dumpData)
1110 {
1111 getTableData(&dopt, tblinfo, numTables, 0);
1113 if (!dopt.dumpSchema)
1115 }
1116
1117 if (!dopt.dumpData && dopt.sequence_data)
1118 getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
1119
1120 /*
1121 * For binary upgrade mode, dump pg_largeobject_metadata and the
1122 * associated pg_shdepend rows. This is faster to restore than the
1123 * equivalent set of large object commands. We can only do this for
1124 * upgrades from v12 and newer; in older versions, pg_largeobject_metadata
1125 * was created WITH OIDS, so the OID column is hidden and won't be dumped.
1126 */
1127 if (dopt.binary_upgrade && fout->remoteVersion >= 120000)
1128 {
1129 TableInfo *lo_metadata = findTableByOid(LargeObjectMetadataRelationId);
1130 TableInfo *shdepend = findTableByOid(SharedDependRelationId);
1131
1132 makeTableDataInfo(&dopt, lo_metadata);
1133 makeTableDataInfo(&dopt, shdepend);
1134
1135 /*
1136 * Save pg_largeobject_metadata's dump ID for use as a dependency for
1137 * pg_shdepend and any large object comments/seclabels.
1138 */
1139 lo_metadata_dumpId = lo_metadata->dataObj->dobj.dumpId;
1141
1142 /*
1143 * Only dump large object shdepend rows for this database.
1144 */
1145 shdepend->dataObj->filtercond = "WHERE classid = 'pg_largeobject'::regclass "
1146 "AND dbid = (SELECT oid FROM pg_database "
1147 " WHERE datname = current_database())";
1148
1149 /*
1150 * If upgrading from v16 or newer, only dump large objects with
1151 * comments/seclabels. For these upgrades, pg_upgrade can copy/link
1152 * pg_largeobject_metadata's files (which is usually faster) but we
1153 * still need to dump LOs with comments/seclabels here so that the
1154 * subsequent COMMENT and SECURITY LABEL commands work. pg_upgrade
1155 * can't copy/link the files from older versions because aclitem
1156 * (needed by pg_largeobject_metadata.lomacl) changed its storage
1157 * format in v16.
1158 */
1159 if (fout->remoteVersion >= 160000)
1160 lo_metadata->dataObj->filtercond = "WHERE oid IN "
1161 "(SELECT objoid FROM pg_description "
1162 "WHERE classoid = " CppAsString2(LargeObjectRelationId) " "
1163 "UNION SELECT objoid FROM pg_seclabel "
1164 "WHERE classoid = " CppAsString2(LargeObjectRelationId) ")";
1165 }
1166
1167 /*
1168 * In binary-upgrade mode, we do not have to worry about the actual LO
1169 * data or the associated metadata that resides in the pg_largeobject and
1170 * pg_largeobject_metadata tables, respectively.
1171 *
1172 * However, we do need to collect LO information as there may be comments
1173 * or other information on LOs that we do need to dump out.
1174 */
1175 if (dopt.outputLOs || dopt.binary_upgrade)
1176 getLOs(fout);
1177
1178 /*
1179 * Collect dependency data to assist in ordering the objects.
1180 */
1181 getDependencies(fout);
1182
1183 /*
1184 * Collect ACLs, comments, and security labels, if wanted.
1185 */
1186 if (!dopt.aclsSkip)
1187 getAdditionalACLs(fout);
1188 if (!dopt.no_comments)
1189 collectComments(fout);
1190 if (!dopt.no_security_labels)
1191 collectSecLabels(fout);
1192
1193 /* For binary upgrade mode, collect required pg_class information. */
1194 if (dopt.binary_upgrade)
1196
1197 /* Collect sequence information. */
1198 collectSequences(fout);
1199
1200 /* Lastly, create dummy objects to represent the section boundaries */
1201 boundaryObjs = createBoundaryObjects();
1202
1203 /* Get pointers to all the known DumpableObjects */
1204 getDumpableObjects(&dobjs, &numObjs);
1205
1206 /*
1207 * Add dummy dependencies to enforce the dump section ordering.
1208 */
1209 addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
1210
1211 /*
1212 * Sort the objects into a safe dump order (no forward references).
1213 *
1214 * We rely on dependency information to help us determine a safe order, so
1215 * the initial sort is mostly for cosmetic purposes: we sort by name to
1216 * ensure that logically identical schemas will dump identically.
1217 */
1218 sortDumpableObjectsByTypeName(dobjs, numObjs);
1219
1220 sortDumpableObjects(dobjs, numObjs,
1221 boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
1222
1223 /*
1224 * Create archive TOC entries for all the objects to be dumped, in a safe
1225 * order.
1226 */
1227
1228 /*
1229 * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
1230 */
1231 dumpEncoding(fout);
1232 dumpStdStrings(fout);
1233 dumpSearchPath(fout);
1234
1235 /* The database items are always next, unless we don't want them at all */
1236 if (dopt.outputCreateDB)
1237 dumpDatabase(fout);
1238
1239 /* Now the rearrangeable objects. */
1240 for (i = 0; i < numObjs; i++)
1241 dumpDumpableObject(fout, dobjs[i]);
1242
1243 /*
1244 * Set up options info to ensure we dump what we want.
1245 */
1246 ropt = NewRestoreOptions();
1247 ropt->filename = filename;
1248
1249 /* if you change this list, see dumpOptionsFromRestoreOptions */
1250 ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
1251 ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
1252 ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
1253 ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
1255 ropt->dropSchema = dopt.outputClean;
1256 ropt->dumpData = dopt.dumpData;
1257 ropt->dumpSchema = dopt.dumpSchema;
1258 ropt->dumpStatistics = dopt.dumpStatistics;
1259 ropt->if_exists = dopt.if_exists;
1260 ropt->column_inserts = dopt.column_inserts;
1261 ropt->dumpSections = dopt.dumpSections;
1262 ropt->aclsSkip = dopt.aclsSkip;
1263 ropt->superuser = dopt.outputSuperuser;
1264 ropt->createDB = dopt.outputCreateDB;
1265 ropt->noOwner = dopt.outputNoOwner;
1266 ropt->noTableAm = dopt.outputNoTableAm;
1267 ropt->noTablespace = dopt.outputNoTablespaces;
1269 ropt->use_setsessauth = dopt.use_setsessauth;
1271 ropt->dump_inserts = dopt.dump_inserts;
1272 ropt->no_comments = dopt.no_comments;
1273 ropt->no_policies = dopt.no_policies;
1274 ropt->no_publications = dopt.no_publications;
1277 ropt->lockWaitTimeout = dopt.lockWaitTimeout;
1280 ropt->sequence_data = dopt.sequence_data;
1281 ropt->binary_upgrade = dopt.binary_upgrade;
1282 ropt->restrict_key = dopt.restrict_key ? pg_strdup(dopt.restrict_key) : NULL;
1283
1284 ropt->compression_spec = compression_spec;
1285
1286 ropt->suppressDumpWarnings = true; /* We've already shown them */
1287
1288 SetArchiveOptions(fout, &dopt, ropt);
1289
1290 /* Mark which entries should be output */
1292
1293 /*
1294 * The archive's TOC entries are now marked as to which ones will actually
1295 * be output, so we can set up their dependency lists properly. This isn't
1296 * necessary for plain-text output, though.
1297 */
1298 if (!plainText)
1300
1301 /*
1302 * And finally we can do the actual output.
1303 *
1304 * Note: for non-plain-text output formats, the output file is written
1305 * inside CloseArchive(). This is, um, bizarre; but not worth changing
1306 * right now.
1307 */
1308 if (plainText)
1309 RestoreArchive(fout);
1310
1311 CloseArchive(fout);
1312
1313 exit_nicely(0);
1314}
TableInfo * getSchemaData(Archive *fout, int *numTablesPtr)
Definition: common.c:98
void on_exit_close_archive(Archive *AHX)
Definition: parallel.c:330
void init_parallel_dump_utils(void)
Definition: parallel.c:238
#define PG_MAX_JOBS
Definition: parallel.h:48
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1212
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:430
char * supports_compression(const pg_compress_specification compression_spec)
Definition: compress_io.c:87
char * validate_compress_specification(pg_compress_specification *spec)
Definition: compression.c:344
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
#define PG_COMPRESSION_OPTION_WORKERS
Definition: compression.h:29
void parse_compress_options(const char *option, char **algorithm, char **detail)
char * generate_restrict_key(void)
Definition: dumputils.c:972
bool valid_restrict_key(const char *restrict_key)
Definition: dumputils.c:996
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:25
#define required_argument
Definition: getopt_long.h:26
static DataDirSyncMethod sync_method
Definition: initdb.c:170
void pg_logging_increase_verbosity(void)
Definition: logging.c:185
void pg_logging_init(const char *argv0)
Definition: logging.c:83
void pg_logging_set_level(enum pg_log_level new_level)
Definition: logging.c:176
@ PG_LOG_WARNING
Definition: logging.h:38
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
bool parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
Definition: option_utils.c:90
void ProcessArchiveRestoreOptions(Archive *AHX)
RestoreOptions * NewRestoreOptions(void)
enum _archiveFormat ArchiveFormat
void ConnectDatabaseAhx(Archive *AHX, const ConnParams *cparams, bool isReconnect)
Definition: pg_backup_db.c:109
void CloseArchive(Archive *AHX)
Archive * CreateArchive(const char *FileSpec, const ArchiveFormat fmt, const pg_compress_specification compression_spec, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker, DataDirSyncMethod sync_method)
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:1663
static void dumpEncoding(Archive *AH)
Definition: pg_dump.c:3835
static SimpleStringList schema_include_patterns
Definition: pg_dump.c:165
static void collectBinaryUpgradeClassOids(Archive *fout)
Definition: pg_dump.c:5823
static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
Definition: pg_dump.c:20137
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3884
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:20113
static void dumpDatabase(Archive *fout)
Definition: pg_dump.c:3282
static SimpleStringList table_include_patterns
Definition: pg_dump.c:170
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:168
static bool have_extra_float_digits
Definition: pg_dump.c:192
static SimpleOidList extension_include_oids
Definition: pg_dump.c:184
static int extra_float_digits
Definition: pg_dump.c:193
static SimpleStringList extension_include_patterns
Definition: pg_dump.c:183
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:187
static SimpleStringList table_exclude_patterns
Definition: pg_dump.c:173
static pg_compress_algorithm compression_algorithm
Definition: pg_dump.c:157
static void dumpStdStrings(Archive *AH)
Definition: pg_dump.c:3860
static void help(const char *progname)
Definition: pg_dump.c:1318
static void BuildArchiveDependencies(Archive *fout)
Definition: pg_dump.c:20263
static void collectRoleNames(Archive *fout)
Definition: pg_dump.c:10716
static bool dosync
Definition: pg_dump.c:150
static void getDependencies(Archive *fout)
Definition: pg_dump.c:19960
static void buildMatViewRefreshDependencies(Archive *fout)
Definition: pg_dump.c:3126
#define DUMP_DEFAULT_ROWS_PER_INSERT
Definition: pg_dump.c:228
static SimpleStringList foreign_servers_include_patterns
Definition: pg_dump.c:180
static void setupDumpWorker(Archive *AH)
Definition: pg_dump.c:1596
static SimpleStringList table_include_patterns_and_children
Definition: pg_dump.c:171
static void getAdditionalACLs(Archive *fout)
Definition: pg_dump.c:10751
static void getTableDataFKConstraints(void)
Definition: pg_dump.c:3241
static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
Definition: pg_dump.c:3020
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:175
static void collectComments(Archive *fout)
Definition: pg_dump.c:11576
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:11661
static void getLOs(Archive *fout)
Definition: pg_dump.c:3946
static void setup_connection(Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role)
Definition: pg_dump.c:1426
static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names, bool with_child_tables)
Definition: pg_dump.c:1827
static void expand_foreign_server_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
Definition: pg_dump.c:1775
static SimpleStringList extension_exclude_patterns
Definition: pg_dump.c:186
static SimpleOidList table_include_oids
Definition: pg_dump.c:172
static SimpleStringList tabledata_exclude_patterns
Definition: pg_dump.c:176
static void collectSecLabels(Archive *fout)
Definition: pg_dump.c:16777
static void collectSequences(Archive *fout)
Definition: pg_dump.c:18911
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode)
Definition: pg_dump.c:1625
static void read_dump_filters(const char *filename, DumpOptions *dopt)
Definition: pg_dump.c:20483
static SimpleStringList tabledata_exclude_patterns_and_children
Definition: pg_dump.c:177
static SimpleOidList tabledata_exclude_oids
Definition: pg_dump.c:178
static SimpleStringList table_exclude_patterns_and_children
Definition: pg_dump.c:174
static SimpleOidList foreign_servers_include_oids
Definition: pg_dump.c:181
static void expand_extension_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
Definition: pg_dump.c:1722
static SimpleOidList schema_include_oids
Definition: pg_dump.c:166
static SimpleStringList schema_exclude_patterns
Definition: pg_dump.c:167
void sortDumpableObjects(DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId)
Definition: pg_dump_sort.c:548
void sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
Definition: pg_dump_sort.c:192
static int statistics_only
Definition: pg_dumpall.c:112
static int no_statistics
Definition: pg_dumpall.c:103
static int no_data
Definition: pg_dumpall.c:101
static int no_schema
Definition: pg_dumpall.c:102
static char * filename
Definition: pg_dumpall.c:120
static int with_statistics
Definition: pg_dumpall.c:108
PGDLLIMPORT int optind
Definition: getopt.c:51
PGDLLIMPORT char * optarg
Definition: getopt.c:53
const char * get_progname(const char *argv0)
Definition: path.c:652
bool quote_all_identifiers
Definition: ruleutils.c:339
void simple_string_list_append(SimpleStringList *list, const char *val)
Definition: simple_list.c:63
int minRemoteVersion
Definition: pg_backup.h:236
bool isStandby
Definition: pg_backup.h:234
int maxRemoteVersion
Definition: pg_backup.h:237
int numWorkers
Definition: pg_backup.h:239
int verbose
Definition: pg_backup.h:231
SimpleOidListCell * head
Definition: simple_list.h:28
char * pgport
Definition: pg_backup.h:87
char * pghost
Definition: pg_backup.h:88
trivalue promptPassword
Definition: pg_backup.h:90
char * username
Definition: pg_backup.h:89
char * dbname
Definition: pg_backup.h:86
char * restrict_key
Definition: pg_backup.h:219
bool dontOutputLOs
Definition: pg_backup.h:207
int use_setsessauth
Definition: pg_backup.h:197
int outputCreateDB
Definition: pg_backup.h:205
bool include_everything
Definition: pg_backup.h:202
bool outputLOs
Definition: pg_backup.h:206
int serializable_deferrable
Definition: pg_backup.h:193
int outputNoTableAm
Definition: pg_backup.h:195
int enable_row_security
Definition: pg_backup.h:198
char * outputSuperuser
Definition: pg_backup.h:209
int dumpSections
Definition: pg_backup.h:177
int no_unlogged_table_data
Definition: pg_backup.h:192
ConnParams cparams
Definition: pg_backup.h:172
int outputClean
Definition: pg_backup.h:204
int disable_triggers
Definition: pg_backup.h:194
int outputNoOwner
Definition: pg_backup.h:208
int include_everything
Definition: pg_backup.h:125
int suppressDumpWarnings
Definition: pg_backup.h:151
ConnParams cparams
Definition: pg_backup.h:145
pg_compress_specification compression_spec
Definition: pg_backup.h:149
int no_subscriptions
Definition: pg_backup.h:117
bool dumpStatistics
Definition: pg_backup.h:165
int disable_dollar_quoting
Definition: pg_backup.h:109
char * restrict_key
Definition: pg_backup.h:167
const char * filename
Definition: pg_backup.h:120
int no_security_labels
Definition: pg_backup.h:116
char * superuser
Definition: pg_backup.h:106
const char * lockWaitTimeout
Definition: pg_backup.h:124
int enable_row_security
Definition: pg_backup.h:158
int disable_triggers
Definition: pg_backup.h:102
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_NO
Definition: vacuumlo.c:37
ArchiveMode
Definition: xlog.h:64

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, addBoundaryDependencies(), addObjectDependency(), archCustom, archDirectory, archNull, archUnknown, _restoreOptions::binary_upgrade, _dumpOptions::binary_upgrade, BuildArchiveDependencies(), buildMatViewRefreshDependencies(), CloseArchive(), collectBinaryUpgradeClassOids(), collectComments(), collectRoleNames(), collectSecLabels(), collectSequences(), _restoreOptions::column_inserts, _dumpOptions::column_inserts, compression_algorithm, _restoreOptions::compression_spec, ConnectDatabaseAhx(), _restoreOptions::cparams, _dumpOptions::cparams, CppAsString2, CreateArchive(), createBoundaryObjects(), _restoreOptions::createDB, DATA_DIR_SYNC_METHOD_FSYNC, _tableInfo::dataObj, _connParams::dbname, _restoreOptions::disable_dollar_quoting, _dumpOptions::disable_dollar_quoting, _restoreOptions::disable_triggers, _dumpOptions::disable_triggers, _dumpOptions::do_nothing, _tableDataInfo::dobj, _dumpOptions::dontOutputLOs, dosync, _restoreOptions::dropSchema, DUMP_DEFAULT_ROWS_PER_INSERT, _restoreOptions::dump_inserts, _dumpOptions::dump_inserts, _restoreOptions::dumpData, _dumpOptions::dumpData, dumpDatabase(), dumpDumpableObject(), dumpEncoding(), _dumpableObject::dumpId, _restoreOptions::dumpSchema, _dumpOptions::dumpSchema, dumpSearchPath(), _restoreOptions::dumpSections, _dumpOptions::dumpSections, _restoreOptions::dumpStatistics, _dumpOptions::dumpStatistics, 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, _tableDataInfo::filtercond, findTableByOid(), FirstNormalObjectId, foreign_servers_include_oids, foreign_servers_include_patterns, format, g_last_builtin_oid, generate_restrict_key(), 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, lo_metadata_dumpId, _dumpOptions::load_via_partition_root, _restoreOptions::lockWaitTimeout, _dumpOptions::lockWaitTimeout, makeTableDataInfo(), Archive::maxRemoteVersion, Archive::minRemoteVersion, NewRestoreOptions(), no_argument, _restoreOptions::no_comments, _dumpOptions::no_comments, no_data, _restoreOptions::no_policies, _dumpOptions::no_policies, _restoreOptions::no_publications, _dumpOptions::no_publications, no_schema, _restoreOptions::no_security_labels, _dumpOptions::no_security_labels, no_statistics, _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(), Archive::remoteVersion, required_argument, RestoreArchive(), _restoreOptions::restrict_key, _dumpOptions::restrict_key, schema_exclude_oids, schema_exclude_patterns, schema_include_oids, schema_include_patterns, _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(), statistics_only, 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, valid_restrict_key(), validate_compress_specification(), Archive::verbose, and with_statistics.

◆ makeTableDataInfo()

static void makeTableDataInfo ( DumpOptions dopt,
TableInfo tbinfo 
)
static

Definition at line 3039 of file pg_dump.c.

3040{
3041 TableDataInfo *tdinfo;
3042
3043 /*
3044 * Nothing to do if we already decided to dump the table. This will
3045 * happen for "config" tables.
3046 */
3047 if (tbinfo->dataObj != NULL)
3048 return;
3049
3050 /* Skip VIEWs (no data to dump) */
3051 if (tbinfo->relkind == RELKIND_VIEW)
3052 return;
3053 /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
3054 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
3057 tbinfo->foreign_server)))
3058 return;
3059 /* Skip partitioned tables (data in partitions) */
3060 if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
3061 return;
3062
3063 /* Don't dump data in unlogged tables, if so requested */
3064 if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
3066 return;
3067
3068 /* Check that the data is not explicitly excluded */
3070 tbinfo->dobj.catId.oid))
3071 return;
3072
3073 /* OK, let's dump it */
3074 tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
3075
3076 if (tbinfo->relkind == RELKIND_MATVIEW)
3078 else if (tbinfo->relkind == RELKIND_SEQUENCE)
3079 tdinfo->dobj.objType = DO_SEQUENCE_SET;
3080 else
3081 tdinfo->dobj.objType = DO_TABLE_DATA;
3082
3083 /*
3084 * Note: use tableoid 0 so that this object won't be mistaken for
3085 * something that pg_depend entries apply to.
3086 */
3087 tdinfo->dobj.catId.tableoid = 0;
3088 tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
3089 AssignDumpId(&tdinfo->dobj);
3090 tdinfo->dobj.name = tbinfo->dobj.name;
3091 tdinfo->dobj.namespace = tbinfo->dobj.namespace;
3092 tdinfo->tdtable = tbinfo;
3093 tdinfo->filtercond = NULL; /* might get set later */
3094 addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
3095
3096 /* A TableDataInfo contains data, of course */
3098
3099 tbinfo->dataObj = tdinfo;
3100
3101 /*
3102 * Materialized view statistics must be restored after the data, because
3103 * REFRESH MATERIALIZED VIEW replaces the storage and resets the stats.
3104 *
3105 * The dependency is added here because the statistics objects are created
3106 * first.
3107 */
3108 if (tbinfo->relkind == RELKIND_MATVIEW && tbinfo->stats != NULL)
3109 {
3110 tbinfo->stats->section = SECTION_POST_DATA;
3111 addObjectDependency(&tbinfo->stats->dobj, tdinfo->dobj.dumpId);
3112 }
3113
3114 /* Make sure that we'll collect per-column info for this table. */
3115 tbinfo->interesting = true;
3116}
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, _relStatsInfo::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, _relStatsInfo::section, SECTION_POST_DATA, simple_oid_list_member(), _tableInfo::stats, tabledata_exclude_oids, CatalogId::tableoid, and _tableDataInfo::tdtable.

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

◆ nonemptyReloptions()

static bool nonemptyReloptions ( const char *  reloptions)
static

Definition at line 20452 of file pg_dump.c.

20453{
20454 /* Don't want to print it if it's just "{}" */
20455 return (reloptions != NULL && strlen(reloptions) > 2);
20456}

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

◆ parse_sequence_type()

static SeqType parse_sequence_type ( const char *  name)
inlinestatic

Definition at line 18880 of file pg_dump.c.

18881{
18882 for (int i = 0; i < lengthof(SeqTypeNames); i++)
18883 {
18884 if (strcmp(SeqTypeNames[i], name) == 0)
18885 return (SeqType) i;
18886 }
18887
18888 pg_fatal("unrecognized sequence type: %s", name);
18889 return (SeqType) 0; /* keep compiler quiet */
18890}
#define lengthof(array)
Definition: c.h:801

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

Referenced by collectSequences(), and dumpSequence().

◆ parseArchiveFormat()

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

Definition at line 1625 of file pg_dump.c.

1626{
1627 ArchiveFormat archiveFormat;
1628
1630
1631 if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
1632 {
1633 /* This is used by pg_dumpall, and is not documented */
1634 archiveFormat = archNull;
1636 }
1637 else if (pg_strcasecmp(format, "c") == 0)
1638 archiveFormat = archCustom;
1639 else if (pg_strcasecmp(format, "custom") == 0)
1640 archiveFormat = archCustom;
1641 else if (pg_strcasecmp(format, "d") == 0)
1642 archiveFormat = archDirectory;
1643 else if (pg_strcasecmp(format, "directory") == 0)
1644 archiveFormat = archDirectory;
1645 else if (pg_strcasecmp(format, "p") == 0)
1646 archiveFormat = archNull;
1647 else if (pg_strcasecmp(format, "plain") == 0)
1648 archiveFormat = archNull;
1649 else if (pg_strcasecmp(format, "t") == 0)
1650 archiveFormat = archTar;
1651 else if (pg_strcasecmp(format, "tar") == 0)
1652 archiveFormat = archTar;
1653 else
1654 pg_fatal("invalid output format \"%s\" specified", format);
1655 return archiveFormat;
1656}
@ archModeWrite
Definition: pg_backup.h:51
@ archModeAppend
Definition: pg_backup.h:50
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 19779 of file pg_dump.c.

19781{
19782 DumpOptions *dopt = fout->dopt;
19783 PQExpBuffer query;
19784 PGresult *res;
19785 int ntups,
19786 i;
19787 int i_conrelid,
19788 i_confrelid;
19789
19790 /* Nothing to do if no extensions */
19791 if (numExtensions == 0)
19792 return;
19793
19794 /*
19795 * Identify extension configuration tables and create TableDataInfo
19796 * objects for them, ensuring their data will be dumped even though the
19797 * tables themselves won't be.
19798 *
19799 * Note that we create TableDataInfo objects even in schema-only mode, ie,
19800 * user data in a configuration table is treated like schema data. This
19801 * seems appropriate since system data in a config table would get
19802 * reloaded by CREATE EXTENSION. If the extension is not listed in the
19803 * list of extensions to be included, none of its data is dumped.
19804 */
19805 for (i = 0; i < numExtensions; i++)
19806 {
19807 ExtensionInfo *curext = &(extinfo[i]);
19808 char *extconfig = curext->extconfig;
19809 char *extcondition = curext->extcondition;
19810 char **extconfigarray = NULL;
19811 char **extconditionarray = NULL;
19812 int nconfigitems = 0;
19813 int nconditionitems = 0;
19814
19815 /*
19816 * Check if this extension is listed as to include in the dump. If
19817 * not, any table data associated with it is discarded.
19818 */
19819 if (extension_include_oids.head != NULL &&
19821 curext->dobj.catId.oid))
19822 continue;
19823
19824 /*
19825 * Check if this extension is listed as to exclude in the dump. If
19826 * yes, any table data associated with it is discarded.
19827 */
19828 if (extension_exclude_oids.head != NULL &&
19830 curext->dobj.catId.oid))
19831 continue;
19832
19833 if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
19834 {
19835 int j;
19836
19837 if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
19838 pg_fatal("could not parse %s array", "extconfig");
19839 if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
19840 pg_fatal("could not parse %s array", "extcondition");
19841 if (nconfigitems != nconditionitems)
19842 pg_fatal("mismatched number of configurations and conditions for extension");
19843
19844 for (j = 0; j < nconfigitems; j++)
19845 {
19846 TableInfo *configtbl;
19847 Oid configtbloid = atooid(extconfigarray[j]);
19848 bool dumpobj =
19850
19851 configtbl = findTableByOid(configtbloid);
19852 if (configtbl == NULL)
19853 continue;
19854
19855 /*
19856 * Tables of not-to-be-dumped extensions shouldn't be dumped
19857 * unless the table or its schema is explicitly included
19858 */
19859 if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
19860 {
19861 /* check table explicitly requested */
19862 if (table_include_oids.head != NULL &&
19864 configtbloid))
19865 dumpobj = true;
19866
19867 /* check table's schema explicitly requested */
19868 if (configtbl->dobj.namespace->dobj.dump &
19870 dumpobj = true;
19871 }
19872
19873 /* check table excluded by an exclusion switch */
19874 if (table_exclude_oids.head != NULL &&
19876 configtbloid))
19877 dumpobj = false;
19878
19879 /* check schema excluded by an exclusion switch */
19881 configtbl->dobj.namespace->dobj.catId.oid))
19882 dumpobj = false;
19883
19884 if (dumpobj)
19885 {
19886 makeTableDataInfo(dopt, configtbl);
19887 if (configtbl->dataObj != NULL)
19888 {
19889 if (strlen(extconditionarray[j]) > 0)
19890 configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
19891 }
19892 }
19893 }
19894 }
19895 if (extconfigarray)
19896 free(extconfigarray);
19897 if (extconditionarray)
19898 free(extconditionarray);
19899 }
19900
19901 /*
19902 * Now that all the TableDataInfo objects have been created for all the
19903 * extensions, check their FK dependencies and register them to try and
19904 * dump the data out in an order that they can be restored in.
19905 *
19906 * Note that this is not a problem for user tables as their FKs are
19907 * recreated after the data has been loaded.
19908 */
19909
19910 query = createPQExpBuffer();
19911
19912 printfPQExpBuffer(query,
19913 "SELECT conrelid, confrelid "
19914 "FROM pg_constraint "
19915 "JOIN pg_depend ON (objid = confrelid) "
19916 "WHERE contype = 'f' "
19917 "AND refclassid = 'pg_extension'::regclass "
19918 "AND classid = 'pg_class'::regclass;");
19919
19920 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19921 ntups = PQntuples(res);
19922
19923 i_conrelid = PQfnumber(res, "conrelid");
19924 i_confrelid = PQfnumber(res, "confrelid");
19925
19926 /* Now get the dependencies and register them */
19927 for (i = 0; i < ntups; i++)
19928 {
19929 Oid conrelid,
19930 confrelid;
19931 TableInfo *reftable,
19932 *contable;
19933
19934 conrelid = atooid(PQgetvalue(res, i, i_conrelid));
19935 confrelid = atooid(PQgetvalue(res, i, i_confrelid));
19936 contable = findTableByOid(conrelid);
19937 reftable = findTableByOid(confrelid);
19938
19939 if (reftable == NULL ||
19940 reftable->dataObj == NULL ||
19941 contable == NULL ||
19942 contable->dataObj == NULL)
19943 continue;
19944
19945 /*
19946 * Make referencing TABLE_DATA object depend on the referenced table's
19947 * TABLE_DATA object.
19948 */
19949 addObjectDependency(&contable->dataObj->dobj,
19950 reftable->dataObj->dobj.dumpId);
19951 }
19952 PQclear(res);
19953 destroyPQExpBuffer(query);
19954}

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

1924{
1925 const char *db;
1926
1927 db = PQdb(conn);
1928 if (db == NULL)
1929 pg_fatal("You are currently not connected to a database.");
1930
1931 if (strcmp(db, dbname) != 0)
1932 pg_fatal("cross-database references are not implemented: %s",
1933 pattern);
1934}
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:7538

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

20484{
20485 FilterStateData fstate;
20486 char *objname;
20487 FilterCommandType comtype;
20488 FilterObjectType objtype;
20489
20490 filter_init(&fstate, filename, exit_nicely);
20491
20492 while (filter_read_item(&fstate, &objname, &comtype, &objtype))
20493 {
20494 if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
20495 {
20496 switch (objtype)
20497 {
20499 break;
20506 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20507 "include",
20508 filter_object_type_name(objtype));
20509 exit_nicely(1);
20510 break; /* unreachable */
20511
20514 break;
20517 break;
20520 dopt->include_everything = false;
20521 break;
20524 dopt->include_everything = false;
20525 break;
20528 objname);
20529 dopt->include_everything = false;
20530 break;
20531 }
20532 }
20533 else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
20534 {
20535 switch (objtype)
20536 {
20538 break;
20544 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20545 "exclude",
20546 filter_object_type_name(objtype));
20547 exit_nicely(1);
20548 break;
20549
20552 break;
20555 objname);
20556 break;
20559 objname);
20560 break;
20563 break;
20566 break;
20569 objname);
20570 break;
20571 }
20572 }
20573 else
20574 {
20575 Assert(comtype == FILTER_COMMAND_TYPE_NONE);
20576 Assert(objtype == FILTER_OBJECT_TYPE_NONE);
20577 }
20578
20579 if (objname)
20580 free(objname);
20581 }
20582
20583 filter_free(&fstate);
20584}
void filter_init(FilterStateData *fstate, const char *filename, exit_function f_exit)
Definition: filter.c:36
void filter_free(FilterStateData *fstate)
Definition: filter.c:60
const char * filter_object_type_name(FilterObjectType fot)
Definition: filter.c:82
bool filter_read_item(FilterStateData *fstate, char **objname, FilterCommandType *comtype, FilterObjectType *objtype)
Definition: filter.c:392
void pg_log_filter_error(FilterStateData *fstate, const char *fmt,...)
Definition: filter.c:154
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 2985 of file pg_dump.c.

2986{
2987 TableInfo *tbinfo = tdinfo->tdtable;
2988 PQExpBuffer q;
2989
2990 /* If the materialized view is not flagged as populated, skip this. */
2991 if (!tbinfo->relispopulated)
2992 return;
2993
2994 q = createPQExpBuffer();
2995
2996 appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
2997 fmtQualifiedDumpable(tbinfo));
2998
2999 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
3000 ArchiveEntry(fout,
3001 tdinfo->dobj.catId, /* catalog ID */
3002 tdinfo->dobj.dumpId, /* dump ID */
3003 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
3004 .namespace = tbinfo->dobj.namespace->dobj.name,
3005 .owner = tbinfo->rolname,
3006 .description = "MATERIALIZED VIEW DATA",
3007 .section = SECTION_POST_DATA,
3008 .createStmt = q->data,
3009 .deps = tdinfo->dobj.dependencies,
3010 .nDeps = tdinfo->dobj.nDeps));
3011
3013}

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

2249{
2250 /* see getAccessMethods() comment about v9.6. */
2251 if (fout->remoteVersion < 90600)
2252 {
2253 method->dobj.dump = DUMP_COMPONENT_NONE;
2254 return;
2255 }
2256
2257 if (checkExtensionMembership(&method->dobj, fout))
2258 return; /* extension membership overrides all else */
2259
2260 /*
2261 * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
2262 * they do not support ACLs currently.
2263 */
2264 if (method->dobj.catId.oid <= g_last_builtin_oid)
2265 method->dobj.dump = DUMP_COMPONENT_NONE;
2266 else
2267 method->dobj.dump = fout->dopt->include_everything ?
2269}
static bool checkExtensionMembership(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:1948
#define DUMP_COMPONENT_ALL
Definition: pg_dump.h:117

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

Referenced by getAccessMethods().

◆ selectDumpableCast()

static void selectDumpableCast ( CastInfo cast,
Archive fout 
)
static

Definition at line 2190 of file pg_dump.c.

2191{
2192 if (checkExtensionMembership(&cast->dobj, fout))
2193 return; /* extension membership overrides all else */
2194
2195 /*
2196 * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
2197 * support ACLs currently.
2198 */
2199 if (cast->dobj.catId.oid <= g_last_builtin_oid)
2201 else
2202 cast->dobj.dump = fout->dopt->include_everything ?
2204}

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

2169{
2170 /* Default ACLs can't be extension members */
2171
2172 if (dinfo->dobj.namespace)
2173 /* default ACLs are considered part of the namespace */
2174 dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
2175 else
2176 dinfo->dobj.dump = dopt->include_everything ?
2178}

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

2284{
2285 /*
2286 * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
2287 * change permissions on their member objects, if they wish to, and have
2288 * those changes preserved.
2289 */
2290 if (extinfo->dobj.catId.oid <= g_last_builtin_oid)
2291 extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
2292 else
2293 {
2294 /* check if there is a list of extensions to dump */
2295 if (extension_include_oids.head != NULL)
2296 extinfo->dobj.dump = extinfo->dobj.dump_contains =
2298 extinfo->dobj.catId.oid) ?
2300 else
2301 extinfo->dobj.dump = extinfo->dobj.dump_contains =
2302 dopt->include_everything ?
2304
2305 /* check that the extension is not explicitly excluded */
2306 if (extinfo->dobj.dump &&
2308 extinfo->dobj.catId.oid))
2309 extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
2310 }
2311}

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

1999{
2000 /*
2001 * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
2002 * and (for --clean) a DROP SCHEMA statement. (In the absence of
2003 * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
2004 */
2005 nsinfo->create = true;
2006
2007 /*
2008 * If specific tables are being dumped, do not dump any complete
2009 * namespaces. If specific namespaces are being dumped, dump just those
2010 * namespaces. Otherwise, dump all non-system namespaces.
2011 */
2012 if (table_include_oids.head != NULL)
2013 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
2014 else if (schema_include_oids.head != NULL)
2015 nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
2017 nsinfo->dobj.catId.oid) ?
2019 else if (fout->remoteVersion >= 90600 &&
2020 strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
2021 {
2022 /*
2023 * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
2024 * they are interesting (and not the original ACLs which were set at
2025 * initdb time, see pg_init_privs).
2026 */
2027 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
2028 }
2029 else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
2030 strcmp(nsinfo->dobj.name, "information_schema") == 0)
2031 {
2032 /* Other system schemas don't get dumped */
2033 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
2034 }
2035 else if (strcmp(nsinfo->dobj.name, "public") == 0)
2036 {
2037 /*
2038 * The public schema is a strange beast that sits in a sort of
2039 * no-mans-land between being a system object and a user object.
2040 * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
2041 * a comment and an indication of ownership. If the owner is the
2042 * default, omit that superfluous DUMP_COMPONENT_DEFINITION. Before
2043 * v15, the default owner was BOOTSTRAP_SUPERUSERID.
2044 */
2045 nsinfo->create = false;
2046 nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
2047 if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
2048 nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
2050
2051 /*
2052 * Also, make like it has a comment even if it doesn't; this is so
2053 * that we'll emit a command to drop the comment, if appropriate.
2054 * (Without this, we'd not call dumpCommentExtended for it.)
2055 */
2057 }
2058 else
2059 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
2060
2061 /*
2062 * In any case, a namespace can be excluded by an exclusion switch
2063 */
2064 if (nsinfo->dobj.dump_contains &&
2066 nsinfo->dobj.catId.oid))
2067 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
2068
2069 /*
2070 * If the schema belongs to an extension, allow extension membership to
2071 * override the dump decision for the schema itself. However, this does
2072 * not change dump_contains, so this won't change what we do with objects
2073 * within the schema. (If they belong to the extension, they'll get
2074 * suppressed by it, otherwise not.)
2075 */
2076 (void) checkExtensionMembership(&nsinfo->dobj, fout);
2077}

References _dumpableObject::catId, checkExtensionMembership(), _dumpableObject::components, _namespaceInfo::create, _namespaceInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_ALL, DUMP_COMPONENT_COMMENT, 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 2358 of file pg_dump.c.

2359{
2360 if (checkExtensionMembership(dobj, fout))
2361 return; /* extension membership overrides all else */
2362
2363 /*
2364 * Default policy is to dump if parent namespace is dumpable, or for
2365 * non-namespace-associated items, dump if we're dumping "everything".
2366 */
2367 if (dobj->namespace)
2368 dobj->dump = dobj->namespace->dobj.dump_contains;
2369 else
2370 dobj->dump = fout->dopt->include_everything ?
2372}

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(), getSubscriptionRelations(), getSubscriptions(), getTransforms(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), and getTSTemplates().

◆ selectDumpableProcLang()

static void selectDumpableProcLang ( ProcLangInfo plang,
Archive fout 
)
static

Definition at line 2215 of file pg_dump.c.

2216{
2217 if (checkExtensionMembership(&plang->dobj, fout))
2218 return; /* extension membership overrides all else */
2219
2220 /*
2221 * Only include procedural languages when we are dumping everything.
2222 *
2223 * For from-initdb procedural languages, only include ACLs, as we do for
2224 * the pg_catalog namespace. We need this because procedural languages do
2225 * not live in any namespace.
2226 */
2227 if (!fout->dopt->include_everything)
2228 plang->dobj.dump = DUMP_COMPONENT_NONE;
2229 else
2230 {
2231 if (plang->dobj.catId.oid <= g_last_builtin_oid)
2232 plang->dobj.dump = fout->remoteVersion < 90600 ?
2234 else
2235 plang->dobj.dump = DUMP_COMPONENT_ALL;
2236 }
2237}

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

2323{
2324 if (checkExtensionMembership(dobj, fout))
2325 return; /* extension membership overrides all else */
2326
2327 dobj->dump = fout->dopt->include_everything ?
2329}

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

2341{
2342 if (checkExtensionMembership(&sobj->dobj, fout))
2343 return; /* extension membership overrides all else */
2344
2345 sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
2346 if (sobj->stattable == NULL ||
2349}

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

2085{
2086 if (checkExtensionMembership(&tbinfo->dobj, fout))
2087 return; /* extension membership overrides all else */
2088
2089 /*
2090 * If specific tables are being dumped, dump just those tables; else, dump
2091 * according to the parent namespace's dump flag.
2092 */
2093 if (table_include_oids.head != NULL)
2095 tbinfo->dobj.catId.oid) ?
2097 else
2098 tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
2099
2100 /*
2101 * In any case, a table can be excluded by an exclusion switch
2102 */
2103 if (tbinfo->dobj.dump &&
2105 tbinfo->dobj.catId.oid))
2106 tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
2107}

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

2124{
2125 /* skip complex types, except for standalone composite types */
2126 if (OidIsValid(tyinfo->typrelid) &&
2127 tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
2128 {
2129 TableInfo *tytable = findTableByOid(tyinfo->typrelid);
2130
2131 tyinfo->dobj.objType = DO_DUMMY_TYPE;
2132 if (tytable != NULL)
2133 tyinfo->dobj.dump = tytable->dobj.dump;
2134 else
2135 tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
2136 return;
2137 }
2138
2139 /* skip auto-generated array and multirange types */
2140 if (tyinfo->isArray || tyinfo->isMultirange)
2141 {
2142 tyinfo->dobj.objType = DO_DUMMY_TYPE;
2143
2144 /*
2145 * Fall through to set the dump flag; we assume that the subsequent
2146 * rules will do the same thing as they would for the array's base
2147 * type or multirange's range type. (We cannot reliably look up the
2148 * base type here, since getTypes may not have processed it yet.)
2149 */
2150 }
2151
2152 if (checkExtensionMembership(&tyinfo->dobj, fout))
2153 return; /* extension membership overrides all else */
2154
2155 /* Dump based on if the contents of the namespace are being dumped */
2156 tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
2157}

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

Referenced by getTypes().

◆ SequenceItemCmp()

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

Definition at line 18896 of file pg_dump.c.

18897{
18898 SequenceItem v1 = *((const SequenceItem *) p1);
18899 SequenceItem v2 = *((const SequenceItem *) p2);
18900
18901 return pg_cmp_u32(v1.oid, v2.oid);
18902}

References SequenceItem::oid, and pg_cmp_u32().

Referenced by dumpSequence(), and dumpSequenceData().

◆ set_restrict_relation_kind()

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

Definition at line 5086 of file pg_dump.c.

5087{
5089 PGresult *res;
5090
5091 appendPQExpBuffer(query,
5092 "SELECT set_config(name, '%s', false) "
5093 "FROM pg_settings "
5094 "WHERE name = 'restrict_nonsystem_relation_kind'",
5095 value);
5096 res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
5097
5098 PQclear(res);
5099 destroyPQExpBuffer(query);
5100}
static struct @171 value

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

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

◆ setup_connection()

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

Definition at line 1426 of file pg_dump.c.

1428{
1429 DumpOptions *dopt = AH->dopt;
1430 PGconn *conn = GetConnection(AH);
1431 const char *std_strings;
1432
1434
1435 /*
1436 * Set the client encoding if requested.
1437 */
1438 if (dumpencoding)
1439 {
1440 if (PQsetClientEncoding(conn, dumpencoding) < 0)
1441 pg_fatal("invalid client encoding \"%s\" specified",
1442 dumpencoding);
1443 }
1444
1445 /*
1446 * Get the active encoding and the standard_conforming_strings setting, so
1447 * we know how to escape strings.
1448 */
1451
1452 std_strings = PQparameterStatus(conn, "standard_conforming_strings");
1453 AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
1454
1455 /*
1456 * Set the role if requested. In a parallel dump worker, we'll be passed
1457 * use_role == NULL, but AH->use_role is already set (if user specified it
1458 * originally) and we should use that.
1459 */
1460 if (!use_role && AH->use_role)
1461 use_role = AH->use_role;
1462
1463 /* Set the role if requested */
1464 if (use_role)
1465 {
1467
1468 appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
1469 ExecuteSqlStatement(AH, query->data);
1470 destroyPQExpBuffer(query);
1471
1472 /* save it for possible later use by parallel workers */
1473 if (!AH->use_role)
1474 AH->use_role = pg_strdup(use_role);
1475 }
1476
1477 /* Set the datestyle to ISO to ensure the dump's portability */
1478 ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
1479
1480 /* Likewise, avoid using sql_standard intervalstyle */
1481 ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
1482
1483 /*
1484 * Use an explicitly specified extra_float_digits if it has been provided.
1485 * Otherwise, set extra_float_digits so that we can dump float data
1486 * exactly (given correctly implemented float I/O code, anyway).
1487 */
1489 {
1491
1492 appendPQExpBuffer(q, "SET extra_float_digits TO %d",
1494 ExecuteSqlStatement(AH, q->data);
1496 }
1497 else
1498 ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
1499
1500 /*
1501 * Disable synchronized scanning, to prevent unpredictable changes in row
1502 * ordering across a dump and reload.
1503 */
1504 ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
1505
1506 /*
1507 * Disable timeouts if supported.
1508 */
1509 ExecuteSqlStatement(AH, "SET statement_timeout = 0");
1510 if (AH->remoteVersion >= 90300)
1511 ExecuteSqlStatement(AH, "SET lock_timeout = 0");
1512 if (AH->remoteVersion >= 90600)
1513 ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
1514 if (AH->remoteVersion >= 170000)
1515 ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
1516
1517 /*
1518 * Quote all identifiers, if requested.
1519 */
1521 ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
1522
1523 /*
1524 * Adjust row-security mode, if supported.
1525 */
1526 if (AH->remoteVersion >= 90500)
1527 {
1528 if (dopt->enable_row_security)
1529 ExecuteSqlStatement(AH, "SET row_security = on");
1530 else
1531 ExecuteSqlStatement(AH, "SET row_security = off");
1532 }
1533
1534 /*
1535 * For security reasons, we restrict the expansion of non-system views and
1536 * access to foreign tables during the pg_dump process. This restriction
1537 * is adjusted when dumping foreign table data.
1538 */
1539 set_restrict_relation_kind(AH, "view, foreign-table");
1540
1541 /*
1542 * Initialize prepared-query state to "nothing prepared". We do this here
1543 * so that a parallel dump worker will have its own state.
1544 */
1545 AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
1546
1547 /*
1548 * Start transaction-snapshot mode transaction to dump consistent data.
1549 */
1550 ExecuteSqlStatement(AH, "BEGIN");
1551
1552 /*
1553 * To support the combination of serializable_deferrable with the jobs
1554 * option we use REPEATABLE READ for the worker connections that are
1555 * passed a snapshot. As long as the snapshot is acquired in a
1556 * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
1557 * REPEATABLE READ transaction provides the appropriate integrity
1558 * guarantees. This is a kluge, but safe for back-patching.
1559 */
1560 if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
1562 "SET TRANSACTION ISOLATION LEVEL "
1563 "SERIALIZABLE, READ ONLY, DEFERRABLE");
1564 else
1566 "SET TRANSACTION ISOLATION LEVEL "
1567 "REPEATABLE READ, READ ONLY");
1568
1569 /*
1570 * If user specified a snapshot to use, select that. In a parallel dump
1571 * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
1572 * is already set (if the server can handle it) and we should use that.
1573 */
1574 if (dumpsnapshot)
1575 AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
1576
1577 if (AH->sync_snapshot_id)
1578 {
1580
1581 appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
1583 ExecuteSqlStatement(AH, query->data);
1584 destroyPQExpBuffer(query);
1585 }
1586 else if (AH->numWorkers > 1)
1587 {
1588 if (AH->isStandby && AH->remoteVersion < 100000)
1589 pg_fatal("parallel dumps from standby servers are not supported by this server version");
1591 }
1592}
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7794
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7802
#define NUM_PREP_QUERIES
Definition: pg_backup.h:80
static char * get_synchronized_snapshot(Archive *fout)
Definition: pg_dump.c:1611
void setFmtEncoding(int encoding)
Definition: string_utils.c:69
char * use_role
Definition: pg_backup.h:248
char * sync_snapshot_id
Definition: pg_backup.h:240

References ALWAYS_SECURE_SEARCH_PATH_SQL, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), conn, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::dopt, _dumpOptions::enable_row_security, Archive::encoding, ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), extra_float_digits, fmtId(), get_synchronized_snapshot(), GetConnection(), have_extra_float_digits, Archive::is_prepared, Archive::isStandby, NUM_PREP_QUERIES, Archive::numWorkers, pg_fatal, pg_malloc0(), pg_strdup(), PQclear, PQclientEncoding(), PQparameterStatus(), PQsetClientEncoding(), quote_all_identifiers, Archive::remoteVersion, _dumpOptions::serializable_deferrable, set_restrict_relation_kind(), setFmtEncoding(), 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 1596 of file pg_dump.c.

1597{
1598 /*
1599 * We want to re-select all the same values the leader connection is
1600 * using. We'll have inherited directly-usable values in
1601 * AH->sync_snapshot_id and AH->use_role, but we need to translate the
1602 * inherited encoding value back to a string to pass to setup_connection.
1603 */
1606 NULL,
1607 NULL);
1608}

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

10139{
10140 if (dopt->binary_upgrade)
10141 return true;
10142 if (tbinfo->attisdropped[colno])
10143 return false;
10144 return (tbinfo->attislocal[colno] || tbinfo->ispartition);
10145}

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

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

◆ StaticAssertDecl()

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

Variable Documentation

◆ binaryUpgradeClassOids

BinaryUpgradeClassOidItem* binaryUpgradeClassOids = NULL
static

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

Referenced by main().

◆ dosync

bool dosync = true
static

Definition at line 150 of file pg_dump.c.

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

◆ extension_exclude_oids

SimpleOidList extension_exclude_oids = {NULL, NULL}
static

Definition at line 187 of file pg_dump.c.

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

◆ extension_exclude_patterns

SimpleStringList extension_exclude_patterns = {NULL, NULL}
static

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

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

◆ extension_include_patterns

SimpleStringList extension_include_patterns = {NULL, NULL}
static

Definition at line 183 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ extra_float_digits

int extra_float_digits
static

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

Referenced by main(), and setup_connection().

◆ lo_metadata_dumpId

DumpId lo_metadata_dumpId
static

Definition at line 219 of file pg_dump.c.

Referenced by getLOs(), and main().

◆ nbinaryUpgradeClassOids

int nbinaryUpgradeClassOids = 0
static

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

Referenced by collectRoleNames(), and getRoleName().

◆ nseclabels

int nseclabels = 0
static

Definition at line 205 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ nsequences

int nsequences = 0
static

Definition at line 213 of file pg_dump.c.

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

◆ rolenames

RoleNameItem* rolenames = NULL
static

Definition at line 196 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ schema_exclude_oids

SimpleOidList schema_exclude_oids = {NULL, NULL}
static

Definition at line 168 of file pg_dump.c.

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

◆ schema_exclude_patterns

SimpleStringList schema_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and selectDumpableNamespace().

◆ schema_include_patterns

SimpleStringList schema_include_patterns = {NULL, NULL}
static

Definition at line 165 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ seclabels

SecLabelItem* seclabels = NULL
static

Definition at line 204 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ SeqTypeNames

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

Definition at line 118 of file pg_dump.c.

Referenced by dumpSequence(), and parse_sequence_type().

◆ sequences

◆ strict_names

int strict_names = 0
static

◆ table_exclude_oids

SimpleOidList table_exclude_oids = {NULL, NULL}
static

Definition at line 175 of file pg_dump.c.

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

◆ table_exclude_patterns

SimpleStringList table_exclude_patterns = {NULL, NULL}
static

Definition at line 173 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 174 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 170 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 171 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 178 of file pg_dump.c.

Referenced by main(), and makeTableDataInfo().

◆ tabledata_exclude_patterns

SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and read_dump_filters().