PostgreSQL Source Code git master
pg_dump.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_aggregate_d.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_attribute_d.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_cast_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_default_acl_d.h"
#include "catalog/pg_largeobject_d.h"
#include "catalog/pg_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 19704 of file pg_dump.c.

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

20033{
20034 bool res;
20035
20036 res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
20037 fout->std_strings);
20038 if (!res)
20039 pg_log_warning("could not parse %s array", "reloptions");
20040}
#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 19830 of file pg_dump.c.

19831{
19832 ArchiveHandle *AH = (ArchiveHandle *) fout;
19833 TocEntry *te;
19834
19835 /* Scan all TOC entries in the archive */
19836 for (te = AH->toc->next; te != AH->toc; te = te->next)
19837 {
19838 DumpableObject *dobj;
19839 DumpId *dependencies;
19840 int nDeps;
19841 int allocDeps;
19842
19843 /* No need to process entries that will not be dumped */
19844 if (te->reqs == 0)
19845 continue;
19846 /* Ignore entries that already have "special" dependencies */
19847 if (te->nDeps > 0)
19848 continue;
19849 /* Otherwise, look up the item's original DumpableObject, if any */
19850 dobj = findObjectByDumpId(te->dumpId);
19851 if (dobj == NULL)
19852 continue;
19853 /* No work if it has no dependencies */
19854 if (dobj->nDeps <= 0)
19855 continue;
19856 /* Set up work array */
19857 allocDeps = 64;
19858 dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
19859 nDeps = 0;
19860 /* Recursively find all dumpable dependencies */
19861 findDumpableDependencies(AH, dobj,
19862 &dependencies, &nDeps, &allocDeps);
19863 /* And save 'em ... */
19864 if (nDeps > 0)
19865 {
19866 dependencies = (DumpId *) pg_realloc(dependencies,
19867 nDeps * sizeof(DumpId));
19868 te->dependencies = dependencies;
19869 te->nDeps = nDeps;
19870 }
19871 else
19872 free(dependencies);
19873 }
19874}
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:19878
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 11274 of file pg_dump.c.

11275{
11276 PGresult *res;
11277 PQExpBuffer query;
11278 int i_description;
11279 int i_classoid;
11280 int i_objoid;
11281 int i_objsubid;
11282 int ntups;
11283 int i;
11284 DumpableObject *dobj;
11285
11286 query = createPQExpBuffer();
11287
11288 appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
11289 "FROM pg_catalog.pg_description "
11290 "ORDER BY classoid, objoid, objsubid");
11291
11292 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
11293
11294 /* Construct lookup table containing OIDs in numeric form */
11295
11296 i_description = PQfnumber(res, "description");
11297 i_classoid = PQfnumber(res, "classoid");
11298 i_objoid = PQfnumber(res, "objoid");
11299 i_objsubid = PQfnumber(res, "objsubid");
11300
11301 ntups = PQntuples(res);
11302
11303 comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
11304 ncomments = 0;
11305 dobj = NULL;
11306
11307 for (i = 0; i < ntups; i++)
11308 {
11309 CatalogId objId;
11310 int subid;
11311
11312 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
11313 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
11314 subid = atoi(PQgetvalue(res, i, i_objsubid));
11315
11316 /* We needn't remember comments that don't match any dumpable object */
11317 if (dobj == NULL ||
11318 dobj->catId.tableoid != objId.tableoid ||
11319 dobj->catId.oid != objId.oid)
11320 dobj = findObjectByCatalogId(objId);
11321 if (dobj == NULL)
11322 continue;
11323
11324 /*
11325 * Comments on columns of composite types are linked to the type's
11326 * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
11327 * in the type's own DumpableObject.
11328 */
11329 if (subid != 0 && dobj->objType == DO_TABLE &&
11330 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
11331 {
11332 TypeInfo *cTypeInfo;
11333
11334 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
11335 if (cTypeInfo)
11337 }
11338 else
11339 dobj->components |= DUMP_COMPONENT_COMMENT;
11340
11341 comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
11343 comments[ncomments].objoid = objId.oid;
11344 comments[ncomments].objsubid = subid;
11345 ncomments++;
11346 }
11347
11348 PQclear(res);
11349 destroyPQExpBuffer(query);
11350}
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 16424 of file pg_dump.c.

16425{
16426 PGresult *res;
16427 PQExpBuffer query;
16428 int i_label;
16429 int i_provider;
16430 int i_classoid;
16431 int i_objoid;
16432 int i_objsubid;
16433 int ntups;
16434 int i;
16435 DumpableObject *dobj;
16436
16437 query = createPQExpBuffer();
16438
16440 "SELECT label, provider, classoid, objoid, objsubid "
16441 "FROM pg_catalog.pg_seclabel "
16442 "ORDER BY classoid, objoid, objsubid");
16443
16444 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16445
16446 /* Construct lookup table containing OIDs in numeric form */
16447 i_label = PQfnumber(res, "label");
16448 i_provider = PQfnumber(res, "provider");
16449 i_classoid = PQfnumber(res, "classoid");
16450 i_objoid = PQfnumber(res, "objoid");
16451 i_objsubid = PQfnumber(res, "objsubid");
16452
16453 ntups = PQntuples(res);
16454
16455 seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
16456 nseclabels = 0;
16457 dobj = NULL;
16458
16459 for (i = 0; i < ntups; i++)
16460 {
16461 CatalogId objId;
16462 int subid;
16463
16464 objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
16465 objId.oid = atooid(PQgetvalue(res, i, i_objoid));
16466 subid = atoi(PQgetvalue(res, i, i_objsubid));
16467
16468 /* We needn't remember labels that don't match any dumpable object */
16469 if (dobj == NULL ||
16470 dobj->catId.tableoid != objId.tableoid ||
16471 dobj->catId.oid != objId.oid)
16472 dobj = findObjectByCatalogId(objId);
16473 if (dobj == NULL)
16474 continue;
16475
16476 /*
16477 * Labels on columns of composite types are linked to the type's
16478 * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
16479 * in the type's own DumpableObject.
16480 */
16481 if (subid != 0 && dobj->objType == DO_TABLE &&
16482 ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
16483 {
16484 TypeInfo *cTypeInfo;
16485
16486 cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
16487 if (cTypeInfo)
16489 }
16490 else
16491 dobj->components |= DUMP_COMPONENT_SECLABEL;
16492
16493 seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
16494 seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
16496 seclabels[nseclabels].objoid = objId.oid;
16497 seclabels[nseclabels].objsubid = subid;
16498 nseclabels++;
16499 }
16500
16501 PQclear(res);
16502 destroyPQExpBuffer(query);
16503}
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 18483 of file pg_dump.c.

18484{
18485 PGresult *res;
18486 const char *query;
18487
18488 /*
18489 * Before Postgres 10, sequence metadata is in the sequence itself. With
18490 * some extra effort, we might be able to use the sorted table for those
18491 * versions, but for now it seems unlikely to be worth it.
18492 *
18493 * Since version 18, we can gather the sequence data in this query with
18494 * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
18495 */
18496 if (fout->remoteVersion < 100000)
18497 return;
18498 else if (fout->remoteVersion < 180000 ||
18499 (!fout->dopt->dumpData && !fout->dopt->sequence_data))
18500 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18501 "seqstart, seqincrement, "
18502 "seqmax, seqmin, "
18503 "seqcache, seqcycle, "
18504 "NULL, 'f' "
18505 "FROM pg_catalog.pg_sequence "
18506 "ORDER BY seqrelid";
18507 else
18508 query = "SELECT seqrelid, format_type(seqtypid, NULL), "
18509 "seqstart, seqincrement, "
18510 "seqmax, seqmin, "
18511 "seqcache, seqcycle, "
18512 "last_value, is_called "
18513 "FROM pg_catalog.pg_sequence, "
18514 "pg_get_sequence_data(seqrelid) "
18515 "ORDER BY seqrelid;";
18516
18517 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
18518
18519 nsequences = PQntuples(res);
18521
18522 for (int i = 0; i < nsequences; i++)
18523 {
18524 sequences[i].oid = atooid(PQgetvalue(res, i, 0));
18526 sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
18527 sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
18528 sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
18529 sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
18530 sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
18531 sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
18532 sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
18533 sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
18534 }
18535
18536 PQclear(res);
18537}
static int nsequences
Definition: pg_dump.c:210
static SeqType parse_sequence_type(const char *name)
Definition: pg_dump.c:18452
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 13971 of file pg_dump.c.

13972{
13973 char *name;
13974 char *paren;
13975 bool inquote;
13976
13977 /* In all cases "-" means a null reference */
13978 if (strcmp(proc, "-") == 0)
13979 return NULL;
13980
13981 name = pg_strdup(proc);
13982 /* find non-double-quoted left paren */
13983 inquote = false;
13984 for (paren = name; *paren; paren++)
13985 {
13986 if (*paren == '(' && !inquote)
13987 {
13988 *paren = '\0';
13989 break;
13990 }
13991 if (*paren == '"')
13992 inquote = !inquote;
13993 }
13994 return name;
13995}
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 14042 of file pg_dump.c.

14043{
14044 char *result;
14045 char query[128];
14046 PGresult *res;
14047
14048 snprintf(query, sizeof(query),
14049 "SELECT '%u'::pg_catalog.regproc", funcOid);
14050 res = ExecuteSqlQueryForSingleRow(fout, query);
14051
14052 result = pg_strdup(PQgetvalue(res, 0, 0));
14053
14054 PQclear(res);
14055
14056 return result;
14057}
#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 19680 of file pg_dump.c.

