PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_dump.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_aggregate_d.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_attribute_d.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_cast_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_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 20123 of file pg_dump.c.

20125{
20126 DumpableObject *preDataBound = boundaryObjs + 0;
20127 DumpableObject *postDataBound = boundaryObjs + 1;
20128 int i;
20129
20130 for (i = 0; i < numObjs; i++)
20131 {
20132 DumpableObject *dobj = dobjs[i];
20133
20134 /*
20135 * The classification of object types here must match the SECTION_xxx
20136 * values assigned during subsequent ArchiveEntry calls!
20137 */
20138 switch (dobj->objType)
20139 {
20140 case DO_NAMESPACE:
20141 case DO_EXTENSION:
20142 case DO_TYPE:
20143 case DO_SHELL_TYPE:
20144 case DO_FUNC:
20145 case DO_AGG:
20146 case DO_OPERATOR:
20147 case DO_ACCESS_METHOD:
20148 case DO_OPCLASS:
20149 case DO_OPFAMILY:
20150 case DO_COLLATION:
20151 case DO_CONVERSION:
20152 case DO_TABLE:
20153 case DO_TABLE_ATTACH:
20154 case DO_ATTRDEF:
20155 case DO_PROCLANG:
20156 case DO_CAST:
20157 case DO_DUMMY_TYPE:
20158 case DO_TSPARSER:
20159 case DO_TSDICT:
20160 case DO_TSTEMPLATE:
20161 case DO_TSCONFIG:
20162 case DO_FDW:
20163 case DO_FOREIGN_SERVER:
20164 case DO_TRANSFORM:
20165 /* Pre-data objects: must come before the pre-data boundary */
20166 addObjectDependency(preDataBound, dobj->dumpId);
20167 break;
20168 case DO_TABLE_DATA:
20169 case DO_SEQUENCE_SET:
20170 case DO_LARGE_OBJECT:
20172 /* Data objects: must come between the boundaries */
20173 addObjectDependency(dobj, preDataBound->dumpId);
20174 addObjectDependency(postDataBound, dobj->dumpId);
20175 break;
20176 case DO_INDEX:
20177 case DO_INDEX_ATTACH:
20178 case DO_STATSEXT:
20179 case DO_REFRESH_MATVIEW:
20180 case DO_TRIGGER:
20181 case DO_EVENT_TRIGGER:
20182 case DO_DEFAULT_ACL:
20183 case DO_POLICY:
20184 case DO_PUBLICATION:
20185 case DO_PUBLICATION_REL:
20187 case DO_SUBSCRIPTION:
20189 /* Post-data objects: must come after the post-data boundary */
20190 addObjectDependency(dobj, postDataBound->dumpId);
20191 break;
20192 case DO_RULE:
20193 /* Rules are post-data, but only if dumped separately */
20194 if (((RuleInfo *) dobj)->separate)
20195 addObjectDependency(dobj, postDataBound->dumpId);
20196 break;
20197 case DO_CONSTRAINT:
20198 case DO_FK_CONSTRAINT:
20199 /* Constraints are post-data, but only if dumped separately */
20200 if (((ConstraintInfo *) dobj)->separate)
20201 addObjectDependency(dobj, postDataBound->dumpId);
20202 break;
20204 /* nothing to do */
20205 break;
20207 /* must come after the pre-data boundary */
20208 addObjectDependency(dobj, preDataBound->dumpId);
20209 break;
20210 case DO_REL_STATS:
20211 /* stats section varies by parent object type, DATA or POST */
20212 if (((RelStatsInfo *) dobj)->section == SECTION_DATA)
20213 {
20214 addObjectDependency(dobj, preDataBound->dumpId);
20215 addObjectDependency(postDataBound, dobj->dumpId);
20216 }
20217 else
20218 addObjectDependency(dobj, postDataBound->dumpId);
20219 break;
20220 }
20221 }
20222}
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 8436 of file pg_dump.c.

8437{
8438 SimplePtrListCell *cell;
8439
8441
8442 for (cell = refidx->partattaches.head; cell; cell = cell->next)
8443 {
8444 IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
8445
8446 addObjectDependency(dobj, attach->dobj.dumpId);
8447
8448 if (attach->partitionIdx->partattaches.head != NULL)
8449 addConstrChildIdxDeps(dobj, attach->partitionIdx);
8450 }
8451}
Assert(PointerIsAligned(start, uint64))
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:8436
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 5622 of file pg_dump.c.

5628{
5629 if (dobj->depends_on_ext)
5630 {
5631 char *nm;
5632 PGresult *res;
5633 PQExpBuffer query;
5634 int ntups;
5635 int i_extname;
5636 int i;
5637
5638 /* dodge fmtId() non-reentrancy */
5639 nm = pg_strdup(objname);
5640
5641 query = createPQExpBuffer();
5642 appendPQExpBuffer(query,
5643 "SELECT e.extname "
5644 "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5645 "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5646 "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5647 "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5648 catalog,
5649 dobj->catId.oid);
5650 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5651 ntups = PQntuples(res);
5652 i_extname = PQfnumber(res, "extname");
5653 for (i = 0; i < ntups; i++)
5654 {
5655 appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5656 keyword, nm,
5657 fmtId(PQgetvalue(res, i, i_extname)));
5658 }
5659
5660 PQclear(res);
5661 destroyPQExpBuffer(query);
5662 pg_free(nm);
5663 }
5664}
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3605
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 10982 of file pg_dump.c.

10984{
10985 appendPQExpBufferStr(out, ",\n\t");
10986
10987 appendStringLiteralAH(out, argname, fout);
10988 appendPQExpBufferStr(out, ", ");
10989
10990 appendStringLiteralAH(out, argval, fout);
10991 appendPQExpBuffer(out, "::%s", argtype);
10992}
#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 20450 of file pg_dump.c.

20452{
20453 bool res;
20454
20455 res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
20456 fout->std_strings);
20457 if (!res)
20458 pg_log_warning("could not parse %s array", "reloptions");
20459}
#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 5933 of file pg_dump.c.

5938{
5939 DumpableObject *extobj = NULL;
5940 int i;
5941
5942 if (!dobj->ext_member)
5943 return;
5944
5945 /*
5946 * Find the parent extension. We could avoid this search if we wanted to
5947 * add a link field to DumpableObject, but the space costs of that would
5948 * be considerable. We assume that member objects could only have a
5949 * direct dependency on their own extension, not any others.
5950 */
5951 for (i = 0; i < dobj->nDeps; i++)
5952 {
5953 extobj = findObjectByDumpId(dobj->dependencies[i]);
5954 if (extobj && extobj->objType == DO_EXTENSION)
5955 break;
5956 extobj = NULL;
5957 }
5958 if (extobj == NULL)
5959 pg_fatal("could not find parent extension for %s %s",
5960 objtype, objname);
5961
5962 appendPQExpBufferStr(upgrade_buffer,
5963 "\n-- For binary upgrade, handle extension membership the hard way\n");
5964 appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5965 fmtId(extobj->name),
5966 objtype);
5967 if (objnamespace && *objnamespace)
5968 appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5969 appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5970}
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 5843 of file pg_dump.c.

