PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_dump.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_aggregate_d.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_attribute_d.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_cast_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_default_acl_d.h"
#include "catalog/pg_largeobject_d.h"
#include "catalog/pg_proc_d.h"
#include "catalog/pg_publication_d.h"
#include "catalog/pg_subscription_d.h"
#include "catalog/pg_type_d.h"
#include "common/connect.h"
#include "common/int.h"
#include "common/relpath.h"
#include "common/shortest_dec.h"
#include "compress_io.h"
#include "dumputils.h"
#include "fe_utils/option_utils.h"
#include "fe_utils/string_utils.h"
#include "filter.h"
#include "getopt_long.h"
#include "libpq/libpq-fs.h"
#include "parallel.h"
#include "pg_backup_db.h"
#include "pg_backup_utils.h"
#include "pg_dump.h"
#include "storage/block.h"
Include dependency graph for pg_dump.c:

Go to the source code of this file.

Data Structures

struct  RoleNameItem
 
struct  CommentItem
 
struct  SecLabelItem
 
struct  BinaryUpgradeClassOidItem
 
struct  SequenceItem
 

Macros

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

Typedefs

typedef enum SeqType SeqType
 
typedef enum OidOptions OidOptions
 

Enumerations

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

Functions

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

Variables

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

Macro Definition Documentation

◆ DUMP_DEFAULT_ROWS_PER_INSERT

#define DUMP_DEFAULT_ROWS_PER_INSERT   1

Definition at line 219 of file pg_dump.c.

◆ fmtQualifiedDumpable

#define fmtQualifiedDumpable (   obj)
Value:
fmtQualifiedId((obj)->dobj.namespace->dobj.name, \
(obj)->dobj.name)
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:296

Definition at line 231 of file pg_dump.c.

◆ MAX_ATTR_STATS_RELS

#define MAX_ATTR_STATS_RELS   64

Definition at line 213 of file pg_dump.c.

◆ MAX_BLOBS_PER_ARCHIVE_ENTRY

#define MAX_BLOBS_PER_ARCHIVE_ENTRY   1000

Definition at line 226 of file pg_dump.c.

Typedef Documentation

◆ OidOptions

typedef enum OidOptions OidOptions

◆ SeqType

typedef enum SeqType SeqType

Enumeration Type Documentation

◆ OidOptions

enum OidOptions
Enumerator
zeroIsError 
zeroAsStar 
zeroAsNone 

Definition at line 139 of file pg_dump.c.

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

◆ SeqType

enum SeqType
Enumerator
SEQTYPE_SMALLINT 
SEQTYPE_INTEGER 
SEQTYPE_BIGINT 

Definition at line 108 of file pg_dump.c.

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

Function Documentation

◆ addBoundaryDependencies()

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

Definition at line 19694 of file pg_dump.c.

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

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

10704{
10705 appendPQExpBufferStr(out, ",\n\t");
10706
10707 appendStringLiteralAH(out, argname, fout);
10708 appendPQExpBufferStr(out, ", ");
10709
10710 appendStringLiteralAH(out, argval, fout);
10711 appendPQExpBuffer(out, "::%s", argtype);
10712}
#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 20021 of file pg_dump.c.

20023{
20024 bool res;
20025
20026 res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
20027 fout->std_strings);
20028 if (!res)
20029 pg_log_warning("could not parse %s array", "reloptions");
20030}
#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:742
#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:876
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 19820 of file pg_dump.c.

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

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

10423{
10424 PGresult *res;
10425 const char *query;
10426 int i;
10427
10428 query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
10429
10430 res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
10431
10432 nrolenames = PQntuples(res);
10433
10435
10436 for (i = 0; i < nrolenames; i++)
10437 {
10438 rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
10440 }
10441
10442 PQclear(res);
10443}
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 16414 of file pg_dump.c.

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

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

13962{
13963 char *name;
13964 char *paren;
13965 bool inquote;
13966
13967 /* In all cases "-" means a null reference */
13968 if (strcmp(proc, "-") == 0)
13969 return NULL;
13970
13971 name = pg_strdup(proc);
13972 /* find non-double-quoted left paren */
13973 inquote = false;
13974 for (paren = name; *paren; paren++)
13975 {
13976 if (*paren == '(' && !inquote)
13977 {
13978 *paren = '\0';
13979 break;
13980 }
13981 if (*paren == '"')
13982 inquote = !inquote;
13983 }
13984 return name;
13985}
const char * name

References name, and pg_strdup().

Referenced by dumpOpr().

◆ convertTSFunction()

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

Definition at line 14032 of file pg_dump.c.

14033{
14034 char *result;
14035 char query[128];
14036 PGresult *res;
14037
14038 snprintf(query, sizeof(query),
14039 "SELECT '%u'::pg_catalog.regproc", funcOid);
14040 res = ExecuteSqlQueryForSingleRow(fout, query);
14041
14042 result = pg_strdup(PQgetvalue(res, 0, 0));
14043
14044 PQclear(res);
14045
14046 return result;
14047}
#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 19670 of file pg_dump.c.

19671{
19672 DumpableObject *dobjs;
19673
19674 dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
19675
19676 dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
19677 dobjs[0].catId = nilCatalogId;
19678 AssignDumpId(dobjs + 0);
19679 dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
19680
19681 dobjs[1].objType = DO_POST_DATA_BOUNDARY;
19682 dobjs[1].catId = nilCatalogId;
19683 AssignDumpId(dobjs + 1);
19684 dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
19685
19686 return dobjs;
19687}
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:634
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 16689 of file pg_dump.c.