19681{
19682 DumpableObject *dobjs;
19683
19684 dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
19685
19686 dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
19687 dobjs[0].catId = nilCatalogId;
19688 AssignDumpId(dobjs + 0);
19689 dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
19690
19691 dobjs[1].objType = DO_POST_DATA_BOUNDARY;
19692 dobjs[1].catId = nilCatalogId;
19693 AssignDumpId(dobjs + 1);
19694 dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
19695
19696 return dobjs;
19697}
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 16699 of file pg_dump.c.

16700{
16701 PQExpBuffer result = createPQExpBuffer();
16702 int j;
16703
16704 appendPQExpBufferStr(result, "SELECT");
16705
16706 for (j = 0; j < tbinfo->numatts; j++)
16707 {
16708 if (j > 0)
16709 appendPQExpBufferChar(result, ',');
16710 appendPQExpBufferStr(result, "\n ");
16711
16712 appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
16713
16714 /*
16715 * Must add collation if not default for the type, because CREATE OR
16716 * REPLACE VIEW won't change it
16717 */
16718 if (OidIsValid(tbinfo->attcollation[j]))
16719 {
16720 CollInfo *coll;
16721
16722 coll = findCollationByOid(tbinfo->attcollation[j]);
16723 if (coll)
16724 appendPQExpBuffer(result, " COLLATE %s",
16725 fmtQualifiedDumpable(coll));
16726 }
16727
16728 appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
16729 }
16730
16731 return result;
16732}
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 16650 of file pg_dump.c.

16651{
16653 PQExpBuffer result = createPQExpBuffer();
16654 PGresult *res;
16655 int len;
16656
16657 /* Fetch the view definition */
16658 appendPQExpBuffer(query,
16659 "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
16660 tbinfo->dobj.catId.oid);
16661
16662 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
16663
16664 if (PQntuples(res) != 1)
16665 {
16666 if (PQntuples(res) < 1)
16667 pg_fatal("query to obtain definition of view \"%s\" returned no data",
16668 tbinfo->dobj.name);
16669 else
16670 pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
16671 tbinfo->dobj.name);
16672 }
16673
16674 len = PQgetlength(res, 0, 0);
16675
16676 if (len == 0)
16677 pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
16678 tbinfo->dobj.name);
16679
16680 /* Strip off the trailing semicolon so that other things may follow. */
16681 Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
16682 appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
16683
16684 PQclear(res);
16685 destroyPQExpBuffer(query);
16686
16687 return result;
16688}
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:2327
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 14064 of file pg_dump.c.

14065{
14066 DumpOptions *dopt = fout->dopt;
14067 PQExpBuffer q;
14068 PQExpBuffer delq;
14069 char *qamname;
14070
14071 /* Do nothing if not dumping schema */
14072 if (!dopt->dumpSchema)
14073 return;
14074
14075 q = createPQExpBuffer();
14076 delq = createPQExpBuffer();
14077
14078 qamname = pg_strdup(fmtId(aminfo->dobj.name));
14079
14080 appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
14081
14082 switch (aminfo->amtype)
14083 {
14084 case AMTYPE_INDEX:
14085 appendPQExpBufferStr(q, "TYPE INDEX ");
14086 break;
14087 case AMTYPE_TABLE:
14088 appendPQExpBufferStr(q, "TYPE TABLE ");
14089 break;
14090 default:
14091 pg_log_warning("invalid type \"%c\" of access method \"%s\"",
14092 aminfo->amtype, qamname);
14094 destroyPQExpBuffer(delq);
14095 free(qamname);
14096 return;
14097 }
14098
14099 appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
14100
14101 appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
14102 qamname);
14103
14104 if (dopt->binary_upgrade)
14106 "ACCESS METHOD", qamname, NULL);
14107
14108 if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14109 ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
14110 ARCHIVE_OPTS(.tag = aminfo->dobj.name,
14111 .description = "ACCESS METHOD",
14112 .section = SECTION_PRE_DATA,
14113 .createStmt = q->data,
14114 .dropStmt = delq->data));
14115
14116 /* Dump Access Method Comments */
14117 if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14118 dumpComment(fout, "ACCESS METHOD", qamname,
14119 NULL, "",
14120 aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
14121
14123 destroyPQExpBuffer(delq);
14124 free(qamname);
14125}
@ 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 16055 of file pg_dump.c.

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

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

17773{
17774 DumpOptions *dopt = fout->dopt;
17775 TableInfo *tbinfo = adinfo->adtable;
17776 int adnum = adinfo->adnum;
17777 PQExpBuffer q;
17778 PQExpBuffer delq;
17779 char *qualrelname;
17780 char *tag;
17781 char *foreign;
17782
17783 /* Do nothing if not dumping schema */
17784 if (!dopt->dumpSchema)
17785 return;
17786
17787 /* Skip if not "separate"; it was dumped in the table's definition */
17788 if (!adinfo->separate)
17789 return;
17790
17791 q = createPQExpBuffer();
17792 delq = createPQExpBuffer();
17793
17794 qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
17795
17796 foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
17797
17799 "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
17800 foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
17801 adinfo->adef_expr);
17802
17803 appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
17804 foreign, qualrelname,
17805 fmtId(tbinfo->attnames[adnum - 1]));
17806
17807 tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
17808
17809 if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
17810 ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
17811 ARCHIVE_OPTS(.tag = tag,
17812 .namespace = tbinfo->dobj.namespace->dobj.name,
17813 .owner = tbinfo->rolname,
17814 .description = "DEFAULT",
17815 .section = SECTION_PRE_DATA,
17816 .createStmt = q->data,
17817 .dropStmt = delq->data));
17818
17819 free(tag);
17821 destroyPQExpBuffer(delq);
17822 free(qualrelname);
17823}
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 12153 of file pg_dump.c.

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

13519{
13520 DumpOptions *dopt = fout->dopt;
13521 PQExpBuffer defqry;
13522 PQExpBuffer delqry;
13523 PQExpBuffer labelq;
13524 PQExpBuffer castargs;
13525 FuncInfo *funcInfo = NULL;
13526 const char *sourceType;
13527 const char *targetType;
13528
13529 /* Do nothing if not dumping schema */
13530 if (!dopt->dumpSchema)
13531 return;
13532
13533 /* Cannot dump if we don't have the cast function's info */
13534 if (OidIsValid(cast->castfunc))
13535 {
13536 funcInfo = findFuncByOid(cast->castfunc);
13537 if (funcInfo == NULL)
13538 pg_fatal("could not find function definition for function with OID %u",
13539 cast->castfunc);
13540 }
13541
13542 defqry = createPQExpBuffer();
13543 delqry = createPQExpBuffer();
13544 labelq = createPQExpBuffer();
13545 castargs = createPQExpBuffer();
13546
13547 sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
13548 targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
13549 appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
13550 sourceType, targetType);
13551
13552 appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
13553 sourceType, targetType);
13554
13555 switch (cast->castmethod)
13556 {
13557 case COERCION_METHOD_BINARY:
13558 appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
13559 break;
13560 case COERCION_METHOD_INOUT:
13561 appendPQExpBufferStr(defqry, "WITH INOUT");
13562 break;
13563 case COERCION_METHOD_FUNCTION:
13564 if (funcInfo)
13565 {
13566 char *fsig = format_function_signature(fout, funcInfo, true);
13567
13568 /*
13569 * Always qualify the function name (format_function_signature
13570 * won't qualify it).
13571 */
13572 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
13573 fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
13574 free(fsig);
13575 }
13576 else
13577 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
13578 break;
13579 default:
13580 pg_log_warning("bogus value in pg_cast.castmethod field");
13581 }
13582
13583 if (cast->castcontext == 'a')
13584 appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
13585 else if (cast->castcontext == 'i')
13586 appendPQExpBufferStr(defqry, " AS IMPLICIT");
13587 appendPQExpBufferStr(defqry, ";\n");
13588
13589 appendPQExpBuffer(labelq, "CAST (%s AS %s)",
13590 sourceType, targetType);
13591
13592 appendPQExpBuffer(castargs, "(%s AS %s)",
13593 sourceType, targetType);
13594
13595 if (dopt->binary_upgrade)
13597 "CAST", castargs->data, NULL);
13598
13600 ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
13601 ARCHIVE_OPTS(.tag = labelq->data,
13602 .description = "CAST",
13603 .section = SECTION_PRE_DATA,
13604 .createStmt = defqry->data,
13605 .dropStmt = delqry->data));
13606
13607 /* Dump Cast Comments */
13608 if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
13609 dumpComment(fout, "CAST", castargs->data,
13610 NULL, "",
13611 cast->dobj.catId, 0, cast->dobj.dumpId);
13612
13613 destroyPQExpBuffer(defqry);
13614 destroyPQExpBuffer(delqry);
13615 destroyPQExpBuffer(labelq);
13616 destroyPQExpBuffer(castargs);
13617}
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 14632 of file pg_dump.c.

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

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

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

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

