PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_dump.h File Reference
#include "pg_backup.h"
#include "catalog/pg_publication_d.h"
Include dependency graph for pg_dump.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  _dumpableObject
 
struct  _dumpableAcl
 
struct  _dumpableObjectWithAcl
 
struct  _namespaceInfo
 
struct  _extensionInfo
 
struct  _typeInfo
 
struct  _shellTypeInfo
 
struct  _funcInfo
 
struct  _aggInfo
 
struct  _oprInfo
 
struct  _accessMethodInfo
 
struct  _opclassInfo
 
struct  _opfamilyInfo
 
struct  _collInfo
 
struct  _convInfo
 
struct  _tableInfo
 
struct  _tableAttachInfo
 
struct  _attrDefInfo
 
struct  _tableDataInfo
 
struct  _indxInfo
 
struct  _indexAttachInfo
 
struct  _relStatsInfo
 
struct  _statsExtInfo
 
struct  _ruleInfo
 
struct  _triggerInfo
 
struct  _evttriggerInfo
 
struct  _constraintInfo
 
struct  _procLangInfo
 
struct  _castInfo
 
struct  _transformInfo
 
struct  _inhInfo
 
struct  _prsInfo
 
struct  _dictInfo
 
struct  _tmplInfo
 
struct  _cfgInfo
 
struct  _fdwInfo
 
struct  _foreignServerInfo
 
struct  _defaultACLInfo
 
struct  _loInfo
 
struct  _policyInfo
 
struct  _PublicationInfo
 
struct  _PublicationRelInfo
 
struct  _PublicationSchemaInfo
 
struct  _SubscriptionInfo
 
struct  _SubRelInfo
 

Macros

#define oidcmp(x, y)   ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) )
 
#define NUM_DUMPABLE_OBJECT_TYPES   (DO_SUBSCRIPTION_REL + 1)
 
#define DUMP_COMPONENT_NONE   (0)
 
#define DUMP_COMPONENT_DEFINITION   (1 << 0)
 
#define DUMP_COMPONENT_DATA   (1 << 1)
 
#define DUMP_COMPONENT_COMMENT   (1 << 2)
 
#define DUMP_COMPONENT_SECLABEL   (1 << 3)
 
#define DUMP_COMPONENT_ACL   (1 << 4)
 
#define DUMP_COMPONENT_POLICY   (1 << 5)
 
#define DUMP_COMPONENT_USERMAP   (1 << 6)
 
#define DUMP_COMPONENT_STATISTICS   (1 << 7)
 
#define DUMP_COMPONENT_ALL   (0xFFFF)
 
#define DUMP_COMPONENTS_REQUIRING_LOCK
 

Typedefs

typedef uint32 DumpComponents
 
typedef struct _dumpableObject DumpableObject
 
typedef struct _dumpableAcl DumpableAcl
 
typedef struct _dumpableObjectWithAcl DumpableObjectWithAcl
 
typedef struct _namespaceInfo NamespaceInfo
 
typedef struct _extensionInfo ExtensionInfo
 
typedef struct _typeInfo TypeInfo
 
typedef struct _shellTypeInfo ShellTypeInfo
 
typedef struct _funcInfo FuncInfo
 
typedef struct _aggInfo AggInfo
 
typedef struct _oprInfo OprInfo
 
typedef struct _accessMethodInfo AccessMethodInfo
 
typedef struct _opclassInfo OpclassInfo
 
typedef struct _opfamilyInfo OpfamilyInfo
 
typedef struct _collInfo CollInfo
 
typedef struct _convInfo ConvInfo
 
typedef struct _tableInfo TableInfo
 
typedef struct _tableAttachInfo TableAttachInfo
 
typedef struct _attrDefInfo AttrDefInfo
 
typedef struct _tableDataInfo TableDataInfo
 
typedef struct _indxInfo IndxInfo
 
typedef struct _indexAttachInfo IndexAttachInfo
 
typedef struct _relStatsInfo RelStatsInfo
 
typedef struct _statsExtInfo StatsExtInfo
 
typedef struct _ruleInfo RuleInfo
 
typedef struct _triggerInfo TriggerInfo
 
typedef struct _evttriggerInfo EventTriggerInfo
 
typedef struct _constraintInfo ConstraintInfo
 
typedef struct _procLangInfo ProcLangInfo
 
typedef struct _castInfo CastInfo
 
typedef struct _transformInfo TransformInfo
 
typedef struct _inhInfo InhInfo
 
typedef struct _prsInfo TSParserInfo
 
typedef struct _dictInfo TSDictInfo
 
typedef struct _tmplInfo TSTemplateInfo
 
typedef struct _cfgInfo TSConfigInfo
 
typedef struct _fdwInfo FdwInfo
 
typedef struct _foreignServerInfo ForeignServerInfo
 
typedef struct _defaultACLInfo DefaultACLInfo
 
typedef struct _loInfo LoInfo
 
typedef struct _policyInfo PolicyInfo
 
typedef struct _PublicationInfo PublicationInfo
 
typedef struct _PublicationRelInfo PublicationRelInfo
 
typedef struct _PublicationSchemaInfo PublicationSchemaInfo
 
typedef struct _SubscriptionInfo SubscriptionInfo
 
typedef struct _SubRelInfo SubRelInfo
 

Enumerations

enum  DumpableObjectType {
  DO_NAMESPACE , DO_EXTENSION , DO_TYPE , DO_SHELL_TYPE ,
  DO_FUNC , DO_AGG , DO_OPERATOR , DO_ACCESS_METHOD ,
  DO_OPCLASS , DO_OPFAMILY , DO_COLLATION , DO_CONVERSION ,
  DO_TABLE , DO_TABLE_ATTACH , DO_ATTRDEF , DO_INDEX ,
  DO_INDEX_ATTACH , DO_STATSEXT , DO_RULE , DO_TRIGGER ,
  DO_CONSTRAINT , DO_FK_CONSTRAINT , DO_PROCLANG , DO_CAST ,
  DO_TABLE_DATA , DO_SEQUENCE_SET , DO_DUMMY_TYPE , DO_TSPARSER ,
  DO_TSDICT , DO_TSTEMPLATE , DO_TSCONFIG , DO_FDW ,
  DO_FOREIGN_SERVER , DO_DEFAULT_ACL , DO_TRANSFORM , DO_LARGE_OBJECT ,
  DO_LARGE_OBJECT_DATA , DO_PRE_DATA_BOUNDARY , DO_POST_DATA_BOUNDARY , DO_EVENT_TRIGGER ,
  DO_REFRESH_MATVIEW , DO_POLICY , DO_PUBLICATION , DO_PUBLICATION_REL ,
  DO_PUBLICATION_TABLE_IN_SCHEMA , DO_REL_STATS , DO_SUBSCRIPTION , DO_SUBSCRIPTION_REL
}
 