5845{
5848
5850
5851 /*
5852 * Preserve the OID and relfilenumber of the table, table's index, table's
5853 * toast table and toast table's index if any.
5854 *
5855 * One complexity is that the current table definition might not require
5856 * the creation of a TOAST table, but the old database might have a TOAST
5857 * table that was created earlier, before some wide columns were dropped.
5858 * By setting the TOAST oid we force creation of the TOAST heap and index
5859 * by the new backend, so we can copy the files during binary upgrade
5860 * without worrying about this case.
5861 */
5862 key.oid = pg_class_oid;
5866
5867 appendPQExpBufferStr(upgrade_buffer,
5868 "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5869
5870 if (entry->relkind != RELKIND_INDEX &&
5871 entry->relkind != RELKIND_PARTITIONED_INDEX)
5872 {
5873 appendPQExpBuffer(upgrade_buffer,
5874 "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5875 pg_class_oid);
5876
5877 /*
5878 * Not every relation has storage. Also, in a pre-v12 database,
5879 * partitioned tables have a relfilenumber, which should not be
5880 * preserved when upgrading.
5881 */
5882 if (RelFileNumberIsValid(entry->relfilenumber) &&
5883 entry->relkind != RELKIND_PARTITIONED_TABLE)
5884 appendPQExpBuffer(upgrade_buffer,
5885 "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5886 entry->relfilenumber);
5887
5888 /*
5889 * In a pre-v12 database, partitioned tables might be marked as having
5890 * toast tables, but we should ignore them if so.
5891 */
5892 if (OidIsValid(entry->toast_oid) &&
5893 entry->relkind != RELKIND_PARTITIONED_TABLE)
5894 {
5895 appendPQExpBuffer(upgrade_buffer,
5896 "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5897 entry->toast_oid);
5898 appendPQExpBuffer(upgrade_buffer,
5899 "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5900 entry->toast_relfilenumber);
5901
5902 /* every toast table has an index */
5903 appendPQExpBuffer(upgrade_buffer,
5904 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5905 entry->toast_index_oid);
5906 appendPQExpBuffer(upgrade_buffer,
5907 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5909 }
5910 }
5911 else
5912 {
5913 /* Preserve the OID and relfilenumber of the index */
5914 appendPQExpBuffer(upgrade_buffer,
5915 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5916 pg_class_oid);
5917 appendPQExpBuffer(upgrade_buffer,
5918 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5919 entry->relfilenumber);
5920 }
5921
5922 appendPQExpBufferChar(upgrade_buffer, '\n');
5923}
#define OidIsValid(objectId)
Definition: c.h:778
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:5793
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 5778 of file pg_dump.c.

5781{
5782 Oid pg_type_oid = tbinfo->reltype;
5783
5784 if (OidIsValid(pg_type_oid))
5785 binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5786 pg_type_oid, false, false);
5787}
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:5698
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 5698 of file pg_dump.c.

5703{
5704 PQExpBuffer upgrade_query = createPQExpBuffer();
5705 PGresult *res;
5706 Oid pg_type_array_oid;
5707 Oid pg_type_multirange_oid;
5708 Oid pg_type_multirange_array_oid;
5709 TypeInfo *tinfo;
5710
5711 appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5712 appendPQExpBuffer(upgrade_buffer,
5713 "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5714 pg_type_oid);
5715
5716 tinfo = findTypeByOid(pg_type_oid);
5717 if (tinfo)
5718 pg_type_array_oid = tinfo->typarray;
5719 else
5720 pg_type_array_oid = InvalidOid;
5721
5722 if (!OidIsValid(pg_type_array_oid) && force_array_type)
5723 pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5724
5725 if (OidIsValid(pg_type_array_oid))
5726 {
5727 appendPQExpBufferStr(upgrade_buffer,
5728 "\n-- For binary upgrade, must preserve pg_type array oid\n");
5729 appendPQExpBuffer(upgrade_buffer,
5730 "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5731 pg_type_array_oid);
5732 }
5733
5734 /*
5735 * Pre-set the multirange type oid and its own array type oid.
5736 */
5737 if (include_multirange_type)
5738 {
5739 if (fout->remoteVersion >= 140000)
5740 {
5741 printfPQExpBuffer(upgrade_query,
5742 "SELECT t.oid, t.typarray "
5743 "FROM pg_catalog.pg_type t "
5744 "JOIN pg_catalog.pg_range r "
5745 "ON t.oid = r.rngmultitypid "
5746 "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5747 pg_type_oid);
5748
5749 res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5750
5751 pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5752 pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5753
5754 PQclear(res);
5755 }
5756 else
5757 {
5758 pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5759 pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5760 }
5761
5762 appendPQExpBufferStr(upgrade_buffer,
5763 "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5764 appendPQExpBuffer(upgrade_buffer,
5765 "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5766 pg_type_multirange_oid);
5767 appendPQExpBufferStr(upgrade_buffer,
5768 "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5769 appendPQExpBuffer(upgrade_buffer,
5770 "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5771 pg_type_multirange_array_oid);
5772 }
5773
5774 destroyPQExpBuffer(upgrade_query);
5775}
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:5667
#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 5793 of file pg_dump.c.

5794{
5797
5798 return pg_cmp_u32(v1.oid, v2.oid);
5799}
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:652

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

20250{
20251 ArchiveHandle *AH = (ArchiveHandle *) fout;
20252 TocEntry *te;
20253
20254 /* Scan all TOC entries in the archive */
20255 for (te = AH->toc->next; te != AH->toc; te = te->next)
20256 {
20257 DumpableObject *dobj;
20258 DumpId *dependencies;
20259 int nDeps;
20260 int allocDeps;
20261
20262 /* No need to process entries that will not be dumped */
20263 if (te->reqs == 0)
20264 continue;
20265 /* Ignore entries that already have "special" dependencies */
20266 if (te->nDeps > 0)
20267 continue;
20268 /* Otherwise, look up the item's original DumpableObject, if any */
20269 dobj = findObjectByDumpId(te->dumpId);
20270 if (dobj == NULL)
20271 continue;
20272 /* No work if it has no dependencies */
20273 if (dobj->nDeps <= 0)
20274 continue;
20275 /* Set up work array */
20276 allocDeps = 64;
20277 dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
20278 nDeps = 0;
20279 /* Recursively find all dumpable dependencies */
20280 findDumpableDependencies(AH, dobj,
20281 &dependencies, &nDeps, &allocDeps);
20282 /* And save 'em ... */
20283 if (nDeps > 0)
20284 {
20285 dependencies = (DumpId *) pg_realloc(dependencies,
20286 nDeps * sizeof(DumpId));
20287 te->dependencies = dependencies;
20288 te->nDeps = nDeps;
20289 }
20290 else
20291 free(dependencies);
20292 }
20293}
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:20297
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 3112 of file pg_dump.c.

3113{
3114 PQExpBuffer query;
3115 PGresult *res;
3116 int ntups,
3117 i;
3118 int i_classid,
3119 i_objid,
3120 i_refobjid;
3121
3122 /* No Mat Views before 9.3. */
3123 if (fout->remoteVersion < 90300)
3124 return;
3125
3126 query = createPQExpBuffer();
3127
3128 appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
3129 "( "
3130 "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
3131 "FROM pg_depend d1 "
3132 "JOIN pg_class c1 ON c1.oid = d1.objid "
3133 "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
3134 " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
3135 "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
3136 "AND d2.objid = r1.oid "
3137 "AND d2.refobjid <> d1.objid "
3138 "JOIN pg_class c2 ON c2.oid = d2.refobjid "
3139 "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
3140 CppAsString2(RELKIND_VIEW) ") "
3141 "WHERE d1.classid = 'pg_class'::regclass "
3142 "UNION "
3143 "SELECT w.objid, d3.refobjid, c3.relkind "
3144 "FROM w "
3145 "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
3146 "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
3147 "AND d3.objid = r3.oid "
3148 "AND d3.refobjid <> w.refobjid "
3149 "JOIN pg_class c3 ON c3.oid = d3.refobjid "
3150 "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
3151 CppAsString2(RELKIND_VIEW) ") "
3152 ") "
3153 "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
3154 "FROM w "
3155 "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
3156
3157 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3158
3159 ntups = PQntuples(res);
3160
3161 i_classid = PQfnumber(res, "classid");
3162 i_objid = PQfnumber(res, "objid");
3163 i_refobjid = PQfnumber(res, "refobjid");
3164
3165 for (i = 0; i < ntups; i++)
3166 {
3167 CatalogId objId;
3168 CatalogId refobjId;
3169 DumpableObject *dobj;
3170 DumpableObject *refdobj;
3171 TableInfo *tbinfo;
3172 TableInfo *reftbinfo;
3173
3174 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
3175 objId.oid = atooid(PQgetvalue(res, i, i_objid));
3176 refobjId.tableoid = objId.tableoid;
3177 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
3178
3179 dobj = findObjectByCatalogId(objId);
3180 if (dobj == NULL)
3181 continue;
3182
3183 Assert(dobj->objType == DO_TABLE);
3184 tbinfo = (TableInfo *) dobj;
3185 Assert(tbinfo->relkind == RELKIND_MATVIEW);
3186 dobj = (DumpableObject *) tbinfo->dataObj;
3187 if (dobj == NULL)
3188 continue;
3190
3191 refdobj = findObjectByCatalogId(refobjId);
3192 if (refdobj == NULL)
3193 continue;
3194
3195 Assert(refdobj->objType == DO_TABLE);
3196 reftbinfo = (TableInfo *) refdobj;
3197 Assert(reftbinfo->relkind == RELKIND_MATVIEW);
3198 refdobj = (DumpableObject *) reftbinfo->dataObj;
3199 if (refdobj == NULL)
3200 continue;
3201 Assert(refdobj->objType == DO_REFRESH_MATVIEW);
3202
3203 addObjectDependency(dobj, refdobj->dumpId);
3204
3205 if (!reftbinfo->relispopulated)
3206 tbinfo->relispopulated = false;
3207 }
3208
3209 PQclear(res);
3210
3211 destroyPQExpBuffer(query);
3212}
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:778
#define CppAsString2(x)
Definition: c.h:422
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 1934 of file pg_dump.c.

1935{
1937
1938 if (ext == NULL)
1939 return false;
1940
1941 dobj->ext_member = true;
1942
1943 /* Record dependency so that getDependencies needn't deal with that */
1944 addObjectDependency(dobj, ext->dobj.dumpId);
1945
1946 /*
1947 * In 9.6 and above, mark the member object to have any non-initial ACLs
1948 * dumped. (Any initial ACLs will be removed later, using data from
1949 * pg_init_privs, so that we'll dump only the delta from the extension's
1950 * initial setup.)
1951 *
1952 * Prior to 9.6, we do not include any extension member components.
1953 *
1954 * In binary upgrades, we still dump all components of the members
1955 * individually, since the idea is to exactly reproduce the database
1956 * contents rather than replace the extension contents with something
1957 * different.
1958 *
1959 * Note: it might be interesting someday to implement storage and delta
1960 * dumping of extension members' RLS policies and/or security labels.
1961 * However there is a pitfall for RLS policies: trying to dump them
1962 * requires getting a lock on their tables, and the calling user might not
1963 * have privileges for that. We need no lock to examine a table's ACLs,
1964 * so the current feature doesn't have a problem of that sort.
1965 */
1966 if (fout->dopt->binary_upgrade)
1967 dobj->dump = ext->dobj.dump;
1968 else
1969 {
1970 if (fout->remoteVersion < 90600)
1971 dobj->dump = DUMP_COMPONENT_NONE;
1972 else
1973 dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
1974 }
1975
1976 return true;
1977}
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 5809 of file pg_dump.c.

5810{
5811 PGresult *res;
5812 const char *query;
5813
5814 query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5815 "ct.relfilenode, i.indexrelid, cti.relfilenode "
5816 "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5817 "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5818 "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5819 "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5820 "ORDER BY c.oid;";
5821
5822 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5823
5827
5828 for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5829 {
5837 }
5838
5839 PQclear(res);
5840}

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

11563{
11564 PGresult *res;
11565 PQExpBuffer query;
11566 int i_description;
11567 int i_classoid;
11568 int i_objoid;
11569 int i_objsubid;
11570 int ntups;
11571 int i;
11572 DumpableObject *dobj;
11573
11574 query = createPQExpBuffer();
11575
11576 appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
11577 "FROM pg_catalog.pg_description "
11578 "ORDER BY classoid, objoid, objsubid");
11579
11580 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11581
11582 /* Construct lookup table containing OIDs in numeric form */
11583
11584 i_description = PQfnumber(res, "description");
11585 i_classoid = PQfnumber(res, "classoid");
11586 i_objoid = PQfnumber(res, "objoid");
11587 i_objsubid = PQfnumber(res, "objsubid");
11588
11589 ntups = PQntuples(res);
11590
11591 comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
11592 ncomments = 0;
11593 dobj = NULL;
11594
11595 for (i = 0; i < ntups; i++)
11596 {
11597 CatalogId objId;
11598 int subid;
11599
11600 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
11601 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
11602 subid = atoi(PQgetvalue(res, i, i_objsubid));
11603
11604 /* We needn't remember comments that don't match any dumpable object */
11605 if (dobj == NULL ||
11606 dobj->catId.tableoid != objId.tableoid ||
11607 dobj->catId.oid != objId.oid)
11608 dobj = findObjectByCatalogId(objId);
11609 if (dobj == NULL)
11610 continue;
11611
11612 /*
11613 * Comments on columns of composite types are linked to the type's
11614 * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
11615 * in the type's own DumpableObject.
11616 */
11617 if (subid != 0 && dobj->objType == DO_TABLE &&
11618 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
11619 {
11620 TypeInfo *cTypeInfo;
11621
11622 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
11623 if (cTypeInfo)
11625 }
11626 else
11627 dobj->components |= DUMP_COMPONENT_COMMENT;
11628
11629 comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
11631 comments[ncomments].objoid = objId.oid;
11632 comments[ncomments].objsubid = subid;
11633 ncomments++;
11634 }
11635
11636 PQclear(res);
11637 destroyPQExpBuffer(query);
11638}
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 10702 of file pg_dump.c.

10703{
10704 PGresult *res;
10705 const char *query;
10706 int i;
10707
10708 query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
10709
10710 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
10711
10712 nrolenames = PQntuples(res);
10713
10715
10716 for (i = 0; i < nrolenames; i++)
10717 {
10718 rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
10720 }
10721
10722 PQclear(res);
10723}
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 16763 of file pg_dump.c.

16764{
16765 PGresult *res;
16766 PQExpBuffer query;
16767 int i_label;
16768 int i_provider;
16769 int i_classoid;
16770 int i_objoid;
16771 int i_objsubid;
16772 int ntups;
16773 int i;
16774 DumpableObject *dobj;
16775
16776 query = createPQExpBuffer();
16777
16779 "SELECT label, provider, classoid, objoid, objsubid "
16780 "FROM pg_catalog.pg_seclabels "
16781 "ORDER BY classoid, objoid, objsubid");
16782
16783 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16784
16785 /* Construct lookup table containing OIDs in numeric form */
16786 i_label = PQfnumber(res, "label");
16787 i_provider = PQfnumber(res, "provider");
16788 i_classoid = PQfnumber(res, "classoid");
16789 i_objoid = PQfnumber(res, "objoid");
16790 i_objsubid = PQfnumber(res, "objsubid");
16791
16792 ntups = PQntuples(res);
16793
16794 seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
16795 nseclabels = 0;
16796 dobj = NULL;
16797
16798 for (i = 0; i < ntups; i++)
16799 {
16800 CatalogId objId;
16801 int subid;
16802
16803 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
16804 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
16805 subid = atoi(PQgetvalue(res, i, i_objsubid));
16806
16807 /* We needn't remember labels that don't match any dumpable object */
16808 if (dobj == NULL ||
16809 dobj->catId.tableoid != objId.tableoid ||
16810 dobj->catId.oid != objId.oid)
16811 dobj = findObjectByCatalogId(objId);
16812 if (dobj == NULL)
16813 continue;
16814
16815 /*
16816 * Labels on columns of composite types are linked to the type's
16817 * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
16818 * in the type's own DumpableObject.
16819 */
16820 if (subid != 0 && dobj->objType == DO_TABLE &&
16821 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
16822 {
16823 TypeInfo *cTypeInfo;
16824
16825 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
16826 if (cTypeInfo)
16828 }
16829 else
16830 dobj->components |= DUMP_COMPONENT_SECLABEL;
16831
16832 seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
16833 seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
16835 seclabels[nseclabels].objoid = objId.oid;
16836 seclabels[nseclabels].objsubid = subid;
16837 nseclabels++;
16838 }
16839
16840 PQclear(res);
16841 destroyPQExpBuffer(query);
16842}
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 18897 of file pg_dump.c.

18898{
18899 PGresult *res;
18900 const char *query;
18901
18902 /*
18903 * Before Postgres 10, sequence metadata is in the sequence itself. With
18904 * some extra effort, we might be able to use the sorted table for those
18905 * versions, but for now it seems unlikely to be worth it.
18906 *
18907 * Since version 18, we can gather the sequence data in this query with
18908 * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
18909 */
18910 if (fout->remoteVersion < 100000)
18911 return;
18912 else if (fout->remoteVersion < 180000 ||
18913 (!fout->dopt->dumpData && !fout->dopt->sequence_data))
18914 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18915 "seqstart, seqincrement, "
18916 "seqmax, seqmin, "
18917 "seqcache, seqcycle, "
18918 "NULL, 'f' "
18919 "FROM pg_catalog.pg_sequence "
18920 "ORDER BY seqrelid";
18921 else
18922 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18923 "seqstart, seqincrement, "
18924 "seqmax, seqmin, "
18925 "seqcache, seqcycle, "
18926 "last_value, is_called "
18927 "FROM pg_catalog.pg_sequence, "
18928 "pg_get_sequence_data(seqrelid) "
18929 "ORDER BY seqrelid;";
18930
18931 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
18932
18933 nsequences = PQntuples(res);
18935
18936 for (int i = 0; i < nsequences; i++)
18937 {
18938 sequences[i].oid = atooid(PQgetvalue(res, i, 0));
18940 sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
18941 sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
18942 sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
18943 sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
18944 sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
18945 sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
18946 sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
18947 sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
18948 }
18949
18950 PQclear(res);
18951}
static int nsequences
Definition: pg_dump.c:213
static SeqType parse_sequence_type(const char *name)
Definition: pg_dump.c:18866
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 14310 of file pg_dump.c.

14311{
14312 char *name;
14313 char *paren;
14314 bool inquote;
14315
14316 /* In all cases "-" means a null reference */
14317 if (strcmp(proc, "-") == 0)
14318 return NULL;
14319
14320 name = pg_strdup(proc);
14321 /* find non-double-quoted left paren */
14322 inquote = false;
14323 for (paren = name; *paren; paren++)
14324 {
14325 if (*paren == '(' && !inquote)
14326 {
14327 *paren = '\0';
14328 break;
14329 }
14330 if (*paren == '"')
14331 inquote = !inquote;
14332 }
14333 return name;
14334}
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 14381 of file pg_dump.c.

14382{
14383 char *result;
14384 char query[128];
14385 PGresult *res;
14386
14387 snprintf(query, sizeof(query),
14388 "SELECT '%u'::pg_catalog.regproc", funcOid);
14389 res = ExecuteSqlQueryForSingleRow(fout, query);
14390
14391 result = pg_strdup(PQgetvalue(res, 0, 0));
14392
14393 PQclear(res);
14394
14395 return result;
14396}
#define snprintf
Definition: port.h:239

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

Referenced by dumpTSParser(), and dumpTSTemplate().

◆ createBoundaryObjects()

static DumpableObject * createBoundaryObjects ( void  )
static

Definition at line 20099 of file pg_dump.c.

20100{
20101 DumpableObject *dobjs;
20102
20103 dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
20104
20105 dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
20106 dobjs[0].catId = nilCatalogId;
20107 AssignDumpId(dobjs + 0);
20108 dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
20109
20110 dobjs[1].objType = DO_POST_DATA_BOUNDARY;
20111 dobjs[1].catId = nilCatalogId;
20112 AssignDumpId(dobjs + 1);
20113 dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
20114
20115 return dobjs;
20116}
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 17038 of file pg_dump.c.

17039{
17040 PQExpBuffer result = createPQExpBuffer();
17041 int j;
17042
17043 appendPQExpBufferStr(result, "SELECT");
17044
17045 for (j = 0; j < tbinfo->numatts; j++)
17046 {
17047 if (j > 0)
17048 appendPQExpBufferChar(result, ',');
17049 appendPQExpBufferStr(result, "\n ");
17050
17051 appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
17052
17053 /*
17054 * Must add collation if not default for the type, because CREATE OR
17055 * REPLACE VIEW won't change it
17056 */
17057 if (OidIsValid(tbinfo->attcollation[j]))
17058 {
17059 CollInfo *coll;
17060
17061 coll = findCollationByOid(tbinfo->attcollation[j]);
17062 if (coll)
17063 appendPQExpBuffer(result, " COLLATE %s",
17064 fmtQualifiedDumpable(coll));
17065 }
17066
17067 appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
17068 }
17069
17070 return result;
17071}
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 16989 of file pg_dump.c.

16990{
16992 PQExpBuffer result = createPQExpBuffer();
16993 PGresult *res;
16994 int len;
16995
16996 /* Fetch the view definition */
16997 appendPQExpBuffer(query,
16998 "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
16999 tbinfo->dobj.catId.oid);
17000
17001 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17002
17003 if (PQntuples(res) != 1)
17004 {
17005 if (PQntuples(res) < 1)
17006 pg_fatal("query to obtain definition of view \"%s\" returned no data",
17007 tbinfo->dobj.name);
17008 else
17009 pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
17010 tbinfo->dobj.name);
17011 }
17012
17013 len = PQgetlength(res, 0, 0);
17014
17015 if (len == 0)
17016 pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
17017 tbinfo->dobj.name);
17018
17019 /* Strip off the trailing semicolon so that other things may follow. */
17020 Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
17021 appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
17022
17023 PQclear(res);
17024 destroyPQExpBuffer(query);
17025
17026 return result;
17027}
#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 9997 of file pg_dump.c.

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

14404{
14405 DumpOptions *dopt = fout->dopt;
14406 PQExpBuffer q;
14407 PQExpBuffer delq;
14408 char *qamname;
14409
14410 /* Do nothing if not dumping schema */
14411 if (!dopt->dumpSchema)
14412 return;
14413
14414 q = createPQExpBuffer();
14415 delq = createPQExpBuffer();
14416
14417 qamname = pg_strdup(fmtId(aminfo->dobj.name));
14418
14419 appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
14420
14421 switch (aminfo->amtype)
14422 {
14423 case AMTYPE_INDEX:
14424 appendPQExpBufferStr(q, "TYPE INDEX ");
14425 break;
14426 case AMTYPE_TABLE:
14427 appendPQExpBufferStr(q, "TYPE TABLE ");
14428 break;
14429 default:
14430 pg_log_warning("invalid type \"%c\" of access method \"%s\"",
14431 aminfo->amtype, qamname);
14433 destroyPQExpBuffer(delq);
14434 free(qamname);
14435 return;
14436 }
14437
14438 appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
14439
14440 appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
14441 qamname);
14442
14443 if (dopt->binary_upgrade)
14445 "ACCESS METHOD", qamname, NULL);
14446
14447 if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14448 ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
14449 ARCHIVE_OPTS(.tag = aminfo->dobj.name,
14450 .description = "ACCESS METHOD",
14451 .section = SECTION_PRE_DATA,
14452 .createStmt = q->data,
14453 .dropStmt = delq->data));
14454
14455 /* Dump Access Method Comments */
14456 if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14457 dumpComment(fout, "ACCESS METHOD", qamname,
14458 NULL, "",
14459 aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
14460
14462 destroyPQExpBuffer(delq);
14463 free(qamname);
14464}
@ 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:10966
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:5933
#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 16394 of file pg_dump.c.

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

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

18162{
18163 DumpOptions *dopt = fout->dopt;
18164 TableInfo *tbinfo = adinfo->adtable;
18165 int adnum = adinfo->adnum;
18166 PQExpBuffer q;
18167 PQExpBuffer delq;
18168 char *qualrelname;
18169 char *tag;
18170 char *foreign;
18171
18172 /* Do nothing if not dumping schema */
18173 if (!dopt->dumpSchema)
18174 return;
18175
18176 /* Skip if not "separate"; it was dumped in the table's definition */
18177 if (!adinfo->separate)
18178 return;
18179
18180 q = createPQExpBuffer();
18181 delq = createPQExpBuffer();
18182
18183 qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
18184
18185 foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
18186
18188 "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
18189 foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
18190 adinfo->adef_expr);
18191
18192 appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
18193 foreign, qualrelname,
18194 fmtId(tbinfo->attnames[adnum - 1]));
18195
18196 tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
18197
18198 if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18199 ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
18200 ARCHIVE_OPTS(.tag = tag,
18201 .namespace = tbinfo->dobj.namespace->dobj.name,
18202 .owner = tbinfo->rolname,
18203 .description = "DEFAULT",
18204 .section = SECTION_PRE_DATA,
18205 .createStmt = q->data,
18206 .dropStmt = delq->data));
18207
18208 free(tag);
18210 destroyPQExpBuffer(delq);
18211 free(qualrelname);
18212}
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 12436 of file pg_dump.c.

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

13858{
13859 DumpOptions *dopt = fout->dopt;
13860 PQExpBuffer defqry;
13861 PQExpBuffer delqry;
13862 PQExpBuffer labelq;
13863 PQExpBuffer castargs;
13864 FuncInfo *funcInfo = NULL;
13865 const char *sourceType;
13866 const char *targetType;
13867
13868 /* Do nothing if not dumping schema */
13869 if (!dopt->dumpSchema)
13870 return;
13871
13872 /* Cannot dump if we don't have the cast function's info */
13873 if (OidIsValid(cast->castfunc))
13874 {
13875 funcInfo = findFuncByOid(cast->castfunc);
13876 if (funcInfo == NULL)
13877 pg_fatal("could not find function definition for function with OID %u",
13878 cast->castfunc);
13879 }
13880
13881 defqry = createPQExpBuffer();
13882 delqry = createPQExpBuffer();
13883 labelq = createPQExpBuffer();
13884 castargs = createPQExpBuffer();
13885
13886 sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
13887 targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
13888 appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
13889 sourceType, targetType);
13890
13891 appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
13892 sourceType, targetType);
13893
13894 switch (cast->castmethod)
13895 {
13896 case COERCION_METHOD_BINARY:
13897 appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
13898 break;
13899 case COERCION_METHOD_INOUT:
13900 appendPQExpBufferStr(defqry, "WITH INOUT");
13901 break;
13902 case COERCION_METHOD_FUNCTION:
13903 if (funcInfo)
13904 {
13905 char *fsig = format_function_signature(fout, funcInfo, true);
13906
13907 /*
13908 * Always qualify the function name (format_function_signature
13909 * won't qualify it).
13910 */
13911 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
13912 fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
13913 free(fsig);
13914 }
13915 else
13916 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
13917 break;
13918 default:
13919 pg_log_warning("bogus value in pg_cast.castmethod field");
13920 }
13921
13922 if (cast->castcontext == 'a')
13923 appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
13924 else if (cast->castcontext == 'i')
13925 appendPQExpBufferStr(defqry, " AS IMPLICIT");
13926 appendPQExpBufferStr(defqry, ";\n");
13927
13928 appendPQExpBuffer(labelq, "CAST (%s AS %s)",
13929 sourceType, targetType);
13930
13931 appendPQExpBuffer(castargs, "(%s AS %s)",
13932 sourceType, targetType);
13933
13934 if (dopt->binary_upgrade)
13936 "CAST", castargs->data, NULL);
13937
13939 ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
13940 ARCHIVE_OPTS(.tag = labelq->data,
13941 .description = "CAST",
13942 .section = SECTION_PRE_DATA,
13943 .createStmt = defqry->data,
13944 .dropStmt = delqry->data));
13945
13946 /* Dump Cast Comments */
13947 if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
13948 dumpComment(fout, "CAST", castargs->data,
13949 NULL, "",
13950 cast->dobj.catId, 0, cast->dobj.dumpId);
13951
13952 destroyPQExpBuffer(defqry);
13953 destroyPQExpBuffer(delqry);
13954 destroyPQExpBuffer(labelq);
13955 destroyPQExpBuffer(castargs);
13956}
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 14971 of file pg_dump.c.

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