14890{
14891 DumpOptions *dopt = fout->dopt;
14892 PQExpBuffer query;
14893 PQExpBuffer q;
14894 PQExpBuffer delq;
14895 char *qconvname;
14896 PGresult *res;
14897 int i_conforencoding;
14898 int i_contoencoding;
14899 int i_conproc;
14900 int i_condefault;
14901 const char *conforencoding;
14902 const char *contoencoding;
14903 const char *conproc;
14904 bool condefault;
14905
14906 /* Do nothing if not dumping schema */
14907 if (!dopt->dumpSchema)
14908 return;
14909
14910 query = createPQExpBuffer();
14911 q = createPQExpBuffer();
14912 delq = createPQExpBuffer();
14913
14914 qconvname = pg_strdup(fmtId(convinfo->dobj.name));
14915
14916 /* Get conversion-specific details */
14917 appendPQExpBuffer(query, "SELECT "
14918 "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
14919 "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
14920 "conproc, condefault "
14921 "FROM pg_catalog.pg_conversion c "
14922 "WHERE c.oid = '%u'::pg_catalog.oid",
14923 convinfo->dobj.catId.oid);
14924
14925 res = ExecuteSqlQueryForSingleRow(fout, query->data);
14926
14927 i_conforencoding = PQfnumber(res, "conforencoding");
14928 i_contoencoding = PQfnumber(res, "contoencoding");
14929 i_conproc = PQfnumber(res, "conproc");
14930 i_condefault = PQfnumber(res, "condefault");
14931
14932 conforencoding = PQgetvalue(res, 0, i_conforencoding);
14933 contoencoding = PQgetvalue(res, 0, i_contoencoding);
14934 conproc = PQgetvalue(res, 0, i_conproc);
14935 condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
14936
14937 appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
14938 fmtQualifiedDumpable(convinfo));
14939
14940 appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
14941 (condefault) ? "DEFAULT " : "",
14942 fmtQualifiedDumpable(convinfo));
14943 appendStringLiteralAH(q, conforencoding, fout);
14944 appendPQExpBufferStr(q, " TO ");
14945 appendStringLiteralAH(q, contoencoding, fout);
14946 /* regproc output is already sufficiently quoted */
14947 appendPQExpBuffer(q, " FROM %s;\n", conproc);
14948
14949 if (dopt->binary_upgrade)
14951 "CONVERSION", qconvname,
14952 convinfo->dobj.namespace->dobj.name);
14953
14954 if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
14955 ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
14956 ARCHIVE_OPTS(.tag = convinfo->dobj.name,
14957 .namespace = convinfo->dobj.namespace->dobj.name,
14958 .owner = convinfo->rolname,
14959 .description = "CONVERSION",
14960 .section = SECTION_PRE_DATA,
14961 .createStmt = q->data,
14962 .dropStmt = delq->data));
14963
14964 /* Dump Conversion Comments */
14965 if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
14966 dumpComment(fout, "CONVERSION", qconvname,
14967 convinfo->dobj.namespace->dobj.name, convinfo->rolname,
14968 convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
14969
14970 PQclear(res);
14971
14972 destroyPQExpBuffer(query);
14974 destroyPQExpBuffer(delq);
14975 free(qconvname);
14976}
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 15963 of file pg_dump.c.

15964{
15965 DumpOptions *dopt = fout->dopt;
15966 PQExpBuffer q;
15967 PQExpBuffer tag;
15968 const char *type;
15969
15970 /* Do nothing if not dumping schema, or if we're skipping ACLs */
15971 if (!dopt->dumpSchema || dopt->aclsSkip)
15972 return;
15973
15974 q = createPQExpBuffer();
15975 tag = createPQExpBuffer();
15976
15977 switch (daclinfo->defaclobjtype)
15978 {
15979 case DEFACLOBJ_RELATION:
15980 type = "TABLES";
15981 break;
15982 case DEFACLOBJ_SEQUENCE:
15983 type = "SEQUENCES";
15984 break;
15985 case DEFACLOBJ_FUNCTION:
15986 type = "FUNCTIONS";
15987 break;
15988 case DEFACLOBJ_TYPE:
15989 type = "TYPES";
15990 break;
15991 case DEFACLOBJ_NAMESPACE:
15992 type = "SCHEMAS";
15993 break;
15994 case DEFACLOBJ_LARGEOBJECT:
15995 type = "LARGE OBJECTS";
15996 break;
15997 default:
15998 /* shouldn't get here */
15999 pg_fatal("unrecognized object type in default privileges: %d",
16000 (int) daclinfo->defaclobjtype);
16001 type = ""; /* keep compiler quiet */
16002 }
16003
16004 appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
16005
16006 /* build the actual command(s) for this tuple */
16008 daclinfo->dobj.namespace != NULL ?
16009 daclinfo->dobj.namespace->dobj.name : NULL,
16010 daclinfo->dacl.acl,
16011 daclinfo->dacl.acldefault,
16012 daclinfo->defaclrole,
16013 fout->remoteVersion,
16014 q))
16015 pg_fatal("could not parse default ACL list (%s)",
16016 daclinfo->dacl.acl);
16017
16018 if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
16019 ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
16020 ARCHIVE_OPTS(.tag = tag->data,
16021 .namespace = daclinfo->dobj.namespace ?
16022 daclinfo->dobj.namespace->dobj.name : NULL,
16023 .owner = daclinfo->defaclrole,
16024 .description = "DEFAULT ACL",
16025 .section = SECTION_POST_DATA,
16026 .createStmt = q->data));
16027
16028 destroyPQExpBuffer(tag);
16030}
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 12402 of file pg_dump.c.

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

11360{
11361 /*
11362 * Clear any dump-request bits for components that don't exist for this
11363 * object. (This makes it safe to initially use DUMP_COMPONENT_ALL as the
11364 * request for every kind of object.)
11365 */
11366 dobj->dump &= dobj->components;
11367
11368 /* Now, short-circuit if there's nothing to be done here. */
11369 if (dobj->dump == 0)
11370 return;
11371
11372 switch (dobj->objType)
11373 {
11374 case DO_NAMESPACE:
11375 dumpNamespace(fout, (const NamespaceInfo *) dobj);
11376 break;
11377 case DO_EXTENSION:
11378 dumpExtension(fout, (const ExtensionInfo *) dobj);
11379 break;
11380 case DO_TYPE:
11381 dumpType(fout, (const TypeInfo *) dobj);
11382 break;
11383 case DO_SHELL_TYPE:
11384 dumpShellType(fout, (const ShellTypeInfo *) dobj);
11385 break;
11386 case DO_FUNC:
11387 dumpFunc(fout, (const FuncInfo *) dobj);
11388 break;
11389 case DO_AGG:
11390 dumpAgg(fout, (const AggInfo *) dobj);
11391 break;
11392 case DO_OPERATOR:
11393 dumpOpr(fout, (const OprInfo *) dobj);
11394 break;
11395 case DO_ACCESS_METHOD:
11396 dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
11397 break;
11398 case DO_OPCLASS:
11399 dumpOpclass(fout, (const OpclassInfo *) dobj);
11400 break;
11401 case DO_OPFAMILY:
11402 dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
11403 break;
11404 case DO_COLLATION:
11405 dumpCollation(fout, (const CollInfo *) dobj);
11406 break;
11407 case DO_CONVERSION:
11408 dumpConversion(fout, (const ConvInfo *) dobj);
11409 break;
11410 case DO_TABLE:
11411 dumpTable(fout, (const TableInfo *) dobj);
11412 break;
11413 case DO_TABLE_ATTACH:
11414 dumpTableAttach(fout, (const TableAttachInfo *) dobj);
11415 break;
11416 case DO_ATTRDEF:
11417 dumpAttrDef(fout, (const AttrDefInfo *) dobj);
11418 break;
11419 case DO_INDEX:
11420 dumpIndex(fout, (const IndxInfo *) dobj);
11421 break;
11422 case DO_INDEX_ATTACH:
11423 dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
11424 break;
11425 case DO_STATSEXT:
11426 dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
11427 break;
11428 case DO_REFRESH_MATVIEW:
11429 refreshMatViewData(fout, (const TableDataInfo *) dobj);
11430 break;
11431 case DO_RULE:
11432 dumpRule(fout, (const RuleInfo *) dobj);
11433 break;
11434 case DO_TRIGGER:
11435 dumpTrigger(fout, (const TriggerInfo *) dobj);
11436 break;
11437 case DO_EVENT_TRIGGER:
11438 dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
11439 break;
11440 case DO_CONSTRAINT:
11441 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11442 break;
11443 case DO_FK_CONSTRAINT:
11444 dumpConstraint(fout, (const ConstraintInfo *) dobj);
11445 break;
11446 case DO_PROCLANG:
11447 dumpProcLang(fout, (const ProcLangInfo *) dobj);
11448 break;
11449 case DO_CAST:
11450 dumpCast(fout, (const CastInfo *) dobj);
11451 break;
11452 case DO_TRANSFORM:
11453 dumpTransform(fout, (const TransformInfo *) dobj);
11454 break;
11455 case DO_SEQUENCE_SET:
11456 dumpSequenceData(fout, (const TableDataInfo *) dobj);
11457 break;
11458 case DO_TABLE_DATA:
11459 dumpTableData(fout, (const TableDataInfo *) dobj);
11460 break;
11461 case DO_DUMMY_TYPE:
11462 /* table rowtypes and array types are never dumped separately */
11463 break;
11464 case DO_TSPARSER:
11465 dumpTSParser(fout, (const TSParserInfo *) dobj);
11466 break;
11467 case DO_TSDICT:
11468 dumpTSDictionary(fout, (const TSDictInfo *) dobj);
11469 break;
11470 case DO_TSTEMPLATE:
11471 dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
11472 break;
11473 case DO_TSCONFIG:
11474 dumpTSConfig(fout, (const TSConfigInfo *) dobj);
11475 break;
11476 case DO_FDW:
11477 dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
11478 break;
11479 case DO_FOREIGN_SERVER:
11480 dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
11481 break;
11482 case DO_DEFAULT_ACL:
11483 dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
11484 break;
11485 case DO_LARGE_OBJECT:
11486 dumpLO(fout, (const LoInfo *) dobj);
11487 break;
11489 if (dobj->dump & DUMP_COMPONENT_DATA)
11490 {
11491 LoInfo *loinfo;
11492 TocEntry *te;
11493
11494 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
11495 if (loinfo == NULL)
11496 pg_fatal("missing metadata for large objects \"%s\"",
11497 dobj->name);
11498
11499 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
11500 ARCHIVE_OPTS(.tag = dobj->name,
11501 .owner = loinfo->rolname,
11502 .description = "BLOBS",
11503 .section = SECTION_DATA,
11504 .deps = dobj->dependencies,
11505 .nDeps = dobj->nDeps,
11506 .dumpFn = dumpLOs,
11507 .dumpArg = loinfo));
11508
11509 /*
11510 * Set the TocEntry's dataLength in case we are doing a
11511 * parallel dump and want to order dump jobs by table size.
11512 * (We need some size estimate for every TocEntry with a
11513 * DataDumper function.) We don't currently have any cheap
11514 * way to estimate the size of LOs, but fortunately it doesn't
11515 * matter too much as long as we get large batches of LOs
11516 * processed reasonably early. Assume 8K per blob.
11517 */
11518 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
11519 }
11520 break;
11521 case DO_POLICY:
11522 dumpPolicy(fout, (const PolicyInfo *) dobj);
11523 break;
11524 case DO_PUBLICATION:
11525 dumpPublication(fout, (const PublicationInfo *) dobj);
11526 break;
11527 case DO_PUBLICATION_REL:
11528 dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
11529 break;
11532 (const PublicationSchemaInfo *) dobj);
11533 break;
11534 case DO_SUBSCRIPTION:
11535 dumpSubscription(fout, (const SubscriptionInfo *) dobj);
11536 break;
11538 dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
11539 break;
11540 case DO_REL_STATS:
11541 dumpRelationStats(fout, (const RelStatsInfo *) dobj);
11542 break;
11545 /* never dumped, nothing to do */
11546 break;
11547 }
11548}
static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
Definition: pg_dump.c:17772
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:11555
static void dumpCast(Archive *fout, const CastInfo *cast)
Definition: pg_dump.c:13518
static void dumpIndex(Archive *fout, const IndxInfo *indxinfo)
Definition: pg_dump.c:17862
static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
Definition: pg_dump.c:15441
static void dumpAgg(Archive *fout, const AggInfo *agginfo)
Definition: pg_dump.c:15017
static void dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
Definition: pg_dump.c:11073
static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
Definition: pg_dump.c:18875
static void dumpTable(Archive *fout, const TableInfo *tbinfo)
Definition: pg_dump.c:16510
static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
Definition: pg_dump.c:18056
static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
Definition: pg_dump.c:18133
static void dumpType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11760
static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
Definition: pg_dump.c:17704
static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
Definition: pg_dump.c:14064
static void dumpOpr(Archive *fout, const OprInfo *oprinfo)
Definition: pg_dump.c:13752
static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
Definition: pg_dump.c:18798
static void dumpFunc(Archive *fout, const FuncInfo *finfo)
Definition: pg_dump.c:13100
static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
Definition: pg_dump.c:15769
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:12870
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:14413
static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
Definition: pg_dump.c:15963
static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
Definition: pg_dump.c:15521
static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
Definition: pg_dump.c:18013
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:13623
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:15377
static void dumpRule(Archive *fout, const RuleInfo *rinfo)
Definition: pg_dump.c:19086
static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
Definition: pg_dump.c:11632
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:19001
static void dumpConversion(Archive *fout, const ConvInfo *convinfo)
Definition: pg_dump.c:14889
static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
Definition: pg_dump.c:15699
static void dumpProcLang(Archive *fout, const ProcLangInfo *plang)
Definition: pg_dump.c:12916
static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
Definition: pg_dump.c:15579
static void dumpCollation(Archive *fout, const CollInfo *collinfo)
Definition: pg_dump.c:14632
static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
Definition: pg_dump.c:14132
#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 11791 of file pg_dump.c.

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