16690{
16691 PQExpBuffer result = createPQExpBuffer();
16692 int j;
16693
16694 appendPQExpBufferStr(result, "SELECT");
16695
16696 for (j = 0; j < tbinfo->numatts; j++)
16697 {
16698 if (j > 0)
16699 appendPQExpBufferChar(result, ',');
16700 appendPQExpBufferStr(result, "\n ");
16701
16702 appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
16703
16704 /*
16705 * Must add collation if not default for the type, because CREATE OR
16706 * REPLACE VIEW won't change it
16707 */
16708 if (OidIsValid(tbinfo->attcollation[j]))
16709 {
16710 CollInfo *coll;
16711
16712 coll = findCollationByOid(tbinfo->attcollation[j]);
16713 if (coll)
16714 appendPQExpBuffer(result, " COLLATE %s",
16715 fmtQualifiedDumpable(coll));
16716 }
16717
16718 appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
16719 }
16720
16721 return result;
16722}
CollInfo * findCollationByOid(Oid oid)
Definition: common.c:931
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 16640 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

10690{
10691 dumpCommentExtended(fout, type, name, namespace, owner,
10692 catalogId, subid, dumpId, NULL);
10693}
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:10586

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

15690{
15691 DumpOptions *dopt = fout->dopt;
15692 PQExpBuffer q;
15693 PQExpBuffer delq;
15694 char *qfdwname;
15695
15696 /* Do nothing if not dumping schema */
15697 if (!dopt->dumpSchema)
15698 return;
15699
15700 q = createPQExpBuffer();
15701 delq = createPQExpBuffer();
15702
15703 qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
15704
15705 appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
15706 qfdwname);
15707
15708 if (strcmp(fdwinfo->fdwhandler, "-") != 0)
15709 appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
15710
15711 if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
15712 appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
15713
15714 if (strlen(fdwinfo->fdwoptions) > 0)
15715 appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions);
15716
15717 appendPQExpBufferStr(q, ";\n");
15718
15719 appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
15720 qfdwname);
15721
15722 if (dopt->binary_upgrade)
15724 "FOREIGN DATA WRAPPER", qfdwname,
15725 NULL);
15726
15727 if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15728 ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
15729 ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
15730 .owner = fdwinfo->rolname,
15731 .description = "FOREIGN DATA WRAPPER",
15732 .section = SECTION_PRE_DATA,
15733 .createStmt = q->data,
15734 .dropStmt = delq->data));
15735
15736 /* Dump Foreign Data Wrapper Comments */
15737 if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15738 dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
15739 NULL, fdwinfo->rolname,
15740 fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
15741
15742 /* Handle the ACL */
15743 if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
15744 dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
15745 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
15746 NULL, fdwinfo->rolname, &fdwinfo->dacl);
15747
15748 free(qfdwname);
15749
15751 destroyPQExpBuffer(delq);
15752}
char * fdwhandler
Definition: pg_dump.h:596
const char * rolname
Definition: pg_dump.h:595
char * fdwvalidator
Definition: pg_dump.h:597
char * fdwoptions
Definition: pg_dump.h:598
DumpableAcl dacl
Definition: pg_dump.h:594
DumpableObject dobj
Definition: pg_dump.h:593

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

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

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

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

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

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

18004{
18005 /* Do nothing if not dumping schema */
18006 if (!fout->dopt->dumpSchema)
18007 return;
18008
18010 {
18012
18013 appendPQExpBuffer(q, "ALTER INDEX %s ",
18014 fmtQualifiedDumpable(attachinfo->parentIdx));
18015 appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
18016 fmtQualifiedDumpable(attachinfo->partitionIdx));
18017
18018 /*
18019 * There is no need for a dropStmt since the drop is done implicitly
18020 * when we drop either the index's table or the partitioned index.
18021 * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
18022 * there's no way to do it anyway. (If you think to change this,
18023 * consider also what to do with --if-exists.)
18024 *
18025 * Although this object doesn't really have ownership as such, set the
18026 * owner field anyway to ensure that the command is run by the correct
18027 * role at restore time.
18028 */
18029 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
18030 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
18031 .namespace = attachinfo->dobj.namespace->dobj.name,
18032 .owner = attachinfo->parentIdx->indextable->rolname,
18033 .description = "INDEX ATTACH",
18034 .section = SECTION_POST_DATA,
18035 .createStmt = q->data));
18036
18038 }
18039}
IndxInfo * parentIdx
Definition: pg_dump.h:435

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:630
DumpableAcl dacl
Definition: pg_dump.h:631
Oid looids[FLEXIBLE_ARRAY_MEMBER]
Definition: pg_dump.h:634

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

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

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

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

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

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

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

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:661
bool puballtables
Definition: pg_dump.h:662
bool pubtruncate
Definition: pg_dump.h:666
PublishGencolsType pubgencols_type
Definition: pg_dump.h:668
DumpableObject dobj
Definition: pg_dump.h:660

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:692
DumpableObject dobj
Definition: pg_dump.h:690
PublicationInfo * publication
Definition: pg_dump.h:691

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

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