10970{
10971 dumpCommentExtended(fout, type, name, namespace, owner,
10972 catalogId, subid, dumpId, NULL);
10973}
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:10866

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

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

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

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

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

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

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

3779{
3780 PGconn *conn = GetConnection(AH);
3782 PGresult *res;
3783
3784 /* First collect database-specific options */
3785 printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
3786 "WHERE setrole = 0 AND setdatabase = '%u'::oid",
3787 dboid);
3788
3789 res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3790
3791 for (int i = 0; i < PQntuples(res); i++)
3793 "DATABASE", dbname, NULL, NULL,
3794 outbuf);
3795
3796 PQclear(res);
3797
3798 /* Now look for role-and-database-specific options */
3799 printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
3800 "FROM pg_db_role_setting s, pg_roles r "
3801 "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
3802 dboid);
3803
3804 res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3805
3806 for (int i = 0; i < PQntuples(res); i++)
3808 "ROLE", PQgetvalue(res, i, 0),
3809 "DATABASE", dbname,
3810 outbuf);
3811
3812 PQclear(res);
3813
3815}
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
Definition: pg_test_fsync.c:72
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 16302 of file pg_dump.c.

16303{
16304 DumpOptions *dopt = fout->dopt;
16305 PQExpBuffer q;
16306 PQExpBuffer tag;
16307 const char *type;
16308
16309 /* Do nothing if not dumping schema, or if we're skipping ACLs */
16310 if (!dopt->dumpSchema || dopt->aclsSkip)
16311 return;
16312
16313 q = createPQExpBuffer();
16314 tag = createPQExpBuffer();
16315
16316 switch (daclinfo->defaclobjtype)
16317 {
16318 case DEFACLOBJ_RELATION:
16319 type = "TABLES";
16320 break;
16321 case DEFACLOBJ_SEQUENCE:
16322 type = "SEQUENCES";
16323 break;
16324 case DEFACLOBJ_FUNCTION:
16325 type = "FUNCTIONS";
16326 break;
16327 case DEFACLOBJ_TYPE:
16328 type = "TYPES";
16329 break;
16330 case DEFACLOBJ_NAMESPACE:
16331 type = "SCHEMAS";
16332 break;
16333 case DEFACLOBJ_LARGEOBJECT:
16334 type = "LARGE OBJECTS";
16335 break;
16336 default:
16337 /* shouldn't get here */
16338 pg_fatal("unrecognized object type in default privileges: %d",
16339 (int) daclinfo->defaclobjtype);
16340 type = ""; /* keep compiler quiet */
16341 }
16342
16343 appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
16344
16345 /* build the actual command(s) for this tuple */
16347 daclinfo->dobj.namespace != NULL ?
16348 daclinfo->dobj.namespace->dobj.name : NULL,
16349 daclinfo->dacl.acl,
16350 daclinfo->dacl.acldefault,
16351 daclinfo->defaclrole,
16352 fout->remoteVersion,
16353 q))
16354 pg_fatal("could not parse default ACL list (%s)",
16355 daclinfo->dacl.acl);
16356
16357 if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
16358 ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
16359 ARCHIVE_OPTS(.tag = tag->data,
16360 .namespace = daclinfo->dobj.namespace ?
16361 daclinfo->dobj.namespace->dobj.name : NULL,
16362 .owner = daclinfo->defaclrole,
16363 .description = "DEFAULT ACL",
16364 .section = SECTION_POST_DATA,
16365 .createStmt = q->data));
16366
16367 destroyPQExpBuffer(tag);
16369}
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 12685 of file pg_dump.c.

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

11648{
11649 /*
11650 * Clear any dump-request bits for components that don't exist for this
11651 * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
11652 * request for every kind of object.)
11653 */
11654 dobj->dump &= dobj->components;
11655
11656 /* Now, short-circuit if there's nothing to be done here. */
11657 if (dobj->dump == 0)
11658 return;
11659
11660 switch (dobj->objType)
11661 {
11662 case DO_NAMESPACE:
11663 dumpNamespace(fout, (const NamespaceInfo *) dobj);
11664 break;
11665 case DO_EXTENSION:
11666 dumpExtension(fout, (const ExtensionInfo *) dobj);
11667 break;
11668 case DO_TYPE:
11669 dumpType(fout, (const TypeInfo *) dobj);
11670 break;
11671 case DO_SHELL_TYPE:
11672 dumpShellType(fout, (const ShellTypeInfo *) dobj);
11673 break;
11674 case DO_FUNC:
11675 dumpFunc(fout, (const FuncInfo *) dobj);
11676 break;
11677 case DO_AGG:
11678 dumpAgg(fout, (const AggInfo *) dobj);
11679 break;
11680 case DO_OPERATOR:
11681 dumpOpr(fout, (const OprInfo *) dobj);
11682 break;
11683 case DO_ACCESS_METHOD:
11684 dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
11685 break;
11686 case DO_OPCLASS:
11687 dumpOpclass(fout, (const OpclassInfo *) dobj);
11688 break;
11689 case DO_OPFAMILY:
11690 dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
11691 break;
11692 case DO_COLLATION:
11693 dumpCollation(fout, (const CollInfo *) dobj);
11694 break;
11695 case DO_CONVERSION:
11696 dumpConversion(fout, (const ConvInfo *) dobj);
11697 break;
11698 case DO_TABLE:
11699 dumpTable(fout, (const TableInfo *) dobj);
11700 break;
11701 case DO_TABLE_ATTACH:
11702 dumpTableAttach(fout, (const TableAttachInfo *) dobj);
11703 break;
11704 case DO_ATTRDEF:
11705 dumpAttrDef(fout, (const AttrDefInfo *) dobj);
11706 break;
11707 case DO_INDEX:
11708 dumpIndex(fout, (const IndxInfo *) dobj);
11709 break;
11710 case DO_INDEX_ATTACH:
11711 dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
11712 break;
11713 case DO_STATSEXT:
11714 dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
11715 break;
11716 case DO_REFRESH_MATVIEW:
11717 refreshMatViewData(fout, (const TableDataInfo *) dobj);
11718 break;
11719 case DO_RULE:
11720 dumpRule(fout, (const RuleInfo *) dobj);
11721 break;
11722 case DO_TRIGGER:
11723 dumpTrigger(fout, (const TriggerInfo *) dobj);
11724 break;
11725 case DO_EVENT_TRIGGER:
11726 dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
11727 break;
11728 case DO_CONSTRAINT:
11729 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11730 break;
11731 case DO_FK_CONSTRAINT:
11732 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11733 break;
11734 case DO_PROCLANG:
11735 dumpProcLang(fout, (const ProcLangInfo *) dobj);
11736 break;
11737 case DO_CAST:
11738 dumpCast(fout, (const CastInfo *) dobj);
11739 break;
11740 case DO_TRANSFORM:
11741 dumpTransform(fout, (const TransformInfo *) dobj);
11742 break;
11743 case DO_SEQUENCE_SET:
11744 dumpSequenceData(fout, (const TableDataInfo *) dobj);
11745 break;
11746 case DO_TABLE_DATA:
11747 dumpTableData(fout, (const TableDataInfo *) dobj);
11748 break;
11749 case DO_DUMMY_TYPE:
11750 /* table rowtypes and array types are never dumped separately */
11751 break;
11752 case DO_TSPARSER:
11753 dumpTSParser(fout, (const TSParserInfo *) dobj);
11754 break;
11755 case DO_TSDICT:
11756 dumpTSDictionary(fout, (const TSDictInfo *) dobj);
11757 break;
11758 case DO_TSTEMPLATE:
11759 dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
11760 break;
11761 case DO_TSCONFIG:
11762 dumpTSConfig(fout, (const TSConfigInfo *) dobj);
11763 break;
11764 case DO_FDW:
11765 dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
11766 break;
11767 case DO_FOREIGN_SERVER:
11768 dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
11769 break;
11770 case DO_DEFAULT_ACL:
11771 dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
11772 break;
11773 case DO_LARGE_OBJECT:
11774 dumpLO(fout, (const LoInfo *) dobj);
11775 break;
11777 if (dobj->dump & DUMP_COMPONENT_DATA)
11778 {
11779 LoInfo *loinfo;
11780 TocEntry *te;
11781
11782 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
11783 if (loinfo == NULL)
11784 pg_fatal("missing metadata for large objects \"%s\"",
11785 dobj->name);
11786
11787 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
11788 ARCHIVE_OPTS(.tag = dobj->name,
11789 .owner = loinfo->rolname,
11790 .description = "BLOBS",
11791 .section = SECTION_DATA,
11792 .deps = dobj->dependencies,
11793 .nDeps = dobj->nDeps,
11794 .dumpFn = dumpLOs,
11795 .dumpArg = loinfo));
11796
11797 /*
11798 * Set the TocEntry's dataLength in case we are doing a
11799 * parallel dump and want to order dump jobs by table size.
11800 * (We need some size estimate for every TocEntry with a
11801 * DataDumper function.) We don't currently have any cheap
11802 * way to estimate the size of LOs, but fortunately it doesn't
11803 * matter too much as long as we get large batches of LOs
11804 * processed reasonably early. Assume 8K per blob.
11805 */
11806 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
11807 }
11808 break;
11809 case DO_POLICY:
11810 dumpPolicy(fout, (const PolicyInfo *) dobj);
11811 break;
11812 case DO_PUBLICATION:
11813 dumpPublication(fout, (const PublicationInfo *) dobj);
11814 break;
11815 case DO_PUBLICATION_REL:
11816 dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
11817 break;
11820 (const PublicationSchemaInfo *) dobj);
11821 break;
11822 case DO_SUBSCRIPTION:
11823 dumpSubscription(fout, (const SubscriptionInfo *) dobj);
11824 break;
11826 dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
11827 break;
11828 case DO_REL_STATS:
11829 dumpRelationStats(fout, (const RelStatsInfo *) dobj);
11830 break;
11833 /* never dumped, nothing to do */
11834 break;
11835 }
11836}
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:18161
static void dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
Definition: pg_dump.c:4949
static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
Definition: pg_dump.c:11843
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:13857
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:18251
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:15780
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:15356
static void dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
Definition: pg_dump.c:11361
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:19289
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16849
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:18445
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:18522
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12043
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:18093
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:14403
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:14091
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:19212
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:13435
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:16108
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2856
static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
Definition: pg_dump.c:13205
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2971
static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
Definition: pg_dump.c:4639
static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
Definition: pg_dump.c:4405
static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
Definition: pg_dump.c:14752
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:16302
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:15860
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:18402
static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
Definition: pg_dump.c:5399
static void dumpTransform(Archive *fout, const TransformInfo *transform)
Definition: pg_dump.c:13962
static void dumpLO(Archive *fout, const LoInfo *loinfo)
Definition: pg_dump.c:4097
static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
Definition: pg_dump.c:4992
static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
Definition: pg_dump.c:15716
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:19505
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:11920
static int dumpLOs(Archive *fout, const void *arg)
Definition: pg_dump.c:4187
static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
Definition: pg_dump.c:5468
static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
Definition: pg_dump.c:19415
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:15228
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:16038
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:13251
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:15918
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:14971
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:14471
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:110
#define pgoff_t
Definition: port.h:401
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 3821 of file pg_dump.c.

3822{
3823 const char *encname = pg_encoding_to_char(AH->encoding);
3825
3826 pg_log_info("saving encoding = %s", encname);
3827
3828 appendPQExpBufferStr(qry, "SET client_encoding = ");
3829 appendStringLiteralAH(qry, encname, AH);
3830 appendPQExpBufferStr(qry, ";\n");
3831
3833 ARCHIVE_OPTS(.tag = "ENCODING",
3834 .description = "ENCODING",
3835 .section = SECTION_PRE_DATA,
3836 .createStmt = qry->data));
3837
3838 destroyPQExpBuffer(qry);
3839}
#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 12074 of file pg_dump.c.

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

19416{
19417 DumpOptions *dopt = fout->dopt;
19418 PQExpBuffer query;
19419 PQExpBuffer delqry;
19420 char *qevtname;
19421
19422 /* Do nothing if not dumping schema */
19423 if (!dopt->dumpSchema)
19424 return;
19425
19426 query = createPQExpBuffer();
19427 delqry = createPQExpBuffer();
19428
19429 qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
19430
19431 appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
19432 appendPQExpBufferStr(query, qevtname);
19433 appendPQExpBufferStr(query, " ON ");
19434 appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
19435
19436 if (strcmp("", evtinfo->evttags) != 0)
19437 {
19438 appendPQExpBufferStr(query, "\n WHEN TAG IN (");
19439 appendPQExpBufferStr(query, evtinfo->evttags);
19440 appendPQExpBufferChar(query, ')');
19441 }
19442
19443 appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
19444 appendPQExpBufferStr(query, evtinfo->evtfname);
19445 appendPQExpBufferStr(query, "();\n");
19446
19447 if (evtinfo->evtenabled != 'O')
19448 {
19449 appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
19450 qevtname);
19451 switch (evtinfo->evtenabled)
19452 {
19453 case 'D':
19454 appendPQExpBufferStr(query, "DISABLE");
19455 break;
19456 case 'A':
19457 appendPQExpBufferStr(query, "ENABLE ALWAYS");
19458 break;
19459 case 'R':
19460 appendPQExpBufferStr(query, "ENABLE REPLICA");
19461 break;
19462 default:
19463 appendPQExpBufferStr(query, "ENABLE");
19464 break;
19465 }
19466 appendPQExpBufferStr(query, ";\n");
19467 }
19468
19469 appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
19470 qevtname);
19471
19472 if (dopt->binary_upgrade)
19473 binary_upgrade_extension_member(query, &evtinfo->dobj,
19474 "EVENT TRIGGER", qevtname, NULL);
19475
19476 if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19477 ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
19478 ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
19479 .owner = evtinfo->evtowner,
19480 .description = "EVENT TRIGGER",
19481 .section = SECTION_POST_DATA,
19482 .createStmt = query->data,
19483 .dropStmt = delqry->data));
19484
19485 if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19486 dumpComment(fout, "EVENT TRIGGER", qevtname,
19487 NULL, evtinfo->evtowner,
19488 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
19489
19490 if (evtinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
19491 dumpSecLabel(fout, "EVENT TRIGGER", qevtname,
19492 NULL, evtinfo->evtowner,
19493 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
19494
19495 destroyPQExpBuffer(query);
19496 destroyPQExpBuffer(delqry);
19497 free(qevtname);
19498}
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 11920 of file pg_dump.c.

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

16039{
16040 DumpOptions *dopt = fout->dopt;
16041 PQExpBuffer q;
16042 PQExpBuffer delq;
16043 char *qfdwname;
16044
16045 /* Do nothing if not dumping schema */
16046 if (!dopt->dumpSchema)
16047 return;
16048
16049 q = createPQExpBuffer();
16050 delq = createPQExpBuffer();
16051
16052 qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
16053
16054 appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
16055 qfdwname);
16056
16057 if (strcmp(fdwinfo->fdwhandler, "-") != 0)
16058 appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
16059
16060 if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
16061 appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
16062
16063 if (strlen(fdwinfo->fdwoptions) > 0)
16064 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
16065
16066 appendPQExpBufferStr(q, ";\n");
16067
16068 appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
16069 qfdwname);
16070
16071 if (dopt->binary_upgrade)
16073 "FOREIGN DATA WRAPPER", qfdwname,
16074 NULL);
16075
16076 if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16077 ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
16078 ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
16079 .owner = fdwinfo->rolname,
16080 .description = "FOREIGN DATA WRAPPER",
16081 .section = SECTION_PRE_DATA,
16082 .createStmt = q->data,
16083 .dropStmt = delq->data));
16084
16085 /* Dump Foreign Data Wrapper Comments */
16086 if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
16087 dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
16088 NULL, fdwinfo->rolname,
16089 fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
16090
16091 /* Handle the ACL */
16092 if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
16093 dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
16094 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
16095 NULL, fdwinfo->rolname, &fdwinfo->dacl);
16096
16097 free(qfdwname);
16098
16100 destroyPQExpBuffer(delq);
16101}
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 16108 of file pg_dump.c.

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

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

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

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