19002{
19003 DumpOptions *dopt = fout->dopt;
19004 PQExpBuffer query;
19005 PQExpBuffer delqry;
19006 char *qevtname;
19007
19008 /* Do nothing if not dumping schema */
19009 if (!dopt->dumpSchema)
19010 return;
19011
19012 query = createPQExpBuffer();
19013 delqry = createPQExpBuffer();
19014
19015 qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
19016
19017 appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
19018 appendPQExpBufferStr(query, qevtname);
19019 appendPQExpBufferStr(query, " ON ");
19020 appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
19021
19022 if (strcmp("", evtinfo->evttags) != 0)
19023 {
19024 appendPQExpBufferStr(query, "\n WHEN TAG IN (");
19025 appendPQExpBufferStr(query, evtinfo->evttags);
19026 appendPQExpBufferChar(query, ')');
19027 }
19028
19029 appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
19030 appendPQExpBufferStr(query, evtinfo->evtfname);
19031 appendPQExpBufferStr(query, "();\n");
19032
19033 if (evtinfo->evtenabled != 'O')
19034 {
19035 appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
19036 qevtname);
19037 switch (evtinfo->evtenabled)
19038 {
19039 case 'D':
19040 appendPQExpBufferStr(query, "DISABLE");
19041 break;
19042 case 'A':
19043 appendPQExpBufferStr(query, "ENABLE ALWAYS");
19044 break;
19045 case 'R':
19046 appendPQExpBufferStr(query, "ENABLE REPLICA");
19047 break;
19048 default:
19049 appendPQExpBufferStr(query, "ENABLE");
19050 break;
19051 }
19052 appendPQExpBufferStr(query, ";\n");
19053 }
19054
19055 appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
19056 qevtname);
19057
19058 if (dopt->binary_upgrade)
19059 binary_upgrade_extension_member(query, &evtinfo->dobj,
19060 "EVENT TRIGGER", qevtname, NULL);
19061
19062 if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
19063 ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
19064 ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
19065 .owner = evtinfo->evtowner,
19066 .description = "EVENT TRIGGER",
19067 .section = SECTION_POST_DATA,
19068 .createStmt = query->data,
19069 .dropStmt = delqry->data));
19070
19071 if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
19072 dumpComment(fout, "EVENT TRIGGER", qevtname,
19073 NULL, evtinfo->evtowner,
19074 evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
19075
19076 destroyPQExpBuffer(query);
19077 destroyPQExpBuffer(delqry);
19078 free(qevtname);
19079}
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 11632 of file pg_dump.c.

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

15700{
15701 DumpOptions *dopt = fout->dopt;
15702 PQExpBuffer q;
15703 PQExpBuffer delq;
15704 char *qfdwname;
15705
15706 /* Do nothing if not dumping schema */
15707 if (!dopt->dumpSchema)
15708 return;
15709
15710 q = createPQExpBuffer();
15711 delq = createPQExpBuffer();
15712
15713 qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
15714
15715 appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
15716 qfdwname);
15717
15718 if (strcmp(fdwinfo->fdwhandler, "-") != 0)
15719 appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
15720
15721 if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
15722 appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
15723
15724 if (strlen(fdwinfo->fdwoptions) > 0)
15725 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
15726
15727 appendPQExpBufferStr(q, ";\n");
15728
15729 appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
15730 qfdwname);
15731
15732 if (dopt->binary_upgrade)
15734 "FOREIGN DATA WRAPPER", qfdwname,
15735 NULL);
15736
15737 if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15738 ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
15739 ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
15740 .owner = fdwinfo->rolname,
15741 .description = "FOREIGN DATA WRAPPER",
15742 .section = SECTION_PRE_DATA,
15743 .createStmt = q->data,
15744 .dropStmt = delq->data));
15745
15746 /* Dump Foreign Data Wrapper Comments */
15747 if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15748 dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
15749 NULL, fdwinfo->rolname,
15750 fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
15751
15752 /* Handle the ACL */
15753 if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
15754 dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
15755 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
15756 NULL, fdwinfo->rolname, &fdwinfo->dacl);
15757
15758 free(qfdwname);
15759
15761 destroyPQExpBuffer(delq);
15762}
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 15769 of file pg_dump.c.