11064{
11065 const DumpableObject *dobj = &rsinfo->dobj;
11066
11067 /* nothing to do if we are not dumping statistics */
11068 if (!fout->dopt->dumpStatistics)
11069 return;
11070
11072 ARCHIVE_OPTS(.tag = dobj->name,
11073 .namespace = dobj->namespace->dobj.name,
11074 .description = "STATISTICS DATA",
11075 .section = rsinfo->section,
11076 .defnFn = dumpRelationStats_dumper,
11077 .defnArg = rsinfo,
11078 .deps = dobj->dependencies,
11079 .nDeps = dobj->nDeps));
11080}
static char * dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
Definition: pg_dump.c:10803
bool dumpStatistics
Definition: pg_backup.h:215
teSection section
Definition: pg_dump.h:454
DumpableObject dobj
Definition: pg_dump.h:441

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

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

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

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

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

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

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

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

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

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

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

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 appendPQExpBuffer(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:715
bool subpasswordrequired
Definition: pg_dump.h:707
char * suborigin
Definition: pg_dump.h:714
const char * rolname
Definition: pg_dump.h:701
char * subsynccommit
Definition: pg_dump.h:712
char * subpublications
Definition: pg_dump.h:713
bool subdisableonerr
Definition: pg_dump.h:706
bool subrunasowner
Definition: pg_dump.h:708
char * subslotname
Definition: pg_dump.h:711
char subtwophasestate
Definition: pg_dump.h:705
char * subconninfo
Definition: pg_dump.h:710
DumpableObject dobj
Definition: pg_dump.h:700

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 appendPQExpBuffer(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:730
char * srsublsn
Definition: pg_dump.h:734
SubscriptionInfo * subinfo
Definition: pg_dump.h:731
TableInfo * tblinfo
Definition: pg_dump.h:732
char srsubstate
Definition: pg_dump.h:733

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

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

17695{
17696 DumpOptions *dopt = fout->dopt;
17697 PQExpBuffer q;
17698 PGresult *res;
17699 char *partbound;
17700
17701 /* Do nothing if not dumping schema */
17702 if (!dopt->dumpSchema)
17703 return;
17704
17705 q = createPQExpBuffer();
17706
17708 {
17709 /* Set up query for partbound details */
17711 "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
17712
17714 "SELECT pg_get_expr(c.relpartbound, c.oid) "
17715 "FROM pg_class c "
17716 "WHERE c.oid = $1");
17717
17718 ExecuteSqlStatement(fout, q->data);
17719
17721 }
17722
17724 "EXECUTE dumpTableAttach('%u')",
17725 attachinfo->partitionTbl->dobj.catId.oid);
17726
17727 res = ExecuteSqlQueryForSingleRow(fout, q->data);
17728 partbound = PQgetvalue(res, 0, 0);
17729
17730 /* Perform ALTER TABLE on the parent */
17732 "ALTER TABLE ONLY %s ",
17733 fmtQualifiedDumpable(attachinfo->parentTbl));
17735 "ATTACH PARTITION %s %s;\n",
17737 partbound);
17738
17739 /*
17740 * There is no point in creating a drop query as the drop is done by table
17741 * drop. (If you think to change this, see also _printTocEntry().)
17742 * Although this object doesn't really have ownership as such, set the
17743 * owner field anyway to ensure that the command is run by the correct
17744 * role at restore time.
17745 */
17746 ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
17747 ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
17748 .namespace = attachinfo->dobj.namespace->dobj.name,
17749 .owner = attachinfo->partitionTbl->rolname,
17750 .description = "TABLE ATTACH",
17751 .section = SECTION_PRE_DATA,
17752 .createStmt = q->data));
17753
17754 PQclear(res);
17756}
@ PREPQUERY_DUMPTABLEATTACH
Definition: pg_backup.h:74
TableInfo * partitionTbl
Definition: pg_dump.h:390
DumpableObject dobj
Definition: pg_dump.h:388
TableInfo * parentTbl
Definition: pg_dump.h:389

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

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

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

18420{
18421 TableInfo *tbinfo = coninfo->contable;
18422 PQExpBuffer conprefix = createPQExpBuffer();
18423 char *qtabname;
18424
18425 qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
18426
18427 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
18428 fmtId(coninfo->dobj.name));
18429
18430 if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
18431 dumpComment(fout, conprefix->data, qtabname,
18432 tbinfo->dobj.namespace->dobj.name,
18433 tbinfo->rolname,
18434 coninfo->dobj.catId, 0,
18435 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
18436
18437 destroyPQExpBuffer(conprefix);
18438 free(qtabname);
18439}

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:19975
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:406
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:373

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

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

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

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

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

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

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

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

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

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

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

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