Functions

TableInfogetSchemaData (Archive *fout, int *numTablesPtr)
 
void AssignDumpId (DumpableObject *dobj)
 
void recordAdditionalCatalogID (CatalogId catId, DumpableObject *dobj)
 
DumpId createDumpId (void)
 
DumpId getMaxDumpId (void)
 
DumpableObjectfindObjectByDumpId (DumpId dumpId)
 
DumpableObjectfindObjectByCatalogId (CatalogId catalogId)
 
void getDumpableObjects (DumpableObject ***objs, int *numObjs)
 
void addObjectDependency (DumpableObject *dobj, DumpId refId)
 
void removeObjectDependency (DumpableObject *dobj, DumpId refId)
 
TableInfofindTableByOid (Oid oid)
 
TypeInfofindTypeByOid (Oid oid)
 
FuncInfofindFuncByOid (Oid oid)
 
OprInfofindOprByOid (Oid oid)
 
CollInfofindCollationByOid (Oid oid)
 
NamespaceInfofindNamespaceByOid (Oid oid)
 
ExtensionInfofindExtensionByOid (Oid oid)
 
PublicationInfofindPublicationByOid (Oid oid)
 
SubscriptionInfofindSubscriptionByOid (Oid oid)
 
void recordExtensionMembership (CatalogId catId, ExtensionInfo *ext)
 
ExtensionInfofindOwningExtension (CatalogId catalogId)
 
void parseOidArray (const char *str, Oid *array, int arraysize)
 
void sortDumpableObjects (DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId)
 
void sortDumpableObjectsByTypeName (DumpableObject **objs, int numObjs)
 
void getNamespaces (Archive *fout)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
void getTypes (Archive *fout)
 
void getFuncs (Archive *fout)
 
void getAggregates (Archive *fout)
 
void getOperators (Archive *fout)
 
void getAccessMethods (Archive *fout)
 
void getOpclasses (Archive *fout)
 
void getOpfamilies (Archive *fout)
 
void getCollations (Archive *fout)
 
void getConversions (Archive *fout)
 
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 getProcLangs (Archive *fout)
 
void getCasts (Archive *fout)
 
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)
 