18403{
18404 /* Do nothing if not dumping schema */
18405 if (!fout->dopt->dumpSchema)
18406 return;
18407
18409 {
18411
18412 appendPQExpBuffer(q, "ALTER INDEX %s ",
18413 fmtQualifiedDumpable(attachinfo->parentIdx));
18414 appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
18415 fmtQualifiedDumpable(attachinfo->partitionIdx));
18416
18417 /*
18418 * There is no need for a dropStmt since the drop is done implicitly
18419 * when we drop either the index's table or the partitioned index.
18420 * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
18421 * there's no way to do it anyway. (If you think to change this,
18422 * consider also what to do with --if-exists.)
18423 *
18424 * Although this object doesn't really have ownership as such, set the
18425 * owner field anyway to ensure that the command is run by the correct
18426 * role at restore time.
18427 */
18428 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18429 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18430 .namespace = attachinfo->dobj.namespace->dobj.name,
18431 .owner = attachinfo->parentIdx->indextable->rolname,
18432 .description = "INDEX ATTACH",
18433 .section = SECTION_POST_DATA,
18434 .createStmt = q->data));
18435
18437 }
18438}
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 4097 of file pg_dump.c.

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

4188{
4189 const LoInfo *loinfo = (const LoInfo *) arg;
4190 PGconn *conn = GetConnection(fout);
4191 char buf[LOBBUFSIZE];
4192
4193 pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
4194
4195 for (int i = 0; i < loinfo->numlos; i++)
4196 {
4197 Oid loOid = loinfo->looids[i];
4198 int loFd;
4199 int cnt;
4200
4201 /* Open the LO */
4202 loFd = lo_open(conn, loOid, INV_READ);
4203 if (loFd == -1)
4204 pg_fatal("could not open large object %u: %s",
4205 loOid, PQerrorMessage(conn));
4206
4207 StartLO(fout, loOid);
4208
4209 /* Now read it in chunks, sending data to archive */
4210 do
4211 {
4212 cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
4213 if (cnt < 0)
4214 pg_fatal("error reading large object %u: %s",
4215 loOid, PQerrorMessage(conn));
4216
4217 WriteData(fout, buf, cnt);
4218 } while (cnt > 0);
4219
4220 lo_close(conn, loFd);
4221
4222 EndLO(fout, loOid);
4223 }
4224
4225 return 1;
4226}
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 11843 of file pg_dump.c.

11844{
11845 DumpOptions *dopt = fout->dopt;
11846 PQExpBuffer q;
11847 PQExpBuffer delq;
11848 char *qnspname;
11849
11850 /* Do nothing if not dumping schema */
11851 if (!dopt->dumpSchema)
11852 return;
11853
11854 q = createPQExpBuffer();
11855 delq = createPQExpBuffer();
11856
11857 qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
11858
11859 if (nspinfo->create)
11860 {
11861 appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
11862 appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
11863 }
11864 else
11865 {
11866 /* see selectDumpableNamespace() */
11868 "-- *not* dropping schema, since initdb creates it\n");
11870 "-- *not* creating schema, since initdb creates it\n");
11871 }
11872
11873 if (dopt->binary_upgrade)
11875 "SCHEMA", qnspname, NULL);
11876
11877 if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11878 ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
11879 ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
11880 .owner = nspinfo->rolname,
11881 .description = "SCHEMA",
11882 .section = SECTION_PRE_DATA,
11883 .createStmt = q->data,
11884 .dropStmt = delq->data));
11885
11886 /* Dump Schema Comments and Security Labels */
11887 if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11888 {
11889 const char *initdb_comment = NULL;
11890
11891 if (!nspinfo->create && strcmp(qnspname, "public") == 0)
11892 initdb_comment = "standard public schema";
11893 dumpCommentExtended(fout, "SCHEMA", qnspname,
11894 NULL, nspinfo->rolname,
11895 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
11896 initdb_comment);
11897 }
11898
11899 if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11900 dumpSecLabel(fout, "SCHEMA", qnspname,
11901 NULL, nspinfo->rolname,
11902 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
11903
11904 if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
11905 dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
11906 qnspname, NULL, NULL,
11907 NULL, nspinfo->rolname, &nspinfo->dacl);
11908
11909 free(qnspname);
11910
11912 destroyPQExpBuffer(delq);
11913}
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 14471 of file pg_dump.c.

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

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

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

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

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

4640{
4641 DumpOptions *dopt = fout->dopt;
4642 PQExpBuffer delq;
4643 PQExpBuffer query;
4644 char *qpubname;
4645 bool first = true;
4646
4647 /* Do nothing if not dumping schema */
4648 if (!dopt->dumpSchema)
4649 return;
4650
4651 delq = createPQExpBuffer();
4652 query = createPQExpBuffer();
4653
4654 qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
4655
4656 appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
4657 qpubname);
4658
4659 appendPQExpBuffer(query, "CREATE PUBLICATION %s",
4660 qpubname);
4661
4662 if (pubinfo->puballtables && pubinfo->puballsequences)
4663 appendPQExpBufferStr(query, " FOR ALL TABLES, ALL SEQUENCES");
4664 else if (pubinfo->puballtables)
4665 appendPQExpBufferStr(query, " FOR ALL TABLES");
4666 else if (pubinfo->puballsequences)
4667 appendPQExpBufferStr(query, " FOR ALL SEQUENCES");
4668
4669 appendPQExpBufferStr(query, " WITH (publish = '");
4670 if (pubinfo->pubinsert)
4671 {
4672 appendPQExpBufferStr(query, "insert");
4673 first = false;
4674 }
4675
4676 if (pubinfo->pubupdate)
4677 {
4678 if (!first)
4679 appendPQExpBufferStr(query, ", ");
4680
4681 appendPQExpBufferStr(query, "update");
4682 first = false;
4683 }
4684
4685 if (pubinfo->pubdelete)
4686 {
4687 if (!first)
4688 appendPQExpBufferStr(query, ", ");
4689
4690 appendPQExpBufferStr(query, "delete");
4691 first = false;
4692 }
4693
4694 if (pubinfo->pubtruncate)
4695 {
4696 if (!first)
4697 appendPQExpBufferStr(query, ", ");
4698
4699 appendPQExpBufferStr(query, "truncate");
4700 first = false;
4701 }
4702
4703 appendPQExpBufferChar(query, '\'');
4704
4705 if (pubinfo->pubviaroot)
4706 appendPQExpBufferStr(query, ", publish_via_partition_root = true");
4707
4708 if (pubinfo->pubgencols_type == PUBLISH_GENCOLS_STORED)
4709 appendPQExpBufferStr(query, ", publish_generated_columns = stored");
4710
4711 appendPQExpBufferStr(query, ");\n");
4712
4713 if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4714 ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
4715 ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
4716 .owner = pubinfo->rolname,
4717 .description = "PUBLICATION",
4718 .section = SECTION_POST_DATA,
4719 .createStmt = query->data,
4720 .dropStmt = delq->data));
4721
4722 if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4723 dumpComment(fout, "PUBLICATION", qpubname,
4724 NULL, pubinfo->rolname,
4725 pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4726
4727 if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4728 dumpSecLabel(fout, "PUBLICATION", qpubname,
4729 NULL, pubinfo->rolname,
4730 pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4731
4732 destroyPQExpBuffer(delq);
4733 destroyPQExpBuffer(query);
4734 free(qpubname);
4735}
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 4949 of file pg_dump.c.

4950{
4951 DumpOptions *dopt = fout->dopt;
4952 NamespaceInfo *schemainfo = pubsinfo->pubschema;
4953 PublicationInfo *pubinfo = pubsinfo->publication;
4954 PQExpBuffer query;
4955 char *tag;
4956
4957 /* Do nothing if not dumping schema */
4958 if (!dopt->dumpSchema)
4959 return;
4960
4961 tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
4962
4963 query = createPQExpBuffer();
4964
4965 appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
4966 appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
4967
4968 /*
4969 * There is no point in creating drop query as the drop is done by schema
4970 * drop.
4971 */
4972 if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4973 ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
4974 ARCHIVE_OPTS(.tag = tag,
4975 .namespace = schemainfo->dobj.name,
4976 .owner = pubinfo->rolname,
4977 .description = "PUBLICATION TABLES IN SCHEMA",
4978 .section = SECTION_POST_DATA,
4979 .createStmt = query->data));
4980
4981 /* These objects can't currently have comments or seclabels */
4982
4983 free(tag);
4984 destroyPQExpBuffer(query);
4985}
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 4992 of file pg_dump.c.

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

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

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

11362{
11363 const DumpableObject *dobj = &rsinfo->dobj;
11364
11365 /* nothing to do if we are not dumping statistics */
11366 if (!fout->dopt->dumpStatistics)
11367 return;
11368
11370 ARCHIVE_OPTS(.tag = dobj->name,
11371 .namespace = dobj->namespace->dobj.name,
11372 .description = "STATISTICS DATA",
11373 .section = rsinfo->section,
11374 .defnFn = dumpRelationStats_dumper,
11375 .defnArg = rsinfo,
11376 .deps = dobj->dependencies,
11377 .nDeps = dobj->nDeps));
11378}
static char * dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
Definition: pg_dump.c:11088
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 11088 of file pg_dump.c.

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

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

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

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

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

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

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

13206{
13207 DumpOptions *dopt = fout->dopt;
13208 PQExpBuffer q;
13209
13210 /* Do nothing if not dumping schema */
13211 if (!dopt->dumpSchema)
13212 return;
13213
13214 q = createPQExpBuffer();
13215
13216 /*
13217 * Note the lack of a DROP command for the shell type; any required DROP
13218 * is driven off the base type entry, instead. This interacts with
13219 * _printTocEntry()'s use of the presence of a DROP command to decide
13220 * whether an entry needs an ALTER OWNER command. We don't want to alter
13221 * the shell type's owner immediately on creation; that should happen only
13222 * after it's filled in, otherwise the backend complains.
13223 */
13224
13225 if (dopt->binary_upgrade)
13227 stinfo->baseType->dobj.catId.oid,
13228 false, false);
13229
13230 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
13231 fmtQualifiedDumpable(stinfo));
13232
13233 if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13234 ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
13235 ARCHIVE_OPTS(.tag = stinfo->dobj.name,
13236 .namespace = stinfo->dobj.namespace->dobj.name,
13237 .owner = stinfo->baseType->rolname,
13238 .description = "SHELL TYPE",
13239 .section = SECTION_PRE_DATA,
13240 .createStmt = q->data));
13241
13243}
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 18445 of file pg_dump.c.

18446{
18447 DumpOptions *dopt = fout->dopt;
18448 PQExpBuffer q;
18449 PQExpBuffer delq;
18450 PQExpBuffer query;
18451 char *qstatsextname;
18452 PGresult *res;
18453 char *stxdef;
18454
18455 /* Do nothing if not dumping schema */
18456 if (!dopt->dumpSchema)
18457 return;
18458
18459 q = createPQExpBuffer();
18460 delq = createPQExpBuffer();
18461 query = createPQExpBuffer();
18462
18463 qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
18464
18465 appendPQExpBuffer(query, "SELECT "
18466 "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
18467 statsextinfo->dobj.catId.oid);
18468
18469 res = ExecuteSqlQueryForSingleRow(fout, query->data);
18470
18471 stxdef = PQgetvalue(res, 0, 0);
18472
18473 /* Result of pg_get_statisticsobjdef is complete except for semicolon */
18474 appendPQExpBuffer(q, "%s;\n", stxdef);
18475
18476 /*
18477 * We only issue an ALTER STATISTICS statement if the stxstattarget entry
18478 * for this statistics object is not the default value.
18479 */
18480 if (statsextinfo->stattarget >= 0)
18481 {
18482 appendPQExpBuffer(q, "ALTER STATISTICS %s ",
18483 fmtQualifiedDumpable(statsextinfo));
18484 appendPQExpBuffer(q, "SET STATISTICS %d;\n",
18485 statsextinfo->stattarget);
18486 }
18487
18488 appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
18489 fmtQualifiedDumpable(statsextinfo));
18490
18491 if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18492 ArchiveEntry(fout, statsextinfo->dobj.catId,
18493 statsextinfo->dobj.dumpId,
18494 ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
18495 .namespace = statsextinfo->dobj.namespace->dobj.name,
18496 .owner = statsextinfo->rolname,
18497 .description = "STATISTICS",
18498 .section = SECTION_POST_DATA,
18499 .createStmt = q->data,
18500 .dropStmt = delq->data));
18501
18502 /* Dump Statistics Comments */
18503 if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18504 dumpComment(fout, "STATISTICS", qstatsextname,
18505 statsextinfo->dobj.namespace->dobj.name,
18506 statsextinfo->rolname,
18507 statsextinfo->dobj.catId, 0,
18508 statsextinfo->dobj.dumpId);
18509
18510 PQclear(res);
18512 destroyPQExpBuffer(delq);
18513 destroyPQExpBuffer(query);
18514 free(qstatsextname);
18515}
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 3846 of file pg_dump.c.

3847{
3848 const char *stdstrings = AH->std_strings ? "on" : "off";
3850
3851 pg_log_info("saving \"standard_conforming_strings = %s\"",
3852 stdstrings);
3853
3854 appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
3855 stdstrings);
3856
3858 ARCHIVE_OPTS(.tag = "STDSTRINGS",
3859 .description = "STDSTRINGS",
3860 .section = SECTION_PRE_DATA,
3861 .createStmt = qry->data));
3862
3863 destroyPQExpBuffer(qry);
3864}

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

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

5400{
5401 DumpOptions *dopt = fout->dopt;
5402 SubscriptionInfo *subinfo = subrinfo->subinfo;
5403 PQExpBuffer query;
5404 char *tag;
5405
5406 /* Do nothing if not dumping schema */
5407 if (!dopt->dumpSchema)
5408 return;
5409
5410 Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
5411
5412 tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
5413
5414 query = createPQExpBuffer();
5415
5416 if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5417 {
5418 /*
5419 * binary_upgrade_add_sub_rel_state will add the subscription relation
5420 * to pg_subscription_rel table. This will be used only in
5421 * binary-upgrade mode.
5422 */
5424 "\n-- For binary upgrade, must preserve the subscriber table.\n");
5426 "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
5427 appendStringLiteralAH(query, subrinfo->dobj.name, fout);
5428 appendPQExpBuffer(query,
5429 ", %u, '%c'",
5430 subrinfo->tblinfo->dobj.catId.oid,
5431 subrinfo->srsubstate);
5432
5433 if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
5434 appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
5435 else
5436 appendPQExpBufferStr(query, ", NULL");
5437
5438 appendPQExpBufferStr(query, ");\n");
5439 }
5440
5441 /*
5442 * There is no point in creating a drop query as the drop is done by table
5443 * drop. (If you think to change this, see also _printTocEntry().)
5444 * Although this object doesn't really have ownership as such, set the
5445 * owner field anyway to ensure that the command is run by the correct
5446 * role at restore time.
5447 */
5448 if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5449 ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
5450 ARCHIVE_OPTS(.tag = tag,
5451 .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
5452 .owner = subinfo->rolname,
5453 .description = "SUBSCRIPTION TABLE",
5454 .section = SECTION_POST_DATA,
5455 .createStmt = query->data));
5456
5457 /* These objects can't currently have comments or seclabels */
5458
5459 free(tag);
5460 destroyPQExpBuffer(query);
5461}
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 16849 of file pg_dump.c.

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