15368{
15369 DumpOptions *dopt = fout->dopt;
15370 PQExpBuffer q;
15371 PQExpBuffer delq;
15372 char *qprsname;
15373
15374 /* Do nothing if not dumping schema */
15375 if (!dopt->dumpSchema)
15376 return;
15377
15378 q = createPQExpBuffer();
15379 delq = createPQExpBuffer();
15380
15381 qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
15382
15383 appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
15384 fmtQualifiedDumpable(prsinfo));
15385
15386 appendPQExpBuffer(q, " START = %s,\n",
15387 convertTSFunction(fout, prsinfo->prsstart));
15388 appendPQExpBuffer(q, " GETTOKEN = %s,\n",
15389 convertTSFunction(fout, prsinfo->prstoken));
15390 appendPQExpBuffer(q, " END = %s,\n",
15391 convertTSFunction(fout, prsinfo->prsend));
15392 if (prsinfo->prsheadline != InvalidOid)
15393 appendPQExpBuffer(q, " HEADLINE = %s,\n",
15394 convertTSFunction(fout, prsinfo->prsheadline));
15395 appendPQExpBuffer(q, " LEXTYPES = %s );\n",
15396 convertTSFunction(fout, prsinfo->prslextype));
15397
15398 appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
15399 fmtQualifiedDumpable(prsinfo));
15400
15401 if (dopt->binary_upgrade)
15403 "TEXT SEARCH PARSER", qprsname,
15404 prsinfo->dobj.namespace->dobj.name);
15405
15406 if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15407 ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
15408 ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
15409 .namespace = prsinfo->dobj.namespace->dobj.name,
15410 .description = "TEXT SEARCH PARSER",
15411 .section = SECTION_PRE_DATA,
15412 .createStmt = q->data,
15413 .dropStmt = delq->data));
15414
15415 /* Dump Parser Comments */
15416 if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15417 dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
15418 prsinfo->dobj.namespace->dobj.name, "",
15419 prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
15420
15422 destroyPQExpBuffer(delq);
15423 free(qprsname);
15424}
static char * convertTSFunction(Archive *fout, Oid funcOid)
Definition: pg_dump.c:14032
DumpableObject dobj
Definition: pg_dump.h:561
Oid prstoken
Definition: pg_dump.h:563
Oid prslextype
Definition: pg_dump.h:566
Oid prsheadline
Definition: pg_dump.h:565
Oid prsstart
Definition: pg_dump.h:562
Oid prsend
Definition: pg_dump.h:564

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

15512{
15513 DumpOptions *dopt = fout->dopt;
15514 PQExpBuffer q;
15515 PQExpBuffer delq;
15516 char *qtmplname;
15517
15518 /* Do nothing if not dumping schema */
15519 if (!dopt->dumpSchema)
15520 return;
15521
15522 q = createPQExpBuffer();
15523 delq = createPQExpBuffer();
15524
15525 qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
15526
15527 appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
15528 fmtQualifiedDumpable(tmplinfo));
15529
15530 if (tmplinfo->tmplinit != InvalidOid)
15531 appendPQExpBuffer(q, " INIT = %s,\n",
15532 convertTSFunction(fout, tmplinfo->tmplinit));
15533 appendPQExpBuffer(q, " LEXIZE = %s );\n",
15534 convertTSFunction(fout, tmplinfo->tmpllexize));
15535
15536 appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
15537 fmtQualifiedDumpable(tmplinfo));
15538
15539 if (dopt->binary_upgrade)
15541 "TEXT SEARCH TEMPLATE", qtmplname,
15542 tmplinfo->dobj.namespace->dobj.name);
15543
15544 if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
15545 ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
15546 ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
15547 .namespace = tmplinfo->dobj.namespace->dobj.name,
15548 .description = "TEXT SEARCH TEMPLATE",
15549 .section = SECTION_PRE_DATA,
15550 .createStmt = q->data,
15551 .dropStmt = delq->data));
15552
15553 /* Dump Template Comments */
15554 if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
15555 dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
15556 tmplinfo->dobj.namespace->dobj.name, "",
15557 tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
15558
15560 destroyPQExpBuffer(delq);
15561 free(qtmplname);
15562}
Oid tmpllexize
Definition: pg_dump.h:581
Oid tmplinit
Definition: pg_dump.h:580
DumpableObject dobj
Definition: pg_dump.h:579

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

11751{
11752 DumpOptions *dopt = fout->dopt;
11753
11754 /* Do nothing if not dumping schema */
11755 if (!dopt->dumpSchema)
11756 return;
11757
11758 /* Dump out in proper style */
11759 if (tyinfo->typtype == TYPTYPE_BASE)
11760 dumpBaseType(fout, tyinfo);
11761 else if (tyinfo->typtype == TYPTYPE_DOMAIN)
11762 dumpDomain(fout, tyinfo);
11763 else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
11764 dumpCompositeType(fout, tyinfo);
11765 else if (tyinfo->typtype == TYPTYPE_ENUM)
11766 dumpEnumType(fout, tyinfo);
11767 else if (tyinfo->typtype == TYPTYPE_RANGE)
11768 dumpRangeType(fout, tyinfo);
11769 else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
11770 dumpUndefinedType(fout, tyinfo);
11771 else
11772 pg_log_warning("typtype of data type \"%s\" appears to be invalid",
11773 tyinfo->dobj.name);
11774}
static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12143
static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11921
static void dumpDomain(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12392
static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12079
static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:12565
static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
Definition: pg_dump.c:11781
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 12079 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

19976{
19977 int numatts = ti->numatts;
19978 char **attnames = ti->attnames;
19979 bool *attisdropped = ti->attisdropped;
19980 char *attgenerated = ti->attgenerated;
19981 bool needComma;
19982 int i;
19983
19984 appendPQExpBufferChar(buffer, '(');
19985 needComma = false;
19986 for (i = 0; i < numatts; i++)
19987 {
19988 if (attisdropped[i])
19989 continue;
19990 if (attgenerated[i])
19991 continue;
19992 if (needComma)
19993 appendPQExpBufferStr(buffer, ", ");
19994 appendPQExpBufferStr(buffer, fmtId(attnames[i]));
19995 needComma = true;
19996 }
19997
19998 if (!needComma)
19999 return ""; /* no undropped columns */
20000
20001 appendPQExpBufferChar(buffer, ')');
20002 return buffer->data;
20003}

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

14976{
14978 int j;
14979
14981 if (honor_quotes)
14982 appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
14983 else
14984 appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
14985
14986 if (agginfo->aggfn.nargs == 0)
14987 appendPQExpBufferStr(&buf, "(*)");
14988 else
14989 {
14991 for (j = 0; j < agginfo->aggfn.nargs; j++)
14992 appendPQExpBuffer(&buf, "%s%s",
14993 (j > 0) ? ", " : "",
14995 agginfo->aggfn.argtypes[j],
14996 zeroIsError));
14998 }
14999 return buf.data;
15000}

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