void getExtensionMembership (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void processExtensionTables (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void getEventTriggers (Archive *fout)
 
void getPolicies (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getPublications (Archive *fout)
 
void getPublicationNamespaces (Archive *fout)
 
void getPublicationTables (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getSubscriptions (Archive *fout)
 
void getSubscriptionTables (Archive *fout)
 

Macro Definition Documentation

◆ DUMP_COMPONENT_ACL

#define DUMP_COMPONENT_ACL   (1 << 4)

Definition at line 113 of file pg_dump.h.

◆ DUMP_COMPONENT_ALL

#define DUMP_COMPONENT_ALL   (0xFFFF)

Definition at line 117 of file pg_dump.h.

◆ DUMP_COMPONENT_COMMENT

#define DUMP_COMPONENT_COMMENT   (1 << 2)

Definition at line 111 of file pg_dump.h.

◆ DUMP_COMPONENT_DATA

#define DUMP_COMPONENT_DATA   (1 << 1)

Definition at line 110 of file pg_dump.h.

◆ DUMP_COMPONENT_DEFINITION

#define DUMP_COMPONENT_DEFINITION   (1 << 0)

Definition at line 109 of file pg_dump.h.

◆ DUMP_COMPONENT_NONE

#define DUMP_COMPONENT_NONE   (0)

Definition at line 108 of file pg_dump.h.

◆ DUMP_COMPONENT_POLICY

#define DUMP_COMPONENT_POLICY   (1 << 5)

Definition at line 114 of file pg_dump.h.

◆ DUMP_COMPONENT_SECLABEL

#define DUMP_COMPONENT_SECLABEL   (1 << 3)

Definition at line 112 of file pg_dump.h.

◆ DUMP_COMPONENT_STATISTICS

#define DUMP_COMPONENT_STATISTICS   (1 << 7)

Definition at line 116 of file pg_dump.h.

◆ DUMP_COMPONENT_USERMAP

#define DUMP_COMPONENT_USERMAP   (1 << 6)

Definition at line 115 of file pg_dump.h.

◆ DUMP_COMPONENTS_REQUIRING_LOCK

#define DUMP_COMPONENTS_REQUIRING_LOCK
Value:
(\
DUMP_COMPONENT_DEFINITION |\
DUMP_COMPONENT_DATA |\
DUMP_COMPONENT_STATISTICS |\
DUMP_COMPONENT_POLICY)

Definition at line 141 of file pg_dump.h.

◆ NUM_DUMPABLE_OBJECT_TYPES

#define NUM_DUMPABLE_OBJECT_TYPES   (DO_SUBSCRIPTION_REL + 1)

Definition at line 91 of file pg_dump.h.

◆ oidcmp

#define oidcmp (   x,
  y 
)    ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) )

Definition at line 21 of file pg_dump.h.

Typedef Documentation

◆ AccessMethodInfo

◆ AggInfo

typedef struct _aggInfo AggInfo

◆ AttrDefInfo

typedef struct _attrDefInfo AttrDefInfo

◆ CastInfo

typedef struct _castInfo CastInfo

◆ CollInfo

typedef struct _collInfo CollInfo

◆ ConstraintInfo

◆ ConvInfo

typedef struct _convInfo ConvInfo

◆ DefaultACLInfo

◆ DumpableAcl

typedef struct _dumpableAcl DumpableAcl

◆ DumpableObject

◆ DumpableObjectWithAcl

◆ DumpComponents

Definition at line 107 of file pg_dump.h.

◆ EventTriggerInfo

◆ ExtensionInfo

typedef struct _extensionInfo ExtensionInfo

◆ FdwInfo

typedef struct _fdwInfo FdwInfo

◆ ForeignServerInfo

◆ FuncInfo

typedef struct _funcInfo FuncInfo

◆ IndexAttachInfo

◆ IndxInfo

typedef struct _indxInfo IndxInfo

◆ InhInfo

typedef struct _inhInfo InhInfo

◆ LoInfo

typedef struct _loInfo LoInfo

◆ NamespaceInfo

typedef struct _namespaceInfo NamespaceInfo

◆ OpclassInfo

typedef struct _opclassInfo OpclassInfo

◆ OpfamilyInfo

typedef struct _opfamilyInfo OpfamilyInfo

◆ OprInfo

typedef struct _oprInfo OprInfo

◆ PolicyInfo

typedef struct _policyInfo PolicyInfo

◆ ProcLangInfo

typedef struct _procLangInfo ProcLangInfo

◆ PublicationInfo

◆ PublicationRelInfo

◆ PublicationSchemaInfo

◆ RelStatsInfo

typedef struct _relStatsInfo RelStatsInfo

◆ RuleInfo

typedef struct _ruleInfo RuleInfo

◆ ShellTypeInfo

typedef struct _shellTypeInfo ShellTypeInfo

◆ StatsExtInfo

typedef struct _statsExtInfo StatsExtInfo

◆ SubRelInfo

typedef struct _SubRelInfo SubRelInfo

◆ SubscriptionInfo

◆ TableAttachInfo

◆ TableDataInfo

typedef struct _tableDataInfo TableDataInfo

◆ TableInfo

typedef struct _tableInfo TableInfo

◆ TransformInfo

typedef struct _transformInfo TransformInfo

◆ TriggerInfo

typedef struct _triggerInfo TriggerInfo

◆ TSConfigInfo

typedef struct _cfgInfo TSConfigInfo

◆ TSDictInfo

typedef struct _dictInfo TSDictInfo

◆ TSParserInfo

typedef struct _prsInfo TSParserInfo

◆ TSTemplateInfo

typedef struct _tmplInfo TSTemplateInfo

◆ TypeInfo

typedef struct _typeInfo TypeInfo

Enumeration Type Documentation

◆ DumpableObjectType

Enumerator
DO_NAMESPACE 
DO_EXTENSION 
DO_TYPE 
DO_SHELL_TYPE 
DO_FUNC 
DO_AGG 
DO_OPERATOR 
DO_ACCESS_METHOD 
DO_OPCLASS 
DO_OPFAMILY 
DO_COLLATION 
DO_CONVERSION 
DO_TABLE 
DO_TABLE_ATTACH 
DO_ATTRDEF 
DO_INDEX 
DO_INDEX_ATTACH 
DO_STATSEXT 
DO_RULE 
DO_TRIGGER 
DO_CONSTRAINT 
DO_FK_CONSTRAINT 
DO_PROCLANG 
DO_CAST 
DO_TABLE_DATA 
DO_SEQUENCE_SET 
DO_DUMMY_TYPE 
DO_TSPARSER 
DO_TSDICT 
DO_TSTEMPLATE 
DO_TSCONFIG 
DO_FDW 
DO_FOREIGN_SERVER 
DO_DEFAULT_ACL 
DO_TRANSFORM 
DO_LARGE_OBJECT 
DO_LARGE_OBJECT_DATA 
DO_PRE_DATA_BOUNDARY 
DO_POST_DATA_BOUNDARY 
DO_EVENT_TRIGGER 
DO_REFRESH_MATVIEW 
DO_POLICY 
DO_PUBLICATION 
DO_PUBLICATION_REL 
DO_PUBLICATION_TABLE_IN_SCHEMA 
DO_REL_STATS 
DO_SUBSCRIPTION 
DO_SUBSCRIPTION_REL 

Definition at line 38 of file pg_dump.h.

39{
40 /* When modifying this enum, update priority tables in pg_dump_sort.c! */
43 DO_TYPE,
45 DO_FUNC,
46 DO_AGG,
59 DO_RULE,
62 DO_FK_CONSTRAINT, /* see note for ConstraintInfo */
64 DO_CAST,
72 DO_FDW,
88 DO_SUBSCRIPTION_REL, /* see note for SubRelInfo */
DumpableObjectType
Definition: pg_dump.h:39
@ 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

Function Documentation

◆ addObjectDependency()

void addObjectDependency ( DumpableObject dobj,
DumpId  refId 
)

◆ AssignDumpId()

void AssignDumpId ( DumpableObject dobj)

Definition at line 634 of file common.c.

635{
636 dobj->dumpId = ++lastDumpId;
637 dobj->name = NULL; /* must be set later */
638 dobj->namespace = NULL; /* may be set later */
639 dobj->dump = DUMP_COMPONENT_ALL; /* default assumption */
640 dobj->dump_contains = DUMP_COMPONENT_ALL; /* default assumption */
641 /* All objects have definitions; we may set more components bits later */
643 dobj->ext_member = false; /* default assumption */
644 dobj->depends_on_ext = false; /* default assumption */
645 dobj->dependencies = NULL;
646 dobj->nDeps = 0;
647 dobj->allocDeps = 0;
648
649 /* Add object to dumpIdMap[], enlarging that array if need be */
650 while (dobj->dumpId >= allocedDumpIds)
651 {
652 int newAlloc;
653
654 if (allocedDumpIds <= 0)
655 {
656 newAlloc = 256;
658 }
659 else
660 {
661 newAlloc = allocedDumpIds * 2;
663 }
664 memset(dumpIdMap + allocedDumpIds, 0,
665 (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
666 allocedDumpIds = newAlloc;
667 }
668 dumpIdMap[dobj->dumpId] = dobj;
669
670 /* If it has a valid CatalogId, enter it into the hash table */
671 if (OidIsValid(dobj->catId.tableoid))
672 {
673 CatalogIdMapEntry *entry;
674 bool found;
675
676 /* Initialize CatalogId hash table if not done yet */
677 if (catalogIdHash == NULL)
678 catalogIdHash = catalogid_create(CATALOGIDHASH_INITIAL_SIZE, NULL);
679
680 entry = catalogid_insert(catalogIdHash, dobj->catId, &found);
681 if (!found)
682 {
683 entry->dobj = NULL;
684 entry->ext = NULL;
685 }
686 Assert(entry->dobj == NULL);
687 entry->dobj = dobj;
688 }
689}
static int allocedDumpIds
Definition: common.c:37
static DumpableObject ** dumpIdMap
Definition: common.c:36
#define CATALOGIDHASH_INITIAL_SIZE
Definition: common.c:79
static catalogid_hash * catalogIdHash
Definition: common.c:81
static DumpId lastDumpId
Definition: common.c:38
#define OidIsValid(objectId)
Definition: c.h:746
Assert(PointerIsAligned(start, uint64))
#define DUMP_COMPONENT_ALL
Definition: pg_dump.h:117
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:109
Oid tableoid
Definition: pg_backup.h:276
ExtensionInfo * ext
Definition: common.c:62
DumpableObject * dobj
Definition: common.c:61
DumpComponents dump
Definition: pg_dump.h:153
char * name
Definition: pg_dump.h:152
DumpId dumpId
Definition: pg_dump.h:151
bool ext_member
Definition: pg_dump.h:157
DumpComponents components
Definition: pg_dump.h:156
CatalogId catId
Definition: pg_dump.h:150
DumpComponents dump_contains
Definition: pg_dump.h:155
bool depends_on_ext
Definition: pg_dump.h:158

References _dumpableObject::allocDeps, allocedDumpIds, Assert(), catalogIdHash, CATALOGIDHASH_INITIAL_SIZE, _dumpableObject::catId, _dumpableObject::components, _dumpableObject::dependencies, _dumpableObject::depends_on_ext, _catalogIdMapEntry::dobj, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_DEFINITION, _dumpableObject::dump_contains, _dumpableObject::dumpId, dumpIdMap, _catalogIdMapEntry::ext, _dumpableObject::ext_member, lastDumpId, _dumpableObject::name, _dumpableObject::nDeps, OidIsValid, pg_malloc_array, pg_realloc_array, and CatalogId::tableoid.

Referenced by createBoundaryObjects(), flagInhAttrs(), flagInhIndexes(), flagInhTables(), getAccessMethods(), getAggregates(), getCasts(), getCollations(), getConstraints(), getConversions(), getDefaultACLs(), getDomainConstraints(), getEventTriggers(), getExtendedStatistics(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getIndexes(), getLOs(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getPolicies(), getProcLangs(), getPublicationNamespaces(), getPublications(), getPublicationTables(), getRelationStatistics(), getRules(), getSubscriptions(), getSubscriptionTables(), getTableAttrs(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), and makeTableDataInfo().

◆ createDumpId()

◆ findCollationByOid()

CollInfo * findCollationByOid ( Oid  oid)

Definition at line 931 of file common.c.

932{
933 CatalogId catId;
934 DumpableObject *dobj;
935
936 catId.tableoid = CollationRelationId;
937 catId.oid = oid;
938 dobj = findObjectByCatalogId(catId);
939 Assert(dobj == NULL || dobj->objType == DO_COLLATION);
940 return (CollInfo *) dobj;
941}
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:755
DumpableObjectType objType
Definition: pg_dump.h:149

References Assert(), DO_COLLATION, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by createDummyViewAsClause(), dumpCompositeType(), dumpDomain(), dumpRangeType(), and dumpTableSchema().

◆ findExtensionByOid()

ExtensionInfo * findExtensionByOid ( Oid  oid)

Definition at line 967 of file common.c.

968{
969 CatalogId catId;
970 DumpableObject *dobj;
971
972 catId.tableoid = ExtensionRelationId;
973 catId.oid = oid;
974 dobj = findObjectByCatalogId(catId);
975 Assert(dobj == NULL || dobj->objType == DO_EXTENSION);
976 return (ExtensionInfo *) dobj;
977}

References Assert(), DO_EXTENSION, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by getExtensionMembership().

◆ findFuncByOid()

FuncInfo * findFuncByOid ( Oid  oid)

Definition at line 895 of file common.c.

896{
897 CatalogId catId;
898 DumpableObject *dobj;
899
900 catId.tableoid = ProcedureRelationId;
901 catId.oid = oid;
902 dobj = findObjectByCatalogId(catId);
903 Assert(dobj == NULL || dobj->objType == DO_FUNC);
904 return (FuncInfo *) dobj;
905}

References Assert(), DO_FUNC, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by dumpCast(), dumpProcLang(), and dumpTransform().

◆ findNamespaceByOid()

NamespaceInfo * findNamespaceByOid ( Oid  oid)

Definition at line 949 of file common.c.

950{
951 CatalogId catId;
952 DumpableObject *dobj;
953
954 catId.tableoid = NamespaceRelationId;
955 catId.oid = oid;
956 dobj = findObjectByCatalogId(catId);
957 Assert(dobj == NULL || dobj->objType == DO_NAMESPACE);
958 return (NamespaceInfo *) dobj;
959}

References Assert(), DO_NAMESPACE, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by findNamespace(), and getPublicationNamespaces().

◆ findObjectByCatalogId()

DumpableObject * findObjectByCatalogId ( CatalogId  catalogId)

Definition at line 755 of file common.c.

756{
757 CatalogIdMapEntry *entry;
758
759 if (catalogIdHash == NULL)
760 return NULL; /* no objects exist yet */
761
762 entry = catalogid_lookup(catalogIdHash, catalogId);
763 if (entry == NULL)
764 return NULL;
765 return entry->dobj;
766}

References catalogIdHash, and _catalogIdMapEntry::dobj.

Referenced by buildMatViewRefreshDependencies(), collectComments(), collectSecLabels(), findCollationByOid(), findExtensionByOid(), findFuncByOid(), findIndexByOid(), findNamespaceByOid(), findOprByOid(), findPublicationByOid(), findSubscriptionByOid(), findTableByOid(), findTypeByOid(), getAdditionalACLs(), and getDependencies().

◆ findObjectByDumpId()

DumpableObject * findObjectByDumpId ( DumpId  dumpId)

Definition at line 742 of file common.c.

743{
744 if (dumpId <= 0 || dumpId >= allocedDumpIds)
745 return NULL; /* out of range? */
746 return dumpIdMap[dumpId];
747}

References allocedDumpIds, and dumpIdMap.

Referenced by binary_upgrade_extension_member(), BuildArchiveDependencies(), dumpConstraint(), dumpDumpableObject(), dumpExtension(), findDumpableDependencies(), and findLoop().

◆ findOprByOid()

OprInfo * findOprByOid ( Oid  oid)

Definition at line 913 of file common.c.

914{
915 CatalogId catId;
916 DumpableObject *dobj;
917
918 catId.tableoid = OperatorRelationId;
919 catId.oid = oid;
920 dobj = findObjectByCatalogId(catId);
921 Assert(dobj == NULL || dobj->objType == DO_OPERATOR);
922 return (OprInfo *) dobj;
923}

References Assert(), DO_OPERATOR, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by getFormattedOperatorName().

◆ findOwningExtension()

ExtensionInfo * findOwningExtension ( CatalogId  catalogId)

Definition at line 1046 of file common.c.

1047{
1048 CatalogIdMapEntry *entry;
1049
1050 if (catalogIdHash == NULL)
1051 return NULL; /* no objects exist yet */
1052
1053 entry = catalogid_lookup(catalogIdHash, catalogId);
1054 if (entry == NULL)
1055 return NULL;
1056 return entry->ext;
1057}

References catalogIdHash, and _catalogIdMapEntry::ext.

Referenced by checkExtensionMembership().

◆ findPublicationByOid()

PublicationInfo * findPublicationByOid ( Oid  oid)

Definition at line 985 of file common.c.

986{
987 CatalogId catId;
988 DumpableObject *dobj;
989
990 catId.tableoid = PublicationRelationId;
991 catId.oid = oid;
992 dobj = findObjectByCatalogId(catId);
993 Assert(dobj == NULL || dobj->objType == DO_PUBLICATION);
994 return (PublicationInfo *) dobj;
995}

References Assert(), DO_PUBLICATION, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by getPublicationNamespaces(), and getPublicationTables().

◆ findSubscriptionByOid()

SubscriptionInfo * findSubscriptionByOid ( Oid  oid)

Definition at line 1003 of file common.c.

1004{
1005 CatalogId catId;
1006 DumpableObject *dobj;
1007
1008 catId.tableoid = SubscriptionRelationId;
1009 catId.oid = oid;
1010 dobj = findObjectByCatalogId(catId);
1011 Assert(dobj == NULL || dobj->objType == DO_SUBSCRIPTION);
1012 return (SubscriptionInfo *) dobj;
1013}

References Assert(), DO_SUBSCRIPTION, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by getSubscriptionTables().

◆ findTableByOid()

◆ findTypeByOid()

TypeInfo * findTypeByOid ( Oid  oid)

Definition at line 876 of file common.c.

877{
878 CatalogId catId;
879 DumpableObject *dobj;
880
881 catId.tableoid = TypeRelationId;
882 catId.oid = oid;
883 dobj = findObjectByCatalogId(catId);
884 Assert(dobj == NULL ||
885 dobj->objType == DO_TYPE || dobj->objType == DO_DUMMY_TYPE);
886 return (TypeInfo *) dobj;
887}

References Assert(), DO_DUMMY_TYPE, DO_TYPE, findObjectByCatalogId(), _dumpableObject::objType, CatalogId::oid, and CatalogId::tableoid.

Referenced by binary_upgrade_set_type_oids_by_type_oid(), collectComments(), collectSecLabels(), DOTypeNameCompare(), getCasts(), getFormattedTypeName(), and getTransforms().

◆ 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}
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:634
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
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int i
Definition: isn.c:77
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:128
PGresult * ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
Definition: pg_backup_db.c:229
static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
Definition: pg_dump.c:2167
#define atooid(x)
Definition: postgres_ext.h:41
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
int remoteVersion
Definition: pg_backup.h:229
char * amhandler
Definition: pg_dump.h:268
DumpableObject dobj
Definition: pg_dump.h:266

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

◆ 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}
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1070
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
static const char * getRoleName(const char *roleoid_str)
Definition: pg_dump.c:10386
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2270
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:5909
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:113
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
DumpOptions * dopt
Definition: pg_backup.h:224
int binary_upgrade
Definition: pg_backup.h:172

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

◆ 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}
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:876
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:2109
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
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:205

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}
const char * rolname
Definition: pg_dump.h:286
DumpableObject dobj
Definition: pg_dump.h:285

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}
TableInfo * findTableByOid(Oid oid)
Definition: common.c:840
static const gbtree_vinfo tinfo
Definition: btree_bit.c:108
int j
Definition: isn.c:78
#define pg_fatal(...)
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:8221
TypeInfo * condomain
Definition: pg_dump.h:510
TableInfo * contable
Definition: pg_dump.h:509
bool condeferred
Definition: pg_dump.h:516
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
DumpableObject dobj
Definition: pg_dump.h:411
struct _indxInfo * indexes
Definition: pg_dump.h:380
DumpableObject dobj
Definition: pg_dump.h:300
char relkind
Definition: pg_dump.h:303
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}
DumpableObject dobj
Definition: pg_dump.h:291
const char * rolname
Definition: pg_dump.h:292

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

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