15770{
15771 DumpOptions *dopt = fout->dopt;
15772 PQExpBuffer q;
15773 PQExpBuffer delq;
15774 PQExpBuffer query;
15775 PGresult *res;
15776 char *qsrvname;
15777 char *fdwname;
15778
15779 /* Do nothing if not dumping schema */
15780 if (!dopt->dumpSchema)
15781 return;
15782
15783 q = createPQExpBuffer();
15784 delq = createPQExpBuffer();
15785 query = createPQExpBuffer();
15786
15787 qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
15788
15789 /* look up the foreign-data wrapper */
15790 appendPQExpBuffer(query, "SELECT fdwname "
15791 "FROM pg_foreign_data_wrapper w "
15792 "WHERE w.oid = '%u'",
15793 srvinfo->srvfdw);
15794 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15795 fdwname = PQgetvalue(res, 0, 0);
15796
15797 appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
15798 if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
15799 {
15800 appendPQExpBufferStr(q, " TYPE ");
15801 appendStringLiteralAH(q, srvinfo->srvtype, fout);
15802 }
15803 if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
15804 {
15805 appendPQExpBufferStr(q, " VERSION ");
15806 appendStringLiteralAH(q, srvinfo->srvversion, fout);
15807 }
15808
15809 appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
15810 appendPQExpBufferStr(q, fmtId(fdwname));
15811
15812 if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
15813 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions);
15814
15815 appendPQExpBufferStr(q, ";\n");
15816
15817 appendPQExpBuffer(delq, "DROP SERVER %s;\n",
15818 qsrvname);
15819
15820 if (dopt->binary_upgrade)
15822 "SERVER", qsrvname, NULL);
15823
15824 if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15825 ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
15826 ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
15827 .owner = srvinfo->rolname,
15828 .description = "SERVER",
15829 .section = SECTION_PRE_DATA,
15830 .createStmt = q->data,
15831 .dropStmt = delq->data));
15832
15833 /* Dump Foreign Server Comments */
15834 if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15835 dumpComment(fout, "SERVER", qsrvname,
15836 NULL, srvinfo->rolname,
15837 srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
15838
15839 /* Handle the ACL */
15840 if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
15841 dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
15842 "FOREIGN SERVER", qsrvname, NULL, NULL,
15843 NULL, srvinfo->rolname, &srvinfo->dacl);
15844
15845 /* Dump user mappings */
15846 if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
15847 dumpUserMappings(fout,
15848 srvinfo->dobj.name, NULL,
15849 srvinfo->rolname,
15850 srvinfo->dobj.catId, srvinfo->dobj.dumpId);
15851
15852 PQclear(res);
15853
15854 free(qsrvname);
15855
15857 destroyPQExpBuffer(delq);
15858 destroyPQExpBuffer(query);
15859}
static void dumpUserMappings(Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
Definition: pg_dump.c:15869
#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 13100 of file pg_dump.c.

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

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

18014{
18015 /* Do nothing if not dumping schema */
18016 if (!fout->dopt->dumpSchema)
18017 return;
18018
18020 {
18022
18023 appendPQExpBuffer(q, "ALTER INDEX %s ",
18024 fmtQualifiedDumpable(attachinfo->parentIdx));
18025 appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
18026 fmtQualifiedDumpable(attachinfo->partitionIdx));
18027
18028 /*
18029 * There is no need for a dropStmt since the drop is done implicitly
18030 * when we drop either the index's table or the partitioned index.
18031 * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
18032 * there's no way to do it anyway. (If you think to change this,
18033 * consider also what to do with --if-exists.)
18034 *
18035 * Although this object doesn't really have ownership as such, set the
18036 * owner field anyway to ensure that the command is run by the correct
18037 * role at restore time.
18038 */
18039 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18040 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18041 .namespace = attachinfo->dobj.namespace->dobj.name,
18042 .owner = attachinfo->parentIdx->indextable->rolname,
18043 .description = "INDEX ATTACH",
18044 .section = SECTION_POST_DATA,
18045 .createStmt = q->data));
18046
18048 }
18049}
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:7625
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 11555 of file pg_dump.c.

11556{
11557 DumpOptions *dopt = fout->dopt;
11558 PQExpBuffer q;
11559 PQExpBuffer delq;
11560 char *qnspname;
11561
11562 /* Do nothing if not dumping schema */
11563 if (!dopt->dumpSchema)
11564 return;
11565
11566 q = createPQExpBuffer();
11567 delq = createPQExpBuffer();
11568
11569 qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
11570
11571 if (nspinfo->create)
11572 {
11573 appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
11574 appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
11575 }
11576 else
11577 {
11578 /* see selectDumpableNamespace() */
11580 "-- *not* dropping schema, since initdb creates it\n");
11582 "-- *not* creating schema, since initdb creates it\n");
11583 }
11584
11585 if (dopt->binary_upgrade)
11587 "SCHEMA", qnspname, NULL);
11588
11589 if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
11590 ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
11591 ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
11592 .owner = nspinfo->rolname,
11593 .description = "SCHEMA",
11594 .section = SECTION_PRE_DATA,
11595 .createStmt = q->data,
11596 .dropStmt = delq->data));
11597
11598 /* Dump Schema Comments and Security Labels */
11599 if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
11600 {
11601 const char *initdb_comment = NULL;
11602
11603 if (!nspinfo->create && strcmp(qnspname, "public") == 0)
11604 initdb_comment = "standard public schema";
11605 dumpCommentExtended(fout, "SCHEMA", qnspname,
11606 NULL, nspinfo->rolname,
11607 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
11608 initdb_comment);
11609 }
11610
11611 if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
11612 dumpSecLabel(fout, "SCHEMA", qnspname,
11613 NULL, nspinfo->rolname,
11614 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
11615
11616 if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
11617 dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
11618 qnspname, NULL, NULL,
11619 NULL, nspinfo->rolname, &nspinfo->dacl);
11620
11621 free(qnspname);
11622
11624 destroyPQExpBuffer(delq);
11625}
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 14132 of file pg_dump.c.

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

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

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

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

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

11074{
11075 const DumpableObject *dobj = &rsinfo->dobj;
11076
11077 /* nothing to do if we are not dumping statistics */
11078 if (!fout->dopt->dumpStatistics)
11079 return;
11080
11082 ARCHIVE_OPTS(.tag = dobj->name,
11083 .namespace = dobj->namespace->dobj.name,
11084 .description = "STATISTICS DATA",
11085 .section = rsinfo->section,
11086 .defnFn = dumpRelationStats_dumper,
11087 .defnArg = rsinfo,
11088 .deps = dobj->dependencies,
11089 .nDeps = dobj->nDeps));
11090}
static char * dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
Definition: pg_dump.c:10813
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 10813 of file pg_dump.c.

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

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

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

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

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

18799{
18800 TableInfo *tbinfo = tdinfo->tdtable;
18801 int64 last;
18802 bool called;
18804
18805 /*
18806 * For versions >= 18, the sequence information is gathered in the sorted
18807 * array before any calls to dumpSequenceData(). See collectSequences()
18808 * for more information.
18809 *
18810 * For older versions, we have to query the sequence relations
18811 * individually.
18812 */
18813 if (fout->remoteVersion < 180000)
18814 {
18815 PGresult *res;
18816
18817 appendPQExpBuffer(query,
18818 "SELECT last_value, is_called FROM %s",
18819 fmtQualifiedDumpable(tbinfo));
18820
18821 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18822
18823 if (PQntuples(res) != 1)
18824 pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
18825 "query to get data of sequence \"%s\" returned %d rows (expected 1)",
18826 PQntuples(res)),
18827 tbinfo->dobj.name, PQntuples(res));
18828
18829 last = strtoi64(PQgetvalue(res, 0, 0), NULL, 10);
18830 called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
18831
18832 PQclear(res);
18833 }
18834 else
18835 {
18836 SequenceItem key = {0};
18837 SequenceItem *entry;
18838
18840 Assert(tbinfo->dobj.catId.oid);
18841
18842 key.oid = tbinfo->dobj.catId.oid;
18843 entry = bsearch(&key, sequences, nsequences,
18844 sizeof(SequenceItem), SequenceItemCmp);
18845
18846 last = entry->last_value;
18847 called = entry->is_called;
18848 }
18849
18850 resetPQExpBuffer(query);
18851 appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
18852 appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
18853 appendPQExpBuffer(query, ", " INT64_FORMAT ", %s);\n",
18854 last, (called ? "true" : "false"));
18855
18856 if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
18858 ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
18859 .namespace = tbinfo->dobj.namespace->dobj.name,
18860 .owner = tbinfo->rolname,
18861 .description = "SEQUENCE SET",
18862 .section = SECTION_DATA,
18863 .createStmt = query->data,
18864 .deps = &(tbinfo->dobj.dumpId),
18865 .nDeps = 1));
18866
18867 destroyPQExpBuffer(query);
18868}
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 12870 of file pg_dump.c.

12871{
12872 DumpOptions *dopt = fout->dopt;
12873 PQExpBuffer q;
12874
12875 /* Do nothing if not dumping schema */
12876 if (!dopt->dumpSchema)
12877 return;
12878
12879 q = createPQExpBuffer();
12880
12881 /*
12882 * Note the lack of a DROP command for the shell type; any required DROP
12883 * is driven off the base type entry, instead. This interacts with
12884 * _printTocEntry()'s use of the presence of a DROP command to decide
12885 * whether an entry needs an ALTER OWNER command. We don't want to alter
12886 * the shell type's owner immediately on creation; that should happen only
12887 * after it's filled in, otherwise the backend complains.
12888 */
12889
12890 if (dopt->binary_upgrade)
12892 stinfo->baseType->dobj.catId.oid,
12893 false, false);
12894
12895 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12896 fmtQualifiedDumpable(stinfo));
12897
12898 if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12899 ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
12900 ARCHIVE_OPTS(.tag = stinfo->dobj.name,
12901 .namespace = stinfo->dobj.namespace->dobj.name,
12902 .owner = stinfo->baseType->rolname,
12903 .description = "SHELL TYPE",
12904 .section = SECTION_PRE_DATA,
12905 .createStmt = q->data));
12906
12908}
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 18056 of file pg_dump.c.