13039{
13041
13044 if (is_agg && finfo->nargs == 0)
13045 appendPQExpBufferStr(&fn, "(*)");
13046 else
13047 appendPQExpBuffer(&fn, "(%s)", funcargs);
13048 return fn.data;
13049}
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 13061 of file pg_dump.c.

13062{
13064 int j;
13065
13067 if (honor_quotes)
13068 appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
13069 else
13070 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
13071 for (j = 0; j < finfo->nargs; j++)
13072 {
13073 if (j > 0)
13074 appendPQExpBufferStr(&fn, ", ");
13075
13077 getFormattedTypeName(fout, finfo->argtypes[j],
13078 zeroIsError));
13079 }
13081 return fn.data;
13082}
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 10457 of file pg_dump.c.

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

17824{
17825 if (attrnum > 0 && attrnum <= tblInfo->numatts)
17826 return tblInfo->attnames[attrnum - 1];
17827 switch (attrnum)
17828 {
17830 return "ctid";
17832 return "xmin";
17834 return "cmin";
17836 return "xmax";
17838 return "cmax";
17840 return "tableoid";
17841 }
17842 pg_fatal("invalid column number %d for table \"%s\"",
17843 attrnum, tblInfo->dobj.name);
17844 return NULL; /* keep compiler quiet */
17845}
#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:380
int numIndexes
Definition: pg_dump.h:379

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

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

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

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

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

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

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

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

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

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

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

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

14003{
14004 OprInfo *oprInfo;
14005
14006 /* In all cases "0" means a null reference */
14007 if (strcmp(oproid, "0") == 0)
14008 return NULL;
14009
14010 oprInfo = findOprByOid(atooid(oproid));
14011 if (oprInfo == NULL)
14012 {
14013 pg_log_warning("could not find operator with OID %s",
14014 oproid);
14015 return NULL;
14016 }
14017
14018 return psprintf("OPERATOR(%s.%s)",
14019 fmtId(oprInfo->dobj.namespace->dobj.name),
14020 oprInfo->dobj.name);
14021}
OprInfo * findOprByOid(Oid oid)
Definition: common.c:913

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

19925{
19926 TypeInfo *typeInfo;
19927 char *result;
19928 PQExpBuffer query;
19929 PGresult *res;
19930
19931 if (oid == 0)
19932 {
19933 if ((opts & zeroAsStar) != 0)
19934 return "*";
19935 else if ((opts & zeroAsNone) != 0)
19936 return "NONE";
19937 }
19938
19939 /* see if we have the result cached in the type's TypeInfo record */
19940 typeInfo = findTypeByOid(oid);
19941 if (typeInfo && typeInfo->ftypname)
19942 return typeInfo->ftypname;
19943
19944 query = createPQExpBuffer();
19945 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
19946 oid);
19947
19948 res = ExecuteSqlQueryForSingleRow(fout, query->data);
19949
19950 /* result of format_type is already quoted */
19951 result = pg_strdup(PQgetvalue(res, 0, 0));
19952
19953 PQclear(res);
19954 destroyPQExpBuffer(query);
19955
19956 /*
19957 * Cache the result for re-use in later requests, if possible. If we
19958 * don't have a TypeInfo for the type, the string will be leaked once the
19959 * caller is done with it ... but that case really should not happen, so
19960 * leaking if it does seems acceptable.
19961 */
19962 if (typeInfo)
19963 typeInfo->ftypname = result;
19964
19965 return result;
19966}
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:556
Oid inhrelid
Definition: pg_dump.h:555

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:696
#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:985
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:446

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