◆ getDumpableObjects()

void getDumpableObjects ( DumpableObject ***  objs,
int *  numObjs 
)

Definition at line 774 of file common.c.

775{
776 int i,
777 j;
778
780 j = 0;
781 for (i = 1; i < allocedDumpIds; i++)
782 {
783 if (dumpIdMap[i])
784 (*objs)[j++] = dumpIdMap[i];
785 }
786 *numObjs = j;
787}

References allocedDumpIds, dumpIdMap, i, j, and pg_malloc_array.

Referenced by getTableDataFKConstraints(), and main().

◆ 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 * evtevent
Definition: pg_dump.h:489
char * evtfname
Definition: pg_dump.h:492
char evtenabled
Definition: pg_dump.h:493
char * evtname
Definition: pg_dump.h:488
const char * evtowner
Definition: pg_dump.h:490
char * evttags
Definition: pg_dump.h:491
DumpableObject dobj
Definition: pg_dump.h:487

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
int stattarget
Definition: pg_dump.h:462
const char * rolname
Definition: pg_dump.h:460
DumpableObject dobj
Definition: pg_dump.h:459

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
#define pg_log_warning(...)
Definition: pgfnames.c:24
DumpableObject dobj
Definition: pg_dump.h:195

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
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 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}
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 _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}
#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 _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().