18094{
18095 DumpOptions *dopt = fout->dopt;
18096 PQExpBuffer q;
18097 PGresult *res;
18098 char *partbound;
18099
18100 /* Do nothing if not dumping schema */
18101 if (!dopt->dumpSchema)
18102 return;
18103
18104 q = createPQExpBuffer();
18105
18107 {
18108 /* Set up query for partbound details */
18110 "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
18111
18113 "SELECT pg_get_expr(c.relpartbound, c.oid) "
18114 "FROM pg_class c "
18115 "WHERE c.oid = $1");
18116
18117 ExecuteSqlStatement(fout, q->data);
18118
18120 }
18121
18123 "EXECUTE dumpTableAttach('%u')",
18124 attachinfo->partitionTbl->dobj.catId.oid);
18125
18126 res = ExecuteSqlQueryForSingleRow(fout, q->data);
18127 partbound = PQgetvalue(res, 0, 0);
18128
18129 /* Perform ALTER TABLE on the parent */
18131 "ALTER TABLE ONLY %s ",
18132 fmtQualifiedDumpable(attachinfo->parentTbl));
18134 "ATTACH PARTITION %s %s;\n",
18136 partbound);
18137
18138 /*
18139 * There is no point in creating a drop query as the drop is done by table
18140 * drop. (If you think to change this, see also _printTocEntry().)
18141 * Although this object doesn't really have ownership as such, set the
18142 * owner field anyway to ensure that the command is run by the correct
18143 * role at restore time.
18144 */
18145 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18146 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18147 .namespace = attachinfo->dobj.namespace->dobj.name,
18148 .owner = attachinfo->partitionTbl->rolname,
18149 .description = "TABLE ATTACH",
18150 .section = SECTION_PRE_DATA,
18151 .createStmt = q->data));
18152
18153 PQclear(res);
18155}
@ 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 11387 of file pg_dump.c.

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

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

18844{
18845 TableInfo *tbinfo = coninfo->contable;
18846 PQExpBuffer conprefix = createPQExpBuffer();
18847 char *qtabname;
18848
18849 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18850
18851 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
18852 fmtId(coninfo->dobj.name));
18853
18854 if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18855 dumpComment(fout, conprefix->data, qtabname,
18856 tbinfo->dobj.namespace->dobj.name,
18857 tbinfo->rolname,
18858 coninfo->dobj.catId, 0,
18859 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
18860
18861 destroyPQExpBuffer(conprefix);
18862 free(qtabname);
18863}

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

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

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

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

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

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

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

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

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

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

15781{
15782 DumpOptions *dopt = fout->dopt;
15783 PQExpBuffer q;
15784 PQExpBuffer delq;
15785 PQExpBuffer query;
15786 char *qdictname;
15787 PGresult *res;
15788 char *nspname;
15789 char *tmplname;
15790
15791 /* Do nothing if not dumping schema */
15792 if (!dopt->dumpSchema)
15793 return;
15794
15795 q = createPQExpBuffer();
15796 delq = createPQExpBuffer();
15797 query = createPQExpBuffer();
15798
15799 qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
15800
15801 /* Fetch name and namespace of the dictionary's template */
15802 appendPQExpBuffer(query, "SELECT nspname, tmplname "
15803 "FROM pg_ts_template p, pg_namespace n "
15804 "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
15805 dictinfo->dicttemplate);
15806 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15807 nspname = PQgetvalue(res, 0, 0);
15808 tmplname = PQgetvalue(res, 0, 1);
15809
15810 appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
15811 fmtQualifiedDumpable(dictinfo));
15812
15813 appendPQExpBufferStr(q, " TEMPLATE = ");
15814 appendPQExpBuffer(q, "%s.", fmtId(nspname));
15815 appendPQExpBufferStr(q, fmtId(tmplname));
15816
15817 PQclear(res);
15818
15819 /* the dictinitoption can be dumped straight into the command */
15820 if (dictinfo->dictinitoption)
15821 appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
15822
15823 appendPQExpBufferStr(q, " );\n");
15824
15825 appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
15826 fmtQualifiedDumpable(dictinfo));
15827
15828 if (dopt->binary_upgrade)
15830 "TEXT SEARCH DICTIONARY", qdictname,
15831 dictinfo->dobj.namespace->dobj.name);
15832
15833 if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15834 ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
15835 ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
15836 .namespace = dictinfo->dobj.namespace->dobj.name,
15837 .owner = dictinfo->rolname,
15838 .description = "TEXT SEARCH DICTIONARY",
15839 .section = SECTION_PRE_DATA,
15840 .createStmt = q->data,
15841 .dropStmt = delq->data));
15842
15843 /* Dump Dictionary Comments */
15844 if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15845 dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
15846 dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
15847 dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
15848
15850 destroyPQExpBuffer(delq);
15851 destroyPQExpBuffer(query);
15852 free(qdictname);
15853}
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 15716 of file pg_dump.c.

15717{
15718 DumpOptions *dopt = fout->dopt;
15719 PQExpBuffer q;
15720 PQExpBuffer delq;
15721 char *qprsname;
15722
15723 /* Do nothing if not dumping schema */
15724 if (!dopt->dumpSchema)
15725 return;
15726
15727 q = createPQExpBuffer();
15728 delq = createPQExpBuffer();
15729
15730 qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
15731
15732 appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
15733 fmtQualifiedDumpable(prsinfo));
15734
15735 appendPQExpBuffer(q, " START = %s,\n",
15736 convertTSFunction(fout, prsinfo->prsstart));
15737 appendPQExpBuffer(q, " GETTOKEN = %s,\n",
15738 convertTSFunction(fout, prsinfo->prstoken));
15739 appendPQExpBuffer(q, " END = %s,\n",
15740 convertTSFunction(fout, prsinfo->prsend));
15741 if (prsinfo->prsheadline != InvalidOid)
15742 appendPQExpBuffer(q, " HEADLINE = %s,\n",
15743 convertTSFunction(fout, prsinfo->prsheadline));
15744 appendPQExpBuffer(q, " LEXTYPES = %s );\n",
15745 convertTSFunction(fout, prsinfo->prslextype));
15746
15747 appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
15748 fmtQualifiedDumpable(prsinfo));
15749
15750 if (dopt->binary_upgrade)
15752 "TEXT SEARCH PARSER", qprsname,
15753 prsinfo->dobj.namespace->dobj.name);
15754
15755 if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15756 ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
15757 ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
15758 .namespace = prsinfo->dobj.namespace->dobj.name,
15759 .description = "TEXT SEARCH PARSER",
15760 .section = SECTION_PRE_DATA,
15761 .createStmt = q->data,
15762 .dropStmt = delq->data));
15763
15764 /* Dump Parser Comments */
15765 if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15766 dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
15767 prsinfo->dobj.namespace->dobj.name, "",
15768 prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
15769
15771 destroyPQExpBuffer(delq);
15772 free(qprsname);
15773}
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:14381
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 15860 of file pg_dump.c.

15861{
15862 DumpOptions *dopt = fout->dopt;
15863 PQExpBuffer q;
15864 PQExpBuffer delq;
15865 char *qtmplname;
15866
15867 /* Do nothing if not dumping schema */
15868 if (!dopt->dumpSchema)
15869 return;
15870
15871 q = createPQExpBuffer();
15872 delq = createPQExpBuffer();
15873
15874 qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
15875
15876 appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
15877 fmtQualifiedDumpable(tmplinfo));
15878
15879 if (tmplinfo->tmplinit != InvalidOid)
15880 appendPQExpBuffer(q, " INIT = %s,\n",
15881 convertTSFunction(fout, tmplinfo->tmplinit));
15882 appendPQExpBuffer(q, " LEXIZE = %s );\n",
15883 convertTSFunction(fout, tmplinfo->tmpllexize));
15884
15885 appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
15886 fmtQualifiedDumpable(tmplinfo));
15887
15888 if (dopt->binary_upgrade)
15890 "TEXT SEARCH TEMPLATE", qtmplname,
15891 tmplinfo->dobj.namespace->dobj.name);
15892
15893 if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15894 ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
15895 ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
15896 .namespace = tmplinfo->dobj.namespace->dobj.name,
15897 .description = "TEXT SEARCH TEMPLATE",
15898 .section = SECTION_PRE_DATA,
15899 .createStmt = q->data,
15900 .dropStmt = delq->data));
15901
15902 /* Dump Template Comments */
15903 if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15904 dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
15905 tmplinfo->dobj.namespace->dobj.name, "",
15906 tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
15907
15909 destroyPQExpBuffer(delq);
15910 free(qtmplname);
15911}
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 12043 of file pg_dump.c.

12044{
12045 DumpOptions *dopt = fout->dopt;
12046
12047 /* Do nothing if not dumping schema */
12048 if (!dopt->dumpSchema)
12049 return;
12050
12051 /* Dump out in proper style */
12052 if (tyinfo->typtype == TYPTYPE_BASE)
12053 dumpBaseType(fout, tyinfo);
12054 else if (tyinfo->typtype == TYPTYPE_DOMAIN)
12055 dumpDomain(fout, tyinfo);
12056 else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
12057 dumpCompositeType(fout, tyinfo);
12058 else if (tyinfo->typtype == TYPTYPE_ENUM)
12059 dumpEnumType(fout, tyinfo);
12060 else if (tyinfo->typtype == TYPTYPE_RANGE)
12061 dumpRangeType(fout, tyinfo);
12062 else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
12063 dumpUndefinedType(fout, tyinfo);
12064 else
12065 pg_log_warning("typtype of data type \"%s\" appears to be invalid",
12066 tyinfo->dobj.name);
12067}
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12436
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12214
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12685
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12372
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12910
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12074
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 12372 of file pg_dump.c.

12373{
12374 DumpOptions *dopt = fout->dopt;
12377 char *qtypname;
12378 char *qualtypname;
12379
12380 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12381 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12382
12383 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12384
12385 if (dopt->binary_upgrade)
12387 tyinfo->dobj.catId.oid,
12388 false, false);
12389
12390 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12391 qualtypname);
12392
12393 if (dopt->binary_upgrade)
12395 "TYPE", qtypname,
12396 tyinfo->dobj.namespace->dobj.name);
12397
12398 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12399 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12400 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12401 .namespace = tyinfo->dobj.namespace->dobj.name,
12402 .owner = tyinfo->rolname,
12403 .description = "TYPE",
12404 .section = SECTION_PRE_DATA,
12405 .createStmt = q->data,
12406 .dropStmt = delq->data));
12407
12408 /* Dump Type Comments and Security Labels */
12409 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12410 dumpComment(fout, "TYPE", qtypname,
12411 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12412 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12413
12414 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12415 dumpSecLabel(fout, "TYPE", qtypname,
12416 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12417 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12418
12419 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12420 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12421 qtypname, NULL,
12422 tyinfo->dobj.namespace->dobj.name,
12423 NULL, tyinfo->rolname, &tyinfo->dacl);
12424
12426 destroyPQExpBuffer(delq);
12427 free(qtypname);
12428 free(qualtypname);
12429}

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

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

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

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

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

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

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

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

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

11486{
11487 CommentItem *middle = NULL;
11488 CommentItem *low;
11489 CommentItem *high;
11490 int nmatch;
11491
11492 /*
11493 * Do binary search to find some item matching the object.
11494 */
11495 low = &comments[0];
11496 high = &comments[ncomments - 1];
11497 while (low <= high)
11498 {
11499 middle = low + (high - low) / 2;
11500
11501 if (classoid < middle->classoid)
11502 high = middle - 1;
11503 else if (classoid > middle->classoid)
11504 low = middle + 1;
11505 else if (objoid < middle->objoid)
11506 high = middle - 1;
11507 else if (objoid > middle->objoid)
11508 low = middle + 1;
11509 else
11510 break; /* found a match */
11511 }
11512
11513 if (low > high) /* no matches */
11514 {
11515 *items = NULL;
11516 return 0;
11517 }
11518
11519 /*
11520 * Now determine how many items match the object. The search loop
11521 * invariant still holds: only items between low and high inclusive could
11522 * match.
11523 */
11524 nmatch = 1;
11525 while (middle > low)
11526 {
11527 if (classoid != middle[-1].classoid ||
11528 objoid != middle[-1].objoid)
11529 break;
11530 middle--;
11531 nmatch++;
11532 }
11533
11534 *items = middle;
11535
11536 middle += nmatch;
11537 while (middle <= high)
11538 {
11539 if (classoid != middle->classoid ||
11540 objoid != middle->objoid)
11541 break;
11542 middle++;
11543 nmatch++;
11544 }
11545
11546 return nmatch;
11547}
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 20297 of file pg_dump.c.

20299{
20300 int i;
20301
20302 /*
20303 * Ignore section boundary objects: if we search through them, we'll
20304 * report lots of bogus dependencies.
20305 */
20306 if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
20308 return;
20309
20310 for (i = 0; i < dobj->nDeps; i++)
20311 {
20312 DumpId depid = dobj->dependencies[i];
20313
20314 if (TocIDRequired(AH, depid) != 0)
20315 {
20316 /* Object will be dumped, so just reference it as a dependency */
20317 if (*nDeps >= *allocDeps)
20318 {
20319 *allocDeps *= 2;
20320 *dependencies = (DumpId *) pg_realloc(*dependencies,
20321 *allocDeps * sizeof(DumpId));
20322 }
20323 (*dependencies)[*nDeps] = depid;
20324 (*nDeps)++;
20325 }
20326 else
20327 {
20328 /*
20329 * Object will not be dumped, so recursively consider its deps. We
20330 * rely on the assumption that sortDumpableObjects already broke
20331 * any dependency loops, else we might recurse infinitely.
20332 */
20333 DumpableObject *otherdobj = findObjectByDumpId(depid);
20334
20335 if (otherdobj)
20336 findDumpableDependencies(AH, otherdobj,
20337 dependencies, nDeps, allocDeps);
20338 }
20339 }
20340}
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 6091 of file pg_dump.c.

6092{
6093 NamespaceInfo *nsinfo;
6094
6095 nsinfo = findNamespaceByOid(nsoid);
6096 if (nsinfo == NULL)
6097 pg_fatal("schema with OID %u does not exist", nsoid);
6098 return nsinfo;
6099}
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 16684 of file pg_dump.c.

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

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

20405{
20406 int numatts = ti->numatts;
20407 char **attnames = ti->attnames;
20408 bool *attisdropped = ti->attisdropped;
20409 char *attgenerated = ti->attgenerated;
20410 bool needComma;
20411 int i;
20412
20413 appendPQExpBufferChar(buffer, '(');
20414 needComma = false;
20415 for (i = 0; i < numatts; i++)
20416 {
20417 if (attisdropped[i])
20418 continue;
20419 if (attgenerated[i])
20420 continue;
20421 if (needComma)
20422 appendPQExpBufferStr(buffer, ", ");
20423 appendPQExpBufferStr(buffer, fmtId(attnames[i]));
20424 needComma = true;
20425 }
20426
20427 if (!needComma)
20428 return ""; /* no undropped columns */
20429
20430 appendPQExpBufferChar(buffer, ')');
20431 return buffer->data;
20432}

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

2829{
2830 TableInfo *parentTbinfo;
2831
2832 Assert(tbinfo->ispartition);
2833 Assert(tbinfo->numParents == 1);
2834
2835 parentTbinfo = tbinfo->parents[0];
2836 if (parentTbinfo->unsafe_partitions)
2837 return true;
2838 while (parentTbinfo->ispartition)
2839 {
2840 Assert(parentTbinfo->numParents == 1);
2841 parentTbinfo = parentTbinfo->parents[0];
2842 if (parentTbinfo->unsafe_partitions)
2843 return true;
2844 }
2845
2846 return false;
2847}
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 15324 of file pg_dump.c.

15325{
15327 int j;
15328
15330 if (honor_quotes)
15331 appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
15332 else
15333 appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
15334
15335 if (agginfo->aggfn.nargs == 0)
15336 appendPQExpBufferStr(&buf, "(*)");
15337 else
15338 {
15340 for (j = 0; j < agginfo->aggfn.nargs; j++)
15341 appendPQExpBuffer(&buf, "%s%s",
15342 (j > 0) ? ", " : "",
15344 agginfo->aggfn.argtypes[j],
15345 zeroIsError));
15347 }
15348 return buf.data;
15349}

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

13384{
13386
13389 if (is_agg && finfo->nargs == 0)
13390 appendPQExpBufferStr(&fn, "(*)");
13391 else
13392 appendPQExpBuffer(&fn, "(%s)", funcargs);
13393 return fn.data;
13394}
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 13406 of file pg_dump.c.

13407{
13409 int j;
13410
13412 if (honor_quotes)
13413 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
13414 else
13415 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
13416 for (j = 0; j < finfo->nargs; j++)
13417 {
13418 if (j > 0)
13419 appendPQExpBufferStr(&fn, ", ");
13420
13422 getFormattedTypeName(fout, finfo->argtypes[j],
13423 zeroIsError));
13424 }
13426 return fn.data;
13427}
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 9115 of file pg_dump.c.