10387{
10388 Oid roleoid = atooid(roleoid_str);
10389
10390 /*
10391 * Do binary search to find the appropriate item.
10392 */
10393 if (nrolenames > 0)
10394 {
10395 RoleNameItem *low = &rolenames[0];
10396 RoleNameItem *high = &rolenames[nrolenames - 1];
10397
10398 while (low <= high)
10399 {
10400 RoleNameItem *middle = low + (high - low) / 2;
10401
10402 if (roleoid < middle->roleoid)
10403 high = middle - 1;
10404 else if (roleoid > middle->roleoid)
10405 low = middle + 1;
10406 else
10407 return middle->rolename; /* found a match */
10408 }
10409 }
10410
10411 pg_fatal("role with OID %u does not exist", roleoid);
10412 return NULL; /* keep compiler quiet */
10413}

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
5037 appendPQExpBuffer(query,
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:1003

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 for servers older than 18; it's also in charge
9103 * of determining 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_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
9259 tbinfo->notnull_islocal = (bool *) pg_malloc(numatts * sizeof(bool));
9260 tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
9261 hasdefaults = false;
9262
9263 for (int j = 0; j < numatts; j++, r++)
9264 {
9265 if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
9266 pg_fatal("invalid column numbering in table \"%s\"",
9267 tbinfo->dobj.name);
9268 tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
9269 tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
9270 if (PQgetisnull(res, r, i_attstattarget))
9271 tbinfo->attstattarget[j] = -1;
9272 else
9273 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
9274 tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
9275 tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
9276 tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
9277 tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
9278 tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
9279 tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
9280 tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
9281 tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
9282 tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
9283
9284 /* Handle not-null constraint name and flags */
9285 determineNotNullFlags(fout, res, r,
9286 tbinfo, j,
9287 i_notnull_name,
9288 i_notnull_invalidoid,
9289 i_notnull_noinherit,
9290 i_notnull_islocal,
9291 &invalidnotnulloids);
9292
9293 tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
9294 tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
9295 tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
9296 tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
9297 tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
9298 tbinfo->attrdefs[j] = NULL; /* fix below */
9299 if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
9300 hasdefaults = true;
9301 }
9302
9303 if (hasdefaults)
9304 {
9305 /* Collect OIDs of interesting tables that have defaults */
9306 if (tbloids->len > 1) /* do we have more than the '{'? */
9307 appendPQExpBufferChar(tbloids, ',');
9308 appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9309 }
9310 }
9311
9312 /* If invalidnotnulloids has any data, finalize it */
9313 if (invalidnotnulloids != NULL)
9314 appendPQExpBufferChar(invalidnotnulloids, '}');
9315
9316 PQclear(res);
9317
9318 /*
9319 * Now get info about column defaults. This is skipped for a data-only
9320 * dump, as it is only needed for table schemas.
9321 */
9322 if (dopt->dumpSchema && tbloids->len > 1)
9323 {
9324 AttrDefInfo *attrdefs;
9325 int numDefaults;
9326 TableInfo *tbinfo = NULL;
9327
9328 pg_log_info("finding table default expressions");
9329
9330 appendPQExpBufferChar(tbloids, '}');
9331
9332 printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9333 "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9334 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9335 "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9336 "ORDER BY a.adrelid, a.adnum",
9337 tbloids->data);
9338
9339 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9340
9341 numDefaults = PQntuples(res);
9342 attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9343
9344 curtblindx = -1;
9345 for (int j = 0; j < numDefaults; j++)
9346 {
9347 Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9348 Oid adoid = atooid(PQgetvalue(res, j, 1));
9349 Oid adrelid = atooid(PQgetvalue(res, j, 2));
9350 int adnum = atoi(PQgetvalue(res, j, 3));
9351 char *adsrc = PQgetvalue(res, j, 4);
9352
9353 /*
9354 * Locate the associated TableInfo; we rely on tblinfo[] being in
9355 * OID order.
9356 */
9357 if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9358 {
9359 while (++curtblindx < numTables)
9360 {
9361 tbinfo = &tblinfo[curtblindx];
9362 if (tbinfo->dobj.catId.oid == adrelid)
9363 break;
9364 }
9365 if (curtblindx >= numTables)
9366 pg_fatal("unrecognized table OID %u", adrelid);
9367 }
9368
9369 if (adnum <= 0 || adnum > tbinfo->numatts)
9370 pg_fatal("invalid adnum value %d for table \"%s\"",
9371 adnum, tbinfo->dobj.name);
9372
9373 /*
9374 * dropped columns shouldn't have defaults, but just in case,
9375 * ignore 'em
9376 */
9377 if (tbinfo->attisdropped[adnum - 1])
9378 continue;
9379
9380 attrdefs[j].dobj.objType = DO_ATTRDEF;
9381 attrdefs[j].dobj.catId.tableoid = adtableoid;
9382 attrdefs[j].dobj.catId.oid = adoid;
9383 AssignDumpId(&attrdefs[j].dobj);
9384 attrdefs[j].adtable = tbinfo;
9385 attrdefs[j].adnum = adnum;
9386 attrdefs[j].adef_expr = pg_strdup(adsrc);
9387
9388 attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9389 attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9390
9391 attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9392
9393 /*
9394 * Figure out whether the default/generation expression should be
9395 * dumped as part of the main CREATE TABLE (or similar) command or
9396 * as a separate ALTER TABLE (or similar) command. The preference
9397 * is to put it into the CREATE command, but in some cases that's
9398 * not possible.
9399 */
9400 if (tbinfo->attgenerated[adnum - 1])
9401 {
9402 /*
9403 * Column generation expressions cannot be dumped separately,
9404 * because there is no syntax for it. By setting separate to
9405 * false here we prevent the "default" from being processed as
9406 * its own dumpable object. Later, flagInhAttrs() will mark
9407 * it as not to be dumped at all, if possible (that is, if it
9408 * can be inherited from a parent).
9409 */
9410 attrdefs[j].separate = false;
9411 }
9412 else if (tbinfo->relkind == RELKIND_VIEW)
9413 {
9414 /*
9415 * Defaults on a VIEW must always be dumped as separate ALTER
9416 * TABLE commands.
9417 */
9418 attrdefs[j].separate = true;
9419 }
9420 else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9421 {
9422 /* column will be suppressed, print default separately */
9423 attrdefs[j].separate = true;
9424 }
9425 else
9426 {
9427 attrdefs[j].separate = false;
9428 }
9429
9430 if (!attrdefs[j].separate)
9431 {
9432 /*
9433 * Mark the default as needing to appear before the table, so
9434 * that any dependencies it has must be emitted before the
9435 * CREATE TABLE. If this is not possible, we'll change to
9436 * "separate" mode while sorting dependencies.
9437 */
9438 addObjectDependency(&tbinfo->dobj,
9439 attrdefs[j].dobj.dumpId);
9440 }
9441
9442 tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9443 }
9444
9445 PQclear(res);
9446 }
9447
9448 /*
9449 * Get info about NOT NULL NOT VALID constraints. This is skipped for a
9450 * data-only dump, as it is only needed for table schemas.
9451 */
9452 if (dopt->dumpSchema && invalidnotnulloids)
9453 {
9454 ConstraintInfo *constrs;
9455 int numConstrs;
9456 int i_tableoid;
9457 int i_oid;
9458 int i_conrelid;
9459 int i_conname;
9460 int i_consrc;
9461 int i_conislocal;
9462
9463 pg_log_info("finding invalid not null constraints");
9464
9467 "SELECT c.tableoid, c.oid, conrelid, conname, "
9468 "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9469 "conislocal, convalidated "
9470 "FROM unnest('%s'::pg_catalog.oid[]) AS src(conoid)\n"
9471 "JOIN pg_catalog.pg_constraint c ON (src.conoid = c.oid)\n"
9472 "ORDER BY c.conrelid, c.conname",
9473 invalidnotnulloids->data);
9474
9475 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9476
9477 numConstrs = PQntuples(res);
9478 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9479
9480 i_tableoid = PQfnumber(res, "tableoid");
9481 i_oid = PQfnumber(res, "oid");
9482 i_conrelid = PQfnumber(res, "conrelid");
9483 i_conname = PQfnumber(res, "conname");
9484 i_consrc = PQfnumber(res, "consrc");
9485 i_conislocal = PQfnumber(res, "conislocal");
9486
9487 /* As above, this loop iterates once per table, not once per row */
9488 curtblindx = -1;
9489 for (int j = 0; j < numConstrs;)
9490 {
9491 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9492 TableInfo *tbinfo = NULL;
9493 int numcons;
9494
9495 /* Count rows for this table */
9496 for (numcons = 1; numcons < numConstrs - j; numcons++)
9497 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9498 break;
9499
9500 /*
9501 * Locate the associated TableInfo; we rely on tblinfo[] being in
9502 * OID order.
9503 */
9504 while (++curtblindx < numTables)
9505 {
9506 tbinfo = &tblinfo[curtblindx];
9507 if (tbinfo->dobj.catId.oid == conrelid)
9508 break;
9509 }
9510 if (curtblindx >= numTables)
9511 pg_fatal("unrecognized table OID %u", conrelid);
9512
9513 for (int c = 0; c < numcons; c++, j++)
9514 {
9515 constrs[j].dobj.objType = DO_CONSTRAINT;
9516 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9517 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9518 AssignDumpId(&constrs[j].dobj);
9519 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9520 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9521 constrs[j].contable = tbinfo;
9522 constrs[j].condomain = NULL;
9523 constrs[j].contype = 'n';
9524 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9525 constrs[j].confrelid = InvalidOid;
9526 constrs[j].conindex = 0;
9527 constrs[j].condeferrable = false;
9528 constrs[j].condeferred = false;
9529 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9530
9531 /*
9532 * All invalid not-null constraints must be dumped separately,
9533 * because CREATE TABLE would not create them as invalid, and
9534 * also because they must be created after potentially
9535 * violating data has been loaded.
9536 */
9537 constrs[j].separate = true;
9538
9539 constrs[j].dobj.dump = tbinfo->dobj.dump;
9540 }
9541 }
9542 PQclear(res);
9543 }
9544
9545 /*
9546 * Get info about table CHECK constraints. This is skipped for a
9547 * data-only dump, as it is only needed for table schemas.
9548 */
9549 if (dopt->dumpSchema && checkoids->len > 2)
9550 {
9551 ConstraintInfo *constrs;
9552 int numConstrs;
9553 int i_tableoid;
9554 int i_oid;
9555 int i_conrelid;
9556 int i_conname;
9557 int i_consrc;
9558 int i_conislocal;
9559 int i_convalidated;
9560
9561 pg_log_info("finding table check constraints");
9562
9565 "SELECT c.tableoid, c.oid, conrelid, conname, "
9566 "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9567 "conislocal, convalidated "
9568 "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9569 "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9570 "WHERE contype = 'c' "
9571 "ORDER BY c.conrelid, c.conname",
9572 checkoids->data);
9573
9574 res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9575
9576 numConstrs = PQntuples(res);
9577 constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9578
9579 i_tableoid = PQfnumber(res, "tableoid");
9580 i_oid = PQfnumber(res, "oid");
9581 i_conrelid = PQfnumber(res, "conrelid");
9582 i_conname = PQfnumber(res, "conname");
9583 i_consrc = PQfnumber(res, "consrc");
9584 i_conislocal = PQfnumber(res, "conislocal");
9585 i_convalidated = PQfnumber(res, "convalidated");
9586
9587 /* As above, this loop iterates once per table, not once per row */
9588 curtblindx = -1;
9589 for (int j = 0; j < numConstrs;)
9590 {
9591 Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9592 TableInfo *tbinfo = NULL;
9593 int numcons;
9594
9595 /* Count rows for this table */
9596 for (numcons = 1; numcons < numConstrs - j; numcons++)
9597 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9598 break;
9599
9600 /*
9601 * Locate the associated TableInfo; we rely on tblinfo[] being in
9602 * OID order.
9603 */
9604 while (++curtblindx < numTables)
9605 {
9606 tbinfo = &tblinfo[curtblindx];
9607 if (tbinfo->dobj.catId.oid == conrelid)
9608 break;
9609 }
9610 if (curtblindx >= numTables)
9611 pg_fatal("unrecognized table OID %u", conrelid);
9612
9613 if (numcons != tbinfo->ncheck)
9614 {
9615 pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9616 "expected %d check constraints on table \"%s\" but found %d",
9617 tbinfo->ncheck),
9618 tbinfo->ncheck, tbinfo->dobj.name, numcons);
9619 pg_log_error_hint("The system catalogs might be corrupted.");
9620 exit_nicely(1);
9621 }
9622
9623 tbinfo->checkexprs = constrs + j;
9624
9625 for (int c = 0; c < numcons; c++, j++)
9626 {
9627 bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9628
9629 constrs[j].dobj.objType = DO_CONSTRAINT;
9630 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9631 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9632 AssignDumpId(&constrs[j].dobj);
9633 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9634 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9635 constrs[j].contable = tbinfo;
9636 constrs[j].condomain = NULL;
9637 constrs[j].contype = 'c';
9638 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9639 constrs[j].confrelid = InvalidOid;
9640 constrs[j].conindex = 0;
9641 constrs[j].condeferrable = false;
9642 constrs[j].condeferred = false;
9643 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9644
9645 /*
9646 * An unvalidated constraint needs to be dumped separately, so
9647 * that potentially-violating existing data is loaded before
9648 * the constraint.
9649 */
9650 constrs[j].separate = !validated;
9651
9652 constrs[j].dobj.dump = tbinfo->dobj.dump;
9653
9654 /*
9655 * Mark the constraint as needing to appear before the table
9656 * --- this is so that any other dependencies of the
9657 * constraint will be emitted before we try to create the
9658 * table. If the constraint is to be dumped separately, it
9659 * will be dumped after data is loaded anyway, so don't do it.
9660 * (There's an automatic dependency in the opposite direction
9661 * anyway, so don't need to add one manually here.)
9662 */
9663 if (!constrs[j].separate)
9664 addObjectDependency(&tbinfo->dobj,
9665 constrs[j].dobj.dumpId);
9666
9667 /*
9668 * We will detect later whether the constraint must be split
9669 * out from the table definition.
9670 */
9671 }
9672 }
9673
9674 PQclear(res);
9675 }
9676
9678 destroyPQExpBuffer(tbloids);
9679 destroyPQExpBuffer(checkoids);
9680}
#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:9727

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_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:774

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:372
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:383
int numTriggers
Definition: pg_dump.h:382

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

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

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

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

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

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

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

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

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:7574
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:19694
static void dumpSearchPath(Archive *AH)
Definition: pg_dump.c:3756
static DumpableObject * createBoundaryObjects(void)
Definition: pg_dump.c:19670
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:19820
static void collectRoleNames(Archive *fout)
Definition: pg_dump.c:10422
static bool dosync
Definition: pg_dump.c:147
static void getDependencies(Archive *fout)
Definition: pg_dump.c:19517
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:10457
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:11264
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
Definition: pg_dump.c:11349
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:16414
static void collectSequences(Archive *fout)
Definition: pg_dump.c:18473
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:20040
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 20009 of file pg_dump.c.