◆ 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}
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static Oid g_last_builtin_oid
Definition: pg_dump.c:149
bool postponed_def
Definition: pg_dump.h:246
Oid lang
Definition: pg_dump.h:242
const char * rolname
Definition: pg_dump.h:241
Oid * argtypes
Definition: pg_dump.h:244
Oid prorettype
Definition: pg_dump.h:245
DumpableObject dobj
Definition: pg_dump.h:239
int nargs
Definition: pg_dump.h:243
DumpableAcl dacl
Definition: pg_dump.h:240

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}
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:795
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 parsePGArray(const char *atext, char ***itemarray, int *nitems)
Definition: string_utils.c:819
bool conperiod
Definition: pg_dump.h:517
bool indisreplident
Definition: pg_dump.h:423
int indnkeyattrs
Definition: pg_dump.h:418
char * indstatvals
Definition: pg_dump.h:417
char * indstatcols
Definition: pg_dump.h:416
int indnattrs
Definition: pg_dump.h:419
TableInfo * indextable
Definition: pg_dump.h:412
Oid parentidx
Definition: pg_dump.h:425
Oid * indkeys
Definition: pg_dump.h:420
char * indreloptions
Definition: pg_dump.h:415
DumpId indexconstraint
Definition: pg_dump.h:429
bool indisclustered
Definition: pg_dump.h:422
SimplePtrList partattaches
Definition: pg_dump.h:426
char * tablespace
Definition: pg_dump.h:414
bool indnullsnotdistinct
Definition: pg_dump.h:424
char * indexdef
Definition: pg_dump.h:413
DumpableObject dobj
Definition: pg_dump.h:441
bool interesting
Definition: pg_dump.h:334
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().