9116{
9117 PQExpBuffer query;
9118 PGresult *res;
9119 char *lanname;
9120
9121 query = createPQExpBuffer();
9122 appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
9123 res = ExecuteSqlQueryForSingleRow(fout, query->data);
9124 lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
9125 destroyPQExpBuffer(query);
9126 PQclear(res);
9127
9128 return lanname;
9129}

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

5668{
5669 /*
5670 * If the old version didn't assign an array type, but the new version
5671 * does, we must select an unused type OID to assign. This currently only
5672 * happens for domains, when upgrading pre-v11 to v11 and up.
5673 *
5674 * Note: local state here is kind of ugly, but we must have some, since we
5675 * mustn't choose the same unused OID more than once.
5676 */
5677 static Oid next_possible_free_oid = FirstNormalObjectId;
5678 PGresult *res;
5679 bool is_dup;
5680
5681 do
5682 {
5683 ++next_possible_free_oid;
5684 printfPQExpBuffer(upgrade_query,
5685 "SELECT EXISTS(SELECT 1 "
5686 "FROM pg_catalog.pg_type "
5687 "WHERE oid = '%u'::pg_catalog.oid);",
5688 next_possible_free_oid);
5689 res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5690 is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
5691 PQclear(res);
5692 } while (is_dup);
5693
5694 return next_possible_free_oid;
5695}
#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 1597 of file pg_dump.c.

1598{
1599 char *query = "SELECT pg_catalog.pg_export_snapshot()";
1600 char *result;
1601 PGresult *res;
1602
1603 res = ExecuteSqlQueryForSingleRow(fout, query);
1604 result = pg_strdup(PQgetvalue(res, 0, 0));
1605 PQclear(res);
1606
1607 return result;
1608}

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

Referenced by setup_connection().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6556 of file pg_dump.c.

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

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

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

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

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

18223{
18224 if (attrnum > 0 && attrnum <= tblInfo->numatts)
18225 return tblInfo->attnames[attrnum - 1];
18226 switch (attrnum)
18227 {
18229 return "ctid";
18231 return "xmin";
18233 return "cmin";
18235 return "xmax";
18237 return "cmax";
18239 return "tableoid";
18240 }
18241 pg_fatal("invalid column number %d for table \"%s\"",
18242 attrnum, tblInfo->dobj.name);
18243 return NULL; /* keep compiler quiet */
18244}
#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 9026 of file pg_dump.c.

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

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

6429{
6430 PGresult *res;
6431 int ntups;
6432 int i;
6433 PQExpBuffer query;
6434 CollInfo *collinfo;
6435 int i_tableoid;
6436 int i_oid;
6437 int i_collname;
6438 int i_collnamespace;
6439 int i_collowner;
6440 int i_collencoding;
6441
6442 query = createPQExpBuffer();
6443
6444 /*
6445 * find all collations, including builtin collations; we filter out
6446 * system-defined collations at dump-out time.
6447 */
6448
6449 appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6450 "collnamespace, "
6451 "collowner, "
6452 "collencoding "
6453 "FROM pg_collation");
6454
6455 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6456
6457 ntups = PQntuples(res);
6458
6459 collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6460
6461 i_tableoid = PQfnumber(res, "tableoid");
6462 i_oid = PQfnumber(res, "oid");
6463 i_collname = PQfnumber(res, "collname");
6464 i_collnamespace = PQfnumber(res, "collnamespace");
6465 i_collowner = PQfnumber(res, "collowner");
6466 i_collencoding = PQfnumber(res, "collencoding");
6467
6468 for (i = 0; i < ntups; i++)
6469 {
6470 collinfo[i].dobj.objType = DO_COLLATION;
6471 collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6472 collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6473 AssignDumpId(&collinfo[i].dobj);
6474 collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6475 collinfo[i].dobj.namespace =
6476 findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6477 collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6478 collinfo[i].collencoding = atoi(PQgetvalue(res, i, i_collencoding));
6479
6480 /* Decide whether we want to dump it */
6481 selectDumpableObject(&(collinfo[i].dobj), fout);
6482 }
6483
6484 PQclear(res);
6485
6486 destroyPQExpBuffer(query);
6487}
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 8277 of file pg_dump.c.

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

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

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

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

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

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

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

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

8865{
8866 int i;
8867 PQExpBuffer query;
8868 PGresult *res;
8869 EventTriggerInfo *evtinfo;
8870 int i_tableoid,
8871 i_oid,
8872 i_evtname,
8873 i_evtevent,
8874 i_evtowner,
8875 i_evttags,
8876 i_evtfname,
8877 i_evtenabled;
8878 int ntups;
8879
8880 /* Before 9.3, there are no event triggers */
8881 if (fout->remoteVersion < 90300)
8882 return;
8883
8884 query = createPQExpBuffer();
8885
8887 "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8888 "evtevent, evtowner, "
8889 "array_to_string(array("
8890 "select quote_literal(x) "
8891 " from unnest(evttags) as t(x)), ', ') as evttags, "
8892 "e.evtfoid::regproc as evtfname "
8893 "FROM pg_event_trigger e "
8894 "ORDER BY e.oid");
8895
8896 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8897
8898 ntups = PQntuples(res);
8899
8900 evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8901
8902 i_tableoid = PQfnumber(res, "tableoid");
8903 i_oid = PQfnumber(res, "oid");
8904 i_evtname = PQfnumber(res, "evtname");
8905 i_evtevent = PQfnumber(res, "evtevent");
8906 i_evtowner = PQfnumber(res, "evtowner");
8907 i_evttags = PQfnumber(res, "evttags");
8908 i_evtfname = PQfnumber(res, "evtfname");
8909 i_evtenabled = PQfnumber(res, "evtenabled");
8910
8911 for (i = 0; i < ntups; i++)
8912 {
8913 evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8914 evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8915 evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8916 AssignDumpId(&evtinfo[i].dobj);
8917 evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8918 evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8919 evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8920 evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8921 evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8922 evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8923 evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8924
8925 /* Decide whether we want to dump it */
8926 selectDumpableObject(&(evtinfo[i].dobj), fout);
8927 }
8928
8929 PQclear(res);
8930
8931 destroyPQExpBuffer(query);
8932}
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 8198 of file pg_dump.c.

8199{
8200 PQExpBuffer query;
8201 PGresult *res;
8202 StatsExtInfo *statsextinfo;
8203 int ntups;
8204 int i_tableoid;
8205 int i_oid;
8206 int i_stxname;
8207 int i_stxnamespace;
8208 int i_stxowner;
8209 int i_stxrelid;
8210 int i_stattarget;
8211 int i;
8212
8213 /* Extended statistics were new in v10 */
8214 if (fout->remoteVersion < 100000)
8215 return;
8216
8217 query = createPQExpBuffer();
8218
8219 if (fout->remoteVersion < 130000)
8220 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8221 "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
8222 "FROM pg_catalog.pg_statistic_ext");
8223 else
8224 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8225 "stxnamespace, stxowner, stxrelid, stxstattarget "
8226 "FROM pg_catalog.pg_statistic_ext");
8227
8228 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8229
8230 ntups = PQntuples(res);
8231
8232 i_tableoid = PQfnumber(res, "tableoid");
8233 i_oid = PQfnumber(res, "oid");
8234 i_stxname = PQfnumber(res, "stxname");
8235 i_stxnamespace = PQfnumber(res, "stxnamespace");
8236 i_stxowner = PQfnumber(res, "stxowner");
8237 i_stxrelid = PQfnumber(res, "stxrelid");
8238 i_stattarget = PQfnumber(res, "stxstattarget");
8239
8240 statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
8241
8242 for (i = 0; i < ntups; i++)
8243 {
8244 statsextinfo[i].dobj.objType = DO_STATSEXT;
8245 statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8246 statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8247 AssignDumpId(&statsextinfo[i].dobj);
8248 statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
8249 statsextinfo[i].dobj.namespace =
8250 findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
8251 statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
8252 statsextinfo[i].stattable =
8253 findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
8254 if (PQgetisnull(res, i, i_stattarget))
8255 statsextinfo[i].stattarget = -1;
8256 else
8257 statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
8258
8259 /* Decide whether we want to dump it */
8260 selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
8261 }
8262
8263 PQclear(res);
8264 destroyPQExpBuffer(query);
8265}
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2326
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 19672 of file pg_dump.c.

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

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

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

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

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

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

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

14352{
14353 OprInfo *oprInfo;
14354
14355 /* In all cases "0" means a null reference */
14356 if (strcmp(oproid, "0") == 0)
14357 return NULL;
14358
14359 oprInfo = findOprByOid(atooid(oproid));
14360 if (oprInfo == NULL)
14361 {
14362 pg_log_warning("could not find operator with OID %s",
14363 oproid);
14364 return NULL;
14365 }
14366
14367 return psprintf("OPERATOR(%s.%s)",
14368 fmtId(oprInfo->dobj.namespace->dobj.name),
14369 oprInfo->dobj.name);
14370}
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 20353 of file pg_dump.c.

20354{
20355 TypeInfo *typeInfo;
20356 char *result;
20357 PQExpBuffer query;
20358 PGresult *res;
20359
20360 if (oid == 0)
20361 {
20362 if ((opts & zeroAsStar) != 0)
20363 return "*";
20364 else if ((opts & zeroAsNone) != 0)
20365 return "NONE";
20366 }
20367
20368 /* see if we have the result cached in the type's TypeInfo record */
20369 typeInfo = findTypeByOid(oid);
20370 if (typeInfo && typeInfo->ftypname)
20371 return typeInfo->ftypname;
20372
20373 query = createPQExpBuffer();
20374 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
20375 oid);
20376
20377 res = ExecuteSqlQueryForSingleRow(fout, query->data);
20378
20379 /* result of format_type is already quoted */
20380 result = pg_strdup(PQgetvalue(res, 0, 0));
20381
20382 PQclear(res);
20383 destroyPQExpBuffer(query);
20384
20385 /*
20386 * Cache the result for re-use in later requests, if possible. If we
20387 * don't have a TypeInfo for the type, the string will be leaked once the
20388 * caller is done with it ... but that case really should not happen, so
20389 * leaking if it does seems acceptable.
20390 */
20391 if (typeInfo)
20392 typeInfo->ftypname = result;
20393
20394 return result;
20395}
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 6899 of file pg_dump.c.

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

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

7714{
7715 PGresult *res;
7716 int ntups;
7717 int i;
7719 InhInfo *inhinfo;
7720
7721 int i_inhrelid;
7722 int i_inhparent;
7723
7724 /* find all the inheritance information */
7725 appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7726
7727 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7728
7729 ntups = PQntuples(res);
7730
7731 *numInherits = ntups;
7732
7733 inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7734
7735 i_inhrelid = PQfnumber(res, "inhrelid");
7736 i_inhparent = PQfnumber(res, "inhparent");
7737
7738 for (i = 0; i < ntups; i++)
7739 {
7740 inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7741 inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7742 }
7743
7744 PQclear(res);
7745
7746 destroyPQExpBuffer(query);
7747
7748 return inhinfo;
7749}
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 3932 of file pg_dump.c.

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

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

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

6631{
6632 PGresult *res;
6633 int ntups;
6634 int i;
6636 OpclassInfo *opcinfo;
6637 int i_tableoid;
6638 int i_oid;
6639 int i_opcmethod;
6640 int i_opcname;
6641 int i_opcnamespace;
6642 int i_opcowner;
6643
6644 /*
6645 * find all opclasses, including builtin opclasses; we filter out
6646 * system-defined opclasses at dump-out time.
6647 */
6648
6649 appendPQExpBufferStr(query, "SELECT tableoid, oid, opcmethod, opcname, "
6650 "opcnamespace, "
6651 "opcowner "
6652 "FROM pg_opclass");
6653
6654 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6655
6656 ntups = PQntuples(res);
6657
6658 opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6659
6660 i_tableoid = PQfnumber(res, "tableoid");
6661 i_oid = PQfnumber(res, "oid");
6662 i_opcmethod = PQfnumber(res, "opcmethod");
6663 i_opcname = PQfnumber(res, "opcname");
6664 i_opcnamespace = PQfnumber(res, "opcnamespace");
6665 i_opcowner = PQfnumber(res, "opcowner");
6666
6667 for (i = 0; i < ntups; i++)
6668 {
6669 opcinfo[i].dobj.objType = DO_OPCLASS;
6670 opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6671 opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6672 AssignDumpId(&opcinfo[i].dobj);
6673 opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6674 opcinfo[i].dobj.namespace =
6675 findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6676 opcinfo[i].opcmethod = atooid(PQgetvalue(res, i, i_opcmethod));
6677 opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6678
6679 /* Decide whether we want to dump it */
6680 selectDumpableObject(&(opcinfo[i].dobj), fout);
6681 }
6682
6683 PQclear(res);
6684
6685 destroyPQExpBuffer(query);
6686}
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 6352 of file pg_dump.c.

6353{
6354 PGresult *res;
6355 int ntups;
6356 int i;
6358 OprInfo *oprinfo;
6359 int i_tableoid;
6360 int i_oid;
6361 int i_oprname;
6362 int i_oprnamespace;
6363 int i_oprowner;
6364 int i_oprkind;
6365 int i_oprleft;
6366 int i_oprright;
6367 int i_oprcode;
6368
6369 /*
6370 * find all operators, including builtin operators; we filter out
6371 * system-defined operators at dump-out time.
6372 */
6373
6374 appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
6375 "oprnamespace, "
6376 "oprowner, "
6377 "oprkind, "
6378 "oprleft, "
6379 "oprright, "
6380 "oprcode::oid AS oprcode "
6381 "FROM pg_operator");
6382
6383 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6384
6385 ntups = PQntuples(res);
6386
6387 oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6388
6389 i_tableoid = PQfnumber(res, "tableoid");
6390 i_oid = PQfnumber(res, "oid");
6391 i_oprname = PQfnumber(res, "oprname");
6392 i_oprnamespace = PQfnumber(res, "oprnamespace");
6393 i_oprowner = PQfnumber(res, "oprowner");
6394 i_oprkind = PQfnumber(res, "oprkind");
6395 i_oprleft = PQfnumber(res, "oprleft");
6396 i_oprright = PQfnumber(res, "oprright");
6397 i_oprcode = PQfnumber(res, "oprcode");
6398
6399 for (i = 0; i < ntups; i++)
6400 {
6401 oprinfo[i].dobj.objType = DO_OPERATOR;
6402 oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6403 oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6404 AssignDumpId(&oprinfo[i].dobj);
6405 oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6406 oprinfo[i].dobj.namespace =
6407 findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6408 oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6409 oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6410 oprinfo[i].oprleft = atooid(PQgetvalue(res, i, i_oprleft));
6411 oprinfo[i].oprright = atooid(PQgetvalue(res, i, i_oprright));
6412 oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6413
6414 /* Decide whether we want to dump it */
6415 selectDumpableObject(&(oprinfo[i].dobj), fout);
6416 }
6417
6418 PQclear(res);
6419
6420 destroyPQExpBuffer(query);
6421}
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 6693 of file pg_dump.c.

6694{
6695 PGresult *res;
6696 int ntups;
6697 int i;
6698 PQExpBuffer query;
6699 OpfamilyInfo *opfinfo;
6700 int i_tableoid;
6701 int i_oid;
6702 int i_opfmethod;
6703 int i_opfname;
6704 int i_opfnamespace;
6705 int i_opfowner;
6706
6707 query = createPQExpBuffer();
6708
6709 /*
6710 * find all opfamilies, including builtin opfamilies; we filter out
6711 * system-defined opfamilies at dump-out time.
6712 */
6713
6714 appendPQExpBufferStr(query, "SELECT tableoid, oid, opfmethod, opfname, "
6715 "opfnamespace, "
6716 "opfowner "
6717 "FROM pg_opfamily");
6718
6719 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6720
6721 ntups = PQntuples(res);
6722
6723 opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6724
6725 i_tableoid = PQfnumber(res, "tableoid");
6726 i_oid = PQfnumber(res, "oid");
6727 i_opfname = PQfnumber(res, "opfname");
6728 i_opfmethod = PQfnumber(res, "opfmethod");
6729 i_opfnamespace = PQfnumber(res, "opfnamespace");
6730 i_opfowner = PQfnumber(res, "opfowner");
6731
6732 for (i = 0; i < ntups; i++)
6733 {
6734 opfinfo[i].dobj.objType = DO_OPFAMILY;
6735 opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6736 opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6737 AssignDumpId(&opfinfo[i].dobj);
6738 opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6739 opfinfo[i].dobj.namespace =
6740 findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6741 opfinfo[i].opfmethod = atooid(PQgetvalue(res, i, i_opfmethod));
6742 opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6743
6744 /* Decide whether we want to dump it */
6745 selectDumpableObject(&(opfinfo[i].dobj), fout);
6746 }
6747
6748 PQclear(res);
6749
6750 destroyPQExpBuffer(query);
6751}
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 7648 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

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

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