18057{
18058 DumpOptions *dopt = fout->dopt;
18059 PQExpBuffer q;
18060 PQExpBuffer delq;
18061 PQExpBuffer query;
18062 char *qstatsextname;
18063 PGresult *res;
18064 char *stxdef;
18065
18066 /* Do nothing if not dumping schema */
18067 if (!dopt->dumpSchema)
18068 return;
18069
18070 q = createPQExpBuffer();
18071 delq = createPQExpBuffer();
18072 query = createPQExpBuffer();
18073
18074 qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
18075
18076 appendPQExpBuffer(query, "SELECT "
18077 "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
18078 statsextinfo->dobj.catId.oid);
18079
18080 res = ExecuteSqlQueryForSingleRow(fout, query->data);
18081
18082 stxdef = PQgetvalue(res, 0, 0);
18083
18084 /* Result of pg_get_statisticsobjdef is complete except for semicolon */
18085 appendPQExpBuffer(q, "%s;\n", stxdef);
18086
18087 /*
18088 * We only issue an ALTER STATISTICS statement if the stxstattarget entry
18089 * for this statistics object is not the default value.
18090 */
18091 if (statsextinfo->stattarget >= 0)
18092 {
18093 appendPQExpBuffer(q, "ALTER STATISTICS %s ",
18094 fmtQualifiedDumpable(statsextinfo));
18095 appendPQExpBuffer(q, "SET STATISTICS %d;\n",
18096 statsextinfo->stattarget);
18097 }
18098
18099 appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
18100 fmtQualifiedDumpable(statsextinfo));
18101
18102 if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
18103 ArchiveEntry(fout, statsextinfo->dobj.catId,
18104 statsextinfo->dobj.dumpId,
18105 ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
18106 .namespace = statsextinfo->dobj.namespace->dobj.name,
18107 .owner = statsextinfo->rolname,
18108 .description = "STATISTICS",
18109 .section = SECTION_POST_DATA,
18110 .createStmt = q->data,
18111 .dropStmt = delq->data));
18112
18113 /* Dump Statistics Comments */
18114 if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18115 dumpComment(fout, "STATISTICS", qstatsextname,
18116 statsextinfo->dobj.namespace->dobj.name,
18117 statsextinfo->rolname,
18118 statsextinfo->dobj.catId, 0,
18119 statsextinfo->dobj.dumpId);
18120
18121 PQclear(res);
18123 destroyPQExpBuffer(delq);
18124 destroyPQExpBuffer(query);
18125 free(qstatsextname);
18126}
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 16510 of file pg_dump.c.

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

17705{
17706 DumpOptions *dopt = fout->dopt;
17707 PQExpBuffer q;
17708 PGresult *res;
17709 char *partbound;
17710
17711 /* Do nothing if not dumping schema */
17712 if (!dopt->dumpSchema)
17713 return;
17714
17715 q = createPQExpBuffer();
17716
17718 {
17719 /* Set up query for partbound details */
17721 "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
17722
17724 "SELECT pg_get_expr(c.relpartbound, c.oid) "
17725 "FROM pg_class c "
17726 "WHERE c.oid = $1");
17727
17728 ExecuteSqlStatement(fout, q->data);
17729
17731 }
17732
17734 "EXECUTE dumpTableAttach('%u')",
17735 attachinfo->partitionTbl->dobj.catId.oid);
17736
17737 res = ExecuteSqlQueryForSingleRow(fout, q->data);
17738 partbound = PQgetvalue(res, 0, 0);
17739
17740 /* Perform ALTER TABLE on the parent */
17742 "ALTER TABLE ONLY %s ",
17743 fmtQualifiedDumpable(attachinfo->parentTbl));
17745 "ATTACH PARTITION %s %s;\n",
17747 partbound);
17748
17749 /*
17750 * There is no point in creating a drop query as the drop is done by table
17751 * drop. (If you think to change this, see also _printTocEntry().)
17752 * Although this object doesn't really have ownership as such, set the
17753 * owner field anyway to ensure that the command is run by the correct
17754 * role at restore time.
17755 */
17756 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
17757 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
17758 .namespace = attachinfo->dobj.namespace->dobj.name,
17759 .owner = attachinfo->partitionTbl->rolname,
17760 .description = "TABLE ATTACH",
17761 .section = SECTION_PRE_DATA,
17762 .createStmt = q->data));
17763
17764 PQclear(res);
17766}
@ 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 11099 of file pg_dump.c.

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

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

18430{
18431 TableInfo *tbinfo = coninfo->contable;
18432 PQExpBuffer conprefix = createPQExpBuffer();
18433 char *qtabname;
18434
18435 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18436
18437 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
18438 fmtId(coninfo->dobj.name));
18439
18440 if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18441 dumpComment(fout, conprefix->data, qtabname,
18442 tbinfo->dobj.namespace->dobj.name,
18443 tbinfo->rolname,
18444 coninfo->dobj.catId, 0,
18445 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
18446
18447 destroyPQExpBuffer(conprefix);
18448 free(qtabname);
18449}

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

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

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

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

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

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

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

15442{
15443 DumpOptions *dopt = fout->dopt;
15444 PQExpBuffer q;
15445 PQExpBuffer delq;
15446 PQExpBuffer query;
15447 char *qdictname;
15448 PGresult *res;
15449 char *nspname;
15450 char *tmplname;
15451
15452 /* Do nothing if not dumping schema */
15453 if (!dopt->dumpSchema)
15454 return;
15455
15456 q = createPQExpBuffer();
15457 delq = createPQExpBuffer();
15458 query = createPQExpBuffer();
15459
15460 qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
15461
15462 /* Fetch name and namespace of the dictionary's template */
15463 appendPQExpBuffer(query, "SELECT nspname, tmplname "
15464 "FROM pg_ts_template p, pg_namespace n "
15465 "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
15466 dictinfo->dicttemplate);
15467 res = ExecuteSqlQueryForSingleRow(fout, query->data);
15468 nspname = PQgetvalue(res, 0, 0);
15469 tmplname = PQgetvalue(res, 0, 1);
15470
15471 appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
15472 fmtQualifiedDumpable(dictinfo));
15473
15474 appendPQExpBufferStr(q, " TEMPLATE = ");
15475 appendPQExpBuffer(q, "%s.", fmtId(nspname));
15476 appendPQExpBufferStr(q, fmtId(tmplname));
15477
15478 PQclear(res);
15479
15480 /* the dictinitoption can be dumped straight into the command */
15481 if (dictinfo->dictinitoption)
15482 appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption);
15483
15484 appendPQExpBufferStr(q, " );\n");
15485
15486 appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
15487 fmtQualifiedDumpable(dictinfo));
15488
15489 if (dopt->binary_upgrade)
15491 "TEXT SEARCH DICTIONARY", qdictname,
15492 dictinfo->dobj.namespace->dobj.name);
15493
15494 if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15495 ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
15496 ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
15497 .namespace = dictinfo->dobj.namespace->dobj.name,
15498 .owner = dictinfo->rolname,
15499 .description = "TEXT SEARCH DICTIONARY",
15500 .section = SECTION_PRE_DATA,
15501 .createStmt = q->data,
15502 .dropStmt = delq->data));
15503
15504 /* Dump Dictionary Comments */
15505 if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15506 dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
15507 dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
15508 dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
15509
15511 destroyPQExpBuffer(delq);
15512 destroyPQExpBuffer(query);
15513 free(qdictname);
15514}
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 15377 of file pg_dump.c.

15378{
15379 DumpOptions *dopt = fout->dopt;
15380 PQExpBuffer q;
15381 PQExpBuffer delq;
15382 char *qprsname;
15383
15384 /* Do nothing if not dumping schema */
15385 if (!dopt->dumpSchema)
15386 return;
15387
15388 q = createPQExpBuffer();
15389 delq = createPQExpBuffer();
15390
15391 qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
15392
15393 appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
15394 fmtQualifiedDumpable(prsinfo));
15395
15396 appendPQExpBuffer(q, " START = %s,\n",
15397 convertTSFunction(fout, prsinfo->prsstart));
15398 appendPQExpBuffer(q, " GETTOKEN = %s,\n",
15399 convertTSFunction(fout, prsinfo->prstoken));
15400 appendPQExpBuffer(q, " END = %s,\n",
15401 convertTSFunction(fout, prsinfo->prsend));
15402 if (prsinfo->prsheadline != InvalidOid)
15403 appendPQExpBuffer(q, " HEADLINE = %s,\n",
15404 convertTSFunction(fout, prsinfo->prsheadline));
15405 appendPQExpBuffer(q, " LEXTYPES = %s );\n",
15406 convertTSFunction(fout, prsinfo->prslextype));
15407
15408 appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
15409 fmtQualifiedDumpable(prsinfo));
15410
15411 if (dopt->binary_upgrade)
15413 "TEXT SEARCH PARSER", qprsname,
15414 prsinfo->dobj.namespace->dobj.name);
15415
15416 if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15417 ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
15418 ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
15419 .namespace = prsinfo->dobj.namespace->dobj.name,
15420 .description = "TEXT SEARCH PARSER",
15421 .section = SECTION_PRE_DATA,
15422 .createStmt = q->data,
15423 .dropStmt = delq->data));
15424
15425 /* Dump Parser Comments */
15426 if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15427 dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
15428 prsinfo->dobj.namespace->dobj.name, "",
15429 prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
15430
15432 destroyPQExpBuffer(delq);
15433 free(qprsname);
15434}
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:14042
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 15521 of file pg_dump.c.

15522{
15523 DumpOptions *dopt = fout->dopt;
15524 PQExpBuffer q;
15525 PQExpBuffer delq;
15526 char *qtmplname;
15527
15528 /* Do nothing if not dumping schema */
15529 if (!dopt->dumpSchema)
15530 return;
15531
15532 q = createPQExpBuffer();
15533 delq = createPQExpBuffer();
15534
15535 qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
15536
15537 appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
15538 fmtQualifiedDumpable(tmplinfo));
15539
15540 if (tmplinfo->tmplinit != InvalidOid)
15541 appendPQExpBuffer(q, " INIT = %s,\n",
15542 convertTSFunction(fout, tmplinfo->tmplinit));
15543 appendPQExpBuffer(q, " LEXIZE = %s );\n",
15544 convertTSFunction(fout, tmplinfo->tmpllexize));
15545
15546 appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
15547 fmtQualifiedDumpable(tmplinfo));
15548
15549 if (dopt->binary_upgrade)
15551 "TEXT SEARCH TEMPLATE", qtmplname,
15552 tmplinfo->dobj.namespace->dobj.name);
15553
15554 if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15555 ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
15556 ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
15557 .namespace = tmplinfo->dobj.namespace->dobj.name,
15558 .description = "TEXT SEARCH TEMPLATE",
15559 .section = SECTION_PRE_DATA,
15560 .createStmt = q->data,
15561 .dropStmt = delq->data));
15562
15563 /* Dump Template Comments */
15564 if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15565 dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
15566 tmplinfo->dobj.namespace->dobj.name, "",
15567 tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
15568
15570 destroyPQExpBuffer(delq);
15571 free(qtmplname);
15572}
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 11760 of file pg_dump.c.