◆ getMaxDumpId()

DumpId getMaxDumpId ( void  )

Definition at line 731 of file common.c.

732{
733 return lastDumpId;
734}

References lastDumpId.

Referenced by findDependencyLoops(), and TopoSort().

◆ 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
char * pstrdup(const char *in)
Definition: mcxt.c:2325
NameData rolname
Definition: pg_authid.h:34
static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
Definition: pg_dump.c:1917
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPGArray(PQExpBuffer buffer, const char *value)
Definition: string_utils.c:902
DumpableObject dobj
Definition: pg_dump.h:186
DumpableAcl dacl
Definition: pg_dump.h:187
const char * rolname
Definition: pg_dump.h:190

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}
DumpableObject dobj
Definition: pg_dump.h:273
const char * rolname
Definition: pg_dump.h:274

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}
DumpableObject dobj
Definition: pg_dump.h:258
char oprkind
Definition: pg_dump.h:260
Oid oprcode
Definition: pg_dump.h:261
const char * rolname
Definition: pg_dump.h:259

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}
const char * rolname
Definition: pg_dump.h:280
DumpableObject dobj
Definition: pg_dump.h:279

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}
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:108
bool is_identity_sequence
Definition: pg_dump.h:330
Oid owning_tab
Definition: pg_dump.h:328

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}
bool dumpData
Definition: pg_backup.h:214
bool unsafe_partitions
Definition: pg_dump.h:338

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 pg_log_info(...)
Definition: logging.h:124
#define DUMP_COMPONENT_POLICY
Definition: pg_dump.h:114
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
int no_policies
Definition: pg_backup.h:185
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
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
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 _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}
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:949
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:985
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2234
NamespaceInfo * pubschema
Definition: pg_dump.h:692
DumpableObject dobj
Definition: pg_dump.h:690
PublicationInfo * publication
Definition: pg_dump.h:691
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}
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(), 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}
#define free(a)
Definition: header.h:65
const char * fmtId(const char *rawid)
Definition: string_utils.c:248

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

◆ 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}
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

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

◆ getSchemaData()

TableInfo * getSchemaData ( Archive fout,
int *  numTablesPtr 
)

Definition at line 97 of file common.c.

98{
99 TableInfo *tblinfo;
100 ExtensionInfo *extinfo;
101 InhInfo *inhinfo;
102 int numTables;
103 int numExtensions;
104 int numInherits;
105
106 /*
107 * We must read extensions and extension membership info first, because
108 * extension membership needs to be consultable during decisions about
109 * whether other objects are to be dumped.
110 */
111 pg_log_info("reading extensions");
112 extinfo = getExtensions(fout, &numExtensions);
113
114 pg_log_info("identifying extension members");
115 getExtensionMembership(fout, extinfo, numExtensions);
116
117 pg_log_info("reading schemas");
118 getNamespaces(fout);
119
120 /*
121 * getTables should be done as soon as possible, so as to minimize the
122 * window between starting our transaction and acquiring per-table locks.
123 * However, we have to do getNamespaces first because the tables get
124 * linked to their containing namespaces during getTables.
125 */
126 pg_log_info("reading user-defined tables");
127 tblinfo = getTables(fout, &numTables);
128
129 getOwnedSeqs(fout, tblinfo, numTables);
130
131 pg_log_info("reading user-defined functions");
132 getFuncs(fout);
133
134 /* this must be after getTables and getFuncs */
135 pg_log_info("reading user-defined types");
136 getTypes(fout);
137
138 /* this must be after getFuncs, too */
139 pg_log_info("reading procedural languages");
140 getProcLangs(fout);
141
142 pg_log_info("reading user-defined aggregate functions");
143 getAggregates(fout);
144
145 pg_log_info("reading user-defined operators");
146 getOperators(fout);
147
148 pg_log_info("reading user-defined access methods");
149 getAccessMethods(fout);
150
151 pg_log_info("reading user-defined operator classes");
152 getOpclasses(fout);
153
154 pg_log_info("reading user-defined operator families");
155 getOpfamilies(fout);
156
157 pg_log_info("reading user-defined text search parsers");
158 getTSParsers(fout);
159
160 pg_log_info("reading user-defined text search templates");
161 getTSTemplates(fout);
162
163 pg_log_info("reading user-defined text search dictionaries");
164 getTSDictionaries(fout);
165
166 pg_log_info("reading user-defined text search configurations");
168
169 pg_log_info("reading user-defined foreign-data wrappers");
171
172 pg_log_info("reading user-defined foreign servers");
173 getForeignServers(fout);
174
175 pg_log_info("reading default privileges");
176 getDefaultACLs(fout);
177
178 pg_log_info("reading user-defined collations");
179 getCollations(fout);
180
181 pg_log_info("reading user-defined conversions");
182 getConversions(fout);
183
184 pg_log_info("reading type casts");
185 getCasts(fout);
186
187 pg_log_info("reading transforms");
188 getTransforms(fout);
189
190 pg_log_info("reading table inheritance information");
191 inhinfo = getInherits(fout, &numInherits);
192
193 pg_log_info("reading event triggers");
194 getEventTriggers(fout);
195
196 /* Identify extension configuration tables that should be dumped */
197 pg_log_info("finding extension tables");
198 processExtensionTables(fout, extinfo, numExtensions);
199
200 /* Link tables to parents, mark parents of target tables interesting */
201 pg_log_info("finding inheritance relationships");
202 flagInhTables(fout, tblinfo, numTables, inhinfo, numInherits);
203
204 pg_log_info("reading column info for interesting tables");
205 getTableAttrs(fout, tblinfo, numTables);
206
207 pg_log_info("flagging inherited columns in subtables");
208 flagInhAttrs(fout, fout->dopt, tblinfo, numTables);
209
210 pg_log_info("reading partitioning data");
212
213 pg_log_info("reading indexes");
214 getIndexes(fout, tblinfo, numTables);
215
216 pg_log_info("flagging indexes in partitioned tables");
217 flagInhIndexes(fout, tblinfo, numTables);
218
219 pg_log_info("reading extended statistics");
221
222 pg_log_info("reading constraints");
223 getConstraints(fout, tblinfo, numTables);
224
225 pg_log_info("reading triggers");
226 getTriggers(fout, tblinfo, numTables);
227
228 pg_log_info("reading rewrite rules");
229 getRules(fout);
230
231 pg_log_info("reading policies");
232 getPolicies(fout, tblinfo, numTables);
233
234 pg_log_info("reading publications");
235 getPublications(fout);
236
237 pg_log_info("reading publication membership of tables");
238 getPublicationTables(fout, tblinfo, numTables);
239
240 pg_log_info("reading publication membership of schemas");
242
243 pg_log_info("reading subscriptions");
244 getSubscriptions(fout);
245
246 pg_log_info("reading subscription membership of tables");
248
249 free(inhinfo); /* not needed any longer */
250
251 *numTablesPtr = numTables;
252 return tblinfo;
253}
static void flagInhAttrs(Archive *fout, DumpOptions *dopt, TableInfo *tblinfo, int numTables)
Definition: common.c:477
static void flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables, InhInfo *inhinfo, int numInherits)
Definition: common.c:268
static void flagInhIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8062
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:5927
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4588
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7554
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7498
void getForeignDataWrappers(Archive *fout)
Definition: pg_dump.c:10117
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4092
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19243
void getTypes(Archive *fout)
Definition: pg_dump.c:6002
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7433
void getOpclasses(Archive *fout)
Definition: pg_dump.c:6423
void getForeignServers(Archive *fout)
Definition: pg_dump.c:10201
void getFuncs(Archive *fout)
Definition: pg_dump.c:6686
void getTSDictionaries(Archive *fout)
Definition: pg_dump.c:9933
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4668
void getCasts(Archive *fout)
Definition: pg_dump.c:8789
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7614
void getTSConfigurations(Archive *fout)
Definition: pg_dump.c:10058
void getAccessMethods(Archive *fout)
Definition: pg_dump.c:6361
void getConversions(Archive *fout)
Definition: pg_dump.c:6299
void getRules(Archive *fout)
Definition: pg_dump.c:8334
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:8983
void getSubscriptionTables(Archive *fout)
Definition: pg_dump.c:5137
void getCollations(Archive *fout)
Definition: pg_dump.c:6237
void getAggregates(Archive *fout)
Definition: pg_dump.c:6545
void getNamespaces(Archive *fout)
Definition: pg_dump.c:5795
void getPublications(Archive *fout)
Definition: pg_dump.c:4382
void getTSParsers(Archive *fout)
Definition: pg_dump.c:9859
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:6956
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:7983
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19336
void getDefaultACLs(Archive *fout)
Definition: pg_dump.c:10289
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:4939
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8431
void getTransforms(Archive *fout)
Definition: pg_dump.c:8899
void getEventTriggers(Archive *fout)
Definition: pg_dump.c:8627
void getTSTemplates(Archive *fout)
Definition: pg_dump.c:9999
void getProcLangs(Archive *fout)
Definition: pg_dump.c:8705
void getOperators(Archive *fout)
Definition: pg_dump.c:6169
void getOpfamilies(Archive *fout)
Definition: pg_dump.c:6483

