PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_dump.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_aggregate_d.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_attribute_d.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_cast_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_default_acl_d.h"
#include "catalog/pg_largeobject_d.h"
#include "catalog/pg_proc_d.h"
#include "catalog/pg_publication_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_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 getSubscriptionTables (Archive *fout)
 
static void append_depends_on_extension (Archive *fout, PQExpBuffer create, const DumpableObject *dobj, const char *catalog, const char *keyword, const char *objname)
 
static Oid get_next_possible_free_pg_type_oid (Archive *fout, PQExpBuffer upgrade_query)
 
static int BinaryUpgradeClassOidItemCmp (const void *p1, const void *p2)
 
void getNamespaces (Archive *fout)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
void getTypes (Archive *fout)
 
void getOperators (Archive *fout)
 
void getCollations (Archive *fout)
 
void getConversions (Archive *fout)
 
void getAccessMethods (Archive *fout)
 
void getOpclasses (Archive *fout)
 
void getOpfamilies (Archive *fout)
 
void getAggregates (Archive *fout)
 
void getFuncs (Archive *fout)
 
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
 

Macro Definition Documentation

◆ DUMP_DEFAULT_ROWS_PER_INSERT

#define DUMP_DEFAULT_ROWS_PER_INSERT   1

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

◆ MAX_ATTR_STATS_RELS

#define MAX_ATTR_STATS_RELS   64

Definition at line 213 of file pg_dump.c.

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

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

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

◆ SeqType

enum SeqType
Enumerator
SEQTYPE_SMALLINT 
SEQTYPE_INTEGER 
SEQTYPE_BIGINT 

Definition at line 108 of file pg_dump.c.

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

Function Documentation

◆ addBoundaryDependencies()

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

Definition at line 19722 of file pg_dump.c.

19724{
19725 DumpableObject *preDataBound = boundaryObjs + 0;
19726 DumpableObject *postDataBound = boundaryObjs + 1;
19727 int i;
19728
19729 for (i = 0; i < numObjs; i++)
19730 {
19731 DumpableObject *dobj = dobjs[i];
19732
19733 /*
19734 * The classification of object types here must match the SECTION_xxx
19735 * values assigned during subsequent ArchiveEntry calls!
19736 */
19737 switch (dobj->objType)
19738 {
19739 case DO_NAMESPACE:
19740 case DO_EXTENSION:
19741 case DO_TYPE:
19742 case DO_SHELL_TYPE:
19743 case DO_FUNC:
19744 case DO_AGG:
19745 case DO_OPERATOR:
19746 case DO_ACCESS_METHOD:
19747 case DO_OPCLASS:
19748 case DO_OPFAMILY:
19749 case DO_COLLATION:
19750 case DO_CONVERSION:
19751 case DO_TABLE:
19752 case DO_TABLE_ATTACH:
19753 case DO_ATTRDEF:
19754 case DO_PROCLANG:
19755 case DO_CAST:
19756 case DO_DUMMY_TYPE:
19757 case DO_TSPARSER:
19758 case DO_TSDICT:
19759 case DO_TSTEMPLATE:
19760 case DO_TSCONFIG:
19761 case DO_FDW:
19762 case DO_FOREIGN_SERVER:
19763 case DO_TRANSFORM:
19764 /* Pre-data objects: must come before the pre-data boundary */
19765 addObjectDependency(preDataBound, dobj->dumpId);
19766 break;
19767 case DO_TABLE_DATA:
19768 case DO_SEQUENCE_SET:
19769 case DO_LARGE_OBJECT:
19771 /* Data objects: must come between the boundaries */
19772 addObjectDependency(dobj, preDataBound->dumpId);
19773 addObjectDependency(postDataBound, dobj->dumpId);
19774 break;
19775 case DO_INDEX:
19776 case DO_INDEX_ATTACH:
19777 case DO_STATSEXT:
19778 case DO_REFRESH_MATVIEW:
19779 case DO_TRIGGER:
19780 case DO_EVENT_TRIGGER:
19781 case DO_DEFAULT_ACL:
19782 case DO_POLICY:
19783 case DO_PUBLICATION:
19784 case DO_PUBLICATION_REL:
19786 case DO_SUBSCRIPTION:
19788 /* Post-data objects: must come after the post-data boundary */
19789 addObjectDependency(dobj, postDataBound->dumpId);
19790 break;
19791 case DO_RULE:
19792 /* Rules are post-data, but only if dumped separately */
19793 if (((RuleInfo *) dobj)->separate)
19794 addObjectDependency(dobj, postDataBound->dumpId);
19795 break;
19796 case DO_CONSTRAINT:
19797 case DO_FK_CONSTRAINT:
19798 /* Constraints are post-data, but only if dumped separately */
19799 if (((ConstraintInfo *) dobj)->separate)
19800 addObjectDependency(dobj, postDataBound->dumpId);
19801 break;
19803 /* nothing to do */
19804 break;
19806 /* must come after the pre-data boundary */
19807 addObjectDependency(dobj, preDataBound->dumpId);
19808 break;
19809 case DO_REL_STATS:
19810 /* stats section varies by parent object type, DATA or POST */
19811 if (((RelStatsInfo *) dobj)->section == SECTION_DATA)
19812 {
19813 addObjectDependency(dobj, preDataBound->dumpId);
19814 addObjectDependency(postDataBound, dobj->dumpId);
19815 }
19816 else
19817 addObjectDependency(dobj, postDataBound->dumpId);
19818 break;
19819 }
19820 }
19821}
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:817
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 8221 of file pg_dump.c.

8222{
8223 SimplePtrListCell *cell;
8224
8226
8227 for (cell = refidx->partattaches.head; cell; cell = cell->next)
8228 {
8229 IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
8230
8231 addObjectDependency(dobj, attach->dobj.dumpId);
8232
8233 if (attach->partitionIdx->partattaches.head != NULL)
8234 addConstrChildIdxDeps(dobj, attach->partitionIdx);
8235 }
8236}
Assert(PointerIsAligned(start, uint64))
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:8221
struct SimplePtrListCell * next
Definition: simple_list.h:48
SimplePtrListCell * head
Definition: simple_list.h:54
IndxInfo * partitionIdx
Definition: pg_dump.h:437
DumpableObject dobj
Definition: pg_dump.h:435
SimplePtrList partattaches
Definition: pg_dump.h:427

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

5446{
5447 if (dobj->depends_on_ext)
5448 {
5449 char *nm;
5450 PGresult *res;
5451 PQExpBuffer query;
5452 int ntups;
5453 int i_extname;
5454 int i;
5455
5456 /* dodge fmtId() non-reentrancy */
5457 nm = pg_strdup(objname);
5458
5459 query = createPQExpBuffer();
5460 appendPQExpBuffer(query,
5461 "SELECT e.extname "
5462 "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
5463 "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
5464 "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
5465 "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
5466 catalog,
5467 dobj->catId.oid);
5468 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5469 ntups = PQntuples(res);
5470 i_extname = PQfnumber(res, "extname");
5471 for (i = 0; i < ntups; i++)
5472 {
5473 appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
5474 keyword, nm,
5475 fmtId(PQgetvalue(res, i, i_extname)));
5476 }
5477
5478 PQclear(res);
5479 destroyPQExpBuffer(query);
5480 pg_free(nm);
5481 }
5482}
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
void PQclear(PGresult *res)
Definition: fe-exec.c:721
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3589
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
@ PGRES_TUPLES_OK
Definition: libpq-fe.h: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 10712 of file pg_dump.c.

10714{
10715 appendPQExpBufferStr(out, ",\n\t");
10716
10717 appendStringLiteralAH(out, argname, fout);
10718 appendPQExpBufferStr(out, ", ");
10719
10720 appendStringLiteralAH(out, argval, fout);
10721 appendPQExpBuffer(out, "::%s", argtype);
10722}
#define appendStringLiteralAH(buf, str, AH)
Definition: pg_backup.h:339
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 20049 of file pg_dump.c.

20051{
20052 bool res;
20053
20054 res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
20055 fout->std_strings);
20056 if (!res)
20057 pg_log_warning("could not parse %s array", "reloptions");
20058}
#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:240
int encoding
Definition: pg_backup.h:239

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

5756{
5757 DumpableObject *extobj = NULL;
5758 int i;
5759
5760 if (!dobj->ext_member)
5761 return;
5762
5763 /*
5764 * Find the parent extension. We could avoid this search if we wanted to
5765 * add a link field to DumpableObject, but the space costs of that would
5766 * be considerable. We assume that member objects could only have a
5767 * direct dependency on their own extension, not any others.
5768 */
5769 for (i = 0; i < dobj->nDeps; i++)
5770 {
5771 extobj = findObjectByDumpId(dobj->dependencies[i]);
5772 if (extobj && extobj->objType == DO_EXTENSION)
5773 break;
5774 extobj = NULL;
5775 }
5776 if (extobj == NULL)
5777 pg_fatal("could not find parent extension for %s %s",
5778 objtype, objname);
5779
5780 appendPQExpBufferStr(upgrade_buffer,
5781 "\n-- For binary upgrade, handle extension membership the hard way\n");
5782 appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
5783 fmtId(extobj->name),
5784 objtype);
5785 if (objnamespace && *objnamespace)
5786 appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
5787 appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
5788}
DumpableObject * findObjectByDumpId(DumpId dumpId)
Definition: common.c:764
#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 5661 of file pg_dump.c.

5663{
5666
5668
5669 /*
5670 * Preserve the OID and relfilenumber of the table, table's index, table's
5671 * toast table and toast table's index if any.
5672 *
5673 * One complexity is that the current table definition might not require
5674 * the creation of a TOAST table, but the old database might have a TOAST
5675 * table that was created earlier, before some wide columns were dropped.
5676 * By setting the TOAST oid we force creation of the TOAST heap and index
5677 * by the new backend, so we can copy the files during binary upgrade
5678 * without worrying about this case.
5679 */
5680 key.oid = pg_class_oid;
5684
5685 appendPQExpBufferStr(upgrade_buffer,
5686 "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5687
5688 if (entry->relkind != RELKIND_INDEX &&
5689 entry->relkind != RELKIND_PARTITIONED_INDEX)
5690 {
5691 appendPQExpBuffer(upgrade_buffer,
5692 "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
5693 pg_class_oid);
5694
5695 /*
5696 * Not every relation has storage. Also, in a pre-v12 database,
5697 * partitioned tables have a relfilenumber, which should not be
5698 * preserved when upgrading.
5699 */
5700 if (RelFileNumberIsValid(entry->relfilenumber) &&
5701 entry->relkind != RELKIND_PARTITIONED_TABLE)
5702 appendPQExpBuffer(upgrade_buffer,
5703 "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5704 entry->relfilenumber);
5705
5706 /*
5707 * In a pre-v12 database, partitioned tables might be marked as having
5708 * toast tables, but we should ignore them if so.
5709 */
5710 if (OidIsValid(entry->toast_oid) &&
5711 entry->relkind != RELKIND_PARTITIONED_TABLE)
5712 {
5713 appendPQExpBuffer(upgrade_buffer,
5714 "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5715 entry->toast_oid);
5716 appendPQExpBuffer(upgrade_buffer,
5717 "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5718 entry->toast_relfilenumber);
5719
5720 /* every toast table has an index */
5721 appendPQExpBuffer(upgrade_buffer,
5722 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5723 entry->toast_index_oid);
5724 appendPQExpBuffer(upgrade_buffer,
5725 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5727 }
5728 }
5729 else
5730 {
5731 /* Preserve the OID and relfilenumber of the index */
5732 appendPQExpBuffer(upgrade_buffer,
5733 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5734 pg_class_oid);
5735 appendPQExpBuffer(upgrade_buffer,
5736 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5737 entry->relfilenumber);
5738 }
5739
5740 appendPQExpBufferChar(upgrade_buffer, '\n');
5741}
#define OidIsValid(objectId)
Definition: c.h:746
static int nbinaryUpgradeClassOids
Definition: pg_dump.c:206
static BinaryUpgradeClassOidItem * binaryUpgradeClassOids
Definition: pg_dump.c:205
static int BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:5611
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
#define RelFileNumberIsValid(relnumber)
Definition: relpath.h:27
RelFileNumber toast_index_relfilenumber
Definition: pg_dump.c:104
RelFileNumber toast_relfilenumber
Definition: pg_dump.c:102
RelFileNumber relfilenumber
Definition: pg_dump.c:100

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

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

◆ binary_upgrade_set_type_oids_by_rel()

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

Definition at line 5596 of file pg_dump.c.

5599{
5600 Oid pg_type_oid = tbinfo->reltype;
5601
5602 if (OidIsValid(pg_type_oid))
5603 binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
5604 pg_type_oid, false, false);
5605}
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:5516
unsigned int Oid
Definition: postgres_ext.h:30
Oid reltype
Definition: pg_dump.h:324

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

5521{
5522 PQExpBuffer upgrade_query = createPQExpBuffer();
5523 PGresult *res;
5524 Oid pg_type_array_oid;
5525 Oid pg_type_multirange_oid;
5526 Oid pg_type_multirange_array_oid;
5527 TypeInfo *tinfo;
5528
5529 appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
5530 appendPQExpBuffer(upgrade_buffer,
5531 "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5532 pg_type_oid);
5533
5534 tinfo = findTypeByOid(pg_type_oid);
5535 if (tinfo)
5536 pg_type_array_oid = tinfo->typarray;
5537 else
5538 pg_type_array_oid = InvalidOid;
5539
5540 if (!OidIsValid(pg_type_array_oid) && force_array_type)
5541 pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5542
5543 if (OidIsValid(pg_type_array_oid))
5544 {
5545 appendPQExpBufferStr(upgrade_buffer,
5546 "\n-- For binary upgrade, must preserve pg_type array oid\n");
5547 appendPQExpBuffer(upgrade_buffer,
5548 "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5549 pg_type_array_oid);
5550 }
5551
5552 /*
5553 * Pre-set the multirange type oid and its own array type oid.
5554 */
5555 if (include_multirange_type)
5556 {
5557 if (fout->remoteVersion >= 140000)
5558 {
5559 printfPQExpBuffer(upgrade_query,
5560 "SELECT t.oid, t.typarray "
5561 "FROM pg_catalog.pg_type t "
5562 "JOIN pg_catalog.pg_range r "
5563 "ON t.oid = r.rngmultitypid "
5564 "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
5565 pg_type_oid);
5566
5567 res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5568
5569 pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
5570 pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
5571
5572 PQclear(res);
5573 }
5574 else
5575 {
5576 pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5577 pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
5578 }
5579
5580 appendPQExpBufferStr(upgrade_buffer,
5581 "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
5582 appendPQExpBuffer(upgrade_buffer,
5583 "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5584 pg_type_multirange_oid);
5585 appendPQExpBufferStr(upgrade_buffer,
5586 "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
5587 appendPQExpBuffer(upgrade_buffer,
5588 "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
5589 pg_type_multirange_array_oid);
5590 }
5591
5592 destroyPQExpBuffer(upgrade_query);
5593}
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:898
static const gbtree_vinfo tinfo
Definition: btree_bit.c:108
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:5485
#define InvalidOid
Definition: postgres_ext.h:35
#define atooid(x)
Definition: postgres_ext.h:41
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
int remoteVersion
Definition: pg_backup.h:229

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

5612{
5615
5616 return pg_cmp_u32(v1.oid, v2.oid);
5617}
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 19848 of file pg_dump.c.

19849{
19850 ArchiveHandle *AH = (ArchiveHandle *) fout;
19851 TocEntry *te;
19852
19853 /* Scan all TOC entries in the archive */
19854 for (te = AH->toc->next; te != AH->toc; te = te->next)
19855 {
19856 DumpableObject *dobj;
19857 DumpId *dependencies;
19858 int nDeps;
19859 int allocDeps;
19860
19861 /* No need to process entries that will not be dumped */
19862 if (te->reqs == 0)
19863 continue;
19864 /* Ignore entries that already have "special" dependencies */
19865 if (te->nDeps > 0)
19866 continue;
19867 /* Otherwise, look up the item's original DumpableObject, if any */
19868 dobj = findObjectByDumpId(te->dumpId);
19869 if (dobj == NULL)
19870 continue;
19871 /* No work if it has no dependencies */
19872 if (dobj->nDeps <= 0)
19873 continue;
19874 /* Set up work array */
19875 allocDeps = 64;
19876 dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
19877 nDeps = 0;
19878 /* Recursively find all dumpable dependencies */
19879 findDumpableDependencies(AH, dobj,
19880 &dependencies, &nDeps, &allocDeps);
19881 /* And save 'em ... */
19882 if (nDeps > 0)
19883 {
19884 dependencies = (DumpId *) pg_realloc(dependencies,
19885 nDeps * sizeof(DumpId));
19886 te->dependencies = dependencies;
19887 te->nDeps = nDeps;
19888 }
19889 else
19890 free(dependencies);
19891 }
19892}
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:280
static void findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
Definition: pg_dump.c:19896
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 3035 of file pg_dump.c.

3036{
3037 PQExpBuffer query;
3038 PGresult *res;
3039 int ntups,
3040 i;
3041 int i_classid,
3042 i_objid,
3043 i_refobjid;
3044
3045 /* No Mat Views before 9.3. */
3046 if (fout->remoteVersion < 90300)
3047 return;
3048
3049 query = createPQExpBuffer();
3050
3051 appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
3052 "( "
3053 "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
3054 "FROM pg_depend d1 "
3055 "JOIN pg_class c1 ON c1.oid = d1.objid "
3056 "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
3057 " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
3058 "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
3059 "AND d2.objid = r1.oid "
3060 "AND d2.refobjid <> d1.objid "
3061 "JOIN pg_class c2 ON c2.oid = d2.refobjid "
3062 "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
3063 CppAsString2(RELKIND_VIEW) ") "
3064 "WHERE d1.classid = 'pg_class'::regclass "
3065 "UNION "
3066 "SELECT w.objid, d3.refobjid, c3.relkind "
3067 "FROM w "
3068 "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
3069 "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
3070 "AND d3.objid = r3.oid "
3071 "AND d3.refobjid <> w.refobjid "
3072 "JOIN pg_class c3 ON c3.oid = d3.refobjid "
3073 "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
3074 CppAsString2(RELKIND_VIEW) ") "
3075 ") "
3076 "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
3077 "FROM w "
3078 "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
3079
3080 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3081
3082 ntups = PQntuples(res);
3083
3084 i_classid = PQfnumber(res, "classid");
3085 i_objid = PQfnumber(res, "objid");
3086 i_refobjid = PQfnumber(res, "refobjid");
3087
3088 for (i = 0; i < ntups; i++)
3089 {
3090 CatalogId objId;
3091 CatalogId refobjId;
3092 DumpableObject *dobj;
3093 DumpableObject *refdobj;
3094 TableInfo *tbinfo;
3095 TableInfo *reftbinfo;
3096
3097 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
3098 objId.oid = atooid(PQgetvalue(res, i, i_objid));
3099 refobjId.tableoid = objId.tableoid;
3100 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
3101
3102 dobj = findObjectByCatalogId(objId);
3103 if (dobj == NULL)
3104 continue;
3105
3106 Assert(dobj->objType == DO_TABLE);
3107 tbinfo = (TableInfo *) dobj;
3108 Assert(tbinfo->relkind == RELKIND_MATVIEW);
3109 dobj = (DumpableObject *) tbinfo->dataObj;
3110 if (dobj == NULL)
3111 continue;
3113
3114 refdobj = findObjectByCatalogId(refobjId);
3115 if (refdobj == NULL)
3116 continue;
3117
3118 Assert(refdobj->objType == DO_TABLE);
3119 reftbinfo = (TableInfo *) refdobj;
3120 Assert(reftbinfo->relkind == RELKIND_MATVIEW);
3121 refdobj = (DumpableObject *) reftbinfo->dataObj;
3122 if (refdobj == NULL)
3123 continue;
3124 Assert(refdobj->objType == DO_REFRESH_MATVIEW);
3125
3126 addObjectDependency(dobj, refdobj->dumpId);
3127
3128 if (!reftbinfo->relispopulated)
3129 tbinfo->relispopulated = false;
3130 }
3131
3132 PQclear(res);
3133
3134 destroyPQExpBuffer(query);
3135}
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:777
#define CppAsString2(x)
Definition: c.h:363
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
Oid tableoid
Definition: pg_backup.h:276
bool relispopulated
Definition: pg_dump.h:305
struct _tableDataInfo * dataObj
Definition: pg_dump.h:382
char relkind
Definition: pg_dump.h:303

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

1868{
1870
1871 if (ext == NULL)
1872 return false;
1873
1874 dobj->ext_member = true;
1875
1876 /* Record dependency so that getDependencies needn't deal with that */
1877 addObjectDependency(dobj, ext->dobj.dumpId);
1878
1879 /*
1880 * In 9.6 and above, mark the member object to have any non-initial ACLs
1881 * dumped. (Any initial ACLs will be removed later, using data from
1882 * pg_init_privs, so that we'll dump only the delta from the extension's
1883 * initial setup.)
1884 *
1885 * Prior to 9.6, we do not include any extension member components.
1886 *
1887 * In binary upgrades, we still dump all components of the members
1888 * individually, since the idea is to exactly reproduce the database
1889 * contents rather than replace the extension contents with something
1890 * different.
1891 *
1892 * Note: it might be interesting someday to implement storage and delta
1893 * dumping of extension members' RLS policies and/or security labels.
1894 * However there is a pitfall for RLS policies: trying to dump them
1895 * requires getting a lock on their tables, and the calling user might not
1896 * have privileges for that. We need no lock to examine a table's ACLs,
1897 * so the current feature doesn't have a problem of that sort.
1898 */
1899 if (fout->dopt->binary_upgrade)
1900 dobj->dump = ext->dobj.dump;
1901 else
1902 {
1903 if (fout->remoteVersion < 90600)
1904 dobj->dump = DUMP_COMPONENT_NONE;
1905 else
1906 dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
1907 }
1908
1909 return true;
1910}
ExtensionInfo * findOwningExtension(CatalogId catalogId)
Definition: common.c:1068
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:113
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:108
DumpOptions * dopt
Definition: pg_backup.h:224
int binary_upgrade
Definition: pg_backup.h:172
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 5627 of file pg_dump.c.

5628{
5629 PGresult *res;
5630 const char *query;
5631
5632 query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5633 "ct.relfilenode, i.indexrelid, cti.relfilenode "
5634 "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5635 "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5636 "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5637 "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5638 "ORDER BY c.oid;";
5639
5640 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5641
5645
5646 for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5647 {
5655 }
5656
5657 PQclear(res);
5658}

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

11293{
11294 PGresult *res;
11295 PQExpBuffer query;
11296 int i_description;
11297 int i_classoid;
11298 int i_objoid;
11299 int i_objsubid;
11300 int ntups;
11301 int i;
11302 DumpableObject *dobj;
11303
11304 query = createPQExpBuffer();
11305
11306 appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
11307 "FROM pg_catalog.pg_description "
11308 "ORDER BY classoid, objoid, objsubid");
11309
11310 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11311
11312 /* Construct lookup table containing OIDs in numeric form */
11313
11314 i_description = PQfnumber(res, "description");
11315 i_classoid = PQfnumber(res, "classoid");
11316 i_objoid = PQfnumber(res, "objoid");
11317 i_objsubid = PQfnumber(res, "objsubid");
11318
11319 ntups = PQntuples(res);
11320
11321 comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
11322 ncomments = 0;
11323 dobj = NULL;
11324
11325 for (i = 0; i < ntups; i++)
11326 {
11327 CatalogId objId;
11328 int subid;
11329
11330 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
11331 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
11332 subid = atoi(PQgetvalue(res, i, i_objsubid));
11333
11334 /* We needn't remember comments that don't match any dumpable object */
11335 if (dobj == NULL ||
11336 dobj->catId.tableoid != objId.tableoid ||
11337 dobj->catId.oid != objId.oid)
11338 dobj = findObjectByCatalogId(objId);
11339 if (dobj == NULL)
11340 continue;
11341
11342 /*
11343 * Comments on columns of composite types are linked to the type's
11344 * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
11345 * in the type's own DumpableObject.
11346 */
11347 if (subid != 0 && dobj->objType == DO_TABLE &&
11348 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
11349 {
11350 TypeInfo *cTypeInfo;
11351
11352 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
11353 if (cTypeInfo)
11355 }
11356 else
11357 dobj->components |= DUMP_COMPONENT_COMMENT;
11358
11359 comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
11361 comments[ncomments].objoid = objId.oid;
11362 comments[ncomments].objsubid = subid;
11363 ncomments++;
11364 }
11365
11366 PQclear(res);
11367 destroyPQExpBuffer(query);
11368}
static int ncomments
Definition: pg_dump.c:198
static CommentItem * comments
Definition: pg_dump.c:197
#define DUMP_COMPONENT_COMMENT
Definition: pg_dump.h:111
Oid classoid
Definition: pg_dump.c:82
Oid objoid
Definition: pg_dump.c:83
int objsubid
Definition: pg_dump.c:84
const char * descr
Definition: pg_dump.c:81
DumpComponents components
Definition: pg_dump.h: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 10432 of file pg_dump.c.

10433{
10434 PGresult *res;
10435 const char *query;
10436 int i;
10437
10438 query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
10439
10440 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
10441
10442 nrolenames = PQntuples(res);
10443
10445
10446 for (i = 0; i < nrolenames; i++)
10447 {
10448 rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
10450 }
10451
10452 PQclear(res);
10453}
static RoleNameItem * rolenames
Definition: pg_dump.c:193
static int nrolenames
Definition: pg_dump.c:194
const char * rolename
Definition: pg_dump.c:76
Oid roleoid
Definition: pg_dump.c:75

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

Referenced by main().

◆ collectSecLabels()

static void collectSecLabels ( Archive fout)
static

Definition at line 16442 of file pg_dump.c.

16443{
16444 PGresult *res;
16445 PQExpBuffer query;
16446 int i_label;
16447 int i_provider;
16448 int i_classoid;
16449 int i_objoid;
16450 int i_objsubid;
16451 int ntups;
16452 int i;
16453 DumpableObject *dobj;
16454
16455 query = createPQExpBuffer();
16456
16458 "SELECT label, provider, classoid, objoid, objsubid "
16459 "FROM pg_catalog.pg_seclabel "
16460 "ORDER BY classoid, objoid, objsubid");
16461
16462 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16463
16464 /* Construct lookup table containing OIDs in numeric form */
16465 i_label = PQfnumber(res, "label");
16466 i_provider = PQfnumber(res, "provider");
16467 i_classoid = PQfnumber(res, "classoid");
16468 i_objoid = PQfnumber(res, "objoid");
16469 i_objsubid = PQfnumber(res, "objsubid");
16470
16471 ntups = PQntuples(res);
16472
16473 seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
16474 nseclabels = 0;
16475 dobj = NULL;
16476
16477 for (i = 0; i < ntups; i++)
16478 {
16479 CatalogId objId;
16480 int subid;
16481
16482 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
16483 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
16484 subid = atoi(PQgetvalue(res, i, i_objsubid));
16485
16486 /* We needn't remember labels that don't match any dumpable object */
16487 if (dobj == NULL ||
16488 dobj->catId.tableoid != objId.tableoid ||
16489 dobj->catId.oid != objId.oid)
16490 dobj = findObjectByCatalogId(objId);
16491 if (dobj == NULL)
16492 continue;
16493
16494 /*
16495 * Labels on columns of composite types are linked to the type's
16496 * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
16497 * in the type's own DumpableObject.
16498 */
16499 if (subid != 0 && dobj->objType == DO_TABLE &&
16500 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
16501 {
16502 TypeInfo *cTypeInfo;
16503
16504 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
16505 if (cTypeInfo)
16507 }
16508 else
16509 dobj->components |= DUMP_COMPONENT_SECLABEL;
16510
16511 seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
16512 seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
16514 seclabels[nseclabels].objoid = objId.oid;
16515 seclabels[nseclabels].objsubid = subid;
16516 nseclabels++;
16517 }
16518
16519 PQclear(res);
16520 destroyPQExpBuffer(query);
16521}
static int nseclabels
Definition: pg_dump.c:202
static SecLabelItem * seclabels
Definition: pg_dump.c:201
#define DUMP_COMPONENT_SECLABEL
Definition: pg_dump.h:112
const char * provider
Definition: pg_dump.c:89
Oid classoid
Definition: pg_dump.c:91
int objsubid
Definition: pg_dump.c:93
const char * label
Definition: pg_dump.c:90
Oid objoid
Definition: pg_dump.c:92

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

Referenced by main().

◆ collectSequences()

static void collectSequences ( Archive fout)
static

Definition at line 18501 of file pg_dump.c.

18502{
18503 PGresult *res;
18504 const char *query;
18505
18506 /*
18507 * Before Postgres 10, sequence metadata is in the sequence itself. With
18508 * some extra effort, we might be able to use the sorted table for those
18509 * versions, but for now it seems unlikely to be worth it.
18510 *
18511 * Since version 18, we can gather the sequence data in this query with
18512 * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
18513 */
18514 if (fout->remoteVersion < 100000)
18515 return;
18516 else if (fout->remoteVersion < 180000 ||
18517 (!fout->dopt->dumpData && !fout->dopt->sequence_data))
18518 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18519 "seqstart, seqincrement, "
18520 "seqmax, seqmin, "
18521 "seqcache, seqcycle, "
18522 "NULL, 'f' "
18523 "FROM pg_catalog.pg_sequence "
18524 "ORDER BY seqrelid";
18525 else
18526 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18527 "seqstart, seqincrement, "
18528 "seqmax, seqmin, "
18529 "seqcache, seqcycle, "
18530 "last_value, is_called "
18531 "FROM pg_catalog.pg_sequence, "
18532 "pg_get_sequence_data(seqrelid) "
18533 "ORDER BY seqrelid;";
18534
18535 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
18536
18537 nsequences = PQntuples(res);
18539
18540 for (int i = 0; i < nsequences; i++)
18541 {
18542 sequences[i].oid = atooid(PQgetvalue(res, i, 0));
18544 sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
18545 sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
18546 sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
18547 sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
18548 sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
18549 sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
18550 sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
18551 sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
18552 }
18553
18554 PQclear(res);
18555}
static int nsequences
Definition: pg_dump.c:210
static SeqType parse_sequence_type(const char *name)
Definition: pg_dump.c:18470
static SequenceItem * sequences
Definition: pg_dump.c:209
int64 minv
Definition: pg_dump.c:130
int64 cache
Definition: pg_dump.c:134
int64 startv
Definition: pg_dump.c:132
int64 maxv
Definition: pg_dump.c:131
bool is_called
Definition: pg_dump.c:136
int64 incby
Definition: pg_dump.c:133
int64 last_value
Definition: pg_dump.c:135
SeqType seqtype
Definition: pg_dump.c:128
bool cycled
Definition: pg_dump.c:129
int sequence_data
Definition: pg_backup.h:209
bool dumpData
Definition: pg_backup.h:214

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

13990{
13991 char *name;
13992 char *paren;
13993 bool inquote;
13994
13995 /* In all cases "-" means a null reference */
13996 if (strcmp(proc, "-") == 0)
13997 return NULL;
13998
13999 name = pg_strdup(proc);
14000 /* find non-double-quoted left paren */
14001 inquote = false;
14002 for (paren = name; *paren; paren++)
14003 {
14004 if (*paren == '(' && !inquote)
14005 {
14006 *paren = '\0';
14007 break;
14008 }
14009 if (*paren == '"')
14010 inquote = !inquote;
14011 }
14012 return name;
14013}
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 14060 of file pg_dump.c.

14061{
14062 char *result;
14063 char query[128];
14064 PGresult *res;
14065
14066 snprintf(query, sizeof(query),
14067 "SELECT '%u'::pg_catalog.regproc", funcOid);
14068 res = ExecuteSqlQueryForSingleRow(fout, query);
14069
14070 result = pg_strdup(PQgetvalue(res, 0, 0));
14071
14072 PQclear(res);
14073
14074 return result;
14075}
#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 19698 of file pg_dump.c.

19699{
19700 DumpableObject *dobjs;
19701
19702 dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
19703
19704 dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
19705 dobjs[0].catId = nilCatalogId;
19706 AssignDumpId(dobjs + 0);
19707 dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
19708
19709 dobjs[1].objType = DO_POST_DATA_BOUNDARY;
19710 dobjs[1].catId = nilCatalogId;
19711 AssignDumpId(dobjs + 1);
19712 dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
19713
19714 return dobjs;
19715}
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:656
static const CatalogId nilCatalogId
Definition: pg_dump.c:186

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

16718{
16719 PQExpBuffer result = createPQExpBuffer();
16720 int j;
16721
16722 appendPQExpBufferStr(result, "SELECT");
16723
16724 for (j = 0; j < tbinfo->numatts; j++)
16725 {
16726 if (j > 0)
16727 appendPQExpBufferChar(result, ',');
16728 appendPQExpBufferStr(result, "\n ");
16729
16730 appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
16731
16732 /*
16733 * Must add collation if not default for the type, because CREATE OR
16734 * REPLACE VIEW won't change it
16735 */
16736 if (OidIsValid(tbinfo->attcollation[j]))
16737 {
16738 CollInfo *coll;
16739
16740 coll = findCollationByOid(tbinfo->attcollation[j]);
16741 if (coll)
16742 appendPQExpBuffer(result, " COLLATE %s",
16743 fmtQualifiedDumpable(coll));
16744 }
16745
16746 appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
16747 }
16748
16749 return result;
16750}
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:953
int j
Definition: isn.c:78
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:231
int numatts
Definition: pg_dump.h:347
Oid * attcollation
Definition: pg_dump.h:360
char ** atttypnames
Definition: pg_dump.h:349
char ** attnames
Definition: pg_dump.h:348

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

16669{
16671 PQExpBuffer result = createPQExpBuffer();
16672 PGresult *res;
16673 int len;
16674
16675 /* Fetch the view definition */
16676 appendPQExpBuffer(query,
16677 "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
16678 tbinfo->dobj.catId.oid);
16679
16680 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16681
16682 if (PQntuples(res) != 1)
16683 {
16684 if (PQntuples(res) < 1)
16685 pg_fatal("query to obtain definition of view \"%s\" returned no data",
16686 tbinfo->dobj.name);
16687 else
16688 pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
16689 tbinfo->dobj.name);
16690 }
16691
16692 len = PQgetlength(res, 0, 0);
16693
16694 if (len == 0)
16695 pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
16696 tbinfo->dobj.name);
16697
16698 /* Strip off the trailing semicolon so that other things may follow. */
16699 Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
16700 appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
16701
16702 PQclear(res);
16703 destroyPQExpBuffer(query);
16704
16705 return result;
16706}
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3887
const void size_t len
void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
Definition: pqexpbuffer.c:397
DumpableObject dobj
Definition: pg_dump.h:300

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_invalidoid,
int  i_notnull_noinherit,
int  i_notnull_islocal,
PQExpBuffer invalidnotnulloids 
)
static

Definition at line 9730 of file pg_dump.c.

9737{
9738 DumpOptions *dopt = fout->dopt;
9739
9740 /*
9741 * If this not-null constraint is not valid, list its OID in
9742 * invalidnotnulloids and do nothing further. It'll be processed
9743 * elsewhere later.
9744 *
9745 * Because invalid not-null constraints are rare, we don't want to malloc
9746 * invalidnotnulloids until we're sure we're going it need it, which
9747 * happens here.
9748 */
9749 if (!PQgetisnull(res, r, i_notnull_invalidoid))
9750 {
9751 char *constroid = PQgetvalue(res, r, i_notnull_invalidoid);
9752
9753 if (*invalidnotnulloids == NULL)
9754 {
9755 *invalidnotnulloids = createPQExpBuffer();
9756 appendPQExpBufferChar(*invalidnotnulloids, '{');
9757 appendPQExpBufferStr(*invalidnotnulloids, constroid);
9758 }
9759 else
9760 appendPQExpBuffer(*invalidnotnulloids, ",%s", constroid);
9761
9762 /*
9763 * Track when a parent constraint is invalid for the cases where a
9764 * child constraint has been validated independenly.
9765 */
9766 tbinfo->notnull_invalid[j] = true;
9767
9768 /* nothing else to do */
9769 tbinfo->notnull_constrs[j] = NULL;
9770 return;
9771 }
9772
9773 /*
9774 * notnull_noinh is straight from the query result. notnull_islocal also,
9775 * though flagInhAttrs may change that one later.
9776 */
9777 tbinfo->notnull_noinh[j] = PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
9778 tbinfo->notnull_islocal[j] = PQgetvalue(res, r, i_notnull_islocal)[0] == 't';
9779 tbinfo->notnull_invalid[j] = false;
9780
9781 /*
9782 * Determine a constraint name to use. If the column is not marked not-
9783 * null, we set NULL which cues ... to do nothing. An empty string says
9784 * to print an unnamed NOT NULL, and anything else is a constraint name to
9785 * use.
9786 */
9787 if (fout->remoteVersion < 180000)
9788 {
9789 /*
9790 * < 18 doesn't have not-null names, so an unnamed constraint is
9791 * sufficient.
9792 */
9793 if (PQgetisnull(res, r, i_notnull_name))
9794 tbinfo->notnull_constrs[j] = NULL;
9795 else
9796 tbinfo->notnull_constrs[j] = "";
9797 }
9798 else
9799 {
9800 if (PQgetisnull(res, r, i_notnull_name))
9801 tbinfo->notnull_constrs[j] = NULL;
9802 else
9803 {
9804 /*
9805 * In binary upgrade of inheritance child tables, must have a
9806 * constraint name that we can UPDATE later.
9807 */
9808 if (dopt->binary_upgrade &&
9809 !tbinfo->ispartition &&
9810 !tbinfo->notnull_islocal)
9811 {
9812 tbinfo->notnull_constrs[j] =
9813 pstrdup(PQgetvalue(res, r, i_notnull_name));
9814 }
9815 else
9816 {
9817 char *default_name;
9818
9819 /* XXX should match ChooseConstraintName better */
9820 default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
9821 tbinfo->attnames[j]);
9822 if (strcmp(default_name,
9823 PQgetvalue(res, r, i_notnull_name)) == 0)
9824 tbinfo->notnull_constrs[j] = "";
9825 else
9826 {
9827 tbinfo->notnull_constrs[j] =
9828 pstrdup(PQgetvalue(res, r, i_notnull_name));
9829 }
9830 free(default_name);
9831 }
9832 }
9833 }
9834}
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
char * pstrdup(const char *in)
Definition: mcxt.c:1703
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
bool * notnull_invalid
Definition: pg_dump.h:368
char ** notnull_constrs
Definition: pg_dump.h:364
bool ispartition
Definition: pg_dump.h:337
bool * notnull_islocal
Definition: pg_dump.h:370
bool * notnull_noinh
Definition: pg_dump.h:369

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

14083{
14084 DumpOptions *dopt = fout->dopt;
14085 PQExpBuffer q;
14086 PQExpBuffer delq;
14087 char *qamname;
14088
14089 /* Do nothing if not dumping schema */
14090 if (!dopt->dumpSchema)
14091 return;
14092
14093 q = createPQExpBuffer();
14094 delq = createPQExpBuffer();
14095
14096 qamname = pg_strdup(fmtId(aminfo->dobj.name));
14097
14098 appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
14099
14100 switch (aminfo->amtype)
14101 {
14102 case AMTYPE_INDEX:
14103 appendPQExpBufferStr(q, "TYPE INDEX ");
14104 break;
14105 case AMTYPE_TABLE:
14106 appendPQExpBufferStr(q, "TYPE TABLE ");
14107 break;
14108 default:
14109 pg_log_warning("invalid type \"%c\" of access method \"%s\"",
14110 aminfo->amtype, qamname);
14112 destroyPQExpBuffer(delq);
14113 free(qamname);
14114 return;
14115 }
14116
14117 appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
14118
14119 appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
14120 qamname);
14121
14122 if (dopt->binary_upgrade)
14124 "ACCESS METHOD", qamname, NULL);
14125
14126 if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14127 ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
14128 ARCHIVE_OPTS(.tag = aminfo->dobj.name,
14129 .description = "ACCESS METHOD",
14130 .section = SECTION_PRE_DATA,
14131 .createStmt = q->data,
14132 .dropStmt = delq->data));
14133
14134 /* Dump Access Method Comments */
14135 if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14136 dumpComment(fout, "ACCESS METHOD", qamname,
14137 NULL, "",
14138 aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
14139
14141 destroyPQExpBuffer(delq);
14142 free(qamname);
14143}
@ 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:10696
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:5751
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:109
char * amhandler
Definition: pg_dump.h:268
DumpableObject dobj
Definition: pg_dump.h:266
bool dumpSchema
Definition: pg_backup.h:213

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

16077{
16078 DumpId aclDumpId = InvalidDumpId;
16079 DumpOptions *dopt = fout->dopt;
16080 const char *acls = dacl->acl;
16081 const char *acldefault = dacl->acldefault;
16082 char privtype = dacl->privtype;
16083 const char *initprivs = dacl->initprivs;
16084 const char *baseacls;
16085 PQExpBuffer sql;
16086
16087 /* Do nothing if ACL dump is not enabled */
16088 if (dopt->aclsSkip)
16089 return InvalidDumpId;
16090
16091 /* --data-only skips ACLs *except* large object ACLs */
16092 if (!dopt->dumpSchema && strcmp(type, "LARGE OBJECT") != 0)
16093 return InvalidDumpId;
16094
16095 sql = createPQExpBuffer();
16096
16097 /*
16098 * In binary upgrade mode, we don't run an extension's script but instead
16099 * dump out the objects independently and then recreate them. To preserve
16100 * any initial privileges which were set on extension objects, we need to
16101 * compute the set of GRANT and REVOKE commands necessary to get from the
16102 * default privileges of an object to its initial privileges as recorded
16103 * in pg_init_privs.
16104 *
16105 * At restore time, we apply these commands after having called
16106 * binary_upgrade_set_record_init_privs(true). That tells the backend to
16107 * copy the results into pg_init_privs. This is how we preserve the
16108 * contents of that catalog across binary upgrades.
16109 */
16110 if (dopt->binary_upgrade && privtype == 'e' &&
16111 initprivs && *initprivs != '\0')
16112 {
16113 appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
16114 if (!buildACLCommands(name, subname, nspname, type,
16115 initprivs, acldefault, owner,
16116 "", fout->remoteVersion, sql))
16117 pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
16118 initprivs, acldefault, name, type);
16119 appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
16120 }
16121
16122 /*
16123 * Now figure the GRANT and REVOKE commands needed to get to the object's
16124 * actual current ACL, starting from the initprivs if given, else from the
16125 * object-type-specific default. Also, while buildACLCommands will assume
16126 * that a NULL/empty acls string means it needn't do anything, what that
16127 * actually represents is the object-type-specific default; so we need to
16128 * substitute the acldefault string to get the right results in that case.
16129 */
16130 if (initprivs && *initprivs != '\0')
16131 {
16132 baseacls = initprivs;
16133 if (acls == NULL || *acls == '\0')
16134 acls = acldefault;
16135 }
16136 else
16137 baseacls = acldefault;
16138
16139 if (!buildACLCommands(name, subname, nspname, type,
16140 acls, baseacls, owner,
16141 "", fout->remoteVersion, sql))
16142 pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
16143 acls, baseacls, name, type);
16144
16145 if (sql->len > 0)
16146 {
16147 PQExpBuffer tagbuf = createPQExpBuffer();
16148 DumpId aclDeps[2];
16149 int nDeps = 0;
16150
16151 if (tag)
16152 appendPQExpBufferStr(tagbuf, tag);
16153 else if (subname)
16154 appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
16155 else
16156 appendPQExpBuffer(tagbuf, "%s %s", type, name);
16157
16158 aclDeps[nDeps++] = objDumpId;
16159 if (altDumpId != InvalidDumpId)
16160 aclDeps[nDeps++] = altDumpId;
16161
16162 aclDumpId = createDumpId();
16163
16164 ArchiveEntry(fout, nilCatalogId, aclDumpId,
16165 ARCHIVE_OPTS(.tag = tagbuf->data,
16166 .namespace = nspname,
16167 .owner = owner,
16168 .description = "ACL",
16169 .section = SECTION_NONE,
16170 .createStmt = sql->data,
16171 .deps = aclDeps,
16172 .nDeps = nDeps));
16173
16174 destroyPQExpBuffer(tagbuf);
16175 }
16176
16177 destroyPQExpBuffer(sql);
16178
16179 return aclDumpId;
16180}
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:787
DumpId createDumpId(void)
Definition: common.c:744
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:66
@ SECTION_NONE
Definition: pg_backup.h:57
#define InvalidDumpId
Definition: pg_backup.h:282
NameData subname
bool aclsSkip
Definition: pg_backup.h:176
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 15035 of file pg_dump.c.

15036{
15037 DumpOptions *dopt = fout->dopt;
15038 PQExpBuffer query;
15039 PQExpBuffer q;
15040 PQExpBuffer delq;
15041 PQExpBuffer details;
15042 char *aggsig; /* identity signature */
15043 char *aggfullsig = NULL; /* full signature */
15044 char *aggsig_tag;
15045 PGresult *res;
15046 int i_agginitval;
15047 int i_aggminitval;
15048 const char *aggtransfn;
15049 const char *aggfinalfn;
15050 const char *aggcombinefn;
15051 const char *aggserialfn;
15052 const char *aggdeserialfn;
15053 const char *aggmtransfn;
15054 const char *aggminvtransfn;
15055 const char *aggmfinalfn;
15056 bool aggfinalextra;
15057 bool aggmfinalextra;
15058 char aggfinalmodify;
15059 char aggmfinalmodify;
15060 const char *aggsortop;
15061 char *aggsortconvop;
15062 char aggkind;
15063 const char *aggtranstype;
15064 const char *aggtransspace;
15065 const char *aggmtranstype;
15066 const char *aggmtransspace;
15067 const char *agginitval;
15068 const char *aggminitval;
15069 const char *proparallel;
15070 char defaultfinalmodify;
15071
15072 /* Do nothing if not dumping schema */
15073 if (!dopt->dumpSchema)
15074 return;
15075
15076 query = createPQExpBuffer();
15077 q = createPQExpBuffer();
15078 delq = createPQExpBuffer();
15079 details = createPQExpBuffer();
15080
15081 if (!fout->is_prepared[PREPQUERY_DUMPAGG])
15082 {
15083 /* Set up query for aggregate-specific details */
15085 "PREPARE dumpAgg(pg_catalog.oid) AS\n");
15086
15088 "SELECT "
15089 "aggtransfn,\n"
15090 "aggfinalfn,\n"
15091 "aggtranstype::pg_catalog.regtype,\n"
15092 "agginitval,\n"
15093 "aggsortop,\n"
15094 "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
15095 "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
15096
15097 if (fout->remoteVersion >= 90400)
15099 "aggkind,\n"
15100 "aggmtransfn,\n"
15101 "aggminvtransfn,\n"
15102 "aggmfinalfn,\n"
15103 "aggmtranstype::pg_catalog.regtype,\n"
15104 "aggfinalextra,\n"
15105 "aggmfinalextra,\n"
15106 "aggtransspace,\n"
15107 "aggmtransspace,\n"
15108 "aggminitval,\n");
15109 else
15111 "'n' AS aggkind,\n"
15112 "'-' AS aggmtransfn,\n"
15113 "'-' AS aggminvtransfn,\n"
15114 "'-' AS aggmfinalfn,\n"
15115 "0 AS aggmtranstype,\n"
15116 "false AS aggfinalextra,\n"
15117 "false AS aggmfinalextra,\n"
15118 "0 AS aggtransspace,\n"
15119 "0 AS aggmtransspace,\n"
15120 "NULL AS aggminitval,\n");
15121
15122 if (fout->remoteVersion >= 90600)
15124 "aggcombinefn,\n"
15125 "aggserialfn,\n"
15126 "aggdeserialfn,\n"
15127 "proparallel,\n");
15128 else
15130 "'-' AS aggcombinefn,\n"
15131 "'-' AS aggserialfn,\n"
15132 "'-' AS aggdeserialfn,\n"
15133 "'u' AS proparallel,\n");
15134
15135 if (fout->remoteVersion >= 110000)
15137 "aggfinalmodify,\n"
15138 "aggmfinalmodify\n");
15139 else
15141 "'0' AS aggfinalmodify,\n"
15142 "'0' AS aggmfinalmodify\n");
15143
15145 "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
15146 "WHERE a.aggfnoid = p.oid "
15147 "AND p.oid = $1");
15148
15149 ExecuteSqlStatement(fout, query->data);
15150
15151 fout->is_prepared[PREPQUERY_DUMPAGG] = true;
15152 }
15153
15154 printfPQExpBuffer(query,
15155 "EXECUTE dumpAgg('%u')",
15156 agginfo->aggfn.dobj.catId.oid);
15157
15158 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15159
15160 i_agginitval = PQfnumber(res, "agginitval");
15161 i_aggminitval = PQfnumber(res, "aggminitval");
15162
15163 aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
15164 aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
15165 aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
15166 aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
15167 aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
15168 aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
15169 aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
15170 aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
15171 aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
15172 aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
15173 aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
15174 aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
15175 aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
15176 aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
15177 aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
15178 aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
15179 aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
15180 aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
15181 agginitval = PQgetvalue(res, 0, i_agginitval);
15182 aggminitval = PQgetvalue(res, 0, i_aggminitval);
15183 proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
15184
15185 {
15186 char *funcargs;
15187 char *funciargs;
15188
15189 funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
15190 funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
15191 aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
15192 aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
15193 }
15194
15195 aggsig_tag = format_aggregate_signature(agginfo, fout, false);
15196
15197 /* identify default modify flag for aggkind (must match DefineAggregate) */
15198 defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
15199 /* replace omitted flags for old versions */
15200 if (aggfinalmodify == '0')
15201 aggfinalmodify = defaultfinalmodify;
15202 if (aggmfinalmodify == '0')
15203 aggmfinalmodify = defaultfinalmodify;
15204
15205 /* regproc and regtype output is already sufficiently quoted */
15206 appendPQExpBuffer(details, " SFUNC = %s,\n STYPE = %s",
15207 aggtransfn, aggtranstype);
15208
15209 if (strcmp(aggtransspace, "0") != 0)
15210 {
15211 appendPQExpBuffer(details, ",\n SSPACE = %s",
15212 aggtransspace);
15213 }
15214
15215 if (!PQgetisnull(res, 0, i_agginitval))
15216 {
15217 appendPQExpBufferStr(details, ",\n INITCOND = ");
15218 appendStringLiteralAH(details, agginitval, fout);
15219 }
15220
15221 if (strcmp(aggfinalfn, "-") != 0)
15222 {
15223 appendPQExpBuffer(details, ",\n FINALFUNC = %s",
15224 aggfinalfn);
15225 if (aggfinalextra)
15226 appendPQExpBufferStr(details, ",\n FINALFUNC_EXTRA");
15227 if (aggfinalmodify != defaultfinalmodify)
15228 {
15229 switch (aggfinalmodify)
15230 {
15231 case AGGMODIFY_READ_ONLY:
15232 appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_ONLY");
15233 break;
15234 case AGGMODIFY_SHAREABLE:
15235 appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHAREABLE");
15236 break;
15237 case AGGMODIFY_READ_WRITE:
15238 appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_WRITE");
15239 break;
15240 default:
15241 pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
15242 agginfo->aggfn.dobj.name);
15243 break;
15244 }
15245 }
15246 }
15247
15248 if (strcmp(aggcombinefn, "-") != 0)
15249 appendPQExpBuffer(details, ",\n COMBINEFUNC = %s", aggcombinefn);
15250
15251 if (strcmp(aggserialfn, "-") != 0)
15252 appendPQExpBuffer(details, ",\n SERIALFUNC = %s", aggserialfn);
15253
15254 if (strcmp(aggdeserialfn, "-") != 0)
15255 appendPQExpBuffer(details, ",\n DESERIALFUNC = %s", aggdeserialfn);
15256
15257 if (strcmp(aggmtransfn, "-") != 0)
15258 {
15259 appendPQExpBuffer(details, ",\n MSFUNC = %s,\n MINVFUNC = %s,\n MSTYPE = %s",
15260 aggmtransfn,
15261 aggminvtransfn,
15262 aggmtranstype);
15263 }
15264
15265 if (strcmp(aggmtransspace, "0") != 0)
15266 {
15267 appendPQExpBuffer(details, ",\n MSSPACE = %s",
15268 aggmtransspace);
15269 }
15270
15271 if (!PQgetisnull(res, 0, i_aggminitval))
15272 {
15273 appendPQExpBufferStr(details, ",\n MINITCOND = ");
15274 appendStringLiteralAH(details, aggminitval, fout);
15275 }
15276
15277 if (strcmp(aggmfinalfn, "-") != 0)
15278 {
15279 appendPQExpBuffer(details, ",\n MFINALFUNC = %s",
15280 aggmfinalfn);
15281 if (aggmfinalextra)
15282 appendPQExpBufferStr(details, ",\n MFINALFUNC_EXTRA");
15283 if (aggmfinalmodify != defaultfinalmodify)
15284 {
15285 switch (aggmfinalmodify)
15286 {
15287 case AGGMODIFY_READ_ONLY:
15288 appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_ONLY");
15289 break;
15290 case AGGMODIFY_SHAREABLE:
15291 appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHAREABLE");
15292 break;
15293 case AGGMODIFY_READ_WRITE:
15294 appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_WRITE");
15295 break;
15296 default:
15297 pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
15298 agginfo->aggfn.dobj.name);
15299 break;
15300 }
15301 }
15302 }
15303
15304 aggsortconvop = getFormattedOperatorName(aggsortop);
15305 if (aggsortconvop)
15306 {
15307 appendPQExpBuffer(details, ",\n SORTOP = %s",
15308 aggsortconvop);
15309 free(aggsortconvop);
15310 }
15311
15312 if (aggkind == AGGKIND_HYPOTHETICAL)
15313 appendPQExpBufferStr(details, ",\n HYPOTHETICAL");
15314
15315 if (proparallel[0] != PROPARALLEL_UNSAFE)
15316 {
15317 if (proparallel[0] == PROPARALLEL_SAFE)
15318 appendPQExpBufferStr(details, ",\n PARALLEL = safe");
15319 else if (proparallel[0] == PROPARALLEL_RESTRICTED)
15320 appendPQExpBufferStr(details, ",\n PARALLEL = restricted");
15321 else if (proparallel[0] != PROPARALLEL_UNSAFE)
15322 pg_fatal("unrecognized proparallel value for function \"%s\"",
15323 agginfo->aggfn.dobj.name);
15324 }
15325
15326 appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
15327 fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
15328 aggsig);
15329
15330 appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
15331 fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
15332 aggfullsig ? aggfullsig : aggsig, details->data);
15333
15334 if (dopt->binary_upgrade)
15335 binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
15336 "AGGREGATE", aggsig,
15337 agginfo->aggfn.dobj.namespace->dobj.name);
15338
15339 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
15340 ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
15341 agginfo->aggfn.dobj.dumpId,
15342 ARCHIVE_OPTS(.tag = aggsig_tag,
15343 .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
15344 .owner = agginfo->aggfn.rolname,
15345 .description = "AGGREGATE",
15346 .section = SECTION_PRE_DATA,
15347 .createStmt = q->data,
15348 .dropStmt = delq->data));
15349
15350 /* Dump Aggregate Comments */
15351 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
15352 dumpComment(fout, "AGGREGATE", aggsig,
15353 agginfo->aggfn.dobj.namespace->dobj.name,
15354 agginfo->aggfn.rolname,
15355 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
15356
15357 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
15358 dumpSecLabel(fout, "AGGREGATE", aggsig,
15359 agginfo->aggfn.dobj.namespace->dobj.name,
15360 agginfo->aggfn.rolname,
15361 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
15362
15363 /*
15364 * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
15365 * command look like a function's GRANT; in particular this affects the
15366 * syntax for zero-argument aggregates and ordered-set aggregates.
15367 */
15368 free(aggsig);
15369
15370 aggsig = format_function_signature(fout, &agginfo->aggfn, true);
15371
15372 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
15373 dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
15374 "FUNCTION", aggsig, NULL,
15375 agginfo->aggfn.dobj.namespace->dobj.name,
15376 NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
15377
15378 free(aggsig);
15379 free(aggfullsig);
15380 free(aggsig_tag);
15381
15382 PQclear(res);
15383
15384 destroyPQExpBuffer(query);
15386 destroyPQExpBuffer(delq);
15387 destroyPQExpBuffer(details);
15388}
@ 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:16073
static char * getFormattedOperatorName(const char *oproid)
Definition: pg_dump.c:14030
static char * format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
Definition: pg_dump.c:13089
static char * format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
Definition: pg_dump.c:13066
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:16201
static char * format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
Definition: pg_dump.c:15003
bool * is_prepared
Definition: pg_backup.h:251

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

17791{
17792 DumpOptions *dopt = fout->dopt;
17793 TableInfo *tbinfo = adinfo->adtable;
17794 int adnum = adinfo->adnum;
17795 PQExpBuffer q;
17796 PQExpBuffer delq;
17797 char *qualrelname;
17798 char *tag;
17799 char *foreign;
17800
17801 /* Do nothing if not dumping schema */
17802 if (!dopt->dumpSchema)
17803 return;
17804
17805 /* Skip if not "separate"; it was dumped in the table's definition */
17806 if (!adinfo->separate)
17807 return;
17808
17809 q = createPQExpBuffer();
17810 delq = createPQExpBuffer();
17811
17812 qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
17813
17814 foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
17815
17817 "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
17818 foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
17819 adinfo->adef_expr);
17820
17821 appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
17822 foreign, qualrelname,
17823 fmtId(tbinfo->attnames[adnum - 1]));
17824
17825 tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
17826
17827 if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17828 ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
17829 ARCHIVE_OPTS(.tag = tag,
17830 .namespace = tbinfo->dobj.namespace->dobj.name,
17831 .owner = tbinfo->rolname,
17832 .description = "DEFAULT",
17833 .section = SECTION_PRE_DATA,
17834 .createStmt = q->data,
17835 .dropStmt = delq->data));
17836
17837 free(tag);
17839 destroyPQExpBuffer(delq);
17840 free(qualrelname);
17841}
DumpableObject dobj
Definition: pg_dump.h:396
char * adef_expr
Definition: pg_dump.h:399
TableInfo * adtable
Definition: pg_dump.h:397
bool separate
Definition: pg_dump.h:400
const char * rolname
Definition: pg_dump.h:302

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

12172{
12173 DumpOptions *dopt = fout->dopt;
12177 PGresult *res;
12178 char *qtypname;
12179 char *qualtypname;
12180 char *typlen;
12181 char *typinput;
12182 char *typoutput;
12183 char *typreceive;
12184 char *typsend;
12185 char *typmodin;
12186 char *typmodout;
12187 char *typanalyze;
12188 char *typsubscript;
12189 Oid typreceiveoid;
12190 Oid typsendoid;
12191 Oid typmodinoid;
12192 Oid typmodoutoid;
12193 Oid typanalyzeoid;
12194 Oid typsubscriptoid;
12195 char *typcategory;
12196 char *typispreferred;
12197 char *typdelim;
12198 char *typbyval;
12199 char *typalign;
12200 char *typstorage;
12201 char *typcollatable;
12202 char *typdefault;
12203 bool typdefault_is_literal = false;
12204
12206 {
12207 /* Set up query for type-specific details */
12209 "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
12210 "SELECT typlen, "
12211 "typinput, typoutput, typreceive, typsend, "
12212 "typreceive::pg_catalog.oid AS typreceiveoid, "
12213 "typsend::pg_catalog.oid AS typsendoid, "
12214 "typanalyze, "
12215 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
12216 "typdelim, typbyval, typalign, typstorage, "
12217 "typmodin, typmodout, "
12218 "typmodin::pg_catalog.oid AS typmodinoid, "
12219 "typmodout::pg_catalog.oid AS typmodoutoid, "
12220 "typcategory, typispreferred, "
12221 "(typcollation <> 0) AS typcollatable, "
12222 "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
12223
12224 if (fout->remoteVersion >= 140000)
12226 "typsubscript, "
12227 "typsubscript::pg_catalog.oid AS typsubscriptoid ");
12228 else
12230 "'-' AS typsubscript, 0 AS typsubscriptoid ");
12231
12232 appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
12233 "WHERE oid = $1");
12234
12235 ExecuteSqlStatement(fout, query->data);
12236
12237 fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
12238 }
12239
12240 printfPQExpBuffer(query,
12241 "EXECUTE dumpBaseType('%u')",
12242 tyinfo->dobj.catId.oid);
12243
12244 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12245
12246 typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
12247 typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
12248 typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
12249 typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
12250 typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
12251 typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
12252 typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
12253 typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
12254 typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
12255 typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
12256 typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
12257 typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
12258 typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
12259 typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
12260 typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
12261 typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
12262 typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
12263 typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
12264 typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
12265 typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
12266 typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
12267 typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
12268 if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
12269 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
12270 else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
12271 {
12272 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
12273 typdefault_is_literal = true; /* it needs quotes */
12274 }
12275 else
12276 typdefault = NULL;
12277
12278 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12279 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12280
12281 /*
12282 * The reason we include CASCADE is that the circular dependency between
12283 * the type and its I/O functions makes it impossible to drop the type any
12284 * other way.
12285 */
12286 appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
12287
12288 /*
12289 * We might already have a shell type, but setting pg_type_oid is
12290 * harmless, and in any case we'd better set the array type OID.
12291 */
12292 if (dopt->binary_upgrade)
12294 tyinfo->dobj.catId.oid,
12295 false, false);
12296
12298 "CREATE TYPE %s (\n"
12299 " INTERNALLENGTH = %s",
12300 qualtypname,
12301 (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
12302
12303 /* regproc result is sufficiently quoted already */
12304 appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
12305 appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
12306 if (OidIsValid(typreceiveoid))
12307 appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
12308 if (OidIsValid(typsendoid))
12309 appendPQExpBuffer(q, ",\n SEND = %s", typsend);
12310 if (OidIsValid(typmodinoid))
12311 appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
12312 if (OidIsValid(typmodoutoid))
12313 appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
12314 if (OidIsValid(typanalyzeoid))
12315 appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
12316
12317 if (strcmp(typcollatable, "t") == 0)
12318 appendPQExpBufferStr(q, ",\n COLLATABLE = true");
12319
12320 if (typdefault != NULL)
12321 {
12322 appendPQExpBufferStr(q, ",\n DEFAULT = ");
12323 if (typdefault_is_literal)
12324 appendStringLiteralAH(q, typdefault, fout);
12325 else
12326 appendPQExpBufferStr(q, typdefault);
12327 }
12328
12329 if (OidIsValid(typsubscriptoid))
12330 appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
12331
12332 if (OidIsValid(tyinfo->typelem))
12333 appendPQExpBuffer(q, ",\n ELEMENT = %s",
12334 getFormattedTypeName(fout, tyinfo->typelem,
12335 zeroIsError));
12336
12337 if (strcmp(typcategory, "U") != 0)
12338 {
12339 appendPQExpBufferStr(q, ",\n CATEGORY = ");
12340 appendStringLiteralAH(q, typcategory, fout);
12341 }
12342
12343 if (strcmp(typispreferred, "t") == 0)
12344 appendPQExpBufferStr(q, ",\n PREFERRED = true");
12345
12346 if (typdelim && strcmp(typdelim, ",") != 0)
12347 {
12348 appendPQExpBufferStr(q, ",\n DELIMITER = ");
12349 appendStringLiteralAH(q, typdelim, fout);
12350 }
12351
12352 if (*typalign == TYPALIGN_CHAR)
12353 appendPQExpBufferStr(q, ",\n ALIGNMENT = char");
12354 else if (*typalign == TYPALIGN_SHORT)
12355 appendPQExpBufferStr(q, ",\n ALIGNMENT = int2");
12356 else if (*typalign == TYPALIGN_INT)
12357 appendPQExpBufferStr(q, ",\n ALIGNMENT = int4");
12358 else if (*typalign == TYPALIGN_DOUBLE)
12359 appendPQExpBufferStr(q, ",\n ALIGNMENT = double");
12360
12361 if (*typstorage == TYPSTORAGE_PLAIN)
12362 appendPQExpBufferStr(q, ",\n STORAGE = plain");
12363 else if (*typstorage == TYPSTORAGE_EXTERNAL)
12364 appendPQExpBufferStr(q, ",\n STORAGE = external");
12365 else if (*typstorage == TYPSTORAGE_EXTENDED)
12366 appendPQExpBufferStr(q, ",\n STORAGE = extended");
12367 else if (*typstorage == TYPSTORAGE_MAIN)
12368 appendPQExpBufferStr(q, ",\n STORAGE = main");
12369
12370 if (strcmp(typbyval, "t") == 0)
12371 appendPQExpBufferStr(q, ",\n PASSEDBYVALUE");
12372
12373 appendPQExpBufferStr(q, "\n);\n");
12374
12375 if (dopt->binary_upgrade)
12377 "TYPE", qtypname,
12378 tyinfo->dobj.namespace->dobj.name);
12379
12380 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12381 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12382 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12383 .namespace = tyinfo->dobj.namespace->dobj.name,
12384 .owner = tyinfo->rolname,
12385 .description = "TYPE",
12386 .section = SECTION_PRE_DATA,
12387 .createStmt = q->data,
12388 .dropStmt = delq->data));
12389
12390 /* Dump Type Comments and Security Labels */
12391 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12392 dumpComment(fout, "TYPE", qtypname,
12393 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12394 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12395
12396 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12397 dumpSecLabel(fout, "TYPE", qtypname,
12398 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12399 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12400
12401 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12402 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12403 qtypname, NULL,
12404 tyinfo->dobj.namespace->dobj.name,
12405 NULL, tyinfo->rolname, &tyinfo->dacl);
12406
12407 PQclear(res);
12409 destroyPQExpBuffer(delq);
12410 destroyPQExpBuffer(query);
12411 free(qtypname);
12412 free(qualtypname);
12413}
@ PREPQUERY_DUMPBASETYPE
Definition: pg_backup.h:67
static const char * getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
Definition: pg_dump.c:19952
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 13536 of file pg_dump.c.

13537{
13538 DumpOptions *dopt = fout->dopt;
13539 PQExpBuffer defqry;
13540 PQExpBuffer delqry;
13541 PQExpBuffer labelq;
13542 PQExpBuffer castargs;
13543 FuncInfo *funcInfo = NULL;
13544 const char *sourceType;
13545 const char *targetType;
13546
13547 /* Do nothing if not dumping schema */
13548 if (!dopt->dumpSchema)
13549 return;
13550
13551 /* Cannot dump if we don't have the cast function's info */
13552 if (OidIsValid(cast->castfunc))
13553 {
13554 funcInfo = findFuncByOid(cast->castfunc);
13555 if (funcInfo == NULL)
13556 pg_fatal("could not find function definition for function with OID %u",
13557 cast->castfunc);
13558 }
13559
13560 defqry = createPQExpBuffer();
13561 delqry = createPQExpBuffer();
13562 labelq = createPQExpBuffer();
13563 castargs = createPQExpBuffer();
13564
13565 sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
13566 targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
13567 appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
13568 sourceType, targetType);
13569
13570 appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
13571 sourceType, targetType);
13572
13573 switch (cast->castmethod)
13574 {
13575 case COERCION_METHOD_BINARY:
13576 appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
13577 break;
13578 case COERCION_METHOD_INOUT:
13579 appendPQExpBufferStr(defqry, "WITH INOUT");
13580 break;
13581 case COERCION_METHOD_FUNCTION:
13582 if (funcInfo)
13583 {
13584 char *fsig = format_function_signature(fout, funcInfo, true);
13585
13586 /*
13587 * Always qualify the function name (format_function_signature
13588 * won't qualify it).
13589 */
13590 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
13591 fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
13592 free(fsig);
13593 }
13594 else
13595 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
13596 break;
13597 default:
13598 pg_log_warning("bogus value in pg_cast.castmethod field");
13599 }
13600
13601 if (cast->castcontext == 'a')
13602 appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
13603 else if (cast->castcontext == 'i')
13604 appendPQExpBufferStr(defqry, " AS IMPLICIT");
13605 appendPQExpBufferStr(defqry, ";\n");
13606
13607 appendPQExpBuffer(labelq, "CAST (%s AS %s)",
13608 sourceType, targetType);
13609
13610 appendPQExpBuffer(castargs, "(%s AS %s)",
13611 sourceType, targetType);
13612
13613 if (dopt->binary_upgrade)
13615 "CAST", castargs->data, NULL);
13616
13618 ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
13619 ARCHIVE_OPTS(.tag = labelq->data,
13620 .description = "CAST",
13621 .section = SECTION_PRE_DATA,
13622 .createStmt = defqry->data,
13623 .dropStmt = delqry->data));
13624
13625 /* Dump Cast Comments */
13626 if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
13627 dumpComment(fout, "CAST", castargs->data,
13628 NULL, "",
13629 cast->dobj.catId, 0, cast->dobj.dumpId);
13630
13631 destroyPQExpBuffer(defqry);
13632 destroyPQExpBuffer(delqry);
13633 destroyPQExpBuffer(labelq);
13634 destroyPQExpBuffer(castargs);
13635}
FuncInfo * findFuncByOid(Oid oid)
Definition: common.c:917
char castmethod
Definition: pg_dump.h:541
Oid casttarget
Definition: pg_dump.h:538
char castcontext
Definition: pg_dump.h:540
DumpableObject dobj
Definition: pg_dump.h:536
Oid castsource
Definition: pg_dump.h:537
Oid castfunc
Definition: pg_dump.h:539
DumpableObject dobj
Definition: pg_dump.h:239

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

14651{
14652 DumpOptions *dopt = fout->dopt;
14653 PQExpBuffer query;
14654 PQExpBuffer q;
14655 PQExpBuffer delq;
14656 char *qcollname;
14657 PGresult *res;
14658 int i_collprovider;
14659 int i_collisdeterministic;
14660 int i_collcollate;
14661 int i_collctype;
14662 int i_colllocale;
14663 int i_collicurules;
14664 const char *collprovider;
14665 const char *collcollate;
14666 const char *collctype;
14667 const char *colllocale;
14668 const char *collicurules;
14669
14670 /* Do nothing if not dumping schema */
14671 if (!dopt->dumpSchema)
14672 return;
14673
14674 query = createPQExpBuffer();
14675 q = createPQExpBuffer();
14676 delq = createPQExpBuffer();
14677
14678 qcollname = pg_strdup(fmtId(collinfo->dobj.name));
14679
14680 /* Get collation-specific details */
14681 appendPQExpBufferStr(query, "SELECT ");
14682
14683 if (fout->remoteVersion >= 100000)
14685 "collprovider, "
14686 "collversion, ");
14687 else
14689 "'c' AS collprovider, "
14690 "NULL AS collversion, ");
14691
14692 if (fout->remoteVersion >= 120000)
14694 "collisdeterministic, ");
14695 else
14697 "true AS collisdeterministic, ");
14698
14699 if (fout->remoteVersion >= 170000)
14701 "colllocale, ");
14702 else if (fout->remoteVersion >= 150000)
14704 "colliculocale AS colllocale, ");
14705 else
14707 "NULL AS colllocale, ");
14708
14709 if (fout->remoteVersion >= 160000)
14711 "collicurules, ");
14712 else
14714 "NULL AS collicurules, ");
14715
14716 appendPQExpBuffer(query,
14717 "collcollate, "
14718 "collctype "
14719 "FROM pg_catalog.pg_collation c "
14720 "WHERE c.oid = '%u'::pg_catalog.oid",
14721 collinfo->dobj.catId.oid);
14722
14723 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14724
14725 i_collprovider = PQfnumber(res, "collprovider");
14726 i_collisdeterministic = PQfnumber(res, "collisdeterministic");
14727 i_collcollate = PQfnumber(res, "collcollate");
14728 i_collctype = PQfnumber(res, "collctype");
14729 i_colllocale = PQfnumber(res, "colllocale");
14730 i_collicurules = PQfnumber(res, "collicurules");
14731
14732 collprovider = PQgetvalue(res, 0, i_collprovider);
14733
14734 if (!PQgetisnull(res, 0, i_collcollate))
14735 collcollate = PQgetvalue(res, 0, i_collcollate);
14736 else
14737 collcollate = NULL;
14738
14739 if (!PQgetisnull(res, 0, i_collctype))
14740 collctype = PQgetvalue(res, 0, i_collctype);
14741 else
14742 collctype = NULL;
14743
14744 /*
14745 * Before version 15, collcollate and collctype were of type NAME and
14746 * non-nullable. Treat empty strings as NULL for consistency.
14747 */
14748 if (fout->remoteVersion < 150000)
14749 {
14750 if (collcollate[0] == '\0')
14751 collcollate = NULL;
14752 if (collctype[0] == '\0')
14753 collctype = NULL;
14754 }
14755
14756 if (!PQgetisnull(res, 0, i_colllocale))
14757 colllocale = PQgetvalue(res, 0, i_colllocale);
14758 else
14759 colllocale = NULL;
14760
14761 if (!PQgetisnull(res, 0, i_collicurules))
14762 collicurules = PQgetvalue(res, 0, i_collicurules);
14763 else
14764 collicurules = NULL;
14765
14766 appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
14767 fmtQualifiedDumpable(collinfo));
14768
14769 appendPQExpBuffer(q, "CREATE COLLATION %s (",
14770 fmtQualifiedDumpable(collinfo));
14771
14772 appendPQExpBufferStr(q, "provider = ");
14773 if (collprovider[0] == 'b')
14774 appendPQExpBufferStr(q, "builtin");
14775 else if (collprovider[0] == 'c')
14776 appendPQExpBufferStr(q, "libc");
14777 else if (collprovider[0] == 'i')
14778 appendPQExpBufferStr(q, "icu");
14779 else if (collprovider[0] == 'd')
14780 /* to allow dumping pg_catalog; not accepted on input */
14781 appendPQExpBufferStr(q, "default");
14782 else
14783 pg_fatal("unrecognized collation provider: %s",
14784 collprovider);
14785
14786 if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
14787 appendPQExpBufferStr(q, ", deterministic = false");
14788
14789 if (collprovider[0] == 'd')
14790 {
14791 if (collcollate || collctype || colllocale || collicurules)
14792 pg_log_warning("invalid collation \"%s\"", qcollname);
14793
14794 /* no locale -- the default collation cannot be reloaded anyway */
14795 }
14796 else if (collprovider[0] == 'b')
14797 {
14798 if (collcollate || collctype || !colllocale || collicurules)
14799 pg_log_warning("invalid collation \"%s\"", qcollname);
14800
14801 appendPQExpBufferStr(q, ", locale = ");
14802 appendStringLiteralAH(q, colllocale ? colllocale : "",
14803 fout);
14804 }
14805 else if (collprovider[0] == 'i')
14806 {
14807 if (fout->remoteVersion >= 150000)
14808 {
14809 if (collcollate || collctype || !colllocale)
14810 pg_log_warning("invalid collation \"%s\"", qcollname);
14811
14812 appendPQExpBufferStr(q, ", locale = ");
14813 appendStringLiteralAH(q, colllocale ? colllocale : "",
14814 fout);
14815 }
14816 else
14817 {
14818 if (!collcollate || !collctype || colllocale ||
14819 strcmp(collcollate, collctype) != 0)
14820 pg_log_warning("invalid collation \"%s\"", qcollname);
14821
14822 appendPQExpBufferStr(q, ", locale = ");
14823 appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
14824 }
14825
14826 if (collicurules)
14827 {
14828 appendPQExpBufferStr(q, ", rules = ");
14829 appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
14830 }
14831 }
14832 else if (collprovider[0] == 'c')
14833 {
14834 if (colllocale || collicurules || !collcollate || !collctype)
14835 pg_log_warning("invalid collation \"%s\"", qcollname);
14836
14837 if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
14838 {
14839 appendPQExpBufferStr(q, ", locale = ");
14840 appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
14841 }
14842 else
14843 {
14844 appendPQExpBufferStr(q, ", lc_collate = ");
14845 appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
14846 appendPQExpBufferStr(q, ", lc_ctype = ");
14847 appendStringLiteralAH(q, collctype ? collctype : "", fout);
14848 }
14849 }
14850 else
14851 pg_fatal("unrecognized collation provider: %s", collprovider);
14852
14853 /*
14854 * For binary upgrade, carry over the collation version. For normal
14855 * dump/restore, omit the version, so that it is computed upon restore.
14856 */
14857 if (dopt->binary_upgrade)
14858 {
14859 int i_collversion;
14860
14861 i_collversion = PQfnumber(res, "collversion");
14862 if (!PQgetisnull(res, 0, i_collversion))
14863 {
14864 appendPQExpBufferStr(q, ", version = ");
14866 PQgetvalue(res, 0, i_collversion),
14867 fout);
14868 }
14869 }
14870
14871 appendPQExpBufferStr(q, ");\n");
14872
14873 if (dopt->binary_upgrade)
14875 "COLLATION", qcollname,
14876 collinfo->dobj.namespace->dobj.name);
14877
14878 if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14879 ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
14880 ARCHIVE_OPTS(.tag = collinfo->dobj.name,
14881 .namespace = collinfo->dobj.namespace->dobj.name,
14882 .owner = collinfo->rolname,
14883 .description = "COLLATION",
14884 .section = SECTION_PRE_DATA,
14885 .createStmt = q->data,
14886 .dropStmt = delq->data));
14887
14888 /* Dump Collation Comments */
14889 if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14890 dumpComment(fout, "COLLATION", qcollname,
14891 collinfo->dobj.namespace->dobj.name, collinfo->rolname,
14892 collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
14893
14894 PQclear(res);
14895
14896 destroyPQExpBuffer(query);
14898 destroyPQExpBuffer(delq);
14899 free(qcollname);
14900}
const char * rolname
Definition: pg_dump.h:286
DumpableObject dobj
Definition: pg_dump.h:285

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

10700{
10701 dumpCommentExtended(fout, type, name, namespace, owner,
10702 catalogId, subid, dumpId, NULL);
10703}
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:10596

References dumpCommentExtended(), name, and type.

Referenced by dumpAccessMethod(), dumpAgg(), dumpBaseType(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpConversion(), dumpDomain(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpLO(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpPolicy(), dumpProcLang(), dumpPublication(), dumpRangeType(), dumpRule(), dumpSequence(), dumpStatisticsExt(), dumpSubscription(), dumpTableConstraintComment(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), and dumpUndefinedType().

◆ dumpCommentExtended()

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

Definition at line 10596 of file pg_dump.c.

10601{
10602 DumpOptions *dopt = fout->dopt;
10604 int ncomments;
10605
10606 /* do nothing, if --no-comments is supplied */
10607 if (dopt->no_comments)
10608 return;
10609
10610 /* Comments are schema not data ... except LO comments are data */
10611 if (strcmp(type, "LARGE OBJECT") != 0)
10612 {
10613 if (!dopt->dumpSchema)
10614 return;
10615 }
10616 else
10617 {
10618 /* We do dump LO comments in binary-upgrade mode */
10619 if (!dopt->dumpData && !dopt->binary_upgrade)
10620 return;
10621 }
10622
10623 /* Search for comments associated with catalogId, using table */
10624 ncomments = findComments(catalogId.tableoid, catalogId.oid,
10625 &comments);
10626
10627 /* Is there one matching the subid? */
10628 while (ncomments > 0)
10629 {
10630 if (comments->objsubid == subid)
10631 break;
10632 comments++;
10633 ncomments--;
10634 }
10635
10636 if (initdb_comment != NULL)
10637 {
10638 static CommentItem empty_comment = {.descr = ""};
10639
10640 /*
10641 * initdb creates this object with a comment. Skip dumping the
10642 * initdb-provided comment, which would complicate matters for
10643 * non-superuser use of pg_dump. When the DBA has removed initdb's
10644 * comment, replicate that.
10645 */
10646 if (ncomments == 0)
10647 {
10648 comments = &empty_comment;
10649 ncomments = 1;
10650 }
10651 else if (strcmp(comments->descr, initdb_comment) == 0)
10652 ncomments = 0;
10653 }
10654
10655 /* If a comment exists, build COMMENT ON statement */
10656 if (ncomments > 0)
10657 {
10660
10661 appendPQExpBuffer(query, "COMMENT ON %s ", type);
10662 if (namespace && *namespace)
10663 appendPQExpBuffer(query, "%s.", fmtId(namespace));
10664 appendPQExpBuffer(query, "%s IS ", name);
10665 appendStringLiteralAH(query, comments->descr, fout);
10666 appendPQExpBufferStr(query, ";\n");
10667
10668 appendPQExpBuffer(tag, "%s %s", type, name);
10669
10670 /*
10671 * We mark comments as SECTION_NONE because they really belong in the
10672 * same section as their parent, whether that is pre-data or
10673 * post-data.
10674 */
10676 ARCHIVE_OPTS(.tag = tag->data,
10677 .namespace = namespace,
10678 .owner = owner,
10679 .description = "COMMENT",
10680 .section = SECTION_NONE,
10681 .createStmt = query->data,
10682 .deps = &dumpId,
10683 .nDeps = 1));
10684
10685 destroyPQExpBuffer(query);
10686 destroyPQExpBuffer(tag);
10687 }
10688}
static int findComments(Oid classoid, Oid objoid, CommentItem **items)
Definition: pg_dump.c:11215
int no_comments
Definition: pg_backup.h:184

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

12594{
12595 DumpOptions *dopt = fout->dopt;
12597 PQExpBuffer dropped = createPQExpBuffer();
12600 PGresult *res;
12601 char *qtypname;
12602 char *qualtypname;
12603 int ntups;
12604 int i_attname;
12605 int i_atttypdefn;
12606 int i_attlen;
12607 int i_attalign;
12608 int i_attisdropped;
12609 int i_attcollation;
12610 int i;
12611 int actual_atts;
12612
12614 {
12615 /*
12616 * Set up query for type-specific details.
12617 *
12618 * Since we only want to dump COLLATE clauses for attributes whose
12619 * collation is different from their type's default, we use a CASE
12620 * here to suppress uninteresting attcollations cheaply. atttypid
12621 * will be 0 for dropped columns; collation does not matter for those.
12622 */
12624 "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
12625 "SELECT a.attname, a.attnum, "
12626 "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
12627 "a.attlen, a.attalign, a.attisdropped, "
12628 "CASE WHEN a.attcollation <> at.typcollation "
12629 "THEN a.attcollation ELSE 0 END AS attcollation "
12630 "FROM pg_catalog.pg_type ct "
12631 "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
12632 "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
12633 "WHERE ct.oid = $1 "
12634 "ORDER BY a.attnum");
12635
12636 ExecuteSqlStatement(fout, query->data);
12637
12639 }
12640
12641 printfPQExpBuffer(query,
12642 "EXECUTE dumpCompositeType('%u')",
12643 tyinfo->dobj.catId.oid);
12644
12645 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
12646
12647 ntups = PQntuples(res);
12648
12649 i_attname = PQfnumber(res, "attname");
12650 i_atttypdefn = PQfnumber(res, "atttypdefn");
12651 i_attlen = PQfnumber(res, "attlen");
12652 i_attalign = PQfnumber(res, "attalign");
12653 i_attisdropped = PQfnumber(res, "attisdropped");
12654 i_attcollation = PQfnumber(res, "attcollation");
12655
12656 if (dopt->binary_upgrade)
12657 {
12659 tyinfo->dobj.catId.oid,
12660 false, false);
12662 }
12663
12664 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12665 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12666
12667 appendPQExpBuffer(q, "CREATE TYPE %s AS (",
12668 qualtypname);
12669
12670 actual_atts = 0;
12671 for (i = 0; i < ntups; i++)
12672 {
12673 char *attname;
12674 char *atttypdefn;
12675 char *attlen;
12676 char *attalign;
12677 bool attisdropped;
12678 Oid attcollation;
12679
12680 attname = PQgetvalue(res, i, i_attname);
12681 atttypdefn = PQgetvalue(res, i, i_atttypdefn);
12682 attlen = PQgetvalue(res, i, i_attlen);
12683 attalign = PQgetvalue(res, i, i_attalign);
12684 attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
12685 attcollation = atooid(PQgetvalue(res, i, i_attcollation));
12686
12687 if (attisdropped && !dopt->binary_upgrade)
12688 continue;
12689
12690 /* Format properly if not first attr */
12691 if (actual_atts++ > 0)
12692 appendPQExpBufferChar(q, ',');
12693 appendPQExpBufferStr(q, "\n\t");
12694
12695 if (!attisdropped)
12696 {
12697 appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
12698
12699 /* Add collation if not default for the column type */
12700 if (OidIsValid(attcollation))
12701 {
12702 CollInfo *coll;
12703
12704 coll = findCollationByOid(attcollation);
12705 if (coll)
12706 appendPQExpBuffer(q, " COLLATE %s",
12707 fmtQualifiedDumpable(coll));
12708 }
12709 }
12710 else
12711 {
12712 /*
12713 * This is a dropped attribute and we're in binary_upgrade mode.
12714 * Insert a placeholder for it in the CREATE TYPE command, and set
12715 * length and alignment with direct UPDATE to the catalogs
12716 * afterwards. See similar code in dumpTableSchema().
12717 */
12718 appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
12719
12720 /* stash separately for insertion after the CREATE TYPE */
12721 appendPQExpBufferStr(dropped,
12722 "\n-- For binary upgrade, recreate dropped column.\n");
12723 appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
12724 "SET attlen = %s, "
12725 "attalign = '%s', attbyval = false\n"
12726 "WHERE attname = ", attlen, attalign);
12727 appendStringLiteralAH(dropped, attname, fout);
12728 appendPQExpBufferStr(dropped, "\n AND attrelid = ");
12729 appendStringLiteralAH(dropped, qualtypname, fout);
12730 appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
12731
12732 appendPQExpBuffer(dropped, "ALTER TYPE %s ",
12733 qualtypname);
12734 appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
12735 fmtId(attname));
12736 }
12737 }
12738 appendPQExpBufferStr(q, "\n);\n");
12739 appendPQExpBufferStr(q, dropped->data);
12740
12741 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12742
12743 if (dopt->binary_upgrade)
12745 "TYPE", qtypname,
12746 tyinfo->dobj.namespace->dobj.name);
12747
12748 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12749 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12750 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12751 .namespace = tyinfo->dobj.namespace->dobj.name,
12752 .owner = tyinfo->rolname,
12753 .description = "TYPE",
12754 .section = SECTION_PRE_DATA,
12755 .createStmt = q->data,
12756 .dropStmt = delq->data));
12757
12758
12759 /* Dump Type Comments and Security Labels */
12760 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12761 dumpComment(fout, "TYPE", qtypname,
12762 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12763 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12764
12765 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12766 dumpSecLabel(fout, "TYPE", qtypname,
12767 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12768 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12769
12770 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12771 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12772 qtypname, NULL,
12773 tyinfo->dobj.namespace->dobj.name,
12774 NULL, tyinfo->rolname, &tyinfo->dacl);
12775
12776 /* Dump any per-column comments */
12777 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12778 dumpCompositeTypeColComments(fout, tyinfo, res);
12779
12780 PQclear(res);
12782 destroyPQExpBuffer(dropped);
12783 destroyPQExpBuffer(delq);
12784 destroyPQExpBuffer(query);
12785 free(qtypname);
12786 free(qualtypname);
12787}
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:5661
static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo, PGresult *res)
Definition: pg_dump.c:12799
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 12799 of file pg_dump.c.

12801{
12803 int ncomments;
12804 PQExpBuffer query;
12805 PQExpBuffer target;
12806 int i;
12807 int ntups;
12808 int i_attname;
12809 int i_attnum;
12810 int i_attisdropped;
12811
12812 /* do nothing, if --no-comments is supplied */
12813 if (fout->dopt->no_comments)
12814 return;
12815
12816 /* Search for comments associated with type's pg_class OID */
12817 ncomments = findComments(RelationRelationId, tyinfo->typrelid,
12818 &comments);
12819
12820 /* If no comments exist, we're done */
12821 if (ncomments <= 0)
12822 return;
12823
12824 /* Build COMMENT ON statements */
12825 query = createPQExpBuffer();
12826 target = createPQExpBuffer();
12827
12828 ntups = PQntuples(res);
12829 i_attnum = PQfnumber(res, "attnum");
12830 i_attname = PQfnumber(res, "attname");
12831 i_attisdropped = PQfnumber(res, "attisdropped");
12832 while (ncomments > 0)
12833 {
12834 const char *attname;
12835
12836 attname = NULL;
12837 for (i = 0; i < ntups; i++)
12838 {
12839 if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
12840 PQgetvalue(res, i, i_attisdropped)[0] != 't')
12841 {
12842 attname = PQgetvalue(res, i, i_attname);
12843 break;
12844 }
12845 }
12846 if (attname) /* just in case we don't find it */
12847 {
12848 const char *descr = comments->descr;
12849
12850 resetPQExpBuffer(target);
12851 appendPQExpBuffer(target, "COLUMN %s.",
12852 fmtId(tyinfo->dobj.name));
12854
12855 resetPQExpBuffer(query);
12856 appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
12857 fmtQualifiedDumpable(tyinfo));
12858 appendPQExpBuffer(query, "%s IS ", fmtId(attname));
12859 appendStringLiteralAH(query, descr, fout);
12860 appendPQExpBufferStr(query, ";\n");
12861
12863 ARCHIVE_OPTS(.tag = target->data,
12864 .namespace = tyinfo->dobj.namespace->dobj.name,
12865 .owner = tyinfo->rolname,
12866 .description = "COMMENT",
12867 .section = SECTION_NONE,
12868 .createStmt = query->data,
12869 .deps = &(tyinfo->dobj.dumpId),
12870 .nDeps = 1));
12871 }
12872
12873 comments++;
12874 ncomments--;
12875 }
12876
12877 destroyPQExpBuffer(query);
12878 destroyPQExpBuffer(target);
12879}
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 18151 of file pg_dump.c.

18152{
18153 DumpOptions *dopt = fout->dopt;
18154 TableInfo *tbinfo = coninfo->contable;
18155 PQExpBuffer q;
18156 PQExpBuffer delq;
18157 char *tag = NULL;
18158 char *foreign;
18159
18160 /* Do nothing if not dumping schema */
18161 if (!dopt->dumpSchema)
18162 return;
18163
18164 q = createPQExpBuffer();
18165 delq = createPQExpBuffer();
18166
18167 foreign = tbinfo &&
18168 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
18169
18170 if (coninfo->contype == 'p' ||
18171 coninfo->contype == 'u' ||
18172 coninfo->contype == 'x')
18173 {
18174 /* Index-related constraint */
18175 IndxInfo *indxinfo;
18176 int k;
18177
18178 indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
18179
18180 if (indxinfo == NULL)
18181 pg_fatal("missing index for constraint \"%s\"",
18182 coninfo->dobj.name);
18183
18184 if (dopt->binary_upgrade)
18186 indxinfo->dobj.catId.oid);
18187
18188 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
18189 fmtQualifiedDumpable(tbinfo));
18190 appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
18191 fmtId(coninfo->dobj.name));
18192
18193 if (coninfo->condef)
18194 {
18195 /* pg_get_constraintdef should have provided everything */
18196 appendPQExpBuffer(q, "%s;\n", coninfo->condef);
18197 }
18198 else
18199 {
18201 coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
18202
18203 /*
18204 * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
18205 * indexes. Being able to create this was fixed, but we need to
18206 * make the index distinct in order to be able to restore the
18207 * dump.
18208 */
18209 if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
18210 appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
18211 appendPQExpBufferStr(q, " (");
18212 for (k = 0; k < indxinfo->indnkeyattrs; k++)
18213 {
18214 int indkey = (int) indxinfo->indkeys[k];
18215 const char *attname;
18216
18217 if (indkey == InvalidAttrNumber)
18218 break;
18219 attname = getAttrName(indkey, tbinfo);
18220
18221 appendPQExpBuffer(q, "%s%s",
18222 (k == 0) ? "" : ", ",
18223 fmtId(attname));
18224 }
18225 if (coninfo->conperiod)
18226 appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
18227
18228 if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
18229 appendPQExpBufferStr(q, ") INCLUDE (");
18230
18231 for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
18232 {
18233 int indkey = (int) indxinfo->indkeys[k];
18234 const char *attname;
18235
18236 if (indkey == InvalidAttrNumber)
18237 break;
18238 attname = getAttrName(indkey, tbinfo);
18239
18240 appendPQExpBuffer(q, "%s%s",
18241 (k == indxinfo->indnkeyattrs) ? "" : ", ",
18242 fmtId(attname));
18243 }
18244
18245 appendPQExpBufferChar(q, ')');
18246
18247 if (nonemptyReloptions(indxinfo->indreloptions))
18248 {
18249 appendPQExpBufferStr(q, " WITH (");
18250 appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
18251 appendPQExpBufferChar(q, ')');
18252 }
18253
18254 if (coninfo->condeferrable)
18255 {
18256 appendPQExpBufferStr(q, " DEFERRABLE");
18257 if (coninfo->condeferred)
18258 appendPQExpBufferStr(q, " INITIALLY DEFERRED");
18259 }
18260
18261 appendPQExpBufferStr(q, ";\n");
18262 }
18263
18264 /*
18265 * Append ALTER TABLE commands as needed to set properties that we
18266 * only have ALTER TABLE syntax for. Keep this in sync with the
18267 * similar code in dumpIndex!
18268 */
18269
18270 /* If the index is clustered, we need to record that. */
18271 if (indxinfo->indisclustered)
18272 {
18273 appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
18274 fmtQualifiedDumpable(tbinfo));
18275 /* index name is not qualified in this syntax */
18276 appendPQExpBuffer(q, " ON %s;\n",
18277 fmtId(indxinfo->dobj.name));
18278 }
18279
18280 /* If the index defines identity, we need to record that. */
18281 if (indxinfo->indisreplident)
18282 {
18283 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
18284 fmtQualifiedDumpable(tbinfo));
18285 /* index name is not qualified in this syntax */
18286 appendPQExpBuffer(q, " INDEX %s;\n",
18287 fmtId(indxinfo->dobj.name));
18288 }
18289
18290 /* Indexes can depend on extensions */
18291 append_depends_on_extension(fout, q, &indxinfo->dobj,
18292 "pg_catalog.pg_class", "INDEX",
18293 fmtQualifiedDumpable(indxinfo));
18294
18295 appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
18296 fmtQualifiedDumpable(tbinfo));
18297 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18298 fmtId(coninfo->dobj.name));
18299
18300 tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
18301
18302 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18303 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18304 ARCHIVE_OPTS(.tag = tag,
18305 .namespace = tbinfo->dobj.namespace->dobj.name,
18306 .tablespace = indxinfo->tablespace,
18307 .owner = tbinfo->rolname,
18308 .description = "CONSTRAINT",
18309 .section = SECTION_POST_DATA,
18310 .createStmt = q->data,
18311 .dropStmt = delq->data));
18312 }
18313 else if (coninfo->contype == 'f')
18314 {
18315 char *only;
18316
18317 /*
18318 * Foreign keys on partitioned tables are always declared as
18319 * inheriting to partitions; for all other cases, emit them as
18320 * applying ONLY directly to the named table, because that's how they
18321 * work for regular inherited tables.
18322 */
18323 only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
18324
18325 /*
18326 * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
18327 * current table data is not processed
18328 */
18329 appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
18330 only, fmtQualifiedDumpable(tbinfo));
18331 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
18332 fmtId(coninfo->dobj.name),
18333 coninfo->condef);
18334
18335 appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
18336 only, fmtQualifiedDumpable(tbinfo));
18337 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18338 fmtId(coninfo->dobj.name));
18339
18340 tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
18341
18342 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18343 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18344 ARCHIVE_OPTS(.tag = tag,
18345 .namespace = tbinfo->dobj.namespace->dobj.name,
18346 .owner = tbinfo->rolname,
18347 .description = "FK CONSTRAINT",
18348 .section = SECTION_POST_DATA,
18349 .createStmt = q->data,
18350 .dropStmt = delq->data));
18351 }
18352 else if ((coninfo->contype == 'c' || coninfo->contype == 'n') && tbinfo)
18353 {
18354 /* CHECK or invalid not-null constraint on a table */
18355
18356 /* Ignore if not to be dumped separately, or if it was inherited */
18357 if (coninfo->separate && coninfo->conislocal)
18358 {
18359 const char *keyword;
18360
18361 if (coninfo->contype == 'c')
18362 keyword = "CHECK CONSTRAINT";
18363 else
18364 keyword = "CONSTRAINT";
18365
18366 /* not ONLY since we want it to propagate to children */
18367 appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
18368 fmtQualifiedDumpable(tbinfo));
18369 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
18370 fmtId(coninfo->dobj.name),
18371 coninfo->condef);
18372
18373 appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
18374 fmtQualifiedDumpable(tbinfo));
18375 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18376 fmtId(coninfo->dobj.name));
18377
18378 tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
18379
18380 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18381 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18382 ARCHIVE_OPTS(.tag = tag,
18383 .namespace = tbinfo->dobj.namespace->dobj.name,
18384 .owner = tbinfo->rolname,
18385 .description = keyword,
18386 .section = SECTION_POST_DATA,
18387 .createStmt = q->data,
18388 .dropStmt = delq->data));
18389 }
18390 }
18391 else if (coninfo->contype == 'c' && tbinfo == NULL)
18392 {
18393 /* CHECK constraint on a domain */
18394 TypeInfo *tyinfo = coninfo->condomain;
18395
18396 /* Ignore if not to be dumped separately */
18397 if (coninfo->separate)
18398 {
18399 appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
18400 fmtQualifiedDumpable(tyinfo));
18401 appendPQExpBuffer(q, " ADD CONSTRAINT %s %s;\n",
18402 fmtId(coninfo->dobj.name),
18403 coninfo->condef);
18404
18405 appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
18406 fmtQualifiedDumpable(tyinfo));
18407 appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
18408 fmtId(coninfo->dobj.name));
18409
18410 tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
18411
18412 if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18413 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
18414 ARCHIVE_OPTS(.tag = tag,
18415 .namespace = tyinfo->dobj.namespace->dobj.name,
18416 .owner = tyinfo->rolname,
18417 .description = "CHECK CONSTRAINT",
18418 .section = SECTION_POST_DATA,
18419 .createStmt = q->data,
18420 .dropStmt = delq->data));
18421 }
18422 }
18423 else
18424 {
18425 pg_fatal("unrecognized constraint type: %c",
18426 coninfo->contype);
18427 }
18428
18429 /* Dump Constraint Comments --- only works for table constraints */
18430 if (tbinfo && coninfo->separate &&
18431 coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18432 dumpTableConstraintComment(fout, coninfo);
18433
18434 free(tag);
18436 destroyPQExpBuffer(delq);
18437}
#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:5440
static const char * getAttrName(int attrnum, const TableInfo *tblInfo)
Definition: pg_dump.c:17851
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, const char *prefix, Archive *fout)
Definition: pg_dump.c:20049
static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:18447
static bool nonemptyReloptions(const char *reloptions)
Definition: pg_dump.c:20037
TypeInfo * condomain
Definition: pg_dump.h:511
TableInfo * contable
Definition: pg_dump.h:510
bool condeferred
Definition: pg_dump.h:517
bool conperiod
Definition: pg_dump.h:518
bool conislocal
Definition: pg_dump.h:519
DumpableObject dobj
Definition: pg_dump.h:509
DumpId conindex
Definition: pg_dump.h:515
bool condeferrable
Definition: pg_dump.h:516
char * condef
Definition: pg_dump.h:513
bool indisreplident
Definition: pg_dump.h:424
int indnkeyattrs
Definition: pg_dump.h:419
int indnattrs
Definition: pg_dump.h:420
Oid * indkeys
Definition: pg_dump.h:421
char * indreloptions
Definition: pg_dump.h:416
bool indisclustered
Definition: pg_dump.h:423
char * tablespace
Definition: pg_dump.h:415
bool indnullsnotdistinct
Definition: pg_dump.h:425
DumpableObject dobj
Definition: pg_dump.h:412

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

14908{
14909 DumpOptions *dopt = fout->dopt;
14910 PQExpBuffer query;
14911 PQExpBuffer q;
14912 PQExpBuffer delq;
14913 char *qconvname;
14914 PGresult *res;
14915 int i_conforencoding;
14916 int i_contoencoding;
14917 int i_conproc;
14918 int i_condefault;
14919 const char *conforencoding;
14920 const char *contoencoding;
14921 const char *conproc;
14922 bool condefault;
14923
14924 /* Do nothing if not dumping schema */
14925 if (!dopt->dumpSchema)
14926 return;
14927
14928 query = createPQExpBuffer();
14929 q = createPQExpBuffer();
14930 delq = createPQExpBuffer();
14931
14932 qconvname = pg_strdup(fmtId(convinfo->dobj.name));
14933
14934 /* Get conversion-specific details */
14935 appendPQExpBuffer(query, "SELECT "
14936 "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
14937 "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
14938 "conproc, condefault "
14939 "FROM pg_catalog.pg_conversion c "
14940 "WHERE c.oid = '%u'::pg_catalog.oid",
14941 convinfo->dobj.catId.oid);
14942
14943 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14944
14945 i_conforencoding = PQfnumber(res, "conforencoding");
14946 i_contoencoding = PQfnumber(res, "contoencoding");
14947 i_conproc = PQfnumber(res, "conproc");
14948 i_condefault = PQfnumber(res, "condefault");
14949
14950 conforencoding = PQgetvalue(res, 0, i_conforencoding);
14951 contoencoding = PQgetvalue(res, 0, i_contoencoding);
14952 conproc = PQgetvalue(res, 0, i_conproc);
14953 condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
14954
14955 appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
14956 fmtQualifiedDumpable(convinfo));
14957
14958 appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
14959 (condefault) ? "DEFAULT " : "",
14960 fmtQualifiedDumpable(convinfo));
14961 appendStringLiteralAH(q, conforencoding, fout);
14962 appendPQExpBufferStr(q, " TO ");
14963 appendStringLiteralAH(q, contoencoding, fout);
14964 /* regproc output is already sufficiently quoted */
14965 appendPQExpBuffer(q, " FROM %s;\n", conproc);
14966
14967 if (dopt->binary_upgrade)
14969 "CONVERSION", qconvname,
14970 convinfo->dobj.namespace->dobj.name);
14971
14972 if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14973 ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
14974 ARCHIVE_OPTS(.tag = convinfo->dobj.name,
14975 .namespace = convinfo->dobj.namespace->dobj.name,
14976 .owner = convinfo->rolname,
14977 .description = "CONVERSION",
14978 .section = SECTION_PRE_DATA,
14979 .createStmt = q->data,
14980 .dropStmt = delq->data));
14981
14982 /* Dump Conversion Comments */
14983 if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14984 dumpComment(fout, "CONVERSION", qconvname,
14985 convinfo->dobj.namespace->dobj.name, convinfo->rolname,
14986 convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
14987
14988 PQclear(res);
14989
14990 destroyPQExpBuffer(query);
14992 destroyPQExpBuffer(delq);
14993 free(qconvname);
14994}
DumpableObject dobj
Definition: pg_dump.h:291
const char * rolname
Definition: pg_dump.h:292

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

3192{
3193 DumpOptions *dopt = fout->dopt;
3195 PQExpBuffer delQry = createPQExpBuffer();
3196 PQExpBuffer creaQry = createPQExpBuffer();
3197 PQExpBuffer labelq = createPQExpBuffer();
3198 PGconn *conn = GetConnection(fout);
3199 PGresult *res;
3200 int i_tableoid,
3201 i_oid,
3202 i_datname,
3203 i_datdba,
3204 i_encoding,
3205 i_datlocprovider,
3206 i_collate,
3207 i_ctype,
3208 i_datlocale,
3209 i_daticurules,
3210 i_frozenxid,
3211 i_minmxid,
3212 i_datacl,
3213 i_acldefault,
3214 i_datistemplate,
3215 i_datconnlimit,
3216 i_datcollversion,
3217 i_tablespace;
3218 CatalogId dbCatId;
3219 DumpId dbDumpId;
3220 DumpableAcl dbdacl;
3221 const char *datname,
3222 *dba,
3223 *encoding,
3225 *collate,
3226 *ctype,
3227 *locale,
3228 *icurules,
3230 *datconnlimit,
3231 *tablespace;
3232 uint32 frozenxid,
3233 minmxid;
3234 char *qdatname;
3235
3236 pg_log_info("saving database definition");
3237
3238 /*
3239 * Fetch the database-level properties for this database.
3240 */
3241 appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
3242 "datdba, "
3243 "pg_encoding_to_char(encoding) AS encoding, "
3244 "datcollate, datctype, datfrozenxid, "
3245 "datacl, acldefault('d', datdba) AS acldefault, "
3246 "datistemplate, datconnlimit, ");
3247 if (fout->remoteVersion >= 90300)
3248 appendPQExpBufferStr(dbQry, "datminmxid, ");
3249 else
3250 appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
3251 if (fout->remoteVersion >= 170000)
3252 appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
3253 else if (fout->remoteVersion >= 150000)
3254 appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
3255 else
3256 appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
3257 if (fout->remoteVersion >= 160000)
3258 appendPQExpBufferStr(dbQry, "daticurules, ");
3259 else
3260 appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
3262 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
3263 "shobj_description(oid, 'pg_database') AS description "
3264 "FROM pg_database "
3265 "WHERE datname = current_database()");
3266
3267 res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
3268
3269 i_tableoid = PQfnumber(res, "tableoid");
3270 i_oid = PQfnumber(res, "oid");
3271 i_datname = PQfnumber(res, "datname");
3272 i_datdba = PQfnumber(res, "datdba");
3273 i_encoding = PQfnumber(res, "encoding");
3274 i_datlocprovider = PQfnumber(res, "datlocprovider");
3275 i_collate = PQfnumber(res, "datcollate");
3276 i_ctype = PQfnumber(res, "datctype");
3277 i_datlocale = PQfnumber(res, "datlocale");
3278 i_daticurules = PQfnumber(res, "daticurules");
3279 i_frozenxid = PQfnumber(res, "datfrozenxid");
3280 i_minmxid = PQfnumber(res, "datminmxid");
3281 i_datacl = PQfnumber(res, "datacl");
3282 i_acldefault = PQfnumber(res, "acldefault");
3283 i_datistemplate = PQfnumber(res, "datistemplate");
3284 i_datconnlimit = PQfnumber(res, "datconnlimit");
3285 i_datcollversion = PQfnumber(res, "datcollversion");
3286 i_tablespace = PQfnumber(res, "tablespace");
3287
3288 dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
3289 dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
3290 datname = PQgetvalue(res, 0, i_datname);
3291 dba = getRoleName(PQgetvalue(res, 0, i_datdba));
3292 encoding = PQgetvalue(res, 0, i_encoding);
3293 datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
3294 collate = PQgetvalue(res, 0, i_collate);
3295 ctype = PQgetvalue(res, 0, i_ctype);
3296 if (!PQgetisnull(res, 0, i_datlocale))
3297 locale = PQgetvalue(res, 0, i_datlocale);
3298 else
3299 locale = NULL;
3300 if (!PQgetisnull(res, 0, i_daticurules))
3301 icurules = PQgetvalue(res, 0, i_daticurules);
3302 else
3303 icurules = NULL;
3304 frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
3305 minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
3306 dbdacl.acl = PQgetvalue(res, 0, i_datacl);
3307 dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
3308 datistemplate = PQgetvalue(res, 0, i_datistemplate);
3309 datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
3310 tablespace = PQgetvalue(res, 0, i_tablespace);
3311
3312 qdatname = pg_strdup(fmtId(datname));
3313
3314 /*
3315 * Prepare the CREATE DATABASE command. We must specify OID (if we want
3316 * to preserve that), as well as the encoding, locale, and tablespace
3317 * since those can't be altered later. Other DB properties are left to
3318 * the DATABASE PROPERTIES entry, so that they can be applied after
3319 * reconnecting to the target DB.
3320 *
3321 * For binary upgrade, we use the FILE_COPY strategy because testing has
3322 * shown it to be faster. When the server is in binary upgrade mode, it
3323 * will also skip the checkpoints this strategy ordinarily performs.
3324 */
3325 if (dopt->binary_upgrade)
3326 {
3327 appendPQExpBuffer(creaQry,
3328 "CREATE DATABASE %s WITH TEMPLATE = template0 "
3329 "OID = %u STRATEGY = FILE_COPY",
3330 qdatname, dbCatId.oid);
3331 }
3332 else
3333 {
3334 appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
3335 qdatname);
3336 }
3337 if (strlen(encoding) > 0)
3338 {
3339 appendPQExpBufferStr(creaQry, " ENCODING = ");
3340 appendStringLiteralAH(creaQry, encoding, fout);
3341 }
3342
3343 appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
3344 if (datlocprovider[0] == 'b')
3345 appendPQExpBufferStr(creaQry, "builtin");
3346 else if (datlocprovider[0] == 'c')
3347 appendPQExpBufferStr(creaQry, "libc");
3348 else if (datlocprovider[0] == 'i')
3349 appendPQExpBufferStr(creaQry, "icu");
3350 else
3351 pg_fatal("unrecognized locale provider: %s",
3353
3354 if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
3355 {
3356 appendPQExpBufferStr(creaQry, " LOCALE = ");
3357 appendStringLiteralAH(creaQry, collate, fout);
3358 }
3359 else
3360 {
3361 if (strlen(collate) > 0)
3362 {
3363 appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
3364 appendStringLiteralAH(creaQry, collate, fout);
3365 }
3366 if (strlen(ctype) > 0)
3367 {
3368 appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
3369 appendStringLiteralAH(creaQry, ctype, fout);
3370 }
3371 }
3372 if (locale)
3373 {
3374 if (datlocprovider[0] == 'b')
3375 appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
3376 else
3377 appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
3378
3379 appendStringLiteralAH(creaQry, locale, fout);
3380 }
3381
3382 if (icurules)
3383 {
3384 appendPQExpBufferStr(creaQry, " ICU_RULES = ");
3385 appendStringLiteralAH(creaQry, icurules, fout);
3386 }
3387
3388 /*
3389 * For binary upgrade, carry over the collation version. For normal
3390 * dump/restore, omit the version, so that it is computed upon restore.
3391 */
3392 if (dopt->binary_upgrade)
3393 {
3394 if (!PQgetisnull(res, 0, i_datcollversion))
3395 {
3396 appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
3397 appendStringLiteralAH(creaQry,
3398 PQgetvalue(res, 0, i_datcollversion),
3399 fout);
3400 }
3401 }
3402
3403 /*
3404 * Note: looking at dopt->outputNoTablespaces here is completely the wrong
3405 * thing; the decision whether to specify a tablespace should be left till
3406 * pg_restore, so that pg_restore --no-tablespaces applies. Ideally we'd
3407 * label the DATABASE entry with the tablespace and let the normal
3408 * tablespace selection logic work ... but CREATE DATABASE doesn't pay
3409 * attention to default_tablespace, so that won't work.
3410 */
3411 if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
3412 !dopt->outputNoTablespaces)
3413 appendPQExpBuffer(creaQry, " TABLESPACE = %s",
3414 fmtId(tablespace));
3415 appendPQExpBufferStr(creaQry, ";\n");
3416
3417 appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
3418 qdatname);
3419
3420 dbDumpId = createDumpId();
3421
3422 ArchiveEntry(fout,
3423 dbCatId, /* catalog ID */
3424 dbDumpId, /* dump ID */
3425 ARCHIVE_OPTS(.tag = datname,
3426 .owner = dba,
3427 .description = "DATABASE",
3428 .section = SECTION_PRE_DATA,
3429 .createStmt = creaQry->data,
3430 .dropStmt = delQry->data));
3431
3432 /* Compute correct tag for archive entry */
3433 appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
3434
3435 /* Dump DB comment if any */
3436 {
3437 /*
3438 * 8.2 and up keep comments on shared objects in a shared table, so we
3439 * cannot use the dumpComment() code used for other database objects.
3440 * Be careful that the ArchiveEntry parameters match that function.
3441 */
3442 char *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
3443
3444 if (comment && *comment && !dopt->no_comments)
3445 {
3446 resetPQExpBuffer(dbQry);
3447
3448 /*
3449 * Generates warning when loaded into a differently-named
3450 * database.
3451 */
3452 appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
3453 appendStringLiteralAH(dbQry, comment, fout);
3454 appendPQExpBufferStr(dbQry, ";\n");
3455
3457 ARCHIVE_OPTS(.tag = labelq->data,
3458 .owner = dba,
3459 .description = "COMMENT",
3460 .section = SECTION_NONE,
3461 .createStmt = dbQry->data,
3462 .deps = &dbDumpId,
3463 .nDeps = 1));
3464 }
3465 }
3466
3467 /* Dump DB security label, if enabled */
3468 if (!dopt->no_security_labels)
3469 {
3470 PGresult *shres;
3471 PQExpBuffer seclabelQry;
3472
3473 seclabelQry = createPQExpBuffer();
3474
3475 buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
3476 shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
3477 resetPQExpBuffer(seclabelQry);
3478 emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
3479 if (seclabelQry->len > 0)
3481 ARCHIVE_OPTS(.tag = labelq->data,
3482 .owner = dba,
3483 .description = "SECURITY LABEL",
3484 .section = SECTION_NONE,
3485 .createStmt = seclabelQry->data,
3486 .deps = &dbDumpId,
3487 .nDeps = 1));
3488 destroyPQExpBuffer(seclabelQry);
3489 PQclear(shres);
3490 }
3491
3492 /*
3493 * Dump ACL if any. Note that we do not support initial privileges
3494 * (pg_init_privs) on databases.
3495 */
3496 dbdacl.privtype = 0;
3497 dbdacl.initprivs = NULL;
3498
3499 dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
3500 qdatname, NULL, NULL,
3501 NULL, dba, &dbdacl);
3502
3503 /*
3504 * Now construct a DATABASE PROPERTIES archive entry to restore any
3505 * non-default database-level properties. (The reason this must be
3506 * separate is that we cannot put any additional commands into the TOC
3507 * entry that has CREATE DATABASE. pg_restore would execute such a group
3508 * in an implicit transaction block, and the backend won't allow CREATE
3509 * DATABASE in that context.)
3510 */
3511 resetPQExpBuffer(creaQry);
3512 resetPQExpBuffer(delQry);
3513
3514 if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
3515 appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
3516 qdatname, datconnlimit);
3517
3518 if (strcmp(datistemplate, "t") == 0)
3519 {
3520 appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
3521 qdatname);
3522
3523 /*
3524 * The backend won't accept DROP DATABASE on a template database. We
3525 * can deal with that by removing the template marking before the DROP
3526 * gets issued. We'd prefer to use ALTER DATABASE IF EXISTS here, but
3527 * since no such command is currently supported, fake it with a direct
3528 * UPDATE on pg_database.
3529 */
3530 appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
3531 "SET datistemplate = false WHERE datname = ");
3532 appendStringLiteralAH(delQry, datname, fout);
3533 appendPQExpBufferStr(delQry, ";\n");
3534 }
3535
3536 /*
3537 * We do not restore pg_database.dathasloginevt because it is set
3538 * automatically on login event trigger creation.
3539 */
3540
3541 /* Add database-specific SET options */
3542 dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
3543
3544 /*
3545 * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
3546 * entry, too, for lack of a better place.
3547 */
3548 if (dopt->binary_upgrade)
3549 {
3550 appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
3551 appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
3552 "SET datfrozenxid = '%u', datminmxid = '%u'\n"
3553 "WHERE datname = ",
3554 frozenxid, minmxid);
3555 appendStringLiteralAH(creaQry, datname, fout);
3556 appendPQExpBufferStr(creaQry, ";\n");
3557 }
3558
3559 if (creaQry->len > 0)
3561 ARCHIVE_OPTS(.tag = datname,
3562 .owner = dba,
3563 .description = "DATABASE PROPERTIES",
3564 .section = SECTION_PRE_DATA,
3565 .createStmt = creaQry->data,
3566 .dropStmt = delQry->data,
3567 .deps = &dbDumpId));
3568
3569 /*
3570 * pg_largeobject comes from the old system intact, so set its
3571 * relfrozenxids, relminmxids and relfilenode.
3572 */
3573 if (dopt->binary_upgrade)
3574 {
3575 PGresult *lo_res;
3576 PQExpBuffer loFrozenQry = createPQExpBuffer();
3577 PQExpBuffer loOutQry = createPQExpBuffer();
3578 PQExpBuffer loHorizonQry = createPQExpBuffer();
3579 int ii_relfrozenxid,
3580 ii_relfilenode,
3581 ii_oid,
3582 ii_relminmxid;
3583
3584 /*
3585 * pg_largeobject
3586 */
3587 if (fout->remoteVersion >= 90300)
3588 appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
3589 "FROM pg_catalog.pg_class\n"
3590 "WHERE oid IN (%u, %u);\n",
3591 LargeObjectRelationId, LargeObjectLOidPNIndexId);
3592 else
3593 appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
3594 "FROM pg_catalog.pg_class\n"
3595 "WHERE oid IN (%u, %u);\n",
3596 LargeObjectRelationId, LargeObjectLOidPNIndexId);
3597
3598 lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
3599
3600 ii_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
3601 ii_relminmxid = PQfnumber(lo_res, "relminmxid");
3602 ii_relfilenode = PQfnumber(lo_res, "relfilenode");
3603 ii_oid = PQfnumber(lo_res, "oid");
3604
3605 appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
3606 appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
3607 for (int i = 0; i < PQntuples(lo_res); ++i)
3608 {
3609 Oid oid;
3610 RelFileNumber relfilenumber;
3611
3612 appendPQExpBuffer(loHorizonQry, "UPDATE pg_catalog.pg_class\n"
3613 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
3614 "WHERE oid = %u;\n",
3615 atooid(PQgetvalue(lo_res, i, ii_relfrozenxid)),
3616 atooid(PQgetvalue(lo_res, i, ii_relminmxid)),
3617 atooid(PQgetvalue(lo_res, i, ii_oid)));
3618
3619 oid = atooid(PQgetvalue(lo_res, i, ii_oid));
3620 relfilenumber = atooid(PQgetvalue(lo_res, i, ii_relfilenode));
3621
3622 if (oid == LargeObjectRelationId)
3623 appendPQExpBuffer(loOutQry,
3624 "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
3625 relfilenumber);
3626 else if (oid == LargeObjectLOidPNIndexId)
3627 appendPQExpBuffer(loOutQry,
3628 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
3629 relfilenumber);
3630 }
3631
3632 appendPQExpBufferStr(loOutQry,
3633 "TRUNCATE pg_catalog.pg_largeobject;\n");
3634 appendPQExpBufferStr(loOutQry, loHorizonQry->data);
3635
3637 ARCHIVE_OPTS(.tag = "pg_largeobject",
3638 .description = "pg_largeobject",
3639 .section = SECTION_PRE_DATA,
3640 .createStmt = loOutQry->data));
3641
3642 PQclear(lo_res);
3643
3644 destroyPQExpBuffer(loFrozenQry);
3645 destroyPQExpBuffer(loHorizonQry);
3646 destroyPQExpBuffer(loOutQry);
3647 }
3648
3649 PQclear(res);
3650
3651 free(qdatname);
3652 destroyPQExpBuffer(dbQry);
3653 destroyPQExpBuffer(delQry);
3654 destroyPQExpBuffer(creaQry);
3655 destroyPQExpBuffer(labelq);
3656}
uint32_t uint32
Definition: c.h:502
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
Definition: connection.c:203
void buildShSecLabelQuery(const char *catalog_name, Oid objectId, PQExpBuffer sql)
Definition: dumputils.c:640
void emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *objtype, const char *objname)
Definition: dumputils.c:658
#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:10396
static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf, const char *dbname, Oid dboid)
Definition: pg_dump.c:3663
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:187
int outputNoTablespaces
Definition: pg_backup.h:194
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 3663 of file pg_dump.c.

3665{
3666 PGconn *conn = GetConnection(AH);
3668 PGresult *res;
3669
3670 /* First collect database-specific options */
3671 printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
3672 "WHERE setrole = 0 AND setdatabase = '%u'::oid",
3673 dboid);
3674
3675 res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3676
3677 for (int i = 0; i < PQntuples(res); i++)
3679 "DATABASE", dbname, NULL, NULL,
3680 outbuf);
3681
3682 PQclear(res);
3683
3684 /* Now look for role-and-database-specific options */
3685 printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
3686 "FROM pg_db_role_setting s, pg_roles r "
3687 "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
3688 dboid);
3689
3690 res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
3691
3692 for (int i = 0; i < PQntuples(res); i++)
3694 "ROLE", PQgetvalue(res, i, 0),
3695 "DATABASE", dbname,
3696 outbuf);
3697
3698 PQclear(res);
3699
3701}
void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, PQExpBuffer buf)
Definition: dumputils.c:826
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 15981 of file pg_dump.c.

15982{
15983 DumpOptions *dopt = fout->dopt;
15984 PQExpBuffer q;
15985 PQExpBuffer tag;
15986 const char *type;
15987
15988 /* Do nothing if not dumping schema, or if we're skipping ACLs */
15989 if (!dopt->dumpSchema || dopt->aclsSkip)
15990 return;
15991
15992 q = createPQExpBuffer();
15993 tag = createPQExpBuffer();
15994
15995 switch (daclinfo->defaclobjtype)
15996 {
15997 case DEFACLOBJ_RELATION:
15998 type = "TABLES";
15999 break;
16000 case DEFACLOBJ_SEQUENCE:
16001 type = "SEQUENCES";
16002 break;
16003 case DEFACLOBJ_FUNCTION:
16004 type = "FUNCTIONS";
16005 break;
16006 case DEFACLOBJ_TYPE:
16007 type = "TYPES";
16008 break;
16009 case DEFACLOBJ_NAMESPACE:
16010 type = "SCHEMAS";
16011 break;
16012 case DEFACLOBJ_LARGEOBJECT:
16013 type = "LARGE OBJECTS";
16014 break;
16015 default:
16016 /* shouldn't get here */
16017 pg_fatal("unrecognized object type in default privileges: %d",
16018 (int) daclinfo->defaclobjtype);
16019 type = ""; /* keep compiler quiet */
16020 }
16021
16022 appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
16023
16024 /* build the actual command(s) for this tuple */
16026 daclinfo->dobj.namespace != NULL ?
16027 daclinfo->dobj.namespace->dobj.name : NULL,
16028 daclinfo->dacl.acl,
16029 daclinfo->dacl.acldefault,
16030 daclinfo->defaclrole,
16031 fout->remoteVersion,
16032 q))
16033 pg_fatal("could not parse default ACL list (%s)",
16034 daclinfo->dacl.acl);
16035
16036 if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
16037 ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
16038 ARCHIVE_OPTS(.tag = tag->data,
16039 .namespace = daclinfo->dobj.namespace ?
16040 daclinfo->dobj.namespace->dobj.name : NULL,
16041 .owner = daclinfo->defaclrole,
16042 .description = "DEFAULT ACL",
16043 .section = SECTION_POST_DATA,
16044 .createStmt = q->data));
16045
16046 destroyPQExpBuffer(tag);
16048}
bool buildDefaultACLCommands(const char *type, const char *nspname, const char *acls, const char *acldefault, const char *owner, int remoteVersion, PQExpBuffer sql)
Definition: dumputils.c:328
DumpableObject dobj
Definition: pg_dump.h:615
DumpableAcl dacl
Definition: pg_dump.h:616
const char * defaclrole
Definition: pg_dump.h:617
char defaclobjtype
Definition: pg_dump.h:618

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

12421{
12422 DumpOptions *dopt = fout->dopt;
12426 PGresult *res;
12427 int i;
12428 char *qtypname;
12429 char *qualtypname;
12430 char *typnotnull;
12431 char *typdefn;
12432 char *typdefault;
12433 Oid typcollation;
12434 bool typdefault_is_literal = false;
12435
12437 {
12438 /* Set up query for domain-specific details */
12440 "PREPARE dumpDomain(pg_catalog.oid) AS\n");
12441
12442 appendPQExpBufferStr(query, "SELECT t.typnotnull, "
12443 "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
12444 "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
12445 "t.typdefault, "
12446 "CASE WHEN t.typcollation <> u.typcollation "
12447 "THEN t.typcollation ELSE 0 END AS typcollation "
12448 "FROM pg_catalog.pg_type t "
12449 "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
12450 "WHERE t.oid = $1");
12451
12452 ExecuteSqlStatement(fout, query->data);
12453
12454 fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
12455 }
12456
12457 printfPQExpBuffer(query,
12458 "EXECUTE dumpDomain('%u')",
12459 tyinfo->dobj.catId.oid);
12460
12461 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12462
12463 typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
12464 typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
12465 if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
12466 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
12467 else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
12468 {
12469 typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
12470 typdefault_is_literal = true; /* it needs quotes */
12471 }
12472 else
12473 typdefault = NULL;
12474 typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
12475
12476 if (dopt->binary_upgrade)
12478 tyinfo->dobj.catId.oid,
12479 true, /* force array type */
12480 false); /* force multirange type */
12481
12482 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12483 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12484
12486 "CREATE DOMAIN %s AS %s",
12487 qualtypname,
12488 typdefn);
12489
12490 /* Print collation only if different from base type's collation */
12491 if (OidIsValid(typcollation))
12492 {
12493 CollInfo *coll;
12494
12495 coll = findCollationByOid(typcollation);
12496 if (coll)
12497 appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
12498 }
12499
12500 if (typnotnull[0] == 't')
12501 appendPQExpBufferStr(q, " NOT NULL");
12502
12503 if (typdefault != NULL)
12504 {
12505 appendPQExpBufferStr(q, " DEFAULT ");
12506 if (typdefault_is_literal)
12507 appendStringLiteralAH(q, typdefault, fout);
12508 else
12509 appendPQExpBufferStr(q, typdefault);
12510 }
12511
12512 PQclear(res);
12513
12514 /*
12515 * Add any CHECK constraints for the domain
12516 */
12517 for (i = 0; i < tyinfo->nDomChecks; i++)
12518 {
12519 ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
12520
12521 if (!domcheck->separate)
12522 appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
12523 fmtId(domcheck->dobj.name), domcheck->condef);
12524 }
12525
12526 appendPQExpBufferStr(q, ";\n");
12527
12528 appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
12529
12530 if (dopt->binary_upgrade)
12532 "DOMAIN", qtypname,
12533 tyinfo->dobj.namespace->dobj.name);
12534
12535 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12536 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12537 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12538 .namespace = tyinfo->dobj.namespace->dobj.name,
12539 .owner = tyinfo->rolname,
12540 .description = "DOMAIN",
12541 .section = SECTION_PRE_DATA,
12542 .createStmt = q->data,
12543 .dropStmt = delq->data));
12544
12545 /* Dump Domain Comments and Security Labels */
12546 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12547 dumpComment(fout, "DOMAIN", qtypname,
12548 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12549 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12550
12551 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12552 dumpSecLabel(fout, "DOMAIN", qtypname,
12553 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12554 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12555
12556 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12557 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12558 qtypname, NULL,
12559 tyinfo->dobj.namespace->dobj.name,
12560 NULL, tyinfo->rolname, &tyinfo->dacl);
12561
12562 /* Dump any per-constraint comments */
12563 for (i = 0; i < tyinfo->nDomChecks; i++)
12564 {
12565 ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
12566 PQExpBuffer conprefix = createPQExpBuffer();
12567
12568 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
12569 fmtId(domcheck->dobj.name));
12570
12571 if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
12572 dumpComment(fout, conprefix->data, qtypname,
12573 tyinfo->dobj.namespace->dobj.name,
12574 tyinfo->rolname,
12575 domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
12576
12577 destroyPQExpBuffer(conprefix);
12578 }
12579
12581 destroyPQExpBuffer(delq);
12582 destroyPQExpBuffer(query);
12583 free(qtypname);
12584 free(qualtypname);
12585}
@ PREPQUERY_DUMPDOMAIN
Definition: pg_backup.h:69
struct _constraintInfo * domChecks
Definition: pg_dump.h:227
int nDomChecks
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, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), _typeInfo::dobj, _constraintInfo::dobj, _typeInfo::domChecks, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_COMMENT, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_SECLABEL, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQueryForSingleRow(), ExecuteSqlStatement(), findCollationByOid(), fmtId(), fmtQualifiedDumpable, free, i, InvalidDumpId, Archive::is_prepared, _dumpableObject::name, _typeInfo::nDomChecks, CatalogId::oid, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PREPQUERY_DUMPDOMAIN, printfPQExpBuffer(), _typeInfo::rolname, SECTION_PRE_DATA, and _constraintInfo::separate.

Referenced by dumpType().

◆ dumpDumpableObject()

static void dumpDumpableObject ( Archive fout,
DumpableObject dobj 
)
static

Definition at line 11377 of file pg_dump.c.

11378{
11379 /*
11380 * Clear any dump-request bits for components that don't exist for this
11381 * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
11382 * request for every kind of object.)
11383 */
11384 dobj->dump &= dobj->components;
11385
11386 /* Now, short-circuit if there's nothing to be done here. */
11387 if (dobj->dump == 0)
11388 return;
11389
11390 switch (dobj->objType)
11391 {
11392 case DO_NAMESPACE:
11393 dumpNamespace(fout, (const NamespaceInfo *) dobj);
11394 break;
11395 case DO_EXTENSION:
11396 dumpExtension(fout, (const ExtensionInfo *) dobj);
11397 break;
11398 case DO_TYPE:
11399 dumpType(fout, (const TypeInfo *) dobj);
11400 break;
11401 case DO_SHELL_TYPE:
11402 dumpShellType(fout, (const ShellTypeInfo *) dobj);
11403 break;
11404 case DO_FUNC:
11405 dumpFunc(fout, (const FuncInfo *) dobj);
11406 break;
11407 case DO_AGG:
11408 dumpAgg(fout, (const AggInfo *) dobj);
11409 break;
11410 case DO_OPERATOR:
11411 dumpOpr(fout, (const OprInfo *) dobj);
11412 break;
11413 case DO_ACCESS_METHOD:
11414 dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
11415 break;
11416 case DO_OPCLASS:
11417 dumpOpclass(fout, (const OpclassInfo *) dobj);
11418 break;
11419 case DO_OPFAMILY:
11420 dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
11421 break;
11422 case DO_COLLATION:
11423 dumpCollation(fout, (const CollInfo *) dobj);
11424 break;
11425 case DO_CONVERSION:
11426 dumpConversion(fout, (const ConvInfo *) dobj);
11427 break;
11428 case DO_TABLE:
11429 dumpTable(fout, (const TableInfo *) dobj);
11430 break;
11431 case DO_TABLE_ATTACH:
11432 dumpTableAttach(fout, (const TableAttachInfo *) dobj);
11433 break;
11434 case DO_ATTRDEF:
11435 dumpAttrDef(fout, (const AttrDefInfo *) dobj);
11436 break;
11437 case DO_INDEX:
11438 dumpIndex(fout, (const IndxInfo *) dobj);
11439 break;
11440 case DO_INDEX_ATTACH:
11441 dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
11442 break;
11443 case DO_STATSEXT:
11444 dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
11445 break;
11446 case DO_REFRESH_MATVIEW:
11447 refreshMatViewData(fout, (const TableDataInfo *) dobj);
11448 break;
11449 case DO_RULE:
11450 dumpRule(fout, (const RuleInfo *) dobj);
11451 break;
11452 case DO_TRIGGER:
11453 dumpTrigger(fout, (const TriggerInfo *) dobj);
11454 break;
11455 case DO_EVENT_TRIGGER:
11456 dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
11457 break;
11458 case DO_CONSTRAINT:
11459 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11460 break;
11461 case DO_FK_CONSTRAINT:
11462 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11463 break;
11464 case DO_PROCLANG:
11465 dumpProcLang(fout, (const ProcLangInfo *) dobj);
11466 break;
11467 case DO_CAST:
11468 dumpCast(fout, (const CastInfo *) dobj);
11469 break;
11470 case DO_TRANSFORM:
11471 dumpTransform(fout, (const TransformInfo *) dobj);
11472 break;
11473 case DO_SEQUENCE_SET:
11474 dumpSequenceData(fout, (const TableDataInfo *) dobj);
11475 break;
11476 case DO_TABLE_DATA:
11477 dumpTableData(fout, (const TableDataInfo *) dobj);
11478 break;
11479 case DO_DUMMY_TYPE:
11480 /* table rowtypes and array types are never dumped separately */
11481 break;
11482 case DO_TSPARSER:
11483 dumpTSParser(fout, (const TSParserInfo *) dobj);
11484 break;
11485 case DO_TSDICT:
11486 dumpTSDictionary(fout, (const TSDictInfo *) dobj);
11487 break;
11488 case DO_TSTEMPLATE:
11489 dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
11490 break;
11491 case DO_TSCONFIG:
11492 dumpTSConfig(fout, (const TSConfigInfo *) dobj);
11493 break;
11494 case DO_FDW:
11495 dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
11496 break;
11497 case DO_FOREIGN_SERVER:
11498 dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
11499 break;
11500 case DO_DEFAULT_ACL:
11501 dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
11502 break;
11503 case DO_LARGE_OBJECT:
11504 dumpLO(fout, (const LoInfo *) dobj);
11505 break;
11507 if (dobj->dump & DUMP_COMPONENT_DATA)
11508 {
11509 LoInfo *loinfo;
11510 TocEntry *te;
11511
11512 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
11513 if (loinfo == NULL)
11514 pg_fatal("missing metadata for large objects \"%s\"",
11515 dobj->name);
11516
11517 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
11518 ARCHIVE_OPTS(.tag = dobj->name,
11519 .owner = loinfo->rolname,
11520 .description = "BLOBS",
11521 .section = SECTION_DATA,
11522 .deps = dobj->dependencies,
11523 .nDeps = dobj->nDeps,
11524 .dumpFn = dumpLOs,
11525 .dumpArg = loinfo));
11526
11527 /*
11528 * Set the TocEntry's dataLength in case we are doing a
11529 * parallel dump and want to order dump jobs by table size.
11530 * (We need some size estimate for every TocEntry with a
11531 * DataDumper function.) We don't currently have any cheap
11532 * way to estimate the size of LOs, but fortunately it doesn't
11533 * matter too much as long as we get large batches of LOs
11534 * processed reasonably early. Assume 8K per blob.
11535 */
11536 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
11537 }
11538 break;
11539 case DO_POLICY:
11540 dumpPolicy(fout, (const PolicyInfo *) dobj);
11541 break;
11542 case DO_PUBLICATION:
11543 dumpPublication(fout, (const PublicationInfo *) dobj);
11544 break;
11545 case DO_PUBLICATION_REL:
11546 dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
11547 break;
11550 (const PublicationSchemaInfo *) dobj);
11551 break;
11552 case DO_SUBSCRIPTION:
11553 dumpSubscription(fout, (const SubscriptionInfo *) dobj);
11554 break;
11556 dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
11557 break;
11558 case DO_REL_STATS:
11559 dumpRelationStats(fout, (const RelStatsInfo *) dobj);
11560 break;
11563 /* never dumped, nothing to do */
11564 break;
11565 }
11566}
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:17790
static void dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
Definition: pg_dump.c:4795
static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
Definition: pg_dump.c:11573
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:13536
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:17880
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:15459
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:15035
static void dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
Definition: pg_dump.c:11091
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:18893
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16528
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:18074
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:18151
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11778
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:17722
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:14082
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:13770
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:18816
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:13118
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:15787
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2782
static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
Definition: pg_dump.c:12888
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:2894
static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
Definition: pg_dump.c:4489
static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
Definition: pg_dump.c:4264
static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
Definition: pg_dump.c:14431
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:15981
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:15539
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:18031
static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
Definition: pg_dump.c:5223
static void dumpTransform(Archive *fout, const TransformInfo *transform)
Definition: pg_dump.c:13641
static void dumpLO(Archive *fout, const LoInfo *loinfo)
Definition: pg_dump.c:3956
static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
Definition: pg_dump.c:4838
static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
Definition: pg_dump.c:15395
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:19104
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:11650
static int dumpLOs(Archive *fout, const void *arg)
Definition: pg_dump.c:4046
static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
Definition: pg_dump.c:5292
static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
Definition: pg_dump.c:19019
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:14907
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:15717
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:12934
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:15597
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:14650
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:14150
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:110
#define pgoff_t
Definition: port.h:401
const char * rolname
Definition: pg_dump.h:633
int numlos
Definition: pg_dump.h:634
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 3707 of file pg_dump.c.

3708{
3709 const char *encname = pg_encoding_to_char(AH->encoding);
3711
3712 pg_log_info("saving encoding = %s", encname);
3713
3714 appendPQExpBufferStr(qry, "SET client_encoding = ");
3715 appendStringLiteralAH(qry, encname, AH);
3716 appendPQExpBufferStr(qry, ";\n");
3717
3719 ARCHIVE_OPTS(.tag = "ENCODING",
3720 .description = "ENCODING",
3721 .section = SECTION_PRE_DATA,
3722 .createStmt = qry->data));
3723
3724 destroyPQExpBuffer(qry);
3725}
#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 11809 of file pg_dump.c.

11810{
11811 DumpOptions *dopt = fout->dopt;
11815 PGresult *res;
11816 int num,
11817 i;
11818 Oid enum_oid;
11819 char *qtypname;
11820 char *qualtypname;
11821 char *label;
11822 int i_enumlabel;
11823 int i_oid;
11824
11826 {
11827 /* Set up query for enum-specific details */
11829 "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
11830 "SELECT oid, enumlabel "
11831 "FROM pg_catalog.pg_enum "
11832 "WHERE enumtypid = $1 "
11833 "ORDER BY enumsortorder");
11834
11835 ExecuteSqlStatement(fout, query->data);
11836
11837 fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
11838 }
11839
11840 printfPQExpBuffer(query,
11841 "EXECUTE dumpEnumType('%u')",
11842 tyinfo->dobj.catId.oid);
11843
11844 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11845
11846 num = PQntuples(res);
11847
11848 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
11849 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
11850
11851 /*
11852 * CASCADE shouldn't be required here as for normal types since the I/O
11853 * functions are generic and do not get dropped.
11854 */
11855 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
11856
11857 if (dopt->binary_upgrade)
11859 tyinfo->dobj.catId.oid,
11860 false, false);
11861
11862 appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
11863 qualtypname);
11864
11865 if (!dopt->binary_upgrade)
11866 {
11867 i_enumlabel = PQfnumber(res, "enumlabel");
11868
11869 /* Labels with server-assigned oids */
11870 for (i = 0; i < num; i++)
11871 {
11872 label = PQgetvalue(res, i, i_enumlabel);
11873 if (i > 0)
11874 appendPQExpBufferChar(q, ',');
11875 appendPQExpBufferStr(q, "\n ");
11876 appendStringLiteralAH(q, label, fout);
11877 }
11878 }
11879
11880 appendPQExpBufferStr(q, "\n);\n");
11881
11882 if (dopt->binary_upgrade)
11883 {
11884 i_oid = PQfnumber(res, "oid");
11885 i_enumlabel = PQfnumber(res, "enumlabel");
11886
11887 /* Labels with dump-assigned (preserved) oids */
11888 for (i = 0; i < num; i++)
11889 {
11890 enum_oid = atooid(PQgetvalue(res, i, i_oid));
11891 label = PQgetvalue(res, i, i_enumlabel);
11892
11893 if (i == 0)
11894 appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
11896 "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
11897 enum_oid);
11898 appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
11899 appendStringLiteralAH(q, label, fout);
11900 appendPQExpBufferStr(q, ";\n\n");
11901 }
11902 }
11903
11904 if (dopt->binary_upgrade)
11906 "TYPE", qtypname,
11907 tyinfo->dobj.namespace->dobj.name);
11908
11909 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11910 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
11911 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
11912 .namespace = tyinfo->dobj.namespace->dobj.name,
11913 .owner = tyinfo->rolname,
11914 .description = "TYPE",
11915 .section = SECTION_PRE_DATA,
11916 .createStmt = q->data,
11917 .dropStmt = delq->data));
11918
11919 /* Dump Type Comments and Security Labels */
11920 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11921 dumpComment(fout, "TYPE", qtypname,
11922 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11923 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11924
11925 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11926 dumpSecLabel(fout, "TYPE", qtypname,
11927 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
11928 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11929
11930 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11931 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
11932 qtypname, NULL,
11933 tyinfo->dobj.namespace->dobj.name,
11934 NULL, tyinfo->rolname, &tyinfo->dacl);
11935
11936 PQclear(res);
11938 destroyPQExpBuffer(delq);
11939 destroyPQExpBuffer(query);
11940 free(qtypname);
11941 free(qualtypname);
11942}
@ 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 19019 of file pg_dump.c.

19020{
19021 DumpOptions *dopt = fout->dopt;
19022 PQExpBuffer query;
19023 PQExpBuffer delqry;
19024 char *qevtname;
19025
19026 /* Do nothing if not dumping schema */
19027 if (!dopt->dumpSchema)
19028 return;
19029
19030 query = createPQExpBuffer();
19031 delqry = createPQExpBuffer();
19032
19033 qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
19034
19035 appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
19036 appendPQExpBufferStr(query, qevtname);
19037 appendPQExpBufferStr(query, " ON ");
19038 appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
19039
19040 if (strcmp("", evtinfo->evttags) != 0)
19041 {
19042 appendPQExpBufferStr(query, "\n WHEN TAG IN (");
19043 appendPQExpBufferStr(query, evtinfo->evttags);
19044 appendPQExpBufferChar(query, ')');
19045 }
19046
19047 appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
19048 appendPQExpBufferStr(query, evtinfo->evtfname);
19049 appendPQExpBufferStr(query, "();\n");
19050
19051 if (evtinfo->evtenabled != 'O')
19052 {
19053 appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
19054 qevtname);
19055 switch (evtinfo->evtenabled)
19056 {
19057 case 'D':
19058 appendPQExpBufferStr(query, "DISABLE");
19059 break;
19060 case 'A':
19061 appendPQExpBufferStr(query, "ENABLE ALWAYS");
19062 break;
19063 case 'R':
19064 appendPQExpBufferStr(query, "ENABLE REPLICA");
19065 break;
19066 default:
19067 appendPQExpBufferStr(query, "ENABLE");
19068 break;
19069 }
19070 appendPQExpBufferStr(query, ";\n");
19071 }
19072
19073 appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
19074 qevtname);
19075
19076 if (dopt->binary_upgrade)
19077 binary_upgrade_extension_member(query, &evtinfo->dobj,
19078 "EVENT TRIGGER", qevtname, NULL);
19079
19080 if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19081 ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
19082 ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
19083 .owner = evtinfo->evtowner,
19084 .description = "EVENT TRIGGER",
19085 .section = SECTION_POST_DATA,
19086 .createStmt = query->data,
19087 .dropStmt = delqry->data));
19088
19089 if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19090 dumpComment(fout, "EVENT TRIGGER", qevtname,
19091 NULL, evtinfo->evtowner,
19092 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
19093
19094 destroyPQExpBuffer(query);
19095 destroyPQExpBuffer(delqry);
19096 free(qevtname);
19097}
char * evtevent
Definition: pg_dump.h:490
char * evtfname
Definition: pg_dump.h:493
char evtenabled
Definition: pg_dump.h:494
const char * evtowner
Definition: pg_dump.h:491
char * evttags
Definition: pg_dump.h:492
DumpableObject dobj
Definition: pg_dump.h:488

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, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, _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 11650 of file pg_dump.c.

11651{
11652 DumpOptions *dopt = fout->dopt;
11653 PQExpBuffer q;
11654 PQExpBuffer delq;
11655 char *qextname;
11656
11657 /* Do nothing if not dumping schema */
11658 if (!dopt->dumpSchema)
11659 return;
11660
11661 q = createPQExpBuffer();
11662 delq = createPQExpBuffer();
11663
11664 qextname = pg_strdup(fmtId(extinfo->dobj.name));
11665
11666 appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
11667
11668 if (!dopt->binary_upgrade)
11669 {
11670 /*
11671 * In a regular dump, we simply create the extension, intentionally
11672 * not specifying a version, so that the destination installation's
11673 * default version is used.
11674 *
11675 * Use of IF NOT EXISTS here is unlike our behavior for other object
11676 * types; but there are various scenarios in which it's convenient to
11677 * manually create the desired extension before restoring, so we
11678 * prefer to allow it to exist already.
11679 */
11680 appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
11681 qextname, fmtId(extinfo->namespace));
11682 }
11683 else
11684 {
11685 /*
11686 * In binary-upgrade mode, it's critical to reproduce the state of the
11687 * database exactly, so our procedure is to create an empty extension,
11688 * restore all the contained objects normally, and add them to the
11689 * extension one by one. This function performs just the first of
11690 * those steps. binary_upgrade_extension_member() takes care of
11691 * adding member objects as they're created.
11692 */
11693 int i;
11694 int n;
11695
11696 appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
11697
11698 /*
11699 * We unconditionally create the extension, so we must drop it if it
11700 * exists. This could happen if the user deleted 'plpgsql' and then
11701 * readded it, causing its oid to be greater than g_last_builtin_oid.
11702 */
11703 appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
11704
11706 "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
11707 appendStringLiteralAH(q, extinfo->dobj.name, fout);
11708 appendPQExpBufferStr(q, ", ");
11709 appendStringLiteralAH(q, extinfo->namespace, fout);
11710 appendPQExpBufferStr(q, ", ");
11711 appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
11712 appendStringLiteralAH(q, extinfo->extversion, fout);
11713 appendPQExpBufferStr(q, ", ");
11714
11715 /*
11716 * Note that we're pushing extconfig (an OID array) back into
11717 * pg_extension exactly as-is. This is OK because pg_class OIDs are
11718 * preserved in binary upgrade.
11719 */
11720 if (strlen(extinfo->extconfig) > 2)
11721 appendStringLiteralAH(q, extinfo->extconfig, fout);
11722 else
11723 appendPQExpBufferStr(q, "NULL");
11724 appendPQExpBufferStr(q, ", ");
11725 if (strlen(extinfo->extcondition) > 2)
11726 appendStringLiteralAH(q, extinfo->extcondition, fout);
11727 else
11728 appendPQExpBufferStr(q, "NULL");
11729 appendPQExpBufferStr(q, ", ");
11730 appendPQExpBufferStr(q, "ARRAY[");
11731 n = 0;
11732 for (i = 0; i < extinfo->dobj.nDeps; i++)
11733 {
11734 DumpableObject *extobj;
11735
11736 extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
11737 if (extobj && extobj->objType == DO_EXTENSION)
11738 {
11739 if (n++ > 0)
11740 appendPQExpBufferChar(q, ',');
11741 appendStringLiteralAH(q, extobj->name, fout);
11742 }
11743 }
11744 appendPQExpBufferStr(q, "]::pg_catalog.text[]");
11745 appendPQExpBufferStr(q, ");\n");
11746 }
11747
11748 if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11749 ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
11750 ARCHIVE_OPTS(.tag = extinfo->dobj.name,
11751 .description = "EXTENSION",
11752 .section = SECTION_PRE_DATA,
11753 .createStmt = q->data,
11754 .dropStmt = delq->data));
11755
11756 /* Dump Extension Comments and Security Labels */
11757 if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11758 dumpComment(fout, "EXTENSION", qextname,
11759 NULL, "",
11760 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
11761
11762 if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11763 dumpSecLabel(fout, "EXTENSION", qextname,
11764 NULL, "",
11765 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
11766
11767 free(qextname);
11768
11770 destroyPQExpBuffer(delq);
11771}
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, DUMP_COMPONENT_SECLABEL, dumpComment(), _dumpableObject::dumpId, _dumpOptions::dumpSchema, dumpSecLabel(), _extensionInfo::extcondition, _extensionInfo::extconfig, _extensionInfo::extversion, findObjectByDumpId(), fmtId(), free, i, _dumpableObject::name, _dumpableObject::nDeps, _dumpableObject::objType, pg_strdup(), _extensionInfo::relocatable, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

◆ dumpForeignDataWrapper()

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

Definition at line 15717 of file pg_dump.c.

15718{
15719 DumpOptions *dopt = fout->dopt;
15720 PQExpBuffer q;
15721 PQExpBuffer delq;
15722 char *qfdwname;
15723
15724 /* Do nothing if not dumping schema */
15725 if (!dopt->dumpSchema)
15726 return;
15727
15728 q = createPQExpBuffer();
15729 delq = createPQExpBuffer();
15730
15731 qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
15732
15733 appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
15734 qfdwname);
15735
15736 if (strcmp(fdwinfo->fdwhandler, "-") != 0)
15737 appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
15738
15739 if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
15740 appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
15741
15742 if (strlen(fdwinfo->fdwoptions) > 0)
15743 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
15744
15745 appendPQExpBufferStr(q, ";\n");
15746
15747 appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
15748 qfdwname);
15749
15750 if (dopt->binary_upgrade)
15752 "FOREIGN DATA WRAPPER", qfdwname,
15753 NULL);
15754
15755 if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15756 ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
15757 ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
15758 .owner = fdwinfo->rolname,
15759 .description = "FOREIGN DATA WRAPPER",
15760 .section = SECTION_PRE_DATA,
15761 .createStmt = q->data,
15762 .dropStmt = delq->data));
15763
15764 /* Dump Foreign Data Wrapper Comments */
15765 if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15766 dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
15767 NULL, fdwinfo->rolname,
15768 fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
15769
15770 /* Handle the ACL */
15771 if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
15772 dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
15773 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
15774 NULL, fdwinfo->rolname, &fdwinfo->dacl);
15775
15776 free(qfdwname);
15777
15779 destroyPQExpBuffer(delq);
15780}
char * fdwhandler
Definition: pg_dump.h:597
const char * rolname
Definition: pg_dump.h:596
char * fdwvalidator
Definition: pg_dump.h:598
char * fdwoptions
Definition: pg_dump.h:599
DumpableAcl dacl
Definition: pg_dump.h:595
DumpableObject dobj
Definition: pg_dump.h:594

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

15788{
15789 DumpOptions *dopt = fout->dopt;
15790 PQExpBuffer q;
15791 PQExpBuffer delq;
15792 PQExpBuffer query;
15793 PGresult *res;
15794 char *qsrvname;
15795 char *fdwname;
15796
15797 /* Do nothing if not dumping schema */
15798 if (!dopt->dumpSchema)
15799 return;
15800
15801 q = createPQExpBuffer();
15802 delq = createPQExpBuffer();
15803 query = createPQExpBuffer();
15804
15805 qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
15806
15807 /* look up the foreign-data wrapper */
15808 appendPQExpBuffer(query, "SELECT fdwname "
15809 "FROM pg_foreign_data_wrapper w "
15810 "WHERE w.oid = '%u'",
15811 srvinfo->srvfdw);
15812 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15813 fdwname = PQgetvalue(res, 0, 0);
15814
15815 appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
15816 if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
15817 {
15818 appendPQExpBufferStr(q, " TYPE ");
15819 appendStringLiteralAH(q, srvinfo->srvtype, fout);
15820 }
15821 if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
15822 {
15823 appendPQExpBufferStr(q, " VERSION ");
15824 appendStringLiteralAH(q, srvinfo->srvversion, fout);
15825 }
15826
15827 appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
15828 appendPQExpBufferStr(q, fmtId(fdwname));
15829
15830 if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
15831 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
15832
15833 appendPQExpBufferStr(q, ";\n");
15834
15835 appendPQExpBuffer(delq, "DROP SERVER %s;\n",
15836 qsrvname);
15837
15838 if (dopt->binary_upgrade)
15840 "SERVER", qsrvname, NULL);
15841
15842 if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15843 ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
15844 ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
15845 .owner = srvinfo->rolname,
15846 .description = "SERVER",
15847 .section = SECTION_PRE_DATA,
15848 .createStmt = q->data,
15849 .dropStmt = delq->data));
15850
15851 /* Dump Foreign Server Comments */
15852 if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15853 dumpComment(fout, "SERVER", qsrvname,
15854 NULL, srvinfo->rolname,
15855 srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
15856
15857 /* Handle the ACL */
15858 if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
15859 dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
15860 "FOREIGN SERVER", qsrvname, NULL, NULL,
15861 NULL, srvinfo->rolname, &srvinfo->dacl);
15862
15863 /* Dump user mappings */
15864 if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
15865 dumpUserMappings(fout,
15866 srvinfo->dobj.name, NULL,
15867 srvinfo->rolname,
15868 srvinfo->dobj.catId, srvinfo->dobj.dumpId);
15869
15870 PQclear(res);
15871
15872 free(qsrvname);
15873
15875 destroyPQExpBuffer(delq);
15876 destroyPQExpBuffer(query);
15877}
static void dumpUserMappings(Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
Definition: pg_dump.c:15887
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:115
DumpableAcl dacl
Definition: pg_dump.h:605
char * srvoptions
Definition: pg_dump.h:610
DumpableObject dobj
Definition: pg_dump.h:604
const char * rolname
Definition: pg_dump.h:606
char * srvversion
Definition: pg_dump.h:609

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

13119{
13120 DumpOptions *dopt = fout->dopt;
13121 PQExpBuffer query;
13122 PQExpBuffer q;
13123 PQExpBuffer delqry;
13124 PQExpBuffer asPart;
13125 PGresult *res;
13126 char *funcsig; /* identity signature */
13127 char *funcfullsig = NULL; /* full signature */
13128 char *funcsig_tag;
13129 char *qual_funcsig;
13130 char *proretset;
13131 char *prosrc;
13132 char *probin;
13133 char *prosqlbody;
13134 char *funcargs;
13135 char *funciargs;
13136 char *funcresult;
13137 char *protrftypes;
13138 char *prokind;
13139 char *provolatile;
13140 char *proisstrict;
13141 char *prosecdef;
13142 char *proleakproof;
13143 char *proconfig;
13144 char *procost;
13145 char *prorows;
13146 char *prosupport;
13147 char *proparallel;
13148 char *lanname;
13149 char **configitems = NULL;
13150 int nconfigitems = 0;
13151 const char *keyword;
13152
13153 /* Do nothing if not dumping schema */
13154 if (!dopt->dumpSchema)
13155 return;
13156
13157 query = createPQExpBuffer();
13158 q = createPQExpBuffer();
13159 delqry = createPQExpBuffer();
13160 asPart = createPQExpBuffer();
13161
13162 if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
13163 {
13164 /* Set up query for function-specific details */
13166 "PREPARE dumpFunc(pg_catalog.oid) AS\n");
13167
13169 "SELECT\n"
13170 "proretset,\n"
13171 "prosrc,\n"
13172 "probin,\n"
13173 "provolatile,\n"
13174 "proisstrict,\n"
13175 "prosecdef,\n"
13176 "lanname,\n"
13177 "proconfig,\n"
13178 "procost,\n"
13179 "prorows,\n"
13180 "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
13181 "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
13182 "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
13183 "proleakproof,\n");
13184
13185 if (fout->remoteVersion >= 90500)
13187 "array_to_string(protrftypes, ' ') AS protrftypes,\n");
13188 else
13190 "NULL AS protrftypes,\n");
13191
13192 if (fout->remoteVersion >= 90600)
13194 "proparallel,\n");
13195 else
13197 "'u' AS proparallel,\n");
13198
13199 if (fout->remoteVersion >= 110000)
13201 "prokind,\n");
13202 else
13204 "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
13205
13206 if (fout->remoteVersion >= 120000)
13208 "prosupport,\n");
13209 else
13211 "'-' AS prosupport,\n");
13212
13213 if (fout->remoteVersion >= 140000)
13215 "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
13216 else
13218 "NULL AS prosqlbody\n");
13219
13221 "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
13222 "WHERE p.oid = $1 "
13223 "AND l.oid = p.prolang");
13224
13225 ExecuteSqlStatement(fout, query->data);
13226
13227 fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
13228 }
13229
13230 printfPQExpBuffer(query,
13231 "EXECUTE dumpFunc('%u')",
13232 finfo->dobj.catId.oid);
13233
13234 res = ExecuteSqlQueryForSingleRow(fout, query->data);
13235
13236 proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
13237 if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
13238 {
13239 prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
13240 probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
13241 prosqlbody = NULL;
13242 }
13243 else
13244 {
13245 prosrc = NULL;
13246 probin = NULL;
13247 prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
13248 }
13249 funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
13250 funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
13251 funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
13252 protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
13253 prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
13254 provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
13255 proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
13256 prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
13257 proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
13258 proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
13259 procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
13260 prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
13261 prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
13262 proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
13263 lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
13264
13265 /*
13266 * See backend/commands/functioncmds.c for details of how the 'AS' clause
13267 * is used.
13268 */
13269 if (prosqlbody)
13270 {
13271 appendPQExpBufferStr(asPart, prosqlbody);
13272 }
13273 else if (probin[0] != '\0')
13274 {
13275 appendPQExpBufferStr(asPart, "AS ");
13276 appendStringLiteralAH(asPart, probin, fout);
13277 if (prosrc[0] != '\0')
13278 {
13279 appendPQExpBufferStr(asPart, ", ");
13280
13281 /*
13282 * where we have bin, use dollar quoting if allowed and src
13283 * contains quote or backslash; else use regular quoting.
13284 */
13285 if (dopt->disable_dollar_quoting ||
13286 (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
13287 appendStringLiteralAH(asPart, prosrc, fout);
13288 else
13289 appendStringLiteralDQ(asPart, prosrc, NULL);
13290 }
13291 }
13292 else
13293 {
13294 appendPQExpBufferStr(asPart, "AS ");
13295 /* with no bin, dollar quote src unconditionally if allowed */
13296 if (dopt->disable_dollar_quoting)
13297 appendStringLiteralAH(asPart, prosrc, fout);
13298 else
13299 appendStringLiteralDQ(asPart, prosrc, NULL);
13300 }
13301
13302 if (*proconfig)
13303 {
13304 if (!parsePGArray(proconfig, &configitems, &nconfigitems))
13305 pg_fatal("could not parse %s array", "proconfig");
13306 }
13307 else
13308 {
13309 configitems = NULL;
13310 nconfigitems = 0;
13311 }
13312
13313 funcfullsig = format_function_arguments(finfo, funcargs, false);
13314 funcsig = format_function_arguments(finfo, funciargs, false);
13315
13316 funcsig_tag = format_function_signature(fout, finfo, false);
13317
13318 qual_funcsig = psprintf("%s.%s",
13319 fmtId(finfo->dobj.namespace->dobj.name),
13320 funcsig);
13321
13322 if (prokind[0] == PROKIND_PROCEDURE)
13323 keyword = "PROCEDURE";
13324 else
13325 keyword = "FUNCTION"; /* works for window functions too */
13326
13327 appendPQExpBuffer(delqry, "DROP %s %s;\n",
13328 keyword, qual_funcsig);
13329
13330 appendPQExpBuffer(q, "CREATE %s %s.%s",
13331 keyword,
13332 fmtId(finfo->dobj.namespace->dobj.name),
13333 funcfullsig ? funcfullsig :
13334 funcsig);
13335
13336 if (prokind[0] == PROKIND_PROCEDURE)
13337 /* no result type to output */ ;
13338 else if (funcresult)
13339 appendPQExpBuffer(q, " RETURNS %s", funcresult);
13340 else
13341 appendPQExpBuffer(q, " RETURNS %s%s",
13342 (proretset[0] == 't') ? "SETOF " : "",
13343 getFormattedTypeName(fout, finfo->prorettype,
13344 zeroIsError));
13345
13346 appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
13347
13348 if (*protrftypes)
13349 {
13350 Oid *typeids = pg_malloc(FUNC_MAX_ARGS * sizeof(Oid));
13351 int i;
13352
13353 appendPQExpBufferStr(q, " TRANSFORM ");
13354 parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
13355 for (i = 0; typeids[i]; i++)
13356 {
13357 if (i != 0)
13358 appendPQExpBufferStr(q, ", ");
13359 appendPQExpBuffer(q, "FOR TYPE %s",
13360 getFormattedTypeName(fout, typeids[i], zeroAsNone));
13361 }
13362
13363 free(typeids);
13364 }
13365
13366 if (prokind[0] == PROKIND_WINDOW)
13367 appendPQExpBufferStr(q, " WINDOW");
13368
13369 if (provolatile[0] != PROVOLATILE_VOLATILE)
13370 {
13371 if (provolatile[0] == PROVOLATILE_IMMUTABLE)
13372 appendPQExpBufferStr(q, " IMMUTABLE");
13373 else if (provolatile[0] == PROVOLATILE_STABLE)
13374 appendPQExpBufferStr(q, " STABLE");
13375 else if (provolatile[0] != PROVOLATILE_VOLATILE)
13376 pg_fatal("unrecognized provolatile value for function \"%s\"",
13377 finfo->dobj.name);
13378 }
13379
13380 if (proisstrict[0] == 't')
13381 appendPQExpBufferStr(q, " STRICT");
13382
13383 if (prosecdef[0] == 't')
13384 appendPQExpBufferStr(q, " SECURITY DEFINER");
13385
13386 if (proleakproof[0] == 't')
13387 appendPQExpBufferStr(q, " LEAKPROOF");
13388
13389 /*
13390 * COST and ROWS are emitted only if present and not default, so as not to
13391 * break backwards-compatibility of the dump without need. Keep this code
13392 * in sync with the defaults in functioncmds.c.
13393 */
13394 if (strcmp(procost, "0") != 0)
13395 {
13396 if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
13397 {
13398 /* default cost is 1 */
13399 if (strcmp(procost, "1") != 0)
13400 appendPQExpBuffer(q, " COST %s", procost);
13401 }
13402 else
13403 {
13404 /* default cost is 100 */
13405 if (strcmp(procost, "100") != 0)
13406 appendPQExpBuffer(q, " COST %s", procost);
13407 }
13408 }
13409 if (proretset[0] == 't' &&
13410 strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
13411 appendPQExpBuffer(q, " ROWS %s", prorows);
13412
13413 if (strcmp(prosupport, "-") != 0)
13414 {
13415 /* We rely on regprocout to provide quoting and qualification */
13416 appendPQExpBuffer(q, " SUPPORT %s", prosupport);
13417 }
13418
13419 if (proparallel[0] != PROPARALLEL_UNSAFE)
13420 {
13421 if (proparallel[0] == PROPARALLEL_SAFE)
13422 appendPQExpBufferStr(q, " PARALLEL SAFE");
13423 else if (proparallel[0] == PROPARALLEL_RESTRICTED)
13424 appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
13425 else if (proparallel[0] != PROPARALLEL_UNSAFE)
13426 pg_fatal("unrecognized proparallel value for function \"%s\"",
13427 finfo->dobj.name);
13428 }
13429
13430 for (int i = 0; i < nconfigitems; i++)
13431 {
13432 /* we feel free to scribble on configitems[] here */
13433 char *configitem = configitems[i];
13434 char *pos;
13435
13436 pos = strchr(configitem, '=');
13437 if (pos == NULL)
13438 continue;
13439 *pos++ = '\0';
13440 appendPQExpBuffer(q, "\n SET %s TO ", fmtId(configitem));
13441
13442 /*
13443 * Variables that are marked GUC_LIST_QUOTE were already fully quoted
13444 * by flatten_set_variable_args() before they were put into the
13445 * proconfig array. However, because the quoting rules used there
13446 * aren't exactly like SQL's, we have to break the list value apart
13447 * and then quote the elements as string literals. (The elements may
13448 * be double-quoted as-is, but we can't just feed them to the SQL
13449 * parser; it would do the wrong thing with elements that are
13450 * zero-length or longer than NAMEDATALEN.)
13451 *
13452 * Variables that are not so marked should just be emitted as simple
13453 * string literals. If the variable is not known to
13454 * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
13455 * to use GUC_LIST_QUOTE for extension variables.
13456 */
13457 if (variable_is_guc_list_quote(configitem))
13458 {
13459 char **namelist;
13460 char **nameptr;
13461
13462 /* Parse string into list of identifiers */
13463 /* this shouldn't fail really */
13464 if (SplitGUCList(pos, ',', &namelist))
13465 {
13466 for (nameptr = namelist; *nameptr; nameptr++)
13467 {
13468 if (nameptr != namelist)
13469 appendPQExpBufferStr(q, ", ");
13470 appendStringLiteralAH(q, *nameptr, fout);
13471 }
13472 }
13473 pg_free(namelist);
13474 }
13475 else
13476 appendStringLiteralAH(q, pos, fout);
13477 }
13478
13479 appendPQExpBuffer(q, "\n %s;\n", asPart->data);
13480
13481 append_depends_on_extension(fout, q, &finfo->dobj,
13482 "pg_catalog.pg_proc", keyword,
13483 qual_funcsig);
13484
13485 if (dopt->binary_upgrade)
13487 keyword, funcsig,
13488 finfo->dobj.namespace->dobj.name);
13489
13490 if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13491 ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
13492 ARCHIVE_OPTS(.tag = funcsig_tag,
13493 .namespace = finfo->dobj.namespace->dobj.name,
13494 .owner = finfo->rolname,
13495 .description = keyword,
13496 .section = finfo->postponed_def ?
13498 .createStmt = q->data,
13499 .dropStmt = delqry->data));
13500
13501 /* Dump Function Comments and Security Labels */
13502 if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13503 dumpComment(fout, keyword, funcsig,
13504 finfo->dobj.namespace->dobj.name, finfo->rolname,
13505 finfo->dobj.catId, 0, finfo->dobj.dumpId);
13506
13507 if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
13508 dumpSecLabel(fout, keyword, funcsig,
13509 finfo->dobj.namespace->dobj.name, finfo->rolname,
13510 finfo->dobj.catId, 0, finfo->dobj.dumpId);
13511
13512 if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
13513 dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
13514 funcsig, NULL,
13515 finfo->dobj.namespace->dobj.name,
13516 NULL, finfo->rolname, &finfo->dacl);
13517
13518 PQclear(res);
13519
13520 destroyPQExpBuffer(query);
13522 destroyPQExpBuffer(delqry);
13523 destroyPQExpBuffer(asPart);
13524 free(funcsig);
13525 free(funcfullsig);
13526 free(funcsig_tag);
13527 free(qual_funcsig);
13528 free(configitems);
13529}
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1092
bool variable_is_guc_list_quote(const char *name)
Definition: dumputils.c:692
@ 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:181
bool postponed_def
Definition: pg_dump.h:246
const char * rolname
Definition: pg_dump.h:241
Oid prorettype
Definition: pg_dump.h:245
DumpableAcl dacl
Definition: pg_dump.h:240
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3773

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

17881{
17882 DumpOptions *dopt = fout->dopt;
17883 TableInfo *tbinfo = indxinfo->indextable;
17884 bool is_constraint = (indxinfo->indexconstraint != 0);
17885 PQExpBuffer q;
17886 PQExpBuffer delq;
17887 char *qindxname;
17888 char *qqindxname;
17889
17890 /* Do nothing if not dumping schema */
17891 if (!dopt->dumpSchema)
17892 return;
17893
17894 q = createPQExpBuffer();
17895 delq = createPQExpBuffer();
17896
17897 qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
17898 qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
17899
17900 /*
17901 * If there's an associated constraint, don't dump the index per se, but
17902 * do dump any comment for it. (This is safe because dependency ordering
17903 * will have ensured the constraint is emitted first.) Note that the
17904 * emitted comment has to be shown as depending on the constraint, not the
17905 * index, in such cases.
17906 */
17907 if (!is_constraint)
17908 {
17909 char *indstatcols = indxinfo->indstatcols;
17910 char *indstatvals = indxinfo->indstatvals;
17911 char **indstatcolsarray = NULL;
17912 char **indstatvalsarray = NULL;
17913 int nstatcols = 0;
17914 int nstatvals = 0;
17915
17916 if (dopt->binary_upgrade)
17918 indxinfo->dobj.catId.oid);
17919
17920 /* Plain secondary index */
17921 appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
17922
17923 /*
17924 * Append ALTER TABLE commands as needed to set properties that we
17925 * only have ALTER TABLE syntax for. Keep this in sync with the
17926 * similar code in dumpConstraint!
17927 */
17928
17929 /* If the index is clustered, we need to record that. */
17930 if (indxinfo->indisclustered)
17931 {
17932 appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
17933 fmtQualifiedDumpable(tbinfo));
17934 /* index name is not qualified in this syntax */
17935 appendPQExpBuffer(q, " ON %s;\n",
17936 qindxname);
17937 }
17938
17939 /*
17940 * If the index has any statistics on some of its columns, generate
17941 * the associated ALTER INDEX queries.
17942 */
17943 if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
17944 {
17945 int j;
17946
17947 if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
17948 pg_fatal("could not parse index statistic columns");
17949 if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
17950 pg_fatal("could not parse index statistic values");
17951 if (nstatcols != nstatvals)
17952 pg_fatal("mismatched number of columns and values for index statistics");
17953
17954 for (j = 0; j < nstatcols; j++)
17955 {
17956 appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
17957
17958 /*
17959 * Note that this is a column number, so no quotes should be
17960 * used.
17961 */
17962 appendPQExpBuffer(q, "ALTER COLUMN %s ",
17963 indstatcolsarray[j]);
17964 appendPQExpBuffer(q, "SET STATISTICS %s;\n",
17965 indstatvalsarray[j]);
17966 }
17967 }
17968
17969 /* Indexes can depend on extensions */
17970 append_depends_on_extension(fout, q, &indxinfo->dobj,
17971 "pg_catalog.pg_class",
17972 "INDEX", qqindxname);
17973
17974 /* If the index defines identity, we need to record that. */
17975 if (indxinfo->indisreplident)
17976 {
17977 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
17978 fmtQualifiedDumpable(tbinfo));
17979 /* index name is not qualified in this syntax */
17980 appendPQExpBuffer(q, " INDEX %s;\n",
17981 qindxname);
17982 }
17983
17984 /*
17985 * If this index is a member of a partitioned index, the backend will
17986 * not allow us to drop it separately, so don't try. It will go away
17987 * automatically when we drop either the index's table or the
17988 * partitioned index. (If, in a selective restore with --clean, we
17989 * drop neither of those, then this index will not be dropped either.
17990 * But that's fine, and even if you think it's not, the backend won't
17991 * let us do differently.)
17992 */
17993 if (indxinfo->parentidx == 0)
17994 appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
17995
17996 if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17997 ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
17998 ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
17999 .namespace = tbinfo->dobj.namespace->dobj.name,
18000 .tablespace = indxinfo->tablespace,
18001 .owner = tbinfo->rolname,
18002 .description = "INDEX",
18003 .section = SECTION_POST_DATA,
18004 .createStmt = q->data,
18005 .dropStmt = delq->data));
18006
18007 free(indstatcolsarray);
18008 free(indstatvalsarray);
18009 }
18010
18011 /* Dump Index Comments */
18012 if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18013 dumpComment(fout, "INDEX", qindxname,
18014 tbinfo->dobj.namespace->dobj.name,
18015 tbinfo->rolname,
18016 indxinfo->dobj.catId, 0,
18017 is_constraint ? indxinfo->indexconstraint :
18018 indxinfo->dobj.dumpId);
18019
18021 destroyPQExpBuffer(delq);
18022 free(qindxname);
18023 free(qqindxname);
18024}
char * indstatvals
Definition: pg_dump.h:418
char * indstatcols
Definition: pg_dump.h:417
TableInfo * indextable
Definition: pg_dump.h:413
Oid parentidx
Definition: pg_dump.h:426
DumpId indexconstraint
Definition: pg_dump.h:430
char * indexdef
Definition: pg_dump.h:414

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

18032{
18033 /* Do nothing if not dumping schema */
18034 if (!fout->dopt->dumpSchema)
18035 return;
18036
18038 {
18040
18041 appendPQExpBuffer(q, "ALTER INDEX %s ",
18042 fmtQualifiedDumpable(attachinfo->parentIdx));
18043 appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
18044 fmtQualifiedDumpable(attachinfo->partitionIdx));
18045
18046 /*
18047 * There is no need for a dropStmt since the drop is done implicitly
18048 * when we drop either the index's table or the partitioned index.
18049 * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
18050 * there's no way to do it anyway. (If you think to change this,
18051 * consider also what to do with --if-exists.)
18052 *
18053 * Although this object doesn't really have ownership as such, set the
18054 * owner field anyway to ensure that the command is run by the correct
18055 * role at restore time.
18056 */
18057 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18058 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18059 .namespace = attachinfo->dobj.namespace->dobj.name,
18060 .owner = attachinfo->parentIdx->indextable->rolname,
18061 .description = "INDEX ATTACH",
18062 .section = SECTION_POST_DATA,
18063 .createStmt = q->data));
18064
18066 }
18067}
IndxInfo * parentIdx
Definition: pg_dump.h:436

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

3957{
3958 PQExpBuffer cquery = createPQExpBuffer();
3959
3960 /*
3961 * The "definition" is just a newline-separated list of OIDs. We need to
3962 * put something into the dropStmt too, but it can just be a comment.
3963 */
3964 for (int i = 0; i < loinfo->numlos; i++)
3965 appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
3966
3967 if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
3968 ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
3969 ARCHIVE_OPTS(.tag = loinfo->dobj.name,
3970 .owner = loinfo->rolname,
3971 .description = "BLOB METADATA",
3972 .section = SECTION_DATA,
3973 .createStmt = cquery->data,
3974 .dropStmt = "-- dummy"));
3975
3976 /*
3977 * Dump per-blob comments and seclabels if any. We assume these are rare
3978 * enough that it's okay to generate retail TOC entries for them.
3979 */
3980 if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
3982 {
3983 for (int i = 0; i < loinfo->numlos; i++)
3984 {
3985 CatalogId catId;
3986 char namebuf[32];
3987
3988 /* Build identifying info for this blob */
3989 catId.tableoid = loinfo->dobj.catId.tableoid;
3990 catId.oid = loinfo->looids[i];
3991 snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
3992
3993 if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
3994 dumpComment(fout, "LARGE OBJECT", namebuf,
3995 NULL, loinfo->rolname,
3996 catId, 0, loinfo->dobj.dumpId);
3997
3998 if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
3999 dumpSecLabel(fout, "LARGE OBJECT", namebuf,
4000 NULL, loinfo->rolname,
4001 catId, 0, loinfo->dobj.dumpId);
4002 }
4003 }
4004
4005 /*
4006 * Dump the ACLs if any (remember that all blobs in the group will have
4007 * the same ACL). If there's just one blob, dump a simple ACL entry; if
4008 * there's more, make a "LARGE OBJECTS" entry that really contains only
4009 * the ACL for the first blob. _printTocEntry() will be cued by the tag
4010 * string to emit a mutated version for each blob.
4011 */
4012 if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
4013 {
4014 char namebuf[32];
4015
4016 /* Build identifying info for the first blob */
4017 snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
4018
4019 if (loinfo->numlos > 1)
4020 {
4021 char tagbuf[64];
4022
4023 snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
4024 loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
4025
4026 dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
4027 "LARGE OBJECT", namebuf, NULL, NULL,
4028 tagbuf, loinfo->rolname, &loinfo->dacl);
4029 }
4030 else
4031 {
4032 dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
4033 "LARGE OBJECT", namebuf, NULL, NULL,
4034 NULL, loinfo->rolname, &loinfo->dacl);
4035 }
4036 }
4037
4038 destroyPQExpBuffer(cquery);
4039}
DumpableObject dobj
Definition: pg_dump.h:631
DumpableAcl dacl
Definition: pg_dump.h:632
Oid looids[FLEXIBLE_ARRAY_MEMBER]
Definition: pg_dump.h:635

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

4047{
4048 const LoInfo *loinfo = (const LoInfo *) arg;
4049 PGconn *conn = GetConnection(fout);
4050 char buf[LOBBUFSIZE];
4051
4052 pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
4053
4054 for (int i = 0; i < loinfo->numlos; i++)
4055 {
4056 Oid loOid = loinfo->looids[i];
4057 int loFd;
4058 int cnt;
4059
4060 /* Open the LO */
4061 loFd = lo_open(conn, loOid, INV_READ);
4062 if (loFd == -1)
4063 pg_fatal("could not open large object %u: %s",
4064 loOid, PQerrorMessage(conn));
4065
4066 StartLO(fout, loOid);
4067
4068 /* Now read it in chunks, sending data to archive */
4069 do
4070 {
4071 cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
4072 if (cnt < 0)
4073 pg_fatal("error reading large object %u: %s",
4074 loOid, PQerrorMessage(conn));
4075
4076 WriteData(fout, buf, cnt);
4077 } while (cnt > 0);
4078
4079 lo_close(conn, loFd);
4080
4081 EndLO(fout, loOid);
4082 }
4083
4084 return 1;
4085}
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:154
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7629
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 11573 of file pg_dump.c.

11574{
11575 DumpOptions *dopt = fout->dopt;
11576 PQExpBuffer q;
11577 PQExpBuffer delq;
11578 char *qnspname;
11579
11580 /* Do nothing if not dumping schema */
11581 if (!dopt->dumpSchema)
11582 return;
11583
11584 q = createPQExpBuffer();
11585 delq = createPQExpBuffer();
11586
11587 qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
11588
11589 if (nspinfo->create)
11590 {
11591 appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
11592 appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
11593 }
11594 else
11595 {
11596 /* see selectDumpableNamespace() */
11598 "-- *not* dropping schema, since initdb creates it\n");
11600 "-- *not* creating schema, since initdb creates it\n");
11601 }
11602
11603 if (dopt->binary_upgrade)
11605 "SCHEMA", qnspname, NULL);
11606
11607 if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11608 ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
11609 ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
11610 .owner = nspinfo->rolname,
11611 .description = "SCHEMA",
11612 .section = SECTION_PRE_DATA,
11613 .createStmt = q->data,
11614 .dropStmt = delq->data));
11615
11616 /* Dump Schema Comments and Security Labels */
11617 if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11618 {
11619 const char *initdb_comment = NULL;
11620
11621 if (!nspinfo->create && strcmp(qnspname, "public") == 0)
11622 initdb_comment = "standard public schema";
11623 dumpCommentExtended(fout, "SCHEMA", qnspname,
11624 NULL, nspinfo->rolname,
11625 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
11626 initdb_comment);
11627 }
11628
11629 if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11630 dumpSecLabel(fout, "SCHEMA", qnspname,
11631 NULL, nspinfo->rolname,
11632 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
11633
11634 if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
11635 dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
11636 qnspname, NULL, NULL,
11637 NULL, nspinfo->rolname, &nspinfo->dacl);
11638
11639 free(qnspname);
11640
11642 destroyPQExpBuffer(delq);
11643}
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 14150 of file pg_dump.c.

14151{
14152 DumpOptions *dopt = fout->dopt;
14153 PQExpBuffer query;
14154 PQExpBuffer q;
14155 PQExpBuffer delq;
14156 PQExpBuffer nameusing;
14157 PGresult *res;
14158 int ntups;
14159 int i_opcintype;
14160 int i_opckeytype;
14161 int i_opcdefault;
14162 int i_opcfamily;
14163 int i_opcfamilyname;
14164 int i_opcfamilynsp;
14165 int i_amname;
14166 int i_amopstrategy;
14167 int i_amopopr;
14168 int i_sortfamily;
14169 int i_sortfamilynsp;
14170 int i_amprocnum;
14171 int i_amproc;
14172 int i_amproclefttype;
14173 int i_amprocrighttype;
14174 char *opcintype;
14175 char *opckeytype;
14176 char *opcdefault;
14177 char *opcfamily;
14178 char *opcfamilyname;
14179 char *opcfamilynsp;
14180 char *amname;
14181 char *amopstrategy;
14182 char *amopopr;
14183 char *sortfamily;
14184 char *sortfamilynsp;
14185 char *amprocnum;
14186 char *amproc;
14187 char *amproclefttype;
14188 char *amprocrighttype;
14189 bool needComma;
14190 int i;
14191
14192 /* Do nothing if not dumping schema */
14193 if (!dopt->dumpSchema)
14194 return;
14195
14196 query = createPQExpBuffer();
14197 q = createPQExpBuffer();
14198 delq = createPQExpBuffer();
14199 nameusing = createPQExpBuffer();
14200
14201 /* Get additional fields from the pg_opclass row */
14202 appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
14203 "opckeytype::pg_catalog.regtype, "
14204 "opcdefault, opcfamily, "
14205 "opfname AS opcfamilyname, "
14206 "nspname AS opcfamilynsp, "
14207 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
14208 "FROM pg_catalog.pg_opclass c "
14209 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
14210 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
14211 "WHERE c.oid = '%u'::pg_catalog.oid",
14212 opcinfo->dobj.catId.oid);
14213
14214 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14215
14216 i_opcintype = PQfnumber(res, "opcintype");
14217 i_opckeytype = PQfnumber(res, "opckeytype");
14218 i_opcdefault = PQfnumber(res, "opcdefault");
14219 i_opcfamily = PQfnumber(res, "opcfamily");
14220 i_opcfamilyname = PQfnumber(res, "opcfamilyname");
14221 i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
14222 i_amname = PQfnumber(res, "amname");
14223
14224 /* opcintype may still be needed after we PQclear res */
14225 opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
14226 opckeytype = PQgetvalue(res, 0, i_opckeytype);
14227 opcdefault = PQgetvalue(res, 0, i_opcdefault);
14228 /* opcfamily will still be needed after we PQclear res */
14229 opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
14230 opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
14231 opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
14232 /* amname will still be needed after we PQclear res */
14233 amname = pg_strdup(PQgetvalue(res, 0, i_amname));
14234
14235 appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
14236 fmtQualifiedDumpable(opcinfo));
14237 appendPQExpBuffer(delq, " USING %s;\n",
14238 fmtId(amname));
14239
14240 /* Build the fixed portion of the CREATE command */
14241 appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n ",
14242 fmtQualifiedDumpable(opcinfo));
14243 if (strcmp(opcdefault, "t") == 0)
14244 appendPQExpBufferStr(q, "DEFAULT ");
14245 appendPQExpBuffer(q, "FOR TYPE %s USING %s",
14246 opcintype,
14247 fmtId(amname));
14248 if (strlen(opcfamilyname) > 0)
14249 {
14250 appendPQExpBufferStr(q, " FAMILY ");
14251 appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
14252 appendPQExpBufferStr(q, fmtId(opcfamilyname));
14253 }
14254 appendPQExpBufferStr(q, " AS\n ");
14255
14256 needComma = false;
14257
14258 if (strcmp(opckeytype, "-") != 0)
14259 {
14260 appendPQExpBuffer(q, "STORAGE %s",
14261 opckeytype);
14262 needComma = true;
14263 }
14264
14265 PQclear(res);
14266
14267 /*
14268 * Now fetch and print the OPERATOR entries (pg_amop rows).
14269 *
14270 * Print only those opfamily members that are tied to the opclass by
14271 * pg_depend entries.
14272 */
14273 resetPQExpBuffer(query);
14274 appendPQExpBuffer(query, "SELECT amopstrategy, "
14275 "amopopr::pg_catalog.regoperator, "
14276 "opfname AS sortfamily, "
14277 "nspname AS sortfamilynsp "
14278 "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
14279 "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
14280 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
14281 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
14282 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
14283 "AND refobjid = '%u'::pg_catalog.oid "
14284 "AND amopfamily = '%s'::pg_catalog.oid "
14285 "ORDER BY amopstrategy",
14286 opcinfo->dobj.catId.oid,
14287 opcfamily);
14288
14289 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14290
14291 ntups = PQntuples(res);
14292
14293 i_amopstrategy = PQfnumber(res, "amopstrategy");
14294 i_amopopr = PQfnumber(res, "amopopr");
14295 i_sortfamily = PQfnumber(res, "sortfamily");
14296 i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
14297
14298 for (i = 0; i < ntups; i++)
14299 {
14300 amopstrategy = PQgetvalue(res, i, i_amopstrategy);
14301 amopopr = PQgetvalue(res, i, i_amopopr);
14302 sortfamily = PQgetvalue(res, i, i_sortfamily);
14303 sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
14304
14305 if (needComma)
14306 appendPQExpBufferStr(q, " ,\n ");
14307
14308 appendPQExpBuffer(q, "OPERATOR %s %s",
14309 amopstrategy, amopopr);
14310
14311 if (strlen(sortfamily) > 0)
14312 {
14313 appendPQExpBufferStr(q, " FOR ORDER BY ");
14314 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
14315 appendPQExpBufferStr(q, fmtId(sortfamily));
14316 }
14317
14318 needComma = true;
14319 }
14320
14321 PQclear(res);
14322
14323 /*
14324 * Now fetch and print the FUNCTION entries (pg_amproc rows).
14325 *
14326 * Print only those opfamily members that are tied to the opclass by
14327 * pg_depend entries.
14328 *
14329 * We print the amproclefttype/amprocrighttype even though in most cases
14330 * the backend could deduce the right values, because of the corner case
14331 * of a btree sort support function for a cross-type comparison.
14332 */
14333 resetPQExpBuffer(query);
14334
14335 appendPQExpBuffer(query, "SELECT amprocnum, "
14336 "amproc::pg_catalog.regprocedure, "
14337 "amproclefttype::pg_catalog.regtype, "
14338 "amprocrighttype::pg_catalog.regtype "
14339 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
14340 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
14341 "AND refobjid = '%u'::pg_catalog.oid "
14342 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
14343 "AND objid = ap.oid "
14344 "ORDER BY amprocnum",
14345 opcinfo->dobj.catId.oid);
14346
14347 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14348
14349 ntups = PQntuples(res);
14350
14351 i_amprocnum = PQfnumber(res, "amprocnum");
14352 i_amproc = PQfnumber(res, "amproc");
14353 i_amproclefttype = PQfnumber(res, "amproclefttype");
14354 i_amprocrighttype = PQfnumber(res, "amprocrighttype");
14355
14356 for (i = 0; i < ntups; i++)
14357 {
14358 amprocnum = PQgetvalue(res, i, i_amprocnum);
14359 amproc = PQgetvalue(res, i, i_amproc);
14360 amproclefttype = PQgetvalue(res, i, i_amproclefttype);
14361 amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
14362
14363 if (needComma)
14364 appendPQExpBufferStr(q, " ,\n ");
14365
14366 appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
14367
14368 if (*amproclefttype && *amprocrighttype)
14369 appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
14370
14371 appendPQExpBuffer(q, " %s", amproc);
14372
14373 needComma = true;
14374 }
14375
14376 PQclear(res);
14377
14378 /*
14379 * If needComma is still false it means we haven't added anything after
14380 * the AS keyword. To avoid printing broken SQL, append a dummy STORAGE
14381 * clause with the same datatype. This isn't sanctioned by the
14382 * documentation, but actually DefineOpClass will treat it as a no-op.
14383 */
14384 if (!needComma)
14385 appendPQExpBuffer(q, "STORAGE %s", opcintype);
14386
14387 appendPQExpBufferStr(q, ";\n");
14388
14389 appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
14390 appendPQExpBuffer(nameusing, " USING %s",
14391 fmtId(amname));
14392
14393 if (dopt->binary_upgrade)
14395 "OPERATOR CLASS", nameusing->data,
14396 opcinfo->dobj.namespace->dobj.name);
14397
14398 if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14399 ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
14400 ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
14401 .namespace = opcinfo->dobj.namespace->dobj.name,
14402 .owner = opcinfo->rolname,
14403 .description = "OPERATOR CLASS",
14404 .section = SECTION_PRE_DATA,
14405 .createStmt = q->data,
14406 .dropStmt = delq->data));
14407
14408 /* Dump Operator Class Comments */
14409 if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14410 dumpComment(fout, "OPERATOR CLASS", nameusing->data,
14411 opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
14412 opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
14413
14414 free(opcintype);
14415 free(opcfamily);
14416 free(amname);
14417 destroyPQExpBuffer(query);
14419 destroyPQExpBuffer(delq);
14420 destroyPQExpBuffer(nameusing);
14421}
DumpableObject dobj
Definition: pg_dump.h:273
const char * rolname
Definition: pg_dump.h:274

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

14432{
14433 DumpOptions *dopt = fout->dopt;
14434 PQExpBuffer query;
14435 PQExpBuffer q;
14436 PQExpBuffer delq;
14437 PQExpBuffer nameusing;
14438 PGresult *res;
14439 PGresult *res_ops;
14440 PGresult *res_procs;
14441 int ntups;
14442 int i_amname;
14443 int i_amopstrategy;
14444 int i_amopopr;
14445 int i_sortfamily;
14446 int i_sortfamilynsp;
14447 int i_amprocnum;
14448 int i_amproc;
14449 int i_amproclefttype;
14450 int i_amprocrighttype;
14451 char *amname;
14452 char *amopstrategy;
14453 char *amopopr;
14454 char *sortfamily;
14455 char *sortfamilynsp;
14456 char *amprocnum;
14457 char *amproc;
14458 char *amproclefttype;
14459 char *amprocrighttype;
14460 bool needComma;
14461 int i;
14462
14463 /* Do nothing if not dumping schema */
14464 if (!dopt->dumpSchema)
14465 return;
14466
14467 query = createPQExpBuffer();
14468 q = createPQExpBuffer();
14469 delq = createPQExpBuffer();
14470 nameusing = createPQExpBuffer();
14471
14472 /*
14473 * Fetch only those opfamily members that are tied directly to the
14474 * opfamily by pg_depend entries.
14475 */
14476 appendPQExpBuffer(query, "SELECT amopstrategy, "
14477 "amopopr::pg_catalog.regoperator, "
14478 "opfname AS sortfamily, "
14479 "nspname AS sortfamilynsp "
14480 "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
14481 "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
14482 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
14483 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
14484 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
14485 "AND refobjid = '%u'::pg_catalog.oid "
14486 "AND amopfamily = '%u'::pg_catalog.oid "
14487 "ORDER BY amopstrategy",
14488 opfinfo->dobj.catId.oid,
14489 opfinfo->dobj.catId.oid);
14490
14491 res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14492
14493 resetPQExpBuffer(query);
14494
14495 appendPQExpBuffer(query, "SELECT amprocnum, "
14496 "amproc::pg_catalog.regprocedure, "
14497 "amproclefttype::pg_catalog.regtype, "
14498 "amprocrighttype::pg_catalog.regtype "
14499 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
14500 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
14501 "AND refobjid = '%u'::pg_catalog.oid "
14502 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
14503 "AND objid = ap.oid "
14504 "ORDER BY amprocnum",
14505 opfinfo->dobj.catId.oid);
14506
14507 res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
14508
14509 /* Get additional fields from the pg_opfamily row */
14510 resetPQExpBuffer(query);
14511
14512 appendPQExpBuffer(query, "SELECT "
14513 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
14514 "FROM pg_catalog.pg_opfamily "
14515 "WHERE oid = '%u'::pg_catalog.oid",
14516 opfinfo->dobj.catId.oid);
14517
14518 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14519
14520 i_amname = PQfnumber(res, "amname");
14521
14522 /* amname will still be needed after we PQclear res */
14523 amname = pg_strdup(PQgetvalue(res, 0, i_amname));
14524
14525 appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
14526 fmtQualifiedDumpable(opfinfo));
14527 appendPQExpBuffer(delq, " USING %s;\n",
14528 fmtId(amname));
14529
14530 /* Build the fixed portion of the CREATE command */
14531 appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
14532 fmtQualifiedDumpable(opfinfo));
14533 appendPQExpBuffer(q, " USING %s;\n",
14534 fmtId(amname));
14535
14536 PQclear(res);
14537
14538 /* Do we need an ALTER to add loose members? */
14539 if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
14540 {
14541 appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
14542 fmtQualifiedDumpable(opfinfo));
14543 appendPQExpBuffer(q, " USING %s ADD\n ",
14544 fmtId(amname));
14545
14546 needComma = false;
14547
14548 /*
14549 * Now fetch and print the OPERATOR entries (pg_amop rows).
14550 */
14551 ntups = PQntuples(res_ops);
14552
14553 i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
14554 i_amopopr = PQfnumber(res_ops, "amopopr");
14555 i_sortfamily = PQfnumber(res_ops, "sortfamily");
14556 i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
14557
14558 for (i = 0; i < ntups; i++)
14559 {
14560 amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
14561 amopopr = PQgetvalue(res_ops, i, i_amopopr);
14562 sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
14563 sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
14564
14565 if (needComma)
14566 appendPQExpBufferStr(q, " ,\n ");
14567
14568 appendPQExpBuffer(q, "OPERATOR %s %s",
14569 amopstrategy, amopopr);
14570
14571 if (strlen(sortfamily) > 0)
14572 {
14573 appendPQExpBufferStr(q, " FOR ORDER BY ");
14574 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
14575 appendPQExpBufferStr(q, fmtId(sortfamily));
14576 }
14577
14578 needComma = true;
14579 }
14580
14581 /*
14582 * Now fetch and print the FUNCTION entries (pg_amproc rows).
14583 */
14584 ntups = PQntuples(res_procs);
14585
14586 i_amprocnum = PQfnumber(res_procs, "amprocnum");
14587 i_amproc = PQfnumber(res_procs, "amproc");
14588 i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
14589 i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
14590
14591 for (i = 0; i < ntups; i++)
14592 {
14593 amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
14594 amproc = PQgetvalue(res_procs, i, i_amproc);
14595 amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
14596 amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
14597
14598 if (needComma)
14599 appendPQExpBufferStr(q, " ,\n ");
14600
14601 appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
14602 amprocnum, amproclefttype, amprocrighttype,
14603 amproc);
14604
14605 needComma = true;
14606 }
14607
14608 appendPQExpBufferStr(q, ";\n");
14609 }
14610
14611 appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
14612 appendPQExpBuffer(nameusing, " USING %s",
14613 fmtId(amname));
14614
14615 if (dopt->binary_upgrade)
14617 "OPERATOR FAMILY", nameusing->data,
14618 opfinfo->dobj.namespace->dobj.name);
14619
14620 if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14621 ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
14622 ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
14623 .namespace = opfinfo->dobj.namespace->dobj.name,
14624 .owner = opfinfo->rolname,
14625 .description = "OPERATOR FAMILY",
14626 .section = SECTION_PRE_DATA,
14627 .createStmt = q->data,
14628 .dropStmt = delq->data));
14629
14630 /* Dump Operator Family Comments */
14631 if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14632 dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
14633 opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
14634 opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
14635
14636 free(amname);
14637 PQclear(res_ops);
14638 PQclear(res_procs);
14639 destroyPQExpBuffer(query);
14641 destroyPQExpBuffer(delq);
14642 destroyPQExpBuffer(nameusing);
14643}
const char * rolname
Definition: pg_dump.h:280
DumpableObject dobj
Definition: pg_dump.h:279

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

13771{
13772 DumpOptions *dopt = fout->dopt;
13773 PQExpBuffer query;
13774 PQExpBuffer q;
13775 PQExpBuffer delq;
13777 PQExpBuffer details;
13778 PGresult *res;
13779 int i_oprkind;
13780 int i_oprcode;
13781 int i_oprleft;
13782 int i_oprright;
13783 int i_oprcom;
13784 int i_oprnegate;
13785 int i_oprrest;
13786 int i_oprjoin;
13787 int i_oprcanmerge;
13788 int i_oprcanhash;
13789 char *oprkind;
13790 char *oprcode;
13791 char *oprleft;
13792 char *oprright;
13793 char *oprcom;
13794 char *oprnegate;
13795 char *oprrest;
13796 char *oprjoin;
13797 char *oprcanmerge;
13798 char *oprcanhash;
13799 char *oprregproc;
13800 char *oprref;
13801
13802 /* Do nothing if not dumping schema */
13803 if (!dopt->dumpSchema)
13804 return;
13805
13806 /*
13807 * some operators are invalid because they were the result of user
13808 * defining operators before commutators exist
13809 */
13810 if (!OidIsValid(oprinfo->oprcode))
13811 return;
13812
13813 query = createPQExpBuffer();
13814 q = createPQExpBuffer();
13815 delq = createPQExpBuffer();
13817 details = createPQExpBuffer();
13818
13819 if (!fout->is_prepared[PREPQUERY_DUMPOPR])
13820 {
13821 /* Set up query for operator-specific details */
13823 "PREPARE dumpOpr(pg_catalog.oid) AS\n"
13824 "SELECT oprkind, "
13825 "oprcode::pg_catalog.regprocedure, "
13826 "oprleft::pg_catalog.regtype, "
13827 "oprright::pg_catalog.regtype, "
13828 "oprcom, "
13829 "oprnegate, "
13830 "oprrest::pg_catalog.regprocedure, "
13831 "oprjoin::pg_catalog.regprocedure, "
13832 "oprcanmerge, oprcanhash "
13833 "FROM pg_catalog.pg_operator "
13834 "WHERE oid = $1");
13835
13836 ExecuteSqlStatement(fout, query->data);
13837
13838 fout->is_prepared[PREPQUERY_DUMPOPR] = true;
13839 }
13840
13841 printfPQExpBuffer(query,
13842 "EXECUTE dumpOpr('%u')",
13843 oprinfo->dobj.catId.oid);
13844
13845 res = ExecuteSqlQueryForSingleRow(fout, query->data);
13846
13847 i_oprkind = PQfnumber(res, "oprkind");
13848 i_oprcode = PQfnumber(res, "oprcode");
13849 i_oprleft = PQfnumber(res, "oprleft");
13850 i_oprright = PQfnumber(res, "oprright");
13851 i_oprcom = PQfnumber(res, "oprcom");
13852 i_oprnegate = PQfnumber(res, "oprnegate");
13853 i_oprrest = PQfnumber(res, "oprrest");
13854 i_oprjoin = PQfnumber(res, "oprjoin");
13855 i_oprcanmerge = PQfnumber(res, "oprcanmerge");
13856 i_oprcanhash = PQfnumber(res, "oprcanhash");
13857
13858 oprkind = PQgetvalue(res, 0, i_oprkind);
13859 oprcode = PQgetvalue(res, 0, i_oprcode);
13860 oprleft = PQgetvalue(res, 0, i_oprleft);
13861 oprright = PQgetvalue(res, 0, i_oprright);
13862 oprcom = PQgetvalue(res, 0, i_oprcom);
13863 oprnegate = PQgetvalue(res, 0, i_oprnegate);
13864 oprrest = PQgetvalue(res, 0, i_oprrest);
13865 oprjoin = PQgetvalue(res, 0, i_oprjoin);
13866 oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
13867 oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
13868
13869 /* In PG14 upwards postfix operator support does not exist anymore. */
13870 if (strcmp(oprkind, "r") == 0)
13871 pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
13872 oprcode);
13873
13874 oprregproc = convertRegProcReference(oprcode);
13875 if (oprregproc)
13876 {
13877 appendPQExpBuffer(details, " FUNCTION = %s", oprregproc);
13878 free(oprregproc);
13879 }
13880
13881 appendPQExpBuffer(oprid, "%s (",
13882 oprinfo->dobj.name);
13883
13884 /*
13885 * right unary means there's a left arg and left unary means there's a
13886 * right arg. (Although the "r" case is dead code for PG14 and later,
13887 * continue to support it in case we're dumping from an old server.)
13888 */
13889 if (strcmp(oprkind, "r") == 0 ||
13890 strcmp(oprkind, "b") == 0)
13891 {
13892 appendPQExpBuffer(details, ",\n LEFTARG = %s", oprleft);
13893 appendPQExpBufferStr(oprid, oprleft);
13894 }
13895 else
13896 appendPQExpBufferStr(oprid, "NONE");
13897
13898 if (strcmp(oprkind, "l") == 0 ||
13899 strcmp(oprkind, "b") == 0)
13900 {
13901 appendPQExpBuffer(details, ",\n RIGHTARG = %s", oprright);
13902 appendPQExpBuffer(oprid, ", %s)", oprright);
13903 }
13904 else
13905 appendPQExpBufferStr(oprid, ", NONE)");
13906
13907 oprref = getFormattedOperatorName(oprcom);
13908 if (oprref)
13909 {
13910 appendPQExpBuffer(details, ",\n COMMUTATOR = %s", oprref);
13911 free(oprref);
13912 }
13913
13914 oprref = getFormattedOperatorName(oprnegate);
13915 if (oprref)
13916 {
13917 appendPQExpBuffer(details, ",\n NEGATOR = %s", oprref);
13918 free(oprref);
13919 }
13920
13921 if (strcmp(oprcanmerge, "t") == 0)
13922 appendPQExpBufferStr(details, ",\n MERGES");
13923
13924 if (strcmp(oprcanhash, "t") == 0)
13925 appendPQExpBufferStr(details, ",\n HASHES");
13926
13927 oprregproc = convertRegProcReference(oprrest);
13928 if (oprregproc)
13929 {
13930 appendPQExpBuffer(details, ",\n RESTRICT = %s", oprregproc);
13931 free(oprregproc);
13932 }
13933
13934 oprregproc = convertRegProcReference(oprjoin);
13935 if (oprregproc)
13936 {
13937 appendPQExpBuffer(details, ",\n JOIN = %s", oprregproc);
13938 free(oprregproc);
13939 }
13940
13941 appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
13942 fmtId(oprinfo->dobj.namespace->dobj.name),
13943 oprid->data);
13944
13945 appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
13946 fmtId(oprinfo->dobj.namespace->dobj.name),
13947 oprinfo->dobj.name, details->data);
13948
13949 if (dopt->binary_upgrade)
13951 "OPERATOR", oprid->data,
13952 oprinfo->dobj.namespace->dobj.name);
13953
13954 if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
13955 ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
13956 ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
13957 .namespace = oprinfo->dobj.namespace->dobj.name,
13958 .owner = oprinfo->rolname,
13959 .description = "OPERATOR",
13960 .section = SECTION_PRE_DATA,
13961 .createStmt = q->data,
13962 .dropStmt = delq->data));
13963
13964 /* Dump Operator Comments */
13965 if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
13966 dumpComment(fout, "OPERATOR", oprid->data,
13967 oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
13968 oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
13969
13970 PQclear(res);
13971
13972 destroyPQExpBuffer(query);
13974 destroyPQExpBuffer(delq);
13976 destroyPQExpBuffer(details);
13977}
Oid oprid(Operator op)
Definition: parse_oper.c:238
@ PREPQUERY_DUMPOPR
Definition: pg_backup.h:72
static char * convertRegProcReference(const char *proc)
Definition: pg_dump.c:13989
DumpableObject dobj
Definition: pg_dump.h:258
Oid oprcode
Definition: pg_dump.h:261
const char * rolname
Definition: pg_dump.h:259

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

4265{
4266 DumpOptions *dopt = fout->dopt;
4267 TableInfo *tbinfo = polinfo->poltable;
4268 PQExpBuffer query;
4269 PQExpBuffer delqry;
4270 PQExpBuffer polprefix;
4271 char *qtabname;
4272 const char *cmd;
4273 char *tag;
4274
4275 /* Do nothing if not dumping schema */
4276 if (!dopt->dumpSchema)
4277 return;
4278
4279 /*
4280 * If polname is NULL, then this record is just indicating that ROW LEVEL
4281 * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
4282 * ROW LEVEL SECURITY.
4283 */
4284 if (polinfo->polname == NULL)
4285 {
4286 query = createPQExpBuffer();
4287
4288 appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
4289 fmtQualifiedDumpable(tbinfo));
4290
4291 /*
4292 * We must emit the ROW SECURITY object's dependency on its table
4293 * explicitly, because it will not match anything in pg_depend (unlike
4294 * the case for other PolicyInfo objects).
4295 */
4296 if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4297 ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4298 ARCHIVE_OPTS(.tag = polinfo->dobj.name,
4299 .namespace = polinfo->dobj.namespace->dobj.name,
4300 .owner = tbinfo->rolname,
4301 .description = "ROW SECURITY",
4302 .section = SECTION_POST_DATA,
4303 .createStmt = query->data,
4304 .deps = &(tbinfo->dobj.dumpId),
4305 .nDeps = 1));
4306
4307 destroyPQExpBuffer(query);
4308 return;
4309 }
4310
4311 if (polinfo->polcmd == '*')
4312 cmd = "";
4313 else if (polinfo->polcmd == 'r')
4314 cmd = " FOR SELECT";
4315 else if (polinfo->polcmd == 'a')
4316 cmd = " FOR INSERT";
4317 else if (polinfo->polcmd == 'w')
4318 cmd = " FOR UPDATE";
4319 else if (polinfo->polcmd == 'd')
4320 cmd = " FOR DELETE";
4321 else
4322 pg_fatal("unexpected policy command type: %c",
4323 polinfo->polcmd);
4324
4325 query = createPQExpBuffer();
4326 delqry = createPQExpBuffer();
4327 polprefix = createPQExpBuffer();
4328
4329 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
4330
4331 appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
4332
4333 appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
4334 !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
4335
4336 if (polinfo->polroles != NULL)
4337 appendPQExpBuffer(query, " TO %s", polinfo->polroles);
4338
4339 if (polinfo->polqual != NULL)
4340 appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
4341
4342 if (polinfo->polwithcheck != NULL)
4343 appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
4344
4345 appendPQExpBufferStr(query, ";\n");
4346
4347 appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
4348 appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
4349
4350 appendPQExpBuffer(polprefix, "POLICY %s ON",
4351 fmtId(polinfo->polname));
4352
4353 tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
4354
4355 if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4356 ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
4357 ARCHIVE_OPTS(.tag = tag,
4358 .namespace = polinfo->dobj.namespace->dobj.name,
4359 .owner = tbinfo->rolname,
4360 .description = "POLICY",
4361 .section = SECTION_POST_DATA,
4362 .createStmt = query->data,
4363 .dropStmt = delqry->data));
4364
4365 if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4366 dumpComment(fout, polprefix->data, qtabname,
4367 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
4368 polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
4369
4370 free(tag);
4371 destroyPQExpBuffer(query);
4372 destroyPQExpBuffer(delqry);
4373 destroyPQExpBuffer(polprefix);
4374 free(qtabname);
4375}
TableInfo * poltable
Definition: pg_dump.h:647
char * polqual
Definition: pg_dump.h:652
char polcmd
Definition: pg_dump.h:649
char * polroles
Definition: pg_dump.h:651
char * polwithcheck
Definition: pg_dump.h:653
DumpableObject dobj
Definition: pg_dump.h:646
bool polpermissive
Definition: pg_dump.h:650
char * polname
Definition: pg_dump.h:648

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

12935{
12936 DumpOptions *dopt = fout->dopt;
12937 PQExpBuffer defqry;
12938 PQExpBuffer delqry;
12939 bool useParams;
12940 char *qlanname;
12941 FuncInfo *funcInfo;
12942 FuncInfo *inlineInfo = NULL;
12943 FuncInfo *validatorInfo = NULL;
12944
12945 /* Do nothing if not dumping schema */
12946 if (!dopt->dumpSchema)
12947 return;
12948
12949 /*
12950 * Try to find the support function(s). It is not an error if we don't
12951 * find them --- if the functions are in the pg_catalog schema, as is
12952 * standard in 8.1 and up, then we won't have loaded them. (In this case
12953 * we will emit a parameterless CREATE LANGUAGE command, which will
12954 * require PL template knowledge in the backend to reload.)
12955 */
12956
12957 funcInfo = findFuncByOid(plang->lanplcallfoid);
12958 if (funcInfo != NULL && !funcInfo->dobj.dump)
12959 funcInfo = NULL; /* treat not-dumped same as not-found */
12960
12961 if (OidIsValid(plang->laninline))
12962 {
12963 inlineInfo = findFuncByOid(plang->laninline);
12964 if (inlineInfo != NULL && !inlineInfo->dobj.dump)
12965 inlineInfo = NULL;
12966 }
12967
12968 if (OidIsValid(plang->lanvalidator))
12969 {
12970 validatorInfo = findFuncByOid(plang->lanvalidator);
12971 if (validatorInfo != NULL && !validatorInfo->dobj.dump)
12972 validatorInfo = NULL;
12973 }
12974
12975 /*
12976 * If the functions are dumpable then emit a complete CREATE LANGUAGE with
12977 * parameters. Otherwise, we'll write a parameterless command, which will
12978 * be interpreted as CREATE EXTENSION.
12979 */
12980 useParams = (funcInfo != NULL &&
12981 (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
12982 (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
12983
12984 defqry = createPQExpBuffer();
12985 delqry = createPQExpBuffer();
12986
12987 qlanname = pg_strdup(fmtId(plang->dobj.name));
12988
12989 appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
12990 qlanname);
12991
12992 if (useParams)
12993 {
12994 appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
12995 plang->lanpltrusted ? "TRUSTED " : "",
12996 qlanname);
12997 appendPQExpBuffer(defqry, " HANDLER %s",
12998 fmtQualifiedDumpable(funcInfo));
12999 if (OidIsValid(plang->laninline))
13000 appendPQExpBuffer(defqry, " INLINE %s",
13001 fmtQualifiedDumpable(inlineInfo));
13002 if (OidIsValid(plang->lanvalidator))
13003 appendPQExpBuffer(defqry, " VALIDATOR %s",
13004 fmtQualifiedDumpable(validatorInfo));
13005 }
13006 else
13007 {
13008 /*
13009 * If not dumping parameters, then use CREATE OR REPLACE so that the
13010 * command will not fail if the language is preinstalled in the target
13011 * database.
13012 *
13013 * Modern servers will interpret this as CREATE EXTENSION IF NOT
13014 * EXISTS; perhaps we should emit that instead? But it might just add
13015 * confusion.
13016 */
13017 appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
13018 qlanname);
13019 }
13020 appendPQExpBufferStr(defqry, ";\n");
13021
13022 if (dopt->binary_upgrade)
13023 binary_upgrade_extension_member(defqry, &plang->dobj,
13024 "LANGUAGE", qlanname, NULL);
13025
13026 if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
13027 ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
13028 ARCHIVE_OPTS(.tag = plang->dobj.name,
13029 .owner = plang->lanowner,
13030 .description = "PROCEDURAL LANGUAGE",
13031 .section = SECTION_PRE_DATA,
13032 .createStmt = defqry->data,
13033 .dropStmt = delqry->data,
13034 ));
13035
13036 /* Dump Proc Lang Comments and Security Labels */
13037 if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
13038 dumpComment(fout, "LANGUAGE", qlanname,
13039 NULL, plang->lanowner,
13040 plang->dobj.catId, 0, plang->dobj.dumpId);
13041
13042 if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
13043 dumpSecLabel(fout, "LANGUAGE", qlanname,
13044 NULL, plang->lanowner,
13045 plang->dobj.catId, 0, plang->dobj.dumpId);
13046
13047 if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
13048 dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
13049 qlanname, NULL, NULL,
13050 NULL, plang->lanowner, &plang->dacl);
13051
13052 free(qlanname);
13053
13054 destroyPQExpBuffer(defqry);
13055 destroyPQExpBuffer(delqry);
13056}
Oid lanvalidator
Definition: pg_dump.h:530
DumpableAcl dacl
Definition: pg_dump.h:526
DumpableObject dobj
Definition: pg_dump.h:525
Oid laninline
Definition: pg_dump.h:529
const char * lanowner
Definition: pg_dump.h:531
Oid lanplcallfoid
Definition: pg_dump.h:528
bool lanpltrusted
Definition: pg_dump.h:527

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

4490{
4491 DumpOptions *dopt = fout->dopt;
4492 PQExpBuffer delq;
4493 PQExpBuffer query;
4494 char *qpubname;
4495 bool first = true;
4496
4497 /* Do nothing if not dumping schema */
4498 if (!dopt->dumpSchema)
4499 return;
4500
4501 delq = createPQExpBuffer();
4502 query = createPQExpBuffer();
4503
4504 qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
4505
4506 appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
4507 qpubname);
4508
4509 appendPQExpBuffer(query, "CREATE PUBLICATION %s",
4510 qpubname);
4511
4512 if (pubinfo->puballtables)
4513 appendPQExpBufferStr(query, " FOR ALL TABLES");
4514
4515 appendPQExpBufferStr(query, " WITH (publish = '");
4516 if (pubinfo->pubinsert)
4517 {
4518 appendPQExpBufferStr(query, "insert");
4519 first = false;
4520 }
4521
4522 if (pubinfo->pubupdate)
4523 {
4524 if (!first)
4525 appendPQExpBufferStr(query, ", ");
4526
4527 appendPQExpBufferStr(query, "update");
4528 first = false;
4529 }
4530
4531 if (pubinfo->pubdelete)
4532 {
4533 if (!first)
4534 appendPQExpBufferStr(query, ", ");
4535
4536 appendPQExpBufferStr(query, "delete");
4537 first = false;
4538 }
4539
4540 if (pubinfo->pubtruncate)
4541 {
4542 if (!first)
4543 appendPQExpBufferStr(query, ", ");
4544
4545 appendPQExpBufferStr(query, "truncate");
4546 first = false;
4547 }
4548
4549 appendPQExpBufferChar(query, '\'');
4550
4551 if (pubinfo->pubviaroot)
4552 appendPQExpBufferStr(query, ", publish_via_partition_root = true");
4553
4554 if (pubinfo->pubgencols_type == PUBLISH_GENCOLS_STORED)
4555 appendPQExpBufferStr(query, ", publish_generated_columns = stored");
4556
4557 appendPQExpBufferStr(query, ");\n");
4558
4559 if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4560 ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
4561 ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
4562 .owner = pubinfo->rolname,
4563 .description = "PUBLICATION",
4564 .section = SECTION_POST_DATA,
4565 .createStmt = query->data,
4566 .dropStmt = delq->data));
4567
4568 if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
4569 dumpComment(fout, "PUBLICATION", qpubname,
4570 NULL, pubinfo->rolname,
4571 pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4572
4573 if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
4574 dumpSecLabel(fout, "PUBLICATION", qpubname,
4575 NULL, pubinfo->rolname,
4576 pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
4577
4578 destroyPQExpBuffer(delq);
4579 destroyPQExpBuffer(query);
4580 free(qpubname);
4581}
const char * rolname
Definition: pg_dump.h:662
bool puballtables
Definition: pg_dump.h:663
bool pubtruncate
Definition: pg_dump.h:667
PublishGencolsType pubgencols_type
Definition: pg_dump.h:669
DumpableObject dobj
Definition: pg_dump.h:661

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

4796{
4797 DumpOptions *dopt = fout->dopt;
4798 NamespaceInfo *schemainfo = pubsinfo->pubschema;
4799 PublicationInfo *pubinfo = pubsinfo->publication;
4800 PQExpBuffer query;
4801 char *tag;
4802
4803 /* Do nothing if not dumping schema */
4804 if (!dopt->dumpSchema)
4805 return;
4806
4807 tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
4808
4809 query = createPQExpBuffer();
4810
4811 appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
4812 appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
4813
4814 /*
4815 * There is no point in creating drop query as the drop is done by schema
4816 * drop.
4817 */
4818 if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4819 ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
4820 ARCHIVE_OPTS(.tag = tag,
4821 .namespace = schemainfo->dobj.name,
4822 .owner = pubinfo->rolname,
4823 .description = "PUBLICATION TABLES IN SCHEMA",
4824 .section = SECTION_POST_DATA,
4825 .createStmt = query->data));
4826
4827 /* These objects can't currently have comments or seclabels */
4828
4829 free(tag);
4830 destroyPQExpBuffer(query);
4831}
NamespaceInfo * pubschema
Definition: pg_dump.h:693
DumpableObject dobj
Definition: pg_dump.h:691
PublicationInfo * publication
Definition: pg_dump.h:692

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

4839{
4840 DumpOptions *dopt = fout->dopt;
4841 PublicationInfo *pubinfo = pubrinfo->publication;
4842 TableInfo *tbinfo = pubrinfo->pubtable;
4843 PQExpBuffer query;
4844 char *tag;
4845
4846 /* Do nothing if not dumping schema */
4847 if (!dopt->dumpSchema)
4848 return;
4849
4850 tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
4851
4852 query = createPQExpBuffer();
4853
4854 appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
4855 fmtId(pubinfo->dobj.name));
4856 appendPQExpBuffer(query, " %s",
4857 fmtQualifiedDumpable(tbinfo));
4858
4859 if (pubrinfo->pubrattrs)
4860 appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
4861
4862 if (pubrinfo->pubrelqual)
4863 {
4864 /*
4865 * It's necessary to add parentheses around the expression because
4866 * pg_get_expr won't supply the parentheses for things like WHERE
4867 * TRUE.
4868 */
4869 appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
4870 }
4871 appendPQExpBufferStr(query, ";\n");
4872
4873 /*
4874 * There is no point in creating a drop query as the drop is done by table
4875 * drop. (If you think to change this, see also _printTocEntry().)
4876 * Although this object doesn't really have ownership as such, set the
4877 * owner field anyway to ensure that the command is run by the correct
4878 * role at restore time.
4879 */
4880 if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
4881 ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
4882 ARCHIVE_OPTS(.tag = tag,
4883 .namespace = tbinfo->dobj.namespace->dobj.name,
4884 .owner = pubinfo->rolname,
4885 .description = "PUBLICATION TABLE",
4886 .section = SECTION_POST_DATA,
4887 .createStmt = query->data));
4888
4889 /* These objects can't currently have comments or seclabels */
4890
4891 free(tag);
4892 destroyPQExpBuffer(query);
4893}

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

11950{
11951 DumpOptions *dopt = fout->dopt;
11955 PGresult *res;
11956 Oid collationOid;
11957 char *qtypname;
11958 char *qualtypname;
11959 char *procname;
11960
11962 {
11963 /* Set up query for range-specific details */
11965 "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
11966
11968 "SELECT ");
11969
11970 if (fout->remoteVersion >= 140000)
11972 "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
11973 else
11975 "NULL AS rngmultitype, ");
11976
11978 "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
11979 "opc.opcname AS opcname, "
11980 "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
11981 " WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
11982 "opc.opcdefault, "
11983 "CASE WHEN rngcollation = st.typcollation THEN 0 "
11984 " ELSE rngcollation END AS collation, "
11985 "rngcanonical, rngsubdiff "
11986 "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
11987 " pg_catalog.pg_opclass opc "
11988 "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
11989 "rngtypid = $1");
11990
11991 ExecuteSqlStatement(fout, query->data);
11992
11994 }
11995
11996 printfPQExpBuffer(query,
11997 "EXECUTE dumpRangeType('%u')",
11998 tyinfo->dobj.catId.oid);
11999
12000 res = ExecuteSqlQueryForSingleRow(fout, query->data);
12001
12002 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12003 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12004
12005 /*
12006 * CASCADE shouldn't be required here as for normal types since the I/O
12007 * functions are generic and do not get dropped.
12008 */
12009 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12010
12011 if (dopt->binary_upgrade)
12013 tyinfo->dobj.catId.oid,
12014 false, true);
12015
12016 appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
12017 qualtypname);
12018
12019 appendPQExpBuffer(q, "\n subtype = %s",
12020 PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
12021
12022 if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
12023 appendPQExpBuffer(q, ",\n multirange_type_name = %s",
12024 PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
12025
12026 /* print subtype_opclass only if not default for subtype */
12027 if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
12028 {
12029 char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
12030 char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
12031
12032 appendPQExpBuffer(q, ",\n subtype_opclass = %s.",
12033 fmtId(nspname));
12034 appendPQExpBufferStr(q, fmtId(opcname));
12035 }
12036
12037 collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
12038 if (OidIsValid(collationOid))
12039 {
12040 CollInfo *coll = findCollationByOid(collationOid);
12041
12042 if (coll)
12043 appendPQExpBuffer(q, ",\n collation = %s",
12044 fmtQualifiedDumpable(coll));
12045 }
12046
12047 procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
12048 if (strcmp(procname, "-") != 0)
12049 appendPQExpBuffer(q, ",\n canonical = %s", procname);
12050
12051 procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
12052 if (strcmp(procname, "-") != 0)
12053 appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
12054
12055 appendPQExpBufferStr(q, "\n);\n");
12056
12057 if (dopt->binary_upgrade)
12059 "TYPE", qtypname,
12060 tyinfo->dobj.namespace->dobj.name);
12061
12062 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12063 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12064 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12065 .namespace = tyinfo->dobj.namespace->dobj.name,
12066 .owner = tyinfo->rolname,
12067 .description = "TYPE",
12068 .section = SECTION_PRE_DATA,
12069 .createStmt = q->data,
12070 .dropStmt = delq->data));
12071
12072 /* Dump Type Comments and Security Labels */
12073 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12074 dumpComment(fout, "TYPE", qtypname,
12075 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12076 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12077
12078 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12079 dumpSecLabel(fout, "TYPE", qtypname,
12080 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12081 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12082
12083 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12084 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12085 qtypname, NULL,
12086 tyinfo->dobj.namespace->dobj.name,
12087 NULL, tyinfo->rolname, &tyinfo->dacl);
12088
12089 PQclear(res);
12091 destroyPQExpBuffer(delq);
12092 destroyPQExpBuffer(query);
12093 free(qtypname);
12094 free(qualtypname);
12095}
@ 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 11091 of file pg_dump.c.

11092{
11093 const DumpableObject *dobj = &rsinfo->dobj;
11094
11095 /* nothing to do if we are not dumping statistics */
11096 if (!fout->dopt->dumpStatistics)
11097 return;
11098
11100 ARCHIVE_OPTS(.tag = dobj->name,
11101 .namespace = dobj->namespace->dobj.name,
11102 .description = "STATISTICS DATA",
11103 .section = rsinfo->section,
11104 .defnFn = dumpRelationStats_dumper,
11105 .defnArg = rsinfo,
11106 .deps = dobj->dependencies,
11107 .nDeps = dobj->nDeps));
11108}
static char * dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
Definition: pg_dump.c:10818
bool dumpStatistics
Definition: pg_backup.h:215
teSection section
Definition: pg_dump.h:455
DumpableObject dobj
Definition: pg_dump.h:442

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

10819{
10820 const RelStatsInfo *rsinfo = (RelStatsInfo *) userArg;
10821 static PGresult *res;
10822 static int rownum;
10823 PQExpBuffer query;
10824 PQExpBufferData out_data;
10825 PQExpBuffer out = &out_data;
10826 int i_schemaname;
10827 int i_tablename;
10828 int i_attname;
10829 int i_inherited;
10830 int i_null_frac;
10831 int i_avg_width;
10832 int i_n_distinct;
10833 int i_most_common_vals;
10834 int i_most_common_freqs;
10835 int i_histogram_bounds;
10836 int i_correlation;
10837 int i_most_common_elems;
10838 int i_most_common_elem_freqs;
10839 int i_elem_count_histogram;
10840 int i_range_length_histogram;
10841 int i_range_empty_frac;
10842 int i_range_bounds_histogram;
10843 static TocEntry *expected_te;
10844
10845 /*
10846 * fetchAttributeStats() assumes that the statistics are dumped in the
10847 * order they are listed in the TOC. We verify that here for safety.
10848 */
10849 if (!expected_te)
10850 expected_te = ((ArchiveHandle *) fout)->toc;
10851
10852 expected_te = expected_te->next;
10853 while ((expected_te->reqs & REQ_STATS) == 0 ||
10854 strcmp(expected_te->desc, "STATISTICS DATA") != 0)
10855 expected_te = expected_te->next;
10856
10857 if (te != expected_te)
10858 pg_fatal("stats dumped out of order (current: %d %s %s) (expected: %d %s %s)",
10859 te->dumpId, te->desc, te->tag,
10860 expected_te->dumpId, expected_te->desc, expected_te->tag);
10861
10862 query = createPQExpBuffer();
10864 {
10866 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
10867 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
10868 "s.null_frac, s.avg_width, s.n_distinct, "
10869 "s.most_common_vals, s.most_common_freqs, "
10870 "s.histogram_bounds, s.correlation, "
10871 "s.most_common_elems, s.most_common_elem_freqs, "
10872 "s.elem_count_histogram, ");
10873
10874 if (fout->remoteVersion >= 170000)
10876 "s.range_length_histogram, "
10877 "s.range_empty_frac, "
10878 "s.range_bounds_histogram ");
10879 else
10881 "NULL AS range_length_histogram,"
10882 "NULL AS range_empty_frac,"
10883 "NULL AS range_bounds_histogram ");
10884
10885 /*
10886 * The results must be in the order of the relations supplied in the
10887 * parameters to ensure we remain in sync as we walk through the TOC.
10888 * The redundant filter clause on s.tablename = ANY(...) seems
10889 * sufficient to convince the planner to use
10890 * pg_class_relname_nsp_index, which avoids a full scan of pg_stats.
10891 * This may not work for all versions.
10892 *
10893 * Our query for retrieving statistics for multiple relations uses
10894 * WITH ORDINALITY and multi-argument UNNEST(), both of which were
10895 * introduced in v9.4. For older versions, we resort to gathering
10896 * statistics for a single relation at a time.
10897 */
10898 if (fout->remoteVersion >= 90400)
10900 "FROM pg_catalog.pg_stats s "
10901 "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) "
10902 "ON s.schemaname = u.schemaname "
10903 "AND s.tablename = u.tablename "
10904 "WHERE s.tablename = ANY($2) "
10905 "ORDER BY u.ord, s.attname, s.inherited");
10906 else
10908 "FROM pg_catalog.pg_stats s "
10909 "WHERE s.schemaname = $1[1] "
10910 "AND s.tablename = $2[1] "
10911 "ORDER BY s.attname, s.inherited");
10912
10913 ExecuteSqlStatement(fout, query->data);
10914
10916 resetPQExpBuffer(query);
10917 }
10918
10919 initPQExpBuffer(out);
10920
10921 /* restore relation stats */
10922 appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
10923 appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
10924 fout->remoteVersion);
10925 appendPQExpBufferStr(out, "\t'schemaname', ");
10926 appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
10927 appendPQExpBufferStr(out, ",\n");
10928 appendPQExpBufferStr(out, "\t'relname', ");
10929 appendStringLiteralAH(out, rsinfo->dobj.name, fout);
10930 appendPQExpBufferStr(out, ",\n");
10931 appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
10932
10933 /*
10934 * Before v14, a reltuples value of 0 was ambiguous: it could either mean
10935 * the relation is empty, or it could mean that it hadn't yet been
10936 * vacuumed or analyzed. (Newer versions use -1 for the latter case.)
10937 * This ambiguity allegedly can cause the planner to choose inefficient
10938 * plans after restoring to v18 or newer. To deal with this, let's just
10939 * set reltuples to -1 in that case.
10940 */
10941 if (fout->remoteVersion < 140000 && strcmp("0", rsinfo->reltuples) == 0)
10942 appendPQExpBufferStr(out, "\t'reltuples', '-1'::real,\n");
10943 else
10944 appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", rsinfo->reltuples);
10945
10946 appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer",
10947 rsinfo->relallvisible);
10948
10949 if (fout->remoteVersion >= 180000)
10950 appendPQExpBuffer(out, ",\n\t'relallfrozen', '%d'::integer", rsinfo->relallfrozen);
10951
10952 appendPQExpBufferStr(out, "\n);\n");
10953
10954 /* Fetch the next batch of attribute statistics if needed. */
10955 if (rownum >= PQntuples(res))
10956 {
10957 PQclear(res);
10958 res = fetchAttributeStats(fout);
10959 rownum = 0;
10960 }
10961
10962 i_schemaname = PQfnumber(res, "schemaname");
10963 i_tablename = PQfnumber(res, "tablename");
10964 i_attname = PQfnumber(res, "attname");
10965 i_inherited = PQfnumber(res, "inherited");
10966 i_null_frac = PQfnumber(res, "null_frac");
10967 i_avg_width = PQfnumber(res, "avg_width");
10968 i_n_distinct = PQfnumber(res, "n_distinct");
10969 i_most_common_vals = PQfnumber(res, "most_common_vals");
10970 i_most_common_freqs = PQfnumber(res, "most_common_freqs");
10971 i_histogram_bounds = PQfnumber(res, "histogram_bounds");
10972 i_correlation = PQfnumber(res, "correlation");
10973 i_most_common_elems = PQfnumber(res, "most_common_elems");
10974 i_most_common_elem_freqs = PQfnumber(res, "most_common_elem_freqs");
10975 i_elem_count_histogram = PQfnumber(res, "elem_count_histogram");
10976 i_range_length_histogram = PQfnumber(res, "range_length_histogram");
10977 i_range_empty_frac = PQfnumber(res, "range_empty_frac");
10978 i_range_bounds_histogram = PQfnumber(res, "range_bounds_histogram");
10979
10980 /* restore attribute stats */
10981 for (; rownum < PQntuples(res); rownum++)
10982 {
10983 const char *attname;
10984
10985 /* Stop if the next stat row in our cache isn't for this relation. */
10986 if (strcmp(te->tag, PQgetvalue(res, rownum, i_tablename)) != 0 ||
10987 strcmp(te->namespace, PQgetvalue(res, rownum, i_schemaname)) != 0)
10988 break;
10989
10990 appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n");
10991 appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
10992 fout->remoteVersion);
10993 appendPQExpBufferStr(out, "\t'schemaname', ");
10994 appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
10995 appendPQExpBufferStr(out, ",\n\t'relname', ");
10996 appendStringLiteralAH(out, rsinfo->dobj.name, fout);
10997
10998 if (PQgetisnull(res, rownum, i_attname))
10999 pg_fatal("attname cannot be NULL");
11000 attname = PQgetvalue(res, rownum, i_attname);
11001
11002 /*
11003 * Indexes look up attname in indAttNames to derive attnum, all others
11004 * use attname directly. We must specify attnum for indexes, since
11005 * their attnames are not necessarily stable across dump/reload.
11006 */
11007 if (rsinfo->nindAttNames == 0)
11008 {
11009 appendPQExpBufferStr(out, ",\n\t'attname', ");
11010 appendStringLiteralAH(out, attname, fout);
11011 }
11012 else
11013 {
11014 bool found = false;
11015
11016 for (int i = 0; i < rsinfo->nindAttNames; i++)
11017 {
11018 if (strcmp(attname, rsinfo->indAttNames[i]) == 0)
11019 {
11020 appendPQExpBuffer(out, ",\n\t'attnum', '%d'::smallint",
11021 i + 1);
11022 found = true;
11023 break;
11024 }
11025 }
11026
11027 if (!found)
11028 pg_fatal("could not find index attname \"%s\"", attname);
11029 }
11030
11031 if (!PQgetisnull(res, rownum, i_inherited))
11032 appendNamedArgument(out, fout, "inherited", "boolean",
11033 PQgetvalue(res, rownum, i_inherited));
11034 if (!PQgetisnull(res, rownum, i_null_frac))
11035 appendNamedArgument(out, fout, "null_frac", "real",
11036 PQgetvalue(res, rownum, i_null_frac));
11037 if (!PQgetisnull(res, rownum, i_avg_width))
11038 appendNamedArgument(out, fout, "avg_width", "integer",
11039 PQgetvalue(res, rownum, i_avg_width));
11040 if (!PQgetisnull(res, rownum, i_n_distinct))
11041 appendNamedArgument(out, fout, "n_distinct", "real",
11042 PQgetvalue(res, rownum, i_n_distinct));
11043 if (!PQgetisnull(res, rownum, i_most_common_vals))
11044 appendNamedArgument(out, fout, "most_common_vals", "text",
11045 PQgetvalue(res, rownum, i_most_common_vals));
11046 if (!PQgetisnull(res, rownum, i_most_common_freqs))
11047 appendNamedArgument(out, fout, "most_common_freqs", "real[]",
11048 PQgetvalue(res, rownum, i_most_common_freqs));
11049 if (!PQgetisnull(res, rownum, i_histogram_bounds))
11050 appendNamedArgument(out, fout, "histogram_bounds", "text",
11051 PQgetvalue(res, rownum, i_histogram_bounds));
11052 if (!PQgetisnull(res, rownum, i_correlation))
11053 appendNamedArgument(out, fout, "correlation", "real",
11054 PQgetvalue(res, rownum, i_correlation));
11055 if (!PQgetisnull(res, rownum, i_most_common_elems))
11056 appendNamedArgument(out, fout, "most_common_elems", "text",
11057 PQgetvalue(res, rownum, i_most_common_elems));
11058 if (!PQgetisnull(res, rownum, i_most_common_elem_freqs))
11059 appendNamedArgument(out, fout, "most_common_elem_freqs", "real[]",
11060 PQgetvalue(res, rownum, i_most_common_elem_freqs));
11061 if (!PQgetisnull(res, rownum, i_elem_count_histogram))
11062 appendNamedArgument(out, fout, "elem_count_histogram", "real[]",
11063 PQgetvalue(res, rownum, i_elem_count_histogram));
11064 if (fout->remoteVersion >= 170000)
11065 {
11066 if (!PQgetisnull(res, rownum, i_range_length_histogram))
11067 appendNamedArgument(out, fout, "range_length_histogram", "text",
11068 PQgetvalue(res, rownum, i_range_length_histogram));
11069 if (!PQgetisnull(res, rownum, i_range_empty_frac))
11070 appendNamedArgument(out, fout, "range_empty_frac", "real",
11071 PQgetvalue(res, rownum, i_range_empty_frac));
11072 if (!PQgetisnull(res, rownum, i_range_bounds_histogram))
11073 appendNamedArgument(out, fout, "range_bounds_histogram", "text",
11074 PQgetvalue(res, rownum, i_range_bounds_histogram));
11075 }
11076 appendPQExpBufferStr(out, "\n);\n");
11077 }
11078
11079 destroyPQExpBuffer(query);
11080 return out->data;
11081}
@ PREPQUERY_GETATTRIBUTESTATS
Definition: pg_backup.h:75
#define REQ_STATS
static PGresult * fetchAttributeStats(Archive *fout)
Definition: pg_dump.c:10730
static void appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname, const char *argtype, const char *argval)
Definition: pg_dump.c:10712
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
int32 nindAttNames
Definition: pg_dump.h:454
char ** indAttNames
Definition: pg_dump.h:453
int32 relpages
Definition: pg_dump.h:443
int32 relallfrozen
Definition: pg_dump.h:446
char * reltuples
Definition: pg_dump.h:444
int32 relallvisible
Definition: pg_dump.h:445

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

19105{
19106 DumpOptions *dopt = fout->dopt;
19107 TableInfo *tbinfo = rinfo->ruletable;
19108 bool is_view;
19109 PQExpBuffer query;
19110 PQExpBuffer cmd;
19111 PQExpBuffer delcmd;
19112 PQExpBuffer ruleprefix;
19113 char *qtabname;
19114 PGresult *res;
19115 char *tag;
19116
19117 /* Do nothing if not dumping schema */
19118 if (!dopt->dumpSchema)
19119 return;
19120
19121 /*
19122 * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
19123 * we do not want to dump it as a separate object.
19124 */
19125 if (!rinfo->separate)
19126 return;
19127
19128 /*
19129 * If it's an ON SELECT rule, we want to print it as a view definition,
19130 * instead of a rule.
19131 */
19132 is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
19133
19134 query = createPQExpBuffer();
19135 cmd = createPQExpBuffer();
19136 delcmd = createPQExpBuffer();
19137 ruleprefix = createPQExpBuffer();
19138
19139 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
19140
19141 if (is_view)
19142 {
19143 PQExpBuffer result;
19144
19145 /*
19146 * We need OR REPLACE here because we'll be replacing a dummy view.
19147 * Otherwise this should look largely like the regular view dump code.
19148 */
19149 appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
19150 fmtQualifiedDumpable(tbinfo));
19151 if (nonemptyReloptions(tbinfo->reloptions))
19152 {
19153 appendPQExpBufferStr(cmd, " WITH (");
19154 appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
19155 appendPQExpBufferChar(cmd, ')');
19156 }
19157 result = createViewAsClause(fout, tbinfo);
19158 appendPQExpBuffer(cmd, " AS\n%s", result->data);
19159 destroyPQExpBuffer(result);
19160 if (tbinfo->checkoption != NULL)
19161 appendPQExpBuffer(cmd, "\n WITH %s CHECK OPTION",
19162 tbinfo->checkoption);
19163 appendPQExpBufferStr(cmd, ";\n");
19164 }
19165 else
19166 {
19167 /* In the rule case, just print pg_get_ruledef's result verbatim */
19168 appendPQExpBuffer(query,
19169 "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
19170 rinfo->dobj.catId.oid);
19171
19172 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19173
19174 if (PQntuples(res) != 1)
19175 pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
19176 rinfo->dobj.name, tbinfo->dobj.name);
19177
19178 printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
19179
19180 PQclear(res);
19181 }
19182
19183 /*
19184 * Add the command to alter the rules replication firing semantics if it
19185 * differs from the default.
19186 */
19187 if (rinfo->ev_enabled != 'O')
19188 {
19189 appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
19190 switch (rinfo->ev_enabled)
19191 {
19192 case 'A':
19193 appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
19194 fmtId(rinfo->dobj.name));
19195 break;
19196 case 'R':
19197 appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
19198 fmtId(rinfo->dobj.name));
19199 break;
19200 case 'D':
19201 appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
19202 fmtId(rinfo->dobj.name));
19203 break;
19204 }
19205 }
19206
19207 if (is_view)
19208 {
19209 /*
19210 * We can't DROP a view's ON SELECT rule. Instead, use CREATE OR
19211 * REPLACE VIEW to replace the rule with something with minimal
19212 * dependencies.
19213 */
19214 PQExpBuffer result;
19215
19216 appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
19217 fmtQualifiedDumpable(tbinfo));
19218 result = createDummyViewAsClause(fout, tbinfo);
19219 appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
19220 destroyPQExpBuffer(result);
19221 }
19222 else
19223 {
19224 appendPQExpBuffer(delcmd, "DROP RULE %s ",
19225 fmtId(rinfo->dobj.name));
19226 appendPQExpBuffer(delcmd, "ON %s;\n",
19227 fmtQualifiedDumpable(tbinfo));
19228 }
19229
19230 appendPQExpBuffer(ruleprefix, "RULE %s ON",
19231 fmtId(rinfo->dobj.name));
19232
19233 tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
19234
19235 if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19236 ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
19237 ARCHIVE_OPTS(.tag = tag,
19238 .namespace = tbinfo->dobj.namespace->dobj.name,
19239 .owner = tbinfo->rolname,
19240 .description = "RULE",
19241 .section = SECTION_POST_DATA,
19242 .createStmt = cmd->data,
19243 .dropStmt = delcmd->data));
19244
19245 /* Dump rule comments */
19246 if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19247 dumpComment(fout, ruleprefix->data, qtabname,
19248 tbinfo->dobj.namespace->dobj.name,
19249 tbinfo->rolname,
19250 rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
19251
19252 free(tag);
19253 destroyPQExpBuffer(query);
19254 destroyPQExpBuffer(cmd);
19255 destroyPQExpBuffer(delcmd);
19256 destroyPQExpBuffer(ruleprefix);
19257 free(qtabname);
19258}
static PQExpBuffer createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16717
static PQExpBuffer createViewAsClause(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16668
DumpableObject dobj
Definition: pg_dump.h:468
bool separate
Definition: pg_dump.h:473
char ev_enabled
Definition: pg_dump.h:472
bool is_instead
Definition: pg_dump.h:471
TableInfo * ruletable
Definition: pg_dump.h:469
char ev_type
Definition: pg_dump.h:470
char * checkoption
Definition: pg_dump.h:309
char * reloptions
Definition: pg_dump.h:308

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

3757{
3760 PGresult *res;
3761 char **schemanames = NULL;
3762 int nschemanames = 0;
3763 int i;
3764
3765 /*
3766 * We use the result of current_schemas(), not the search_path GUC,
3767 * because that might contain wildcards such as "$user", which won't
3768 * necessarily have the same value during restore. Also, this way avoids
3769 * listing schemas that may appear in search_path but not actually exist,
3770 * which seems like a prudent exclusion.
3771 */
3773 "SELECT pg_catalog.current_schemas(false)");
3774
3775 if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
3776 pg_fatal("could not parse result of current_schemas()");
3777
3778 /*
3779 * We use set_config(), not a simple "SET search_path" command, because
3780 * the latter has less-clean behavior if the search path is empty. While
3781 * that's likely to get fixed at some point, it seems like a good idea to
3782 * be as backwards-compatible as possible in what we put into archives.
3783 */
3784 for (i = 0; i < nschemanames; i++)
3785 {
3786 if (i > 0)
3787 appendPQExpBufferStr(path, ", ");
3788 appendPQExpBufferStr(path, fmtId(schemanames[i]));
3789 }
3790
3791 appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
3792 appendStringLiteralAH(qry, path->data, AH);
3793 appendPQExpBufferStr(qry, ", false);\n");
3794
3795 pg_log_info("saving \"search_path = %s\"", path->data);
3796
3798 ARCHIVE_OPTS(.tag = "SEARCHPATH",
3799 .description = "SEARCHPATH",
3800 .section = SECTION_PRE_DATA,
3801 .createStmt = qry->data));
3802
3803 /* Also save it in AH->searchpath, in case we're doing plain text dump */
3804 AH->searchpath = pg_strdup(qry->data);
3805
3806 free(schemanames);
3807 PQclear(res);
3808 destroyPQExpBuffer(qry);
3809 destroyPQExpBuffer(path);
3810}
char * searchpath
Definition: pg_backup.h:243

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

16204{
16205 DumpOptions *dopt = fout->dopt;
16206 SecLabelItem *labels;
16207 int nlabels;
16208 int i;
16209 PQExpBuffer query;
16210
16211 /* do nothing, if --no-security-labels is supplied */
16212 if (dopt->no_security_labels)
16213 return;
16214
16215 /*
16216 * Security labels are schema not data ... except large object labels are
16217 * data
16218 */
16219 if (strcmp(type, "LARGE OBJECT") != 0)
16220 {
16221 if (!dopt->dumpSchema)
16222 return;
16223 }
16224 else
16225 {
16226 /* We do dump large object security labels in binary-upgrade mode */
16227 if (!dopt->dumpData && !dopt->binary_upgrade)
16228 return;
16229 }
16230
16231 /* Search for security labels associated with catalogId, using table */
16232 nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
16233
16234 query = createPQExpBuffer();
16235
16236 for (i = 0; i < nlabels; i++)
16237 {
16238 /*
16239 * Ignore label entries for which the subid doesn't match.
16240 */
16241 if (labels[i].objsubid != subid)
16242 continue;
16243
16244 appendPQExpBuffer(query,
16245 "SECURITY LABEL FOR %s ON %s ",
16246 fmtId(labels[i].provider), type);
16247 if (namespace && *namespace)
16248 appendPQExpBuffer(query, "%s.", fmtId(namespace));
16249 appendPQExpBuffer(query, "%s IS ", name);
16250 appendStringLiteralAH(query, labels[i].label, fout);
16251 appendPQExpBufferStr(query, ";\n");
16252 }
16253
16254 if (query->len > 0)
16255 {
16257
16258 appendPQExpBuffer(tag, "%s %s", type, name);
16260 ARCHIVE_OPTS(.tag = tag->data,
16261 .namespace = namespace,
16262 .owner = owner,
16263 .description = "SECURITY LABEL",
16264 .section = SECTION_NONE,
16265 .createStmt = query->data,
16266 .deps = &dumpId,
16267 .nDeps = 1));
16268 destroyPQExpBuffer(tag);
16269 }
16270
16271 destroyPQExpBuffer(query);
16272}
static int findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
Definition: pg_dump.c:16363

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(), dumpExtension(), dumpFunc(), dumpLO(), dumpNamespace(), dumpProcLang(), dumpPublication(), dumpRangeType(), dumpSequence(), dumpSubscription(), and dumpUndefinedType().

◆ dumpSequence()

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

Definition at line 18562 of file pg_dump.c.

18563{
18564 DumpOptions *dopt = fout->dopt;
18565 SequenceItem *seq;
18566 bool is_ascending;
18567 int64 default_minv,
18568 default_maxv;
18570 PQExpBuffer delqry = createPQExpBuffer();
18571 char *qseqname;
18572 TableInfo *owning_tab = NULL;
18573
18574 qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
18575
18576 /*
18577 * For versions >= 10, the sequence information is gathered in a sorted
18578 * table before any calls to dumpSequence(). See collectSequences() for
18579 * more information.
18580 */
18581 if (fout->remoteVersion >= 100000)
18582 {
18583 SequenceItem key = {0};
18584
18586
18587 key.oid = tbinfo->dobj.catId.oid;
18588 seq = bsearch(&key, sequences, nsequences,
18589 sizeof(SequenceItem), SequenceItemCmp);
18590 }
18591 else
18592 {
18593 PGresult *res;
18594
18595 /*
18596 * Before PostgreSQL 10, sequence metadata is in the sequence itself.
18597 *
18598 * Note: it might seem that 'bigint' potentially needs to be
18599 * schema-qualified, but actually that's a keyword.
18600 */
18601 appendPQExpBuffer(query,
18602 "SELECT 'bigint' AS sequence_type, "
18603 "start_value, increment_by, max_value, min_value, "
18604 "cache_value, is_cycled FROM %s",
18605 fmtQualifiedDumpable(tbinfo));
18606
18607 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18608
18609 if (PQntuples(res) != 1)
18610 pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
18611 "query to get data of sequence \"%s\" returned %d rows (expected 1)",
18612 PQntuples(res)),
18613 tbinfo->dobj.name, PQntuples(res));
18614
18615 seq = pg_malloc0(sizeof(SequenceItem));
18616 seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0));
18617 seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10);
18618 seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10);
18619 seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10);
18620 seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10);
18621 seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10);
18622 seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
18623
18624 PQclear(res);
18625 }
18626
18627 /* Calculate default limits for a sequence of this type */
18628 is_ascending = (seq->incby >= 0);
18629 if (seq->seqtype == SEQTYPE_SMALLINT)
18630 {
18631 default_minv = is_ascending ? 1 : PG_INT16_MIN;
18632 default_maxv = is_ascending ? PG_INT16_MAX : -1;
18633 }
18634 else if (seq->seqtype == SEQTYPE_INTEGER)
18635 {
18636 default_minv = is_ascending ? 1 : PG_INT32_MIN;
18637 default_maxv = is_ascending ? PG_INT32_MAX : -1;
18638 }
18639 else if (seq->seqtype == SEQTYPE_BIGINT)
18640 {
18641 default_minv = is_ascending ? 1 : PG_INT64_MIN;
18642 default_maxv = is_ascending ? PG_INT64_MAX : -1;
18643 }
18644 else
18645 {
18646 pg_fatal("unrecognized sequence type: %d", seq->seqtype);
18647 default_minv = default_maxv = 0; /* keep compiler quiet */
18648 }
18649
18650 /*
18651 * Identity sequences are not to be dropped separately.
18652 */
18653 if (!tbinfo->is_identity_sequence)
18654 {
18655 appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
18656 fmtQualifiedDumpable(tbinfo));
18657 }
18658
18659 resetPQExpBuffer(query);
18660
18661 if (dopt->binary_upgrade)
18662 {
18664 tbinfo->dobj.catId.oid);
18665
18666 /*
18667 * In older PG versions a sequence will have a pg_type entry, but v14
18668 * and up don't use that, so don't attempt to preserve the type OID.
18669 */
18670 }
18671
18672 if (tbinfo->is_identity_sequence)
18673 {
18674 owning_tab = findTableByOid(tbinfo->owning_tab);
18675
18676 appendPQExpBuffer(query,
18677 "ALTER TABLE %s ",
18678 fmtQualifiedDumpable(owning_tab));
18679 appendPQExpBuffer(query,
18680 "ALTER COLUMN %s ADD GENERATED ",
18681 fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
18682 if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
18683 appendPQExpBufferStr(query, "ALWAYS");
18684 else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
18685 appendPQExpBufferStr(query, "BY DEFAULT");
18686 appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n",
18687 fmtQualifiedDumpable(tbinfo));
18688
18689 /*
18690 * Emit persistence option only if it's different from the owning
18691 * table's. This avoids using this new syntax unnecessarily.
18692 */
18693 if (tbinfo->relpersistence != owning_tab->relpersistence)
18694 appendPQExpBuffer(query, " %s\n",
18695 tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
18696 "UNLOGGED" : "LOGGED");
18697 }
18698 else
18699 {
18700 appendPQExpBuffer(query,
18701 "CREATE %sSEQUENCE %s\n",
18702 tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
18703 "UNLOGGED " : "",
18704 fmtQualifiedDumpable(tbinfo));
18705
18706 if (seq->seqtype != SEQTYPE_BIGINT)
18707 appendPQExpBuffer(query, " AS %s\n", SeqTypeNames[seq->seqtype]);
18708 }
18709
18710 appendPQExpBuffer(query, " START WITH " INT64_FORMAT "\n", seq->startv);
18711
18712 appendPQExpBuffer(query, " INCREMENT BY " INT64_FORMAT "\n", seq->incby);
18713
18714 if (seq->minv != default_minv)
18715 appendPQExpBuffer(query, " MINVALUE " INT64_FORMAT "\n", seq->minv);
18716 else
18717 appendPQExpBufferStr(query, " NO MINVALUE\n");
18718
18719 if (seq->maxv != default_maxv)
18720 appendPQExpBuffer(query, " MAXVALUE " INT64_FORMAT "\n", seq->maxv);
18721 else
18722 appendPQExpBufferStr(query, " NO MAXVALUE\n");
18723
18724 appendPQExpBuffer(query,
18725 " CACHE " INT64_FORMAT "%s",
18726 seq->cache, (seq->cycled ? "\n CYCLE" : ""));
18727
18728 if (tbinfo->is_identity_sequence)
18729 appendPQExpBufferStr(query, "\n);\n");
18730 else
18731 appendPQExpBufferStr(query, ";\n");
18732
18733 /* binary_upgrade: no need to clear TOAST table oid */
18734
18735 if (dopt->binary_upgrade)
18736 binary_upgrade_extension_member(query, &tbinfo->dobj,
18737 "SEQUENCE", qseqname,
18738 tbinfo->dobj.namespace->dobj.name);
18739
18740 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18741 ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
18742 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
18743 .namespace = tbinfo->dobj.namespace->dobj.name,
18744 .owner = tbinfo->rolname,
18745 .description = "SEQUENCE",
18746 .section = SECTION_PRE_DATA,
18747 .createStmt = query->data,
18748 .dropStmt = delqry->data));
18749
18750 /*
18751 * If the sequence is owned by a table column, emit the ALTER for it as a
18752 * separate TOC entry immediately following the sequence's own entry. It's
18753 * OK to do this rather than using full sorting logic, because the
18754 * dependency that tells us it's owned will have forced the table to be
18755 * created first. We can't just include the ALTER in the TOC entry
18756 * because it will fail if we haven't reassigned the sequence owner to
18757 * match the table's owner.
18758 *
18759 * We need not schema-qualify the table reference because both sequence
18760 * and table must be in the same schema.
18761 */
18762 if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
18763 {
18764 owning_tab = findTableByOid(tbinfo->owning_tab);
18765
18766 if (owning_tab == NULL)
18767 pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
18768 tbinfo->owning_tab, tbinfo->dobj.catId.oid);
18769
18770 if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
18771 {
18772 resetPQExpBuffer(query);
18773 appendPQExpBuffer(query, "ALTER SEQUENCE %s",
18774 fmtQualifiedDumpable(tbinfo));
18775 appendPQExpBuffer(query, " OWNED BY %s",
18776 fmtQualifiedDumpable(owning_tab));
18777 appendPQExpBuffer(query, ".%s;\n",
18778 fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
18779
18780 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18782 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
18783 .namespace = tbinfo->dobj.namespace->dobj.name,
18784 .owner = tbinfo->rolname,
18785 .description = "SEQUENCE OWNED BY",
18786 .section = SECTION_PRE_DATA,
18787 .createStmt = query->data,
18788 .deps = &(tbinfo->dobj.dumpId),
18789 .nDeps = 1));
18790 }
18791 }
18792
18793 /* Dump Sequence Comments and Security Labels */
18794 if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18795 dumpComment(fout, "SEQUENCE", qseqname,
18796 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
18797 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
18798
18799 if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
18800 dumpSecLabel(fout, "SEQUENCE", qseqname,
18801 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
18802 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
18803
18804 if (fout->remoteVersion < 100000)
18805 pg_free(seq);
18806 destroyPQExpBuffer(query);
18807 destroyPQExpBuffer(delqry);
18808 free(qseqname);
18809}
TableInfo * findTableByOid(Oid oid)
Definition: common.c:862
#define PG_INT32_MAX
Definition: c.h:560
#define ngettext(s, p, n)
Definition: c.h:1152
#define INT64_FORMAT
Definition: c.h:520
int64_t int64
Definition: c.h:499
#define PG_INT16_MIN
Definition: c.h:556
#define PG_INT64_MAX
Definition: c.h:563
#define PG_INT64_MIN
Definition: c.h:562
#define PG_INT32_MIN
Definition: c.h:559
#define PG_INT16_MAX
Definition: c.h:557
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static int SequenceItemCmp(const void *p1, const void *p2)
Definition: pg_dump.c:18486
static const char *const SeqTypeNames[]
Definition: pg_dump.c:115
char * attidentity
Definition: pg_dump.h:354
bool is_identity_sequence
Definition: pg_dump.h:330
int owning_col
Definition: pg_dump.h:329
Oid owning_tab
Definition: pg_dump.h:328
char relpersistence
Definition: pg_dump.h:304

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

18817{
18818 TableInfo *tbinfo = tdinfo->tdtable;
18819 int64 last;
18820 bool called;
18822
18823 /*
18824 * For versions >= 18, the sequence information is gathered in the sorted
18825 * array before any calls to dumpSequenceData(). See collectSequences()
18826 * for more information.
18827 *
18828 * For older versions, we have to query the sequence relations
18829 * individually.
18830 */
18831 if (fout->remoteVersion < 180000)
18832 {
18833 PGresult *res;
18834
18835 appendPQExpBuffer(query,
18836 "SELECT last_value, is_called FROM %s",
18837 fmtQualifiedDumpable(tbinfo));
18838
18839 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18840
18841 if (PQntuples(res) != 1)
18842 pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
18843 "query to get data of sequence \"%s\" returned %d rows (expected 1)",
18844 PQntuples(res)),
18845 tbinfo->dobj.name, PQntuples(res));
18846
18847 last = strtoi64(PQgetvalue(res, 0, 0), NULL, 10);
18848 called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
18849
18850 PQclear(res);
18851 }
18852 else
18853 {
18854 SequenceItem key = {0};
18855 SequenceItem *entry;
18856
18858 Assert(tbinfo->dobj.catId.oid);
18859
18860 key.oid = tbinfo->dobj.catId.oid;
18861 entry = bsearch(&key, sequences, nsequences,
18862 sizeof(SequenceItem), SequenceItemCmp);
18863
18864 last = entry->last_value;
18865 called = entry->is_called;
18866 }
18867
18868 resetPQExpBuffer(query);
18869 appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
18870 appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
18871 appendPQExpBuffer(query, ", " INT64_FORMAT ", %s);\n",
18872 last, (called ? "true" : "false"));
18873
18874 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
18876 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
18877 .namespace = tbinfo->dobj.namespace->dobj.name,
18878 .owner = tbinfo->rolname,
18879 .description = "SEQUENCE SET",
18880 .section = SECTION_DATA,
18881 .createStmt = query->data,
18882 .deps = &(tbinfo->dobj.dumpId),
18883 .nDeps = 1));
18884
18885 destroyPQExpBuffer(query);
18886}
TableInfo * tdtable
Definition: pg_dump.h:406
DumpableObject dobj
Definition: pg_dump.h:405

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

12889{
12890 DumpOptions *dopt = fout->dopt;
12891 PQExpBuffer q;
12892
12893 /* Do nothing if not dumping schema */
12894 if (!dopt->dumpSchema)
12895 return;
12896
12897 q = createPQExpBuffer();
12898
12899 /*
12900 * Note the lack of a DROP command for the shell type; any required DROP
12901 * is driven off the base type entry, instead. This interacts with
12902 * _printTocEntry()'s use of the presence of a DROP command to decide
12903 * whether an entry needs an ALTER OWNER command. We don't want to alter
12904 * the shell type's owner immediately on creation; that should happen only
12905 * after it's filled in, otherwise the backend complains.
12906 */
12907
12908 if (dopt->binary_upgrade)
12910 stinfo->baseType->dobj.catId.oid,
12911 false, false);
12912
12913 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12914 fmtQualifiedDumpable(stinfo));
12915
12916 if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12917 ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
12918 ARCHIVE_OPTS(.tag = stinfo->dobj.name,
12919 .namespace = stinfo->dobj.namespace->dobj.name,
12920 .owner = stinfo->baseType->rolname,
12921 .description = "SHELL TYPE",
12922 .section = SECTION_PRE_DATA,
12923 .createStmt = q->data));
12924
12926}
TypeInfo * baseType
Definition: pg_dump.h:234
DumpableObject dobj
Definition: pg_dump.h:232

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

18075{
18076 DumpOptions *dopt = fout->dopt;
18077 PQExpBuffer q;
18078 PQExpBuffer delq;
18079 PQExpBuffer query;
18080 char *qstatsextname;
18081 PGresult *res;
18082 char *stxdef;
18083
18084 /* Do nothing if not dumping schema */
18085 if (!dopt->dumpSchema)
18086 return;
18087
18088 q = createPQExpBuffer();
18089 delq = createPQExpBuffer();
18090 query = createPQExpBuffer();
18091
18092 qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
18093
18094 appendPQExpBuffer(query, "SELECT "
18095 "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
18096 statsextinfo->dobj.catId.oid);
18097
18098 res = ExecuteSqlQueryForSingleRow(fout, query->data);
18099
18100 stxdef = PQgetvalue(res, 0, 0);
18101
18102 /* Result of pg_get_statisticsobjdef is complete except for semicolon */
18103 appendPQExpBuffer(q, "%s;\n", stxdef);
18104
18105 /*
18106 * We only issue an ALTER STATISTICS statement if the stxstattarget entry
18107 * for this statistics object is not the default value.
18108 */
18109 if (statsextinfo->stattarget >= 0)
18110 {
18111 appendPQExpBuffer(q, "ALTER STATISTICS %s ",
18112 fmtQualifiedDumpable(statsextinfo));
18113 appendPQExpBuffer(q, "SET STATISTICS %d;\n",
18114 statsextinfo->stattarget);
18115 }
18116
18117 appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
18118 fmtQualifiedDumpable(statsextinfo));
18119
18120 if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18121 ArchiveEntry(fout, statsextinfo->dobj.catId,
18122 statsextinfo->dobj.dumpId,
18123 ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
18124 .namespace = statsextinfo->dobj.namespace->dobj.name,
18125 .owner = statsextinfo->rolname,
18126 .description = "STATISTICS",
18127 .section = SECTION_POST_DATA,
18128 .createStmt = q->data,
18129 .dropStmt = delq->data));
18130
18131 /* Dump Statistics Comments */
18132 if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18133 dumpComment(fout, "STATISTICS", qstatsextname,
18134 statsextinfo->dobj.namespace->dobj.name,
18135 statsextinfo->rolname,
18136 statsextinfo->dobj.catId, 0,
18137 statsextinfo->dobj.dumpId);
18138
18139 PQclear(res);
18141 destroyPQExpBuffer(delq);
18142 destroyPQExpBuffer(query);
18143 free(qstatsextname);
18144}
int stattarget
Definition: pg_dump.h:463
const char * rolname
Definition: pg_dump.h:461
DumpableObject dobj
Definition: pg_dump.h:460

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

3733{
3734 const char *stdstrings = AH->std_strings ? "on" : "off";
3736
3737 pg_log_info("saving \"standard_conforming_strings = %s\"",
3738 stdstrings);
3739
3740 appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
3741 stdstrings);
3742
3744 ARCHIVE_OPTS(.tag = "STDSTRINGS",
3745 .description = "STDSTRINGS",
3746 .section = SECTION_PRE_DATA,
3747 .createStmt = qry->data));
3748
3749 destroyPQExpBuffer(qry);
3750}

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

5293{
5294 DumpOptions *dopt = fout->dopt;
5295 PQExpBuffer delq;
5296 PQExpBuffer query;
5297 PQExpBuffer publications;
5298 char *qsubname;
5299 char **pubnames = NULL;
5300 int npubnames = 0;
5301 int i;
5302
5303 /* Do nothing if not dumping schema */
5304 if (!dopt->dumpSchema)
5305 return;
5306
5307 delq = createPQExpBuffer();
5308 query = createPQExpBuffer();
5309
5310 qsubname = pg_strdup(fmtId(subinfo->dobj.name));
5311
5312 appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
5313 qsubname);
5314
5315 appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
5316 qsubname);
5317 appendStringLiteralAH(query, subinfo->subconninfo, fout);
5318
5319 /* Build list of quoted publications and append them to query. */
5320 if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
5321 pg_fatal("could not parse %s array", "subpublications");
5322
5323 publications = createPQExpBuffer();
5324 for (i = 0; i < npubnames; i++)
5325 {
5326 if (i > 0)
5327 appendPQExpBufferStr(publications, ", ");
5328
5329 appendPQExpBufferStr(publications, fmtId(pubnames[i]));
5330 }
5331
5332 appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
5333 if (subinfo->subslotname)
5334 appendStringLiteralAH(query, subinfo->subslotname, fout);
5335 else
5336 appendPQExpBufferStr(query, "NONE");
5337
5338 if (subinfo->subbinary)
5339 appendPQExpBufferStr(query, ", binary = true");
5340
5341 if (subinfo->substream == LOGICALREP_STREAM_ON)
5342 appendPQExpBufferStr(query, ", streaming = on");
5343 else if (subinfo->substream == LOGICALREP_STREAM_PARALLEL)
5344 appendPQExpBufferStr(query, ", streaming = parallel");
5345 else
5346 appendPQExpBufferStr(query, ", streaming = off");
5347
5348 if (subinfo->subtwophasestate != LOGICALREP_TWOPHASE_STATE_DISABLED)
5349 appendPQExpBufferStr(query, ", two_phase = on");
5350
5351 if (subinfo->subdisableonerr)
5352 appendPQExpBufferStr(query, ", disable_on_error = true");
5353
5354 if (!subinfo->subpasswordrequired)
5355 appendPQExpBufferStr(query, ", password_required = false");
5356
5357 if (subinfo->subrunasowner)
5358 appendPQExpBufferStr(query, ", run_as_owner = true");
5359
5360 if (subinfo->subfailover)
5361 appendPQExpBufferStr(query, ", failover = true");
5362
5363 if (strcmp(subinfo->subsynccommit, "off") != 0)
5364 appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
5365
5366 if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
5367 appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
5368
5369 appendPQExpBufferStr(query, ");\n");
5370
5371 /*
5372 * In binary-upgrade mode, we allow the replication to continue after the
5373 * upgrade.
5374 */
5375 if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5376 {
5377 if (subinfo->suboriginremotelsn)
5378 {
5379 /*
5380 * Preserve the remote_lsn for the subscriber's replication
5381 * origin. This value is required to start the replication from
5382 * the position before the upgrade. This value will be stale if
5383 * the publisher gets upgraded before the subscriber node.
5384 * However, this shouldn't be a problem as the upgrade of the
5385 * publisher ensures that all the transactions were replicated
5386 * before upgrading it.
5387 */
5389 "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
5391 "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
5392 appendStringLiteralAH(query, subinfo->dobj.name, fout);
5393 appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
5394 }
5395
5396 if (subinfo->subenabled)
5397 {
5398 /*
5399 * Enable the subscription to allow the replication to continue
5400 * after the upgrade.
5401 */
5403 "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
5404 appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
5405 }
5406 }
5407
5408 if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5409 ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
5410 ARCHIVE_OPTS(.tag = subinfo->dobj.name,
5411 .owner = subinfo->rolname,
5412 .description = "SUBSCRIPTION",
5413 .section = SECTION_POST_DATA,
5414 .createStmt = query->data,
5415 .dropStmt = delq->data));
5416
5417 if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
5418 dumpComment(fout, "SUBSCRIPTION", qsubname,
5419 NULL, subinfo->rolname,
5420 subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5421
5422 if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
5423 dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
5424 NULL, subinfo->rolname,
5425 subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
5426
5427 destroyPQExpBuffer(publications);
5428 free(pubnames);
5429
5430 destroyPQExpBuffer(delq);
5431 destroyPQExpBuffer(query);
5432 free(qsubname);
5433}
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char * suboriginremotelsn
Definition: pg_dump.h:716
bool subpasswordrequired
Definition: pg_dump.h:708
char * suborigin
Definition: pg_dump.h:715
const char * rolname
Definition: pg_dump.h:702
char * subsynccommit
Definition: pg_dump.h:713
char * subpublications
Definition: pg_dump.h:714
bool subdisableonerr
Definition: pg_dump.h:707
bool subrunasowner
Definition: pg_dump.h:709
char * subslotname
Definition: pg_dump.h:712
char subtwophasestate
Definition: pg_dump.h:706
char * subconninfo
Definition: pg_dump.h:711
DumpableObject dobj
Definition: pg_dump.h:701

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::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, and _SubscriptionInfo::subtwophasestate.

Referenced by dumpDumpableObject().

◆ dumpSubscriptionTable()

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

Definition at line 5223 of file pg_dump.c.

5224{
5225 DumpOptions *dopt = fout->dopt;
5226 SubscriptionInfo *subinfo = subrinfo->subinfo;
5227 PQExpBuffer query;
5228 char *tag;
5229
5230 /* Do nothing if not dumping schema */
5231 if (!dopt->dumpSchema)
5232 return;
5233
5234 Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
5235
5236 tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
5237
5238 query = createPQExpBuffer();
5239
5240 if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5241 {
5242 /*
5243 * binary_upgrade_add_sub_rel_state will add the subscription relation
5244 * to pg_subscription_rel table. This will be used only in
5245 * binary-upgrade mode.
5246 */
5248 "\n-- For binary upgrade, must preserve the subscriber table.\n");
5250 "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
5251 appendStringLiteralAH(query, subrinfo->dobj.name, fout);
5252 appendPQExpBuffer(query,
5253 ", %u, '%c'",
5254 subrinfo->tblinfo->dobj.catId.oid,
5255 subrinfo->srsubstate);
5256
5257 if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
5258 appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
5259 else
5260 appendPQExpBufferStr(query, ", NULL");
5261
5262 appendPQExpBufferStr(query, ");\n");
5263 }
5264
5265 /*
5266 * There is no point in creating a drop query as the drop is done by table
5267 * drop. (If you think to change this, see also _printTocEntry().)
5268 * Although this object doesn't really have ownership as such, set the
5269 * owner field anyway to ensure that the command is run by the correct
5270 * role at restore time.
5271 */
5272 if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
5273 ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
5274 ARCHIVE_OPTS(.tag = tag,
5275 .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
5276 .owner = subinfo->rolname,
5277 .description = "SUBSCRIPTION TABLE",
5278 .section = SECTION_POST_DATA,
5279 .createStmt = query->data));
5280
5281 /* These objects can't currently have comments or seclabels */
5282
5283 free(tag);
5284 destroyPQExpBuffer(query);
5285}
DumpableObject dobj
Definition: pg_dump.h:731
char * srsublsn
Definition: pg_dump.h:735
SubscriptionInfo * subinfo
Definition: pg_dump.h:732
TableInfo * tblinfo
Definition: pg_dump.h:733
char srsubstate
Definition: pg_dump.h:734

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

16529{
16530 DumpOptions *dopt = fout->dopt;
16531 DumpId tableAclDumpId = InvalidDumpId;
16532 char *namecopy;
16533
16534 /* Do nothing if not dumping schema */
16535 if (!dopt->dumpSchema)
16536 return;
16537
16538 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16539 {
16540 if (tbinfo->relkind == RELKIND_SEQUENCE)
16541 dumpSequence(fout, tbinfo);
16542 else
16543 dumpTableSchema(fout, tbinfo);
16544 }
16545
16546 /* Handle the ACL here */
16547 namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
16548 if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
16549 {
16550 const char *objtype =
16551 (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
16552
16553 tableAclDumpId =
16554 dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
16555 objtype, namecopy, NULL,
16556 tbinfo->dobj.namespace->dobj.name,
16557 NULL, tbinfo->rolname, &tbinfo->dacl);
16558 }
16559
16560 /*
16561 * Handle column ACLs, if any. Note: we pull these with a separate query
16562 * rather than trying to fetch them during getTableAttrs, so that we won't
16563 * miss ACLs on system columns. Doing it this way also allows us to dump
16564 * ACLs for catalogs that we didn't mark "interesting" back in getTables.
16565 */
16566 if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
16567 {
16569 PGresult *res;
16570 int i;
16571
16573 {
16574 /* Set up query for column ACLs */
16576 "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
16577
16578 if (fout->remoteVersion >= 90600)
16579 {
16580 /*
16581 * In principle we should call acldefault('c', relowner) to
16582 * get the default ACL for a column. However, we don't
16583 * currently store the numeric OID of the relowner in
16584 * TableInfo. We could convert the owner name using regrole,
16585 * but that creates a risk of failure due to concurrent role
16586 * renames. Given that the default ACL for columns is empty
16587 * and is likely to stay that way, it's not worth extra cycles
16588 * and risk to avoid hard-wiring that knowledge here.
16589 */
16591 "SELECT at.attname, "
16592 "at.attacl, "
16593 "'{}' AS acldefault, "
16594 "pip.privtype, pip.initprivs "
16595 "FROM pg_catalog.pg_attribute at "
16596 "LEFT JOIN pg_catalog.pg_init_privs pip ON "
16597 "(at.attrelid = pip.objoid "
16598 "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
16599 "AND at.attnum = pip.objsubid) "
16600 "WHERE at.attrelid = $1 AND "
16601 "NOT at.attisdropped "
16602 "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
16603 "ORDER BY at.attnum");
16604 }
16605 else
16606 {
16608 "SELECT attname, attacl, '{}' AS acldefault, "
16609 "NULL AS privtype, NULL AS initprivs "
16610 "FROM pg_catalog.pg_attribute "
16611 "WHERE attrelid = $1 AND NOT attisdropped "
16612 "AND attacl IS NOT NULL "
16613 "ORDER BY attnum");
16614 }
16615
16616 ExecuteSqlStatement(fout, query->data);
16617
16619 }
16620
16621 printfPQExpBuffer(query,
16622 "EXECUTE getColumnACLs('%u')",
16623 tbinfo->dobj.catId.oid);
16624
16625 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16626
16627 for (i = 0; i < PQntuples(res); i++)
16628 {
16629 char *attname = PQgetvalue(res, i, 0);
16630 char *attacl = PQgetvalue(res, i, 1);
16631 char *acldefault = PQgetvalue(res, i, 2);
16632 char privtype = *(PQgetvalue(res, i, 3));
16633 char *initprivs = PQgetvalue(res, i, 4);
16634 DumpableAcl coldacl;
16635 char *attnamecopy;
16636
16637 coldacl.acl = attacl;
16638 coldacl.acldefault = acldefault;
16639 coldacl.privtype = privtype;
16640 coldacl.initprivs = initprivs;
16641 attnamecopy = pg_strdup(fmtId(attname));
16642
16643 /*
16644 * Column's GRANT type is always TABLE. Each column ACL depends
16645 * on the table-level ACL, since we can restore column ACLs in
16646 * parallel but the table-level ACL has to be done first.
16647 */
16648 dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
16649 "TABLE", namecopy, attnamecopy,
16650 tbinfo->dobj.namespace->dobj.name,
16651 NULL, tbinfo->rolname, &coldacl);
16652 free(attnamecopy);
16653 }
16654 PQclear(res);
16655 destroyPQExpBuffer(query);
16656 }
16657
16658 free(namecopy);
16659}
@ PREPQUERY_GETCOLUMNACLS
Definition: pg_backup.h:76
static void dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16757
static void dumpSequence(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:18562
DumpableAcl dacl
Definition: pg_dump.h:301
bool hascolumnACLs
Definition: pg_dump.h:314

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

17723{
17724 DumpOptions *dopt = fout->dopt;
17725 PQExpBuffer q;
17726 PGresult *res;
17727 char *partbound;
17728
17729 /* Do nothing if not dumping schema */
17730 if (!dopt->dumpSchema)
17731 return;
17732
17733 q = createPQExpBuffer();
17734
17736 {
17737 /* Set up query for partbound details */
17739 "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
17740
17742 "SELECT pg_get_expr(c.relpartbound, c.oid) "
17743 "FROM pg_class c "
17744 "WHERE c.oid = $1");
17745
17746 ExecuteSqlStatement(fout, q->data);
17747
17749 }
17750
17752 "EXECUTE dumpTableAttach('%u')",
17753 attachinfo->partitionTbl->dobj.catId.oid);
17754
17755 res = ExecuteSqlQueryForSingleRow(fout, q->data);
17756 partbound = PQgetvalue(res, 0, 0);
17757
17758 /* Perform ALTER TABLE on the parent */
17760 "ALTER TABLE ONLY %s ",
17761 fmtQualifiedDumpable(attachinfo->parentTbl));
17763 "ATTACH PARTITION %s %s;\n",
17765 partbound);
17766
17767 /*
17768 * There is no point in creating a drop query as the drop is done by table
17769 * drop. (If you think to change this, see also _printTocEntry().)
17770 * Although this object doesn't really have ownership as such, set the
17771 * owner field anyway to ensure that the command is run by the correct
17772 * role at restore time.
17773 */
17774 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
17775 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
17776 .namespace = attachinfo->dobj.namespace->dobj.name,
17777 .owner = attachinfo->partitionTbl->rolname,
17778 .description = "TABLE ATTACH",
17779 .section = SECTION_PRE_DATA,
17780 .createStmt = q->data));
17781
17782 PQclear(res);
17784}
@ PREPQUERY_DUMPTABLEATTACH
Definition: pg_backup.h:74
TableInfo * partitionTbl
Definition: pg_dump.h:391
DumpableObject dobj
Definition: pg_dump.h:389
TableInfo * parentTbl
Definition: pg_dump.h:390

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

11119{
11120 DumpOptions *dopt = fout->dopt;
11122 int ncomments;
11123 PQExpBuffer query;
11124 PQExpBuffer tag;
11125
11126 /* do nothing, if --no-comments is supplied */
11127 if (dopt->no_comments)
11128 return;
11129
11130 /* Comments are SCHEMA not data */
11131 if (!dopt->dumpSchema)
11132 return;
11133
11134 /* Search for comments associated with relation, using table */
11136 tbinfo->dobj.catId.oid,
11137 &comments);
11138
11139 /* If comments exist, build COMMENT ON statements */
11140 if (ncomments <= 0)
11141 return;
11142
11143 query = createPQExpBuffer();
11144 tag = createPQExpBuffer();
11145
11146 while (ncomments > 0)
11147 {
11148 const char *descr = comments->descr;
11149 int objsubid = comments->objsubid;
11150
11151 if (objsubid == 0)
11152 {
11153 resetPQExpBuffer(tag);
11154 appendPQExpBuffer(tag, "%s %s", reltypename,
11155 fmtId(tbinfo->dobj.name));
11156
11157 resetPQExpBuffer(query);
11158 appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
11159 fmtQualifiedDumpable(tbinfo));
11160 appendStringLiteralAH(query, descr, fout);
11161 appendPQExpBufferStr(query, ";\n");
11162
11164 ARCHIVE_OPTS(.tag = tag->data,
11165 .namespace = tbinfo->dobj.namespace->dobj.name,
11166 .owner = tbinfo->rolname,
11167 .description = "COMMENT",
11168 .section = SECTION_NONE,
11169 .createStmt = query->data,
11170 .deps = &(tbinfo->dobj.dumpId),
11171 .nDeps = 1));
11172 }
11173 else if (objsubid > 0 && objsubid <= tbinfo->numatts)
11174 {
11175 resetPQExpBuffer(tag);
11176 appendPQExpBuffer(tag, "COLUMN %s.",
11177 fmtId(tbinfo->dobj.name));
11178 appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
11179
11180 resetPQExpBuffer(query);
11181 appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
11182 fmtQualifiedDumpable(tbinfo));
11183 appendPQExpBuffer(query, "%s IS ",
11184 fmtId(tbinfo->attnames[objsubid - 1]));
11185 appendStringLiteralAH(query, descr, fout);
11186 appendPQExpBufferStr(query, ";\n");
11187
11189 ARCHIVE_OPTS(.tag = tag->data,
11190 .namespace = tbinfo->dobj.namespace->dobj.name,
11191 .owner = tbinfo->rolname,
11192 .description = "COMMENT",
11193 .section = SECTION_NONE,
11194 .createStmt = query->data,
11195 .deps = &(tbinfo->dobj.dumpId),
11196 .nDeps = 1));
11197 }
11198
11199 comments++;
11200 ncomments--;
11201 }
11202
11203 destroyPQExpBuffer(query);
11204 destroyPQExpBuffer(tag);
11205}

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

18448{
18449 TableInfo *tbinfo = coninfo->contable;
18450 PQExpBuffer conprefix = createPQExpBuffer();
18451 char *qtabname;
18452
18453 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18454
18455 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
18456 fmtId(coninfo->dobj.name));
18457
18458 if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18459 dumpComment(fout, conprefix->data, qtabname,
18460 tbinfo->dobj.namespace->dobj.name,
18461 tbinfo->rolname,
18462 coninfo->dobj.catId, 0,
18463 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
18464
18465 destroyPQExpBuffer(conprefix);
18466 free(qtabname);
18467}

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

2783{
2784 DumpOptions *dopt = fout->dopt;
2785 TableInfo *tbinfo = tdinfo->tdtable;
2786 PQExpBuffer copyBuf = createPQExpBuffer();
2787 PQExpBuffer clistBuf = createPQExpBuffer();
2788 DataDumperPtr dumpFn;
2789 char *tdDefn = NULL;
2790 char *copyStmt;
2791 const char *copyFrom;
2792
2793 /* We had better have loaded per-column details about this table */
2794 Assert(tbinfo->interesting);
2795
2796 /*
2797 * When load-via-partition-root is set or forced, get the root table name
2798 * for the partition table, so that we can reload data through the root
2799 * table. Then construct a comment to be inserted into the TOC entry's
2800 * defn field, so that such cases can be identified reliably.
2801 */
2802 if (tbinfo->ispartition &&
2803 (dopt->load_via_partition_root ||
2804 forcePartitionRootLoad(tbinfo)))
2805 {
2806 TableInfo *parentTbinfo;
2807
2808 parentTbinfo = getRootTableInfo(tbinfo);
2809 copyFrom = fmtQualifiedDumpable(parentTbinfo);
2810 printfPQExpBuffer(copyBuf, "-- load via partition root %s",
2811 copyFrom);
2812 tdDefn = pg_strdup(copyBuf->data);
2813 }
2814 else
2815 copyFrom = fmtQualifiedDumpable(tbinfo);
2816
2817 if (dopt->dump_inserts == 0)
2818 {
2819 /* Dump/restore using COPY */
2820 dumpFn = dumpTableData_copy;
2821 /* must use 2 steps here 'cause fmtId is nonreentrant */
2822 printfPQExpBuffer(copyBuf, "COPY %s ",
2823 copyFrom);
2824 appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
2825 fmtCopyColumnList(tbinfo, clistBuf));
2826 copyStmt = copyBuf->data;
2827 }
2828 else
2829 {
2830 /* Restore using INSERT */
2831 dumpFn = dumpTableData_insert;
2832 copyStmt = NULL;
2833 }
2834
2835 /*
2836 * Note: although the TableDataInfo is a full DumpableObject, we treat its
2837 * dependency on its table as "special" and pass it to ArchiveEntry now.
2838 * See comments for BuildArchiveDependencies.
2839 */
2840 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2841 {
2842 TocEntry *te;
2843
2844 te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
2845 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2846 .namespace = tbinfo->dobj.namespace->dobj.name,
2847 .owner = tbinfo->rolname,
2848 .description = "TABLE DATA",
2849 .section = SECTION_DATA,
2850 .createStmt = tdDefn,
2851 .copyStmt = copyStmt,
2852 .deps = &(tbinfo->dobj.dumpId),
2853 .nDeps = 1,
2854 .dumpFn = dumpFn,
2855 .dumpArg = tdinfo));
2856
2857 /*
2858 * Set the TocEntry's dataLength in case we are doing a parallel dump
2859 * and want to order dump jobs by table size. We choose to measure
2860 * dataLength in table pages (including TOAST pages) during dump, so
2861 * no scaling is needed.
2862 *
2863 * However, relpages is declared as "integer" in pg_class, and hence
2864 * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
2865 * Cast so that we get the right interpretation of table sizes
2866 * exceeding INT_MAX pages.
2867 */
2868 te->dataLength = (BlockNumber) tbinfo->relpages;
2869 te->dataLength += (BlockNumber) tbinfo->toastpages;
2870
2871 /*
2872 * If pgoff_t is only 32 bits wide, the above refinement is useless,
2873 * and instead we'd better worry about integer overflow. Clamp to
2874 * INT_MAX if the correct result exceeds that.
2875 */
2876 if (sizeof(te->dataLength) == 4 &&
2877 (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
2878 te->dataLength < 0))
2879 te->dataLength = INT_MAX;
2880 }
2881
2882 destroyPQExpBuffer(copyBuf);
2883 destroyPQExpBuffer(clistBuf);
2884}
uint32 BlockNumber
Definition: block.h:31
int(* DataDumperPtr)(Archive *AH, const void *userArg)
static bool forcePartitionRootLoad(const TableInfo *tbinfo)
Definition: pg_dump.c:2754
static int dumpTableData_copy(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2292
static const char * fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
Definition: pg_dump.c:20003
static int dumpTableData_insert(Archive *fout, const void *dcontext)
Definition: pg_dump.c:2460
static TableInfo * getRootTableInfo(const TableInfo *tbinfo)
Definition: pg_dump.c:2729
int dump_inserts
Definition: pg_backup.h:178
int load_via_partition_root
Definition: pg_backup.h:197
bool interesting
Definition: pg_dump.h:334
int toastpages
Definition: pg_dump.h:332
int32 relpages
Definition: pg_dump.h:331

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

Referenced by dumpDumpableObject().

◆ dumpTableData_copy()

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

Definition at line 2292 of file pg_dump.c.

2293{
2294 TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2295 TableInfo *tbinfo = tdinfo->tdtable;
2296 const char *classname = tbinfo->dobj.name;
2298
2299 /*
2300 * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
2301 * which uses it already.
2302 */
2303 PQExpBuffer clistBuf = createPQExpBuffer();
2304 PGconn *conn = GetConnection(fout);
2305 PGresult *res;
2306 int ret;
2307 char *copybuf;
2308 const char *column_list;
2309
2310 pg_log_info("dumping contents of table \"%s.%s\"",
2311 tbinfo->dobj.namespace->dobj.name, classname);
2312
2313 /*
2314 * Specify the column list explicitly so that we have no possibility of
2315 * retrieving data in the wrong column order. (The default column
2316 * ordering of COPY will not be what we want in certain corner cases
2317 * involving ADD COLUMN and inheritance.)
2318 */
2319 column_list = fmtCopyColumnList(tbinfo, clistBuf);
2320
2321 /*
2322 * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
2323 * a filter condition was specified. For other cases a simple COPY
2324 * suffices.
2325 */
2326 if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2327 {
2328 /* Temporary allows to access to foreign tables to dump data */
2329 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2330 set_restrict_relation_kind(fout, "view");
2331
2332 appendPQExpBufferStr(q, "COPY (SELECT ");
2333 /* klugery to get rid of parens in column list */
2334 if (strlen(column_list) > 2)
2335 {
2336 appendPQExpBufferStr(q, column_list + 1);
2337 q->data[q->len - 1] = ' ';
2338 }
2339 else
2340 appendPQExpBufferStr(q, "* ");
2341
2342 appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
2343 fmtQualifiedDumpable(tbinfo),
2344 tdinfo->filtercond ? tdinfo->filtercond : "");
2345 }
2346 else
2347 {
2348 appendPQExpBuffer(q, "COPY %s %s TO stdout;",
2349 fmtQualifiedDumpable(tbinfo),
2350 column_list);
2351 }
2352 res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
2353 PQclear(res);
2354 destroyPQExpBuffer(clistBuf);
2355
2356 for (;;)
2357 {
2358 ret = PQgetCopyData(conn, &copybuf, 0);
2359
2360 if (ret < 0)
2361 break; /* done or error */
2362
2363 if (copybuf)
2364 {
2365 WriteData(fout, copybuf, ret);
2367 }
2368
2369 /* ----------
2370 * THROTTLE:
2371 *
2372 * There was considerable discussion in late July, 2000 regarding
2373 * slowing down pg_dump when backing up large tables. Users with both
2374 * slow & fast (multi-processor) machines experienced performance
2375 * degradation when doing a backup.
2376 *
2377 * Initial attempts based on sleeping for a number of ms for each ms
2378 * of work were deemed too complex, then a simple 'sleep in each loop'
2379 * implementation was suggested. The latter failed because the loop
2380 * was too tight. Finally, the following was implemented:
2381 *
2382 * If throttle is non-zero, then
2383 * See how long since the last sleep.
2384 * Work out how long to sleep (based on ratio).
2385 * If sleep is more than 100ms, then
2386 * sleep
2387 * reset timer
2388 * EndIf
2389 * EndIf
2390 *
2391 * where the throttle value was the number of ms to sleep per ms of
2392 * work. The calculation was done in each loop.
2393 *
2394 * Most of the hard work is done in the backend, and this solution
2395 * still did not work particularly well: on slow machines, the ratio
2396 * was 50:1, and on medium paced machines, 1:1, and on fast
2397 * multi-processor machines, it had little or no effect, for reasons
2398 * that were unclear.
2399 *
2400 * Further discussion ensued, and the proposal was dropped.
2401 *
2402 * For those people who want this feature, it can be implemented using
2403 * gettimeofday in each loop, calculating the time since last sleep,
2404 * multiplying that by the sleep ratio, then if the result is more
2405 * than a preset 'minimum sleep time' (say 100ms), call the 'select'
2406 * function to sleep for a subsecond period ie.
2407 *
2408 * select(0, NULL, NULL, NULL, &tvi);
2409 *
2410 * This will return after the interval specified in the structure tvi.
2411 * Finally, call gettimeofday again to save the 'last sleep time'.
2412 * ----------
2413 */
2414 }
2415 archprintf(fout, "\\.\n\n\n");
2416
2417 if (ret == -2)
2418 {
2419 /* copy data transfer failed */
2420 pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
2421 pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2422 pg_log_error_detail("Command was: %s", q->data);
2423 exit_nicely(1);
2424 }
2425
2426 /* Check command status and return to normal libpq state */
2427 res = PQgetResult(conn);
2428 if (PQresultStatus(res) != PGRES_COMMAND_OK)
2429 {
2430 pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
2431 pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
2432 pg_log_error_detail("Command was: %s", q->data);
2433 exit_nicely(1);
2434 }
2435 PQclear(res);
2436
2437 /* Do this to ensure we've pumped libpq back to idle state */
2438 if (PQgetResult(conn) != NULL)
2439 pg_log_warning("unexpected extra results during COPY of table \"%s\"",
2440 classname);
2441
2443
2444 /* Revert back the setting */
2445 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2446 set_restrict_relation_kind(fout, "view, foreign-table");
2447
2448 return 1;
2449}
void PQfreemem(void *ptr)
Definition: fe-exec.c:4032
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2062
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2816
@ 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:4918
char * filtercond
Definition: pg_dump.h:407
static StringInfo copybuf
Definition: tablesync.c:137

References appendPQExpBuffer(), appendPQExpBufferStr(), archprintf(), conn, copybuf, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, ExecuteSqlQuery(), exit_nicely(), _tableDataInfo::filtercond, fmtCopyColumnList(), fmtQualifiedDumpable, GetConnection(), PQExpBufferData::len, _dumpableObject::name, pg_log_error, pg_log_error_detail, pg_log_info, pg_log_warning, PGRES_COMMAND_OK, PGRES_COPY_OUT, PQclear(), PQerrorMessage(), PQfreemem(), PQgetCopyData(), PQgetResult(), PQresultStatus(), _tableInfo::relkind, 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 2460 of file pg_dump.c.

2461{
2462 TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
2463 TableInfo *tbinfo = tdinfo->tdtable;
2464 DumpOptions *dopt = fout->dopt;
2466 PQExpBuffer insertStmt = NULL;
2467 char *attgenerated;
2468 PGresult *res;
2469 int nfields,
2470 i;
2471 int rows_per_statement = dopt->dump_inserts;
2472 int rows_this_statement = 0;
2473
2474 /* Temporary allows to access to foreign tables to dump data */
2475 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2476 set_restrict_relation_kind(fout, "view");
2477
2478 /*
2479 * If we're going to emit INSERTs with column names, the most efficient
2480 * way to deal with generated columns is to exclude them entirely. For
2481 * INSERTs without column names, we have to emit DEFAULT rather than the
2482 * actual column value --- but we can save a few cycles by fetching nulls
2483 * rather than the uninteresting-to-us value.
2484 */
2485 attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
2486 appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
2487 nfields = 0;
2488 for (i = 0; i < tbinfo->numatts; i++)
2489 {
2490 if (tbinfo->attisdropped[i])
2491 continue;
2492 if (tbinfo->attgenerated[i] && dopt->column_inserts)
2493 continue;
2494 if (nfields > 0)
2495 appendPQExpBufferStr(q, ", ");
2496 if (tbinfo->attgenerated[i])
2497 appendPQExpBufferStr(q, "NULL");
2498 else
2499 appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
2500 attgenerated[nfields] = tbinfo->attgenerated[i];
2501 nfields++;
2502 }
2503 /* Servers before 9.4 will complain about zero-column SELECT */
2504 if (nfields == 0)
2505 appendPQExpBufferStr(q, "NULL");
2506 appendPQExpBuffer(q, " FROM ONLY %s",
2507 fmtQualifiedDumpable(tbinfo));
2508 if (tdinfo->filtercond)
2509 appendPQExpBuffer(q, " %s", tdinfo->filtercond);
2510
2511 ExecuteSqlStatement(fout, q->data);
2512
2513 while (1)
2514 {
2515 res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
2517
2518 /* cross-check field count, allowing for dummy NULL if any */
2519 if (nfields != PQnfields(res) &&
2520 !(nfields == 0 && PQnfields(res) == 1))
2521 pg_fatal("wrong number of fields retrieved from table \"%s\"",
2522 tbinfo->dobj.name);
2523
2524 /*
2525 * First time through, we build as much of the INSERT statement as
2526 * possible in "insertStmt", which we can then just print for each
2527 * statement. If the table happens to have zero dumpable columns then
2528 * this will be a complete statement, otherwise it will end in
2529 * "VALUES" and be ready to have the row's column values printed.
2530 */
2531 if (insertStmt == NULL)
2532 {
2533 TableInfo *targettab;
2534
2535 insertStmt = createPQExpBuffer();
2536
2537 /*
2538 * When load-via-partition-root is set or forced, get the root
2539 * table name for the partition table, so that we can reload data
2540 * through the root table.
2541 */
2542 if (tbinfo->ispartition &&
2543 (dopt->load_via_partition_root ||
2544 forcePartitionRootLoad(tbinfo)))
2545 targettab = getRootTableInfo(tbinfo);
2546 else
2547 targettab = tbinfo;
2548
2549 appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
2550 fmtQualifiedDumpable(targettab));
2551
2552 /* corner case for zero-column table */
2553 if (nfields == 0)
2554 {
2555 appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
2556 }
2557 else
2558 {
2559 /* append the list of column names if required */
2560 if (dopt->column_inserts)
2561 {
2562 appendPQExpBufferChar(insertStmt, '(');
2563 for (int field = 0; field < nfields; field++)
2564 {
2565 if (field > 0)
2566 appendPQExpBufferStr(insertStmt, ", ");
2567 appendPQExpBufferStr(insertStmt,
2568 fmtId(PQfname(res, field)));
2569 }
2570 appendPQExpBufferStr(insertStmt, ") ");
2571 }
2572
2573 if (tbinfo->needs_override)
2574 appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
2575
2576 appendPQExpBufferStr(insertStmt, "VALUES");
2577 }
2578 }
2579
2580 for (int tuple = 0; tuple < PQntuples(res); tuple++)
2581 {
2582 /* Write the INSERT if not in the middle of a multi-row INSERT. */
2583 if (rows_this_statement == 0)
2584 archputs(insertStmt->data, fout);
2585
2586 /*
2587 * If it is zero-column table then we've already written the
2588 * complete statement, which will mean we've disobeyed
2589 * --rows-per-insert when it's set greater than 1. We do support
2590 * a way to make this multi-row with: SELECT UNION ALL SELECT
2591 * UNION ALL ... but that's non-standard so we should avoid it
2592 * given that using INSERTs is mostly only ever needed for
2593 * cross-database exports.
2594 */
2595 if (nfields == 0)
2596 continue;
2597
2598 /* Emit a row heading */
2599 if (rows_per_statement == 1)
2600 archputs(" (", fout);
2601 else if (rows_this_statement > 0)
2602 archputs(",\n\t(", fout);
2603 else
2604 archputs("\n\t(", fout);
2605
2606 for (int field = 0; field < nfields; field++)
2607 {
2608 if (field > 0)
2609 archputs(", ", fout);
2610 if (attgenerated[field])
2611 {
2612 archputs("DEFAULT", fout);
2613 continue;
2614 }
2615 if (PQgetisnull(res, tuple, field))
2616 {
2617 archputs("NULL", fout);
2618 continue;
2619 }
2620
2621 /* XXX This code is partially duplicated in ruleutils.c */
2622 switch (PQftype(res, field))
2623 {
2624 case INT2OID:
2625 case INT4OID:
2626 case INT8OID:
2627 case OIDOID:
2628 case FLOAT4OID:
2629 case FLOAT8OID:
2630 case NUMERICOID:
2631 {
2632 /*
2633 * These types are printed without quotes unless
2634 * they contain values that aren't accepted by the
2635 * scanner unquoted (e.g., 'NaN'). Note that
2636 * strtod() and friends might accept NaN, so we
2637 * can't use that to test.
2638 *
2639 * In reality we only need to defend against
2640 * infinity and NaN, so we need not get too crazy
2641 * about pattern matching here.
2642 */
2643 const char *s = PQgetvalue(res, tuple, field);
2644
2645 if (strspn(s, "0123456789 +-eE.") == strlen(s))
2646 archputs(s, fout);
2647 else
2648 archprintf(fout, "'%s'", s);
2649 }
2650 break;
2651
2652 case BITOID:
2653 case VARBITOID:
2654 archprintf(fout, "B'%s'",
2655 PQgetvalue(res, tuple, field));
2656 break;
2657
2658 case BOOLOID:
2659 if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
2660 archputs("true", fout);
2661 else
2662 archputs("false", fout);
2663 break;
2664
2665 default:
2666 /* All other types are printed as string literals. */
2669 PQgetvalue(res, tuple, field),
2670 fout);
2671 archputs(q->data, fout);
2672 break;
2673 }
2674 }
2675
2676 /* Terminate the row ... */
2677 archputs(")", fout);
2678
2679 /* ... and the statement, if the target no. of rows is reached */
2680 if (++rows_this_statement >= rows_per_statement)
2681 {
2682 if (dopt->do_nothing)
2683 archputs(" ON CONFLICT DO NOTHING;\n", fout);
2684 else
2685 archputs(";\n", fout);
2686 /* Reset the row counter */
2687 rows_this_statement = 0;
2688 }
2689 }
2690
2691 if (PQntuples(res) <= 0)
2692 {
2693 PQclear(res);
2694 break;
2695 }
2696 PQclear(res);
2697 }
2698
2699 /* Terminate any statements that didn't make the row count. */
2700 if (rows_this_statement > 0)
2701 {
2702 if (dopt->do_nothing)
2703 archputs(" ON CONFLICT DO NOTHING;\n", fout);
2704 else
2705 archputs(";\n", fout);
2706 }
2707
2708 archputs("\n\n", fout);
2709
2710 ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
2711
2713 if (insertStmt != NULL)
2714 destroyPQExpBuffer(insertStmt);
2715 free(attgenerated);
2716
2717 /* Revert back the setting */
2718 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2719 set_restrict_relation_kind(fout, "view, foreign-table");
2720
2721 return 1;
2722}
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3719
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3567
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3489
void archputs(const char *s, Archive *AH)
int column_inserts
Definition: pg_backup.h:182
int do_nothing
Definition: pg_backup.h:210
char * attgenerated
Definition: pg_dump.h:355
bool * attisdropped
Definition: pg_dump.h:353
bool needs_override
Definition: pg_dump.h:374

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

16758{
16759 DumpOptions *dopt = fout->dopt;
16763 char *qrelname;
16764 char *qualrelname;
16765 int numParents;
16766 TableInfo **parents;
16767 int actual_atts; /* number of attrs in this CREATE statement */
16768 const char *reltypename;
16769 char *storage;
16770 int j,
16771 k;
16772
16773 /* We had better have loaded per-column details about this table */
16774 Assert(tbinfo->interesting);
16775
16776 qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
16777 qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
16778
16779 if (tbinfo->hasoids)
16780 pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
16781 qrelname);
16782
16783 if (dopt->binary_upgrade)
16784 binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
16785
16786 /* Is it a table or a view? */
16787 if (tbinfo->relkind == RELKIND_VIEW)
16788 {
16789 PQExpBuffer result;
16790
16791 /*
16792 * Note: keep this code in sync with the is_view case in dumpRule()
16793 */
16794
16795 reltypename = "VIEW";
16796
16797 appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
16798
16799 if (dopt->binary_upgrade)
16801 tbinfo->dobj.catId.oid);
16802
16803 appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
16804
16805 if (tbinfo->dummy_view)
16806 result = createDummyViewAsClause(fout, tbinfo);
16807 else
16808 {
16809 if (nonemptyReloptions(tbinfo->reloptions))
16810 {
16811 appendPQExpBufferStr(q, " WITH (");
16812 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
16813 appendPQExpBufferChar(q, ')');
16814 }
16815 result = createViewAsClause(fout, tbinfo);
16816 }
16817 appendPQExpBuffer(q, " AS\n%s", result->data);
16818 destroyPQExpBuffer(result);
16819
16820 if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
16821 appendPQExpBuffer(q, "\n WITH %s CHECK OPTION", tbinfo->checkoption);
16822 appendPQExpBufferStr(q, ";\n");
16823 }
16824 else
16825 {
16826 char *partkeydef = NULL;
16827 char *ftoptions = NULL;
16828 char *srvname = NULL;
16829 const char *foreign = "";
16830
16831 /*
16832 * Set reltypename, and collect any relkind-specific data that we
16833 * didn't fetch during getTables().
16834 */
16835 switch (tbinfo->relkind)
16836 {
16837 case RELKIND_PARTITIONED_TABLE:
16838 {
16840 PGresult *res;
16841
16842 reltypename = "TABLE";
16843
16844 /* retrieve partition key definition */
16845 appendPQExpBuffer(query,
16846 "SELECT pg_get_partkeydef('%u')",
16847 tbinfo->dobj.catId.oid);
16848 res = ExecuteSqlQueryForSingleRow(fout, query->data);
16849 partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
16850 PQclear(res);
16851 destroyPQExpBuffer(query);
16852 break;
16853 }
16854 case RELKIND_FOREIGN_TABLE:
16855 {
16857 PGresult *res;
16858 int i_srvname;
16859 int i_ftoptions;
16860
16861 reltypename = "FOREIGN TABLE";
16862
16863 /* retrieve name of foreign server and generic options */
16864 appendPQExpBuffer(query,
16865 "SELECT fs.srvname, "
16866 "pg_catalog.array_to_string(ARRAY("
16867 "SELECT pg_catalog.quote_ident(option_name) || "
16868 "' ' || pg_catalog.quote_literal(option_value) "
16869 "FROM pg_catalog.pg_options_to_table(ftoptions) "
16870 "ORDER BY option_name"
16871 "), E',\n ') AS ftoptions "
16872 "FROM pg_catalog.pg_foreign_table ft "
16873 "JOIN pg_catalog.pg_foreign_server fs "
16874 "ON (fs.oid = ft.ftserver) "
16875 "WHERE ft.ftrelid = '%u'",
16876 tbinfo->dobj.catId.oid);
16877 res = ExecuteSqlQueryForSingleRow(fout, query->data);
16878 i_srvname = PQfnumber(res, "srvname");
16879 i_ftoptions = PQfnumber(res, "ftoptions");
16880 srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
16881 ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
16882 PQclear(res);
16883 destroyPQExpBuffer(query);
16884
16885 foreign = "FOREIGN ";
16886 break;
16887 }
16888 case RELKIND_MATVIEW:
16889 reltypename = "MATERIALIZED VIEW";
16890 break;
16891 default:
16892 reltypename = "TABLE";
16893 break;
16894 }
16895
16896 numParents = tbinfo->numParents;
16897 parents = tbinfo->parents;
16898
16899 appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
16900
16901 if (dopt->binary_upgrade)
16903 tbinfo->dobj.catId.oid);
16904
16905 /*
16906 * PostgreSQL 18 has disabled UNLOGGED for partitioned tables, so
16907 * ignore it when dumping if it was set in this case.
16908 */
16909 appendPQExpBuffer(q, "CREATE %s%s %s",
16910 (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
16911 tbinfo->relkind != RELKIND_PARTITIONED_TABLE) ?
16912 "UNLOGGED " : "",
16913 reltypename,
16914 qualrelname);
16915
16916 /*
16917 * Attach to type, if reloftype; except in case of a binary upgrade,
16918 * we dump the table normally and attach it to the type afterward.
16919 */
16920 if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
16921 appendPQExpBuffer(q, " OF %s",
16922 getFormattedTypeName(fout, tbinfo->reloftype,
16923 zeroIsError));
16924
16925 if (tbinfo->relkind != RELKIND_MATVIEW)
16926 {
16927 /* Dump the attributes */
16928 actual_atts = 0;
16929 for (j = 0; j < tbinfo->numatts; j++)
16930 {
16931 /*
16932 * Normally, dump if it's locally defined in this table, and
16933 * not dropped. But for binary upgrade, we'll dump all the
16934 * columns, and then fix up the dropped and nonlocal cases
16935 * below.
16936 */
16937 if (shouldPrintColumn(dopt, tbinfo, j))
16938 {
16939 bool print_default;
16940 bool print_notnull;
16941
16942 /*
16943 * Default value --- suppress if to be printed separately
16944 * or not at all.
16945 */
16946 print_default = (tbinfo->attrdefs[j] != NULL &&
16947 tbinfo->attrdefs[j]->dobj.dump &&
16948 !tbinfo->attrdefs[j]->separate);
16949
16950 /*
16951 * Not Null constraint --- print it if it is locally
16952 * defined, or if binary upgrade. (In the latter case, we
16953 * reset conislocal below.)
16954 */
16955 print_notnull = (tbinfo->notnull_constrs[j] != NULL &&
16956 (tbinfo->notnull_islocal[j] ||
16957 dopt->binary_upgrade ||
16958 tbinfo->ispartition));
16959
16960 /*
16961 * Skip column if fully defined by reloftype, except in
16962 * binary upgrade
16963 */
16964 if (OidIsValid(tbinfo->reloftype) &&
16965 !print_default && !print_notnull &&
16966 !dopt->binary_upgrade)
16967 continue;
16968
16969 /* Format properly if not first attr */
16970 if (actual_atts == 0)
16971 appendPQExpBufferStr(q, " (");
16972 else
16973 appendPQExpBufferChar(q, ',');
16974 appendPQExpBufferStr(q, "\n ");
16975 actual_atts++;
16976
16977 /* Attribute name */
16978 appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
16979
16980 if (tbinfo->attisdropped[j])
16981 {
16982 /*
16983 * ALTER TABLE DROP COLUMN clears
16984 * pg_attribute.atttypid, so we will not have gotten a
16985 * valid type name; insert INTEGER as a stopgap. We'll
16986 * clean things up later.
16987 */
16988 appendPQExpBufferStr(q, " INTEGER /* dummy */");
16989 /* and skip to the next column */
16990 continue;
16991 }
16992
16993 /*
16994 * Attribute type; print it except when creating a typed
16995 * table ('OF type_name'), but in binary-upgrade mode,
16996 * print it in that case too.
16997 */
16998 if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
16999 {
17000 appendPQExpBuffer(q, " %s",
17001 tbinfo->atttypnames[j]);
17002 }
17003
17004 if (print_default)
17005 {
17006 if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
17007 appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
17008 tbinfo->attrdefs[j]->adef_expr);
17009 else if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_VIRTUAL)
17010 appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s)",
17011 tbinfo->attrdefs[j]->adef_expr);
17012 else
17013 appendPQExpBuffer(q, " DEFAULT %s",
17014 tbinfo->attrdefs[j]->adef_expr);
17015 }
17016
17017 if (print_notnull)
17018 {
17019 if (tbinfo->notnull_constrs[j][0] == '\0')
17020 appendPQExpBufferStr(q, " NOT NULL");
17021 else
17022 appendPQExpBuffer(q, " CONSTRAINT %s NOT NULL",
17023 fmtId(tbinfo->notnull_constrs[j]));
17024
17025 if (tbinfo->notnull_noinh[j])
17026 appendPQExpBufferStr(q, " NO INHERIT");
17027 }
17028
17029 /* Add collation if not default for the type */
17030 if (OidIsValid(tbinfo->attcollation[j]))
17031 {
17032 CollInfo *coll;
17033
17034 coll = findCollationByOid(tbinfo->attcollation[j]);
17035 if (coll)
17036 appendPQExpBuffer(q, " COLLATE %s",
17037 fmtQualifiedDumpable(coll));
17038 }
17039 }
17040
17041 /*
17042 * On the other hand, if we choose not to print a column
17043 * (likely because it is created by inheritance), but the
17044 * column has a locally-defined not-null constraint, we need
17045 * to dump the constraint as a standalone object.
17046 *
17047 * This syntax isn't SQL-conforming, but if you wanted
17048 * standard output you wouldn't be creating non-standard
17049 * objects to begin with.
17050 */
17051 if (!shouldPrintColumn(dopt, tbinfo, j) &&
17052 !tbinfo->attisdropped[j] &&
17053 tbinfo->notnull_constrs[j] != NULL &&
17054 tbinfo->notnull_islocal[j])
17055 {
17056 /* Format properly if not first attr */
17057 if (actual_atts == 0)
17058 appendPQExpBufferStr(q, " (");
17059 else
17060 appendPQExpBufferChar(q, ',');
17061 appendPQExpBufferStr(q, "\n ");
17062 actual_atts++;
17063
17064 if (tbinfo->notnull_constrs[j][0] == '\0')
17065 appendPQExpBuffer(q, "NOT NULL %s",
17066 fmtId(tbinfo->attnames[j]));
17067 else
17068 appendPQExpBuffer(q, "CONSTRAINT %s NOT NULL %s",
17069 tbinfo->notnull_constrs[j],
17070 fmtId(tbinfo->attnames[j]));
17071 }
17072 }
17073
17074 /*
17075 * Add non-inherited CHECK constraints, if any.
17076 *
17077 * For partitions, we need to include check constraints even if
17078 * they're not defined locally, because the ALTER TABLE ATTACH
17079 * PARTITION that we'll emit later expects the constraint to be
17080 * there. (No need to fix conislocal: ATTACH PARTITION does that)
17081 */
17082 for (j = 0; j < tbinfo->ncheck; j++)
17083 {
17084 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
17085
17086 if (constr->separate ||
17087 (!constr->conislocal && !tbinfo->ispartition))
17088 continue;
17089
17090 if (actual_atts == 0)
17091 appendPQExpBufferStr(q, " (\n ");
17092 else
17093 appendPQExpBufferStr(q, ",\n ");
17094
17095 appendPQExpBuffer(q, "CONSTRAINT %s ",
17096 fmtId(constr->dobj.name));
17097 appendPQExpBufferStr(q, constr->condef);
17098
17099 actual_atts++;
17100 }
17101
17102 if (actual_atts)
17103 appendPQExpBufferStr(q, "\n)");
17104 else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
17105 {
17106 /*
17107 * No attributes? we must have a parenthesized attribute list,
17108 * even though empty, when not using the OF TYPE syntax.
17109 */
17110 appendPQExpBufferStr(q, " (\n)");
17111 }
17112
17113 /*
17114 * Emit the INHERITS clause (not for partitions), except in
17115 * binary-upgrade mode.
17116 */
17117 if (numParents > 0 && !tbinfo->ispartition &&
17118 !dopt->binary_upgrade)
17119 {
17120 appendPQExpBufferStr(q, "\nINHERITS (");
17121 for (k = 0; k < numParents; k++)
17122 {
17123 TableInfo *parentRel = parents[k];
17124
17125 if (k > 0)
17126 appendPQExpBufferStr(q, ", ");
17128 }
17129 appendPQExpBufferChar(q, ')');
17130 }
17131
17132 if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
17133 appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
17134
17135 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
17136 appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
17137 }
17138
17139 if (nonemptyReloptions(tbinfo->reloptions) ||
17141 {
17142 bool addcomma = false;
17143
17144 appendPQExpBufferStr(q, "\nWITH (");
17145 if (nonemptyReloptions(tbinfo->reloptions))
17146 {
17147 addcomma = true;
17148 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
17149 }
17151 {
17152 if (addcomma)
17153 appendPQExpBufferStr(q, ", ");
17154 appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
17155 fout);
17156 }
17157 appendPQExpBufferChar(q, ')');
17158 }
17159
17160 /* Dump generic options if any */
17161 if (ftoptions && ftoptions[0])
17162 appendPQExpBuffer(q, "\nOPTIONS (\n %s\n)", ftoptions);
17163
17164 /*
17165 * For materialized views, create the AS clause just like a view. At
17166 * this point, we always mark the view as not populated.
17167 */
17168 if (tbinfo->relkind == RELKIND_MATVIEW)
17169 {
17170 PQExpBuffer result;
17171
17172 result = createViewAsClause(fout, tbinfo);
17173 appendPQExpBuffer(q, " AS\n%s\n WITH NO DATA;\n",
17174 result->data);
17175 destroyPQExpBuffer(result);
17176 }
17177 else
17178 appendPQExpBufferStr(q, ";\n");
17179
17180 /* Materialized views can depend on extensions */
17181 if (tbinfo->relkind == RELKIND_MATVIEW)
17182 append_depends_on_extension(fout, q, &tbinfo->dobj,
17183 "pg_catalog.pg_class",
17184 "MATERIALIZED VIEW",
17185 qualrelname);
17186
17187 /*
17188 * in binary upgrade mode, update the catalog with any missing values
17189 * that might be present.
17190 */
17191 if (dopt->binary_upgrade)
17192 {
17193 for (j = 0; j < tbinfo->numatts; j++)
17194 {
17195 if (tbinfo->attmissingval[j][0] != '\0')
17196 {
17197 appendPQExpBufferStr(q, "\n-- set missing value.\n");
17199 "SELECT pg_catalog.binary_upgrade_set_missing_value(");
17200 appendStringLiteralAH(q, qualrelname, fout);
17201 appendPQExpBufferStr(q, "::pg_catalog.regclass,");
17202 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
17203 appendPQExpBufferChar(q, ',');
17204 appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
17205 appendPQExpBufferStr(q, ");\n\n");
17206 }
17207 }
17208 }
17209
17210 /*
17211 * To create binary-compatible heap files, we have to ensure the same
17212 * physical column order, including dropped columns, as in the
17213 * original. Therefore, we create dropped columns above and drop them
17214 * here, also updating their attlen/attalign values so that the
17215 * dropped column can be skipped properly. (We do not bother with
17216 * restoring the original attbyval setting.) Also, inheritance
17217 * relationships are set up by doing ALTER TABLE INHERIT rather than
17218 * using an INHERITS clause --- the latter would possibly mess up the
17219 * column order. That also means we have to take care about setting
17220 * attislocal correctly, plus fix up any inherited CHECK constraints.
17221 * Analogously, we set up typed tables using ALTER TABLE / OF here.
17222 *
17223 * We process foreign and partitioned tables here, even though they
17224 * lack heap storage, because they can participate in inheritance
17225 * relationships and we want this stuff to be consistent across the
17226 * inheritance tree. We can exclude indexes, toast tables, sequences
17227 * and matviews, even though they have storage, because we don't
17228 * support altering or dropping columns in them, nor can they be part
17229 * of inheritance trees.
17230 */
17231 if (dopt->binary_upgrade &&
17232 (tbinfo->relkind == RELKIND_RELATION ||
17233 tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
17234 tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
17235 {
17236 bool firstitem;
17237 bool firstitem_extra;
17238
17239 /*
17240 * Drop any dropped columns. Merge the pg_attribute manipulations
17241 * into a single SQL command, so that we don't cause repeated
17242 * relcache flushes on the target table. Otherwise we risk O(N^2)
17243 * relcache bloat while dropping N columns.
17244 */
17245 resetPQExpBuffer(extra);
17246 firstitem = true;
17247 for (j = 0; j < tbinfo->numatts; j++)
17248 {
17249 if (tbinfo->attisdropped[j])
17250 {
17251 if (firstitem)
17252 {
17253 appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped columns.\n"
17254 "UPDATE pg_catalog.pg_attribute\n"
17255 "SET attlen = v.dlen, "
17256 "attalign = v.dalign, "
17257 "attbyval = false\n"
17258 "FROM (VALUES ");
17259 firstitem = false;
17260 }
17261 else
17262 appendPQExpBufferStr(q, ",\n ");
17263 appendPQExpBufferChar(q, '(');
17264 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
17265 appendPQExpBuffer(q, ", %d, '%c')",
17266 tbinfo->attlen[j],
17267 tbinfo->attalign[j]);
17268 /* The ALTER ... DROP COLUMN commands must come after */
17269 appendPQExpBuffer(extra, "ALTER %sTABLE ONLY %s ",
17270 foreign, qualrelname);
17271 appendPQExpBuffer(extra, "DROP COLUMN %s;\n",
17272 fmtId(tbinfo->attnames[j]));
17273 }
17274 }
17275 if (!firstitem)
17276 {
17277 appendPQExpBufferStr(q, ") v(dname, dlen, dalign)\n"
17278 "WHERE attrelid = ");
17279 appendStringLiteralAH(q, qualrelname, fout);
17280 appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
17281 " AND attname = v.dname;\n");
17282 /* Now we can issue the actual DROP COLUMN commands */
17283 appendBinaryPQExpBuffer(q, extra->data, extra->len);
17284 }
17285
17286 /*
17287 * Fix up inherited columns. As above, do the pg_attribute
17288 * manipulations in a single SQL command.
17289 */
17290 firstitem = true;
17291 for (j = 0; j < tbinfo->numatts; j++)
17292 {
17293 if (!tbinfo->attisdropped[j] &&
17294 !tbinfo->attislocal[j])
17295 {
17296 if (firstitem)
17297 {
17298 appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited columns.\n");
17299 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
17300 "SET attislocal = false\n"
17301 "WHERE attrelid = ");
17302 appendStringLiteralAH(q, qualrelname, fout);
17303 appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
17304 " AND attname IN (");
17305 firstitem = false;
17306 }
17307 else
17308 appendPQExpBufferStr(q, ", ");
17309 appendStringLiteralAH(q, tbinfo->attnames[j], fout);
17310 }
17311 }
17312 if (!firstitem)
17313 appendPQExpBufferStr(q, ");\n");
17314
17315 /*
17316 * Fix up not-null constraints that come from inheritance. As
17317 * above, do the pg_constraint manipulations in a single SQL
17318 * command. (Actually, two in special cases, if we're doing an
17319 * upgrade from < 18).
17320 */
17321 firstitem = true;
17322 firstitem_extra = true;
17323 resetPQExpBuffer(extra);
17324 for (j = 0; j < tbinfo->numatts; j++)
17325 {
17326 /*
17327 * If a not-null constraint comes from inheritance, reset
17328 * conislocal. The inhcount is fixed by ALTER TABLE INHERIT,
17329 * below. Special hack: in versions < 18, columns with no
17330 * local definition need their constraint to be matched by
17331 * column number in conkeys instead of by constraint name,
17332 * because the latter is not available. (We distinguish the
17333 * case because the constraint name is the empty string.)
17334 */
17335 if (tbinfo->notnull_constrs[j] != NULL &&
17336 !tbinfo->notnull_islocal[j])
17337 {
17338 if (tbinfo->notnull_constrs[j][0] != '\0')
17339 {
17340 if (firstitem)
17341 {
17342 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
17343 "SET conislocal = false\n"
17344 "WHERE contype = 'n' AND conrelid = ");
17345 appendStringLiteralAH(q, qualrelname, fout);
17346 appendPQExpBufferStr(q, "::pg_catalog.regclass AND\n"
17347 "conname IN (");
17348 firstitem = false;
17349 }
17350 else
17351 appendPQExpBufferStr(q, ", ");
17352 appendStringLiteralAH(q, tbinfo->notnull_constrs[j], fout);
17353 }
17354 else
17355 {
17356 if (firstitem_extra)
17357 {
17358 appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
17359 "SET conislocal = false\n"
17360 "WHERE contype = 'n' AND conrelid = ");
17361 appendStringLiteralAH(extra, qualrelname, fout);
17362 appendPQExpBufferStr(extra, "::pg_catalog.regclass AND\n"
17363 "conkey IN (");
17364 firstitem_extra = false;
17365 }
17366 else
17367 appendPQExpBufferStr(extra, ", ");
17368 appendPQExpBuffer(extra, "'{%d}'", j + 1);
17369 }
17370 }
17371 }
17372 if (!firstitem)
17373 appendPQExpBufferStr(q, ");\n");
17374 if (!firstitem_extra)
17375 appendPQExpBufferStr(extra, ");\n");
17376
17377 if (extra->len > 0)
17378 appendBinaryPQExpBuffer(q, extra->data, extra->len);
17379
17380 /*
17381 * Add inherited CHECK constraints, if any.
17382 *
17383 * For partitions, they were already dumped, and conislocal
17384 * doesn't need fixing.
17385 *
17386 * As above, issue only one direct manipulation of pg_constraint.
17387 * Although it is tempting to merge the ALTER ADD CONSTRAINT
17388 * commands into one as well, refrain for now due to concern about
17389 * possible backend memory bloat if there are many such
17390 * constraints.
17391 */
17392 resetPQExpBuffer(extra);
17393 firstitem = true;
17394 for (k = 0; k < tbinfo->ncheck; k++)
17395 {
17396 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
17397
17398 if (constr->separate || constr->conislocal || tbinfo->ispartition)
17399 continue;
17400
17401 if (firstitem)
17402 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraints.\n");
17403 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
17404 foreign, qualrelname,
17405 fmtId(constr->dobj.name),
17406 constr->condef);
17407 /* Update pg_constraint after all the ALTER TABLEs */
17408 if (firstitem)
17409 {
17410 appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
17411 "SET conislocal = false\n"
17412 "WHERE contype = 'c' AND conrelid = ");
17413 appendStringLiteralAH(extra, qualrelname, fout);
17414 appendPQExpBufferStr(extra, "::pg_catalog.regclass\n");
17415 appendPQExpBufferStr(extra, " AND conname IN (");
17416 firstitem = false;
17417 }
17418 else
17419 appendPQExpBufferStr(extra, ", ");
17420 appendStringLiteralAH(extra, constr->dobj.name, fout);
17421 }
17422 if (!firstitem)
17423 {
17424 appendPQExpBufferStr(extra, ");\n");
17425 appendBinaryPQExpBuffer(q, extra->data, extra->len);
17426 }
17427
17428 if (numParents > 0 && !tbinfo->ispartition)
17429 {
17430 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
17431 for (k = 0; k < numParents; k++)
17432 {
17433 TableInfo *parentRel = parents[k];
17434
17435 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
17436 qualrelname,
17437 fmtQualifiedDumpable(parentRel));
17438 }
17439 }
17440
17441 if (OidIsValid(tbinfo->reloftype))
17442 {
17443 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
17444 appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
17445 qualrelname,
17446 getFormattedTypeName(fout, tbinfo->reloftype,
17447 zeroIsError));
17448 }
17449 }
17450
17451 /*
17452 * In binary_upgrade mode, arrange to restore the old relfrozenxid and
17453 * relminmxid of all vacuumable relations. (While vacuum.c processes
17454 * TOAST tables semi-independently, here we see them only as children
17455 * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
17456 * child toast table is handled below.)
17457 */
17458 if (dopt->binary_upgrade &&
17459 (tbinfo->relkind == RELKIND_RELATION ||
17460 tbinfo->relkind == RELKIND_MATVIEW))
17461 {
17462 appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
17463 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
17464 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
17465 "WHERE oid = ",
17466 tbinfo->frozenxid, tbinfo->minmxid);
17467 appendStringLiteralAH(q, qualrelname, fout);
17468 appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
17469
17470 if (tbinfo->toast_oid)
17471 {
17472 /*
17473 * The toast table will have the same OID at restore, so we
17474 * can safely target it by OID.
17475 */
17476 appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
17477 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
17478 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
17479 "WHERE oid = '%u';\n",
17480 tbinfo->toast_frozenxid,
17481 tbinfo->toast_minmxid, tbinfo->toast_oid);
17482 }
17483 }
17484
17485 /*
17486 * In binary_upgrade mode, restore matviews' populated status by
17487 * poking pg_class directly. This is pretty ugly, but we can't use
17488 * REFRESH MATERIALIZED VIEW since it's possible that some underlying
17489 * matview is not populated even though this matview is; in any case,
17490 * we want to transfer the matview's heap storage, not run REFRESH.
17491 */
17492 if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
17493 tbinfo->relispopulated)
17494 {
17495 appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
17496 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
17497 "SET relispopulated = 't'\n"
17498 "WHERE oid = ");
17499 appendStringLiteralAH(q, qualrelname, fout);
17500 appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
17501 }
17502
17503 /*
17504 * Dump additional per-column properties that we can't handle in the
17505 * main CREATE TABLE command.
17506 */
17507 for (j = 0; j < tbinfo->numatts; j++)
17508 {
17509 /* None of this applies to dropped columns */
17510 if (tbinfo->attisdropped[j])
17511 continue;
17512
17513 /*
17514 * Dump per-column statistics information. We only issue an ALTER
17515 * TABLE statement if the attstattarget entry for this column is
17516 * not the default value.
17517 */
17518 if (tbinfo->attstattarget[j] >= 0)
17519 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
17520 foreign, qualrelname,
17521 fmtId(tbinfo->attnames[j]),
17522 tbinfo->attstattarget[j]);
17523
17524 /*
17525 * Dump per-column storage information. The statement is only
17526 * dumped if the storage has been changed from the type's default.
17527 */
17528 if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
17529 {
17530 switch (tbinfo->attstorage[j])
17531 {
17532 case TYPSTORAGE_PLAIN:
17533 storage = "PLAIN";
17534 break;
17535 case TYPSTORAGE_EXTERNAL:
17536 storage = "EXTERNAL";
17537 break;
17538 case TYPSTORAGE_EXTENDED:
17539 storage = "EXTENDED";
17540 break;
17541 case TYPSTORAGE_MAIN:
17542 storage = "MAIN";
17543 break;
17544 default:
17545 storage = NULL;
17546 }
17547
17548 /*
17549 * Only dump the statement if it's a storage type we recognize
17550 */
17551 if (storage != NULL)
17552 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
17553 foreign, qualrelname,
17554 fmtId(tbinfo->attnames[j]),
17555 storage);
17556 }
17557
17558 /*
17559 * Dump per-column compression, if it's been set.
17560 */
17561 if (!dopt->no_toast_compression)
17562 {
17563 const char *cmname;
17564
17565 switch (tbinfo->attcompression[j])
17566 {
17567 case 'p':
17568 cmname = "pglz";
17569 break;
17570 case 'l':
17571 cmname = "lz4";
17572 break;
17573 default:
17574 cmname = NULL;
17575 break;
17576 }
17577
17578 if (cmname != NULL)
17579 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
17580 foreign, qualrelname,
17581 fmtId(tbinfo->attnames[j]),
17582 cmname);
17583 }
17584
17585 /*
17586 * Dump per-column attributes.
17587 */
17588 if (tbinfo->attoptions[j][0] != '\0')
17589 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
17590 foreign, qualrelname,
17591 fmtId(tbinfo->attnames[j]),
17592 tbinfo->attoptions[j]);
17593
17594 /*
17595 * Dump per-column fdw options.
17596 */
17597 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
17598 tbinfo->attfdwoptions[j][0] != '\0')
17600 "ALTER FOREIGN TABLE ONLY %s ALTER COLUMN %s OPTIONS (\n"
17601 " %s\n"
17602 ");\n",
17603 qualrelname,
17604 fmtId(tbinfo->attnames[j]),
17605 tbinfo->attfdwoptions[j]);
17606 } /* end loop over columns */
17607
17608 free(partkeydef);
17609 free(ftoptions);
17610 free(srvname);
17611 }
17612
17613 /*
17614 * dump properties we only have ALTER TABLE syntax for
17615 */
17616 if ((tbinfo->relkind == RELKIND_RELATION ||
17617 tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
17618 tbinfo->relkind == RELKIND_MATVIEW) &&
17619 tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
17620 {
17621 if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
17622 {
17623 /* nothing to do, will be set when the index is dumped */
17624 }
17625 else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
17626 {
17627 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
17628 qualrelname);
17629 }
17630 else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
17631 {
17632 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
17633 qualrelname);
17634 }
17635 }
17636
17637 if (tbinfo->forcerowsec)
17638 appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
17639 qualrelname);
17640
17641 if (dopt->binary_upgrade)
17643 reltypename, qrelname,
17644 tbinfo->dobj.namespace->dobj.name);
17645
17646 if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17647 {
17648 char *tablespace = NULL;
17649 char *tableam = NULL;
17650
17651 /*
17652 * _selectTablespace() relies on tablespace-enabled objects in the
17653 * default tablespace to have a tablespace of "" (empty string) versus
17654 * non-tablespace-enabled objects to have a tablespace of NULL.
17655 * getTables() sets tbinfo->reltablespace to "" for the default
17656 * tablespace (not NULL).
17657 */
17658 if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
17659 tablespace = tbinfo->reltablespace;
17660
17661 if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
17662 tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
17663 tableam = tbinfo->amname;
17664
17665 ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
17666 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
17667 .namespace = tbinfo->dobj.namespace->dobj.name,
17668 .tablespace = tablespace,
17669 .tableam = tableam,
17670 .relkind = tbinfo->relkind,
17671 .owner = tbinfo->rolname,
17672 .description = reltypename,
17673 .section = tbinfo->postponed_def ?
17675 .createStmt = q->data,
17676 .dropStmt = delq->data));
17677 }
17678
17679 /* Dump Table Comments */
17680 if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
17681 dumpTableComment(fout, tbinfo, reltypename);
17682
17683 /* Dump Table Security Labels */
17684 if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
17685 dumpTableSecLabel(fout, tbinfo, reltypename);
17686
17687 /* Dump comments on inlined table constraints */
17688 for (j = 0; j < tbinfo->ncheck; j++)
17689 {
17690 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
17691
17692 if (constr->separate || !constr->conislocal)
17693 continue;
17694
17695 if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
17696 dumpTableConstraintComment(fout, constr);
17697 }
17698
17700 destroyPQExpBuffer(delq);
17701 destroyPQExpBuffer(extra);
17702 free(qrelname);
17703 free(qualrelname);
17704}
#define storage
Definition: indent_codes.h:68
static void dumpTableComment(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:11117
static void binary_upgrade_set_type_oids_by_rel(Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tbinfo)
Definition: pg_dump.c:5596
bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
Definition: pg_dump.c:9854
static void dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
Definition: pg_dump.c:16281
int no_toast_compression
Definition: pg_backup.h:189
char * reltablespace
Definition: pg_dump.h:307
int ncheck
Definition: pg_dump.h:323
bool * attislocal
Definition: pg_dump.h:358
Oid reloftype
Definition: pg_dump.h:325
int numParents
Definition: pg_dump.h:340
char * toast_reloptions
Definition: pg_dump.h:310
struct _tableInfo ** parents
Definition: pg_dump.h:341
int * attlen
Definition: pg_dump.h:356
char ** attfdwoptions
Definition: pg_dump.h:362
bool hasoids
Definition: pg_dump.h:317
Oid toast_oid
Definition: pg_dump.h:320
struct _constraintInfo * checkexprs
Definition: pg_dump.h:372
int * attstattarget
Definition: pg_dump.h:350
uint32 frozenxid
Definition: pg_dump.h:318
char * typstorage
Definition: pg_dump.h:352
struct _attrDefInfo ** attrdefs
Definition: pg_dump.h:371
char ** attoptions
Definition: pg_dump.h:359
char relreplident
Definition: pg_dump.h:306
uint32 minmxid
Definition: pg_dump.h:319
char * attstorage
Definition: pg_dump.h:351
char * amname
Definition: pg_dump.h:375
bool dummy_view
Definition: pg_dump.h:335
bool forcerowsec
Definition: pg_dump.h:316
char ** attmissingval
Definition: pg_dump.h:363
uint32 toast_frozenxid
Definition: pg_dump.h:321
uint32 toast_minmxid
Definition: pg_dump.h:322
char * attalign
Definition: pg_dump.h:357
char * attcompression
Definition: pg_dump.h:361
bool postponed_def
Definition: pg_dump.h:336

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

Referenced by dumpTable().

◆ dumpTableSecLabel()

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

Definition at line 16281 of file pg_dump.c.

16282{
16283 DumpOptions *dopt = fout->dopt;
16284 SecLabelItem *labels;
16285 int nlabels;
16286 int i;
16287 PQExpBuffer query;
16288 PQExpBuffer target;
16289
16290 /* do nothing, if --no-security-labels is supplied */
16291 if (dopt->no_security_labels)
16292 return;
16293
16294 /* SecLabel are SCHEMA not data */
16295 if (!dopt->dumpSchema)
16296 return;
16297
16298 /* Search for comments associated with relation, using table */
16299 nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
16300 tbinfo->dobj.catId.oid,
16301 &labels);
16302
16303 /* If security labels exist, build SECURITY LABEL statements */
16304 if (nlabels <= 0)
16305 return;
16306
16307 query = createPQExpBuffer();
16308 target = createPQExpBuffer();
16309
16310 for (i = 0; i < nlabels; i++)
16311 {
16312 const char *colname;
16313 const char *provider = labels[i].provider;
16314 const char *label = labels[i].label;
16315 int objsubid = labels[i].objsubid;
16316
16317 resetPQExpBuffer(target);
16318 if (objsubid == 0)
16319 {
16320 appendPQExpBuffer(target, "%s %s", reltypename,
16321 fmtQualifiedDumpable(tbinfo));
16322 }
16323 else
16324 {
16325 colname = getAttrName(objsubid, tbinfo);
16326 /* first fmtXXX result must be consumed before calling again */
16327 appendPQExpBuffer(target, "COLUMN %s",
16328 fmtQualifiedDumpable(tbinfo));
16329 appendPQExpBuffer(target, ".%s", fmtId(colname));
16330 }
16331 appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
16332 fmtId(provider), target->data);
16333 appendStringLiteralAH(query, label, fout);
16334 appendPQExpBufferStr(query, ";\n");
16335 }
16336 if (query->len > 0)
16337 {
16338 resetPQExpBuffer(target);
16339 appendPQExpBuffer(target, "%s %s", reltypename,
16340 fmtId(tbinfo->dobj.name));
16342 ARCHIVE_OPTS(.tag = target->data,
16343 .namespace = tbinfo->dobj.namespace->dobj.name,
16344 .owner = tbinfo->rolname,
16345 .description = "SECURITY LABEL",
16346 .section = SECTION_NONE,
16347 .createStmt = query->data,
16348 .deps = &(tbinfo->dobj.dumpId),
16349 .nDeps = 1));
16350 }
16351 destroyPQExpBuffer(query);
16352 destroyPQExpBuffer(target);
16353}

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

13642{
13643 DumpOptions *dopt = fout->dopt;
13644 PQExpBuffer defqry;
13645 PQExpBuffer delqry;
13646 PQExpBuffer labelq;
13647 PQExpBuffer transformargs;
13648 FuncInfo *fromsqlFuncInfo = NULL;
13649 FuncInfo *tosqlFuncInfo = NULL;
13650 char *lanname;
13651 const char *transformType;
13652
13653 /* Do nothing if not dumping schema */
13654 if (!dopt->dumpSchema)
13655 return;
13656
13657 /* Cannot dump if we don't have the transform functions' info */
13658 if (OidIsValid(transform->trffromsql))
13659 {
13660 fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
13661 if (fromsqlFuncInfo == NULL)
13662 pg_fatal("could not find function definition for function with OID %u",
13663 transform->trffromsql);
13664 }
13665 if (OidIsValid(transform->trftosql))
13666 {
13667 tosqlFuncInfo = findFuncByOid(transform->trftosql);
13668 if (tosqlFuncInfo == NULL)
13669 pg_fatal("could not find function definition for function with OID %u",
13670 transform->trftosql);
13671 }
13672
13673 defqry = createPQExpBuffer();
13674 delqry = createPQExpBuffer();
13675 labelq = createPQExpBuffer();
13676 transformargs = createPQExpBuffer();
13677
13678 lanname = get_language_name(fout, transform->trflang);
13679 transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
13680
13681 appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
13682 transformType, lanname);
13683
13684 appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
13685 transformType, lanname);
13686
13687 if (!transform->trffromsql && !transform->trftosql)
13688 pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
13689
13690 if (transform->trffromsql)
13691 {
13692 if (fromsqlFuncInfo)
13693 {
13694 char *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
13695
13696 /*
13697 * Always qualify the function name (format_function_signature
13698 * won't qualify it).
13699 */
13700 appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
13701 fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
13702 free(fsig);
13703 }
13704 else
13705 pg_log_warning("bogus value in pg_transform.trffromsql field");
13706 }
13707
13708 if (transform->trftosql)
13709 {
13710 if (transform->trffromsql)
13711 appendPQExpBufferStr(defqry, ", ");
13712
13713 if (tosqlFuncInfo)
13714 {
13715 char *fsig = format_function_signature(fout, tosqlFuncInfo, true);
13716
13717 /*
13718 * Always qualify the function name (format_function_signature
13719 * won't qualify it).
13720 */
13721 appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
13722 fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
13723 free(fsig);
13724 }
13725 else
13726 pg_log_warning("bogus value in pg_transform.trftosql field");
13727 }
13728
13729 appendPQExpBufferStr(defqry, ");\n");
13730
13731 appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
13732 transformType, lanname);
13733
13734 appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
13735 transformType, lanname);
13736
13737 if (dopt->binary_upgrade)
13738 binary_upgrade_extension_member(defqry, &transform->dobj,
13739 "TRANSFORM", transformargs->data, NULL);
13740
13741 if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
13742 ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
13743 ARCHIVE_OPTS(.tag = labelq->data,
13744 .description = "TRANSFORM",
13745 .section = SECTION_PRE_DATA,
13746 .createStmt = defqry->data,
13747 .dropStmt = delqry->data,
13748 .deps = transform->dobj.dependencies,
13749 .nDeps = transform->dobj.nDeps));
13750
13751 /* Dump Transform Comments */
13752 if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
13753 dumpComment(fout, "TRANSFORM", transformargs->data,
13754 NULL, "",
13755 transform->dobj.catId, 0, transform->dobj.dumpId);
13756
13757 free(lanname);
13758 destroyPQExpBuffer(defqry);
13759 destroyPQExpBuffer(delqry);
13760 destroyPQExpBuffer(labelq);
13761 destroyPQExpBuffer(transformargs);
13762}
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8878
DumpableObject dobj
Definition: pg_dump.h:546
Oid trffromsql
Definition: pg_dump.h:549

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

18894{
18895 DumpOptions *dopt = fout->dopt;
18896 TableInfo *tbinfo = tginfo->tgtable;
18897 PQExpBuffer query;
18898 PQExpBuffer delqry;
18899 PQExpBuffer trigprefix;
18900 PQExpBuffer trigidentity;
18901 char *qtabname;
18902 char *tag;
18903
18904 /* Do nothing if not dumping schema */
18905 if (!dopt->dumpSchema)
18906 return;
18907
18908 query = createPQExpBuffer();
18909 delqry = createPQExpBuffer();
18910 trigprefix = createPQExpBuffer();
18911 trigidentity = createPQExpBuffer();
18912
18913 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18914
18915 appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
18916 appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
18917
18918 appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
18919 appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
18920
18921 /* Triggers can depend on extensions */
18922 append_depends_on_extension(fout, query, &tginfo->dobj,
18923 "pg_catalog.pg_trigger", "TRIGGER",
18924 trigidentity->data);
18925
18926 if (tginfo->tgispartition)
18927 {
18928 Assert(tbinfo->ispartition);
18929
18930 /*
18931 * Partition triggers only appear here because their 'tgenabled' flag
18932 * differs from its parent's. The trigger is created already, so
18933 * remove the CREATE and replace it with an ALTER. (Clear out the
18934 * DROP query too, so that pg_dump --create does not cause errors.)
18935 */
18936 resetPQExpBuffer(query);
18937 resetPQExpBuffer(delqry);
18938 appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
18939 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
18940 fmtQualifiedDumpable(tbinfo));
18941 switch (tginfo->tgenabled)
18942 {
18943 case 'f':
18944 case 'D':
18945 appendPQExpBufferStr(query, "DISABLE");
18946 break;
18947 case 't':
18948 case 'O':
18949 appendPQExpBufferStr(query, "ENABLE");
18950 break;
18951 case 'R':
18952 appendPQExpBufferStr(query, "ENABLE REPLICA");
18953 break;
18954 case 'A':
18955 appendPQExpBufferStr(query, "ENABLE ALWAYS");
18956 break;
18957 }
18958 appendPQExpBuffer(query, " TRIGGER %s;\n",
18959 fmtId(tginfo->dobj.name));
18960 }
18961 else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
18962 {
18963 appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
18964 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
18965 fmtQualifiedDumpable(tbinfo));
18966 switch (tginfo->tgenabled)
18967 {
18968 case 'D':
18969 case 'f':
18970 appendPQExpBufferStr(query, "DISABLE");
18971 break;
18972 case 'A':
18973 appendPQExpBufferStr(query, "ENABLE ALWAYS");
18974 break;
18975 case 'R':
18976 appendPQExpBufferStr(query, "ENABLE REPLICA");
18977 break;
18978 default:
18979 appendPQExpBufferStr(query, "ENABLE");
18980 break;
18981 }
18982 appendPQExpBuffer(query, " TRIGGER %s;\n",
18983 fmtId(tginfo->dobj.name));
18984 }
18985
18986 appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
18987 fmtId(tginfo->dobj.name));
18988
18989 tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
18990
18991 if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18992 ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
18993 ARCHIVE_OPTS(.tag = tag,
18994 .namespace = tbinfo->dobj.namespace->dobj.name,
18995 .owner = tbinfo->rolname,
18996 .description = "TRIGGER",
18997 .section = SECTION_POST_DATA,
18998 .createStmt = query->data,
18999 .dropStmt = delqry->data));
19000
19001 if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19002 dumpComment(fout, trigprefix->data, qtabname,
19003 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
19004 tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
19005
19006 free(tag);
19007 destroyPQExpBuffer(query);
19008 destroyPQExpBuffer(delqry);
19009 destroyPQExpBuffer(trigprefix);
19010 destroyPQExpBuffer(trigidentity);
19011 free(qtabname);
19012}
TableInfo * tgtable
Definition: pg_dump.h:480
DumpableObject dobj
Definition: pg_dump.h:479
char tgenabled
Definition: pg_dump.h:481
char * tgdef
Definition: pg_dump.h:483
bool tgispartition
Definition: pg_dump.h:482

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

15598{
15599 DumpOptions *dopt = fout->dopt;
15600 PQExpBuffer q;
15601 PQExpBuffer delq;
15602 PQExpBuffer query;
15603 char *qcfgname;
15604 PGresult *res;
15605 char *nspname;
15606 char *prsname;
15607 int ntups,
15608 i;
15609 int i_tokenname;
15610 int i_dictname;
15611
15612 /* Do nothing if not dumping schema */
15613 if (!dopt->dumpSchema)
15614 return;
15615
15616 q = createPQExpBuffer();
15617 delq = createPQExpBuffer();
15618 query = createPQExpBuffer();
15619
15620 qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
15621
15622 /* Fetch name and namespace of the config's parser */
15623 appendPQExpBuffer(query, "SELECT nspname, prsname "
15624 "FROM pg_ts_parser p, pg_namespace n "
15625 "WHERE p.oid = '%u' AND n.oid = prsnamespace",
15626 cfginfo->cfgparser);
15627 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15628 nspname = PQgetvalue(res, 0, 0);
15629 prsname = PQgetvalue(res, 0, 1);
15630
15631 appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
15632 fmtQualifiedDumpable(cfginfo));
15633
15634 appendPQExpBuffer(q, " PARSER = %s.", fmtId(nspname));
15635 appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
15636
15637 PQclear(res);
15638
15639 resetPQExpBuffer(query);
15640 appendPQExpBuffer(query,
15641 "SELECT\n"
15642 " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
15643 " WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
15644 " m.mapdict::pg_catalog.regdictionary AS dictname\n"
15645 "FROM pg_catalog.pg_ts_config_map AS m\n"
15646 "WHERE m.mapcfg = '%u'\n"
15647 "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
15648 cfginfo->cfgparser, cfginfo->dobj.catId.oid);
15649
15650 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15651 ntups = PQntuples(res);
15652
15653 i_tokenname = PQfnumber(res, "tokenname");
15654 i_dictname = PQfnumber(res, "dictname");
15655
15656 for (i = 0; i < ntups; i++)
15657 {
15658 char *tokenname = PQgetvalue(res, i, i_tokenname);
15659 char *dictname = PQgetvalue(res, i, i_dictname);
15660
15661 if (i == 0 ||
15662 strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
15663 {
15664 /* starting a new token type, so start a new command */
15665 if (i > 0)
15666 appendPQExpBufferStr(q, ";\n");
15667 appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
15668 fmtQualifiedDumpable(cfginfo));
15669 /* tokenname needs quoting, dictname does NOT */
15670 appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
15671 fmtId(tokenname), dictname);
15672 }
15673 else
15674 appendPQExpBuffer(q, ", %s", dictname);
15675 }
15676
15677 if (ntups > 0)
15678 appendPQExpBufferStr(q, ";\n");
15679
15680 PQclear(res);
15681
15682 appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
15683 fmtQualifiedDumpable(cfginfo));
15684
15685 if (dopt->binary_upgrade)
15687 "TEXT SEARCH CONFIGURATION", qcfgname,
15688 cfginfo->dobj.namespace->dobj.name);
15689
15690 if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15691 ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
15692 ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
15693 .namespace = cfginfo->dobj.namespace->dobj.name,
15694 .owner = cfginfo->rolname,
15695 .description = "TEXT SEARCH CONFIGURATION",
15696 .section = SECTION_PRE_DATA,
15697 .createStmt = q->data,
15698 .dropStmt = delq->data));
15699
15700 /* Dump Configuration Comments */
15701 if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15702 dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
15703 cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
15704 cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
15705
15707 destroyPQExpBuffer(delq);
15708 destroyPQExpBuffer(query);
15709 free(qcfgname);
15710}
Oid cfgparser
Definition: pg_dump.h:589
DumpableObject dobj
Definition: pg_dump.h:587
const char * rolname
Definition: pg_dump.h:588

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

15460{
15461 DumpOptions *dopt = fout->dopt;
15462 PQExpBuffer q;
15463 PQExpBuffer delq;
15464 PQExpBuffer query;
15465 char *qdictname;
15466 PGresult *res;
15467 char *nspname;
15468 char *tmplname;
15469
15470 /* Do nothing if not dumping schema */
15471 if (!dopt->dumpSchema)
15472 return;
15473
15474 q = createPQExpBuffer();
15475 delq = createPQExpBuffer();
15476 query = createPQExpBuffer();
15477
15478 qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
15479
15480 /* Fetch name and namespace of the dictionary's template */
15481 appendPQExpBuffer(query, "SELECT nspname, tmplname "
15482 "FROM pg_ts_template p, pg_namespace n "
15483 "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
15484 dictinfo->dicttemplate);
15485 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15486 nspname = PQgetvalue(res, 0, 0);
15487 tmplname = PQgetvalue(res, 0, 1);
15488
15489 appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
15490 fmtQualifiedDumpable(dictinfo));
15491
15492 appendPQExpBufferStr(q, " TEMPLATE = ");
15493 appendPQExpBuffer(q, "%s.", fmtId(nspname));
15494 appendPQExpBufferStr(q, fmtId(tmplname));
15495
15496 PQclear(res);
15497
15498 /* the dictinitoption can be dumped straight into the command */
15499 if (dictinfo->dictinitoption)
15500 appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
15501
15502 appendPQExpBufferStr(q, " );\n");
15503
15504 appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
15505 fmtQualifiedDumpable(dictinfo));
15506
15507 if (dopt->binary_upgrade)
15509 "TEXT SEARCH DICTIONARY", qdictname,
15510 dictinfo->dobj.namespace->dobj.name);
15511
15512 if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15513 ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
15514 ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
15515 .namespace = dictinfo->dobj.namespace->dobj.name,
15516 .owner = dictinfo->rolname,
15517 .description = "TEXT SEARCH DICTIONARY",
15518 .section = SECTION_PRE_DATA,
15519 .createStmt = q->data,
15520 .dropStmt = delq->data));
15521
15522 /* Dump Dictionary Comments */
15523 if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15524 dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
15525 dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
15526 dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
15527
15529 destroyPQExpBuffer(delq);
15530 destroyPQExpBuffer(query);
15531 free(qdictname);
15532}
char * dictinitoption
Definition: pg_dump.h:575
DumpableObject dobj
Definition: pg_dump.h:572
const char * rolname
Definition: pg_dump.h:573
Oid dicttemplate
Definition: pg_dump.h:574

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

15396{
15397 DumpOptions *dopt = fout->dopt;
15398 PQExpBuffer q;
15399 PQExpBuffer delq;
15400 char *qprsname;
15401
15402 /* Do nothing if not dumping schema */
15403 if (!dopt->dumpSchema)
15404 return;
15405
15406 q = createPQExpBuffer();
15407 delq = createPQExpBuffer();
15408
15409 qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
15410
15411 appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
15412 fmtQualifiedDumpable(prsinfo));
15413
15414 appendPQExpBuffer(q, " START = %s,\n",
15415 convertTSFunction(fout, prsinfo->prsstart));
15416 appendPQExpBuffer(q, " GETTOKEN = %s,\n",
15417 convertTSFunction(fout, prsinfo->prstoken));
15418 appendPQExpBuffer(q, " END = %s,\n",
15419 convertTSFunction(fout, prsinfo->prsend));
15420 if (prsinfo->prsheadline != InvalidOid)
15421 appendPQExpBuffer(q, " HEADLINE = %s,\n",
15422 convertTSFunction(fout, prsinfo->prsheadline));
15423 appendPQExpBuffer(q, " LEXTYPES = %s );\n",
15424 convertTSFunction(fout, prsinfo->prslextype));
15425
15426 appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
15427 fmtQualifiedDumpable(prsinfo));
15428
15429 if (dopt->binary_upgrade)
15431 "TEXT SEARCH PARSER", qprsname,
15432 prsinfo->dobj.namespace->dobj.name);
15433
15434 if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15435 ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
15436 ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
15437 .namespace = prsinfo->dobj.namespace->dobj.name,
15438 .description = "TEXT SEARCH PARSER",
15439 .section = SECTION_PRE_DATA,
15440 .createStmt = q->data,
15441 .dropStmt = delq->data));
15442
15443 /* Dump Parser Comments */
15444 if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15445 dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
15446 prsinfo->dobj.namespace->dobj.name, "",
15447 prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
15448
15450 destroyPQExpBuffer(delq);
15451 free(qprsname);
15452}
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:14060
DumpableObject dobj
Definition: pg_dump.h:562
Oid prstoken
Definition: pg_dump.h:564
Oid prslextype
Definition: pg_dump.h:567
Oid prsheadline
Definition: pg_dump.h:566
Oid prsstart
Definition: pg_dump.h:563
Oid prsend
Definition: pg_dump.h:565

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

15540{
15541 DumpOptions *dopt = fout->dopt;
15542 PQExpBuffer q;
15543 PQExpBuffer delq;
15544 char *qtmplname;
15545
15546 /* Do nothing if not dumping schema */
15547 if (!dopt->dumpSchema)
15548 return;
15549
15550 q = createPQExpBuffer();
15551 delq = createPQExpBuffer();
15552
15553 qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
15554
15555 appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
15556 fmtQualifiedDumpable(tmplinfo));
15557
15558 if (tmplinfo->tmplinit != InvalidOid)
15559 appendPQExpBuffer(q, " INIT = %s,\n",
15560 convertTSFunction(fout, tmplinfo->tmplinit));
15561 appendPQExpBuffer(q, " LEXIZE = %s );\n",
15562 convertTSFunction(fout, tmplinfo->tmpllexize));
15563
15564 appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
15565 fmtQualifiedDumpable(tmplinfo));
15566
15567 if (dopt->binary_upgrade)
15569 "TEXT SEARCH TEMPLATE", qtmplname,
15570 tmplinfo->dobj.namespace->dobj.name);
15571
15572 if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15573 ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
15574 ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
15575 .namespace = tmplinfo->dobj.namespace->dobj.name,
15576 .description = "TEXT SEARCH TEMPLATE",
15577 .section = SECTION_PRE_DATA,
15578 .createStmt = q->data,
15579 .dropStmt = delq->data));
15580
15581 /* Dump Template Comments */
15582 if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15583 dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
15584 tmplinfo->dobj.namespace->dobj.name, "",
15585 tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
15586
15588 destroyPQExpBuffer(delq);
15589 free(qtmplname);
15590}
Oid tmpllexize
Definition: pg_dump.h:582
Oid tmplinit
Definition: pg_dump.h:581
DumpableObject dobj
Definition: pg_dump.h:580

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

11779{
11780 DumpOptions *dopt = fout->dopt;
11781
11782 /* Do nothing if not dumping schema */
11783 if (!dopt->dumpSchema)
11784 return;
11785
11786 /* Dump out in proper style */
11787 if (tyinfo->typtype == TYPTYPE_BASE)
11788 dumpBaseType(fout, tyinfo);
11789 else if (tyinfo->typtype == TYPTYPE_DOMAIN)
11790 dumpDomain(fout, tyinfo);
11791 else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
11792 dumpCompositeType(fout, tyinfo);
11793 else if (tyinfo->typtype == TYPTYPE_ENUM)
11794 dumpEnumType(fout, tyinfo);
11795 else if (tyinfo->typtype == TYPTYPE_RANGE)
11796 dumpRangeType(fout, tyinfo);
11797 else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
11798 dumpUndefinedType(fout, tyinfo);
11799 else
11800 pg_log_warning("typtype of data type \"%s\" appears to be invalid",
11801 tyinfo->dobj.name);
11802}
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12171
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11949
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12420
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12107
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12593
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11809
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 12107 of file pg_dump.c.

12108{
12109 DumpOptions *dopt = fout->dopt;
12112 char *qtypname;
12113 char *qualtypname;
12114
12115 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12116 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12117
12118 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12119
12120 if (dopt->binary_upgrade)
12122 tyinfo->dobj.catId.oid,
12123 false, false);
12124
12125 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12126 qualtypname);
12127
12128 if (dopt->binary_upgrade)
12130 "TYPE", qtypname,
12131 tyinfo->dobj.namespace->dobj.name);
12132
12133 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12134 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12135 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12136 .namespace = tyinfo->dobj.namespace->dobj.name,
12137 .owner = tyinfo->rolname,
12138 .description = "TYPE",
12139 .section = SECTION_PRE_DATA,
12140 .createStmt = q->data,
12141 .dropStmt = delq->data));
12142
12143 /* Dump Type Comments and Security Labels */
12144 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12145 dumpComment(fout, "TYPE", qtypname,
12146 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12147 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12148
12149 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12150 dumpSecLabel(fout, "TYPE", qtypname,
12151 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12152 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12153
12154 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12155 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12156 qtypname, NULL,
12157 tyinfo->dobj.namespace->dobj.name,
12158 NULL, tyinfo->rolname, &tyinfo->dacl);
12159
12161 destroyPQExpBuffer(delq);
12162 free(qtypname);
12163 free(qualtypname);
12164}

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

15891{
15892 PQExpBuffer q;
15893 PQExpBuffer delq;
15894 PQExpBuffer query;
15895 PQExpBuffer tag;
15896 PGresult *res;
15897 int ntups;
15898 int i_usename;
15899 int i_umoptions;
15900 int i;
15901
15902 q = createPQExpBuffer();
15903 tag = createPQExpBuffer();
15904 delq = createPQExpBuffer();
15905 query = createPQExpBuffer();
15906
15907 /*
15908 * We read from the publicly accessible view pg_user_mappings, so as not
15909 * to fail if run by a non-superuser. Note that the view will show
15910 * umoptions as null if the user hasn't got privileges for the associated
15911 * server; this means that pg_dump will dump such a mapping, but with no
15912 * OPTIONS clause. A possible alternative is to skip such mappings
15913 * altogether, but it's not clear that that's an improvement.
15914 */
15915 appendPQExpBuffer(query,
15916 "SELECT usename, "
15917 "array_to_string(ARRAY("
15918 "SELECT quote_ident(option_name) || ' ' || "
15919 "quote_literal(option_value) "
15920 "FROM pg_options_to_table(umoptions) "
15921 "ORDER BY option_name"
15922 "), E',\n ') AS umoptions "
15923 "FROM pg_user_mappings "
15924 "WHERE srvid = '%u' "
15925 "ORDER BY usename",
15926 catalogId.oid);
15927
15928 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
15929
15930 ntups = PQntuples(res);
15931 i_usename = PQfnumber(res, "usename");
15932 i_umoptions = PQfnumber(res, "umoptions");
15933
15934 for (i = 0; i < ntups; i++)
15935 {
15936 char *usename;
15937 char *umoptions;
15938
15939 usename = PQgetvalue(res, i, i_usename);
15940 umoptions = PQgetvalue(res, i, i_umoptions);
15941
15943 appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
15944 appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
15945
15946 if (umoptions && strlen(umoptions) > 0)
15947 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions);
15948
15949 appendPQExpBufferStr(q, ";\n");
15950
15951 resetPQExpBuffer(delq);
15952 appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
15953 appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
15954
15955 resetPQExpBuffer(tag);
15956 appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
15957 usename, servername);
15958
15960 ARCHIVE_OPTS(.tag = tag->data,
15961 .namespace = namespace,
15962 .owner = owner,
15963 .description = "USER MAPPING",
15964 .section = SECTION_PRE_DATA,
15965 .createStmt = q->data,
15966 .dropStmt = delq->data));
15967 }
15968
15969 PQclear(res);
15970
15971 destroyPQExpBuffer(query);
15972 destroyPQExpBuffer(delq);
15973 destroyPQExpBuffer(tag);
15975}

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

1645{
1646 PQExpBuffer query;
1647 PGresult *res;
1649 int i;
1650
1651 if (patterns->head == NULL)
1652 return; /* nothing to do */
1653
1654 query = createPQExpBuffer();
1655
1656 /*
1657 * The loop below runs multiple SELECTs might sometimes result in
1658 * duplicate entries in the OID list, but we don't care.
1659 */
1660 for (cell = patterns->head; cell; cell = cell->next)
1661 {
1662 int dotcnt;
1663
1665 "SELECT oid FROM pg_catalog.pg_extension e\n");
1666 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1667 false, NULL, "e.extname", NULL, NULL, NULL,
1668 &dotcnt);
1669 if (dotcnt > 0)
1670 pg_fatal("improper qualified name (too many dotted names): %s",
1671 cell->val);
1672
1673 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1674 if (strict_names && PQntuples(res) == 0)
1675 pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
1676
1677 for (i = 0; i < PQntuples(res); i++)
1678 {
1679 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1680 }
1681
1682 PQclear(res);
1683 resetPQExpBuffer(query);
1684 }
1685
1686 destroyPQExpBuffer(query);
1687}
static int strict_names
Definition: pg_dump.c:152
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 1694 of file pg_dump.c.

1697{
1698 PQExpBuffer query;
1699 PGresult *res;
1701 int i;
1702
1703 if (patterns->head == NULL)
1704 return; /* nothing to do */
1705
1706 query = createPQExpBuffer();
1707
1708 /*
1709 * The loop below runs multiple SELECTs might sometimes result in
1710 * duplicate entries in the OID list, but we don't care.
1711 */
1712
1713 for (cell = patterns->head; cell; cell = cell->next)
1714 {
1715 int dotcnt;
1716
1718 "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
1719 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1720 false, NULL, "s.srvname", NULL, NULL, NULL,
1721 &dotcnt);
1722 if (dotcnt > 0)
1723 pg_fatal("improper qualified name (too many dotted names): %s",
1724 cell->val);
1725
1726 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1727 if (PQntuples(res) == 0)
1728 pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
1729
1730 for (i = 0; i < PQntuples(res); i++)
1731 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1732
1733 PQclear(res);
1734 resetPQExpBuffer(query);
1735 }
1736
1737 destroyPQExpBuffer(query);
1738}

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

1586{
1587 PQExpBuffer query;
1588 PGresult *res;
1590 int i;
1591
1592 if (patterns->head == NULL)
1593 return; /* nothing to do */
1594
1595 query = createPQExpBuffer();
1596
1597 /*
1598 * The loop below runs multiple SELECTs might sometimes result in
1599 * duplicate entries in the OID list, but we don't care.
1600 */
1601
1602 for (cell = patterns->head; cell; cell = cell->next)
1603 {
1604 PQExpBufferData dbbuf;
1605 int dotcnt;
1606
1608 "SELECT oid FROM pg_catalog.pg_namespace n\n");
1609 initPQExpBuffer(&dbbuf);
1610 processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1611 false, NULL, "n.nspname", NULL, NULL, &dbbuf,
1612 &dotcnt);
1613 if (dotcnt > 1)
1614 pg_fatal("improper qualified name (too many dotted names): %s",
1615 cell->val);
1616 else if (dotcnt == 1)
1617 prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1618 termPQExpBuffer(&dbbuf);
1619
1620 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1621 if (strict_names && PQntuples(res) == 0)
1622 pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
1623
1624 for (i = 0; i < PQntuples(res); i++)
1625 {
1626 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1627 }
1628
1629 PQclear(res);
1630 resetPQExpBuffer(query);
1631 }
1632
1633 destroyPQExpBuffer(query);
1634}
static void prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
Definition: pg_dump.c:1842
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 1746 of file pg_dump.c.

1749{
1750 PQExpBuffer query;
1751 PGresult *res;
1753 int i;
1754
1755 if (patterns->head == NULL)
1756 return; /* nothing to do */
1757
1758 query = createPQExpBuffer();
1759
1760 /*
1761 * this might sometimes result in duplicate entries in the OID list, but
1762 * we don't care.
1763 */
1764
1765 for (cell = patterns->head; cell; cell = cell->next)
1766 {
1767 PQExpBufferData dbbuf;
1768 int dotcnt;
1769
1770 /*
1771 * Query must remain ABSOLUTELY devoid of unqualified names. This
1772 * would be unnecessary given a pg_table_is_visible() variant taking a
1773 * search_path argument.
1774 *
1775 * For with_child_tables, we start with the basic query's results and
1776 * recursively search the inheritance tree to add child tables.
1777 */
1778 if (with_child_tables)
1779 {
1780 appendPQExpBufferStr(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
1781 }
1782
1783 appendPQExpBuffer(query,
1784 "SELECT c.oid"
1785 "\nFROM pg_catalog.pg_class c"
1786 "\n LEFT JOIN pg_catalog.pg_namespace n"
1787 "\n ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
1788 "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
1789 "\n (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
1790 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
1791 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
1792 RELKIND_PARTITIONED_TABLE);
1793 initPQExpBuffer(&dbbuf);
1794 processSQLNamePattern(GetConnection(fout), query, cell->val, true,
1795 false, "n.nspname", "c.relname", NULL,
1796 "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
1797 &dotcnt);
1798 if (dotcnt > 2)
1799 pg_fatal("improper relation name (too many dotted names): %s",
1800 cell->val);
1801 else if (dotcnt == 2)
1802 prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
1803 termPQExpBuffer(&dbbuf);
1804
1805 if (with_child_tables)
1806 {
1807 appendPQExpBufferStr(query, "UNION"
1808 "\nSELECT i.inhrelid"
1809 "\nFROM partition_tree p"
1810 "\n JOIN pg_catalog.pg_inherits i"
1811 "\n ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
1812 "\n)"
1813 "\nSELECT relid FROM partition_tree");
1814 }
1815
1816 ExecuteSqlStatement(fout, "RESET search_path");
1817 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1820 if (strict_names && PQntuples(res) == 0)
1821 pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
1822
1823 for (i = 0; i < PQntuples(res); i++)
1824 {
1825 simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1826 }
1827
1828 PQclear(res);
1829 resetPQExpBuffer(query);
1830 }
1831
1832 destroyPQExpBuffer(query);
1833}
#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 10730 of file pg_dump.c.

10731{
10732 ArchiveHandle *AH = (ArchiveHandle *) fout;
10733 PQExpBuffer nspnames = createPQExpBuffer();
10734 PQExpBuffer relnames = createPQExpBuffer();
10735 int count = 0;
10736 PGresult *res = NULL;
10737 static TocEntry *te;
10738 static bool restarted;
10739 int max_rels = MAX_ATTR_STATS_RELS;
10740
10741 /*
10742 * Our query for retrieving statistics for multiple relations uses WITH
10743 * ORDINALITY and multi-argument UNNEST(), both of which were introduced
10744 * in v9.4. For older versions, we resort to gathering statistics for a
10745 * single relation at a time.
10746 */
10747 if (fout->remoteVersion < 90400)
10748 max_rels = 1;
10749
10750 /* If we're just starting, set our TOC pointer. */
10751 if (!te)
10752 te = AH->toc->next;
10753
10754 /*
10755 * We can't easily avoid a second TOC scan for the tar format because it
10756 * writes restore.sql separately, which means we must execute the queries
10757 * twice. This feels risky, but there is no known reason it should
10758 * generate different output than the first pass. Even if it does, the
10759 * worst-case scenario is that restore.sql might have different statistics
10760 * data than the archive.
10761 */
10762 if (!restarted && te == AH->toc && AH->format == archTar)
10763 {
10764 te = AH->toc->next;
10765 restarted = true;
10766 }
10767
10768 appendPQExpBufferChar(nspnames, '{');
10769 appendPQExpBufferChar(relnames, '{');
10770
10771 /*
10772 * Scan the TOC for the next set of relevant stats entries. We assume
10773 * that statistics are dumped in the order they are listed in the TOC.
10774 * This is perhaps not the sturdiest assumption, so we verify it matches
10775 * reality in dumpRelationStats_dumper().
10776 */
10777 for (; te != AH->toc && count < max_rels; te = te->next)
10778 {
10779 if ((te->reqs & REQ_STATS) != 0 &&
10780 strcmp(te->desc, "STATISTICS DATA") == 0)
10781 {
10782 appendPGArray(nspnames, te->namespace);
10783 appendPGArray(relnames, te->tag);
10784 count++;
10785 }
10786 }
10787
10788 appendPQExpBufferChar(nspnames, '}');
10789 appendPQExpBufferChar(relnames, '}');
10790
10791 /* Execute the query for the next batch of relations. */
10792 if (count > 0)
10793 {
10795
10796 appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
10797 appendStringLiteralAH(query, nspnames->data, fout);
10798 appendPQExpBufferStr(query, "::pg_catalog.name[],");
10799 appendStringLiteralAH(query, relnames->data, fout);
10800 appendPQExpBufferStr(query, "::pg_catalog.name[])");
10801 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10802 destroyPQExpBuffer(query);
10803 }
10804
10805 destroyPQExpBuffer(nspnames);
10806 destroyPQExpBuffer(relnames);
10807 return res;
10808}
@ archTar
Definition: pg_backup.h:43
#define MAX_ATTR_STATS_RELS
Definition: pg_dump.c:213
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 11215 of file pg_dump.c.

11216{
11217 CommentItem *middle = NULL;
11218 CommentItem *low;
11219 CommentItem *high;
11220 int nmatch;
11221
11222 /*
11223 * Do binary search to find some item matching the object.
11224 */
11225 low = &comments[0];
11226 high = &comments[ncomments - 1];
11227 while (low <= high)
11228 {
11229 middle = low + (high - low) / 2;
11230
11231 if (classoid < middle->classoid)
11232 high = middle - 1;
11233 else if (classoid > middle->classoid)
11234 low = middle + 1;
11235 else if (objoid < middle->objoid)
11236 high = middle - 1;
11237 else if (objoid > middle->objoid)
11238 low = middle + 1;
11239 else
11240 break; /* found a match */
11241 }
11242
11243 if (low > high) /* no matches */
11244 {
11245 *items = NULL;
11246 return 0;
11247 }
11248
11249 /*
11250 * Now determine how many items match the object. The search loop
11251 * invariant still holds: only items between low and high inclusive could
11252 * match.
11253 */
11254 nmatch = 1;
11255 while (middle > low)
11256 {
11257 if (classoid != middle[-1].classoid ||
11258 objoid != middle[-1].objoid)
11259 break;
11260 middle--;
11261 nmatch++;
11262 }
11263
11264 *items = middle;
11265
11266 middle += nmatch;
11267 while (middle <= high)
11268 {
11269 if (classoid != middle->classoid ||
11270 objoid != middle->objoid)
11271 break;
11272 middle++;
11273 nmatch++;
11274 }
11275
11276 return nmatch;
11277}
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 19896 of file pg_dump.c.

19898{
19899 int i;
19900
19901 /*
19902 * Ignore section boundary objects: if we search through them, we'll
19903 * report lots of bogus dependencies.
19904 */
19905 if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
19907 return;
19908
19909 for (i = 0; i < dobj->nDeps; i++)
19910 {
19911 DumpId depid = dobj->dependencies[i];
19912
19913 if (TocIDRequired(AH, depid) != 0)
19914 {
19915 /* Object will be dumped, so just reference it as a dependency */
19916 if (*nDeps >= *allocDeps)
19917 {
19918 *allocDeps *= 2;
19919 *dependencies = (DumpId *) pg_realloc(*dependencies,
19920 *allocDeps * sizeof(DumpId));
19921 }
19922 (*dependencies)[*nDeps] = depid;
19923 (*nDeps)++;
19924 }
19925 else
19926 {
19927 /*
19928 * Object will not be dumped, so recursively consider its deps. We
19929 * rely on the assumption that sortDumpableObjects already broke
19930 * any dependency loops, else we might recurse infinitely.
19931 */
19932 DumpableObject *otherdobj = findObjectByDumpId(depid);
19933
19934 if (otherdobj)
19935 findDumpableDependencies(AH, otherdobj,
19936 dependencies, nDeps, allocDeps);
19937 }
19938 }
19939}
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 5909 of file pg_dump.c.

5910{
5911 NamespaceInfo *nsinfo;
5912
5913 nsinfo = findNamespaceByOid(nsoid);
5914 if (nsinfo == NULL)
5915 pg_fatal("schema with OID %u does not exist", nsoid);
5916 return nsinfo;
5917}
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:971

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

16364{
16365 SecLabelItem *middle = NULL;
16366 SecLabelItem *low;
16367 SecLabelItem *high;
16368 int nmatch;
16369
16370 if (nseclabels <= 0) /* no labels, so no match is possible */
16371 {
16372 *items = NULL;
16373 return 0;
16374 }
16375
16376 /*
16377 * Do binary search to find some item matching the object.
16378 */
16379 low = &seclabels[0];
16380 high = &seclabels[nseclabels - 1];
16381 while (low <= high)
16382 {
16383 middle = low + (high - low) / 2;
16384
16385 if (classoid < middle->classoid)
16386 high = middle - 1;
16387 else if (classoid > middle->classoid)
16388 low = middle + 1;
16389 else if (objoid < middle->objoid)
16390 high = middle - 1;
16391 else if (objoid > middle->objoid)
16392 low = middle + 1;
16393 else
16394 break; /* found a match */
16395 }
16396
16397 if (low > high) /* no matches */
16398 {
16399 *items = NULL;
16400 return 0;
16401 }
16402
16403 /*
16404 * Now determine how many items match the object. The search loop
16405 * invariant still holds: only items between low and high inclusive could
16406 * match.
16407 */
16408 nmatch = 1;
16409 while (middle > low)
16410 {
16411 if (classoid != middle[-1].classoid ||
16412 objoid != middle[-1].objoid)
16413 break;
16414 middle--;
16415 nmatch++;
16416 }
16417
16418 *items = middle;
16419
16420 middle += nmatch;
16421 while (middle <= high)
16422 {
16423 if (classoid != middle->classoid ||
16424 objoid != middle->objoid)
16425 break;
16426 middle++;
16427 nmatch++;
16428 }
16429
16430 return nmatch;
16431}

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

20004{
20005 int numatts = ti->numatts;
20006 char **attnames = ti->attnames;
20007 bool *attisdropped = ti->attisdropped;
20008 char *attgenerated = ti->attgenerated;
20009 bool needComma;
20010 int i;
20011
20012 appendPQExpBufferChar(buffer, '(');
20013 needComma = false;
20014 for (i = 0; i < numatts; i++)
20015 {
20016 if (attisdropped[i])
20017 continue;
20018 if (attgenerated[i])
20019 continue;
20020 if (needComma)
20021 appendPQExpBufferStr(buffer, ", ");
20022 appendPQExpBufferStr(buffer, fmtId(attnames[i]));
20023 needComma = true;
20024 }
20025
20026 if (!needComma)
20027 return ""; /* no undropped columns */
20028
20029 appendPQExpBufferChar(buffer, ')');
20030 return buffer->data;
20031}

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

2755{
2756 TableInfo *parentTbinfo;
2757
2758 Assert(tbinfo->ispartition);
2759 Assert(tbinfo->numParents == 1);
2760
2761 parentTbinfo = tbinfo->parents[0];
2762 if (parentTbinfo->unsafe_partitions)
2763 return true;
2764 while (parentTbinfo->ispartition)
2765 {
2766 Assert(parentTbinfo->numParents == 1);
2767 parentTbinfo = parentTbinfo->parents[0];
2768 if (parentTbinfo->unsafe_partitions)
2769 return true;
2770 }
2771
2772 return false;
2773}
bool unsafe_partitions
Definition: pg_dump.h:338

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

15004{
15006 int j;
15007
15009 if (honor_quotes)
15010 appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
15011 else
15012 appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
15013
15014 if (agginfo->aggfn.nargs == 0)
15015 appendPQExpBufferStr(&buf, "(*)");
15016 else
15017 {
15019 for (j = 0; j < agginfo->aggfn.nargs; j++)
15020 appendPQExpBuffer(&buf, "%s%s",
15021 (j > 0) ? ", " : "",
15023 agginfo->aggfn.argtypes[j],
15024 zeroIsError));
15026 }
15027 return buf.data;
15028}

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

13067{
13069
13072 if (is_agg && finfo->nargs == 0)
13073 appendPQExpBufferStr(&fn, "(*)");
13074 else
13075 appendPQExpBuffer(&fn, "(%s)", funcargs);
13076 return fn.data;
13077}
int nargs
Definition: pg_dump.h:243
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 13089 of file pg_dump.c.

13090{
13092 int j;
13093
13095 if (honor_quotes)
13096 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
13097 else
13098 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
13099 for (j = 0; j < finfo->nargs; j++)
13100 {
13101 if (j > 0)
13102 appendPQExpBufferStr(&fn, ", ");
13103
13105 getFormattedTypeName(fout, finfo->argtypes[j],
13106 zeroIsError));
13107 }
13109 return fn.data;
13110}
Oid * argtypes
Definition: pg_dump.h:244

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

8879{
8880 PQExpBuffer query;
8881 PGresult *res;
8882 char *lanname;
8883
8884 query = createPQExpBuffer();
8885 appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
8886 res = ExecuteSqlQueryForSingleRow(fout, query->data);
8887 lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
8888 destroyPQExpBuffer(query);
8889 PQclear(res);
8890
8891 return lanname;
8892}

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

5486{
5487 /*
5488 * If the old version didn't assign an array type, but the new version
5489 * does, we must select an unused type OID to assign. This currently only
5490 * happens for domains, when upgrading pre-v11 to v11 and up.
5491 *
5492 * Note: local state here is kind of ugly, but we must have some, since we
5493 * mustn't choose the same unused OID more than once.
5494 */
5495 static Oid next_possible_free_oid = FirstNormalObjectId;
5496 PGresult *res;
5497 bool is_dup;
5498
5499 do
5500 {
5501 ++next_possible_free_oid;
5502 printfPQExpBuffer(upgrade_query,
5503 "SELECT EXISTS(SELECT 1 "
5504 "FROM pg_catalog.pg_type "
5505 "WHERE oid = '%u'::pg_catalog.oid);",
5506 next_possible_free_oid);
5507 res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5508 is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
5509 PQclear(res);
5510 } while (is_dup);
5511
5512 return next_possible_free_oid;
5513}
#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 1530 of file pg_dump.c.

1531{
1532 char *query = "SELECT pg_catalog.pg_export_snapshot()";
1533 char *result;
1534 PGresult *res;
1535
1536 res = ExecuteSqlQueryForSingleRow(fout, query);
1537 result = pg_strdup(PQgetvalue(res, 0, 0));
1538 PQclear(res);
1539
1540 return result;
1541}

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

Referenced by setup_connection().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6361 of file pg_dump.c.

6362{
6363 PGresult *res;
6364 int ntups;
6365 int i;
6366 PQExpBuffer query;
6367 AccessMethodInfo *aminfo;
6368 int i_tableoid;
6369 int i_oid;
6370 int i_amname;
6371 int i_amhandler;
6372 int i_amtype;
6373
6374 /* Before 9.6, there are no user-defined access methods */
6375 if (fout->remoteVersion < 90600)
6376 return;
6377
6378 query = createPQExpBuffer();
6379
6380 /* Select all access methods from pg_am table */
6381 appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6382 "amhandler::pg_catalog.regproc AS amhandler "
6383 "FROM pg_am");
6384
6385 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6386
6387 ntups = PQntuples(res);
6388
6389 aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6390
6391 i_tableoid = PQfnumber(res, "tableoid");
6392 i_oid = PQfnumber(res, "oid");
6393 i_amname = PQfnumber(res, "amname");
6394 i_amhandler = PQfnumber(res, "amhandler");
6395 i_amtype = PQfnumber(res, "amtype");
6396
6397 for (i = 0; i < ntups; i++)
6398 {
6399 aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6400 aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6401 aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6402 AssignDumpId(&aminfo[i].dobj);
6403 aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6404 aminfo[i].dobj.namespace = NULL;
6405 aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6406 aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6407
6408 /* Decide whether we want to dump it */
6409 selectDumpableAccessMethod(&(aminfo[i]), fout);
6410 }
6411
6412 PQclear(res);
6413
6414 destroyPQExpBuffer(query);
6415}
static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
Definition: pg_dump.c:2167

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

10468{
10470 PGresult *res;
10471 int ntups,
10472 i;
10473
10474 /* Check for per-column ACLs */
10476 "SELECT DISTINCT attrelid FROM pg_attribute "
10477 "WHERE attacl IS NOT NULL");
10478
10479 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10480
10481 ntups = PQntuples(res);
10482 for (i = 0; i < ntups; i++)
10483 {
10484 Oid relid = atooid(PQgetvalue(res, i, 0));
10485 TableInfo *tblinfo;
10486
10487 tblinfo = findTableByOid(relid);
10488 /* OK to ignore tables we haven't got a DumpableObject for */
10489 if (tblinfo)
10490 {
10492 tblinfo->hascolumnACLs = true;
10493 }
10494 }
10495 PQclear(res);
10496
10497 /* Fetch initial-privileges data */
10498 if (fout->remoteVersion >= 90600)
10499 {
10500 printfPQExpBuffer(query,
10501 "SELECT objoid, classoid, objsubid, privtype, initprivs "
10502 "FROM pg_init_privs");
10503
10504 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10505
10506 ntups = PQntuples(res);
10507 for (i = 0; i < ntups; i++)
10508 {
10509 Oid objoid = atooid(PQgetvalue(res, i, 0));
10510 Oid classoid = atooid(PQgetvalue(res, i, 1));
10511 int objsubid = atoi(PQgetvalue(res, i, 2));
10512 char privtype = *(PQgetvalue(res, i, 3));
10513 char *initprivs = PQgetvalue(res, i, 4);
10514 CatalogId objId;
10515 DumpableObject *dobj;
10516
10517 objId.tableoid = classoid;
10518 objId.oid = objoid;
10519 dobj = findObjectByCatalogId(objId);
10520 /* OK to ignore entries we haven't got a DumpableObject for */
10521 if (dobj)
10522 {
10523 /* Cope with sub-object initprivs */
10524 if (objsubid != 0)
10525 {
10526 if (dobj->objType == DO_TABLE)
10527 {
10528 /* For a column initprivs, set the table's ACL flags */
10530 ((TableInfo *) dobj)->hascolumnACLs = true;
10531 }
10532 else
10533 pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10534 classoid, objoid, objsubid);
10535 continue;
10536 }
10537
10538 /*
10539 * We ignore any pg_init_privs.initprivs entry for the public
10540 * schema, as explained in getNamespaces().
10541 */
10542 if (dobj->objType == DO_NAMESPACE &&
10543 strcmp(dobj->name, "public") == 0)
10544 continue;
10545
10546 /* Else it had better be of a type we think has ACLs */
10547 if (dobj->objType == DO_NAMESPACE ||
10548 dobj->objType == DO_TYPE ||
10549 dobj->objType == DO_FUNC ||
10550 dobj->objType == DO_AGG ||
10551 dobj->objType == DO_TABLE ||
10552 dobj->objType == DO_PROCLANG ||
10553 dobj->objType == DO_FDW ||
10554 dobj->objType == DO_FOREIGN_SERVER)
10555 {
10557
10558 daobj->dacl.privtype = privtype;
10559 daobj->dacl.initprivs = pstrdup(initprivs);
10560 }
10561 else
10562 pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
10563 classoid, objoid, objsubid);
10564 }
10565 }
10566 PQclear(res);
10567 }
10568
10569 destroyPQExpBuffer(query);
10570}
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 6545 of file pg_dump.c.

6546{
6547 DumpOptions *dopt = fout->dopt;
6548 PGresult *res;
6549 int ntups;
6550 int i;
6552 AggInfo *agginfo;
6553 int i_tableoid;
6554 int i_oid;
6555 int i_aggname;
6556 int i_aggnamespace;
6557 int i_pronargs;
6558 int i_proargtypes;
6559 int i_proowner;
6560 int i_aggacl;
6561 int i_acldefault;
6562
6563 /*
6564 * Find all interesting aggregates. See comment in getFuncs() for the
6565 * rationale behind the filtering logic.
6566 */
6567 if (fout->remoteVersion >= 90600)
6568 {
6569 const char *agg_check;
6570
6571 agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
6572 : "p.proisagg");
6573
6574 appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
6575 "p.proname AS aggname, "
6576 "p.pronamespace AS aggnamespace, "
6577 "p.pronargs, p.proargtypes, "
6578 "p.proowner, "
6579 "p.proacl AS aggacl, "
6580 "acldefault('f', p.proowner) AS acldefault "
6581 "FROM pg_proc p "
6582 "LEFT JOIN pg_init_privs pip ON "
6583 "(p.oid = pip.objoid "
6584 "AND pip.classoid = 'pg_proc'::regclass "
6585 "AND pip.objsubid = 0) "
6586 "WHERE %s AND ("
6587 "p.pronamespace != "
6588 "(SELECT oid FROM pg_namespace "
6589 "WHERE nspname = 'pg_catalog') OR "
6590 "p.proacl IS DISTINCT FROM pip.initprivs",
6591 agg_check);
6592 if (dopt->binary_upgrade)
6594 " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6595 "classid = 'pg_proc'::regclass AND "
6596 "objid = p.oid AND "
6597 "refclassid = 'pg_extension'::regclass AND "
6598 "deptype = 'e')");
6599 appendPQExpBufferChar(query, ')');
6600 }
6601 else
6602 {
6603 appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
6604 "pronamespace AS aggnamespace, "
6605 "pronargs, proargtypes, "
6606 "proowner, "
6607 "proacl AS aggacl, "
6608 "acldefault('f', proowner) AS acldefault "
6609 "FROM pg_proc p "
6610 "WHERE proisagg AND ("
6611 "pronamespace != "
6612 "(SELECT oid FROM pg_namespace "
6613 "WHERE nspname = 'pg_catalog')");
6614 if (dopt->binary_upgrade)
6616 " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6617 "classid = 'pg_proc'::regclass AND "
6618 "objid = p.oid AND "
6619 "refclassid = 'pg_extension'::regclass AND "
6620 "deptype = 'e')");
6621 appendPQExpBufferChar(query, ')');
6622 }
6623
6624 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6625
6626 ntups = PQntuples(res);
6627
6628 agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
6629
6630 i_tableoid = PQfnumber(res, "tableoid");
6631 i_oid = PQfnumber(res, "oid");
6632 i_aggname = PQfnumber(res, "aggname");
6633 i_aggnamespace = PQfnumber(res, "aggnamespace");
6634 i_pronargs = PQfnumber(res, "pronargs");
6635 i_proargtypes = PQfnumber(res, "proargtypes");
6636 i_proowner = PQfnumber(res, "proowner");
6637 i_aggacl = PQfnumber(res, "aggacl");
6638 i_acldefault = PQfnumber(res, "acldefault");
6639
6640 for (i = 0; i < ntups; i++)
6641 {
6642 agginfo[i].aggfn.dobj.objType = DO_AGG;
6643 agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6644 agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6645 AssignDumpId(&agginfo[i].aggfn.dobj);
6646 agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
6647 agginfo[i].aggfn.dobj.namespace =
6648 findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
6649 agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
6650 agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6651 agginfo[i].aggfn.dacl.privtype = 0;
6652 agginfo[i].aggfn.dacl.initprivs = NULL;
6653 agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6654 agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
6655 agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
6656 agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
6657 if (agginfo[i].aggfn.nargs == 0)
6658 agginfo[i].aggfn.argtypes = NULL;
6659 else
6660 {
6661 agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
6662 parseOidArray(PQgetvalue(res, i, i_proargtypes),
6663 agginfo[i].aggfn.argtypes,
6664 agginfo[i].aggfn.nargs);
6665 }
6666 agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
6667
6668 /* Decide whether we want to dump it */
6669 selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
6670
6671 /* Mark whether aggregate has an ACL */
6672 if (!PQgetisnull(res, i, i_aggacl))
6673 agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
6674 }
6675
6676 PQclear(res);
6677
6678 destroyPQExpBuffer(query);
6679}
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2270
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:5909

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

17852{
17853 if (attrnum > 0 && attrnum <= tblInfo->numatts)
17854 return tblInfo->attnames[attrnum - 1];
17855 switch (attrnum)
17856 {
17858 return "ctid";
17860 return "xmin";
17862 return "cmin";
17864 return "xmax";
17866 return "cmax";
17868 return "tableoid";
17869 }
17870 pg_fatal("invalid column number %d for table \"%s\"",
17871 attrnum, tblInfo->dobj.name);
17872 return NULL; /* keep compiler quiet */
17873}
#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 8789 of file pg_dump.c.

8790{
8791 PGresult *res;
8792 int ntups;
8793 int i;
8795 CastInfo *castinfo;
8796 int i_tableoid;
8797 int i_oid;
8798 int i_castsource;
8799 int i_casttarget;
8800 int i_castfunc;
8801 int i_castcontext;
8802 int i_castmethod;
8803
8804 if (fout->remoteVersion >= 140000)
8805 {
8806 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8807 "castsource, casttarget, castfunc, castcontext, "
8808 "castmethod "
8809 "FROM pg_cast c "
8810 "WHERE NOT EXISTS ( "
8811 "SELECT 1 FROM pg_range r "
8812 "WHERE c.castsource = r.rngtypid "
8813 "AND c.casttarget = r.rngmultitypid "
8814 ") "
8815 "ORDER BY 3,4");
8816 }
8817 else
8818 {
8819 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8820 "castsource, casttarget, castfunc, castcontext, "
8821 "castmethod "
8822 "FROM pg_cast ORDER BY 3,4");
8823 }
8824
8825 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8826
8827 ntups = PQntuples(res);
8828
8829 castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8830
8831 i_tableoid = PQfnumber(res, "tableoid");
8832 i_oid = PQfnumber(res, "oid");
8833 i_castsource = PQfnumber(res, "castsource");
8834 i_casttarget = PQfnumber(res, "casttarget");
8835 i_castfunc = PQfnumber(res, "castfunc");
8836 i_castcontext = PQfnumber(res, "castcontext");
8837 i_castmethod = PQfnumber(res, "castmethod");
8838
8839 for (i = 0; i < ntups; i++)
8840 {
8841 PQExpBufferData namebuf;
8842 TypeInfo *sTypeInfo;
8843 TypeInfo *tTypeInfo;
8844
8845 castinfo[i].dobj.objType = DO_CAST;
8846 castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8847 castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8848 AssignDumpId(&castinfo[i].dobj);
8849 castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8850 castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8851 castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8852 castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8853 castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8854
8855 /*
8856 * Try to name cast as concatenation of typnames. This is only used
8857 * for purposes of sorting. If we fail to find either type, the name
8858 * will be an empty string.
8859 */
8860 initPQExpBuffer(&namebuf);
8861 sTypeInfo = findTypeByOid(castinfo[i].castsource);
8862 tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8863 if (sTypeInfo && tTypeInfo)
8864 appendPQExpBuffer(&namebuf, "%s %s",
8865 sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8866 castinfo[i].dobj.name = namebuf.data;
8867
8868 /* Decide whether we want to dump it */
8869 selectDumpableCast(&(castinfo[i]), fout);
8870 }
8871
8872 PQclear(res);
8873
8874 destroyPQExpBuffer(query);
8875}
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:2109

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

6238{
6239 PGresult *res;
6240 int ntups;
6241 int i;
6242 PQExpBuffer query;
6243 CollInfo *collinfo;
6244 int i_tableoid;
6245 int i_oid;
6246 int i_collname;
6247 int i_collnamespace;
6248 int i_collowner;
6249
6250 query = createPQExpBuffer();
6251
6252 /*
6253 * find all collations, including builtin collations; we filter out
6254 * system-defined collations at dump-out time.
6255 */
6256
6257 appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6258 "collnamespace, "
6259 "collowner "
6260 "FROM pg_collation");
6261
6262 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6263
6264 ntups = PQntuples(res);
6265
6266 collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6267
6268 i_tableoid = PQfnumber(res, "tableoid");
6269 i_oid = PQfnumber(res, "oid");
6270 i_collname = PQfnumber(res, "collname");
6271 i_collnamespace = PQfnumber(res, "collnamespace");
6272 i_collowner = PQfnumber(res, "collowner");
6273
6274 for (i = 0; i < ntups; i++)
6275 {
6276 collinfo[i].dobj.objType = DO_COLLATION;
6277 collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6278 collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6279 AssignDumpId(&collinfo[i].dobj);
6280 collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6281 collinfo[i].dobj.namespace =
6282 findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6283 collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6284
6285 /* Decide whether we want to dump it */
6286 selectDumpableObject(&(collinfo[i].dobj), fout);
6287 }
6288
6289 PQclear(res);
6290
6291 destroyPQExpBuffer(query);
6292}

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

Referenced by getSchemaData().

◆ getConstraints()

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

Definition at line 8062 of file pg_dump.c.

8063{
8065 PQExpBuffer tbloids = createPQExpBuffer();
8066 PGresult *res;
8067 int ntups;
8068 int curtblindx;
8069 TableInfo *tbinfo = NULL;
8070 ConstraintInfo *constrinfo;
8071 int i_contableoid,
8072 i_conoid,
8073 i_conrelid,
8074 i_conname,
8075 i_confrelid,
8076 i_conindid,
8077 i_condef;
8078
8079 /*
8080 * We want to perform just one query against pg_constraint. However, we
8081 * mustn't try to select every row of the catalog and then sort it out on
8082 * the client side, because some of the server-side functions we need
8083 * would be unsafe to apply to tables we don't have lock on. Hence, we
8084 * build an array of the OIDs of tables we care about (and now have lock
8085 * on!), and use a WHERE clause to constrain which rows are selected.
8086 */
8087 appendPQExpBufferChar(tbloids, '{');
8088 for (int i = 0; i < numTables; i++)
8089 {
8090 TableInfo *tinfo = &tblinfo[i];
8091
8092 if (!(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8093 continue;
8094
8095 /* OK, we need info for this table */
8096 if (tbloids->len > 1) /* do we have more than the '{'? */
8097 appendPQExpBufferChar(tbloids, ',');
8098 appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
8099 }
8100 appendPQExpBufferChar(tbloids, '}');
8101
8103 "SELECT c.tableoid, c.oid, "
8104 "conrelid, conname, confrelid, ");
8105 if (fout->remoteVersion >= 110000)
8106 appendPQExpBufferStr(query, "conindid, ");
8107 else
8108 appendPQExpBufferStr(query, "0 AS conindid, ");
8109 appendPQExpBuffer(query,
8110 "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
8111 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8112 "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
8113 "WHERE contype = 'f' ",
8114 tbloids->data);
8115 if (fout->remoteVersion >= 110000)
8117 "AND conparentid = 0 ");
8119 "ORDER BY conrelid, conname");
8120
8121 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8122
8123 ntups = PQntuples(res);
8124
8125 i_contableoid = PQfnumber(res, "tableoid");
8126 i_conoid = PQfnumber(res, "oid");
8127 i_conrelid = PQfnumber(res, "conrelid");
8128 i_conname = PQfnumber(res, "conname");
8129 i_confrelid = PQfnumber(res, "confrelid");
8130 i_conindid = PQfnumber(res, "conindid");
8131 i_condef = PQfnumber(res, "condef");
8132
8133 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
8134
8135 curtblindx = -1;
8136 for (int j = 0; j < ntups; j++)
8137 {
8138 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
8139 TableInfo *reftable;
8140
8141 /*
8142 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8143 * order.
8144 */
8145 if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
8146 {
8147 while (++curtblindx < numTables)
8148 {
8149 tbinfo = &tblinfo[curtblindx];
8150 if (tbinfo->dobj.catId.oid == conrelid)
8151 break;
8152 }
8153 if (curtblindx >= numTables)
8154 pg_fatal("unrecognized table OID %u", conrelid);
8155 }
8156
8157 constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
8158 constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
8159 constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
8160 AssignDumpId(&constrinfo[j].dobj);
8161 constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
8162 constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
8163 constrinfo[j].contable = tbinfo;
8164 constrinfo[j].condomain = NULL;
8165 constrinfo[j].contype = 'f';
8166 constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
8167 constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
8168 constrinfo[j].conindex = 0;
8169 constrinfo[j].condeferrable = false;
8170 constrinfo[j].condeferred = false;
8171 constrinfo[j].conislocal = true;
8172 constrinfo[j].separate = true;
8173
8174 /*
8175 * Restoring an FK that points to a partitioned table requires that
8176 * all partition indexes have been attached beforehand. Ensure that
8177 * happens by making the constraint depend on each index partition
8178 * attach object.
8179 */
8180 reftable = findTableByOid(constrinfo[j].confrelid);
8181 if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
8182 {
8183 Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
8184
8185 if (indexOid != InvalidOid)
8186 {
8187 for (int k = 0; k < reftable->numIndexes; k++)
8188 {
8189 IndxInfo *refidx;
8190
8191 /* not our index? */
8192 if (reftable->indexes[k].dobj.catId.oid != indexOid)
8193 continue;
8194
8195 refidx = &reftable->indexes[k];
8196 addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
8197 break;
8198 }
8199 }
8200 }
8201 }
8202
8203 PQclear(res);
8204
8205 destroyPQExpBuffer(query);
8206 destroyPQExpBuffer(tbloids);
8207}
struct _indxInfo * indexes
Definition: pg_dump.h:381
int numIndexes
Definition: pg_dump.h:380

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

6300{
6301 PGresult *res;
6302 int ntups;
6303 int i;
6304 PQExpBuffer query;
6305 ConvInfo *convinfo;
6306 int i_tableoid;
6307 int i_oid;
6308 int i_conname;
6309 int i_connamespace;
6310 int i_conowner;
6311
6312 query = createPQExpBuffer();
6313
6314 /*
6315 * find all conversions, including builtin conversions; we filter out
6316 * system-defined conversions at dump-out time.
6317 */
6318
6319 appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6320 "connamespace, "
6321 "conowner "
6322 "FROM pg_conversion");
6323
6324 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6325
6326 ntups = PQntuples(res);
6327
6328 convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6329
6330 i_tableoid = PQfnumber(res, "tableoid");
6331 i_oid = PQfnumber(res, "oid");
6332 i_conname = PQfnumber(res, "conname");
6333 i_connamespace = PQfnumber(res, "connamespace");
6334 i_conowner = PQfnumber(res, "conowner");
6335
6336 for (i = 0; i < ntups; i++)
6337 {
6338 convinfo[i].dobj.objType = DO_CONVERSION;
6339 convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6340 convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6341 AssignDumpId(&convinfo[i].dobj);
6342 convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6343 convinfo[i].dobj.namespace =
6344 findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6345 convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6346
6347 /* Decide whether we want to dump it */
6348 selectDumpableObject(&(convinfo[i].dobj), fout);
6349 }
6350
6351 PQclear(res);
6352
6353 destroyPQExpBuffer(query);
6354}

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

10300{
10301 DumpOptions *dopt = fout->dopt;
10302 DefaultACLInfo *daclinfo;
10303 PQExpBuffer query;
10304 PGresult *res;
10305 int i_oid;
10306 int i_tableoid;
10307 int i_defaclrole;
10308 int i_defaclnamespace;
10309 int i_defaclobjtype;
10310 int i_defaclacl;
10311 int i_acldefault;
10312 int i,
10313 ntups;
10314
10315 query = createPQExpBuffer();
10316
10317 /*
10318 * Global entries (with defaclnamespace=0) replace the hard-wired default
10319 * ACL for their object type. We should dump them as deltas from the
10320 * default ACL, since that will be used as a starting point for
10321 * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
10322 * non-global entries can only add privileges not revoke them. We must
10323 * dump those as-is (i.e., as deltas from an empty ACL).
10324 *
10325 * We can use defaclobjtype as the object type for acldefault(), except
10326 * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
10327 * 's'.
10328 */
10330 "SELECT oid, tableoid, "
10331 "defaclrole, "
10332 "defaclnamespace, "
10333 "defaclobjtype, "
10334 "defaclacl, "
10335 "CASE WHEN defaclnamespace = 0 THEN "
10336 "acldefault(CASE WHEN defaclobjtype = 'S' "
10337 "THEN 's'::\"char\" ELSE defaclobjtype END, "
10338 "defaclrole) ELSE '{}' END AS acldefault "
10339 "FROM pg_default_acl");
10340
10341 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10342
10343 ntups = PQntuples(res);
10344
10345 daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
10346
10347 i_oid = PQfnumber(res, "oid");
10348 i_tableoid = PQfnumber(res, "tableoid");
10349 i_defaclrole = PQfnumber(res, "defaclrole");
10350 i_defaclnamespace = PQfnumber(res, "defaclnamespace");
10351 i_defaclobjtype = PQfnumber(res, "defaclobjtype");
10352 i_defaclacl = PQfnumber(res, "defaclacl");
10353 i_acldefault = PQfnumber(res, "acldefault");
10354
10355 for (i = 0; i < ntups; i++)
10356 {
10357 Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
10358
10359 daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
10360 daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10361 daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10362 AssignDumpId(&daclinfo[i].dobj);
10363 /* cheesy ... is it worth coming up with a better object name? */
10364 daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
10365
10366 if (nspid != InvalidOid)
10367 daclinfo[i].dobj.namespace = findNamespace(nspid);
10368 else
10369 daclinfo[i].dobj.namespace = NULL;
10370
10371 daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
10372 daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10373 daclinfo[i].dacl.privtype = 0;
10374 daclinfo[i].dacl.initprivs = NULL;
10375 daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
10376 daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
10377
10378 /* Default ACLs are ACLs, of course */
10379 daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10380
10381 /* Decide whether we want to dump it */
10382 selectDumpableDefaultACL(&(daclinfo[i]), dopt);
10383 }
10384
10385 PQclear(res);
10386
10387 destroyPQExpBuffer(query);
10388}
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:2087

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

19546{
19547 PQExpBuffer query;
19548 PGresult *res;
19549 int ntups,
19550 i;
19551 int i_classid,
19552 i_objid,
19553 i_refclassid,
19554 i_refobjid,
19555 i_deptype;
19556 DumpableObject *dobj,
19557 *refdobj;
19558
19559 pg_log_info("reading dependency data");
19560
19561 query = createPQExpBuffer();
19562
19563 /*
19564 * Messy query to collect the dependency data we need. Note that we
19565 * ignore the sub-object column, so that dependencies of or on a column
19566 * look the same as dependencies of or on a whole table.
19567 *
19568 * PIN dependencies aren't interesting, and EXTENSION dependencies were
19569 * already processed by getExtensionMembership.
19570 */
19571 appendPQExpBufferStr(query, "SELECT "
19572 "classid, objid, refclassid, refobjid, deptype "
19573 "FROM pg_depend "
19574 "WHERE deptype != 'p' AND deptype != 'e'\n");
19575
19576 /*
19577 * Since we don't treat pg_amop entries as separate DumpableObjects, we
19578 * have to translate their dependencies into dependencies of their parent
19579 * opfamily. Ignore internal dependencies though, as those will point to
19580 * their parent opclass, which we needn't consider here (and if we did,
19581 * it'd just result in circular dependencies). Also, "loose" opfamily
19582 * entries will have dependencies on their parent opfamily, which we
19583 * should drop since they'd likewise become useless self-dependencies.
19584 * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
19585 */
19586 appendPQExpBufferStr(query, "UNION ALL\n"
19587 "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
19588 "FROM pg_depend d, pg_amop o "
19589 "WHERE deptype NOT IN ('p', 'e', 'i') AND "
19590 "classid = 'pg_amop'::regclass AND objid = o.oid "
19591 "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
19592
19593 /* Likewise for pg_amproc entries */
19594 appendPQExpBufferStr(query, "UNION ALL\n"
19595 "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
19596 "FROM pg_depend d, pg_amproc p "
19597 "WHERE deptype NOT IN ('p', 'e', 'i') AND "
19598 "classid = 'pg_amproc'::regclass AND objid = p.oid "
19599 "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
19600
19601 /* Sort the output for efficiency below */
19602 appendPQExpBufferStr(query, "ORDER BY 1,2");
19603
19604 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19605
19606 ntups = PQntuples(res);
19607
19608 i_classid = PQfnumber(res, "classid");
19609 i_objid = PQfnumber(res, "objid");
19610 i_refclassid = PQfnumber(res, "refclassid");
19611 i_refobjid = PQfnumber(res, "refobjid");
19612 i_deptype = PQfnumber(res, "deptype");
19613
19614 /*
19615 * Since we ordered the SELECT by referencing ID, we can expect that
19616 * multiple entries for the same object will appear together; this saves
19617 * on searches.
19618 */
19619 dobj = NULL;
19620
19621 for (i = 0; i < ntups; i++)
19622 {
19623 CatalogId objId;
19624 CatalogId refobjId;
19625 char deptype;
19626
19627 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
19628 objId.oid = atooid(PQgetvalue(res, i, i_objid));
19629 refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
19630 refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
19631 deptype = *(PQgetvalue(res, i, i_deptype));
19632
19633 if (dobj == NULL ||
19634 dobj->catId.tableoid != objId.tableoid ||
19635 dobj->catId.oid != objId.oid)
19636 dobj = findObjectByCatalogId(objId);
19637
19638 /*
19639 * Failure to find objects mentioned in pg_depend is not unexpected,
19640 * since for example we don't collect info about TOAST tables.
19641 */
19642 if (dobj == NULL)
19643 {
19644#ifdef NOT_USED
19645 pg_log_warning("no referencing object %u %u",
19646 objId.tableoid, objId.oid);
19647#endif
19648 continue;
19649 }
19650
19651 refdobj = findObjectByCatalogId(refobjId);
19652
19653 if (refdobj == NULL)
19654 {
19655#ifdef NOT_USED
19656 pg_log_warning("no referenced object %u %u",
19657 refobjId.tableoid, refobjId.oid);
19658#endif
19659 continue;
19660 }
19661
19662 /*
19663 * For 'x' dependencies, mark the object for later; we still add the
19664 * normal dependency, for possible ordering purposes. Currently
19665 * pg_dump_sort.c knows to put extensions ahead of all object types
19666 * that could possibly depend on them, but this is safer.
19667 */
19668 if (deptype == 'x')
19669 dobj->depends_on_ext = true;
19670
19671 /*
19672 * Ordinarily, table rowtypes have implicit dependencies on their
19673 * tables. However, for a composite type the implicit dependency goes
19674 * the other way in pg_depend; which is the right thing for DROP but
19675 * it doesn't produce the dependency ordering we need. So in that one
19676 * case, we reverse the direction of the dependency.
19677 */
19678 if (deptype == 'i' &&
19679 dobj->objType == DO_TABLE &&
19680 refdobj->objType == DO_TYPE)
19681 addObjectDependency(refdobj, dobj->dumpId);
19682 else
19683 /* normal case */
19684 addObjectDependency(dobj, refdobj->dumpId);
19685 }
19686
19687 PQclear(res);
19688
19689 destroyPQExpBuffer(query);
19690}

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

8245{
8246 int i;
8247 ConstraintInfo *constrinfo;
8249 PGresult *res;
8250 int i_tableoid,
8251 i_oid,
8252 i_conname,
8253 i_consrc;
8254 int ntups;
8255
8257 {
8258 /* Set up query for constraint-specific details */
8260 "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
8261 "SELECT tableoid, oid, conname, "
8262 "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
8263 "convalidated "
8264 "FROM pg_catalog.pg_constraint "
8265 "WHERE contypid = $1 AND contype = 'c' "
8266 "ORDER BY conname");
8267
8268 ExecuteSqlStatement(fout, query->data);
8269
8271 }
8272
8273 printfPQExpBuffer(query,
8274 "EXECUTE getDomainConstraints('%u')",
8275 tyinfo->dobj.catId.oid);
8276
8277 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8278
8279 ntups = PQntuples(res);
8280
8281 i_tableoid = PQfnumber(res, "tableoid");
8282 i_oid = PQfnumber(res, "oid");
8283 i_conname = PQfnumber(res, "conname");
8284 i_consrc = PQfnumber(res, "consrc");
8285
8286 constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
8287
8288 tyinfo->nDomChecks = ntups;
8289 tyinfo->domChecks = constrinfo;
8290
8291 for (i = 0; i < ntups; i++)
8292 {
8293 bool validated = PQgetvalue(res, i, 4)[0] == 't';
8294
8295 constrinfo[i].dobj.objType = DO_CONSTRAINT;
8296 constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8297 constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8298 AssignDumpId(&constrinfo[i].dobj);
8299 constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
8300 constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
8301 constrinfo[i].contable = NULL;
8302 constrinfo[i].condomain = tyinfo;
8303 constrinfo[i].contype = 'c';
8304 constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
8305 constrinfo[i].confrelid = InvalidOid;
8306 constrinfo[i].conindex = 0;
8307 constrinfo[i].condeferrable = false;
8308 constrinfo[i].condeferred = false;
8309 constrinfo[i].conislocal = true;
8310
8311 constrinfo[i].separate = !validated;
8312
8313 /*
8314 * Make the domain depend on the constraint, ensuring it won't be
8315 * output till any constraint dependencies are OK. If the constraint
8316 * has not been validated, it's going to be dumped after the domain
8317 * anyway, so this doesn't matter.
8318 */
8319 if (validated)
8320 addObjectDependency(&tyinfo->dobj,
8321 constrinfo[i].dobj.dumpId);
8322 }
8323
8324 PQclear(res);
8325
8326 destroyPQExpBuffer(query);
8327}
@ PREPQUERY_GETDOMAINCONSTRAINTS
Definition: pg_backup.h:77

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

Referenced by getTypes().

◆ getEventTriggers()

void getEventTriggers ( Archive fout)

Definition at line 8627 of file pg_dump.c.

8628{
8629 int i;
8630 PQExpBuffer query;
8631 PGresult *res;
8632 EventTriggerInfo *evtinfo;
8633 int i_tableoid,
8634 i_oid,
8635 i_evtname,
8636 i_evtevent,
8637 i_evtowner,
8638 i_evttags,
8639 i_evtfname,
8640 i_evtenabled;
8641 int ntups;
8642
8643 /* Before 9.3, there are no event triggers */
8644 if (fout->remoteVersion < 90300)
8645 return;
8646
8647 query = createPQExpBuffer();
8648
8650 "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8651 "evtevent, evtowner, "
8652 "array_to_string(array("
8653 "select quote_literal(x) "
8654 " from unnest(evttags) as t(x)), ', ') as evttags, "
8655 "e.evtfoid::regproc as evtfname "
8656 "FROM pg_event_trigger e "
8657 "ORDER BY e.oid");
8658
8659 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8660
8661 ntups = PQntuples(res);
8662
8663 evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8664
8665 i_tableoid = PQfnumber(res, "tableoid");
8666 i_oid = PQfnumber(res, "oid");
8667 i_evtname = PQfnumber(res, "evtname");
8668 i_evtevent = PQfnumber(res, "evtevent");
8669 i_evtowner = PQfnumber(res, "evtowner");
8670 i_evttags = PQfnumber(res, "evttags");
8671 i_evtfname = PQfnumber(res, "evtfname");
8672 i_evtenabled = PQfnumber(res, "evtenabled");
8673
8674 for (i = 0; i < ntups; i++)
8675 {
8676 evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8677 evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8678 evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8679 AssignDumpId(&evtinfo[i].dobj);
8680 evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8681 evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8682 evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8683 evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8684 evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8685 evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8686 evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8687
8688 /* Decide whether we want to dump it */
8689 selectDumpableObject(&(evtinfo[i].dobj), fout);
8690 }
8691
8692 PQclear(res);
8693
8694 destroyPQExpBuffer(query);
8695}
char * evtname
Definition: pg_dump.h:489

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

7984{
7985 PQExpBuffer query;
7986 PGresult *res;
7987 StatsExtInfo *statsextinfo;
7988 int ntups;
7989 int i_tableoid;
7990 int i_oid;
7991 int i_stxname;
7992 int i_stxnamespace;
7993 int i_stxowner;
7994 int i_stxrelid;
7995 int i_stattarget;
7996 int i;
7997
7998 /* Extended statistics were new in v10 */
7999 if (fout->remoteVersion < 100000)
8000 return;
8001
8002 query = createPQExpBuffer();
8003
8004 if (fout->remoteVersion < 130000)
8005 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8006 "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
8007 "FROM pg_catalog.pg_statistic_ext");
8008 else
8009 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8010 "stxnamespace, stxowner, stxrelid, stxstattarget "
8011 "FROM pg_catalog.pg_statistic_ext");
8012
8013 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8014
8015 ntups = PQntuples(res);
8016
8017 i_tableoid = PQfnumber(res, "tableoid");
8018 i_oid = PQfnumber(res, "oid");
8019 i_stxname = PQfnumber(res, "stxname");
8020 i_stxnamespace = PQfnumber(res, "stxnamespace");
8021 i_stxowner = PQfnumber(res, "stxowner");
8022 i_stxrelid = PQfnumber(res, "stxrelid");
8023 i_stattarget = PQfnumber(res, "stxstattarget");
8024
8025 statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
8026
8027 for (i = 0; i < ntups; i++)
8028 {
8029 statsextinfo[i].dobj.objType = DO_STATSEXT;
8030 statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8031 statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8032 AssignDumpId(&statsextinfo[i].dobj);
8033 statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
8034 statsextinfo[i].dobj.namespace =
8035 findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
8036 statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
8037 statsextinfo[i].stattable =
8038 findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
8039 if (PQgetisnull(res, i, i_stattarget))
8040 statsextinfo[i].stattarget = -1;
8041 else
8042 statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
8043
8044 /* Decide whether we want to dump it */
8045 selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
8046 }
8047
8048 PQclear(res);
8049 destroyPQExpBuffer(query);
8050}
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2252
TableInfo * stattable
Definition: pg_dump.h:462

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

19273{
19274 PQExpBuffer query;
19275 PGresult *res;
19276 int ntups,
19277 i;
19278 int i_classid,
19279 i_objid,
19280 i_refobjid;
19281 ExtensionInfo *ext;
19282
19283 /* Nothing to do if no extensions */
19284 if (numExtensions == 0)
19285 return;
19286
19287 query = createPQExpBuffer();
19288
19289 /* refclassid constraint is redundant but may speed the search */
19290 appendPQExpBufferStr(query, "SELECT "
19291 "classid, objid, refobjid "
19292 "FROM pg_depend "
19293 "WHERE refclassid = 'pg_extension'::regclass "
19294 "AND deptype = 'e' "
19295 "ORDER BY 3");
19296
19297 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19298
19299 ntups = PQntuples(res);
19300
19301 i_classid = PQfnumber(res, "classid");
19302 i_objid = PQfnumber(res, "objid");
19303 i_refobjid = PQfnumber(res, "refobjid");
19304
19305 /*
19306 * Since we ordered the SELECT by referenced ID, we can expect that
19307 * multiple entries for the same extension will appear together; this
19308 * saves on searches.
19309 */
19310 ext = NULL;
19311
19312 for (i = 0; i < ntups; i++)
19313 {
19314 CatalogId objId;
19315 Oid extId;
19316
19317 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
19318 objId.oid = atooid(PQgetvalue(res, i, i_objid));
19319 extId = atooid(PQgetvalue(res, i, i_refobjid));
19320
19321 if (ext == NULL ||
19322 ext->dobj.catId.oid != extId)
19323 ext = findExtensionByOid(extId);
19324
19325 if (ext == NULL)
19326 {
19327 /* shouldn't happen */
19328 pg_log_warning("could not find referenced extension %u", extId);
19329 continue;
19330 }
19331
19332 recordExtensionMembership(objId, ext);
19333 }
19334
19335 PQclear(res);
19336
19337 destroyPQExpBuffer(query);
19338}
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1044
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:989

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

5928{
5929 DumpOptions *dopt = fout->dopt;
5930 PGresult *res;
5931 int ntups;
5932 int i;
5933 PQExpBuffer query;
5934 ExtensionInfo *extinfo = NULL;
5935 int i_tableoid;
5936 int i_oid;
5937 int i_extname;
5938 int i_nspname;
5939 int i_extrelocatable;
5940 int i_extversion;
5941 int i_extconfig;
5942 int i_extcondition;
5943
5944 query = createPQExpBuffer();
5945
5946 appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5947 "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5948 "FROM pg_extension x "
5949 "JOIN pg_namespace n ON n.oid = x.extnamespace");
5950
5951 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5952
5953 ntups = PQntuples(res);
5954 if (ntups == 0)
5955 goto cleanup;
5956
5957 extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5958
5959 i_tableoid = PQfnumber(res, "tableoid");
5960 i_oid = PQfnumber(res, "oid");
5961 i_extname = PQfnumber(res, "extname");
5962 i_nspname = PQfnumber(res, "nspname");
5963 i_extrelocatable = PQfnumber(res, "extrelocatable");
5964 i_extversion = PQfnumber(res, "extversion");
5965 i_extconfig = PQfnumber(res, "extconfig");
5966 i_extcondition = PQfnumber(res, "extcondition");
5967
5968 for (i = 0; i < ntups; i++)
5969 {
5970 extinfo[i].dobj.objType = DO_EXTENSION;
5971 extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5972 extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5973 AssignDumpId(&extinfo[i].dobj);
5974 extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5975 extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5976 extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5977 extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5978 extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5979 extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5980
5981 /* Decide whether we want to dump it */
5982 selectDumpableExtension(&(extinfo[i]), dopt);
5983 }
5984
5985cleanup:
5986 PQclear(res);
5987 destroyPQExpBuffer(query);
5988
5989 *numExtensions = ntups;
5990
5991 return extinfo;
5992}
static void cleanup(void)
Definition: bootstrap.c:713
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2195

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

10128{
10129 PGresult *res;
10130 int ntups;
10131 int i;
10132 PQExpBuffer query;
10133 FdwInfo *fdwinfo;
10134 int i_tableoid;
10135 int i_oid;
10136 int i_fdwname;
10137 int i_fdwowner;
10138 int i_fdwhandler;
10139 int i_fdwvalidator;
10140 int i_fdwacl;
10141 int i_acldefault;
10142 int i_fdwoptions;
10143
10144 query = createPQExpBuffer();
10145
10146 appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
10147 "fdwowner, "
10148 "fdwhandler::pg_catalog.regproc, "
10149 "fdwvalidator::pg_catalog.regproc, "
10150 "fdwacl, "
10151 "acldefault('F', fdwowner) AS acldefault, "
10152 "array_to_string(ARRAY("
10153 "SELECT quote_ident(option_name) || ' ' || "
10154 "quote_literal(option_value) "
10155 "FROM pg_options_to_table(fdwoptions) "
10156 "ORDER BY option_name"
10157 "), E',\n ') AS fdwoptions "
10158 "FROM pg_foreign_data_wrapper");
10159
10160 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10161
10162 ntups = PQntuples(res);
10163
10164 fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
10165
10166 i_tableoid = PQfnumber(res, "tableoid");
10167 i_oid = PQfnumber(res, "oid");
10168 i_fdwname = PQfnumber(res, "fdwname");
10169 i_fdwowner = PQfnumber(res, "fdwowner");
10170 i_fdwhandler = PQfnumber(res, "fdwhandler");
10171 i_fdwvalidator = PQfnumber(res, "fdwvalidator");
10172 i_fdwacl = PQfnumber(res, "fdwacl");
10173 i_acldefault = PQfnumber(res, "acldefault");
10174 i_fdwoptions = PQfnumber(res, "fdwoptions");
10175
10176 for (i = 0; i < ntups; i++)
10177 {
10178 fdwinfo[i].dobj.objType = DO_FDW;
10179 fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10180 fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10181 AssignDumpId(&fdwinfo[i].dobj);
10182 fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
10183 fdwinfo[i].dobj.namespace = NULL;
10184 fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
10185 fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10186 fdwinfo[i].dacl.privtype = 0;
10187 fdwinfo[i].dacl.initprivs = NULL;
10188 fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
10189 fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
10190 fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
10191 fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
10192
10193 /* Decide whether we want to dump it */
10194 selectDumpableObject(&(fdwinfo[i].dobj), fout);
10195
10196 /* Mark whether FDW has an ACL */
10197 if (!PQgetisnull(res, i, i_fdwacl))
10198 fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10199 }
10200
10201 PQclear(res);
10202
10203 destroyPQExpBuffer(query);
10204}

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

10212{
10213 PGresult *res;
10214 int ntups;
10215 int i;
10216 PQExpBuffer query;
10217 ForeignServerInfo *srvinfo;
10218 int i_tableoid;
10219 int i_oid;
10220 int i_srvname;
10221 int i_srvowner;
10222 int i_srvfdw;
10223 int i_srvtype;
10224 int i_srvversion;
10225 int i_srvacl;
10226 int i_acldefault;
10227 int i_srvoptions;
10228
10229 query = createPQExpBuffer();
10230
10231 appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
10232 "srvowner, "
10233 "srvfdw, srvtype, srvversion, srvacl, "
10234 "acldefault('S', srvowner) AS acldefault, "
10235 "array_to_string(ARRAY("
10236 "SELECT quote_ident(option_name) || ' ' || "
10237 "quote_literal(option_value) "
10238 "FROM pg_options_to_table(srvoptions) "
10239 "ORDER BY option_name"
10240 "), E',\n ') AS srvoptions "
10241 "FROM pg_foreign_server");
10242
10243 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10244
10245 ntups = PQntuples(res);
10246
10247 srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
10248
10249 i_tableoid = PQfnumber(res, "tableoid");
10250 i_oid = PQfnumber(res, "oid");
10251 i_srvname = PQfnumber(res, "srvname");
10252 i_srvowner = PQfnumber(res, "srvowner");
10253 i_srvfdw = PQfnumber(res, "srvfdw");
10254 i_srvtype = PQfnumber(res, "srvtype");
10255 i_srvversion = PQfnumber(res, "srvversion");
10256 i_srvacl = PQfnumber(res, "srvacl");
10257 i_acldefault = PQfnumber(res, "acldefault");
10258 i_srvoptions = PQfnumber(res, "srvoptions");
10259
10260 for (i = 0; i < ntups; i++)
10261 {
10262 srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
10263 srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10264 srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10265 AssignDumpId(&srvinfo[i].dobj);
10266 srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
10267 srvinfo[i].dobj.namespace = NULL;
10268 srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
10269 srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10270 srvinfo[i].dacl.privtype = 0;
10271 srvinfo[i].dacl.initprivs = NULL;
10272 srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
10273 srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
10274 srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
10275 srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
10276 srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
10277
10278 /* Decide whether we want to dump it */
10279 selectDumpableObject(&(srvinfo[i].dobj), fout);
10280
10281 /* Servers have user mappings */
10283
10284 /* Mark whether server has an ACL */
10285 if (!PQgetisnull(res, i, i_srvacl))
10286 srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10287 }
10288
10289 PQclear(res);
10290
10291 destroyPQExpBuffer(query);
10292}

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

14031{
14032 OprInfo *oprInfo;
14033
14034 /* In all cases "0" means a null reference */
14035 if (strcmp(oproid, "0") == 0)
14036 return NULL;
14037
14038 oprInfo = findOprByOid(atooid(oproid));
14039 if (oprInfo == NULL)
14040 {
14041 pg_log_warning("could not find operator with OID %s",
14042 oproid);
14043 return NULL;
14044 }
14045
14046 return psprintf("OPERATOR(%s.%s)",
14047 fmtId(oprInfo->dobj.namespace->dobj.name),
14048 oprInfo->dobj.name);
14049}
OprInfo * findOprByOid(Oid oid)
Definition: common.c:935

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

19953{
19954 TypeInfo *typeInfo;
19955 char *result;
19956 PQExpBuffer query;
19957 PGresult *res;
19958
19959 if (oid == 0)
19960 {
19961 if ((opts & zeroAsStar) != 0)
19962 return "*";
19963 else if ((opts & zeroAsNone) != 0)
19964 return "NONE";
19965 }
19966
19967 /* see if we have the result cached in the type's TypeInfo record */
19968 typeInfo = findTypeByOid(oid);
19969 if (typeInfo && typeInfo->ftypname)
19970 return typeInfo->ftypname;
19971
19972 query = createPQExpBuffer();
19973 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
19974 oid);
19975
19976 res = ExecuteSqlQueryForSingleRow(fout, query->data);
19977
19978 /* result of format_type is already quoted */
19979 result = pg_strdup(PQgetvalue(res, 0, 0));
19980
19981 PQclear(res);
19982 destroyPQExpBuffer(query);
19983
19984 /*
19985 * Cache the result for re-use in later requests, if possible. If we
19986 * don't have a TypeInfo for the type, the string will be leaked once the
19987 * caller is done with it ... but that case really should not happen, so
19988 * leaking if it does seems acceptable.
19989 */
19990 if (typeInfo)
19991 typeInfo->ftypname = result;
19992
19993 return result;
19994}
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 6686 of file pg_dump.c.

6687{
6688 DumpOptions *dopt = fout->dopt;
6689 PGresult *res;
6690 int ntups;
6691 int i;
6693 FuncInfo *finfo;
6694 int i_tableoid;
6695 int i_oid;
6696 int i_proname;
6697 int i_pronamespace;
6698 int i_proowner;
6699 int i_prolang;
6700 int i_pronargs;
6701 int i_proargtypes;
6702 int i_prorettype;
6703 int i_proacl;
6704 int i_acldefault;
6705
6706 /*
6707 * Find all interesting functions. This is a bit complicated:
6708 *
6709 * 1. Always exclude aggregates; those are handled elsewhere.
6710 *
6711 * 2. Always exclude functions that are internally dependent on something
6712 * else, since presumably those will be created as a result of creating
6713 * the something else. This currently acts only to suppress constructor
6714 * functions for range types. Note this is OK only because the
6715 * constructors don't have any dependencies the range type doesn't have;
6716 * otherwise we might not get creation ordering correct.
6717 *
6718 * 3. Otherwise, we normally exclude functions in pg_catalog. However, if
6719 * they're members of extensions and we are in binary-upgrade mode then
6720 * include them, since we want to dump extension members individually in
6721 * that mode. Also, if they are used by casts or transforms then we need
6722 * to gather the information about them, though they won't be dumped if
6723 * they are built-in. Also, in 9.6 and up, include functions in
6724 * pg_catalog if they have an ACL different from what's shown in
6725 * pg_init_privs (so we have to join to pg_init_privs; annoying).
6726 */
6727 if (fout->remoteVersion >= 90600)
6728 {
6729 const char *not_agg_check;
6730
6731 not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
6732 : "NOT p.proisagg");
6733
6734 appendPQExpBuffer(query,
6735 "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
6736 "p.pronargs, p.proargtypes, p.prorettype, "
6737 "p.proacl, "
6738 "acldefault('f', p.proowner) AS acldefault, "
6739 "p.pronamespace, "
6740 "p.proowner "
6741 "FROM pg_proc p "
6742 "LEFT JOIN pg_init_privs pip ON "
6743 "(p.oid = pip.objoid "
6744 "AND pip.classoid = 'pg_proc'::regclass "
6745 "AND pip.objsubid = 0) "
6746 "WHERE %s"
6747 "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6748 "WHERE classid = 'pg_proc'::regclass AND "
6749 "objid = p.oid AND deptype = 'i')"
6750 "\n AND ("
6751 "\n pronamespace != "
6752 "(SELECT oid FROM pg_namespace "
6753 "WHERE nspname = 'pg_catalog')"
6754 "\n OR EXISTS (SELECT 1 FROM pg_cast"
6755 "\n WHERE pg_cast.oid > %u "
6756 "\n AND p.oid = pg_cast.castfunc)"
6757 "\n OR EXISTS (SELECT 1 FROM pg_transform"
6758 "\n WHERE pg_transform.oid > %u AND "
6759 "\n (p.oid = pg_transform.trffromsql"
6760 "\n OR p.oid = pg_transform.trftosql))",
6761 not_agg_check,
6764 if (dopt->binary_upgrade)
6766 "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6767 "classid = 'pg_proc'::regclass AND "
6768 "objid = p.oid AND "
6769 "refclassid = 'pg_extension'::regclass AND "
6770 "deptype = 'e')");
6772 "\n OR p.proacl IS DISTINCT FROM pip.initprivs");
6773 appendPQExpBufferChar(query, ')');
6774 }
6775 else
6776 {
6777 appendPQExpBuffer(query,
6778 "SELECT tableoid, oid, proname, prolang, "
6779 "pronargs, proargtypes, prorettype, proacl, "
6780 "acldefault('f', proowner) AS acldefault, "
6781 "pronamespace, "
6782 "proowner "
6783 "FROM pg_proc p "
6784 "WHERE NOT proisagg"
6785 "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6786 "WHERE classid = 'pg_proc'::regclass AND "
6787 "objid = p.oid AND deptype = 'i')"
6788 "\n AND ("
6789 "\n pronamespace != "
6790 "(SELECT oid FROM pg_namespace "
6791 "WHERE nspname = 'pg_catalog')"
6792 "\n OR EXISTS (SELECT 1 FROM pg_cast"
6793 "\n WHERE pg_cast.oid > '%u'::oid"
6794 "\n AND p.oid = pg_cast.castfunc)",
6796
6797 if (fout->remoteVersion >= 90500)
6798 appendPQExpBuffer(query,
6799 "\n OR EXISTS (SELECT 1 FROM pg_transform"
6800 "\n WHERE pg_transform.oid > '%u'::oid"
6801 "\n AND (p.oid = pg_transform.trffromsql"
6802 "\n OR p.oid = pg_transform.trftosql))",
6804
6805 if (dopt->binary_upgrade)
6807 "\n 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
6815 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6816
6817 ntups = PQntuples(res);
6818
6819 finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
6820
6821 i_tableoid = PQfnumber(res, "tableoid");
6822 i_oid = PQfnumber(res, "oid");
6823 i_proname = PQfnumber(res, "proname");
6824 i_pronamespace = PQfnumber(res, "pronamespace");
6825 i_proowner = PQfnumber(res, "proowner");
6826 i_prolang = PQfnumber(res, "prolang");
6827 i_pronargs = PQfnumber(res, "pronargs");
6828 i_proargtypes = PQfnumber(res, "proargtypes");
6829 i_prorettype = PQfnumber(res, "prorettype");
6830 i_proacl = PQfnumber(res, "proacl");
6831 i_acldefault = PQfnumber(res, "acldefault");
6832
6833 for (i = 0; i < ntups; i++)
6834 {
6835 finfo[i].dobj.objType = DO_FUNC;
6836 finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6837 finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6838 AssignDumpId(&finfo[i].dobj);
6839 finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
6840 finfo[i].dobj.namespace =
6841 findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
6842 finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
6843 finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6844 finfo[i].dacl.privtype = 0;
6845 finfo[i].dacl.initprivs = NULL;
6846 finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6847 finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
6848 finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
6849 finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
6850 if (finfo[i].nargs == 0)
6851 finfo[i].argtypes = NULL;
6852 else
6853 {
6854 finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
6855 parseOidArray(PQgetvalue(res, i, i_proargtypes),
6856 finfo[i].argtypes, finfo[i].nargs);
6857 }
6858 finfo[i].postponed_def = false; /* might get set during sort */
6859
6860 /* Decide whether we want to dump it */
6861 selectDumpableObject(&(finfo[i].dobj), fout);
6862
6863 /* Mark whether function has an ACL */
6864 if (!PQgetisnull(res, i, i_proacl))
6866 }
6867
6868 PQclear(res);
6869
6870 destroyPQExpBuffer(query);
6871}
static Oid g_last_builtin_oid
Definition: pg_dump.c:149
Oid lang
Definition: pg_dump.h:242

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

7615{
7617 PQExpBuffer tbloids = createPQExpBuffer();
7618 PGresult *res;
7619 int ntups;
7620 int curtblindx;
7621 IndxInfo *indxinfo;
7622 int i_tableoid,
7623 i_oid,
7624 i_indrelid,
7625 i_indexname,
7626 i_relpages,
7627 i_reltuples,
7628 i_relallvisible,
7629 i_relallfrozen,
7630 i_parentidx,
7631 i_indexdef,
7632 i_indnkeyatts,
7633 i_indnatts,
7634 i_indkey,
7635 i_indisclustered,
7636 i_indisreplident,
7637 i_indnullsnotdistinct,
7638 i_contype,
7639 i_conname,
7640 i_condeferrable,
7641 i_condeferred,
7642 i_conperiod,
7643 i_contableoid,
7644 i_conoid,
7645 i_condef,
7646 i_indattnames,
7647 i_tablespace,
7648 i_indreloptions,
7649 i_indstatcols,
7650 i_indstatvals;
7651
7652 /*
7653 * We want to perform just one query against pg_index. However, we
7654 * mustn't try to select every row of the catalog and then sort it out on
7655 * the client side, because some of the server-side functions we need
7656 * would be unsafe to apply to tables we don't have lock on. Hence, we
7657 * build an array of the OIDs of tables we care about (and now have lock
7658 * on!), and use a WHERE clause to constrain which rows are selected.
7659 */
7660 appendPQExpBufferChar(tbloids, '{');
7661 for (int i = 0; i < numTables; i++)
7662 {
7663 TableInfo *tbinfo = &tblinfo[i];
7664
7665 if (!tbinfo->hasindex)
7666 continue;
7667
7668 /*
7669 * We can ignore indexes of uninteresting tables.
7670 */
7671 if (!tbinfo->interesting)
7672 continue;
7673
7674 /* OK, we need info for this table */
7675 if (tbloids->len > 1) /* do we have more than the '{'? */
7676 appendPQExpBufferChar(tbloids, ',');
7677 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
7678 }
7679 appendPQExpBufferChar(tbloids, '}');
7680
7682 "SELECT t.tableoid, t.oid, i.indrelid, "
7683 "t.relname AS indexname, "
7684 "t.relpages, t.reltuples, t.relallvisible, ");
7685
7686 if (fout->remoteVersion >= 180000)
7687 appendPQExpBufferStr(query, "t.relallfrozen, ");
7688 else
7689 appendPQExpBufferStr(query, "0 AS relallfrozen, ");
7690
7692 "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7693 "i.indkey, i.indisclustered, "
7694 "c.contype, c.conname, "
7695 "c.condeferrable, c.condeferred, "
7696 "c.tableoid AS contableoid, "
7697 "c.oid AS conoid, "
7698 "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
7699 "CASE WHEN i.indexprs IS NOT NULL THEN "
7700 "(SELECT pg_catalog.array_agg(attname ORDER BY attnum)"
7701 " FROM pg_catalog.pg_attribute "
7702 " WHERE attrelid = i.indexrelid) "
7703 "ELSE NULL END AS indattnames, "
7704 "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
7705 "t.reloptions AS indreloptions, ");
7706
7707
7708 if (fout->remoteVersion >= 90400)
7710 "i.indisreplident, ");
7711 else
7713 "false AS indisreplident, ");
7714
7715 if (fout->remoteVersion >= 110000)
7717 "inh.inhparent AS parentidx, "
7718 "i.indnkeyatts AS indnkeyatts, "
7719 "i.indnatts AS indnatts, "
7720 "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
7721 " FROM pg_catalog.pg_attribute "
7722 " WHERE attrelid = i.indexrelid AND "
7723 " attstattarget >= 0) AS indstatcols, "
7724 "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
7725 " FROM pg_catalog.pg_attribute "
7726 " WHERE attrelid = i.indexrelid AND "
7727 " attstattarget >= 0) AS indstatvals, ");
7728 else
7730 "0 AS parentidx, "
7731 "i.indnatts AS indnkeyatts, "
7732 "i.indnatts AS indnatts, "
7733 "'' AS indstatcols, "
7734 "'' AS indstatvals, ");
7735
7736 if (fout->remoteVersion >= 150000)
7738 "i.indnullsnotdistinct, ");
7739 else
7741 "false AS indnullsnotdistinct, ");
7742
7743 if (fout->remoteVersion >= 180000)
7745 "c.conperiod ");
7746 else
7748 "NULL AS conperiod ");
7749
7750 /*
7751 * The point of the messy-looking outer join is to find a constraint that
7752 * is related by an internal dependency link to the index. If we find one,
7753 * create a CONSTRAINT entry linked to the INDEX entry. We assume an
7754 * index won't have more than one internal dependency.
7755 *
7756 * Note: the check on conrelid is redundant, but useful because that
7757 * column is indexed while conindid is not.
7758 */
7759 if (fout->remoteVersion >= 110000)
7760 {
7761 appendPQExpBuffer(query,
7762 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7763 "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7764 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7765 "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
7766 "LEFT JOIN pg_catalog.pg_constraint c "
7767 "ON (i.indrelid = c.conrelid AND "
7768 "i.indexrelid = c.conindid AND "
7769 "c.contype IN ('p','u','x')) "
7770 "LEFT JOIN pg_catalog.pg_inherits inh "
7771 "ON (inh.inhrelid = indexrelid) "
7772 "WHERE (i.indisvalid OR t2.relkind = 'p') "
7773 "AND i.indisready "
7774 "ORDER BY i.indrelid, indexname",
7775 tbloids->data);
7776 }
7777 else
7778 {
7779 /*
7780 * the test on indisready is necessary in 9.2, and harmless in
7781 * earlier/later versions
7782 */
7783 appendPQExpBuffer(query,
7784 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7785 "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7786 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7787 "LEFT JOIN pg_catalog.pg_constraint c "
7788 "ON (i.indrelid = c.conrelid AND "
7789 "i.indexrelid = c.conindid AND "
7790 "c.contype IN ('p','u','x')) "
7791 "WHERE i.indisvalid AND i.indisready "
7792 "ORDER BY i.indrelid, indexname",
7793 tbloids->data);
7794 }
7795
7796 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7797
7798 ntups = PQntuples(res);
7799
7800 i_tableoid = PQfnumber(res, "tableoid");
7801 i_oid = PQfnumber(res, "oid");
7802 i_indrelid = PQfnumber(res, "indrelid");
7803 i_indexname = PQfnumber(res, "indexname");
7804 i_relpages = PQfnumber(res, "relpages");
7805 i_reltuples = PQfnumber(res, "reltuples");
7806 i_relallvisible = PQfnumber(res, "relallvisible");
7807 i_relallfrozen = PQfnumber(res, "relallfrozen");
7808 i_parentidx = PQfnumber(res, "parentidx");
7809 i_indexdef = PQfnumber(res, "indexdef");
7810 i_indnkeyatts = PQfnumber(res, "indnkeyatts");
7811 i_indnatts = PQfnumber(res, "indnatts");
7812 i_indkey = PQfnumber(res, "indkey");
7813 i_indisclustered = PQfnumber(res, "indisclustered");
7814 i_indisreplident = PQfnumber(res, "indisreplident");
7815 i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
7816 i_contype = PQfnumber(res, "contype");
7817 i_conname = PQfnumber(res, "conname");
7818 i_condeferrable = PQfnumber(res, "condeferrable");
7819 i_condeferred = PQfnumber(res, "condeferred");
7820 i_conperiod = PQfnumber(res, "conperiod");
7821 i_contableoid = PQfnumber(res, "contableoid");
7822 i_conoid = PQfnumber(res, "conoid");
7823 i_condef = PQfnumber(res, "condef");
7824 i_indattnames = PQfnumber(res, "indattnames");
7825 i_tablespace = PQfnumber(res, "tablespace");
7826 i_indreloptions = PQfnumber(res, "indreloptions");
7827 i_indstatcols = PQfnumber(res, "indstatcols");
7828 i_indstatvals = PQfnumber(res, "indstatvals");
7829
7830 indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
7831
7832 /*
7833 * Outer loop iterates once per table, not once per row. Incrementing of
7834 * j is handled by the inner loop.
7835 */
7836 curtblindx = -1;
7837 for (int j = 0; j < ntups;)
7838 {
7839 Oid indrelid = atooid(PQgetvalue(res, j, i_indrelid));
7840 TableInfo *tbinfo = NULL;
7841 char **indAttNames = NULL;
7842 int nindAttNames = 0;
7843 int numinds;
7844
7845 /* Count rows for this table */
7846 for (numinds = 1; numinds < ntups - j; numinds++)
7847 if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
7848 break;
7849
7850 /*
7851 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7852 * order.
7853 */
7854 while (++curtblindx < numTables)
7855 {
7856 tbinfo = &tblinfo[curtblindx];
7857 if (tbinfo->dobj.catId.oid == indrelid)
7858 break;
7859 }
7860 if (curtblindx >= numTables)
7861 pg_fatal("unrecognized table OID %u", indrelid);
7862 /* cross-check that we only got requested tables */
7863 if (!tbinfo->hasindex ||
7864 !tbinfo->interesting)
7865 pg_fatal("unexpected index data for table \"%s\"",
7866 tbinfo->dobj.name);
7867
7868 /* Save data for this table */
7869 tbinfo->indexes = indxinfo + j;
7870 tbinfo->numIndexes = numinds;
7871
7872 for (int c = 0; c < numinds; c++, j++)
7873 {
7874 char contype;
7875 char indexkind;
7876 RelStatsInfo *relstats;
7877 int32 relpages = atoi(PQgetvalue(res, j, i_relpages));
7878 int32 relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
7879 int32 relallfrozen = atoi(PQgetvalue(res, j, i_relallfrozen));
7880
7881 indxinfo[j].dobj.objType = DO_INDEX;
7882 indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
7883 indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
7884 AssignDumpId(&indxinfo[j].dobj);
7885 indxinfo[j].dobj.dump = tbinfo->dobj.dump;
7886 indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
7887 indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7888 indxinfo[j].indextable = tbinfo;
7889 indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
7890 indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
7891 indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
7892 indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
7893 indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
7894 indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
7895 indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
7896 indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
7897 parseOidArray(PQgetvalue(res, j, i_indkey),
7898 indxinfo[j].indkeys, indxinfo[j].indnattrs);
7899 indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
7900 indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
7901 indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
7902 indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
7903 indxinfo[j].partattaches = (SimplePtrList)
7904 {
7905 NULL, NULL
7906 };
7907
7908 if (indxinfo[j].parentidx == 0)
7909 indexkind = RELKIND_INDEX;
7910 else
7911 indexkind = RELKIND_PARTITIONED_INDEX;
7912
7913 if (!PQgetisnull(res, j, i_indattnames))
7914 {
7915 if (!parsePGArray(PQgetvalue(res, j, i_indattnames),
7916 &indAttNames, &nindAttNames))
7917 pg_fatal("could not parse %s array", "indattnames");
7918 }
7919
7920 relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
7921 PQgetvalue(res, j, i_reltuples),
7922 relallvisible, relallfrozen, indexkind,
7923 indAttNames, nindAttNames);
7924
7925 contype = *(PQgetvalue(res, j, i_contype));
7926 if (contype == 'p' || contype == 'u' || contype == 'x')
7927 {
7928 /*
7929 * If we found a constraint matching the index, create an
7930 * entry for it.
7931 */
7932 ConstraintInfo *constrinfo;
7933
7934 constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
7935 constrinfo->dobj.objType = DO_CONSTRAINT;
7936 constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7937 constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7938 AssignDumpId(&constrinfo->dobj);
7939 constrinfo->dobj.dump = tbinfo->dobj.dump;
7940 constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7941 constrinfo->dobj.namespace = tbinfo->dobj.namespace;
7942 constrinfo->contable = tbinfo;
7943 constrinfo->condomain = NULL;
7944 constrinfo->contype = contype;
7945 if (contype == 'x')
7946 constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
7947 else
7948 constrinfo->condef = NULL;
7949 constrinfo->confrelid = InvalidOid;
7950 constrinfo->conindex = indxinfo[j].dobj.dumpId;
7951 constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
7952 constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
7953 constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
7954 constrinfo->conislocal = true;
7955 constrinfo->separate = true;
7956
7957 indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
7958 if (relstats != NULL)
7959 addObjectDependency(&relstats->dobj, constrinfo->dobj.dumpId);
7960 }
7961 else
7962 {
7963 /* Plain secondary index */
7964 indxinfo[j].indexconstraint = 0;
7965 }
7966 }
7967 }
7968
7969 PQclear(res);
7970
7971 destroyPQExpBuffer(query);
7972 destroyPQExpBuffer(tbloids);
7973}
int32_t int32
Definition: c.h:498
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:6881
char * c
struct SimplePtrList SimplePtrList
bool hasindex
Definition: pg_dump.h:311

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

7499{
7500 PGresult *res;
7501 int ntups;
7502 int i;
7504 InhInfo *inhinfo;
7505
7506 int i_inhrelid;
7507 int i_inhparent;
7508
7509 /* find all the inheritance information */
7510 appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7511
7512 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7513
7514 ntups = PQntuples(res);
7515
7516 *numInherits = ntups;
7517
7518 inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7519
7520 i_inhrelid = PQfnumber(res, "inhrelid");
7521 i_inhparent = PQfnumber(res, "inhparent");
7522
7523 for (i = 0; i < ntups; i++)
7524 {
7525 inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7526 inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7527 }
7528
7529 PQclear(res);
7530
7531 destroyPQExpBuffer(query);
7532
7533 return inhinfo;
7534}
Oid inhparent
Definition: pg_dump.h:557
Oid inhrelid
Definition: pg_dump.h:556

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

3819{
3820 DumpOptions *dopt = fout->dopt;
3822 PGresult *res;
3823 int ntups;
3824 int i;
3825 int n;
3826 int i_oid;
3827 int i_lomowner;
3828 int i_lomacl;
3829 int i_acldefault;
3830
3831 pg_log_info("reading large objects");
3832
3833 /*
3834 * Fetch LO OIDs and owner/ACL data. Order the data so that all the blobs
3835 * with the same owner/ACL appear together.
3836 */
3838 "SELECT oid, lomowner, lomacl, "
3839 "acldefault('L', lomowner) AS acldefault "
3840 "FROM pg_largeobject_metadata "
3841 "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
3842
3843 res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
3844
3845 i_oid = PQfnumber(res, "oid");
3846 i_lomowner = PQfnumber(res, "lomowner");
3847 i_lomacl = PQfnumber(res, "lomacl");
3848 i_acldefault = PQfnumber(res, "acldefault");
3849
3850 ntups = PQntuples(res);
3851
3852 /*
3853 * Group the blobs into suitably-sized groups that have the same owner and
3854 * ACL setting, and build a metadata and a data DumpableObject for each
3855 * group. (If we supported initprivs for blobs, we'd have to insist that
3856 * groups also share initprivs settings, since the DumpableObject only has
3857 * room for one.) i is the index of the first tuple in the current group,
3858 * and n is the number of tuples we include in the group.
3859 */
3860 for (i = 0; i < ntups; i += n)
3861 {
3862 Oid thisoid = atooid(PQgetvalue(res, i, i_oid));
3863 char *thisowner = PQgetvalue(res, i, i_lomowner);
3864 char *thisacl = PQgetvalue(res, i, i_lomacl);
3865 LoInfo *loinfo;
3866 DumpableObject *lodata;
3867 char namebuf[64];
3868
3869 /* Scan to find first tuple not to be included in group */
3870 n = 1;
3871 while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
3872 {
3873 if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
3874 strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
3875 break;
3876 n++;
3877 }
3878
3879 /* Build the metadata DumpableObject */
3880 loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
3881
3882 loinfo->dobj.objType = DO_LARGE_OBJECT;
3883 loinfo->dobj.catId.tableoid = LargeObjectRelationId;
3884 loinfo->dobj.catId.oid = thisoid;
3885 AssignDumpId(&loinfo->dobj);
3886
3887 if (n > 1)
3888 snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
3889 atooid(PQgetvalue(res, i + n - 1, i_oid)));
3890 else
3891 snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
3892 loinfo->dobj.name = pg_strdup(namebuf);
3893 loinfo->dacl.acl = pg_strdup(thisacl);
3894 loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
3895 loinfo->dacl.privtype = 0;
3896 loinfo->dacl.initprivs = NULL;
3897 loinfo->rolname = getRoleName(thisowner);
3898 loinfo->numlos = n;
3899 loinfo->looids[0] = thisoid;
3900 /* Collect OIDs of the remaining blobs in this group */
3901 for (int k = 1; k < n; k++)
3902 {
3903 CatalogId extraID;
3904
3905 loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
3906
3907 /* Make sure we can look up loinfo by any of the blobs' OIDs */
3908 extraID.tableoid = LargeObjectRelationId;
3909 extraID.oid = loinfo->looids[k];
3910 recordAdditionalCatalogID(extraID, &loinfo->dobj);
3911 }
3912
3913 /* LOs have data */
3915
3916 /* Mark whether LO group has a non-empty ACL */
3917 if (!PQgetisnull(res, i, i_lomacl))
3919
3920 /*
3921 * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
3922 * as it will be copied by pg_upgrade, which simply copies the
3923 * pg_largeobject table. We *do* however dump out anything but the
3924 * data, as pg_upgrade copies just pg_largeobject, but not
3925 * pg_largeobject_metadata, after the dump is restored.
3926 */
3927 if (dopt->binary_upgrade)
3928 loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
3929
3930 /*
3931 * Create a "BLOBS" data item for the group, too. This is just a
3932 * placeholder for sorting; it carries no data now.
3933 */
3934 lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
3935 lodata->objType = DO_LARGE_OBJECT_DATA;
3936 lodata->catId = nilCatalogId;
3937 AssignDumpId(lodata);
3938 lodata->name = pg_strdup(namebuf);
3940 /* Set up explicit dependency from data to metadata */
3941 lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
3942 lodata->dependencies[0] = loinfo->dobj.dumpId;
3943 lodata->nDeps = lodata->allocDeps = 1;
3944 }
3945
3946 PQclear(res);
3947 destroyPQExpBuffer(loQry);
3948}
void recordAdditionalCatalogID(CatalogId catId, DumpableObject *dobj)
Definition: common.c:718
#define MAX_BLOBS_PER_ARCHIVE_ENTRY
Definition: pg_dump.c:226

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

Referenced by main().

◆ getNamespaces()

void getNamespaces ( Archive fout)

Definition at line 5795 of file pg_dump.c.

5796{
5797 PGresult *res;
5798 int ntups;
5799 int i;
5800 PQExpBuffer query;
5801 NamespaceInfo *nsinfo;
5802 int i_tableoid;
5803 int i_oid;
5804 int i_nspname;
5805 int i_nspowner;
5806 int i_nspacl;
5807 int i_acldefault;
5808
5809 query = createPQExpBuffer();
5810
5811 /*
5812 * we fetch all namespaces including system ones, so that every object we
5813 * read in can be linked to a containing namespace.
5814 */
5815 appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5816 "n.nspowner, "
5817 "n.nspacl, "
5818 "acldefault('n', n.nspowner) AS acldefault "
5819 "FROM pg_namespace n");
5820
5821 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5822
5823 ntups = PQntuples(res);
5824
5825 nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5826
5827 i_tableoid = PQfnumber(res, "tableoid");
5828 i_oid = PQfnumber(res, "oid");
5829 i_nspname = PQfnumber(res, "nspname");
5830 i_nspowner = PQfnumber(res, "nspowner");
5831 i_nspacl = PQfnumber(res, "nspacl");
5832 i_acldefault = PQfnumber(res, "acldefault");
5833
5834 for (i = 0; i < ntups; i++)
5835 {
5836 const char *nspowner;
5837
5838 nsinfo[i].dobj.objType = DO_NAMESPACE;
5839 nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5840 nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5841 AssignDumpId(&nsinfo[i].dobj);
5842 nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5843 nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5844 nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5845 nsinfo[i].dacl.privtype = 0;
5846 nsinfo[i].dacl.initprivs = NULL;
5847 nspowner = PQgetvalue(res, i, i_nspowner);
5848 nsinfo[i].nspowner = atooid(nspowner);
5849 nsinfo[i].rolname = getRoleName(nspowner);
5850
5851 /* Decide whether to dump this namespace */
5852 selectDumpableNamespace(&nsinfo[i], fout);
5853
5854 /* Mark whether namespace has an ACL */
5855 if (!PQgetisnull(res, i, i_nspacl))
5857
5858 /*
5859 * We ignore any pg_init_privs.initprivs entry for the public schema
5860 * and assume a predetermined default, for several reasons. First,
5861 * dropping and recreating the schema removes its pg_init_privs entry,
5862 * but an empty destination database starts with this ACL nonetheless.
5863 * Second, we support dump/reload of public schema ownership changes.
5864 * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5865 * initprivs continues to reflect the initial owner. Hence,
5866 * synthesize the value that nspacl will have after the restore's
5867 * ALTER SCHEMA OWNER. Third, this makes the destination database
5868 * match the source's ACL, even if the latter was an initdb-default
5869 * ACL, which changed in v15. An upgrade pulls in changes to most
5870 * system object ACLs that the DBA had not customized. We've made the
5871 * public schema depart from that, because changing its ACL so easily
5872 * breaks applications.
5873 */
5874 if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5875 {
5876 PQExpBuffer aclarray = createPQExpBuffer();
5877 PQExpBuffer aclitem = createPQExpBuffer();
5878
5879 /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5880 appendPQExpBufferChar(aclarray, '{');
5881 quoteAclUserName(aclitem, nsinfo[i].rolname);
5882 appendPQExpBufferStr(aclitem, "=UC/");
5883 quoteAclUserName(aclitem, nsinfo[i].rolname);
5884 appendPGArray(aclarray, aclitem->data);
5885 resetPQExpBuffer(aclitem);
5886 appendPQExpBufferStr(aclitem, "=U/");
5887 quoteAclUserName(aclitem, nsinfo[i].rolname);
5888 appendPGArray(aclarray, aclitem->data);
5889 appendPQExpBufferChar(aclarray, '}');
5890
5891 nsinfo[i].dacl.privtype = 'i';
5892 nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5894
5895 destroyPQExpBuffer(aclarray);
5896 destroyPQExpBuffer(aclitem);
5897 }
5898 }
5899
5900 PQclear(res);
5901 destroyPQExpBuffer(query);
5902}
void quoteAclUserName(PQExpBuffer output, const char *input)
Definition: dumputils.c:547
NameData rolname
Definition: pg_authid.h:34
static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
Definition: pg_dump.c:1917

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

6424{
6425 PGresult *res;
6426 int ntups;
6427 int i;
6429 OpclassInfo *opcinfo;
6430 int i_tableoid;
6431 int i_oid;
6432 int i_opcname;
6433 int i_opcnamespace;
6434 int i_opcowner;
6435
6436 /*
6437 * find all opclasses, including builtin opclasses; we filter out
6438 * system-defined opclasses at dump-out time.
6439 */
6440
6441 appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
6442 "opcnamespace, "
6443 "opcowner "
6444 "FROM pg_opclass");
6445
6446 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6447
6448 ntups = PQntuples(res);
6449
6450 opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6451
6452 i_tableoid = PQfnumber(res, "tableoid");
6453 i_oid = PQfnumber(res, "oid");
6454 i_opcname = PQfnumber(res, "opcname");
6455 i_opcnamespace = PQfnumber(res, "opcnamespace");
6456 i_opcowner = PQfnumber(res, "opcowner");
6457
6458 for (i = 0; i < ntups; i++)
6459 {
6460 opcinfo[i].dobj.objType = DO_OPCLASS;
6461 opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6462 opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6463 AssignDumpId(&opcinfo[i].dobj);
6464 opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6465 opcinfo[i].dobj.namespace =
6466 findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6467 opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6468
6469 /* Decide whether we want to dump it */
6470 selectDumpableObject(&(opcinfo[i].dobj), fout);
6471 }
6472
6473 PQclear(res);
6474
6475 destroyPQExpBuffer(query);
6476}

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

Referenced by getSchemaData().

◆ getOperators()

void getOperators ( Archive fout)

Definition at line 6169 of file pg_dump.c.

6170{
6171 PGresult *res;
6172 int ntups;
6173 int i;
6175 OprInfo *oprinfo;
6176 int i_tableoid;
6177 int i_oid;
6178 int i_oprname;
6179 int i_oprnamespace;
6180 int i_oprowner;
6181 int i_oprkind;
6182 int i_oprcode;
6183
6184 /*
6185 * find all operators, including builtin operators; we filter out
6186 * system-defined operators at dump-out time.
6187 */
6188
6189 appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
6190 "oprnamespace, "
6191 "oprowner, "
6192 "oprkind, "
6193 "oprcode::oid AS oprcode "
6194 "FROM pg_operator");
6195
6196 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6197
6198 ntups = PQntuples(res);
6199
6200 oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6201
6202 i_tableoid = PQfnumber(res, "tableoid");
6203 i_oid = PQfnumber(res, "oid");
6204 i_oprname = PQfnumber(res, "oprname");
6205 i_oprnamespace = PQfnumber(res, "oprnamespace");
6206 i_oprowner = PQfnumber(res, "oprowner");
6207 i_oprkind = PQfnumber(res, "oprkind");
6208 i_oprcode = PQfnumber(res, "oprcode");
6209
6210 for (i = 0; i < ntups; i++)
6211 {
6212 oprinfo[i].dobj.objType = DO_OPERATOR;
6213 oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6214 oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6215 AssignDumpId(&oprinfo[i].dobj);
6216 oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6217 oprinfo[i].dobj.namespace =
6218 findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6219 oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6220 oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6221 oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6222
6223 /* Decide whether we want to dump it */
6224 selectDumpableObject(&(oprinfo[i].dobj), fout);
6225 }
6226
6227 PQclear(res);
6228
6229 destroyPQExpBuffer(query);
6230}
char oprkind
Definition: pg_dump.h:260

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

Referenced by getSchemaData().

◆ getOpfamilies()

void getOpfamilies ( Archive fout)

Definition at line 6483 of file pg_dump.c.

6484{
6485 PGresult *res;
6486 int ntups;
6487 int i;
6488 PQExpBuffer query;
6489 OpfamilyInfo *opfinfo;
6490 int i_tableoid;
6491 int i_oid;
6492 int i_opfname;
6493 int i_opfnamespace;
6494 int i_opfowner;
6495
6496 query = createPQExpBuffer();
6497
6498 /*
6499 * find all opfamilies, including builtin opfamilies; we filter out
6500 * system-defined opfamilies at dump-out time.
6501 */
6502
6503 appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
6504 "opfnamespace, "
6505 "opfowner "
6506 "FROM pg_opfamily");
6507
6508 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6509
6510 ntups = PQntuples(res);
6511
6512 opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6513
6514 i_tableoid = PQfnumber(res, "tableoid");
6515 i_oid = PQfnumber(res, "oid");
6516 i_opfname = PQfnumber(res, "opfname");
6517 i_opfnamespace = PQfnumber(res, "opfnamespace");
6518 i_opfowner = PQfnumber(res, "opfowner");
6519
6520 for (i = 0; i < ntups; i++)
6521 {
6522 opfinfo[i].dobj.objType = DO_OPFAMILY;
6523 opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6524 opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6525 AssignDumpId(&opfinfo[i].dobj);
6526 opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6527 opfinfo[i].dobj.namespace =
6528 findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6529 opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6530
6531 /* Decide whether we want to dump it */
6532 selectDumpableObject(&(opfinfo[i].dobj), fout);
6533 }
6534
6535 PQclear(res);
6536
6537 destroyPQExpBuffer(query);
6538}

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

Referenced by getSchemaData().

◆ getOwnedSeqs()

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

Definition at line 7433 of file pg_dump.c.

7434{
7435 int i;
7436
7437 /*
7438 * Force sequences that are "owned" by table columns to be dumped whenever
7439 * their owning table is being dumped.
7440 */
7441 for (i = 0; i < numTables; i++)
7442 {
7443 TableInfo *seqinfo = &tblinfo[i];
7444 TableInfo *owning_tab;
7445
7446 if (!OidIsValid(seqinfo->owning_tab))
7447 continue; /* not an owned sequence */
7448
7449 owning_tab = findTableByOid(seqinfo->owning_tab);
7450 if (owning_tab == NULL)
7451 pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7452 seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7453
7454 /*
7455 * For an identity sequence, dump exactly the same components for the
7456 * sequence as for the owning table. This is important because we
7457 * treat the identity sequence as an integral part of the table. For
7458 * example, there is not any DDL command that allows creation of such
7459 * a sequence independently of the table.
7460 *
7461 * For other owned sequences such as serial sequences, we need to dump
7462 * the components that are being dumped for the table and any
7463 * components that the sequence is explicitly marked with.
7464 *
7465 * We can't simply use the set of components which are being dumped
7466 * for the table as the table might be in an extension (and only the
7467 * non-extension components, eg: ACLs if changed, security labels, and
7468 * policies, are being dumped) while the sequence is not (and
7469 * therefore the definition and other components should also be
7470 * dumped).
7471 *
7472 * If the sequence is part of the extension then it should be properly
7473 * marked by checkExtensionMembership() and this will be a no-op as
7474 * the table will be equivalently marked.
7475 */
7476 if (seqinfo->is_identity_sequence)
7477 seqinfo->dobj.dump = owning_tab->dobj.dump;
7478 else
7479 seqinfo->dobj.dump |= owning_tab->dobj.dump;
7480
7481 /* Make sure that necessary data is available if we're dumping it */
7482 if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7483 {
7484 seqinfo->interesting = true;
7485 owning_tab->interesting = true;
7486 }
7487 }
7488}

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

7555{
7556 PQExpBuffer query;
7557 PGresult *res;
7558 int ntups;
7559
7560 /* hash partitioning didn't exist before v11 */
7561 if (fout->remoteVersion < 110000)
7562 return;
7563 /* needn't bother if not dumping data */
7564 if (!fout->dopt->dumpData)
7565 return;
7566
7567 query = createPQExpBuffer();
7568
7569 /*
7570 * Unsafe partitioning schemes are exactly those for which hash enum_ops
7571 * appears among the partition opclasses. We needn't check partstrat.
7572 *
7573 * Note that this query may well retrieve info about tables we aren't
7574 * going to dump and hence have no lock on. That's okay since we need not
7575 * invoke any unsafe server-side functions.
7576 */
7578 "SELECT partrelid FROM pg_partitioned_table WHERE\n"
7579 "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
7580 "ON c.opcmethod = a.oid\n"
7581 "WHERE opcname = 'enum_ops' "
7582 "AND opcnamespace = 'pg_catalog'::regnamespace "
7583 "AND amname = 'hash') = ANY(partclass)");
7584
7585 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7586
7587 ntups = PQntuples(res);
7588
7589 for (int i = 0; i < ntups; i++)
7590 {
7591 Oid tabrelid = atooid(PQgetvalue(res, i, 0));
7592 TableInfo *tbinfo;
7593
7594 tbinfo = findTableByOid(tabrelid);
7595 if (tbinfo == NULL)
7596 pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
7597 tabrelid);
7598 tbinfo->unsafe_partitions = true;
7599 }
7600
7601 PQclear(res);
7602
7603 destroyPQExpBuffer(query);
7604}

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

4093{
4094 DumpOptions *dopt = fout->dopt;
4095 PQExpBuffer query;
4096 PQExpBuffer tbloids;
4097 PGresult *res;
4098 PolicyInfo *polinfo;
4099 int i_oid;
4100 int i_tableoid;
4101 int i_polrelid;
4102 int i_polname;
4103 int i_polcmd;
4104 int i_polpermissive;
4105 int i_polroles;
4106 int i_polqual;
4107 int i_polwithcheck;
4108 int i,
4109 j,
4110 ntups;
4111
4112 /* No policies before 9.5 */
4113 if (fout->remoteVersion < 90500)
4114 return;
4115
4116 /* Skip if --no-policies was specified */
4117 if (dopt->no_policies)
4118 return;
4119
4120 query = createPQExpBuffer();
4121 tbloids = createPQExpBuffer();
4122
4123 /*
4124 * Identify tables of interest, and check which ones have RLS enabled.
4125 */
4126 appendPQExpBufferChar(tbloids, '{');
4127 for (i = 0; i < numTables; i++)
4128 {
4129 TableInfo *tbinfo = &tblinfo[i];
4130
4131 /* Ignore row security on tables not to be dumped */
4132 if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
4133 continue;
4134
4135 /* It can't have RLS or policies if it's not a table */
4136 if (tbinfo->relkind != RELKIND_RELATION &&
4137 tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
4138 continue;
4139
4140 /* Add it to the list of table OIDs to be probed below */
4141 if (tbloids->len > 1) /* do we have more than the '{'? */
4142 appendPQExpBufferChar(tbloids, ',');
4143 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
4144
4145 /* Is RLS enabled? (That's separate from whether it has policies) */
4146 if (tbinfo->rowsec)
4147 {
4149
4150 /*
4151 * We represent RLS being enabled on a table by creating a
4152 * PolicyInfo object with null polname.
4153 *
4154 * Note: use tableoid 0 so that this object won't be mistaken for
4155 * something that pg_depend entries apply to.
4156 */
4157 polinfo = pg_malloc(sizeof(PolicyInfo));
4158 polinfo->dobj.objType = DO_POLICY;
4159 polinfo->dobj.catId.tableoid = 0;
4160 polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
4161 AssignDumpId(&polinfo->dobj);
4162 polinfo->dobj.namespace = tbinfo->dobj.namespace;
4163 polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
4164 polinfo->poltable = tbinfo;
4165 polinfo->polname = NULL;
4166 polinfo->polcmd = '\0';
4167 polinfo->polpermissive = 0;
4168 polinfo->polroles = NULL;
4169 polinfo->polqual = NULL;
4170 polinfo->polwithcheck = NULL;
4171 }
4172 }
4173 appendPQExpBufferChar(tbloids, '}');
4174
4175 /*
4176 * Now, read all RLS policies belonging to the tables of interest, and
4177 * create PolicyInfo objects for them. (Note that we must filter the
4178 * results server-side not locally, because we dare not apply pg_get_expr
4179 * to tables we don't have lock on.)
4180 */
4181 pg_log_info("reading row-level security policies");
4182
4183 printfPQExpBuffer(query,
4184 "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
4185 if (fout->remoteVersion >= 100000)
4186 appendPQExpBufferStr(query, "pol.polpermissive, ");
4187 else
4188 appendPQExpBufferStr(query, "'t' as polpermissive, ");
4189 appendPQExpBuffer(query,
4190 "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
4191 " 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, "
4192 "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
4193 "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
4194 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
4195 "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
4196 tbloids->data);
4197
4198 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4199
4200 ntups = PQntuples(res);
4201 if (ntups > 0)
4202 {
4203 i_oid = PQfnumber(res, "oid");
4204 i_tableoid = PQfnumber(res, "tableoid");
4205 i_polrelid = PQfnumber(res, "polrelid");
4206 i_polname = PQfnumber(res, "polname");
4207 i_polcmd = PQfnumber(res, "polcmd");
4208 i_polpermissive = PQfnumber(res, "polpermissive");
4209 i_polroles = PQfnumber(res, "polroles");
4210 i_polqual = PQfnumber(res, "polqual");
4211 i_polwithcheck = PQfnumber(res, "polwithcheck");
4212
4213 polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
4214
4215 for (j = 0; j < ntups; j++)
4216 {
4217 Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
4218 TableInfo *tbinfo = findTableByOid(polrelid);
4219
4221
4222 polinfo[j].dobj.objType = DO_POLICY;
4223 polinfo[j].dobj.catId.tableoid =
4224 atooid(PQgetvalue(res, j, i_tableoid));
4225 polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4226 AssignDumpId(&polinfo[j].dobj);
4227 polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4228 polinfo[j].poltable = tbinfo;
4229 polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
4230 polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
4231
4232 polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
4233 polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
4234
4235 if (PQgetisnull(res, j, i_polroles))
4236 polinfo[j].polroles = NULL;
4237 else
4238 polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
4239
4240 if (PQgetisnull(res, j, i_polqual))
4241 polinfo[j].polqual = NULL;
4242 else
4243 polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
4244
4245 if (PQgetisnull(res, j, i_polwithcheck))
4246 polinfo[j].polwithcheck = NULL;
4247 else
4248 polinfo[j].polwithcheck
4249 = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
4250 }
4251 }
4252
4253 PQclear(res);
4254
4255 destroyPQExpBuffer(query);
4256 destroyPQExpBuffer(tbloids);
4257}
#define DUMP_COMPONENT_POLICY
Definition: pg_dump.h:114
int no_policies
Definition: pg_backup.h:185
bool rowsec
Definition: pg_dump.h:315

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

8706{
8707 PGresult *res;
8708 int ntups;
8709 int i;
8711 ProcLangInfo *planginfo;
8712 int i_tableoid;
8713 int i_oid;
8714 int i_lanname;
8715 int i_lanpltrusted;
8716 int i_lanplcallfoid;
8717 int i_laninline;
8718 int i_lanvalidator;
8719 int i_lanacl;
8720 int i_acldefault;
8721 int i_lanowner;
8722
8723 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8724 "lanname, lanpltrusted, lanplcallfoid, "
8725 "laninline, lanvalidator, "
8726 "lanacl, "
8727 "acldefault('l', lanowner) AS acldefault, "
8728 "lanowner "
8729 "FROM pg_language "
8730 "WHERE lanispl "
8731 "ORDER BY oid");
8732
8733 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8734
8735 ntups = PQntuples(res);
8736
8737 planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8738
8739 i_tableoid = PQfnumber(res, "tableoid");
8740 i_oid = PQfnumber(res, "oid");
8741 i_lanname = PQfnumber(res, "lanname");
8742 i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8743 i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8744 i_laninline = PQfnumber(res, "laninline");
8745 i_lanvalidator = PQfnumber(res, "lanvalidator");
8746 i_lanacl = PQfnumber(res, "lanacl");
8747 i_acldefault = PQfnumber(res, "acldefault");
8748 i_lanowner = PQfnumber(res, "lanowner");
8749
8750 for (i = 0; i < ntups; i++)
8751 {
8752 planginfo[i].dobj.objType = DO_PROCLANG;
8753 planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8754 planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8755 AssignDumpId(&planginfo[i].dobj);
8756
8757 planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8758 planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8759 planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8760 planginfo[i].dacl.privtype = 0;
8761 planginfo[i].dacl.initprivs = NULL;
8762 planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8763 planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8764 planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8765 planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8766 planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8767
8768 /* Decide whether we want to dump it */
8769 selectDumpableProcLang(&(planginfo[i]), fout);
8770
8771 /* Mark whether language has an ACL */
8772 if (!PQgetisnull(res, i, i_lanacl))
8773 planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8774 }
8775
8776 PQclear(res);
8777
8778 destroyPQExpBuffer(query);
8779}
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:2134

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

4589{
4590 PQExpBuffer query;
4591 PGresult *res;
4592 PublicationSchemaInfo *pubsinfo;
4593 DumpOptions *dopt = fout->dopt;
4594 int i_tableoid;
4595 int i_oid;
4596 int i_pnpubid;
4597 int i_pnnspid;
4598 int i,
4599 j,
4600 ntups;
4601
4602 if (dopt->no_publications || fout->remoteVersion < 150000)
4603 return;
4604
4605 query = createPQExpBuffer();
4606
4607 /* Collect all publication membership info. */
4609 "SELECT tableoid, oid, pnpubid, pnnspid "
4610 "FROM pg_catalog.pg_publication_namespace");
4611 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4612
4613 ntups = PQntuples(res);
4614
4615 i_tableoid = PQfnumber(res, "tableoid");
4616 i_oid = PQfnumber(res, "oid");
4617 i_pnpubid = PQfnumber(res, "pnpubid");
4618 i_pnnspid = PQfnumber(res, "pnnspid");
4619
4620 /* this allocation may be more than we need */
4621 pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4622 j = 0;
4623
4624 for (i = 0; i < ntups; i++)
4625 {
4626 Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4627 Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4628 PublicationInfo *pubinfo;
4629 NamespaceInfo *nspinfo;
4630
4631 /*
4632 * Ignore any entries for which we aren't interested in either the
4633 * publication or the rel.
4634 */
4635 pubinfo = findPublicationByOid(pnpubid);
4636 if (pubinfo == NULL)
4637 continue;
4638 nspinfo = findNamespaceByOid(pnnspid);
4639 if (nspinfo == NULL)
4640 continue;
4641
4642 /* OK, make a DumpableObject for this relationship */
4644 pubsinfo[j].dobj.catId.tableoid =
4645 atooid(PQgetvalue(res, i, i_tableoid));
4646 pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4647 AssignDumpId(&pubsinfo[j].dobj);
4648 pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4649 pubsinfo[j].dobj.name = nspinfo->dobj.name;
4650 pubsinfo[j].publication = pubinfo;
4651 pubsinfo[j].pubschema = nspinfo;
4652
4653 /* Decide whether we want to dump it */
4654 selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4655
4656 j++;
4657 }
4658
4659 PQclear(res);
4660 destroyPQExpBuffer(query);
4661}
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:1007
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2234
int no_publications
Definition: pg_backup.h:186

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

4383{
4384 DumpOptions *dopt = fout->dopt;
4385 PQExpBuffer query;
4386 PGresult *res;
4387 PublicationInfo *pubinfo;
4388 int i_tableoid;
4389 int i_oid;
4390 int i_pubname;
4391 int i_pubowner;
4392 int i_puballtables;
4393 int i_pubinsert;
4394 int i_pubupdate;
4395 int i_pubdelete;
4396 int i_pubtruncate;
4397 int i_pubviaroot;
4398 int i_pubgencols;
4399 int i,
4400 ntups;
4401
4402 if (dopt->no_publications || fout->remoteVersion < 100000)
4403 return;
4404
4405 query = createPQExpBuffer();
4406
4407 /* Get the publications. */
4408 appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, "
4409 "p.pubowner, p.puballtables, p.pubinsert, "
4410 "p.pubupdate, p.pubdelete, ");
4411
4412 if (fout->remoteVersion >= 110000)
4413 appendPQExpBufferStr(query, "p.pubtruncate, ");
4414 else
4415 appendPQExpBufferStr(query, "false AS pubtruncate, ");
4416
4417 if (fout->remoteVersion >= 130000)
4418 appendPQExpBufferStr(query, "p.pubviaroot, ");
4419 else
4420 appendPQExpBufferStr(query, "false AS pubviaroot, ");
4421
4422 if (fout->remoteVersion >= 180000)
4423 appendPQExpBufferStr(query, "p.pubgencols ");
4424 else
4425 appendPQExpBuffer(query, "'%c' AS pubgencols ", PUBLISH_GENCOLS_NONE);
4426
4427 appendPQExpBufferStr(query, "FROM pg_publication p");
4428
4429 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4430
4431 ntups = PQntuples(res);
4432
4433 if (ntups == 0)
4434 goto cleanup;
4435
4436 i_tableoid = PQfnumber(res, "tableoid");
4437 i_oid = PQfnumber(res, "oid");
4438 i_pubname = PQfnumber(res, "pubname");
4439 i_pubowner = PQfnumber(res, "pubowner");
4440 i_puballtables = PQfnumber(res, "puballtables");
4441 i_pubinsert = PQfnumber(res, "pubinsert");
4442 i_pubupdate = PQfnumber(res, "pubupdate");
4443 i_pubdelete = PQfnumber(res, "pubdelete");
4444 i_pubtruncate = PQfnumber(res, "pubtruncate");
4445 i_pubviaroot = PQfnumber(res, "pubviaroot");
4446 i_pubgencols = PQfnumber(res, "pubgencols");
4447
4448 pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4449
4450 for (i = 0; i < ntups; i++)
4451 {
4452 pubinfo[i].dobj.objType = DO_PUBLICATION;
4453 pubinfo[i].dobj.catId.tableoid =
4454 atooid(PQgetvalue(res, i, i_tableoid));
4455 pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4456 AssignDumpId(&pubinfo[i].dobj);
4457 pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4458 pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4459 pubinfo[i].puballtables =
4460 (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4461 pubinfo[i].pubinsert =
4462 (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4463 pubinfo[i].pubupdate =
4464 (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4465 pubinfo[i].pubdelete =
4466 (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4467 pubinfo[i].pubtruncate =
4468 (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4469 pubinfo[i].pubviaroot =
4470 (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4471 pubinfo[i].pubgencols_type =
4472 *(PQgetvalue(res, i, i_pubgencols));
4473
4474 /* Decide whether we want to dump it */
4475 selectDumpableObject(&(pubinfo[i].dobj), fout);
4476 }
4477
4478cleanup:
4479 PQclear(res);
4480
4481 destroyPQExpBuffer(query);
4482}

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

4669{
4670 PQExpBuffer query;
4671 PGresult *res;
4672 PublicationRelInfo *pubrinfo;
4673 DumpOptions *dopt = fout->dopt;
4674 int i_tableoid;
4675 int i_oid;
4676 int i_prpubid;
4677 int i_prrelid;
4678 int i_prrelqual;
4679 int i_prattrs;
4680 int i,
4681 j,
4682 ntups;
4683
4684 if (dopt->no_publications || fout->remoteVersion < 100000)
4685 return;
4686
4687 query = createPQExpBuffer();
4688
4689 /* Collect all publication membership info. */
4690 if (fout->remoteVersion >= 150000)
4692 "SELECT tableoid, oid, prpubid, prrelid, "
4693 "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
4694 "(CASE\n"
4695 " WHEN pr.prattrs IS NOT NULL THEN\n"
4696 " (SELECT array_agg(attname)\n"
4697 " FROM\n"
4698 " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
4699 " pg_catalog.pg_attribute\n"
4700 " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
4701 " ELSE NULL END) prattrs "
4702 "FROM pg_catalog.pg_publication_rel pr");
4703 else
4705 "SELECT tableoid, oid, prpubid, prrelid, "
4706 "NULL AS prrelqual, NULL AS prattrs "
4707 "FROM pg_catalog.pg_publication_rel");
4708 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4709
4710 ntups = PQntuples(res);
4711
4712 i_tableoid = PQfnumber(res, "tableoid");
4713 i_oid = PQfnumber(res, "oid");
4714 i_prpubid = PQfnumber(res, "prpubid");
4715 i_prrelid = PQfnumber(res, "prrelid");
4716 i_prrelqual = PQfnumber(res, "prrelqual");
4717 i_prattrs = PQfnumber(res, "prattrs");
4718
4719 /* this allocation may be more than we need */
4720 pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4721 j = 0;
4722
4723 for (i = 0; i < ntups; i++)
4724 {
4725 Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4726 Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4727 PublicationInfo *pubinfo;
4728 TableInfo *tbinfo;
4729
4730 /*
4731 * Ignore any entries for which we aren't interested in either the
4732 * publication or the rel.
4733 */
4734 pubinfo = findPublicationByOid(prpubid);
4735 if (pubinfo == NULL)
4736 continue;
4737 tbinfo = findTableByOid(prrelid);
4738 if (tbinfo == NULL)
4739 continue;
4740
4741 /* OK, make a DumpableObject for this relationship */
4742 pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4743 pubrinfo[j].dobj.catId.tableoid =
4744 atooid(PQgetvalue(res, i, i_tableoid));
4745 pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4746 AssignDumpId(&pubrinfo[j].dobj);
4747 pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4748 pubrinfo[j].dobj.name = tbinfo->dobj.name;
4749 pubrinfo[j].publication = pubinfo;
4750 pubrinfo[j].pubtable = tbinfo;
4751 if (PQgetisnull(res, i, i_prrelqual))
4752 pubrinfo[j].pubrelqual = NULL;
4753 else
4754 pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
4755
4756 if (!PQgetisnull(res, i, i_prattrs))
4757 {
4758 char **attnames;
4759 int nattnames;
4760 PQExpBuffer attribs;
4761
4762 if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
4763 &attnames, &nattnames))
4764 pg_fatal("could not parse %s array", "prattrs");
4765 attribs = createPQExpBuffer();
4766 for (int k = 0; k < nattnames; k++)
4767 {
4768 if (k > 0)
4769 appendPQExpBufferStr(attribs, ", ");
4770
4771 appendPQExpBufferStr(attribs, fmtId(attnames[k]));
4772 }
4773 pubrinfo[j].pubrattrs = attribs->data;
4774 free(attribs); /* but not attribs->data */
4775 free(attnames);
4776 }
4777 else
4778 pubrinfo[j].pubrattrs = NULL;
4779
4780 /* Decide whether we want to dump it */
4781 selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
4782
4783 j++;
4784 }
4785
4786 PQclear(res);
4787 destroyPQExpBuffer(query);
4788}

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

6885{
6886 if (!fout->dopt->dumpStatistics)
6887 return NULL;
6888
6889 if ((relkind == RELKIND_RELATION) ||
6890 (relkind == RELKIND_PARTITIONED_TABLE) ||
6891 (relkind == RELKIND_INDEX) ||
6892 (relkind == RELKIND_PARTITIONED_INDEX) ||
6893 (relkind == RELKIND_MATVIEW))
6894 {
6895 RelStatsInfo *info = pg_malloc0(sizeof(RelStatsInfo));
6896 DumpableObject *dobj = &info->dobj;
6897
6898 dobj->objType = DO_REL_STATS;
6899 dobj->catId.tableoid = 0;
6900 dobj->catId.oid = 0;
6901 AssignDumpId(dobj);
6902 dobj->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
6903 dobj->dependencies[0] = rel->dumpId;
6904 dobj->nDeps = 1;
6905 dobj->allocDeps = 1;
6907 dobj->name = pg_strdup(rel->name);
6908 dobj->namespace = rel->namespace;
6909 info->relpages = relpages;
6910 info->reltuples = pstrdup(reltuples);
6911 info->relallvisible = relallvisible;
6912 info->relallfrozen = relallfrozen;
6913 info->relkind = relkind;
6914 info->indAttNames = indAttNames;
6915 info->nindAttNames = nindAttNames;
6916
6917 /*
6918 * Ordinarily, stats go in SECTION_DATA for tables and
6919 * SECTION_POST_DATA for indexes.
6920 *
6921 * However, the section may be updated later for materialized view
6922 * stats. REFRESH MATERIALIZED VIEW replaces the storage and resets
6923 * the stats, so the stats must be restored after the data. Also, the
6924 * materialized view definition may be postponed to SECTION_POST_DATA
6925 * (see repairMatViewBoundaryMultiLoop()).
6926 */
6927 switch (info->relkind)
6928 {
6929 case RELKIND_RELATION:
6930 case RELKIND_PARTITIONED_TABLE:
6931 case RELKIND_MATVIEW:
6932 info->section = SECTION_DATA;
6933 break;
6934 case RELKIND_INDEX:
6935 case RELKIND_PARTITIONED_INDEX:
6936 info->section = SECTION_POST_DATA;
6937 break;
6938 default:
6939 pg_fatal("cannot dump statistics for relation kind '%c'",
6940 info->relkind);
6941 }
6942
6943 return info;
6944 }
6945 return NULL;
6946}
#define DUMP_COMPONENT_STATISTICS
Definition: pg_dump.h:116
char relkind
Definition: pg_dump.h:447

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

10397{
10398 Oid roleoid = atooid(roleoid_str);
10399
10400 /*
10401 * Do binary search to find the appropriate item.
10402 */
10403 if (nrolenames > 0)
10404 {
10405 RoleNameItem *low = &rolenames[0];
10406 RoleNameItem *high = &rolenames[nrolenames - 1];
10407
10408 while (low <= high)
10409 {
10410 RoleNameItem *middle = low + (high - low) / 2;
10411
10412 if (roleoid < middle->roleoid)
10413 high = middle - 1;
10414 else if (roleoid > middle->roleoid)
10415 low = middle + 1;
10416 else
10417 return middle->rolename; /* found a match */
10418 }
10419 }
10420
10421 pg_fatal("role with OID %u does not exist", roleoid);
10422 return NULL; /* keep compiler quiet */
10423}

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

2730{
2731 TableInfo *parentTbinfo;
2732
2733 Assert(tbinfo->ispartition);
2734 Assert(tbinfo->numParents == 1);
2735
2736 parentTbinfo = tbinfo->parents[0];
2737 while (parentTbinfo->ispartition)
2738 {
2739 Assert(parentTbinfo->numParents == 1);
2740 parentTbinfo = parentTbinfo->parents[0];
2741 }
2742
2743 return parentTbinfo;
2744}

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

Referenced by dumpTableData(), and dumpTableData_insert().

◆ getRules()

void getRules ( Archive fout)

Definition at line 8334 of file pg_dump.c.

8335{
8336 PGresult *res;
8337 int ntups;
8338 int i;
8340 RuleInfo *ruleinfo;
8341 int i_tableoid;
8342 int i_oid;
8343 int i_rulename;
8344 int i_ruletable;
8345 int i_ev_type;
8346 int i_is_instead;
8347 int i_ev_enabled;
8348
8349 appendPQExpBufferStr(query, "SELECT "
8350 "tableoid, oid, rulename, "
8351 "ev_class AS ruletable, ev_type, is_instead, "
8352 "ev_enabled "
8353 "FROM pg_rewrite "
8354 "ORDER BY oid");
8355
8356 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8357
8358 ntups = PQntuples(res);
8359
8360 ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8361
8362 i_tableoid = PQfnumber(res, "tableoid");
8363 i_oid = PQfnumber(res, "oid");
8364 i_rulename = PQfnumber(res, "rulename");
8365 i_ruletable = PQfnumber(res, "ruletable");
8366 i_ev_type = PQfnumber(res, "ev_type");
8367 i_is_instead = PQfnumber(res, "is_instead");
8368 i_ev_enabled = PQfnumber(res, "ev_enabled");
8369
8370 for (i = 0; i < ntups; i++)
8371 {
8372 Oid ruletableoid;
8373
8374 ruleinfo[i].dobj.objType = DO_RULE;
8375 ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8376 ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8377 AssignDumpId(&ruleinfo[i].dobj);
8378 ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8379 ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8380 ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8381 if (ruleinfo[i].ruletable == NULL)
8382 pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8383 ruletableoid, ruleinfo[i].dobj.catId.oid);
8384 ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8385 ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8386 ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8387 ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8388 ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8389 if (ruleinfo[i].ruletable)
8390 {
8391 /*
8392 * If the table is a view or materialized view, force its ON
8393 * SELECT rule to be sorted before the view itself --- this
8394 * ensures that any dependencies for the rule affect the table's
8395 * positioning. Other rules are forced to appear after their
8396 * table.
8397 */
8398 if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8399 ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8400 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8401 {
8402 addObjectDependency(&ruleinfo[i].ruletable->dobj,
8403 ruleinfo[i].dobj.dumpId);
8404 /* We'll merge the rule into CREATE VIEW, if possible */
8405 ruleinfo[i].separate = false;
8406 }
8407 else
8408 {
8409 addObjectDependency(&ruleinfo[i].dobj,
8410 ruleinfo[i].ruletable->dobj.dumpId);
8411 ruleinfo[i].separate = true;
8412 }
8413 }
8414 else
8415 ruleinfo[i].separate = true;
8416 }
8417
8418 PQclear(res);
8419
8420 destroyPQExpBuffer(query);
8421}

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

◆ getSubscriptions()

void getSubscriptions ( Archive fout)

Definition at line 4939 of file pg_dump.c.

4940{
4941 DumpOptions *dopt = fout->dopt;
4942 PQExpBuffer query;
4943 PGresult *res;
4944 SubscriptionInfo *subinfo;
4945 int i_tableoid;
4946 int i_oid;
4947 int i_subname;
4948 int i_subowner;
4949 int i_subbinary;
4950 int i_substream;
4951 int i_subtwophasestate;
4952 int i_subdisableonerr;
4953 int i_subpasswordrequired;
4954 int i_subrunasowner;
4955 int i_subconninfo;
4956 int i_subslotname;
4957 int i_subsynccommit;
4958 int i_subpublications;
4959 int i_suborigin;
4960 int i_suboriginremotelsn;
4961 int i_subenabled;
4962 int i_subfailover;
4963 int i,
4964 ntups;
4965
4966 if (dopt->no_subscriptions || fout->remoteVersion < 100000)
4967 return;
4968
4969 if (!is_superuser(fout))
4970 {
4971 int n;
4972
4973 res = ExecuteSqlQuery(fout,
4974 "SELECT count(*) FROM pg_subscription "
4975 "WHERE subdbid = (SELECT oid FROM pg_database"
4976 " WHERE datname = current_database())",
4978 n = atoi(PQgetvalue(res, 0, 0));
4979 if (n > 0)
4980 pg_log_warning("subscriptions not dumped because current user is not a superuser");
4981 PQclear(res);
4982 return;
4983 }
4984
4985 query = createPQExpBuffer();
4986
4987 /* Get the subscriptions in current database. */
4989 "SELECT s.tableoid, s.oid, s.subname,\n"
4990 " s.subowner,\n"
4991 " s.subconninfo, s.subslotname, s.subsynccommit,\n"
4992 " s.subpublications,\n");
4993
4994 if (fout->remoteVersion >= 140000)
4995 appendPQExpBufferStr(query, " s.subbinary,\n");
4996 else
4997 appendPQExpBufferStr(query, " false AS subbinary,\n");
4998
4999 if (fout->remoteVersion >= 140000)
5000 appendPQExpBufferStr(query, " s.substream,\n");
5001 else
5002 appendPQExpBufferStr(query, " 'f' AS substream,\n");
5003
5004 if (fout->remoteVersion >= 150000)
5006 " s.subtwophasestate,\n"
5007 " s.subdisableonerr,\n");
5008 else
5009 appendPQExpBuffer(query,
5010 " '%c' AS subtwophasestate,\n"
5011 " false AS subdisableonerr,\n",
5012 LOGICALREP_TWOPHASE_STATE_DISABLED);
5013
5014 if (fout->remoteVersion >= 160000)
5016 " s.subpasswordrequired,\n"
5017 " s.subrunasowner,\n"
5018 " s.suborigin,\n");
5019 else
5020 appendPQExpBuffer(query,
5021 " 't' AS subpasswordrequired,\n"
5022 " 't' AS subrunasowner,\n"
5023 " '%s' AS suborigin,\n",
5024 LOGICALREP_ORIGIN_ANY);
5025
5026 if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5027 appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
5028 " s.subenabled,\n");
5029 else
5030 appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
5031 " false AS subenabled,\n");
5032
5033 if (fout->remoteVersion >= 170000)
5035 " s.subfailover\n");
5036 else
5038 " false AS subfailover\n");
5039
5041 "FROM pg_subscription s\n");
5042
5043 if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
5045 "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
5046 " ON o.external_id = 'pg_' || s.oid::text \n");
5047
5049 "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
5050 " WHERE datname = current_database())");
5051
5052 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5053
5054 ntups = PQntuples(res);
5055
5056 /*
5057 * Get subscription fields. We don't include subskiplsn in the dump as
5058 * after restoring the dump this value may no longer be relevant.
5059 */
5060 i_tableoid = PQfnumber(res, "tableoid");
5061 i_oid = PQfnumber(res, "oid");
5062 i_subname = PQfnumber(res, "subname");
5063 i_subowner = PQfnumber(res, "subowner");
5064 i_subenabled = PQfnumber(res, "subenabled");
5065 i_subbinary = PQfnumber(res, "subbinary");
5066 i_substream = PQfnumber(res, "substream");
5067 i_subtwophasestate = PQfnumber(res, "subtwophasestate");
5068 i_subdisableonerr = PQfnumber(res, "subdisableonerr");
5069 i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
5070 i_subrunasowner = PQfnumber(res, "subrunasowner");
5071 i_subfailover = PQfnumber(res, "subfailover");
5072 i_subconninfo = PQfnumber(res, "subconninfo");
5073 i_subslotname = PQfnumber(res, "subslotname");
5074 i_subsynccommit = PQfnumber(res, "subsynccommit");
5075 i_subpublications = PQfnumber(res, "subpublications");
5076 i_suborigin = PQfnumber(res, "suborigin");
5077 i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
5078
5079 subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
5080
5081 for (i = 0; i < ntups; i++)
5082 {
5083 subinfo[i].dobj.objType = DO_SUBSCRIPTION;
5084 subinfo[i].dobj.catId.tableoid =
5085 atooid(PQgetvalue(res, i, i_tableoid));
5086 subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5087 AssignDumpId(&subinfo[i].dobj);
5088 subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
5089 subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
5090
5091 subinfo[i].subenabled =
5092 (strcmp(PQgetvalue(res, i, i_subenabled), "t") == 0);
5093 subinfo[i].subbinary =
5094 (strcmp(PQgetvalue(res, i, i_subbinary), "t") == 0);
5095 subinfo[i].substream = *(PQgetvalue(res, i, i_substream));
5096 subinfo[i].subtwophasestate = *(PQgetvalue(res, i, i_subtwophasestate));
5097 subinfo[i].subdisableonerr =
5098 (strcmp(PQgetvalue(res, i, i_subdisableonerr), "t") == 0);
5099 subinfo[i].subpasswordrequired =
5100 (strcmp(PQgetvalue(res, i, i_subpasswordrequired), "t") == 0);
5101 subinfo[i].subrunasowner =
5102 (strcmp(PQgetvalue(res, i, i_subrunasowner), "t") == 0);
5103 subinfo[i].subfailover =
5104 (strcmp(PQgetvalue(res, i, i_subfailover), "t") == 0);
5105 subinfo[i].subconninfo =
5106 pg_strdup(PQgetvalue(res, i, i_subconninfo));
5107 if (PQgetisnull(res, i, i_subslotname))
5108 subinfo[i].subslotname = NULL;
5109 else
5110 subinfo[i].subslotname =
5111 pg_strdup(PQgetvalue(res, i, i_subslotname));
5112 subinfo[i].subsynccommit =
5113 pg_strdup(PQgetvalue(res, i, i_subsynccommit));
5114 subinfo[i].subpublications =
5115 pg_strdup(PQgetvalue(res, i, i_subpublications));
5116 subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
5117 if (PQgetisnull(res, i, i_suboriginremotelsn))
5118 subinfo[i].suboriginremotelsn = NULL;
5119 else
5120 subinfo[i].suboriginremotelsn =
5121 pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
5122
5123 /* Decide whether we want to dump it */
5124 selectDumpableObject(&(subinfo[i].dobj), fout);
5125 }
5126 PQclear(res);
5127
5128 destroyPQExpBuffer(query);
5129}
static bool is_superuser(Archive *fout)
Definition: pg_dump.c:4899
int no_subscriptions
Definition: pg_backup.h:188

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::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, _SubscriptionInfo::subtwophasestate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSubscriptionTables()

void getSubscriptionTables ( Archive fout)

Definition at line 5137 of file pg_dump.c.

5138{
5139 DumpOptions *dopt = fout->dopt;
5140 SubscriptionInfo *subinfo = NULL;
5141 SubRelInfo *subrinfo;
5142 PGresult *res;
5143 int i_srsubid;
5144 int i_srrelid;
5145 int i_srsubstate;
5146 int i_srsublsn;
5147 int ntups;
5148 Oid last_srsubid = InvalidOid;
5149
5150 if (dopt->no_subscriptions || !dopt->binary_upgrade ||
5151 fout->remoteVersion < 170000)
5152 return;
5153
5154 res = ExecuteSqlQuery(fout,
5155 "SELECT srsubid, srrelid, srsubstate, srsublsn "
5156 "FROM pg_catalog.pg_subscription_rel "
5157 "ORDER BY srsubid",
5159 ntups = PQntuples(res);
5160 if (ntups == 0)
5161 goto cleanup;
5162
5163 /* Get pg_subscription_rel attributes */
5164 i_srsubid = PQfnumber(res, "srsubid");
5165 i_srrelid = PQfnumber(res, "srrelid");
5166 i_srsubstate = PQfnumber(res, "srsubstate");
5167 i_srsublsn = PQfnumber(res, "srsublsn");
5168
5169 subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
5170 for (int i = 0; i < ntups; i++)
5171 {
5172 Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
5173 Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
5174 TableInfo *tblinfo;
5175
5176 /*
5177 * If we switched to a new subscription, check if the subscription
5178 * exists.
5179 */
5180 if (cur_srsubid != last_srsubid)
5181 {
5182 subinfo = findSubscriptionByOid(cur_srsubid);
5183 if (subinfo == NULL)
5184 pg_fatal("subscription with OID %u does not exist", cur_srsubid);
5185
5186 last_srsubid = cur_srsubid;
5187 }
5188
5189 tblinfo = findTableByOid(relid);
5190 if (tblinfo == NULL)
5191 pg_fatal("failed sanity check, table with OID %u not found",
5192 relid);
5193
5194 /* OK, make a DumpableObject for this relationship */
5195 subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
5196 subrinfo[i].dobj.catId.tableoid = relid;
5197 subrinfo[i].dobj.catId.oid = cur_srsubid;
5198 AssignDumpId(&subrinfo[i].dobj);
5199 subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
5200 subrinfo[i].tblinfo = tblinfo;
5201 subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
5202 if (PQgetisnull(res, i, i_srsublsn))
5203 subrinfo[i].srsublsn = NULL;
5204 else
5205 subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
5206
5207 subrinfo[i].subinfo = subinfo;
5208
5209 /* Decide whether we want to dump it */
5210 selectDumpableObject(&(subrinfo[i].dobj), fout);
5211 }
5212
5213cleanup:
5214 PQclear(res);
5215}
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:1025

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

◆ getTableAttrs()

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

Definition at line 8983 of file pg_dump.c.

8984{
8985 DumpOptions *dopt = fout->dopt;
8987 PQExpBuffer tbloids = createPQExpBuffer();
8988 PQExpBuffer checkoids = createPQExpBuffer();
8989 PQExpBuffer invalidnotnulloids = NULL;
8990 PGresult *res;
8991 int ntups;
8992 int curtblindx;
8993 int i_attrelid;
8994 int i_attnum;
8995 int i_attname;
8996 int i_atttypname;
8997 int i_attstattarget;
8998 int i_attstorage;
8999 int i_typstorage;
9000 int i_attidentity;
9001 int i_attgenerated;
9002 int i_attisdropped;
9003 int i_attlen;
9004 int i_attalign;
9005 int i_attislocal;
9006 int i_notnull_name;
9007 int i_notnull_noinherit;
9008 int i_notnull_islocal;
9009 int i_notnull_invalidoid;
9010 int i_attoptions;
9011 int i_attcollation;
9012 int i_attcompression;
9013 int i_attfdwoptions;
9014 int i_attmissingval;
9015 int i_atthasdef;
9016
9017 /*
9018 * We want to perform just one query against pg_attribute, and then just
9019 * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
9020 * (for CHECK constraints and for NOT NULL constraints). However, we
9021 * mustn't try to select every row of those catalogs and then sort it out
9022 * on the client side, because some of the server-side functions we need
9023 * would be unsafe to apply to tables we don't have lock on. Hence, we
9024 * build an array of the OIDs of tables we care about (and now have lock
9025 * on!), and use a WHERE clause to constrain which rows are selected.
9026 */
9027 appendPQExpBufferChar(tbloids, '{');
9028 appendPQExpBufferChar(checkoids, '{');
9029 for (int i = 0; i < numTables; i++)
9030 {
9031 TableInfo *tbinfo = &tblinfo[i];
9032
9033 /* Don't bother to collect info for sequences */
9034 if (tbinfo->relkind == RELKIND_SEQUENCE)
9035 continue;
9036
9037 /* Don't bother with uninteresting tables, either */
9038 if (!tbinfo->interesting)
9039 continue;
9040
9041 /* OK, we need info for this table */
9042 if (tbloids->len > 1) /* do we have more than the '{'? */
9043 appendPQExpBufferChar(tbloids, ',');
9044 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9045
9046 if (tbinfo->ncheck > 0)
9047 {
9048 /* Also make a list of the ones with check constraints */
9049 if (checkoids->len > 1) /* do we have more than the '{'? */
9050 appendPQExpBufferChar(checkoids, ',');
9051 appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
9052 }
9053 }
9054 appendPQExpBufferChar(tbloids, '}');
9055 appendPQExpBufferChar(checkoids, '}');
9056
9057 /*
9058 * Find all the user attributes and their types.
9059 *
9060 * Since we only want to dump COLLATE clauses for attributes whose
9061 * collation is different from their type's default, we use a CASE here to
9062 * suppress uninteresting attcollations cheaply.
9063 */
9065 "SELECT\n"
9066 "a.attrelid,\n"
9067 "a.attnum,\n"
9068 "a.attname,\n"
9069 "a.attstattarget,\n"
9070 "a.attstorage,\n"
9071 "t.typstorage,\n"
9072 "a.atthasdef,\n"
9073 "a.attisdropped,\n"
9074 "a.attlen,\n"
9075 "a.attalign,\n"
9076 "a.attislocal,\n"
9077 "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
9078 "array_to_string(a.attoptions, ', ') AS attoptions,\n"
9079 "CASE WHEN a.attcollation <> t.typcollation "
9080 "THEN a.attcollation ELSE 0 END AS attcollation,\n"
9081 "pg_catalog.array_to_string(ARRAY("
9082 "SELECT pg_catalog.quote_ident(option_name) || "
9083 "' ' || pg_catalog.quote_literal(option_value) "
9084 "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
9085 "ORDER BY option_name"
9086 "), E',\n ') AS attfdwoptions,\n");
9087
9088 /*
9089 * Find out any NOT NULL markings for each column. In 18 and up we read
9090 * pg_constraint to obtain the constraint name. notnull_noinherit is set
9091 * according to the NO INHERIT property. For versions prior to 18, we
9092 * store an empty string as the name when a constraint is marked as
9093 * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
9094 * without a name); also, such cases are never NO INHERIT.
9095 *
9096 * For invalid constraints, we need to store their OIDs for processing
9097 * elsewhere, so we bring the pg_constraint.oid value when the constraint
9098 * is invalid, and NULL otherwise.
9099 *
9100 * We track in notnull_islocal whether the constraint was defined directly
9101 * in this table or via an ancestor, for binary upgrade. flagInhAttrs
9102 * might modify this later; that routine is also in charge of determining
9103 * the correct inhcount.
9104 */
9105 if (fout->remoteVersion >= 180000)
9107 "co.conname AS notnull_name,\n"
9108 "CASE WHEN NOT co.convalidated THEN co.oid "
9109 "ELSE NULL END AS notnull_invalidoid,\n"
9110 "co.connoinherit AS notnull_noinherit,\n"
9111 "co.conislocal AS notnull_islocal,\n");
9112 else
9114 "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
9115 "NULL AS notnull_invalidoid,\n"
9116 "false AS notnull_noinherit,\n"
9117 "a.attislocal AS notnull_islocal,\n");
9118
9119 if (fout->remoteVersion >= 140000)
9121 "a.attcompression AS attcompression,\n");
9122 else
9124 "'' AS attcompression,\n");
9125
9126 if (fout->remoteVersion >= 100000)
9128 "a.attidentity,\n");
9129 else
9131 "'' AS attidentity,\n");
9132
9133 if (fout->remoteVersion >= 110000)
9135 "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
9136 "THEN a.attmissingval ELSE null END AS attmissingval,\n");
9137 else
9139 "NULL AS attmissingval,\n");
9140
9141 if (fout->remoteVersion >= 120000)
9143 "a.attgenerated\n");
9144 else
9146 "'' AS attgenerated\n");
9147
9148 /* need left join to pg_type to not fail on dropped columns ... */
9150 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9151 "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
9152 "LEFT JOIN pg_catalog.pg_type t "
9153 "ON (a.atttypid = t.oid)\n",
9154 tbloids->data);
9155
9156 /*
9157 * In versions 18 and up, we need pg_constraint for explicit NOT NULL
9158 * entries. Also, we need to know if the NOT NULL for each column is
9159 * backing a primary key.
9160 */
9161 if (fout->remoteVersion >= 180000)
9163 " LEFT JOIN pg_catalog.pg_constraint co ON "
9164 "(a.attrelid = co.conrelid\n"
9165 " AND co.contype = 'n' AND "
9166 "co.conkey = array[a.attnum])\n");
9167
9169 "WHERE a.attnum > 0::pg_catalog.int2\n"
9170 "ORDER BY a.attrelid, a.attnum");
9171
9172 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9173
9174 ntups = PQntuples(res);
9175
9176 i_attrelid = PQfnumber(res, "attrelid");
9177 i_attnum = PQfnumber(res, "attnum");
9178 i_attname = PQfnumber(res, "attname");
9179 i_atttypname = PQfnumber(res, "atttypname");
9180 i_attstattarget = PQfnumber(res, "attstattarget");
9181 i_attstorage = PQfnumber(res, "attstorage");
9182 i_typstorage = PQfnumber(res, "typstorage");
9183 i_attidentity = PQfnumber(res, "attidentity");
9184 i_attgenerated = PQfnumber(res, "attgenerated");
9185 i_attisdropped = PQfnumber(res, "attisdropped");
9186 i_attlen = PQfnumber(res, "attlen");
9187 i_attalign = PQfnumber(res, "attalign");
9188 i_attislocal = PQfnumber(res, "attislocal");
9189 i_notnull_name = PQfnumber(res, "notnull_name");
9190 i_notnull_invalidoid = PQfnumber(res, "notnull_invalidoid");
9191 i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
9192 i_notnull_islocal = PQfnumber(res, "notnull_islocal");
9193 i_attoptions = PQfnumber(res, "attoptions");
9194 i_attcollation = PQfnumber(res, "attcollation");
9195 i_attcompression = PQfnumber(res, "attcompression");
9196 i_attfdwoptions = PQfnumber(res, "attfdwoptions");
9197 i_attmissingval = PQfnumber(res, "attmissingval");
9198 i_atthasdef = PQfnumber(res, "atthasdef");
9199
9200 /* Within the next loop, we'll accumulate OIDs of tables with defaults */
9201 resetPQExpBuffer(tbloids);
9202 appendPQExpBufferChar(tbloids, '{');
9203
9204 /*
9205 * Outer loop iterates once per table, not once per row. Incrementing of
9206 * r is handled by the inner loop.
9207 */
9208 curtblindx = -1;
9209 for (int r = 0; r < ntups;)
9210 {
9211 Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
9212 TableInfo *tbinfo = NULL;
9213 int numatts;
9214 bool hasdefaults;
9215
9216 /* Count rows for this table */
9217 for (numatts = 1; numatts < ntups - r; numatts++)
9218 if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
9219 break;
9220
9221 /*
9222 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
9223 * order.
9224 */
9225 while (++curtblindx < numTables)
9226 {
9227 tbinfo = &tblinfo[curtblindx];
9228 if (tbinfo->dobj.catId.oid == attrelid)
9229 break;
9230 }
9231 if (curtblindx >= numTables)
9232 pg_fatal("unrecognized table OID %u", attrelid);
9233 /* cross-check that we only got requested tables */
9234 if (tbinfo->relkind == RELKIND_SEQUENCE ||
9235 !tbinfo->interesting)
9236 pg_fatal("unexpected column data for table \"%s\"",
9237 tbinfo->dobj.name);
9238
9239 /* Save data for this table */
9240 tbinfo->numatts = numatts;
9241 tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
9242 tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
9243 tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
9244 tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
9245 tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
9246 tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
9247 tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
9248 tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
9249 tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
9250 tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
9251 tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
9252 tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
9253 tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
9254 tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
9255 tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
9256 tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
9257 tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
9258 tbinfo->notnull_invalid = (bool *) pg_malloc(numatts * sizeof(bool));
9259 tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
9260 tbinfo->notnull_islocal = (bool *) pg_malloc(numatts * sizeof(bool));
9261 tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
9262 hasdefaults = false;
9263
9264 for (int j = 0; j < numatts; j++, r++)
9265 {
9266 if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
9267 pg_fatal("invalid column numbering in table \"%s\"",
9268 tbinfo->dobj.name);
9269 tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
9270 tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
9271 if (PQgetisnull(res, r, i_attstattarget))
9272 tbinfo->attstattarget[j] = -1;
9273 else
9274 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
9275 tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
9276 tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
9277 tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
9278 tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
9279 tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
9280 tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
9281 tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
9282 tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
9283 tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
9284
9285 /* Handle not-null constraint name and flags */
9286 determineNotNullFlags(fout, res, r,
9287 tbinfo, j,
9288 i_notnull_name,
9289 i_notnull_invalidoid,
9290 i_notnull_noinherit,
9291 i_notnull_islocal,
9292 &invalidnotnulloids);
9293
9294 tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
9295 tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
9296 tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
9297 tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
9298 tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
9299 tbinfo->attrdefs[j] = NULL; /* fix below */
9300 if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
9301 hasdefaults = true;
9302 }
9303
9304 if (hasdefaults)
9305 {
9306 /* Collect OIDs of interesting tables that have defaults */
9307 if (tbloids->len > 1) /* do we have more than the '{'? */
9308 appendPQExpBufferChar(tbloids, ',');
9309 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9310 }
9311 }
9312
9313 /* If invalidnotnulloids has any data, finalize it */
9314 if (invalidnotnulloids != NULL)
9315 appendPQExpBufferChar(invalidnotnulloids, '}');
9316
9317 PQclear(res);
9318
9319 /*
9320 * Now get info about column defaults. This is skipped for a data-only
9321 * dump, as it is only needed for table schemas.
9322 */
9323 if (dopt->dumpSchema && tbloids->len > 1)
9324 {
9325 AttrDefInfo *attrdefs;
9326 int numDefaults;
9327 TableInfo *tbinfo = NULL;
9328
9329 pg_log_info("finding table default expressions");
9330
9331 appendPQExpBufferChar(tbloids, '}');
9332
9333 printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9334 "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9335 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9336 "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9337 "ORDER BY a.adrelid, a.adnum",
9338 tbloids->data);
9339
9340 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9341
9342 numDefaults = PQntuples(res);
9343 attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9344
9345 curtblindx = -1;
9346 for (int j = 0; j < numDefaults; j++)
9347 {
9348 Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9349 Oid adoid = atooid(PQgetvalue(res, j, 1));
9350 Oid adrelid = atooid(PQgetvalue(res, j, 2));
9351 int adnum = atoi(PQgetvalue(res, j, 3));
9352 char *adsrc = PQgetvalue(res, j, 4);
9353
9354 /*
9355 * Locate the associated TableInfo; we rely on tblinfo[] being in
9356 * OID order.
9357 */
9358 if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9359 {
9360 while (++curtblindx < numTables)
9361 {
9362 tbinfo = &tblinfo[curtblindx];
9363 if (tbinfo->dobj.catId.oid == adrelid)
9364 break;
9365 }
9366 if (curtblindx >= numTables)
9367 pg_fatal("unrecognized table OID %u", adrelid);
9368 }
9369
9370 if (adnum <= 0 || adnum > tbinfo->numatts)
9371 pg_fatal("invalid adnum value %d for table \"%s\"",
9372 adnum, tbinfo->dobj.name);
9373
9374 /*
9375 * dropped columns shouldn't have defaults, but just in case,
9376 * ignore 'em
9377 */
9378 if (tbinfo->attisdropped[adnum - 1])
9379 continue;
9380
9381 attrdefs[j].dobj.objType = DO_ATTRDEF;
9382 attrdefs[j].dobj.catId.tableoid = adtableoid;
9383 attrdefs[j].dobj.catId.oid = adoid;
9384 AssignDumpId(&attrdefs[j].dobj);
9385 attrdefs[j].adtable = tbinfo;
9386 attrdefs[j].adnum = adnum;
9387 attrdefs[j].adef_expr = pg_strdup(adsrc);
9388
9389 attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9390 attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9391
9392 attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9393
9394 /*
9395 * Figure out whether the default/generation expression should be
9396 * dumped as part of the main CREATE TABLE (or similar) command or
9397 * as a separate ALTER TABLE (or similar) command. The preference
9398 * is to put it into the CREATE command, but in some cases that's
9399 * not possible.
9400 */
9401 if (tbinfo->attgenerated[adnum - 1])
9402 {
9403 /*
9404 * Column generation expressions cannot be dumped separately,
9405 * because there is no syntax for it. By setting separate to
9406 * false here we prevent the "default" from being processed as
9407 * its own dumpable object. Later, flagInhAttrs() will mark
9408 * it as not to be dumped at all, if possible (that is, if it
9409 * can be inherited from a parent).
9410 */
9411 attrdefs[j].separate = false;
9412 }
9413 else if (tbinfo->relkind == RELKIND_VIEW)
9414 {
9415 /*
9416 * Defaults on a VIEW must always be dumped as separate ALTER
9417 * TABLE commands.
9418 */
9419 attrdefs[j].separate = true;
9420 }
9421 else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9422 {
9423 /* column will be suppressed, print default separately */
9424 attrdefs[j].separate = true;
9425 }
9426 else
9427 {
9428 attrdefs[j].separate = false;
9429 }
9430
9431 if (!attrdefs[j].separate)
9432 {
9433 /*
9434 * Mark the default as needing to appear before the table, so
9435 * that any dependencies it has must be emitted before the
9436 * CREATE TABLE. If this is not possible, we'll change to
9437 * "separate" mode while sorting dependencies.
9438 */
9439 addObjectDependency(&tbinfo->dobj,
9440 attrdefs[j].dobj.dumpId);
9441 }
9442
9443 tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9444 }
9445
9446 PQclear(res);
9447 }
9448
9449 /*
9450 * Get info about NOT NULL NOT VALID constraints. This is skipped for a
9451 * data-only dump, as it is only needed for table schemas.
9452 */
9453 if (dopt->dumpSchema && invalidnotnulloids)
9454 {
9455 ConstraintInfo *constrs;
9456 int numConstrs;
9457 int i_tableoid;
9458 int i_oid;
9459 int i_conrelid;
9460 int i_conname;
9461 int i_consrc;
9462 int i_conislocal;
9463
9464 pg_log_info("finding invalid not null constraints");
9465
9468 "SELECT c.tableoid, c.oid, conrelid, conname, "
9469 "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9470 "conislocal, convalidated "
9471 "FROM unnest('%s'::pg_catalog.oid[]) AS src(conoid)\n"
9472 "JOIN pg_catalog.pg_constraint c ON (src.conoid = c.oid)\n"
9473 "ORDER BY c.conrelid, c.conname",
9474 invalidnotnulloids->data);
9475
9476 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9477
9478 numConstrs = PQntuples(res);
9479 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9480
9481 i_tableoid = PQfnumber(res, "tableoid");
9482 i_oid = PQfnumber(res, "oid");
9483 i_conrelid = PQfnumber(res, "conrelid");
9484 i_conname = PQfnumber(res, "conname");
9485 i_consrc = PQfnumber(res, "consrc");
9486 i_conislocal = PQfnumber(res, "conislocal");
9487
9488 /* As above, this loop iterates once per table, not once per row */
9489 curtblindx = -1;
9490 for (int j = 0; j < numConstrs;)
9491 {
9492 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9493 TableInfo *tbinfo = NULL;
9494 int numcons;
9495
9496 /* Count rows for this table */
9497 for (numcons = 1; numcons < numConstrs - j; numcons++)
9498 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9499 break;
9500
9501 /*
9502 * Locate the associated TableInfo; we rely on tblinfo[] being in
9503 * OID order.
9504 */
9505 while (++curtblindx < numTables)
9506 {
9507 tbinfo = &tblinfo[curtblindx];
9508 if (tbinfo->dobj.catId.oid == conrelid)
9509 break;
9510 }
9511 if (curtblindx >= numTables)
9512 pg_fatal("unrecognized table OID %u", conrelid);
9513
9514 for (int c = 0; c < numcons; c++, j++)
9515 {
9516 constrs[j].dobj.objType = DO_CONSTRAINT;
9517 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9518 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9519 AssignDumpId(&constrs[j].dobj);
9520 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9521 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9522 constrs[j].contable = tbinfo;
9523 constrs[j].condomain = NULL;
9524 constrs[j].contype = 'n';
9525 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9526 constrs[j].confrelid = InvalidOid;
9527 constrs[j].conindex = 0;
9528 constrs[j].condeferrable = false;
9529 constrs[j].condeferred = false;
9530 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9531
9532 /*
9533 * All invalid not-null constraints must be dumped separately,
9534 * because CREATE TABLE would not create them as invalid, and
9535 * also because they must be created after potentially
9536 * violating data has been loaded.
9537 */
9538 constrs[j].separate = true;
9539
9540 constrs[j].dobj.dump = tbinfo->dobj.dump;
9541 }
9542 }
9543 PQclear(res);
9544 }
9545
9546 /*
9547 * Get info about table CHECK constraints. This is skipped for a
9548 * data-only dump, as it is only needed for table schemas.
9549 */
9550 if (dopt->dumpSchema && checkoids->len > 2)
9551 {
9552 ConstraintInfo *constrs;
9553 int numConstrs;
9554 int i_tableoid;
9555 int i_oid;
9556 int i_conrelid;
9557 int i_conname;
9558 int i_consrc;
9559 int i_conislocal;
9560 int i_convalidated;
9561
9562 pg_log_info("finding table check constraints");
9563
9566 "SELECT c.tableoid, c.oid, conrelid, conname, "
9567 "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9568 "conislocal, convalidated "
9569 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9570 "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9571 "WHERE contype = 'c' "
9572 "ORDER BY c.conrelid, c.conname",
9573 checkoids->data);
9574
9575 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9576
9577 numConstrs = PQntuples(res);
9578 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9579
9580 i_tableoid = PQfnumber(res, "tableoid");
9581 i_oid = PQfnumber(res, "oid");
9582 i_conrelid = PQfnumber(res, "conrelid");
9583 i_conname = PQfnumber(res, "conname");
9584 i_consrc = PQfnumber(res, "consrc");
9585 i_conislocal = PQfnumber(res, "conislocal");
9586 i_convalidated = PQfnumber(res, "convalidated");
9587
9588 /* As above, this loop iterates once per table, not once per row */
9589 curtblindx = -1;
9590 for (int j = 0; j < numConstrs;)
9591 {
9592 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9593 TableInfo *tbinfo = NULL;
9594 int numcons;
9595
9596 /* Count rows for this table */
9597 for (numcons = 1; numcons < numConstrs - j; numcons++)
9598 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9599 break;
9600
9601 /*
9602 * Locate the associated TableInfo; we rely on tblinfo[] being in
9603 * OID order.
9604 */
9605 while (++curtblindx < numTables)
9606 {
9607 tbinfo = &tblinfo[curtblindx];
9608 if (tbinfo->dobj.catId.oid == conrelid)
9609 break;
9610 }
9611 if (curtblindx >= numTables)
9612 pg_fatal("unrecognized table OID %u", conrelid);
9613
9614 if (numcons != tbinfo->ncheck)
9615 {
9616 pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9617 "expected %d check constraints on table \"%s\" but found %d",
9618 tbinfo->ncheck),
9619 tbinfo->ncheck, tbinfo->dobj.name, numcons);
9620 pg_log_error_hint("The system catalogs might be corrupted.");
9621 exit_nicely(1);
9622 }
9623
9624 tbinfo->checkexprs = constrs + j;
9625
9626 for (int c = 0; c < numcons; c++, j++)
9627 {
9628 bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9629
9630 constrs[j].dobj.objType = DO_CONSTRAINT;
9631 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9632 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9633 AssignDumpId(&constrs[j].dobj);
9634 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9635 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9636 constrs[j].contable = tbinfo;
9637 constrs[j].condomain = NULL;
9638 constrs[j].contype = 'c';
9639 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9640 constrs[j].confrelid = InvalidOid;
9641 constrs[j].conindex = 0;
9642 constrs[j].condeferrable = false;
9643 constrs[j].condeferred = false;
9644 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9645
9646 /*
9647 * An unvalidated constraint needs to be dumped separately, so
9648 * that potentially-violating existing data is loaded before
9649 * the constraint.
9650 */
9651 constrs[j].separate = !validated;
9652
9653 constrs[j].dobj.dump = tbinfo->dobj.dump;
9654
9655 /*
9656 * Mark the constraint as needing to appear before the table
9657 * --- this is so that any other dependencies of the
9658 * constraint will be emitted before we try to create the
9659 * table. If the constraint is to be dumped separately, it
9660 * will be dumped after data is loaded anyway, so don't do it.
9661 * (There's an automatic dependency in the opposite direction
9662 * anyway, so don't need to add one manually here.)
9663 */
9664 if (!constrs[j].separate)
9665 addObjectDependency(&tbinfo->dobj,
9666 constrs[j].dobj.dumpId);
9667
9668 /*
9669 * We will detect later whether the constraint must be split
9670 * out from the table definition.
9671 */
9672 }
9673 }
9674
9675 PQclear(res);
9676 }
9677
9679 destroyPQExpBuffer(tbloids);
9680 destroyPQExpBuffer(checkoids);
9681}
#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_invalidoid, int i_notnull_noinherit, int i_notnull_islocal, PQExpBuffer *invalidnotnulloids)
Definition: pg_dump.c:9730

References addObjectDependency(), _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attcompression, _tableInfo::attfdwoptions, _tableInfo::attgenerated, _tableInfo::attidentity, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attmissingval, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypnames, _dumpableObject::catId, _tableInfo::checkexprs, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, 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_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 2929 of file pg_dump.c.

2930{
2931 int i;
2932
2933 for (i = 0; i < numTables; i++)
2934 {
2935 if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
2936 (!relkind || tblinfo[i].relkind == relkind))
2937 makeTableDataInfo(dopt, &(tblinfo[i]));
2938 }
2939}
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2948

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

Referenced by main().

◆ getTableDataFKConstraints()

static void getTableDataFKConstraints ( void  )
static

Definition at line 3150 of file pg_dump.c.

3151{
3152 DumpableObject **dobjs;
3153 int numObjs;
3154 int i;
3155
3156 /* Search through all the dumpable objects for FK constraints */
3157 getDumpableObjects(&dobjs, &numObjs);
3158 for (i = 0; i < numObjs; i++)
3159 {
3160 if (dobjs[i]->objType == DO_FK_CONSTRAINT)
3161 {
3162 ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
3163 TableInfo *ftable;
3164
3165 /* Not interesting unless both tables are to be dumped */
3166 if (cinfo->contable == NULL ||
3167 cinfo->contable->dataObj == NULL)
3168 continue;
3169 ftable = findTableByOid(cinfo->confrelid);
3170 if (ftable == NULL ||
3171 ftable->dataObj == NULL)
3172 continue;
3173
3174 /*
3175 * Okay, make referencing table's TABLE_DATA object depend on the
3176 * referenced table's TABLE_DATA object.
3177 */
3179 ftable->dataObj->dobj.dumpId);
3180 }
3181 }
3182 free(dobjs);
3183}
void getDumpableObjects(DumpableObject ***objs, int *numObjs)
Definition: common.c:796

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

6957{
6958 DumpOptions *dopt = fout->dopt;
6959 PGresult *res;
6960 int ntups;
6961 int i;
6963 TableInfo *tblinfo;
6964 int i_reltableoid;
6965 int i_reloid;
6966 int i_relname;
6967 int i_relnamespace;
6968 int i_relkind;
6969 int i_reltype;
6970 int i_relowner;
6971 int i_relchecks;
6972 int i_relhasindex;
6973 int i_relhasrules;
6974 int i_relpages;
6975 int i_reltuples;
6976 int i_relallvisible;
6977 int i_relallfrozen;
6978 int i_toastpages;
6979 int i_owning_tab;
6980 int i_owning_col;
6981 int i_reltablespace;
6982 int i_relhasoids;
6983 int i_relhastriggers;
6984 int i_relpersistence;
6985 int i_relispopulated;
6986 int i_relreplident;
6987 int i_relrowsec;
6988 int i_relforcerowsec;
6989 int i_relfrozenxid;
6990 int i_toastfrozenxid;
6991 int i_toastoid;
6992 int i_relminmxid;
6993 int i_toastminmxid;
6994 int i_reloptions;
6995 int i_checkoption;
6996 int i_toastreloptions;
6997 int i_reloftype;
6998 int i_foreignserver;
6999 int i_amname;
7000 int i_is_identity_sequence;
7001 int i_relacl;
7002 int i_acldefault;
7003 int i_ispartition;
7004
7005 /*
7006 * Find all the tables and table-like objects.
7007 *
7008 * We must fetch all tables in this phase because otherwise we cannot
7009 * correctly identify inherited columns, owned sequences, etc.
7010 *
7011 * We include system catalogs, so that we can work if a user table is
7012 * defined to inherit from a system catalog (pretty weird, but...)
7013 *
7014 * Note: in this phase we should collect only a minimal amount of
7015 * information about each table, basically just enough to decide if it is
7016 * interesting. In particular, since we do not yet have lock on any user
7017 * table, we MUST NOT invoke any server-side data collection functions
7018 * (for instance, pg_get_partkeydef()). Those are likely to fail or give
7019 * wrong answers if any concurrent DDL is happening.
7020 */
7021
7023 "SELECT c.tableoid, c.oid, c.relname, "
7024 "c.relnamespace, c.relkind, c.reltype, "
7025 "c.relowner, "
7026 "c.relchecks, "
7027 "c.relhasindex, c.relhasrules, c.relpages, "
7028 "c.reltuples, c.relallvisible, ");
7029
7030 if (fout->remoteVersion >= 180000)
7031 appendPQExpBufferStr(query, "c.relallfrozen, ");
7032 else
7033 appendPQExpBufferStr(query, "0 AS relallfrozen, ");
7034
7036 "c.relhastriggers, c.relpersistence, "
7037 "c.reloftype, "
7038 "c.relacl, "
7039 "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
7040 " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
7041 "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
7042 "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
7043 "ELSE 0 END AS foreignserver, "
7044 "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
7045 "tc.oid AS toid, "
7046 "tc.relpages AS toastpages, "
7047 "tc.reloptions AS toast_reloptions, "
7048 "d.refobjid AS owning_tab, "
7049 "d.refobjsubid AS owning_col, "
7050 "tsp.spcname AS reltablespace, ");
7051
7052 if (fout->remoteVersion >= 120000)
7054 "false AS relhasoids, ");
7055 else
7057 "c.relhasoids, ");
7058
7059 if (fout->remoteVersion >= 90300)
7061 "c.relispopulated, ");
7062 else
7064 "'t' as relispopulated, ");
7065
7066 if (fout->remoteVersion >= 90400)
7068 "c.relreplident, ");
7069 else
7071 "'d' AS relreplident, ");
7072
7073 if (fout->remoteVersion >= 90500)
7075 "c.relrowsecurity, c.relforcerowsecurity, ");
7076 else
7078 "false AS relrowsecurity, "
7079 "false AS relforcerowsecurity, ");
7080
7081 if (fout->remoteVersion >= 90300)
7083 "c.relminmxid, tc.relminmxid AS tminmxid, ");
7084 else
7086 "0 AS relminmxid, 0 AS tminmxid, ");
7087
7088 if (fout->remoteVersion >= 90300)
7090 "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
7091 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
7092 "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
7093 else
7095 "c.reloptions, NULL AS checkoption, ");
7096
7097 if (fout->remoteVersion >= 90600)
7099 "am.amname, ");
7100 else
7102 "NULL AS amname, ");
7103
7104 if (fout->remoteVersion >= 90600)
7106 "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
7107 else
7109 "false AS is_identity_sequence, ");
7110
7111 if (fout->remoteVersion >= 100000)
7113 "c.relispartition AS ispartition ");
7114 else
7116 "false AS ispartition ");
7117
7118 /*
7119 * Left join to pg_depend to pick up dependency info linking sequences to
7120 * their owning column, if any (note this dependency is AUTO except for
7121 * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
7122 * collect the spcname.
7123 */
7125 "\nFROM pg_class c\n"
7126 "LEFT JOIN pg_depend d ON "
7127 "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
7128 "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
7129 "d.objsubid = 0 AND "
7130 "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
7131 "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
7132
7133 /*
7134 * In 9.6 and up, left join to pg_am to pick up the amname.
7135 */
7136 if (fout->remoteVersion >= 90600)
7138 "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
7139
7140 /*
7141 * We purposefully ignore toast OIDs for partitioned tables; the reason is
7142 * that versions 10 and 11 have them, but later versions do not, so
7143 * emitting them causes the upgrade to fail.
7144 */
7146 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
7147 " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
7148 " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
7149
7150 /*
7151 * Restrict to interesting relkinds (in particular, not indexes). Not all
7152 * relkinds are possible in older servers, but it's not worth the trouble
7153 * to emit a version-dependent list.
7154 *
7155 * Composite-type table entries won't be dumped as such, but we have to
7156 * make a DumpableObject for them so that we can track dependencies of the
7157 * composite type (pg_depend entries for columns of the composite type
7158 * link to the pg_class entry not the pg_type entry).
7159 */
7161 "WHERE c.relkind IN ("
7162 CppAsString2(RELKIND_RELATION) ", "
7163 CppAsString2(RELKIND_SEQUENCE) ", "
7164 CppAsString2(RELKIND_VIEW) ", "
7165 CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
7166 CppAsString2(RELKIND_MATVIEW) ", "
7167 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
7168 CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
7169 "ORDER BY c.oid");
7170
7171 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7172
7173 ntups = PQntuples(res);
7174
7175 *numTables = ntups;
7176
7177 /*
7178 * Extract data from result and lock dumpable tables. We do the locking
7179 * before anything else, to minimize the window wherein a table could
7180 * disappear under us.
7181 *
7182 * Note that we have to save info about all tables here, even when dumping
7183 * only one, because we don't yet know which tables might be inheritance
7184 * ancestors of the target table.
7185 */
7186 tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
7187
7188 i_reltableoid = PQfnumber(res, "tableoid");
7189 i_reloid = PQfnumber(res, "oid");
7190 i_relname = PQfnumber(res, "relname");
7191 i_relnamespace = PQfnumber(res, "relnamespace");
7192 i_relkind = PQfnumber(res, "relkind");
7193 i_reltype = PQfnumber(res, "reltype");
7194 i_relowner = PQfnumber(res, "relowner");
7195 i_relchecks = PQfnumber(res, "relchecks");
7196 i_relhasindex = PQfnumber(res, "relhasindex");
7197 i_relhasrules = PQfnumber(res, "relhasrules");
7198 i_relpages = PQfnumber(res, "relpages");
7199 i_reltuples = PQfnumber(res, "reltuples");
7200 i_relallvisible = PQfnumber(res, "relallvisible");
7201 i_relallfrozen = PQfnumber(res, "relallfrozen");
7202 i_toastpages = PQfnumber(res, "toastpages");
7203 i_owning_tab = PQfnumber(res, "owning_tab");
7204 i_owning_col = PQfnumber(res, "owning_col");
7205 i_reltablespace = PQfnumber(res, "reltablespace");
7206 i_relhasoids = PQfnumber(res, "relhasoids");
7207 i_relhastriggers = PQfnumber(res, "relhastriggers");
7208 i_relpersistence = PQfnumber(res, "relpersistence");
7209 i_relispopulated = PQfnumber(res, "relispopulated");
7210 i_relreplident = PQfnumber(res, "relreplident");
7211 i_relrowsec = PQfnumber(res, "relrowsecurity");
7212 i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
7213 i_relfrozenxid = PQfnumber(res, "relfrozenxid");
7214 i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
7215 i_toastoid = PQfnumber(res, "toid");
7216 i_relminmxid = PQfnumber(res, "relminmxid");
7217 i_toastminmxid = PQfnumber(res, "tminmxid");
7218 i_reloptions = PQfnumber(res, "reloptions");
7219 i_checkoption = PQfnumber(res, "checkoption");
7220 i_toastreloptions = PQfnumber(res, "toast_reloptions");
7221 i_reloftype = PQfnumber(res, "reloftype");
7222 i_foreignserver = PQfnumber(res, "foreignserver");
7223 i_amname = PQfnumber(res, "amname");
7224 i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
7225 i_relacl = PQfnumber(res, "relacl");
7226 i_acldefault = PQfnumber(res, "acldefault");
7227 i_ispartition = PQfnumber(res, "ispartition");
7228
7229 if (dopt->lockWaitTimeout)
7230 {
7231 /*
7232 * Arrange to fail instead of waiting forever for a table lock.
7233 *
7234 * NB: this coding assumes that the only queries issued within the
7235 * following loop are LOCK TABLEs; else the timeout may be undesirably
7236 * applied to other things too.
7237 */
7238 resetPQExpBuffer(query);
7239 appendPQExpBufferStr(query, "SET statement_timeout = ");
7241 ExecuteSqlStatement(fout, query->data);
7242 }
7243
7244 resetPQExpBuffer(query);
7245
7246 for (i = 0; i < ntups; i++)
7247 {
7248 int32 relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
7249 int32 relallfrozen = atoi(PQgetvalue(res, i, i_relallfrozen));
7250
7251 tblinfo[i].dobj.objType = DO_TABLE;
7252 tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
7253 tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
7254 AssignDumpId(&tblinfo[i].dobj);
7255 tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
7256 tblinfo[i].dobj.namespace =
7257 findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
7258 tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
7259 tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
7260 tblinfo[i].dacl.privtype = 0;
7261 tblinfo[i].dacl.initprivs = NULL;
7262 tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
7263 tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
7264 tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
7265 tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
7266 tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
7267 tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
7268 tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
7269 if (PQgetisnull(res, i, i_toastpages))
7270 tblinfo[i].toastpages = 0;
7271 else
7272 tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
7273 if (PQgetisnull(res, i, i_owning_tab))
7274 {
7275 tblinfo[i].owning_tab = InvalidOid;
7276 tblinfo[i].owning_col = 0;
7277 }
7278 else
7279 {
7280 tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
7281 tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
7282 }
7283 tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
7284 tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
7285 tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
7286 tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
7287 tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
7288 tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
7289 tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
7290 tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
7291 tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
7292 tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
7293 tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
7294 tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
7295 tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
7296 tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
7297 if (PQgetisnull(res, i, i_checkoption))
7298 tblinfo[i].checkoption = NULL;
7299 else
7300 tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
7301 tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
7302 tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
7303 tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
7304 if (PQgetisnull(res, i, i_amname))
7305 tblinfo[i].amname = NULL;
7306 else
7307 tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
7308 tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
7309 tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
7310
7311 /* other fields were zeroed above */
7312
7313 /*
7314 * Decide whether we want to dump this table.
7315 */
7316 if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
7317 tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
7318 else
7319 selectDumpableTable(&tblinfo[i], fout);
7320
7321 /*
7322 * Now, consider the table "interesting" if we need to dump its
7323 * definition, data or its statistics. Later on, we'll skip a lot of
7324 * data collection for uninteresting tables.
7325 *
7326 * Note: the "interesting" flag will also be set by flagInhTables for
7327 * parents of interesting tables, so that we collect necessary
7328 * inheritance info even when the parents are not themselves being
7329 * dumped. This is the main reason why we need an "interesting" flag
7330 * that's separate from the components-to-dump bitmask.
7331 */
7332 tblinfo[i].interesting = (tblinfo[i].dobj.dump &
7336
7337 tblinfo[i].dummy_view = false; /* might get set during sort */
7338 tblinfo[i].postponed_def = false; /* might get set during sort */
7339
7340 /* Tables have data */
7342
7343 /* Mark whether table has an ACL */
7344 if (!PQgetisnull(res, i, i_relacl))
7345 tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
7346 tblinfo[i].hascolumnACLs = false; /* may get set later */
7347
7348 /* Add statistics */
7349 if (tblinfo[i].interesting)
7350 {
7351 RelStatsInfo *stats;
7352
7353 stats = getRelationStatistics(fout, &tblinfo[i].dobj,
7354 tblinfo[i].relpages,
7355 PQgetvalue(res, i, i_reltuples),
7356 relallvisible, relallfrozen,
7357 tblinfo[i].relkind, NULL, 0);
7358 if (tblinfo[i].relkind == RELKIND_MATVIEW)
7359 tblinfo[i].stats = stats;
7360 }
7361
7362 /*
7363 * Read-lock target tables to make sure they aren't DROPPED or altered
7364 * in schema before we get around to dumping them.
7365 *
7366 * Note that we don't explicitly lock parents of the target tables; we
7367 * assume our lock on the child is enough to prevent schema
7368 * alterations to parent tables.
7369 *
7370 * NOTE: it'd be kinda nice to lock other relations too, not only
7371 * plain or partitioned tables, but the backend doesn't presently
7372 * allow that.
7373 *
7374 * We only need to lock the table for certain components; see
7375 * pg_dump.h
7376 */
7377 if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
7378 (tblinfo[i].relkind == RELKIND_RELATION ||
7379 tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
7380 {
7381 /*
7382 * Tables are locked in batches. When dumping from a remote
7383 * server this can save a significant amount of time by reducing
7384 * the number of round trips.
7385 */
7386 if (query->len == 0)
7387 appendPQExpBuffer(query, "LOCK TABLE %s",
7388 fmtQualifiedDumpable(&tblinfo[i]));
7389 else
7390 {
7391 appendPQExpBuffer(query, ", %s",
7392 fmtQualifiedDumpable(&tblinfo[i]));
7393
7394 /* Arbitrarily end a batch when query length reaches 100K. */
7395 if (query->len >= 100000)
7396 {
7397 /* Lock another batch of tables. */
7398 appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7399 ExecuteSqlStatement(fout, query->data);
7400 resetPQExpBuffer(query);
7401 }
7402 }
7403 }
7404 }
7405
7406 if (query->len != 0)
7407 {
7408 /* Lock the tables in the last batch. */
7409 appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7410 ExecuteSqlStatement(fout, query->data);
7411 }
7412
7413 if (dopt->lockWaitTimeout)
7414 {
7415 ExecuteSqlStatement(fout, "SET statement_timeout = 0");
7416 }
7417
7418 PQclear(res);
7419
7420 destroyPQExpBuffer(query);
7421
7422 return tblinfo;
7423}
static void selectDumpableTable(TableInfo *tbinfo, Archive *fout)
Definition: pg_dump.c:2003
#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:177
struct _relStatsInfo * stats
Definition: pg_dump.h:373
Oid foreign_server
Definition: pg_dump.h:326
bool hasrules
Definition: pg_dump.h:312
bool hastriggers
Definition: pg_dump.h:313

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

8900{
8901 PGresult *res;
8902 int ntups;
8903 int i;
8904 PQExpBuffer query;
8905 TransformInfo *transforminfo;
8906 int i_tableoid;
8907 int i_oid;
8908 int i_trftype;
8909 int i_trflang;
8910 int i_trffromsql;
8911 int i_trftosql;
8912
8913 /* Transforms didn't exist pre-9.5 */
8914 if (fout->remoteVersion < 90500)
8915 return;
8916
8917 query = createPQExpBuffer();
8918
8919 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8920 "trftype, trflang, trffromsql::oid, trftosql::oid "
8921 "FROM pg_transform "
8922 "ORDER BY 3,4");
8923
8924 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8925
8926 ntups = PQntuples(res);
8927
8928 transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8929
8930 i_tableoid = PQfnumber(res, "tableoid");
8931 i_oid = PQfnumber(res, "oid");
8932 i_trftype = PQfnumber(res, "trftype");
8933 i_trflang = PQfnumber(res, "trflang");
8934 i_trffromsql = PQfnumber(res, "trffromsql");
8935 i_trftosql = PQfnumber(res, "trftosql");
8936
8937 for (i = 0; i < ntups; i++)
8938 {
8939 PQExpBufferData namebuf;
8940 TypeInfo *typeInfo;
8941 char *lanname;
8942
8943 transforminfo[i].dobj.objType = DO_TRANSFORM;
8944 transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8945 transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8946 AssignDumpId(&transforminfo[i].dobj);
8947 transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8948 transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8949 transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8950 transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8951
8952 /*
8953 * Try to name transform as concatenation of type and language name.
8954 * This is only used for purposes of sorting. If we fail to find
8955 * either, the name will be an empty string.
8956 */
8957 initPQExpBuffer(&namebuf);
8958 typeInfo = findTypeByOid(transforminfo[i].trftype);
8959 lanname = get_language_name(fout, transforminfo[i].trflang);
8960 if (typeInfo && lanname)
8961 appendPQExpBuffer(&namebuf, "%s %s",
8962 typeInfo->dobj.name, lanname);
8963 transforminfo[i].dobj.name = namebuf.data;
8964 free(lanname);
8965
8966 /* Decide whether we want to dump it */
8967 selectDumpableObject(&(transforminfo[i].dobj), fout);
8968 }
8969
8970 PQclear(res);
8971
8972 destroyPQExpBuffer(query);
8973}

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

8432{
8434 PQExpBuffer tbloids = createPQExpBuffer();
8435 PGresult *res;
8436 int ntups;
8437 int curtblindx;
8438 TriggerInfo *tginfo;
8439 int i_tableoid,
8440 i_oid,
8441 i_tgrelid,
8442 i_tgname,
8443 i_tgenabled,
8444 i_tgispartition,
8445 i_tgdef;
8446
8447 /*
8448 * We want to perform just one query against pg_trigger. However, we
8449 * mustn't try to select every row of the catalog and then sort it out on
8450 * the client side, because some of the server-side functions we need
8451 * would be unsafe to apply to tables we don't have lock on. Hence, we
8452 * build an array of the OIDs of tables we care about (and now have lock
8453 * on!), and use a WHERE clause to constrain which rows are selected.
8454 */
8455 appendPQExpBufferChar(tbloids, '{');
8456 for (int i = 0; i < numTables; i++)
8457 {
8458 TableInfo *tbinfo = &tblinfo[i];
8459
8460 if (!tbinfo->hastriggers ||
8461 !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8462 continue;
8463
8464 /* OK, we need info for this table */
8465 if (tbloids->len > 1) /* do we have more than the '{'? */
8466 appendPQExpBufferChar(tbloids, ',');
8467 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8468 }
8469 appendPQExpBufferChar(tbloids, '}');
8470
8471 if (fout->remoteVersion >= 150000)
8472 {
8473 /*
8474 * NB: think not to use pretty=true in pg_get_triggerdef. It could
8475 * result in non-forward-compatible dumps of WHEN clauses due to
8476 * under-parenthesization.
8477 *
8478 * NB: We need to see partition triggers in case the tgenabled flag
8479 * has been changed from the parent.
8480 */
8481 appendPQExpBuffer(query,
8482 "SELECT t.tgrelid, t.tgname, "
8483 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8484 "t.tgenabled, t.tableoid, t.oid, "
8485 "t.tgparentid <> 0 AS tgispartition\n"
8486 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8487 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8488 "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8489 "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
8490 "OR t.tgenabled != u.tgenabled) "
8491 "ORDER BY t.tgrelid, t.tgname",
8492 tbloids->data);
8493 }
8494 else if (fout->remoteVersion >= 130000)
8495 {
8496 /*
8497 * NB: think not to use pretty=true in pg_get_triggerdef. It could
8498 * result in non-forward-compatible dumps of WHEN clauses due to
8499 * under-parenthesization.
8500 *
8501 * NB: We need to see tgisinternal triggers in partitions, in case the
8502 * tgenabled flag has been changed from the parent.
8503 */
8504 appendPQExpBuffer(query,
8505 "SELECT t.tgrelid, t.tgname, "
8506 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8507 "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
8508 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8509 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8510 "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8511 "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
8512 "ORDER BY t.tgrelid, t.tgname",
8513 tbloids->data);
8514 }
8515 else if (fout->remoteVersion >= 110000)
8516 {
8517 /*
8518 * NB: We need to see tgisinternal triggers in partitions, in case the
8519 * tgenabled flag has been changed from the parent. No tgparentid in
8520 * version 11-12, so we have to match them via pg_depend.
8521 *
8522 * See above about pretty=true in pg_get_triggerdef.
8523 */
8524 appendPQExpBuffer(query,
8525 "SELECT t.tgrelid, t.tgname, "
8526 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8527 "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
8528 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8529 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8530 "LEFT JOIN pg_catalog.pg_depend AS d ON "
8531 " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8532 " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8533 " d.objid = t.oid "
8534 "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8535 "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
8536 "ORDER BY t.tgrelid, t.tgname",
8537 tbloids->data);
8538 }
8539 else
8540 {
8541 /* See above about pretty=true in pg_get_triggerdef */
8542 appendPQExpBuffer(query,
8543 "SELECT t.tgrelid, t.tgname, "
8544 "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8545 "t.tgenabled, false as tgispartition, "
8546 "t.tableoid, t.oid "
8547 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8548 "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8549 "WHERE NOT tgisinternal "
8550 "ORDER BY t.tgrelid, t.tgname",
8551 tbloids->data);
8552 }
8553
8554 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8555
8556 ntups = PQntuples(res);
8557
8558 i_tableoid = PQfnumber(res, "tableoid");
8559 i_oid = PQfnumber(res, "oid");
8560 i_tgrelid = PQfnumber(res, "tgrelid");
8561 i_tgname = PQfnumber(res, "tgname");
8562 i_tgenabled = PQfnumber(res, "tgenabled");
8563 i_tgispartition = PQfnumber(res, "tgispartition");
8564 i_tgdef = PQfnumber(res, "tgdef");
8565
8566 tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
8567
8568 /*
8569 * Outer loop iterates once per table, not once per row. Incrementing of
8570 * j is handled by the inner loop.
8571 */
8572 curtblindx = -1;
8573 for (int j = 0; j < ntups;)
8574 {
8575 Oid tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
8576 TableInfo *tbinfo = NULL;
8577 int numtrigs;
8578
8579 /* Count rows for this table */
8580 for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
8581 if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
8582 break;
8583
8584 /*
8585 * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8586 * order.
8587 */
8588 while (++curtblindx < numTables)
8589 {
8590 tbinfo = &tblinfo[curtblindx];
8591 if (tbinfo->dobj.catId.oid == tgrelid)
8592 break;
8593 }
8594 if (curtblindx >= numTables)
8595 pg_fatal("unrecognized table OID %u", tgrelid);
8596
8597 /* Save data for this table */
8598 tbinfo->triggers = tginfo + j;
8599 tbinfo->numTriggers = numtrigs;
8600
8601 for (int c = 0; c < numtrigs; c++, j++)
8602 {
8603 tginfo[j].dobj.objType = DO_TRIGGER;
8604 tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8605 tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8606 AssignDumpId(&tginfo[j].dobj);
8607 tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
8608 tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8609 tginfo[j].tgtable = tbinfo;
8610 tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8611 tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
8612 tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
8613 }
8614 }
8615
8616 PQclear(res);
8617
8618 destroyPQExpBuffer(query);
8619 destroyPQExpBuffer(tbloids);
8620}
struct _triggerInfo * triggers
Definition: pg_dump.h:384
int numTriggers
Definition: pg_dump.h:383

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

10069{
10070 PGresult *res;
10071 int ntups;
10072 int i;
10073 PQExpBuffer query;
10074 TSConfigInfo *cfginfo;
10075 int i_tableoid;
10076 int i_oid;
10077 int i_cfgname;
10078 int i_cfgnamespace;
10079 int i_cfgowner;
10080 int i_cfgparser;
10081
10082 query = createPQExpBuffer();
10083
10084 appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
10085 "cfgnamespace, cfgowner, cfgparser "
10086 "FROM pg_ts_config");
10087
10088 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10089
10090 ntups = PQntuples(res);
10091
10092 cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
10093
10094 i_tableoid = PQfnumber(res, "tableoid");
10095 i_oid = PQfnumber(res, "oid");
10096 i_cfgname = PQfnumber(res, "cfgname");
10097 i_cfgnamespace = PQfnumber(res, "cfgnamespace");
10098 i_cfgowner = PQfnumber(res, "cfgowner");
10099 i_cfgparser = PQfnumber(res, "cfgparser");
10100
10101 for (i = 0; i < ntups; i++)
10102 {
10103 cfginfo[i].dobj.objType = DO_TSCONFIG;
10104 cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10105 cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10106 AssignDumpId(&cfginfo[i].dobj);
10107 cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
10108 cfginfo[i].dobj.namespace =
10109 findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
10110 cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
10111 cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
10112
10113 /* Decide whether we want to dump it */
10114 selectDumpableObject(&(cfginfo[i].dobj), fout);
10115 }
10116
10117 PQclear(res);
10118
10119 destroyPQExpBuffer(query);
10120}

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

9944{
9945 PGresult *res;
9946 int ntups;
9947 int i;
9948 PQExpBuffer query;
9949 TSDictInfo *dictinfo;
9950 int i_tableoid;
9951 int i_oid;
9952 int i_dictname;
9953 int i_dictnamespace;
9954 int i_dictowner;
9955 int i_dicttemplate;
9956 int i_dictinitoption;
9957
9958 query = createPQExpBuffer();
9959
9960 appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9961 "dictnamespace, dictowner, "
9962 "dicttemplate, dictinitoption "
9963 "FROM pg_ts_dict");
9964
9965 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9966
9967 ntups = PQntuples(res);
9968
9969 dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9970
9971 i_tableoid = PQfnumber(res, "tableoid");
9972 i_oid = PQfnumber(res, "oid");
9973 i_dictname = PQfnumber(res, "dictname");
9974 i_dictnamespace = PQfnumber(res, "dictnamespace");
9975 i_dictowner = PQfnumber(res, "dictowner");
9976 i_dictinitoption = PQfnumber(res, "dictinitoption");
9977 i_dicttemplate = PQfnumber(res, "dicttemplate");
9978
9979 for (i = 0; i < ntups; i++)
9980 {
9981 dictinfo[i].dobj.objType = DO_TSDICT;
9982 dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9983 dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9984 AssignDumpId(&dictinfo[i].dobj);
9985 dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9986 dictinfo[i].dobj.namespace =
9987 findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9988 dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9989 dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9990 if (PQgetisnull(res, i, i_dictinitoption))
9991 dictinfo[i].dictinitoption = NULL;
9992 else
9993 dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9994
9995 /* Decide whether we want to dump it */
9996 selectDumpableObject(&(dictinfo[i].dobj), fout);
9997 }
9998
9999 PQclear(res);
10000
10001 destroyPQExpBuffer(query);
10002}

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

9870{
9871 PGresult *res;
9872 int ntups;
9873 int i;
9874 PQExpBuffer query;
9875 TSParserInfo *prsinfo;
9876 int i_tableoid;
9877 int i_oid;
9878 int i_prsname;
9879 int i_prsnamespace;
9880 int i_prsstart;
9881 int i_prstoken;
9882 int i_prsend;
9883 int i_prsheadline;
9884 int i_prslextype;
9885
9886 query = createPQExpBuffer();
9887
9888 /*
9889 * find all text search objects, including builtin ones; we filter out
9890 * system-defined objects at dump-out time.
9891 */
9892
9893 appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
9894 "prsstart::oid, prstoken::oid, "
9895 "prsend::oid, prsheadline::oid, prslextype::oid "
9896 "FROM pg_ts_parser");
9897
9898 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9899
9900 ntups = PQntuples(res);
9901
9902 prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
9903
9904 i_tableoid = PQfnumber(res, "tableoid");
9905 i_oid = PQfnumber(res, "oid");
9906 i_prsname = PQfnumber(res, "prsname");
9907 i_prsnamespace = PQfnumber(res, "prsnamespace");
9908 i_prsstart = PQfnumber(res, "prsstart");
9909 i_prstoken = PQfnumber(res, "prstoken");
9910 i_prsend = PQfnumber(res, "prsend");
9911 i_prsheadline = PQfnumber(res, "prsheadline");
9912 i_prslextype = PQfnumber(res, "prslextype");
9913
9914 for (i = 0; i < ntups; i++)
9915 {
9916 prsinfo[i].dobj.objType = DO_TSPARSER;
9917 prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9918 prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9919 AssignDumpId(&prsinfo[i].dobj);
9920 prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
9921 prsinfo[i].dobj.namespace =
9922 findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
9923 prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
9924 prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
9925 prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
9926 prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
9927 prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
9928
9929 /* Decide whether we want to dump it */
9930 selectDumpableObject(&(prsinfo[i].dobj), fout);
9931 }
9932
9933 PQclear(res);
9934
9935 destroyPQExpBuffer(query);
9936}

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

10010{
10011 PGresult *res;
10012 int ntups;
10013 int i;
10014 PQExpBuffer query;
10015 TSTemplateInfo *tmplinfo;
10016 int i_tableoid;
10017 int i_oid;
10018 int i_tmplname;
10019 int i_tmplnamespace;
10020 int i_tmplinit;
10021 int i_tmpllexize;
10022
10023 query = createPQExpBuffer();
10024
10025 appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
10026 "tmplnamespace, tmplinit::oid, tmpllexize::oid "
10027 "FROM pg_ts_template");
10028
10029 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10030
10031 ntups = PQntuples(res);
10032
10033 tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
10034
10035 i_tableoid = PQfnumber(res, "tableoid");
10036 i_oid = PQfnumber(res, "oid");
10037 i_tmplname = PQfnumber(res, "tmplname");
10038 i_tmplnamespace = PQfnumber(res, "tmplnamespace");
10039 i_tmplinit = PQfnumber(res, "tmplinit");
10040 i_tmpllexize = PQfnumber(res, "tmpllexize");
10041
10042 for (i = 0; i < ntups; i++)
10043 {
10044 tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
10045 tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10046 tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10047 AssignDumpId(&tmplinfo[i].dobj);
10048 tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
10049 tmplinfo[i].dobj.namespace =
10050 findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
10051 tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
10052 tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
10053
10054 /* Decide whether we want to dump it */
10055 selectDumpableObject(&(tmplinfo[i].dobj), fout);
10056 }
10057
10058 PQclear(res);
10059
10060 destroyPQExpBuffer(query);
10061}

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

6003{
6004 PGresult *res;
6005 int ntups;
6006 int i;
6008 TypeInfo *tyinfo;
6009 ShellTypeInfo *stinfo;
6010 int i_tableoid;
6011 int i_oid;
6012 int i_typname;
6013 int i_typnamespace;
6014 int i_typacl;
6015 int i_acldefault;
6016 int i_typowner;
6017 int i_typelem;
6018 int i_typrelid;
6019 int i_typrelkind;
6020 int i_typtype;
6021 int i_typisdefined;
6022 int i_isarray;
6023 int i_typarray;
6024
6025 /*
6026 * we include even the built-in types because those may be used as array
6027 * elements by user-defined types
6028 *
6029 * we filter out the built-in types when we dump out the types
6030 *
6031 * same approach for undefined (shell) types and array types
6032 *
6033 * Note: as of 8.3 we can reliably detect whether a type is an
6034 * auto-generated array type by checking the element type's typarray.
6035 * (Before that the test is capable of generating false positives.) We
6036 * still check for name beginning with '_', though, so as to avoid the
6037 * cost of the subselect probe for all standard types. This would have to
6038 * be revisited if the backend ever allows renaming of array types.
6039 */
6040 appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
6041 "typnamespace, typacl, "
6042 "acldefault('T', typowner) AS acldefault, "
6043 "typowner, "
6044 "typelem, typrelid, typarray, "
6045 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
6046 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
6047 "typtype, typisdefined, "
6048 "typname[0] = '_' AND typelem != 0 AND "
6049 "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
6050 "FROM pg_type");
6051
6052 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6053
6054 ntups = PQntuples(res);
6055
6056 tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
6057
6058 i_tableoid = PQfnumber(res, "tableoid");
6059 i_oid = PQfnumber(res, "oid");
6060 i_typname = PQfnumber(res, "typname");
6061 i_typnamespace = PQfnumber(res, "typnamespace");
6062 i_typacl = PQfnumber(res, "typacl");
6063 i_acldefault = PQfnumber(res, "acldefault");
6064 i_typowner = PQfnumber(res, "typowner");
6065 i_typelem = PQfnumber(res, "typelem");
6066 i_typrelid = PQfnumber(res, "typrelid");
6067 i_typrelkind = PQfnumber(res, "typrelkind");
6068 i_typtype = PQfnumber(res, "typtype");
6069 i_typisdefined = PQfnumber(res, "typisdefined");
6070 i_isarray = PQfnumber(res, "isarray");
6071 i_typarray = PQfnumber(res, "typarray");
6072
6073 for (i = 0; i < ntups; i++)
6074 {
6075 tyinfo[i].dobj.objType = DO_TYPE;
6076 tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6077 tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6078 AssignDumpId(&tyinfo[i].dobj);
6079 tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
6080 tyinfo[i].dobj.namespace =
6081 findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
6082 tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
6083 tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6084 tyinfo[i].dacl.privtype = 0;
6085 tyinfo[i].dacl.initprivs = NULL;
6086 tyinfo[i].ftypname = NULL; /* may get filled later */
6087 tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
6088 tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
6089 tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
6090 tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
6091 tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
6092 tyinfo[i].shellType = NULL;
6093
6094 if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
6095 tyinfo[i].isDefined = true;
6096 else
6097 tyinfo[i].isDefined = false;
6098
6099 if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
6100 tyinfo[i].isArray = true;
6101 else
6102 tyinfo[i].isArray = false;
6103
6104 tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
6105
6106 if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
6107 tyinfo[i].isMultirange = true;
6108 else
6109 tyinfo[i].isMultirange = false;
6110
6111 /* Decide whether we want to dump it */
6112 selectDumpableType(&tyinfo[i], fout);
6113
6114 /* Mark whether type has an ACL */
6115 if (!PQgetisnull(res, i, i_typacl))
6117
6118 /*
6119 * If it's a domain, fetch info about its constraints, if any
6120 */
6121 tyinfo[i].nDomChecks = 0;
6122 tyinfo[i].domChecks = NULL;
6123 if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6124 tyinfo[i].typtype == TYPTYPE_DOMAIN)
6125 getDomainConstraints(fout, &(tyinfo[i]));
6126
6127 /*
6128 * If it's a base type, make a DumpableObject representing a shell
6129 * definition of the type. We will need to dump that ahead of the I/O
6130 * functions for the type. Similarly, range types need a shell
6131 * definition in case they have a canonicalize function.
6132 *
6133 * Note: the shell type doesn't have a catId. You might think it
6134 * should copy the base type's catId, but then it might capture the
6135 * pg_depend entries for the type, which we don't want.
6136 */
6137 if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6138 (tyinfo[i].typtype == TYPTYPE_BASE ||
6139 tyinfo[i].typtype == TYPTYPE_RANGE))
6140 {
6141 stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
6142 stinfo->dobj.objType = DO_SHELL_TYPE;
6143 stinfo->dobj.catId = nilCatalogId;
6144 AssignDumpId(&stinfo->dobj);
6145 stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
6146 stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
6147 stinfo->baseType = &(tyinfo[i]);
6148 tyinfo[i].shellType = stinfo;
6149
6150 /*
6151 * Initially mark the shell type as not to be dumped. We'll only
6152 * dump it if the I/O or canonicalize functions need to be dumped;
6153 * this is taken care of while sorting dependencies.
6154 */
6155 stinfo->dobj.dump = DUMP_COMPONENT_NONE;
6156 }
6157 }
6158
6159 PQclear(res);
6160
6161 destroyPQExpBuffer(query);
6162}
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:8244
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:2042
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, _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 1236 of file pg_dump.c.

1237{
1238 printf(_("%s dumps a database as a text file or to other formats.\n\n"), progname);
1239 printf(_("Usage:\n"));
1240 printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
1241
1242 printf(_("\nGeneral options:\n"));
1243 printf(_(" -f, --file=FILENAME output file or directory name\n"));
1244 printf(_(" -F, --format=c|d|t|p output file format (custom, directory, tar,\n"
1245 " plain text (default))\n"));
1246 printf(_(" -j, --jobs=NUM use this many parallel jobs to dump\n"));
1247 printf(_(" -v, --verbose verbose mode\n"));
1248 printf(_(" -V, --version output version information, then exit\n"));
1249 printf(_(" -Z, --compress=METHOD[:DETAIL]\n"
1250 " compress as specified\n"));
1251 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
1252 printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
1253 printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
1254 printf(_(" -?, --help show this help, then exit\n"));
1255
1256 printf(_("\nOptions controlling the output content:\n"));
1257 printf(_(" -a, --data-only dump only the data, not the schema or statistics\n"));
1258 printf(_(" -b, --large-objects include large objects in dump\n"));
1259 printf(_(" --blobs (same as --large-objects, deprecated)\n"));
1260 printf(_(" -B, --no-large-objects exclude large objects in dump\n"));
1261 printf(_(" --no-blobs (same as --no-large-objects, deprecated)\n"));
1262 printf(_(" -c, --clean clean (drop) database objects before recreating\n"));
1263 printf(_(" -C, --create include commands to create database in dump\n"));
1264 printf(_(" -e, --extension=PATTERN dump the specified extension(s) only\n"));
1265 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
1266 printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n"));
1267 printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
1268 printf(_(" -O, --no-owner skip restoration of object ownership in\n"
1269 " plain-text format\n"));
1270 printf(_(" -s, --schema-only dump only the schema, no data or statistics\n"));
1271 printf(_(" -S, --superuser=NAME superuser user name to use in plain-text format\n"));
1272 printf(_(" -t, --table=PATTERN dump only the specified table(s)\n"));
1273 printf(_(" -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n"));
1274 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
1275 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
1276 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
1277 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
1278 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
1279 printf(_(" --enable-row-security enable row security (dump only content user has\n"
1280 " access to)\n"));
1281 printf(_(" --exclude-extension=PATTERN do NOT dump the specified extension(s)\n"));
1282 printf(_(" --exclude-table-and-children=PATTERN\n"
1283 " do NOT dump the specified table(s), including\n"
1284 " child and partition tables\n"));
1285 printf(_(" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
1286 printf(_(" --exclude-table-data-and-children=PATTERN\n"
1287 " do NOT dump data for the specified table(s),\n"
1288 " including child and partition tables\n"));
1289 printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
1290 printf(_(" --filter=FILENAME include or exclude objects and data from dump\n"
1291 " based on expressions in FILENAME\n"));
1292 printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
1293 printf(_(" --include-foreign-data=PATTERN\n"
1294 " include data of foreign tables on foreign\n"
1295 " servers matching PATTERN\n"));
1296 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
1297 printf(_(" --load-via-partition-root load partitions via the root table\n"));
1298 printf(_(" --no-comments do not dump comment commands\n"));
1299 printf(_(" --no-data do not dump data\n"));
1300 printf(_(" --no-policies do not dump row security policies\n"));
1301 printf(_(" --no-publications do not dump publications\n"));
1302 printf(_(" --no-schema do not dump schema\n"));
1303 printf(_(" --no-security-labels do not dump security label assignments\n"));
1304 printf(_(" --no-statistics do not dump statistics\n"));
1305 printf(_(" --no-subscriptions do not dump subscriptions\n"));
1306 printf(_(" --no-table-access-method do not dump table access methods\n"));
1307 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
1308 printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
1309 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
1310 printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
1311 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
1312 printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
1313 printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
1314 printf(_(" --sequence-data include sequence data in dump\n"));
1315 printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
1316 printf(_(" --snapshot=SNAPSHOT use given snapshot for the dump\n"));
1317 printf(_(" --statistics-only dump only the statistics, not schema or data\n"));
1318 printf(_(" --strict-names require table and/or schema include patterns to\n"
1319 " match at least one entity each\n"));
1320 printf(_(" --table-and-children=PATTERN dump only the specified table(s), including\n"
1321 " child and partition tables\n"));
1322 printf(_(" --use-set-session-authorization\n"
1323 " use SET SESSION AUTHORIZATION commands instead of\n"
1324 " ALTER OWNER commands to set ownership\n"));
1325 printf(_(" --with-data dump the data\n"));
1326 printf(_(" --with-schema dump the schema\n"));
1327 printf(_(" --with-statistics dump the statistics\n"));
1328
1329 printf(_("\nConnection options:\n"));
1330 printf(_(" -d, --dbname=DBNAME database to dump\n"));
1331 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
1332 printf(_(" -p, --port=PORT database server port number\n"));
1333 printf(_(" -U, --username=NAME connect as specified database user\n"));
1334 printf(_(" -w, --no-password never prompt for password\n"));
1335 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
1336 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
1337
1338 printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
1339 "variable value is used.\n\n"));
1340 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1341 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1342}
#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 4899 of file pg_dump.c.

4900{
4901 ArchiveHandle *AH = (ArchiveHandle *) fout;
4902 const char *val;
4903
4904 val = PQparameterStatus(AH->connection, "is_superuser");
4905
4906 if (val && strcmp(val, "on") == 0)
4907 return true;
4908
4909 return false;
4910}
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7584
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 410 of file pg_dump.c.

411{
412 int c;
413 const char *filename = NULL;
414 const char *format = "p";
415 TableInfo *tblinfo;
416 int numTables;
417 DumpableObject **dobjs;
418 int numObjs;
419 DumpableObject *boundaryObjs;
420 int i;
421 int optindex;
422 RestoreOptions *ropt;
423 Archive *fout; /* the script file */
424 bool g_verbose = false;
425 const char *dumpencoding = NULL;
426 const char *dumpsnapshot = NULL;
427 char *use_role = NULL;
428 int numWorkers = 1;
429 int plainText = 0;
430 ArchiveFormat archiveFormat = archUnknown;
431 ArchiveMode archiveMode;
432 pg_compress_specification compression_spec = {0};
433 char *compression_detail = NULL;
434 char *compression_algorithm_str = "none";
435 char *error_detail = NULL;
436 bool user_compression_defined = false;
438 bool data_only = false;
439 bool schema_only = false;
440 bool statistics_only = false;
441 bool with_data = false;
442 bool with_schema = false;
443 bool with_statistics = false;
444 bool no_data = false;
445 bool no_schema = false;
446 bool no_statistics = false;
447
448 static DumpOptions dopt;
449
450 static struct option long_options[] = {
451 {"data-only", no_argument, NULL, 'a'},
452 {"blobs", no_argument, NULL, 'b'},
453 {"large-objects", no_argument, NULL, 'b'},
454 {"no-blobs", no_argument, NULL, 'B'},
455 {"no-large-objects", no_argument, NULL, 'B'},
456 {"clean", no_argument, NULL, 'c'},
457 {"create", no_argument, NULL, 'C'},
458 {"dbname", required_argument, NULL, 'd'},
459 {"extension", required_argument, NULL, 'e'},
460 {"file", required_argument, NULL, 'f'},
461 {"format", required_argument, NULL, 'F'},
462 {"host", required_argument, NULL, 'h'},
463 {"jobs", 1, NULL, 'j'},
464 {"no-reconnect", no_argument, NULL, 'R'},
465 {"no-owner", no_argument, NULL, 'O'},
466 {"port", required_argument, NULL, 'p'},
467 {"schema", required_argument, NULL, 'n'},
468 {"exclude-schema", required_argument, NULL, 'N'},
469 {"schema-only", no_argument, NULL, 's'},
470 {"superuser", required_argument, NULL, 'S'},
471 {"table", required_argument, NULL, 't'},
472 {"exclude-table", required_argument, NULL, 'T'},
473 {"no-password", no_argument, NULL, 'w'},
474 {"password", no_argument, NULL, 'W'},
475 {"username", required_argument, NULL, 'U'},
476 {"verbose", no_argument, NULL, 'v'},
477 {"no-privileges", no_argument, NULL, 'x'},
478 {"no-acl", no_argument, NULL, 'x'},
479 {"compress", required_argument, NULL, 'Z'},
480 {"encoding", required_argument, NULL, 'E'},
481 {"help", no_argument, NULL, '?'},
482 {"version", no_argument, NULL, 'V'},
483
484 /*
485 * the following options don't have an equivalent short option letter
486 */
487 {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
488 {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
489 {"column-inserts", no_argument, &dopt.column_inserts, 1},
490 {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
491 {"disable-triggers", no_argument, &dopt.disable_triggers, 1},
492 {"enable-row-security", no_argument, &dopt.enable_row_security, 1},
493 {"exclude-table-data", required_argument, NULL, 4},
494 {"extra-float-digits", required_argument, NULL, 8},
495 {"if-exists", no_argument, &dopt.if_exists, 1},
496 {"inserts", no_argument, NULL, 9},
497 {"lock-wait-timeout", required_argument, NULL, 2},
498 {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1},
499 {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
500 {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
501 {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1},
502 {"role", required_argument, NULL, 3},
503 {"section", required_argument, NULL, 5},
504 {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
505 {"snapshot", required_argument, NULL, 6},
506 {"statistics-only", no_argument, NULL, 18},
507 {"strict-names", no_argument, &strict_names, 1},
508 {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
509 {"no-comments", no_argument, &dopt.no_comments, 1},
510 {"no-data", no_argument, NULL, 19},
511 {"no-policies", no_argument, &dopt.no_policies, 1},
512 {"no-publications", no_argument, &dopt.no_publications, 1},
513 {"no-schema", no_argument, NULL, 20},
514 {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
515 {"no-statistics", no_argument, NULL, 21},
516 {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
517 {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
518 {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
519 {"no-sync", no_argument, NULL, 7},
520 {"with-data", no_argument, NULL, 22},
521 {"with-schema", no_argument, NULL, 23},
522 {"with-statistics", no_argument, NULL, 24},
523 {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
524 {"rows-per-insert", required_argument, NULL, 10},
525 {"include-foreign-data", required_argument, NULL, 11},
526 {"table-and-children", required_argument, NULL, 12},
527 {"exclude-table-and-children", required_argument, NULL, 13},
528 {"exclude-table-data-and-children", required_argument, NULL, 14},
529 {"sync-method", required_argument, NULL, 15},
530 {"filter", required_argument, NULL, 16},
531 {"exclude-extension", required_argument, NULL, 17},
532 {"sequence-data", no_argument, &dopt.sequence_data, 1},
533
534 {NULL, 0, NULL, 0}
535 };
536
537 pg_logging_init(argv[0]);
539 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
540
541 /*
542 * Initialize what we need for parallel execution, especially for thread
543 * support on Windows.
544 */
546
547 progname = get_progname(argv[0]);
548
549 if (argc > 1)
550 {
551 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
552 {
553 help(progname);
554 exit_nicely(0);
555 }
556 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
557 {
558 puts("pg_dump (PostgreSQL) " PG_VERSION);
559 exit_nicely(0);
560 }
561 }
562
563 InitDumpOptions(&dopt);
564
565 while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxXZ:",
566 long_options, &optindex)) != -1)
567 {
568 switch (c)
569 {
570 case 'a': /* Dump data only */
571 data_only = true;
572 break;
573
574 case 'b': /* Dump LOs */
575 dopt.outputLOs = true;
576 break;
577
578 case 'B': /* Don't dump LOs */
579 dopt.dontOutputLOs = true;
580 break;
581
582 case 'c': /* clean (i.e., drop) schema prior to create */
583 dopt.outputClean = 1;
584 break;
585
586 case 'C': /* Create DB */
587 dopt.outputCreateDB = 1;
588 break;
589
590 case 'd': /* database name */
592 break;
593
594 case 'e': /* include extension(s) */
596 dopt.include_everything = false;
597 break;
598
599 case 'E': /* Dump encoding */
600 dumpencoding = pg_strdup(optarg);
601 break;
602
603 case 'f':
605 break;
606
607 case 'F':
609 break;
610
611 case 'h': /* server host */
613 break;
614
615 case 'j': /* number of dump jobs */
616 if (!option_parse_int(optarg, "-j/--jobs", 1,
618 &numWorkers))
619 exit_nicely(1);
620 break;
621
622 case 'n': /* include schema(s) */
624 dopt.include_everything = false;
625 break;
626
627 case 'N': /* exclude schema(s) */
629 break;
630
631 case 'O': /* Don't reconnect to match owner */
632 dopt.outputNoOwner = 1;
633 break;
634
635 case 'p': /* server port */
637 break;
638
639 case 'R':
640 /* no-op, still accepted for backwards compatibility */
641 break;
642
643 case 's': /* dump schema only */
644 schema_only = true;
645 break;
646
647 case 'S': /* Username for superuser in plain text output */
649 break;
650
651 case 't': /* include table(s) */
653 dopt.include_everything = false;
654 break;
655
656 case 'T': /* exclude table(s) */
658 break;
659
660 case 'U':
662 break;
663
664 case 'v': /* verbose */
665 g_verbose = true;
667 break;
668
669 case 'w':
671 break;
672
673 case 'W':
675 break;
676
677 case 'x': /* skip ACL dump */
678 dopt.aclsSkip = true;
679 break;
680
681 case 'Z': /* Compression */
682 parse_compress_options(optarg, &compression_algorithm_str,
683 &compression_detail);
684 user_compression_defined = true;
685 break;
686
687 case 0:
688 /* This covers the long options. */
689 break;
690
691 case 2: /* lock-wait-timeout */
693 break;
694
695 case 3: /* SET ROLE */
696 use_role = pg_strdup(optarg);
697 break;
698
699 case 4: /* exclude table(s) data */
701 break;
702
703 case 5: /* section */
705 break;
706
707 case 6: /* snapshot */
708 dumpsnapshot = pg_strdup(optarg);
709 break;
710
711 case 7: /* no-sync */
712 dosync = false;
713 break;
714
715 case 8:
717 if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
719 exit_nicely(1);
720 break;
721
722 case 9: /* inserts */
723
724 /*
725 * dump_inserts also stores --rows-per-insert, careful not to
726 * overwrite that.
727 */
728 if (dopt.dump_inserts == 0)
730 break;
731
732 case 10: /* rows per insert */
733 if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
734 &dopt.dump_inserts))
735 exit_nicely(1);
736 break;
737
738 case 11: /* include foreign data */
740 optarg);
741 break;
742
743 case 12: /* include table(s) and their children */
745 optarg);
746 dopt.include_everything = false;
747 break;
748
749 case 13: /* exclude table(s) and their children */
751 optarg);
752 break;
753
754 case 14: /* exclude data of table(s) and children */
756 optarg);
757 break;
758
759 case 15:
761 exit_nicely(1);
762 break;
763
764 case 16: /* read object filters from file */
766 break;
767
768 case 17: /* exclude extension(s) */
770 optarg);
771 break;
772
773 case 18:
774 statistics_only = true;
775 break;
776
777 case 19:
778 no_data = true;
779 break;
780
781 case 20:
782 no_schema = true;
783 break;
784
785 case 21:
786 no_statistics = true;
787 break;
788
789 case 22:
790 with_data = true;
791 break;
792
793 case 23:
794 with_schema = true;
795 break;
796
797 case 24:
798 with_statistics = true;
799 break;
800
801 default:
802 /* getopt_long already emitted a complaint */
803 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
804 exit_nicely(1);
805 }
806 }
807
808 /*
809 * Non-option argument specifies database name as long as it wasn't
810 * already specified with -d / --dbname
811 */
812 if (optind < argc && dopt.cparams.dbname == NULL)
813 dopt.cparams.dbname = argv[optind++];
814
815 /* Complain if any arguments remain */
816 if (optind < argc)
817 {
818 pg_log_error("too many command-line arguments (first is \"%s\")",
819 argv[optind]);
820 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
821 exit_nicely(1);
822 }
823
824 /* --column-inserts implies --inserts */
825 if (dopt.column_inserts && dopt.dump_inserts == 0)
827
828 /* reject conflicting "-only" options */
829 if (data_only && schema_only)
830 pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
831 if (schema_only && statistics_only)
832 pg_fatal("options -s/--schema-only and --statistics-only cannot be used together");
833 if (data_only && statistics_only)
834 pg_fatal("options -a/--data-only and --statistics-only cannot be used together");
835
836 /* reject conflicting "-only" and "no-" options */
837 if (data_only && no_data)
838 pg_fatal("options -a/--data-only and --no-data cannot be used together");
839 if (schema_only && no_schema)
840 pg_fatal("options -s/--schema-only and --no-schema cannot be used together");
842 pg_fatal("options --statistics-only and --no-statistics cannot be used together");
843
844 /* reject conflicting "with-" and "no-" options */
845 if (with_data && no_data)
846 pg_fatal("options --with-data and --no-data cannot be used together");
847 if (with_schema && no_schema)
848 pg_fatal("options --with-schema and --no-schema cannot be used together");
850 pg_fatal("options --with-statistics and --no-statistics cannot be used together");
851
852 if (schema_only && foreign_servers_include_patterns.head != NULL)
853 pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
854
855 if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
856 pg_fatal("option --include-foreign-data is not supported with parallel backup");
857
858 if (data_only && dopt.outputClean)
859 pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
860
861 if (dopt.if_exists && !dopt.outputClean)
862 pg_fatal("option --if-exists requires option -c/--clean");
863
864 /*
865 * Set derivative flags. An "-only" option may be overridden by an
866 * explicit "with-" option; e.g. "--schema-only --with-statistics" will
867 * include schema and statistics. Other ambiguous or nonsensical
868 * combinations, e.g. "--schema-only --no-schema", will have already
869 * caused an error in one of the checks above.
870 */
871 dopt.dumpData = ((dopt.dumpData && !schema_only && !statistics_only) ||
872 (data_only || with_data)) && !no_data;
873 dopt.dumpSchema = ((dopt.dumpSchema && !data_only && !statistics_only) ||
874 (schema_only || with_schema)) && !no_schema;
875 dopt.dumpStatistics = ((dopt.dumpStatistics && !schema_only && !data_only) ||
877
878
879 /*
880 * --inserts are already implied above if --column-inserts or
881 * --rows-per-insert were specified.
882 */
883 if (dopt.do_nothing && dopt.dump_inserts == 0)
884 pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
885
886 /* Identify archive format to emit */
887 archiveFormat = parseArchiveFormat(format, &archiveMode);
888
889 /* archiveFormat specific setup */
890 if (archiveFormat == archNull)
891 plainText = 1;
892
893 /*
894 * Custom and directory formats are compressed by default with gzip when
895 * available, not the others. If gzip is not available, no compression is
896 * done by default.
897 */
898 if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
899 !user_compression_defined)
900 {
901#ifdef HAVE_LIBZ
902 compression_algorithm_str = "gzip";
903#else
904 compression_algorithm_str = "none";
905#endif
906 }
907
908 /*
909 * Compression options
910 */
911 if (!parse_compress_algorithm(compression_algorithm_str,
913 pg_fatal("unrecognized compression algorithm: \"%s\"",
914 compression_algorithm_str);
915
917 &compression_spec);
918 error_detail = validate_compress_specification(&compression_spec);
919 if (error_detail != NULL)
920 pg_fatal("invalid compression specification: %s",
921 error_detail);
922
923 error_detail = supports_compression(compression_spec);
924 if (error_detail != NULL)
925 pg_fatal("%s", error_detail);
926
927 /*
928 * Disable support for zstd workers for now - these are based on
929 * threading, and it's unclear how it interacts with parallel dumps on
930 * platforms where that relies on threads too (e.g. Windows).
931 */
932 if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
933 pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
934 "workers");
935
936 /*
937 * If emitting an archive format, we always want to emit a DATABASE item,
938 * in case --create is specified at pg_restore time.
939 */
940 if (!plainText)
941 dopt.outputCreateDB = 1;
942
943 /* Parallel backup only in the directory archive format so far */
944 if (archiveFormat != archDirectory && numWorkers > 1)
945 pg_fatal("parallel backup only supported by the directory format");
946
947 /* Open the output file */
948 fout = CreateArchive(filename, archiveFormat, compression_spec,
949 dosync, archiveMode, setupDumpWorker, sync_method);
950
951 /* Make dump options accessible right away */
952 SetArchiveOptions(fout, &dopt, NULL);
953
954 /* Register the cleanup hook */
956
957 /* Let the archiver know how noisy to be */
958 fout->verbose = g_verbose;
959
960
961 /*
962 * We allow the server to be back to 9.2, and up to any minor release of
963 * our own major version. (See also version check in pg_dumpall.c.)
964 */
965 fout->minRemoteVersion = 90200;
966 fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
967
968 fout->numWorkers = numWorkers;
969
970 /*
971 * Open the database using the Archiver, so it knows about it. Errors mean
972 * death.
973 */
974 ConnectDatabaseAhx(fout, &dopt.cparams, false);
975 setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
976
977 /*
978 * On hot standbys, never try to dump unlogged table data, since it will
979 * just throw an error.
980 */
981 if (fout->isStandby)
982 dopt.no_unlogged_table_data = true;
983
984 /*
985 * Find the last built-in OID, if needed (prior to 8.1)
986 *
987 * With 8.1 and above, we can just use FirstNormalObjectId - 1.
988 */
990
991 pg_log_info("last built-in OID is %u", g_last_builtin_oid);
992
993 /* Expand schema selection patterns into OID lists */
994 if (schema_include_patterns.head != NULL)
995 {
999 if (schema_include_oids.head == NULL)
1000 pg_fatal("no matching schemas were found");
1001 }
1004 false);
1005 /* non-matching exclusion patterns aren't an error */
1006
1007 /* Expand table selection patterns into OID lists */
1010 strict_names, false);
1013 strict_names, true);
1014 if ((table_include_patterns.head != NULL ||
1016 table_include_oids.head == NULL)
1017 pg_fatal("no matching tables were found");
1018
1021 false, false);
1024 false, true);
1025
1028 false, false);
1031 false, true);
1032
1035
1036 /* non-matching exclusion patterns aren't an error */
1037
1038 /* Expand extension selection patterns into OID lists */
1039 if (extension_include_patterns.head != NULL)
1040 {
1043 strict_names);
1044 if (extension_include_oids.head == NULL)
1045 pg_fatal("no matching extensions were found");
1046 }
1049 false);
1050 /* non-matching exclusion patterns aren't an error */
1051
1052 /*
1053 * Dumping LOs is the default for dumps where an inclusion switch is not
1054 * used (an "include everything" dump). -B can be used to exclude LOs
1055 * from those dumps. -b can be used to include LOs even when an inclusion
1056 * switch is used.
1057 *
1058 * -s means "schema only" and LOs are data, not schema, so we never
1059 * include LOs when -s is used.
1060 */
1061 if (dopt.include_everything && dopt.dumpData && !dopt.dontOutputLOs)
1062 dopt.outputLOs = true;
1063
1064 /*
1065 * Collect role names so we can map object owner OIDs to names.
1066 */
1067 collectRoleNames(fout);
1068
1069 /*
1070 * Now scan the database and create DumpableObject structs for all the
1071 * objects we intend to dump.
1072 */
1073 tblinfo = getSchemaData(fout, &numTables);
1074
1075 if (dopt.dumpData)
1076 {
1077 getTableData(&dopt, tblinfo, numTables, 0);
1079 if (!dopt.dumpSchema)
1081 }
1082
1083 if (!dopt.dumpData && dopt.sequence_data)
1084 getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
1085
1086 /*
1087 * In binary-upgrade mode, we do not have to worry about the actual LO
1088 * data or the associated metadata that resides in the pg_largeobject and
1089 * pg_largeobject_metadata tables, respectively.
1090 *
1091 * However, we do need to collect LO information as there may be comments
1092 * or other information on LOs that we do need to dump out.
1093 */
1094 if (dopt.outputLOs || dopt.binary_upgrade)
1095 getLOs(fout);
1096
1097 /*
1098 * Collect dependency data to assist in ordering the objects.
1099 */
1100 getDependencies(fout);
1101
1102 /*
1103 * Collect ACLs, comments, and security labels, if wanted.
1104 */
1105 if (!dopt.aclsSkip)
1106 getAdditionalACLs(fout);
1107 if (!dopt.no_comments)
1108 collectComments(fout);
1109 if (!dopt.no_security_labels)
1110 collectSecLabels(fout);
1111
1112 /* For binary upgrade mode, collect required pg_class information. */
1113 if (dopt.binary_upgrade)
1115
1116 /* Collect sequence information. */
1117 collectSequences(fout);
1118
1119 /* Lastly, create dummy objects to represent the section boundaries */
1120 boundaryObjs = createBoundaryObjects();
1121
1122 /* Get pointers to all the known DumpableObjects */
1123 getDumpableObjects(&dobjs, &numObjs);
1124
1125 /*
1126 * Add dummy dependencies to enforce the dump section ordering.
1127 */
1128 addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
1129
1130 /*
1131 * Sort the objects into a safe dump order (no forward references).
1132 *
1133 * We rely on dependency information to help us determine a safe order, so
1134 * the initial sort is mostly for cosmetic purposes: we sort by name to
1135 * ensure that logically identical schemas will dump identically.
1136 */
1137 sortDumpableObjectsByTypeName(dobjs, numObjs);
1138
1139 sortDumpableObjects(dobjs, numObjs,
1140 boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
1141
1142 /*
1143 * Create archive TOC entries for all the objects to be dumped, in a safe
1144 * order.
1145 */
1146
1147 /*
1148 * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
1149 */
1150 dumpEncoding(fout);
1151 dumpStdStrings(fout);
1152 dumpSearchPath(fout);
1153
1154 /* The database items are always next, unless we don't want them at all */
1155 if (dopt.outputCreateDB)
1156 dumpDatabase(fout);
1157
1158 /* Now the rearrangeable objects. */
1159 for (i = 0; i < numObjs; i++)
1160 dumpDumpableObject(fout, dobjs[i]);
1161
1162 /*
1163 * Set up options info to ensure we dump what we want.
1164 */
1165 ropt = NewRestoreOptions();
1166 ropt->filename = filename;
1167
1168 /* if you change this list, see dumpOptionsFromRestoreOptions */
1169 ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
1170 ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
1171 ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
1172 ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
1174 ropt->dropSchema = dopt.outputClean;
1175 ropt->dumpData = dopt.dumpData;
1176 ropt->dumpSchema = dopt.dumpSchema;
1177 ropt->dumpStatistics = dopt.dumpStatistics;
1178 ropt->if_exists = dopt.if_exists;
1179 ropt->column_inserts = dopt.column_inserts;
1180 ropt->dumpSections = dopt.dumpSections;
1181 ropt->aclsSkip = dopt.aclsSkip;
1182 ropt->superuser = dopt.outputSuperuser;
1183 ropt->createDB = dopt.outputCreateDB;
1184 ropt->noOwner = dopt.outputNoOwner;
1185 ropt->noTableAm = dopt.outputNoTableAm;
1186 ropt->noTablespace = dopt.outputNoTablespaces;
1188 ropt->use_setsessauth = dopt.use_setsessauth;
1190 ropt->dump_inserts = dopt.dump_inserts;
1191 ropt->no_comments = dopt.no_comments;
1192 ropt->no_policies = dopt.no_policies;
1193 ropt->no_publications = dopt.no_publications;
1196 ropt->lockWaitTimeout = dopt.lockWaitTimeout;
1199 ropt->sequence_data = dopt.sequence_data;
1200 ropt->binary_upgrade = dopt.binary_upgrade;
1201
1202 ropt->compression_spec = compression_spec;
1203
1204 ropt->suppressDumpWarnings = true; /* We've already shown them */
1205
1206 SetArchiveOptions(fout, &dopt, ropt);
1207
1208 /* Mark which entries should be output */
1210
1211 /*
1212 * The archive's TOC entries are now marked as to which ones will actually
1213 * be output, so we can set up their dependency lists properly. This isn't
1214 * necessary for plain-text output, though.
1215 */
1216 if (!plainText)
1218
1219 /*
1220 * And finally we can do the actual output.
1221 *
1222 * Note: for non-plain-text output formats, the output file is written
1223 * inside CloseArchive(). This is, um, bizarre; but not worth changing
1224 * right now.
1225 */
1226 if (plainText)
1227 RestoreArchive(fout, false);
1228
1229 CloseArchive(fout);
1230
1231 exit_nicely(0);
1232}
TableInfo * getSchemaData(Archive *fout, int *numTablesPtr)
Definition: common.c:97
void on_exit_close_archive(Archive *AHX)
Definition: parallel.c:330
void init_parallel_dump_utils(void)
Definition: parallel.c:238
#define PG_MAX_JOBS
Definition: parallel.h:48
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1185
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:429
char * supports_compression(const pg_compress_specification compression_spec)
Definition: compress_io.c:87
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)
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 RestoreArchive(Archive *AHX, bool append_data)
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)
@ 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:1582
static void dumpEncoding(Archive *AH)
Definition: pg_dump.c:3707
static SimpleStringList schema_include_patterns
Definition: pg_dump.c:162
static void collectBinaryUpgradeClassOids(Archive *fout)
Definition: pg_dump.c:5627
static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
Definition: pg_dump.c:19722
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3756
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:19698
static void dumpDatabase(Archive *fout)
Definition: pg_dump.c:3191
static SimpleStringList table_include_patterns
Definition: pg_dump.c:167
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:165
static bool have_extra_float_digits
Definition: pg_dump.c:189
static SimpleOidList extension_include_oids
Definition: pg_dump.c:181
static int extra_float_digits
Definition: pg_dump.c:190
static SimpleStringList extension_include_patterns
Definition: pg_dump.c:180
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:184
static SimpleStringList table_exclude_patterns
Definition: pg_dump.c:170
static pg_compress_algorithm compression_algorithm
Definition: pg_dump.c:154
static void dumpStdStrings(Archive *AH)
Definition: pg_dump.c:3732
static void help(const char *progname)
Definition: pg_dump.c:1236
static void BuildArchiveDependencies(Archive *fout)
Definition: pg_dump.c:19848
static void collectRoleNames(Archive *fout)
Definition: pg_dump.c:10432
static bool dosync
Definition: pg_dump.c:147
static void getDependencies(Archive *fout)
Definition: pg_dump.c:19545
static void buildMatViewRefreshDependencies(Archive *fout)
Definition: pg_dump.c:3035
#define DUMP_DEFAULT_ROWS_PER_INSERT
Definition: pg_dump.c:219
static SimpleStringList foreign_servers_include_patterns
Definition: pg_dump.c:177
static void setupDumpWorker(Archive *AH)
Definition: pg_dump.c:1515
static SimpleStringList table_include_patterns_and_children
Definition: pg_dump.c:168
static void getAdditionalACLs(Archive *fout)
Definition: pg_dump.c:10467
static void getTableDataFKConstraints(void)
Definition: pg_dump.c:3150
static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
Definition: pg_dump.c:2929
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:172
static void collectComments(Archive *fout)
Definition: pg_dump.c:11292
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:11377
static void getLOs(Archive *fout)
Definition: pg_dump.c:3818
static void setup_connection(Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role)
Definition: pg_dump.c:1345
static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names, bool with_child_tables)
Definition: pg_dump.c:1746
static void expand_foreign_server_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
Definition: pg_dump.c:1694
static SimpleStringList extension_exclude_patterns
Definition: pg_dump.c:183
static SimpleOidList table_include_oids
Definition: pg_dump.c:169
static SimpleStringList tabledata_exclude_patterns
Definition: pg_dump.c:173
static void collectSecLabels(Archive *fout)
Definition: pg_dump.c:16442
static void collectSequences(Archive *fout)
Definition: pg_dump.c:18501
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode)
Definition: pg_dump.c:1544
static void read_dump_filters(const char *filename, DumpOptions *dopt)
Definition: pg_dump.c:20068
static SimpleStringList tabledata_exclude_patterns_and_children
Definition: pg_dump.c:174
static SimpleOidList tabledata_exclude_oids
Definition: pg_dump.c:175
static SimpleStringList table_exclude_patterns_and_children
Definition: pg_dump.c:171
static SimpleOidList foreign_servers_include_oids
Definition: pg_dump.c:178
static void expand_extension_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names)
Definition: pg_dump.c:1641
static SimpleOidList schema_include_oids
Definition: pg_dump.c:163
static SimpleStringList schema_exclude_patterns
Definition: pg_dump.c:164
void sortDumpableObjects(DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId)
Definition: pg_dump_sort.c:334
void sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
Definition: pg_dump_sort.c:190
static int statistics_only
Definition: pg_dumpall.c:116
static int with_data
Definition: pg_dumpall.c:110
static int with_schema
Definition: pg_dumpall.c:111
static int no_statistics
Definition: pg_dumpall.c:105
static int no_data
Definition: pg_dumpall.c:103
static int no_schema
Definition: pg_dumpall.c:104
static char * filename
Definition: pg_dumpall.c:124
static int with_statistics
Definition: pg_dumpall.c:112
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:232
bool isStandby
Definition: pg_backup.h:230
int maxRemoteVersion
Definition: pg_backup.h:233
int numWorkers
Definition: pg_backup.h:235
int verbose
Definition: pg_backup.h:227
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
bool dontOutputLOs
Definition: pg_backup.h:205
int use_setsessauth
Definition: pg_backup.h:195
int outputCreateDB
Definition: pg_backup.h:203
bool include_everything
Definition: pg_backup.h:200
bool outputLOs
Definition: pg_backup.h:204
int serializable_deferrable
Definition: pg_backup.h:191
int outputNoTableAm
Definition: pg_backup.h:193
int enable_row_security
Definition: pg_backup.h:196
char * outputSuperuser
Definition: pg_backup.h:207
int dumpSections
Definition: pg_backup.h:175
int no_unlogged_table_data
Definition: pg_backup.h:190
ConnParams cparams
Definition: pg_backup.h:170
int outputClean
Definition: pg_backup.h:202
int disable_triggers
Definition: pg_backup.h:192
int outputNoOwner
Definition: pg_backup.h:206
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
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(), 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, CreateArchive(), createBoundaryObjects(), _restoreOptions::createDB, DATA_DIR_SYNC_METHOD_FSYNC, _connParams::dbname, _restoreOptions::disable_dollar_quoting, _dumpOptions::disable_dollar_quoting, _restoreOptions::disable_triggers, _dumpOptions::disable_triggers, _dumpOptions::do_nothing, _dumpOptions::dontOutputLOs, dosync, _restoreOptions::dropSchema, DUMP_DEFAULT_ROWS_PER_INSERT, _restoreOptions::dump_inserts, _dumpOptions::dump_inserts, _restoreOptions::dumpData, _dumpOptions::dumpData, dumpDatabase(), dumpDumpableObject(), dumpEncoding(), _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, FirstNormalObjectId, foreign_servers_include_oids, foreign_servers_include_patterns, format, g_last_builtin_oid, get_progname(), getAdditionalACLs(), getDependencies(), getDumpableObjects(), getLOs(), getopt_long(), getSchemaData(), getTableData(), getTableDataFKConstraints(), have_extra_float_digits, SimpleOidList::head, SimpleStringList::head, help(), i, _restoreOptions::if_exists, _dumpOptions::if_exists, _restoreOptions::include_everything, _dumpOptions::include_everything, init_parallel_dump_utils(), InitDumpOptions(), Archive::isStandby, _dumpOptions::load_via_partition_root, _restoreOptions::lockWaitTimeout, _dumpOptions::lockWaitTimeout, Archive::maxRemoteVersion, Archive::minRemoteVersion, NewRestoreOptions(), no_argument, _restoreOptions::no_comments, _dumpOptions::no_comments, 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(), required_argument, RestoreArchive(), 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, validate_compress_specification(), Archive::verbose, with_data, with_schema, and with_statistics.

◆ makeTableDataInfo()

static void makeTableDataInfo ( DumpOptions dopt,
TableInfo tbinfo 
)
static

Definition at line 2948 of file pg_dump.c.

2949{
2950 TableDataInfo *tdinfo;
2951
2952 /*
2953 * Nothing to do if we already decided to dump the table. This will
2954 * happen for "config" tables.
2955 */
2956 if (tbinfo->dataObj != NULL)
2957 return;
2958
2959 /* Skip VIEWs (no data to dump) */
2960 if (tbinfo->relkind == RELKIND_VIEW)
2961 return;
2962 /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
2963 if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
2966 tbinfo->foreign_server)))
2967 return;
2968 /* Skip partitioned tables (data in partitions) */
2969 if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
2970 return;
2971
2972 /* Don't dump data in unlogged tables, if so requested */
2973 if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
2975 return;
2976
2977 /* Check that the data is not explicitly excluded */
2979 tbinfo->dobj.catId.oid))
2980 return;
2981
2982 /* OK, let's dump it */
2983 tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
2984
2985 if (tbinfo->relkind == RELKIND_MATVIEW)
2987 else if (tbinfo->relkind == RELKIND_SEQUENCE)
2988 tdinfo->dobj.objType = DO_SEQUENCE_SET;
2989 else
2990 tdinfo->dobj.objType = DO_TABLE_DATA;
2991
2992 /*
2993 * Note: use tableoid 0 so that this object won't be mistaken for
2994 * something that pg_depend entries apply to.
2995 */
2996 tdinfo->dobj.catId.tableoid = 0;
2997 tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
2998 AssignDumpId(&tdinfo->dobj);
2999 tdinfo->dobj.name = tbinfo->dobj.name;
3000 tdinfo->dobj.namespace = tbinfo->dobj.namespace;
3001 tdinfo->tdtable = tbinfo;
3002 tdinfo->filtercond = NULL; /* might get set later */
3003 addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
3004
3005 /* A TableDataInfo contains data, of course */
3007
3008 tbinfo->dataObj = tdinfo;
3009
3010 /*
3011 * Materialized view statistics must be restored after the data, because
3012 * REFRESH MATERIALIZED VIEW replaces the storage and resets the stats.
3013 *
3014 * The dependency is added here because the statistics objects are created
3015 * first.
3016 */
3017 if (tbinfo->relkind == RELKIND_MATVIEW && tbinfo->stats != NULL)
3018 {
3019 tbinfo->stats->section = SECTION_POST_DATA;
3020 addObjectDependency(&tbinfo->stats->dobj, tdinfo->dobj.dumpId);
3021 }
3022
3023 /* Make sure that we'll collect per-column info for this table. */
3024 tbinfo->interesting = true;
3025}
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(), and processExtensionTables().

◆ nonemptyReloptions()

static bool nonemptyReloptions ( const char *  reloptions)
static

Definition at line 20037 of file pg_dump.c.

20038{
20039 /* Don't want to print it if it's just "{}" */
20040 return (reloptions != NULL && strlen(reloptions) > 2);
20041}

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

◆ parse_sequence_type()

static SeqType parse_sequence_type ( const char *  name)
inlinestatic

Definition at line 18470 of file pg_dump.c.

18471{
18472 for (int i = 0; i < lengthof(SeqTypeNames); i++)
18473 {
18474 if (strcmp(SeqTypeNames[i], name) == 0)
18475 return (SeqType) i;
18476 }
18477
18478 pg_fatal("unrecognized sequence type: %s", name);
18479 return (SeqType) 0; /* keep compiler quiet */
18480}
#define lengthof(array)
Definition: c.h:759

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

1545{
1546 ArchiveFormat archiveFormat;
1547
1549
1550 if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
1551 {
1552 /* This is used by pg_dumpall, and is not documented */
1553 archiveFormat = archNull;
1555 }
1556 else if (pg_strcasecmp(format, "c") == 0)
1557 archiveFormat = archCustom;
1558 else if (pg_strcasecmp(format, "custom") == 0)
1559 archiveFormat = archCustom;
1560 else if (pg_strcasecmp(format, "d") == 0)
1561 archiveFormat = archDirectory;
1562 else if (pg_strcasecmp(format, "directory") == 0)
1563 archiveFormat = archDirectory;
1564 else if (pg_strcasecmp(format, "p") == 0)
1565 archiveFormat = archNull;
1566 else if (pg_strcasecmp(format, "plain") == 0)
1567 archiveFormat = archNull;
1568 else if (pg_strcasecmp(format, "t") == 0)
1569 archiveFormat = archTar;
1570 else if (pg_strcasecmp(format, "tar") == 0)
1571 archiveFormat = archTar;
1572 else
1573 pg_fatal("invalid output format \"%s\" specified", format);
1574 return archiveFormat;
1575}
@ archModeWrite
Definition: pg_backup.h:51
@ archModeAppend
Definition: pg_backup.h:50
static PgChecksumMode mode
Definition: pg_checksums.c:55

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

Referenced by main().

◆ processExtensionTables()

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

Definition at line 19364 of file pg_dump.c.

19366{
19367 DumpOptions *dopt = fout->dopt;
19368 PQExpBuffer query;
19369 PGresult *res;
19370 int ntups,
19371 i;
19372 int i_conrelid,
19373 i_confrelid;
19374
19375 /* Nothing to do if no extensions */
19376 if (numExtensions == 0)
19377 return;
19378
19379 /*
19380 * Identify extension configuration tables and create TableDataInfo
19381 * objects for them, ensuring their data will be dumped even though the
19382 * tables themselves won't be.
19383 *
19384 * Note that we create TableDataInfo objects even in schema-only mode, ie,
19385 * user data in a configuration table is treated like schema data. This
19386 * seems appropriate since system data in a config table would get
19387 * reloaded by CREATE EXTENSION. If the extension is not listed in the
19388 * list of extensions to be included, none of its data is dumped.
19389 */
19390 for (i = 0; i < numExtensions; i++)
19391 {
19392 ExtensionInfo *curext = &(extinfo[i]);
19393 char *extconfig = curext->extconfig;
19394 char *extcondition = curext->extcondition;
19395 char **extconfigarray = NULL;
19396 char **extconditionarray = NULL;
19397 int nconfigitems = 0;
19398 int nconditionitems = 0;
19399
19400 /*
19401 * Check if this extension is listed as to include in the dump. If
19402 * not, any table data associated with it is discarded.
19403 */
19404 if (extension_include_oids.head != NULL &&
19406 curext->dobj.catId.oid))
19407 continue;
19408
19409 /*
19410 * Check if this extension is listed as to exclude in the dump. If
19411 * yes, any table data associated with it is discarded.
19412 */
19413 if (extension_exclude_oids.head != NULL &&
19415 curext->dobj.catId.oid))
19416 continue;
19417
19418 if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
19419 {
19420 int j;
19421
19422 if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
19423 pg_fatal("could not parse %s array", "extconfig");
19424 if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
19425 pg_fatal("could not parse %s array", "extcondition");
19426 if (nconfigitems != nconditionitems)
19427 pg_fatal("mismatched number of configurations and conditions for extension");
19428
19429 for (j = 0; j < nconfigitems; j++)
19430 {
19431 TableInfo *configtbl;
19432 Oid configtbloid = atooid(extconfigarray[j]);
19433 bool dumpobj =
19435
19436 configtbl = findTableByOid(configtbloid);
19437 if (configtbl == NULL)
19438 continue;
19439
19440 /*
19441 * Tables of not-to-be-dumped extensions shouldn't be dumped
19442 * unless the table or its schema is explicitly included
19443 */
19444 if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
19445 {
19446 /* check table explicitly requested */
19447 if (table_include_oids.head != NULL &&
19449 configtbloid))
19450 dumpobj = true;
19451
19452 /* check table's schema explicitly requested */
19453 if (configtbl->dobj.namespace->dobj.dump &
19455 dumpobj = true;
19456 }
19457
19458 /* check table excluded by an exclusion switch */
19459 if (table_exclude_oids.head != NULL &&
19461 configtbloid))
19462 dumpobj = false;
19463
19464 /* check schema excluded by an exclusion switch */
19466 configtbl->dobj.namespace->dobj.catId.oid))
19467 dumpobj = false;
19468
19469 if (dumpobj)
19470 {
19471 makeTableDataInfo(dopt, configtbl);
19472 if (configtbl->dataObj != NULL)
19473 {
19474 if (strlen(extconditionarray[j]) > 0)
19475 configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
19476 }
19477 }
19478 }
19479 }
19480 if (extconfigarray)
19481 free(extconfigarray);
19482 if (extconditionarray)
19483 free(extconditionarray);
19484 }
19485
19486 /*
19487 * Now that all the TableDataInfo objects have been created for all the
19488 * extensions, check their FK dependencies and register them to try and
19489 * dump the data out in an order that they can be restored in.
19490 *
19491 * Note that this is not a problem for user tables as their FKs are
19492 * recreated after the data has been loaded.
19493 */
19494
19495 query = createPQExpBuffer();
19496
19497 printfPQExpBuffer(query,
19498 "SELECT conrelid, confrelid "
19499 "FROM pg_constraint "
19500 "JOIN pg_depend ON (objid = confrelid) "
19501 "WHERE contype = 'f' "
19502 "AND refclassid = 'pg_extension'::regclass "
19503 "AND classid = 'pg_class'::regclass;");
19504
19505 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19506 ntups = PQntuples(res);
19507
19508 i_conrelid = PQfnumber(res, "conrelid");
19509 i_confrelid = PQfnumber(res, "confrelid");
19510
19511 /* Now get the dependencies and register them */
19512 for (i = 0; i < ntups; i++)
19513 {
19514 Oid conrelid,
19515 confrelid;
19516 TableInfo *reftable,
19517 *contable;
19518
19519 conrelid = atooid(PQgetvalue(res, i, i_conrelid));
19520 confrelid = atooid(PQgetvalue(res, i, i_confrelid));
19521 contable = findTableByOid(conrelid);
19522 reftable = findTableByOid(confrelid);
19523
19524 if (reftable == NULL ||
19525 reftable->dataObj == NULL ||
19526 contable == NULL ||
19527 contable->dataObj == NULL)
19528 continue;
19529
19530 /*
19531 * Make referencing TABLE_DATA object depend on the referenced table's
19532 * TABLE_DATA object.
19533 */
19534 addObjectDependency(&contable->dataObj->dobj,
19535 reftable->dataObj->dobj.dumpId);
19536 }
19537 PQclear(res);
19538 destroyPQExpBuffer(query);
19539}

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

1843{
1844 const char *db;
1845
1846 db = PQdb(conn);
1847 if (db == NULL)
1848 pg_fatal("You are currently not connected to a database.");
1849
1850 if (strcmp(db, dbname) != 0)
1851 pg_fatal("cross-database references are not implemented: %s",
1852 pattern);
1853}
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:7457

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

20069{
20070 FilterStateData fstate;
20071 char *objname;
20072 FilterCommandType comtype;
20073 FilterObjectType objtype;
20074
20075 filter_init(&fstate, filename, exit_nicely);
20076
20077 while (filter_read_item(&fstate, &objname, &comtype, &objtype))
20078 {
20079 if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
20080 {
20081 switch (objtype)
20082 {
20084 break;
20091 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20092 "include",
20093 filter_object_type_name(objtype));
20094 exit_nicely(1);
20095 break; /* unreachable */
20096
20099 break;
20102 break;
20105 dopt->include_everything = false;
20106 break;
20109 dopt->include_everything = false;
20110 break;
20113 objname);
20114 dopt->include_everything = false;
20115 break;
20116 }
20117 }
20118 else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
20119 {
20120 switch (objtype)
20121 {
20123 break;
20129 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20130 "exclude",
20131 filter_object_type_name(objtype));
20132 exit_nicely(1);
20133 break;
20134
20137 break;
20140 objname);
20141 break;
20144 objname);
20145 break;
20148 break;
20151 break;
20154 objname);
20155 break;
20156 }
20157 }
20158 else
20159 {
20160 Assert(comtype == FILTER_COMMAND_TYPE_NONE);
20161 Assert(objtype == FILTER_OBJECT_TYPE_NONE);
20162 }
20163
20164 if (objname)
20165 free(objname);
20166 }
20167
20168 filter_free(&fstate);
20169}
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:389
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 2894 of file pg_dump.c.

2895{
2896 TableInfo *tbinfo = tdinfo->tdtable;
2897 PQExpBuffer q;
2898
2899 /* If the materialized view is not flagged as populated, skip this. */
2900 if (!tbinfo->relispopulated)
2901 return;
2902
2903 q = createPQExpBuffer();
2904
2905 appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
2906 fmtQualifiedDumpable(tbinfo));
2907
2908 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
2909 ArchiveEntry(fout,
2910 tdinfo->dobj.catId, /* catalog ID */
2911 tdinfo->dobj.dumpId, /* dump ID */
2912 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
2913 .namespace = tbinfo->dobj.namespace->dobj.name,
2914 .owner = tbinfo->rolname,
2915 .description = "MATERIALIZED VIEW DATA",
2916 .section = SECTION_POST_DATA,
2917 .createStmt = q->data,
2918 .deps = tdinfo->dobj.dependencies,
2919 .nDeps = tdinfo->dobj.nDeps));
2920
2922}

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

2168{
2169 if (checkExtensionMembership(&method->dobj, fout))
2170 return; /* extension membership overrides all else */
2171
2172 /*
2173 * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
2174 * they do not support ACLs currently.
2175 */
2176 if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2177 method->dobj.dump = DUMP_COMPONENT_NONE;
2178 else
2179 method->dobj.dump = fout->dopt->include_everything ?
2181}
static bool checkExtensionMembership(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:1867
#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, and CatalogId::oid.

Referenced by getAccessMethods().

◆ selectDumpableCast()

static void selectDumpableCast ( CastInfo cast,
Archive fout 
)
static

Definition at line 2109 of file pg_dump.c.

2110{
2111 if (checkExtensionMembership(&cast->dobj, fout))
2112 return; /* extension membership overrides all else */
2113
2114 /*
2115 * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
2116 * support ACLs currently.
2117 */
2118 if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2120 else
2121 cast->dobj.dump = fout->dopt->include_everything ?
2123}

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

2088{
2089 /* Default ACLs can't be extension members */
2090
2091 if (dinfo->dobj.namespace)
2092 /* default ACLs are considered part of the namespace */
2093 dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
2094 else
2095 dinfo->dobj.dump = dopt->include_everything ?
2097}

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

2196{
2197 /*
2198 * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
2199 * change permissions on their member objects, if they wish to, and have
2200 * those changes preserved.
2201 */
2202 if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2203 extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
2204 else
2205 {
2206 /* check if there is a list of extensions to dump */
2207 if (extension_include_oids.head != NULL)
2208 extinfo->dobj.dump = extinfo->dobj.dump_contains =
2210 extinfo->dobj.catId.oid) ?
2212 else
2213 extinfo->dobj.dump = extinfo->dobj.dump_contains =
2214 dopt->include_everything ?
2216
2217 /* check that the extension is not explicitly excluded */
2218 if (extinfo->dobj.dump &&
2220 extinfo->dobj.catId.oid))
2221 extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
2222 }
2223}

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

1918{
1919 /*
1920 * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
1921 * and (for --clean) a DROP SCHEMA statement. (In the absence of
1922 * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
1923 */
1924 nsinfo->create = true;
1925
1926 /*
1927 * If specific tables are being dumped, do not dump any complete
1928 * namespaces. If specific namespaces are being dumped, dump just those
1929 * namespaces. Otherwise, dump all non-system namespaces.
1930 */
1931 if (table_include_oids.head != NULL)
1932 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1933 else if (schema_include_oids.head != NULL)
1934 nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
1936 nsinfo->dobj.catId.oid) ?
1938 else if (fout->remoteVersion >= 90600 &&
1939 strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
1940 {
1941 /*
1942 * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
1943 * they are interesting (and not the original ACLs which were set at
1944 * initdb time, see pg_init_privs).
1945 */
1946 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
1947 }
1948 else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
1949 strcmp(nsinfo->dobj.name, "information_schema") == 0)
1950 {
1951 /* Other system schemas don't get dumped */
1952 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1953 }
1954 else if (strcmp(nsinfo->dobj.name, "public") == 0)
1955 {
1956 /*
1957 * The public schema is a strange beast that sits in a sort of
1958 * no-mans-land between being a system object and a user object.
1959 * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
1960 * a comment and an indication of ownership. If the owner is the
1961 * default, omit that superfluous DUMP_COMPONENT_DEFINITION. Before
1962 * v15, the default owner was BOOTSTRAP_SUPERUSERID.
1963 */
1964 nsinfo->create = false;
1965 nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
1966 if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
1967 nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
1969
1970 /*
1971 * Also, make like it has a comment even if it doesn't; this is so
1972 * that we'll emit a command to drop the comment, if appropriate.
1973 * (Without this, we'd not call dumpCommentExtended for it.)
1974 */
1976 }
1977 else
1978 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
1979
1980 /*
1981 * In any case, a namespace can be excluded by an exclusion switch
1982 */
1983 if (nsinfo->dobj.dump_contains &&
1985 nsinfo->dobj.catId.oid))
1986 nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
1987
1988 /*
1989 * If the schema belongs to an extension, allow extension membership to
1990 * override the dump decision for the schema itself. However, this does
1991 * not change dump_contains, so this won't change what we do with objects
1992 * within the schema. (If they belong to the extension, they'll get
1993 * suppressed by it, otherwise not.)
1994 */
1995 (void) checkExtensionMembership(&nsinfo->dobj, fout);
1996}

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

2271{
2272 if (checkExtensionMembership(dobj, fout))
2273 return; /* extension membership overrides all else */
2274
2275 /*
2276 * Default policy is to dump if parent namespace is dumpable, or for
2277 * non-namespace-associated items, dump if we're dumping "everything".
2278 */
2279 if (dobj->namespace)
2280 dobj->dump = dobj->namespace->dobj.dump_contains;
2281 else
2282 dobj->dump = fout->dopt->include_everything ?
2284}

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

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

◆ selectDumpableProcLang()

static void selectDumpableProcLang ( ProcLangInfo plang,
Archive fout 
)
static

Definition at line 2134 of file pg_dump.c.

2135{
2136 if (checkExtensionMembership(&plang->dobj, fout))
2137 return; /* extension membership overrides all else */
2138
2139 /*
2140 * Only include procedural languages when we are dumping everything.
2141 *
2142 * For from-initdb procedural languages, only include ACLs, as we do for
2143 * the pg_catalog namespace. We need this because procedural languages do
2144 * not live in any namespace.
2145 */
2146 if (!fout->dopt->include_everything)
2147 plang->dobj.dump = DUMP_COMPONENT_NONE;
2148 else
2149 {
2150 if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
2151 plang->dobj.dump = fout->remoteVersion < 90600 ?
2153 else
2154 plang->dobj.dump = DUMP_COMPONENT_ALL;
2155 }
2156}

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

2235{
2236 if (checkExtensionMembership(dobj, fout))
2237 return; /* extension membership overrides all else */
2238
2239 dobj->dump = fout->dopt->include_everything ?
2241}

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

2253{
2254 if (checkExtensionMembership(&sobj->dobj, fout))
2255 return; /* extension membership overrides all else */
2256
2257 sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
2258 if (sobj->stattable == NULL ||
2261}

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

2004{
2005 if (checkExtensionMembership(&tbinfo->dobj, fout))
2006 return; /* extension membership overrides all else */
2007
2008 /*
2009 * If specific tables are being dumped, dump just those tables; else, dump
2010 * according to the parent namespace's dump flag.
2011 */
2012 if (table_include_oids.head != NULL)
2014 tbinfo->dobj.catId.oid) ?
2016 else
2017 tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
2018
2019 /*
2020 * In any case, a table can be excluded by an exclusion switch
2021 */
2022 if (tbinfo->dobj.dump &&
2024 tbinfo->dobj.catId.oid))
2025 tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
2026}

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

2043{
2044 /* skip complex types, except for standalone composite types */
2045 if (OidIsValid(tyinfo->typrelid) &&
2046 tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
2047 {
2048 TableInfo *tytable = findTableByOid(tyinfo->typrelid);
2049
2050 tyinfo->dobj.objType = DO_DUMMY_TYPE;
2051 if (tytable != NULL)
2052 tyinfo->dobj.dump = tytable->dobj.dump;
2053 else
2054 tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
2055 return;
2056 }
2057
2058 /* skip auto-generated array and multirange types */
2059 if (tyinfo->isArray || tyinfo->isMultirange)
2060 {
2061 tyinfo->dobj.objType = DO_DUMMY_TYPE;
2062
2063 /*
2064 * Fall through to set the dump flag; we assume that the subsequent
2065 * rules will do the same thing as they would for the array's base
2066 * type or multirange's range type. (We cannot reliably look up the
2067 * base type here, since getTypes may not have processed it yet.)
2068 */
2069 }
2070
2071 if (checkExtensionMembership(&tyinfo->dobj, fout))
2072 return; /* extension membership overrides all else */
2073
2074 /* Dump based on if the contents of the namespace are being dumped */
2075 tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
2076}

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

18487{
18488 SequenceItem v1 = *((const SequenceItem *) p1);
18489 SequenceItem v2 = *((const SequenceItem *) p2);
18490
18491 return pg_cmp_u32(v1.oid, v2.oid);
18492}

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

4919{
4921 PGresult *res;
4922
4923 appendPQExpBuffer(query,
4924 "SELECT set_config(name, '%s', false) "
4925 "FROM pg_settings "
4926 "WHERE name = 'restrict_nonsystem_relation_kind'",
4927 value);
4928 res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
4929
4930 PQclear(res);
4931 destroyPQExpBuffer(query);
4932}
static struct @165 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 1345 of file pg_dump.c.

1347{
1348 DumpOptions *dopt = AH->dopt;
1349 PGconn *conn = GetConnection(AH);
1350 const char *std_strings;
1351
1353
1354 /*
1355 * Set the client encoding if requested.
1356 */
1357 if (dumpencoding)
1358 {
1359 if (PQsetClientEncoding(conn, dumpencoding) < 0)
1360 pg_fatal("invalid client encoding \"%s\" specified",
1361 dumpencoding);
1362 }
1363
1364 /*
1365 * Get the active encoding and the standard_conforming_strings setting, so
1366 * we know how to escape strings.
1367 */
1370
1371 std_strings = PQparameterStatus(conn, "standard_conforming_strings");
1372 AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
1373
1374 /*
1375 * Set the role if requested. In a parallel dump worker, we'll be passed
1376 * use_role == NULL, but AH->use_role is already set (if user specified it
1377 * originally) and we should use that.
1378 */
1379 if (!use_role && AH->use_role)
1380 use_role = AH->use_role;
1381
1382 /* Set the role if requested */
1383 if (use_role)
1384 {
1386
1387 appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
1388 ExecuteSqlStatement(AH, query->data);
1389 destroyPQExpBuffer(query);
1390
1391 /* save it for possible later use by parallel workers */
1392 if (!AH->use_role)
1393 AH->use_role = pg_strdup(use_role);
1394 }
1395
1396 /* Set the datestyle to ISO to ensure the dump's portability */
1397 ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
1398
1399 /* Likewise, avoid using sql_standard intervalstyle */
1400 ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
1401
1402 /*
1403 * Use an explicitly specified extra_float_digits if it has been provided.
1404 * Otherwise, set extra_float_digits so that we can dump float data
1405 * exactly (given correctly implemented float I/O code, anyway).
1406 */
1408 {
1410
1411 appendPQExpBuffer(q, "SET extra_float_digits TO %d",
1413 ExecuteSqlStatement(AH, q->data);
1415 }
1416 else
1417 ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
1418
1419 /*
1420 * Disable synchronized scanning, to prevent unpredictable changes in row
1421 * ordering across a dump and reload.
1422 */
1423 ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
1424
1425 /*
1426 * Disable timeouts if supported.
1427 */
1428 ExecuteSqlStatement(AH, "SET statement_timeout = 0");
1429 if (AH->remoteVersion >= 90300)
1430 ExecuteSqlStatement(AH, "SET lock_timeout = 0");
1431 if (AH->remoteVersion >= 90600)
1432 ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
1433 if (AH->remoteVersion >= 170000)
1434 ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
1435
1436 /*
1437 * Quote all identifiers, if requested.
1438 */
1440 ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
1441
1442 /*
1443 * Adjust row-security mode, if supported.
1444 */
1445 if (AH->remoteVersion >= 90500)
1446 {
1447 if (dopt->enable_row_security)
1448 ExecuteSqlStatement(AH, "SET row_security = on");
1449 else
1450 ExecuteSqlStatement(AH, "SET row_security = off");
1451 }
1452
1453 /*
1454 * For security reasons, we restrict the expansion of non-system views and
1455 * access to foreign tables during the pg_dump process. This restriction
1456 * is adjusted when dumping foreign table data.
1457 */
1458 set_restrict_relation_kind(AH, "view, foreign-table");
1459
1460 /*
1461 * Initialize prepared-query state to "nothing prepared". We do this here
1462 * so that a parallel dump worker will have its own state.
1463 */
1464 AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
1465
1466 /*
1467 * Start transaction-snapshot mode transaction to dump consistent data.
1468 */
1469 ExecuteSqlStatement(AH, "BEGIN");
1470
1471 /*
1472 * To support the combination of serializable_deferrable with the jobs
1473 * option we use REPEATABLE READ for the worker connections that are
1474 * passed a snapshot. As long as the snapshot is acquired in a
1475 * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
1476 * REPEATABLE READ transaction provides the appropriate integrity
1477 * guarantees. This is a kluge, but safe for back-patching.
1478 */
1479 if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
1481 "SET TRANSACTION ISOLATION LEVEL "
1482 "SERIALIZABLE, READ ONLY, DEFERRABLE");
1483 else
1485 "SET TRANSACTION ISOLATION LEVEL "
1486 "REPEATABLE READ, READ ONLY");
1487
1488 /*
1489 * If user specified a snapshot to use, select that. In a parallel dump
1490 * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
1491 * is already set (if the server can handle it) and we should use that.
1492 */
1493 if (dumpsnapshot)
1494 AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
1495
1496 if (AH->sync_snapshot_id)
1497 {
1499
1500 appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
1502 ExecuteSqlStatement(AH, query->data);
1503 destroyPQExpBuffer(query);
1504 }
1505 else if (AH->numWorkers > 1)
1506 {
1507 if (AH->isStandby && AH->remoteVersion < 100000)
1508 pg_fatal("parallel dumps from standby servers are not supported by this server version");
1510 }
1511}
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7719
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7727
#define NUM_PREP_QUERIES
Definition: pg_backup.h:80
static char * get_synchronized_snapshot(Archive *fout)
Definition: pg_dump.c:1530
void setFmtEncoding(int encoding)
Definition: string_utils.c:69
char * use_role
Definition: pg_backup.h:244
char * sync_snapshot_id
Definition: pg_backup.h:236

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

1516{
1517 /*
1518 * We want to re-select all the same values the leader connection is
1519 * using. We'll have inherited directly-usable values in
1520 * AH->sync_snapshot_id and AH->use_role, but we need to translate the
1521 * inherited encoding value back to a string to pass to setup_connection.
1522 */
1525 NULL,
1526 NULL);
1527}

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

9855{
9856 if (dopt->binary_upgrade)
9857 return true;
9858 if (tbinfo->attisdropped[colno])
9859 return false;
9860 return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9861}

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

Referenced by main().

◆ dosync

bool dosync = true
static

Definition at line 147 of file pg_dump.c.

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

◆ extension_exclude_oids

SimpleOidList extension_exclude_oids = {NULL, NULL}
static

Definition at line 184 of file pg_dump.c.

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

◆ extension_exclude_patterns

SimpleStringList extension_exclude_patterns = {NULL, NULL}
static

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

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

◆ extension_include_patterns

SimpleStringList extension_include_patterns = {NULL, NULL}
static

Definition at line 180 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ extra_float_digits

int extra_float_digits
static

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

Referenced by main(), and setup_connection().

◆ nbinaryUpgradeClassOids

int nbinaryUpgradeClassOids = 0
static

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

Referenced by collectRoleNames(), and getRoleName().

◆ nseclabels

int nseclabels = 0
static

Definition at line 202 of file pg_dump.c.

Referenced by collectSecLabels(), and findSecLabels().

◆ nsequences

int nsequences = 0
static

Definition at line 210 of file pg_dump.c.

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

◆ rolenames

RoleNameItem* rolenames = NULL
static

Definition at line 193 of file pg_dump.c.

Referenced by collectRoleNames(), and getRoleName().

◆ schema_exclude_oids

SimpleOidList schema_exclude_oids = {NULL, NULL}
static

Definition at line 165 of file pg_dump.c.

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

◆ schema_exclude_patterns

SimpleStringList schema_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and selectDumpableNamespace().

◆ schema_include_patterns

SimpleStringList schema_include_patterns = {NULL, NULL}
static

Definition at line 162 of file pg_dump.c.

Referenced by main(), and read_dump_filters().

◆ seclabels

SecLabelItem* seclabels = NULL
static

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

Referenced by dumpSequence(), and parse_sequence_type().

◆ sequences

SequenceItem* sequences = NULL
static

Definition at line 209 of file pg_dump.c.

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

◆ strict_names

int strict_names = 0
static

◆ table_exclude_oids

SimpleOidList table_exclude_oids = {NULL, NULL}
static

Definition at line 172 of file pg_dump.c.

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

◆ table_exclude_patterns

SimpleStringList table_exclude_patterns = {NULL, NULL}
static

Definition at line 170 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 171 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 167 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 168 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 175 of file pg_dump.c.

Referenced by main(), and makeTableDataInfo().

◆ tabledata_exclude_patterns

SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
static

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

Referenced by main(), and read_dump_filters().