11761{
11762 DumpOptions *dopt = fout->dopt;
11763
11764 /* Do nothing if not dumping schema */
11765 if (!dopt->dumpSchema)
11766 return;
11767
11768 /* Dump out in proper style */
11769 if (tyinfo->typtype == TYPTYPE_BASE)
11770 dumpBaseType(fout, tyinfo);
11771 else if (tyinfo->typtype == TYPTYPE_DOMAIN)
11772 dumpDomain(fout, tyinfo);
11773 else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
11774 dumpCompositeType(fout, tyinfo);
11775 else if (tyinfo->typtype == TYPTYPE_ENUM)
11776 dumpEnumType(fout, tyinfo);
11777 else if (tyinfo->typtype == TYPTYPE_RANGE)
11778 dumpRangeType(fout, tyinfo);
11779 else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
11780 dumpUndefinedType(fout, tyinfo);
11781 else
11782 pg_log_warning("typtype of data type \"%s\" appears to be invalid",
11783 tyinfo->dobj.name);
11784}
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12153
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11931
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12402
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12089
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12575
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11791
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 12089 of file pg_dump.c.

12090{
12091 DumpOptions *dopt = fout->dopt;
12094 char *qtypname;
12095 char *qualtypname;
12096
12097 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
12098 qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
12099
12100 appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
12101
12102 if (dopt->binary_upgrade)
12104 tyinfo->dobj.catId.oid,
12105 false, false);
12106
12107 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
12108 qualtypname);
12109
12110 if (dopt->binary_upgrade)
12112 "TYPE", qtypname,
12113 tyinfo->dobj.namespace->dobj.name);
12114
12115 if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
12116 ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
12117 ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
12118 .namespace = tyinfo->dobj.namespace->dobj.name,
12119 .owner = tyinfo->rolname,
12120 .description = "TYPE",
12121 .section = SECTION_PRE_DATA,
12122 .createStmt = q->data,
12123 .dropStmt = delq->data));
12124
12125 /* Dump Type Comments and Security Labels */
12126 if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
12127 dumpComment(fout, "TYPE", qtypname,
12128 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12129 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12130
12131 if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
12132 dumpSecLabel(fout, "TYPE", qtypname,
12133 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
12134 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
12135
12136 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
12137 dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
12138 qtypname, NULL,
12139 tyinfo->dobj.namespace->dobj.name,
12140 NULL, tyinfo->rolname, &tyinfo->dacl);
12141
12143 destroyPQExpBuffer(delq);
12144 free(qtypname);
12145 free(qualtypname);
12146}

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

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

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 /*
10769 * Scan the TOC for the next set of relevant stats entries. We assume
10770 * that statistics are dumped in the order they are listed in the TOC.
10771 * This is perhaps not the sturdiest assumption, so we verify it matches
10772 * reality in dumpRelationStats_dumper().
10773 */
10774 for (; te != AH->toc && count < max_rels; te = te->next)
10775 {
10776 if ((te->reqs & REQ_STATS) != 0 &&
10777 strcmp(te->desc, "STATISTICS DATA") == 0)
10778 {
10779 appendPQExpBuffer(nspnames, "%s%s", count ? "," : "",
10780 fmtId(te->namespace));
10781 appendPQExpBuffer(relnames, "%s%s", count ? "," : "",
10782 fmtId(te->tag));
10783 count++;
10784 }
10785 }
10786
10787 /* Execute the query for the next batch of relations. */
10788 if (count > 0)
10789 {
10791
10792 appendPQExpBuffer(query, "EXECUTE getAttributeStats("
10793 "'{%s}'::pg_catalog.name[],"
10794 "'{%s}'::pg_catalog.name[])",
10795 nspnames->data, relnames->data);
10796 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10797 destroyPQExpBuffer(query);
10798 }
10799
10800 destroyPQExpBuffer(nspnames);
10801 destroyPQExpBuffer(relnames);
10802 return res;
10803}
@ archTar
Definition: pg_backup.h:43
#define MAX_ATTR_STATS_RELS
Definition: pg_dump.c:213
ArchiveFormat format

References appendPQExpBuffer(), archTar, createPQExpBuffer(), PQExpBufferData::data, _tocEntry::desc, destroyPQExpBuffer(), ExecuteSqlQuery(), fmtId(), _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 11197 of file pg_dump.c.

11198{
11199 CommentItem *middle = NULL;
11200 CommentItem *low;
11201 CommentItem *high;
11202 int nmatch;
11203
11204 /*
11205 * Do binary search to find some item matching the object.
11206 */
11207 low = &comments[0];
11208 high = &comments[ncomments - 1];
11209 while (low <= high)
11210 {
11211 middle = low + (high - low) / 2;
11212
11213 if (classoid < middle->classoid)
11214 high = middle - 1;
11215 else if (classoid > middle->classoid)
11216 low = middle + 1;
11217 else if (objoid < middle->objoid)
11218 high = middle - 1;
11219 else if (objoid > middle->objoid)
11220 low = middle + 1;
11221 else
11222 break; /* found a match */
11223 }
11224
11225 if (low > high) /* no matches */
11226 {
11227 *items = NULL;
11228 return 0;
11229 }
11230
11231 /*
11232 * Now determine how many items match the object. The search loop
11233 * invariant still holds: only items between low and high inclusive could
11234 * match.
11235 */
11236 nmatch = 1;
11237 while (middle > low)
11238 {
11239 if (classoid != middle[-1].classoid ||
11240 objoid != middle[-1].objoid)
11241 break;
11242 middle--;
11243 nmatch++;
11244 }
11245
11246 *items = middle;
11247
11248 middle += nmatch;
11249 while (middle <= high)
11250 {
11251 if (classoid != middle->classoid ||
11252 objoid != middle->objoid)
11253 break;
11254 middle++;
11255 nmatch++;
11256 }
11257
11258 return nmatch;
11259}
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 19878 of file pg_dump.c.

19880{
19881 int i;
19882
19883 /*
19884 * Ignore section boundary objects: if we search through them, we'll
19885 * report lots of bogus dependencies.
19886 */
19887 if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
19889 return;
19890
19891 for (i = 0; i < dobj->nDeps; i++)
19892 {
19893 DumpId depid = dobj->dependencies[i];
19894
19895 if (TocIDRequired(AH, depid) != 0)
19896 {
19897 /* Object will be dumped, so just reference it as a dependency */
19898 if (*nDeps >= *allocDeps)
19899 {
19900 *allocDeps *= 2;
19901 *dependencies = (DumpId *) pg_realloc(*dependencies,
19902 *allocDeps * sizeof(DumpId));
19903 }
19904 (*dependencies)[*nDeps] = depid;
19905 (*nDeps)++;
19906 }
19907 else
19908 {
19909 /*
19910 * Object will not be dumped, so recursively consider its deps. We
19911 * rely on the assumption that sortDumpableObjects already broke
19912 * any dependency loops, else we might recurse infinitely.
19913 */
19914 DumpableObject *otherdobj = findObjectByDumpId(depid);
19915
19916 if (otherdobj)
19917 findDumpableDependencies(AH, otherdobj,
19918 dependencies, nDeps, allocDeps);
19919 }
19920 }
19921}
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 16345 of file pg_dump.c.

16346{
16347 SecLabelItem *middle = NULL;
16348 SecLabelItem *low;
16349 SecLabelItem *high;
16350 int nmatch;
16351
16352 if (nseclabels <= 0) /* no labels, so no match is possible */
16353 {
16354 *items = NULL;
16355 return 0;
16356 }
16357
16358 /*
16359 * Do binary search to find some item matching the object.
16360 */
16361 low = &seclabels[0];
16362 high = &seclabels[nseclabels - 1];
16363 while (low <= high)
16364 {
16365 middle = low + (high - low) / 2;
16366
16367 if (classoid < middle->classoid)
16368 high = middle - 1;
16369 else if (classoid > middle->classoid)
16370 low = middle + 1;
16371 else if (objoid < middle->objoid)
16372 high = middle - 1;
16373 else if (objoid > middle->objoid)
16374 low = middle + 1;
16375 else
16376 break; /* found a match */
16377 }
16378
16379 if (low > high) /* no matches */
16380 {
16381 *items = NULL;
16382 return 0;
16383 }
16384
16385 /*
16386 * Now determine how many items match the object. The search loop
16387 * invariant still holds: only items between low and high inclusive could
16388 * match.
16389 */
16390 nmatch = 1;
16391 while (middle > low)
16392 {
16393 if (classoid != middle[-1].classoid ||
16394 objoid != middle[-1].objoid)
16395 break;
16396 middle--;
16397 nmatch++;
16398 }
16399
16400 *items = middle;
16401
16402 middle += nmatch;
16403 while (middle <= high)
16404 {
16405 if (classoid != middle->classoid ||
16406 objoid != middle->objoid)
16407 break;
16408 middle++;
16409 nmatch++;
16410 }
16411
16412 return nmatch;
16413}

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