References Archive::dopt, flagInhAttrs(), flagInhIndexes(), flagInhTables(), free, getAccessMethods(), getAggregates(), getCasts(), getCollations(), getConstraints(), getConversions(), getDefaultACLs(), getEventTriggers(), getExtendedStatistics(), getExtensionMembership(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getIndexes(), getInherits(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getOwnedSeqs(), getPartitioningInfo(), getPolicies(), getProcLangs(), getPublicationNamespaces(), getPublications(), getPublicationTables(), getRules(), getSubscriptions(), getSubscriptionTables(), getTableAttrs(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), pg_log_info, and processExtensionTables().

Referenced by main().

◆ getSubscriptions()

void getSubscriptions ( Archive fout)

Definition at line 4939 of file pg_dump.c.

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

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

◆ 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}
#define CppAsString2(x)
Definition: c.h:363
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
Definition: connection.c:203
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
void ExecuteSqlStatement(Archive *AHX, const char *query)
Definition: pg_backup_db.c:217
static void selectDumpableTable(TableInfo *tbinfo, Archive *fout)
Definition: pg_dump.c:2003
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:231
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:110
#define DUMP_COMPONENTS_REQUIRING_LOCK
Definition: pg_dump.h:141
#define DUMP_COMPONENT_STATISTICS
Definition: pg_dump.h:116
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:446
const char * lockWaitTimeout
Definition: pg_backup.h:177
char * reltablespace
Definition: pg_dump.h:307
struct _relStatsInfo * stats
Definition: pg_dump.h:372
bool ispartition
Definition: pg_dump.h:337
Oid reloftype
Definition: pg_dump.h:325
char * toast_reloptions
Definition: pg_dump.h:310
DumpableAcl dacl
Definition: pg_dump.h:301
bool relispopulated
Definition: pg_dump.h:305
Oid reltype
Definition: pg_dump.h:324
bool hasoids
Definition: pg_dump.h:317
Oid toast_oid
Definition: pg_dump.h:320
Oid foreign_server
Definition: pg_dump.h:326
bool hasrules
Definition: pg_dump.h:312
uint32 frozenxid
Definition: pg_dump.h:318
int owning_col
Definition: pg_dump.h:329
char * checkoption
Definition: pg_dump.h:309
bool hastriggers
Definition: pg_dump.h:313
const char * rolname
Definition: pg_dump.h:302
char relreplident
Definition: pg_dump.h:306
uint32 minmxid
Definition: pg_dump.h:319
int toastpages
Definition: pg_dump.h:332
char * amname
Definition: pg_dump.h:374
bool dummy_view
Definition: pg_dump.h:335
int32 relpages
Definition: pg_dump.h:331
bool forcerowsec
Definition: pg_dump.h:316
char relpersistence
Definition: pg_dump.h:304
char * reloptions
Definition: pg_dump.h:308
uint32 toast_frozenxid
Definition: pg_dump.h:321
uint32 toast_minmxid
Definition: pg_dump.h:322
bool postponed_def
Definition: pg_dump.h:336

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}
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(), 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
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 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}
Oid cfgparser
Definition: pg_dump.h:588
DumpableObject dobj
Definition: pg_dump.h:586
const char * rolname
Definition: pg_dump.h:587

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}
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 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}
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 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}
Oid tmpllexize
Definition: pg_dump.h:581
Oid tmplinit
Definition: pg_dump.h:580
DumpableObject dobj
Definition: pg_dump.h:579

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 const CatalogId nilCatalogId
Definition: pg_dump.c:186
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:8244
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:2042
TypeInfo * baseType
Definition: pg_dump.h:234
DumpableObject dobj
Definition: pg_dump.h:232
bool isMultirange
Definition: pg_dump.h:221
struct _constraintInfo * domChecks
Definition: pg_dump.h:227
DumpableAcl dacl
Definition: pg_dump.h:206
bool isDefined
Definition: pg_dump.h:222
char * ftypname
Definition: pg_dump.h:213
char typrelkind
Definition: pg_dump.h:218
Oid typarray
Definition: pg_dump.h:217
Oid typelem
Definition: pg_dump.h:215
struct _shellTypeInfo * shellType
Definition: pg_dump.h:224
int nDomChecks
Definition: pg_dump.h:226
char typtype
Definition: pg_dump.h:219
const char * rolname
Definition: pg_dump.h:214
Oid typrelid
Definition: pg_dump.h:216
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().