7098{
7099 if (!fout->dopt->dumpStatistics)
7100 return NULL;
7101
7102 if ((relkind == RELKIND_RELATION) ||
7103 (relkind == RELKIND_PARTITIONED_TABLE) ||
7104 (relkind == RELKIND_INDEX) ||
7105 (relkind == RELKIND_PARTITIONED_INDEX) ||
7106 (relkind == RELKIND_MATVIEW ||
7107 relkind == RELKIND_FOREIGN_TABLE))
7108 {
7109 RelStatsInfo *info = pg_malloc0(sizeof(RelStatsInfo));
7110 DumpableObject *dobj = &info->dobj;
7111
7112 dobj->objType = DO_REL_STATS;
7113 dobj->catId.tableoid = 0;
7114 dobj->catId.oid = 0;
7115 AssignDumpId(dobj);
7116 dobj->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
7117 dobj->dependencies[0] = rel->dumpId;
7118 dobj->nDeps = 1;
7119 dobj->allocDeps = 1;
7121 dobj->name = pg_strdup(rel->name);
7122 dobj->namespace = rel->namespace;
7123 info->relpages = relpages;
7124 info->reltuples = pstrdup(reltuples);
7125 info->relallvisible = relallvisible;
7126 info->relallfrozen = relallfrozen;
7127 info->relkind = relkind;
7128 info->indAttNames = indAttNames;
7129 info->nindAttNames = nindAttNames;
7130
7131 /*
7132 * Ordinarily, stats go in SECTION_DATA for tables and
7133 * SECTION_POST_DATA for indexes.
7134 *
7135 * However, the section may be updated later for materialized view
7136 * stats. REFRESH MATERIALIZED VIEW replaces the storage and resets
7137 * the stats, so the stats must be restored after the data. Also, the
7138 * materialized view definition may be postponed to SECTION_POST_DATA
7139 * (see repairMatViewBoundaryMultiLoop()).
7140 */
7141 switch (info->relkind)
7142 {
7143 case RELKIND_RELATION:
7144 case RELKIND_PARTITIONED_TABLE:
7145 case RELKIND_MATVIEW:
7146 case RELKIND_FOREIGN_TABLE:
7147 info->section = SECTION_DATA;
7148 break;
7149 case RELKIND_INDEX:
7150 case RELKIND_PARTITIONED_INDEX:
7151 info->section = SECTION_POST_DATA;
7152 break;
7153 default:
7154 pg_fatal("cannot dump statistics for relation kind \"%c\"",
7155 info->relkind);
7156 }
7157
7158 return info;
7159 }
7160 return NULL;
7161}
#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 10666 of file pg_dump.c.

10667{
10668 Oid roleoid = atooid(roleoid_str);
10669
10670 /*
10671 * Do binary search to find the appropriate item.
10672 */
10673 if (nrolenames > 0)
10674 {
10675 RoleNameItem *low = &rolenames[0];
10676 RoleNameItem *high = &rolenames[nrolenames - 1];
10677
10678 while (low <= high)
10679 {
10680 RoleNameItem *middle = low + (high - low) / 2;
10681
10682 if (roleoid < middle->roleoid)
10683 high = middle - 1;
10684 else if (roleoid > middle->roleoid)
10685 low = middle + 1;
10686 else
10687 return middle->rolename; /* found a match */
10688 }
10689 }
10690
10691 pg_fatal("role with OID %u does not exist", roleoid);
10692 return NULL; /* keep compiler quiet */
10693}

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

2804{
2805 TableInfo *parentTbinfo;
2806
2807 Assert(tbinfo->ispartition);
2808 Assert(tbinfo->numParents == 1);
2809
2810 parentTbinfo = tbinfo->parents[0];
2811 while (parentTbinfo->ispartition)
2812 {
2813 Assert(parentTbinfo->numParents == 1);
2814 parentTbinfo = parentTbinfo->parents[0];
2815 }
2816
2817 return parentTbinfo;
2818}

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

Referenced by dumpTableData(), and dumpTableData_insert().

◆ getRules()

void getRules ( Archive fout)

Definition at line 8571 of file pg_dump.c.

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

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

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

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

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

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

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

3007{
3008 int i;
3009
3010 for (i = 0; i < numTables; i++)
3011 {
3012 if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
3013 (!relkind || tblinfo[i].relkind == relkind))
3014 makeTableDataInfo(dopt, &(tblinfo[i]));
3015 }
3016}
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:3025

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

Referenced by main().

◆ getTableDataFKConstraints()

static void getTableDataFKConstraints ( void  )
static

Definition at line 3227 of file pg_dump.c.

3228{
3229 DumpableObject **dobjs;
3230 int numObjs;
3231 int i;
3232
3233 /* Search through all the dumpable objects for FK constraints */
3234 getDumpableObjects(&dobjs, &numObjs);
3235 for (i = 0; i < numObjs; i++)
3236 {
3237 if (dobjs[i]->objType == DO_FK_CONSTRAINT)
3238 {
3239 ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
3240 TableInfo *ftable;
3241
3242 /* Not interesting unless both tables are to be dumped */
3243 if (cinfo->contable == NULL ||
3244 cinfo->contable->dataObj == NULL)
3245 continue;
3246 ftable = findTableByOid(cinfo->confrelid);
3247 if (ftable == NULL ||
3248 ftable->dataObj == NULL)
3249 continue;
3250
3251 /*
3252 * Okay, make referencing table's TABLE_DATA object depend on the
3253 * referenced table's TABLE_DATA object.
3254 */
3256 ftable->dataObj->dobj.dumpId);
3257 }
3258 }
3259 free(dobjs);
3260}
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 7171 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

References _, printf, and progname.

Referenced by main().

◆ is_superuser()

static bool is_superuser ( Archive fout)
static

Definition at line 5053 of file pg_dump.c.

5054{
5055 ArchiveHandle *AH = (ArchiveHandle *) fout;
5056 const char *val;
5057
5058 val = PQparameterStatus(AH->connection, "is_superuser");
5059
5060 if (val && strcmp(val, "on") == 0)
5061 return true;
5062
5063 return false;
5064}
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/--schema-only and -a/--data-only cannot be used together");
835 if (schema_only && statistics_only)
836 pg_fatal("options -s/--schema-only and --statistics-only cannot be used together");
837 if (data_only && statistics_only)
838 pg_fatal("options -a/--data-only and --statistics-only cannot be used together");
839
840 /* reject conflicting "-only" and "no-" options */
841 if (data_only && no_data)
842 pg_fatal("options -a/--data-only and --no-data cannot be used together");
843 if (schema_only && no_schema)
844 pg_fatal("options -s/--schema-only and --no-schema cannot be used together");
846 pg_fatal("options --statistics-only and --no-statistics cannot be used together");
847
848 /* reject conflicting "no-" options */
850 pg_fatal("options --statistics and --no-statistics cannot be used together");
851
852 /* reject conflicting "-only" options */
853 if (data_only && with_statistics)
854 pg_fatal("options %s and %s cannot be used together",
855 "-a/--data-only", "--statistics");
856 if (schema_only && with_statistics)
857 pg_fatal("options %s and %s cannot be used together",
858 "-s/--schema-only", "--statistics");
859
860 if (schema_only && foreign_servers_include_patterns.head != NULL)
861 pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
862
863 if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
864 pg_fatal("option --include-foreign-data is not supported with parallel backup");
865
866 if (data_only && dopt.outputClean)
867 pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
868
869 if (dopt.if_exists && !dopt.outputClean)
870 pg_fatal("option --if-exists requires option -c/--clean");
871
872 /*
873 * Set derivative flags. Ambiguous or nonsensical combinations, e.g.
874 * "--schema-only --no-schema", will have already caused an error in one
875 * of the checks above.
876 */
877 dopt.dumpData = ((dopt.dumpData && !schema_only && !statistics_only) ||
878 data_only) && !no_data;
879 dopt.dumpSchema = ((dopt.dumpSchema && !data_only && !statistics_only) ||
880 schema_only) && !no_schema;
881 dopt.dumpStatistics = ((dopt.dumpStatistics && !schema_only && !data_only) ||
883
884
885 /*
886 * --inserts are already implied above if --column-inserts or
887 * --rows-per-insert were specified.
888 */
889 if (dopt.do_nothing && dopt.dump_inserts == 0)
890 pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
891
892 /* Identify archive format to emit */
893 archiveFormat = parseArchiveFormat(format, &archiveMode);
894
895 /* archiveFormat specific setup */
896 if (archiveFormat == archNull)
897 {
898 plainText = 1;
899
900 /*
901 * If you don't provide a restrict key, one will be appointed for you.
902 */
903 if (!dopt.restrict_key)
905 if (!dopt.restrict_key)
906 pg_fatal("could not generate restrict key");
908 pg_fatal("invalid restrict key");
909 }
910 else if (dopt.restrict_key)
911 pg_fatal("option --restrict-key can only be used with --format=plain");
912
913 /*
914 * Custom and directory formats are compressed by default with gzip when
915 * available, not the others. If gzip is not available, no compression is
916 * done by default.
917 */
918 if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
919 !user_compression_defined)
920 {
921#ifdef HAVE_LIBZ
922 compression_algorithm_str = "gzip";
923#else
924 compression_algorithm_str = "none";
925#endif
926 }
927
928 /*
929 * Compression options
930 */
931 if (!parse_compress_algorithm(compression_algorithm_str,
933 pg_fatal("unrecognized compression algorithm: \"%s\"",
934 compression_algorithm_str);
935
937 &compression_spec);
938 error_detail = validate_compress_specification(&compression_spec);
939 if (error_detail != NULL)
940 pg_fatal("invalid compression specification: %s",
941 error_detail);
942
943 error_detail = supports_compression(compression_spec);
944 if (error_detail != NULL)
945 pg_fatal("%s", error_detail);
946
947 /*
948 * Disable support for zstd workers for now - these are based on
949 * threading, and it's unclear how it interacts with parallel dumps on
950 * platforms where that relies on threads too (e.g. Windows).
951 */
952 if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
953 pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
954 "workers");
955
956 /*
957 * If emitting an archive format, we always want to emit a DATABASE item,
958 * in case --create is specified at pg_restore time.
959 */
960 if (!plainText)
961 dopt.outputCreateDB = 1;
962
963 /* Parallel backup only in the directory archive format so far */
964 if (archiveFormat != archDirectory && numWorkers > 1)
965 pg_fatal("parallel backup only supported by the directory format");
966
967 /* Open the output file */
968 fout = CreateArchive(filename, archiveFormat, compression_spec,
969 dosync, archiveMode, setupDumpWorker, sync_method);
970
971 /* Make dump options accessible right away */
972 SetArchiveOptions(fout, &dopt, NULL);
973
974 /* Register the cleanup hook */
976
977 /* Let the archiver know how noisy to be */
978 fout->verbose = g_verbose;
979
980
981 /*
982 * We allow the server to be back to 9.2, and up to any minor release of
983 * our own major version. (See also version check in pg_dumpall.c.)
984 */
985 fout->minRemoteVersion = 90200;
986 fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
987
988 fout->numWorkers = numWorkers;
989
990 /*
991 * Open the database using the Archiver, so it knows about it. Errors mean
992 * death.
993 */
994 ConnectDatabaseAhx(fout, &dopt.cparams, false);
995 setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
996
997 /*
998 * On hot standbys, never try to dump unlogged table data, since it will
999 * just throw an error.
1000 */
1001 if (fout->isStandby)
1002 dopt.no_unlogged_table_data = true;
1003
1004 /*
1005 * Find the last built-in OID, if needed (prior to 8.1)
1006 *
1007 * With 8.1 and above, we can just use FirstNormalObjectId - 1.
1008 */
1010
1011 pg_log_info("last built-in OID is %u", g_last_builtin_oid);
1012
1013 /* Expand schema selection patterns into OID lists */
1014 if (schema_include_patterns.head != NULL)
1015 {
1018 strict_names);
1019 if (schema_include_oids.head == NULL)
1020 pg_fatal("no matching schemas were found");
1021 }
1024 false);
1025 /* non-matching exclusion patterns aren't an error */
1026
1027 /* Expand table selection patterns into OID lists */
1030 strict_names, false);
1033 strict_names, true);
1034 if ((table_include_patterns.head != NULL ||
1036 table_include_oids.head == NULL)
1037 pg_fatal("no matching tables were found");
1038
1041 false, false);
1044 false, true);
1045
1048 false, false);
1051 false, true);
1052
1055
1056 /* non-matching exclusion patterns aren't an error */
1057
1058 /* Expand extension selection patterns into OID lists */
1059 if (extension_include_patterns.head != NULL)
1060 {
1063 strict_names);
1064 if (extension_include_oids.head == NULL)
1065 pg_fatal("no matching extensions were found");
1066 }
1069 false);
1070 /* non-matching exclusion patterns aren't an error */
1071
1072 /*
1073 * Dumping LOs is the default for dumps where an inclusion switch is not
1074 * used (an "include everything" dump). -B can be used to exclude LOs
1075 * from those dumps. -b can be used to include LOs even when an inclusion
1076 * switch is used.
1077 *
1078 * -s means "schema only" and LOs are data, not schema, so we never
1079 * include LOs when -s is used.
1080 */
1081 if (dopt.include_everything && dopt.dumpData && !dopt.dontOutputLOs)
1082 dopt.outputLOs = true;
1083
1084 /*
1085 * Collect role names so we can map object owner OIDs to names.
1086 */
1087 collectRoleNames(fout);
1088
1089 /*
1090 * Now scan the database and create DumpableObject structs for all the
1091 * objects we intend to dump.
1092 */
1093 tblinfo = getSchemaData(fout, &numTables);
1094
1095 if (dopt.dumpData)
1096 {
1097 getTableData(&dopt, tblinfo, numTables, 0);
1099 if (!dopt.dumpSchema)
1101 }
1102
1103 if (!dopt.dumpData && dopt.sequence_data)
1104 getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
1105
1106 /*
1107 * For binary upgrade mode, dump pg_largeobject_metadata and the
1108 * associated pg_shdepend rows. This is faster to restore than the
1109 * equivalent set of large object commands. We can only do this for
1110 * upgrades from v12 and newer; in older versions, pg_largeobject_metadata
1111 * was created WITH OIDS, so the OID column is hidden and won't be dumped.
1112 */
1113 if (dopt.binary_upgrade && fout->remoteVersion >= 120000)
1114 {
1115 TableInfo *lo_metadata = findTableByOid(LargeObjectMetadataRelationId);
1116 TableInfo *shdepend = findTableByOid(SharedDependRelationId);
1117
1118 makeTableDataInfo(&dopt, lo_metadata);
1119 makeTableDataInfo(&dopt, shdepend);
1120
1121 /*
1122 * Save pg_largeobject_metadata's dump ID for use as a dependency for
1123 * pg_shdepend and any large object comments/seclabels.
1124 */
1125 lo_metadata_dumpId = lo_metadata->dataObj->dobj.dumpId;
1127
1128 /*
1129 * Only dump large object shdepend rows for this database.
1130 */
1131 shdepend->dataObj->filtercond = "WHERE classid = 'pg_largeobject'::regclass "
1132 "AND dbid = (SELECT oid FROM pg_database "
1133 " WHERE datname = current_database())";
1134
1135 /*
1136 * If upgrading from v16 or newer, only dump large objects with
1137 * comments/seclabels. For these upgrades, pg_upgrade can copy/link
1138 * pg_largeobject_metadata's files (which is usually faster) but we
1139 * still need to dump LOs with comments/seclabels here so that the
1140 * subsequent COMMENT and SECURITY LABEL commands work. pg_upgrade
1141 * can't copy/link the files from older versions because aclitem
1142 * (needed by pg_largeobject_metadata.lomacl) changed its storage
1143 * format in v16.
1144 */
1145 if (fout->remoteVersion >= 160000)
1146 lo_metadata->dataObj->filtercond = "WHERE oid IN "
1147 "(SELECT objoid FROM pg_description "
1148 "WHERE classoid = " CppAsString2(LargeObjectRelationId) " "
1149 "UNION SELECT objoid FROM pg_seclabel "
1150 "WHERE classoid = " CppAsString2(LargeObjectRelationId) ")";
1151 }
1152
1153 /*
1154 * In binary-upgrade mode, we do not have to worry about the actual LO
1155 * data or the associated metadata that resides in the pg_largeobject and
1156 * pg_largeobject_metadata tables, respectively.
1157 *
1158 * However, we do need to collect LO information as there may be comments
1159 * or other information on LOs that we do need to dump out.
1160 */
1161 if (dopt.outputLOs || dopt.binary_upgrade)
1162 getLOs(fout);
1163
1164 /*
1165 * Collect dependency data to assist in ordering the objects.
1166 */
1167 getDependencies(fout);
1168
1169 /*
1170 * Collect ACLs, comments, and security labels, if wanted.
1171 */
1172 if (!dopt.aclsSkip)
1173 getAdditionalACLs(fout);
1174 if (!dopt.no_comments)
1175 collectComments(fout);
1176 if (!dopt.no_security_labels)
1177 collectSecLabels(fout);
1178
1179 /* For binary upgrade mode, collect required pg_class information. */
1180 if (dopt.binary_upgrade)
1182
1183 /* Collect sequence information. */
1184 collectSequences(fout);
1185
1186 /* Lastly, create dummy objects to represent the section boundaries */
1187 boundaryObjs = createBoundaryObjects();
1188
1189 /* Get pointers to all the known DumpableObjects */
1190 getDumpableObjects(&dobjs, &numObjs);
1191
1192 /*
1193 * Add dummy dependencies to enforce the dump section ordering.
1194 */
1195 addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
1196
1197 /*
1198 * Sort the objects into a safe dump order (no forward references).
1199 *
1200 * We rely on dependency information to help us determine a safe order, so
1201 * the initial sort is mostly for cosmetic purposes: we sort by name to
1202 * ensure that logically identical schemas will dump identically.
1203 */
1204 sortDumpableObjectsByTypeName(dobjs, numObjs);
1205
1206 sortDumpableObjects(dobjs, numObjs,
1207 boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
1208
1209 /*
1210 * Create archive TOC entries for all the objects to be dumped, in a safe
1211 * order.
1212 */
1213
1214 /*
1215 * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
1216 */
1217 dumpEncoding(fout);
1218 dumpStdStrings(fout);
1219 dumpSearchPath(fout);
1220
1221 /* The database items are always next, unless we don't want them at all */
1222 if (dopt.outputCreateDB)
1223 dumpDatabase(fout);
1224
1225 /* Now the rearrangeable objects. */
1226 for (i = 0; i < numObjs; i++)
1227 dumpDumpableObject(fout, dobjs[i]);
1228
1229 /*
1230 * Set up options info to ensure we dump what we want.
1231 */
1232 ropt = NewRestoreOptions();
1233 ropt->filename = filename;
1234
1235 /* if you change this list, see dumpOptionsFromRestoreOptions */
1236 ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
1237 ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
1238 ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
1239 ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
1241 ropt->dropSchema = dopt.outputClean;
1242 ropt->dumpData = dopt.dumpData;
1243 ropt->dumpSchema = dopt.dumpSchema;
1244 ropt->dumpStatistics = dopt.dumpStatistics;
1245 ropt->if_exists = dopt.if_exists;
1246 ropt->column_inserts = dopt.column_inserts;
1247 ropt->dumpSections = dopt.dumpSections;
1248 ropt->aclsSkip = dopt.aclsSkip;
1249 ropt->superuser = dopt.outputSuperuser;
1250 ropt->createDB = dopt.outputCreateDB;
1251 ropt->noOwner = dopt.outputNoOwner;
1252 ropt->noTableAm = dopt.outputNoTableAm;
1253 ropt->noTablespace = dopt.outputNoTablespaces;
1255 ropt->use_setsessauth = dopt.use_setsessauth;
1257 ropt->dump_inserts = dopt.dump_inserts;
1258 ropt->no_comments = dopt.no_comments;
1259 ropt->no_policies = dopt.no_policies;
1260 ropt->no_publications = dopt.no_publications;
1263 ropt->lockWaitTimeout = dopt.lockWaitTimeout;
1266 ropt->sequence_data = dopt.sequence_data;
1267 ropt->binary_upgrade = dopt.binary_upgrade;
1268 ropt->restrict_key = dopt.restrict_key ? pg_strdup(dopt.restrict_key) : NULL;
1269
1270 ropt->compression_spec = compression_spec;
1271
1272 ropt->suppressDumpWarnings = true; /* We've already shown them */
1273
1274 SetArchiveOptions(fout, &dopt, ropt);
1275
1276 /* Mark which entries should be output */
1278
1279 /*
1280 * The archive's TOC entries are now marked as to which ones will actually
1281 * be output, so we can set up their dependency lists properly. This isn't
1282 * necessary for plain-text output, though.
1283 */
1284 if (!plainText)
1286
1287 /*
1288 * And finally we can do the actual output.
1289 *
1290 * Note: for non-plain-text output formats, the output file is written
1291 * inside CloseArchive(). This is, um, bizarre; but not worth changing
1292 * right now.
1293 */
1294 if (plainText)
1295 RestoreArchive(fout);
1296
1297 CloseArchive(fout);
1298
1299 exit_nicely(0);
1300}
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:1217
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:1649
static void dumpEncoding(Archive *AH)
Definition: pg_dump.c:3821
static SimpleStringList schema_include_patterns
Definition: pg_dump.c:165
static void collectBinaryUpgradeClassOids(Archive *fout)
Definition: pg_dump.c:5809
static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
Definition: pg_dump.c:20123
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3870
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:20099
static void dumpDatabase(Archive *fout)
Definition: pg_dump.c:3268
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:3846
static void help(const char *progname)
Definition: pg_dump.c:1304
static void BuildArchiveDependencies(Archive *fout)
Definition: pg_dump.c:20249
static void collectRoleNames(Archive *fout)
Definition: pg_dump.c:10702
static bool dosync
Definition: pg_dump.c:150
static void getDependencies(Archive *fout)
Definition: pg_dump.c:19946
static void buildMatViewRefreshDependencies(Archive *fout)
Definition: pg_dump.c:3112
#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:1582
static SimpleStringList table_include_patterns_and_children
Definition: pg_dump.c:171
static void getAdditionalACLs(Archive *fout)
Definition: pg_dump.c:10737
static void getTableDataFKConstraints(void)
Definition: pg_dump.c:3227
static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
Definition: pg_dump.c:3006
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:175
static void collectComments(Archive *fout)
Definition: pg_dump.c:11562
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:11647
static void getLOs(Archive *fout)
Definition: pg_dump.c:3932
static void setup_connection(Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role)
Definition: pg_dump.c:1412
static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names, bool with_child_tables)
Definition: pg_dump.c:1813
static void expand_foreign_server_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
Definition: pg_dump.c:1761
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:16763
static void collectSequences(Archive *fout)
Definition: pg_dump.c:18897
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode)
Definition: pg_dump.c:1611
static void read_dump_filters(const char *filename, DumpOptions *dopt)
Definition: pg_dump.c:20469
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:1708
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 3025 of file pg_dump.c.

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