19986{
19987 int numatts = ti->numatts;
19988 char **attnames = ti->attnames;
19989 bool *attisdropped = ti->attisdropped;
19990 char *attgenerated = ti->attgenerated;
19991 bool needComma;
19992 int i;
19993
19994 appendPQExpBufferChar(buffer, '(');
19995 needComma = false;
19996 for (i = 0; i < numatts; i++)
19997 {
19998 if (attisdropped[i])
19999 continue;
20000 if (attgenerated[i])
20001 continue;
20002 if (needComma)
20003 appendPQExpBufferStr(buffer, ", ");
20004 appendPQExpBufferStr(buffer, fmtId(attnames[i]));
20005 needComma = true;
20006 }
20007
20008 if (!needComma)
20009 return ""; /* no undropped columns */
20010
20011 appendPQExpBufferChar(buffer, ')');
20012 return buffer->data;
20013}

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

14986{
14988 int j;
14989
14991 if (honor_quotes)
14992 appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
14993 else
14994 appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
14995
14996 if (agginfo->aggfn.nargs == 0)
14997 appendPQExpBufferStr(&buf, "(*)");
14998 else
14999 {
15001 for (j = 0; j < agginfo->aggfn.nargs; j++)
15002 appendPQExpBuffer(&buf, "%s%s",
15003 (j > 0) ? ", " : "",
15005 agginfo->aggfn.argtypes[j],
15006 zeroIsError));
15008 }
15009 return buf.data;
15010}

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

13049{
13051
13054 if (is_agg && finfo->nargs == 0)
13055 appendPQExpBufferStr(&fn, "(*)");
13056 else
13057 appendPQExpBuffer(&fn, "(%s)", funcargs);
13058 return fn.data;
13059}
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 13071 of file pg_dump.c.

13072{
13074 int j;
13075
13077 if (honor_quotes)
13078 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
13079 else
13080 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
13081 for (j = 0; j < finfo->nargs; j++)
13082 {
13083 if (j > 0)
13084 appendPQExpBufferStr(&fn, ", ");
13085
13087 getFormattedTypeName(fout, finfo->argtypes[j],
13088 zeroIsError));
13089 }
13091 return fn.data;
13092}
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 17833 of file pg_dump.c.

17834{
17835 if (attrnum > 0 && attrnum <= tblInfo->numatts)
17836 return tblInfo->attnames[attrnum - 1];
17837 switch (attrnum)
17838 {
17840 return "ctid";
17842 return "xmin";
17844 return "cmin";
17846 return "xmax";
17848 return "cmax";
17850 return "tableoid";
17851 }
17852 pg_fatal("invalid column number %d for table \"%s\"",
17853 attrnum, tblInfo->dobj.name);
17854 return NULL; /* keep compiler quiet */
17855}
#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 19527 of file pg_dump.c.

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

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

19255{
19256 PQExpBuffer query;
19257 PGresult *res;
19258 int ntups,
19259 i;
19260 int i_classid,
19261 i_objid,
19262 i_refobjid;
19263 ExtensionInfo *ext;
19264
19265 /* Nothing to do if no extensions */
19266 if (numExtensions == 0)
19267 return;
19268
19269 query = createPQExpBuffer();
19270
19271 /* refclassid constraint is redundant but may speed the search */
19272 appendPQExpBufferStr(query, "SELECT "
19273 "classid, objid, refobjid "
19274 "FROM pg_depend "
19275 "WHERE refclassid = 'pg_extension'::regclass "
19276 "AND deptype = 'e' "
19277 "ORDER BY 3");
19278
19279 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19280
19281 ntups = PQntuples(res);
19282
19283 i_classid = PQfnumber(res, "classid");
19284 i_objid = PQfnumber(res, "objid");
19285 i_refobjid = PQfnumber(res, "refobjid");
19286
19287 /*
19288 * Since we ordered the SELECT by referenced ID, we can expect that
19289 * multiple entries for the same extension will appear together; this
19290 * saves on searches.
19291 */
19292 ext = NULL;
19293
19294 for (i = 0; i < ntups; i++)
19295 {
19296 CatalogId objId;
19297 Oid extId;
19298
19299 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
19300 objId.oid = atooid(PQgetvalue(res, i, i_objid));
19301 extId = atooid(PQgetvalue(res, i, i_refobjid));
19302
19303 if (ext == NULL ||
19304 ext->dobj.catId.oid != extId)
19305 ext = findExtensionByOid(extId);
19306
19307 if (ext == NULL)
19308 {
19309 /* shouldn't happen */
19310 pg_log_warning("could not find referenced extension %u", extId);
19311 continue;
19312 }
19313
19314 recordExtensionMembership(objId, ext);
19315 }
19316
19317 PQclear(res);
19318
19319 destroyPQExpBuffer(query);
19320}
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 14012 of file pg_dump.c.

14013{
14014 OprInfo *oprInfo;
14015
14016 /* In all cases "0" means a null reference */
14017 if (strcmp(oproid, "0") == 0)
14018 return NULL;
14019
14020 oprInfo = findOprByOid(atooid(oproid));
14021 if (oprInfo == NULL)
14022 {
14023 pg_log_warning("could not find operator with OID %s",
14024 oproid);
14025 return NULL;
14026 }
14027
14028 return psprintf("OPERATOR(%s.%s)",
14029 fmtId(oprInfo->dobj.namespace->dobj.name),
14030 oprInfo->dobj.name);
14031}
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 19934 of file pg_dump.c.

19935{
19936 TypeInfo *typeInfo;
19937 char *result;
19938 PQExpBuffer query;
19939 PGresult *res;
19940
19941 if (oid == 0)
19942 {
19943 if ((opts & zeroAsStar) != 0)
19944 return "*";
19945 else if ((opts & zeroAsNone) != 0)
19946 return "NONE";
19947 }
19948
19949 /* see if we have the result cached in the type's TypeInfo record */
19950 typeInfo = findTypeByOid(oid);
19951 if (typeInfo && typeInfo->ftypname)
19952 return typeInfo->ftypname;
19953
19954 query = createPQExpBuffer();
19955 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
19956 oid);
19957
19958 res = ExecuteSqlQueryForSingleRow(fout, query->data);
19959
19960 /* result of format_type is already quoted */
19961 result = pg_strdup(PQgetvalue(res, 0, 0));
19962
19963 PQclear(res);
19964 destroyPQExpBuffer(query);
19965
19966 /*
19967 * Cache the result for re-use in later requests, if possible. If we
19968 * don't have a TypeInfo for the type, the string will be leaked once the
19969 * caller is done with it ... but that case really should not happen, so
19970 * leaking if it does seems acceptable.
19971 */
19972 if (typeInfo)
19973 typeInfo->ftypname = result;
19974
19975 return result;
19976}
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
void appendPGArray(PQExpBuffer buffer, const char *value)
Definition: string_utils.c:902

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:7580
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:19704
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3756
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:19680
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:19830
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:19527
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:11274
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:11359
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:16424
static void collectSequences(Archive *fout)
Definition: pg_dump.c:18483
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:20050
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:123
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 20019 of file pg_dump.c.

20020{
20021 /* Don't want to print it if it's just "{}" */
20022 return (reloptions != NULL && strlen(reloptions) > 2);
20023}

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

◆ parse_sequence_type()

static SeqType parse_sequence_type ( const char *  name)
inlinestatic

Definition at line 18452 of file pg_dump.c.

18453{
18454 for (int i = 0; i < lengthof(SeqTypeNames); i++)
18455 {
18456 if (strcmp(SeqTypeNames[i], name) == 0)
18457 return (SeqType) i;
18458 }
18459
18460 pg_fatal("unrecognized sequence type: %s", name);
18461 return (SeqType) 0; /* keep compiler quiet */
18462}
#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 19346 of file pg_dump.c.

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

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:7453

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

20051{
20052 FilterStateData fstate;
20053 char *objname;
20054 FilterCommandType comtype;
20055 FilterObjectType objtype;
20056
20057 filter_init(&fstate, filename, exit_nicely);
20058
20059 while (filter_read_item(&fstate, &objname, &comtype, &objtype))
20060 {
20061 if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
20062 {
20063 switch (objtype)
20064 {
20066 break;
20073 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20074 "include",
20075 filter_object_type_name(objtype));
20076 exit_nicely(1);
20077 break; /* unreachable */
20078
20081 break;
20084 break;
20087 dopt->include_everything = false;
20088 break;
20091 dopt->include_everything = false;
20092 break;
20095 objname);
20096 dopt->include_everything = false;
20097 break;
20098 }
20099 }
20100 else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
20101 {
20102 switch (objtype)
20103 {
20105 break;
20111 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20112 "exclude",
20113 filter_object_type_name(objtype));
20114 exit_nicely(1);
20115 break;
20116
20119 break;
20122 objname);
20123 break;
20126 objname);
20127 break;
20130 break;
20133 break;
20136 objname);
20137 break;
20138 }
20139 }
20140 else
20141 {
20142 Assert(comtype == FILTER_COMMAND_TYPE_NONE);
20143 Assert(objtype == FILTER_OBJECT_TYPE_NONE);
20144 }
20145
20146 if (objname)
20147 free(objname);
20148 }
20149
20150 filter_free(&fstate);
20151}
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 18468 of file pg_dump.c.

18469{
18470 SequenceItem v1 = *((const SequenceItem *) p1);
18471 SequenceItem v2 = *((const SequenceItem *) p2);
18472
18473 return pg_cmp_u32(v1.oid, v2.oid);
18474}

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:7715
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7723
#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().