◆ parseOidArray()

void parseOidArray ( const char *  str,
Oid array,
int  arraysize 
)

Definition at line 1070 of file common.c.

1071{
1072 int j,
1073 argNum;
1074 char temp[100];
1075 char s;
1076
1077 argNum = 0;
1078 j = 0;
1079 for (;;)
1080 {
1081 s = *str++;
1082 if (s == ' ' || s == '\0')
1083 {
1084 if (j > 0)
1085 {
1086 if (argNum >= arraysize)
1087 pg_fatal("could not parse numeric array \"%s\": too many numbers", str);
1088 temp[j] = '\0';
1089 array[argNum++] = atooid(temp);
1090 j = 0;
1091 }
1092 if (s == '\0')
1093 break;
1094 }
1095 else
1096 {
1097 if (!(isdigit((unsigned char) s) || s == '-') ||
1098 j >= sizeof(temp) - 1)
1099 pg_fatal("could not parse numeric array \"%s\": invalid character in number", str);
1100 temp[j++] = s;
1101 }
1102 }
1103
1104 while (argNum < arraysize)
1105 array[argNum++] = InvalidOid;
1106}
const char * str

References atooid, InvalidOid, j, pg_fatal, and str.

Referenced by dumpFunc(), getAggregates(), getFuncs(), and getIndexes().

◆ 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}
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:165
static SimpleOidList extension_include_oids
Definition: pg_dump.c:181
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:184
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2948
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:172
static SimpleOidList table_include_oids
Definition: pg_dump.c:169
bool simple_oid_list_member(SimpleOidList *list, Oid val)
Definition: simple_list.c:45
SimpleOidListCell * head
Definition: simple_list.h:28
DumpableObject dobj
Definition: pg_dump.h:404
char * filtercond
Definition: pg_dump.h:406
struct _tableDataInfo * dataObj
Definition: pg_dump.h:381

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

◆ recordAdditionalCatalogID()

void recordAdditionalCatalogID ( CatalogId  catId,
DumpableObject dobj 
)

Definition at line 696 of file common.c.

697{
698 CatalogIdMapEntry *entry;
699 bool found;
700
701 /* CatalogId hash table must exist, if we have a DumpableObject */
702 Assert(catalogIdHash != NULL);
703
704 /* Add reference to CatalogId hash */
705 entry = catalogid_insert(catalogIdHash, catId, &found);
706 if (!found)
707 {
708 entry->dobj = NULL;
709 entry->ext = NULL;
710 }
711 Assert(entry->dobj == NULL);
712 entry->dobj = dobj;
713}

References Assert(), catalogIdHash, _catalogIdMapEntry::dobj, and _catalogIdMapEntry::ext.

Referenced by getLOs().

◆ recordExtensionMembership()

void recordExtensionMembership ( CatalogId  catId,
ExtensionInfo ext 
)

Definition at line 1022 of file common.c.

1023{
1024 CatalogIdMapEntry *entry;
1025 bool found;
1026
1027 /* CatalogId hash table must exist, if we have an ExtensionInfo */
1028 Assert(catalogIdHash != NULL);
1029
1030 /* Add reference to CatalogId hash */
1031 entry = catalogid_insert(catalogIdHash, catId, &found);
1032 if (!found)
1033 {
1034 entry->dobj = NULL;
1035 entry->ext = NULL;
1036 }
1037 Assert(entry->ext == NULL);
1038 entry->ext = ext;
1039}

References Assert(), catalogIdHash, _catalogIdMapEntry::dobj, and _catalogIdMapEntry::ext.

Referenced by getExtensionMembership().

◆ removeObjectDependency()

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

◆ sortDumpableObjects()

void sortDumpableObjects ( DumpableObject **  objs,
int  numObjs,
DumpId  preBoundaryId,
DumpId  postBoundaryId 
)

Definition at line 334 of file pg_dump_sort.c.

336{
337 DumpableObject **ordering;
338 int nOrdering;
339
340 if (numObjs <= 0) /* can't happen anymore ... */
341 return;
342
343 /*
344 * Saving the boundary IDs in static variables is a bit grotty, but seems
345 * better than adding them to parameter lists of subsidiary functions.
346 */
347 preDataBoundId = preBoundaryId;
348 postDataBoundId = postBoundaryId;
349
350 ordering = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
351 while (!TopoSort(objs, numObjs, ordering, &nOrdering))
352 findDependencyLoops(ordering, nOrdering, numObjs);
353
354 memcpy(objs, ordering, numObjs * sizeof(DumpableObject *));
355
356 free(ordering);
357}
static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
Definition: pg_dump_sort.c:535
static DumpId preDataBoundId
Definition: pg_dump_sort.c:160
static bool TopoSort(DumpableObject **objs, int numObjs, DumpableObject **ordering, int *nOrdering)
Definition: pg_dump_sort.c:386
static DumpId postDataBoundId
Definition: pg_dump_sort.c:161

References findDependencyLoops(), free, pg_malloc(), postDataBoundId, preDataBoundId, and TopoSort().

Referenced by main().

◆ sortDumpableObjectsByTypeName()

void sortDumpableObjectsByTypeName ( DumpableObject **  objs,
int  numObjs 
)

Definition at line 190 of file pg_dump_sort.c.

191{
192 if (numObjs > 1)
193 qsort(objs, numObjs, sizeof(DumpableObject *),
195}
static int DOTypeNameCompare(const void *p1, const void *p2)
Definition: pg_dump_sort.c:198
#define qsort(a, b, c, d)
Definition: port.h:479

References DOTypeNameCompare(), and qsort.

Referenced by main().