20439{
20440 /* Don't want to print it if it's just "{}" */
20441 return (reloptions != NULL && strlen(reloptions) > 2);
20442}

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

◆ parse_sequence_type()

static SeqType parse_sequence_type ( const char *  name)
inlinestatic

Definition at line 18866 of file pg_dump.c.

18867{
18868 for (int i = 0; i < lengthof(SeqTypeNames); i++)
18869 {
18870 if (strcmp(SeqTypeNames[i], name) == 0)
18871 return (SeqType) i;
18872 }
18873
18874 pg_fatal("unrecognized sequence type: %s", name);
18875 return (SeqType) 0; /* keep compiler quiet */
18876}
#define lengthof(array)
Definition: c.h:791

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

1612{
1613 ArchiveFormat archiveFormat;
1614
1616
1617 if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
1618 {
1619 /* This is used by pg_dumpall, and is not documented */
1620 archiveFormat = archNull;
1622 }
1623 else if (pg_strcasecmp(format, "c") == 0)
1624 archiveFormat = archCustom;
1625 else if (pg_strcasecmp(format, "custom") == 0)
1626 archiveFormat = archCustom;
1627 else if (pg_strcasecmp(format, "d") == 0)
1628 archiveFormat = archDirectory;
1629 else if (pg_strcasecmp(format, "directory") == 0)
1630 archiveFormat = archDirectory;
1631 else if (pg_strcasecmp(format, "p") == 0)
1632 archiveFormat = archNull;
1633 else if (pg_strcasecmp(format, "plain") == 0)
1634 archiveFormat = archNull;
1635 else if (pg_strcasecmp(format, "t") == 0)
1636 archiveFormat = archTar;
1637 else if (pg_strcasecmp(format, "tar") == 0)
1638 archiveFormat = archTar;
1639 else
1640 pg_fatal("invalid output format \"%s\" specified", format);
1641 return archiveFormat;
1642}
@ 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 19765 of file pg_dump.c.

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

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

1910{
1911 const char *db;
1912
1913 db = PQdb(conn);
1914 if (db == NULL)
1915 pg_fatal("You are currently not connected to a database.");
1916
1917 if (strcmp(db, dbname) != 0)
1918 pg_fatal("cross-database references are not implemented: %s",
1919 pattern);
1920}
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 20469 of file pg_dump.c.

20470{
20471 FilterStateData fstate;
20472 char *objname;
20473 FilterCommandType comtype;
20474 FilterObjectType objtype;
20475
20476 filter_init(&fstate, filename, exit_nicely);
20477
20478 while (filter_read_item(&fstate, &objname, &comtype, &objtype))
20479 {
20480 if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
20481 {
20482 switch (objtype)
20483 {
20485 break;
20492 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20493 "include",
20494 filter_object_type_name(objtype));
20495 exit_nicely(1);
20496 break; /* unreachable */
20497
20500 break;
20503 break;
20506 dopt->include_everything = false;
20507 break;
20510 dopt->include_everything = false;
20511 break;
20514 objname);
20515 dopt->include_everything = false;
20516 break;
20517 }
20518 }
20519 else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
20520 {
20521 switch (objtype)
20522 {
20524 break;
20530 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20531 "exclude",
20532 filter_object_type_name(objtype));
20533 exit_nicely(1);
20534 break;
20535
20538 break;
20541 objname);
20542 break;
20545 objname);
20546 break;
20549 break;
20552 break;
20555 objname);
20556 break;
20557 }
20558 }
20559 else
20560 {
20561 Assert(comtype == FILTER_COMMAND_TYPE_NONE);
20562 Assert(objtype == FILTER_OBJECT_TYPE_NONE);
20563 }
20564
20565 if (objname)
20566 free(objname);
20567 }
20568
20569 filter_free(&fstate);
20570}
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 2971 of file pg_dump.c.

2972{
2973 TableInfo *tbinfo = tdinfo->tdtable;
2974 PQExpBuffer q;
2975
2976 /* If the materialized view is not flagged as populated, skip this. */
2977 if (!tbinfo->relispopulated)
2978 return;
2979
2980 q = createPQExpBuffer();
2981
2982 appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
2983 fmtQualifiedDumpable(tbinfo));
2984
2985 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2986 ArchiveEntry(fout,
2987 tdinfo->dobj.catId, /* catalog ID */
2988 tdinfo->dobj.dumpId, /* dump ID */
2989 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2990 .namespace = tbinfo->dobj.namespace->dobj.name,
2991 .owner = tbinfo->rolname,
2992 .description = "MATERIALIZED VIEW DATA",
2993 .section = SECTION_POST_DATA,
2994 .createStmt = q->data,
2995 .deps = tdinfo->dobj.dependencies,
2996 .nDeps = tdinfo->dobj.nDeps));
2997
2999}

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

2235{
2236 /* see getAccessMethods() comment about v9.6. */
2237 if (fout->remoteVersion < 90600)
2238 {
2239 method->dobj.dump = DUMP_COMPONENT_NONE;
2240 return;
2241 }
2242
2243 if (checkExtensionMembership(&method->dobj, fout))
2244 return; /* extension membership overrides all else */
2245
2246 /*
2247 * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
2248 * they do not support ACLs currently.
2249 */
2250 if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2251 method->dobj.dump = DUMP_COMPONENT_NONE;
2252 else
2253 method->dobj.dump = fout->dopt->include_everything ?
2255}
static bool checkExtensionMembership(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:1934
#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 2176 of file pg_dump.c.

2177{
2178 if (checkExtensionMembership(&cast->dobj, fout))
2179 return; /* extension membership overrides all else */
2180
2181 /*
2182 * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
2183 * support ACLs currently.
2184 */
2185 if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2187 else
2188 cast->dobj.dump = fout->dopt->include_everything ?
2190}

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

2155{
2156 /* Default ACLs can't be extension members */
2157
2158 if (dinfo->dobj.namespace)
2159 /* default ACLs are considered part of the namespace */
2160 dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
2161 else
2162 dinfo->dobj.dump = dopt->include_everything ?
2164}

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

2270{
2271 /*
2272 * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
2273 * change permissions on their member objects, if they wish to, and have
2274 * those changes preserved.
2275 */
2276 if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2277 extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
2278 else
2279 {
2280 /* check if there is a list of extensions to dump */
2281 if (extension_include_oids.head != NULL)
2282 extinfo->dobj.dump = extinfo->dobj.dump_contains =
2284 extinfo->dobj.catId.oid) ?
2286 else
2287 extinfo->dobj.dump = extinfo->dobj.dump_contains =
2288 dopt->include_everything ?
2290
2291 /* check that the extension is not explicitly excluded */
2292 if (extinfo->dobj.dump &&
2294 extinfo->dobj.catId.oid))
2295 extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
2296 }
2297}

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

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

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

2345{
2346 if (checkExtensionMembership(dobj, fout))
2347 return; /* extension membership overrides all else */
2348
2349 /*
2350 * Default policy is to dump if parent namespace is dumpable, or for
2351 * non-namespace-associated items, dump if we're dumping "everything".
2352 */
2353 if (dobj->namespace)
2354 dobj->dump = dobj->namespace->dobj.dump_contains;
2355 else
2356 dobj->dump = fout->dopt->include_everything ?
2358}

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

2202{
2203 if (checkExtensionMembership(&plang->dobj, fout))
2204 return; /* extension membership overrides all else */
2205
2206 /*
2207 * Only include procedural languages when we are dumping everything.
2208 *
2209 * For from-initdb procedural languages, only include ACLs, as we do for
2210 * the pg_catalog namespace. We need this because procedural languages do
2211 * not live in any namespace.
2212 */
2213 if (!fout->dopt->include_everything)
2214 plang->dobj.dump = DUMP_COMPONENT_NONE;
2215 else
2216 {
2217 if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2218 plang->dobj.dump = fout->remoteVersion < 90600 ?
2220 else
2221 plang->dobj.dump = DUMP_COMPONENT_ALL;
2222 }
2223}

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

2309{
2310 if (checkExtensionMembership(dobj, fout))
2311 return; /* extension membership overrides all else */
2312
2313 dobj->dump = fout->dopt->include_everything ?
2315}

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

2327{
2328 if (checkExtensionMembership(&sobj->dobj, fout))
2329 return; /* extension membership overrides all else */
2330
2331 sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
2332 if (sobj->stattable == NULL ||
2335}

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

2071{
2072 if (checkExtensionMembership(&tbinfo->dobj, fout))
2073 return; /* extension membership overrides all else */
2074
2075 /*
2076 * If specific tables are being dumped, dump just those tables; else, dump
2077 * according to the parent namespace's dump flag.
2078 */
2079 if (table_include_oids.head != NULL)
2081 tbinfo->dobj.catId.oid) ?
2083 else
2084 tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
2085
2086 /*
2087 * In any case, a table can be excluded by an exclusion switch
2088 */
2089 if (tbinfo->dobj.dump &&
2091 tbinfo->dobj.catId.oid))
2092 tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
2093}

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

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

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

18883{
18884 SequenceItem v1 = *((const SequenceItem *) p1);
18885 SequenceItem v2 = *((const SequenceItem *) p2);
18886
18887 return pg_cmp_u32(v1.oid, v2.oid);
18888}

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

5073{
5075 PGresult *res;
5076
5077 appendPQExpBuffer(query,
5078 "SELECT set_config(name, '%s', false) "
5079 "FROM pg_settings "
5080 "WHERE name = 'restrict_nonsystem_relation_kind'",
5081 value);
5082 res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
5083
5084 PQclear(res);
5085 destroyPQExpBuffer(query);
5086}
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 1412 of file pg_dump.c.

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

1583{
1584 /*
1585 * We want to re-select all the same values the leader connection is
1586 * using. We'll have inherited directly-usable values in
1587 * AH->sync_snapshot_id and AH->use_role, but we need to translate the
1588 * inherited encoding value back to a string to pass to setup_connection.
1589 */
1592 NULL,
1593 NULL);
1594}

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

10125{
10126 if (dopt->binary_upgrade)
10127 return true;
10128 if (tbinfo->attisdropped[colno])
10129 return false;
10130 return (tbinfo->attislocal[colno] || tbinfo->ispartition);
10131}

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