20010{
20011 /* Don't want to print it if it's just "{}" */
20012 return (reloptions != NULL && strlen(reloptions) > 2);
20013}

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

◆ parse_sequence_type()

static SeqType parse_sequence_type ( const char *  name)
inlinestatic

Definition at line 18442 of file pg_dump.c.

18443{
18444 for (int i = 0; i < lengthof(SeqTypeNames); i++)
18445 {
18446 if (strcmp(SeqTypeNames[i], name) == 0)
18447 return (SeqType) i;
18448 }
18449
18450 pg_fatal("unrecognized sequence type: %s", name);
18451 return (SeqType) 0; /* keep compiler quiet */
18452}
#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 19336 of file pg_dump.c.

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

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

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

20041{
20042 FilterStateData fstate;
20043 char *objname;
20044 FilterCommandType comtype;
20045 FilterObjectType objtype;
20046
20047 filter_init(&fstate, filename, exit_nicely);
20048
20049 while (filter_read_item(&fstate, &objname, &comtype, &objtype))
20050 {
20051 if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
20052 {
20053 switch (objtype)
20054 {
20056 break;
20063 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20064 "include",
20065 filter_object_type_name(objtype));
20066 exit_nicely(1);
20067 break; /* unreachable */
20068
20071 break;
20074 break;
20077 dopt->include_everything = false;
20078 break;
20081 dopt->include_everything = false;
20082 break;
20085 objname);
20086 dopt->include_everything = false;
20087 break;
20088 }
20089 }
20090 else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
20091 {
20092 switch (objtype)
20093 {
20095 break;
20101 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
20102 "exclude",
20103 filter_object_type_name(objtype));
20104 exit_nicely(1);
20105 break;
20106
20109 break;
20112 objname);
20113 break;
20116 objname);
20117 break;
20120 break;
20123 break;
20126 objname);
20127 break;
20128 }
20129 }
20130 else
20131 {
20132 Assert(comtype == FILTER_COMMAND_TYPE_NONE);
20133 Assert(objtype == FILTER_OBJECT_TYPE_NONE);
20134 }
20135
20136 if (objname)
20137 free(objname);
20138 }
20139
20140 filter_free(&fstate);
20141}
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 18458 of file pg_dump.c.

18459{
18460 SequenceItem v1 = *((const SequenceItem *) p1);
18461 SequenceItem v2 = *((const SequenceItem *) p2);
18462
18463 return pg_cmp_u32(v1.oid, v2.oid);
18464}

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:7709
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7717
#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 9844 of file pg_dump.c.

9845{
9846 if (dopt->binary_upgrade)
9847 return true;
9848 if (tbinfo->attisdropped[colno])
9849 return false;
9850 return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9851}

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