PostgreSQL Source Code git master
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)
 
AccessMethodInfofindAccessMethodByOid (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 getSubscriptionRelations (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 657 of file common.c.

658{
659 dobj->dumpId = ++lastDumpId;
660 dobj->name = NULL; /* must be set later */
661 dobj->namespace = NULL; /* may be set later */
662 dobj->dump = DUMP_COMPONENT_ALL; /* default assumption */
663 dobj->dump_contains = DUMP_COMPONENT_ALL; /* default assumption */
664 /* All objects have definitions; we may set more components bits later */
666 dobj->ext_member = false; /* default assumption */
667 dobj->depends_on_ext = false; /* default assumption */
668 dobj->dependencies = NULL;
669 dobj->nDeps = 0;
670 dobj->allocDeps = 0;
671
672 /* Add object to dumpIdMap[], enlarging that array if need be */
673 while (dobj->dumpId >= allocedDumpIds)
674 {
675 int newAlloc;
676
677 if (allocedDumpIds <= 0)
678 {
679 newAlloc = 256;
681 }
682 else
683 {
684 newAlloc = allocedDumpIds * 2;
686 }
687 memset(dumpIdMap + allocedDumpIds, 0,
688 (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
689 allocedDumpIds = newAlloc;
690 }
691 dumpIdMap[dobj->dumpId] = dobj;
692
693 /* If it has a valid CatalogId, enter it into the hash table */
694 if (OidIsValid(dobj->catId.tableoid))
695 {
696 CatalogIdMapEntry *entry;
697 bool found;
698
699 /* Initialize CatalogId hash table if not done yet */
700 if (catalogIdHash == NULL)
701 catalogIdHash = catalogid_create(CATALOGIDHASH_INITIAL_SIZE, NULL);
702
703 entry = catalogid_insert(catalogIdHash, dobj->catId, &found);
704 if (!found)
705 {
706 entry->dobj = NULL;
707 entry->ext = NULL;
708 }
709 Assert(entry->dobj == NULL);
710 entry->dobj = dobj;
711 }
712}
static int allocedDumpIds
Definition: common.c:38
static DumpableObject ** dumpIdMap
Definition: common.c:37
#define CATALOGIDHASH_INITIAL_SIZE
Definition: common.c:80
static catalogid_hash * catalogIdHash
Definition: common.c:82
static DumpId lastDumpId
Definition: common.c:39
#define OidIsValid(objectId)
Definition: c.h:777
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:280
ExtensionInfo * ext
Definition: common.c:63
DumpableObject * dobj
Definition: common.c:62
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(), getSubscriptionRelations(), getSubscriptions(), getTableAttrs(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), and makeTableDataInfo().

◆ createDumpId()

◆ findAccessMethodByOid()

AccessMethodInfo * findAccessMethodByOid ( Oid  oid)

Definition at line 954 of file common.c.

955{
956 CatalogId catId;
957 DumpableObject *dobj;
958
959 catId.tableoid = AccessMethodRelationId;
960 catId.oid = oid;
961 dobj = findObjectByCatalogId(catId);
962 Assert(dobj == NULL || dobj->objType == DO_ACCESS_METHOD);
963 return (AccessMethodInfo *) dobj;
964}
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:778
DumpableObjectType objType
Definition: pg_dump.h:149

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

Referenced by accessMethodNameCompare().

◆ findCollationByOid()

CollInfo * findCollationByOid ( Oid  oid)

Definition at line 972 of file common.c.

973{
974 CatalogId catId;
975 DumpableObject *dobj;
976
977 catId.tableoid = CollationRelationId;
978 catId.oid = oid;
979 dobj = findObjectByCatalogId(catId);
980 Assert(dobj == NULL || dobj->objType == DO_COLLATION);
981 return (CollInfo *) dobj;
982}

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 1008 of file common.c.

1009{
1010 CatalogId catId;
1011 DumpableObject *dobj;
1012
1013 catId.tableoid = ExtensionRelationId;
1014 catId.oid = oid;
1015 dobj = findObjectByCatalogId(catId);
1016 Assert(dobj == NULL || dobj->objType == DO_EXTENSION);
1017 return (ExtensionInfo *) dobj;
1018}

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

Referenced by getExtensionMembership().

◆ findFuncByOid()

FuncInfo * findFuncByOid ( Oid  oid)

Definition at line 918 of file common.c.

919{
920 CatalogId catId;
921 DumpableObject *dobj;
922
923 catId.tableoid = ProcedureRelationId;
924 catId.oid = oid;
925 dobj = findObjectByCatalogId(catId);
926 Assert(dobj == NULL || dobj->objType == DO_FUNC);
927 return (FuncInfo *) dobj;
928}

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 990 of file common.c.

991{
992 CatalogId catId;
993 DumpableObject *dobj;
994
995 catId.tableoid = NamespaceRelationId;
996 catId.oid = oid;
997 dobj = findObjectByCatalogId(catId);
998 Assert(dobj == NULL || dobj->objType == DO_NAMESPACE);
999 return (NamespaceInfo *) dobj;
1000}

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 778 of file common.c.

779{
780 CatalogIdMapEntry *entry;
781
782 if (catalogIdHash == NULL)
783 return NULL; /* no objects exist yet */
784
785 entry = catalogid_lookup(catalogIdHash, catalogId);
786 if (entry == NULL)
787 return NULL;
788 return entry->dobj;
789}

References catalogIdHash, and _catalogIdMapEntry::dobj.

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

◆ findObjectByDumpId()

DumpableObject * findObjectByDumpId ( DumpId  dumpId)

Definition at line 765 of file common.c.

766{
767 if (dumpId <= 0 || dumpId >= allocedDumpIds)
768 return NULL; /* out of range? */
769 return dumpIdMap[dumpId];
770}

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 936 of file common.c.

937{
938 CatalogId catId;
939 DumpableObject *dobj;
940
941 catId.tableoid = OperatorRelationId;
942 catId.oid = oid;
943 dobj = findObjectByCatalogId(catId);
944 Assert(dobj == NULL || dobj->objType == DO_OPERATOR);
945 return (OprInfo *) dobj;
946}

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

Referenced by getFormattedOperatorName().

◆ findOwningExtension()

ExtensionInfo * findOwningExtension ( CatalogId  catalogId)

Definition at line 1087 of file common.c.

1088{
1089 CatalogIdMapEntry *entry;
1090
1091 if (catalogIdHash == NULL)
1092 return NULL; /* no objects exist yet */
1093
1094 entry = catalogid_lookup(catalogIdHash, catalogId);
1095 if (entry == NULL)
1096 return NULL;
1097 return entry->ext;
1098}

References catalogIdHash, and _catalogIdMapEntry::ext.

Referenced by checkExtensionMembership().

◆ findPublicationByOid()

PublicationInfo * findPublicationByOid ( Oid  oid)

Definition at line 1026 of file common.c.

1027{
1028 CatalogId catId;
1029 DumpableObject *dobj;
1030
1031 catId.tableoid = PublicationRelationId;
1032 catId.oid = oid;
1033 dobj = findObjectByCatalogId(catId);
1034 Assert(dobj == NULL || dobj->objType == DO_PUBLICATION);
1035 return (PublicationInfo *) dobj;
1036}

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 1044 of file common.c.

1045{
1046 CatalogId catId;
1047 DumpableObject *dobj;
1048
1049 catId.tableoid = SubscriptionRelationId;
1050 catId.oid = oid;
1051 dobj = findObjectByCatalogId(catId);
1052 Assert(dobj == NULL || dobj->objType == DO_SUBSCRIPTION);
1053 return (SubscriptionInfo *) dobj;
1054}

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

Referenced by getSubscriptionRelations().

◆ findTableByOid()

◆ findTypeByOid()

TypeInfo * findTypeByOid ( Oid  oid)

Definition at line 899 of file common.c.

900{
901 CatalogId catId;
902 DumpableObject *dobj;
903
904 catId.tableoid = TypeRelationId;
905 catId.oid = oid;
906 dobj = findObjectByCatalogId(catId);
907 Assert(dobj == NULL ||
908 dobj->objType == DO_TYPE || dobj->objType == DO_DUMMY_TYPE);
909 return (TypeInfo *) dobj;
910}

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(), getCasts(), getFormattedTypeName(), getTransforms(), and pgTypeNameCompare().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6556 of file pg_dump.c.

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

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

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

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

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

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

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

Referenced by getSchemaData().

◆ getConstraints()

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

Definition at line 8277 of file pg_dump.c.

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

References addConstrChildIdxDeps(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_FK_CONSTRAINT, _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, DUMP_COMPONENT_DEFINITION, ExecuteSqlQuery(), findTableByOid(), i, _tableInfo::indexes, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::numIndexes, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, _tableInfo::relkind, Archive::remoteVersion, _constraintInfo::separate, CatalogId::tableoid, and tinfo.

Referenced by getSchemaData().

◆ getConversions()

void getConversions ( Archive fout)

Definition at line 6494 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getDefaultACLs()

void getDefaultACLs ( Archive fout)

Definition at line 10569 of file pg_dump.c.

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

798{
799 int i,
800 j;
801
803 j = 0;
804 for (i = 1; i < allocedDumpIds; i++)
805 {
806 if (dumpIdMap[i])
807 (*objs)[j++] = dumpIdMap[i];
808 }
809 *numObjs = j;
810}

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

Referenced by getTableDataFKConstraints(), and main().

◆ getEventTriggers()

void getEventTriggers ( Archive fout)

Definition at line 8864 of file pg_dump.c.

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

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_EVENT_TRIGGER, _evttriggerInfo::dobj, _evttriggerInfo::evtenabled, _evttriggerInfo::evtevent, _evttriggerInfo::evtfname, _evttriggerInfo::evtname, _evttriggerInfo::evtowner, _evttriggerInfo::evttags, ExecuteSqlQuery(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, Archive::remoteVersion, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtendedStatistics()

void getExtendedStatistics ( Archive fout)

Definition at line 8198 of file pg_dump.c.

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

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_STATSEXT, _statsExtInfo::dobj, ExecuteSqlQuery(), findNamespace(), findTableByOid(), getRoleName(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, Archive::remoteVersion, _statsExtInfo::rolname, selectDumpableStatisticsObject(), _statsExtInfo::stattable, _statsExtInfo::stattarget, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtensionMembership()

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

Definition at line 19672 of file pg_dump.c.

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

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

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _fdwInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_FDW, _fdwInfo::dobj, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), _fdwInfo::fdwhandler, _fdwInfo::fdwoptions, _fdwInfo::fdwvalidator, getRoleName(), i, _dumpableAcl::initprivs, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, _dumpableAcl::privtype, _fdwInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignServers()

void getForeignServers ( Archive fout)

Definition at line 10481 of file pg_dump.c.

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

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

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), _funcInfo::argtypes, AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _funcInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_FUNC, _funcInfo::dobj, Archive::dopt, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findNamespace(), g_last_builtin_oid, getRoleName(), i, _dumpableAcl::initprivs, _funcInfo::lang, _dumpableObject::name, _funcInfo::nargs, _dumpableObject::objType, CatalogId::oid, parseOidArray(), pg_malloc(), pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, _funcInfo::postponed_def, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, _dumpableAcl::privtype, _funcInfo::prorettype, Archive::remoteVersion, _funcInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getIndexes()

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

Definition at line 7829 of file pg_dump.c.

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

References addObjectDependency(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::conperiod, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_CONSTRAINT, DO_INDEX, _tableInfo::dobj, _indxInfo::dobj, _relStatsInfo::dobj, _constraintInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), getRelationStatistics(), _tableInfo::hasindex, i, _indxInfo::indexconstraint, _indxInfo::indexdef, _tableInfo::indexes, _indxInfo::indextable, _indxInfo::indisclustered, _indxInfo::indisreplident, _indxInfo::indkeys, _indxInfo::indnattrs, _indxInfo::indnkeyattrs, _indxInfo::indnullsnotdistinct, _indxInfo::indreloptions, _indxInfo::indstatcols, _indxInfo::indstatvals, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::numIndexes, _dumpableObject::objType, CatalogId::oid, _indxInfo::parentidx, parseOidArray(), parsePGArray(), _indxInfo::partattaches, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, Archive::remoteVersion, _constraintInfo::separate, CatalogId::tableoid, and _indxInfo::tablespace.

Referenced by getSchemaData().

◆ getInherits()

InhInfo * getInherits ( Archive fout,
int *  numInherits 
)

Definition at line 7713 of file pg_dump.c.

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

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), i, _inhInfo::inhparent, _inhInfo::inhrelid, pg_malloc(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, and PQntuples.

Referenced by getSchemaData().

◆ getMaxDumpId()

DumpId getMaxDumpId ( void  )

Definition at line 754 of file common.c.

755{
756 return lastDumpId;
757}

References lastDumpId.

Referenced by findDependencyLoops(), and TopoSort().

◆ getNamespaces()

void getNamespaces ( Archive fout)

Definition at line 5977 of file pg_dump.c.

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

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

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

Referenced by getSchemaData().

◆ getOperators()

void getOperators ( Archive fout)

Definition at line 6352 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getOpfamilies()

void getOpfamilies ( Archive fout)

Definition at line 6693 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getOwnedSeqs()

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

Definition at line 7648 of file pg_dump.c.

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

References _dumpableObject::catId, _tableInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_NONE, findTableByOid(), i, _tableInfo::interesting, _tableInfo::is_identity_sequence, CatalogId::oid, OidIsValid, _tableInfo::owning_tab, and pg_fatal.

Referenced by getSchemaData().

◆ getPartitioningInfo()

void getPartitioningInfo ( Archive fout)

Definition at line 7769 of file pg_dump.c.

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

References appendPQExpBufferStr(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::dopt, _dumpOptions::dumpData, ExecuteSqlQuery(), findTableByOid(), i, pg_fatal, PGRES_TUPLES_OK, PQclear, PQgetvalue, PQntuples, Archive::remoteVersion, and _tableInfo::unsafe_partitions.

Referenced by getSchemaData().

◆ getPolicies()

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

Definition at line 4233 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_POLICY, _tableInfo::dobj, _policyInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_POLICY, ExecuteSqlQuery(), findTableByOid(), i, j, PQExpBufferData::len, _dumpableObject::name, _dumpOptions::no_policies, _dumpableObject::objType, CatalogId::oid, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, _policyInfo::polcmd, _policyInfo::polname, _policyInfo::polpermissive, _policyInfo::polqual, _policyInfo::polroles, _policyInfo::poltable, _policyInfo::polwithcheck, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, _tableInfo::rowsec, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getProcLangs()

void getProcLangs ( Archive fout)

Definition at line 8942 of file pg_dump.c.

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _procLangInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_PROCLANG, _procLangInfo::dobj, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), getRoleName(), i, _dumpableAcl::initprivs, _procLangInfo::laninline, _procLangInfo::lanowner, _procLangInfo::lanplcallfoid, _procLangInfo::lanpltrusted, _procLangInfo::lanvalidator, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, _dumpableAcl::privtype, selectDumpableProcLang(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationNamespaces()

void getPublicationNamespaces ( Archive fout)

Definition at line 4742 of file pg_dump.c.

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

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_TABLE_IN_SCHEMA, _namespaceInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, ExecuteSqlQuery(), findNamespaceByOid(), findPublicationByOid(), i, j, _dumpableObject::name, _dumpOptions::no_publications, _dumpableObject::objType, CatalogId::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, _PublicationSchemaInfo::publication, _PublicationSchemaInfo::pubschema, Archive::remoteVersion, selectDumpablePublicationObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublications()

void getPublications ( Archive fout)

Definition at line 4523 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, cleanup(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION, _PublicationInfo::dobj, Archive::dopt, ExecuteSqlQuery(), getRoleName(), i, _dumpableObject::name, _dumpOptions::no_publications, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, _PublicationInfo::puballsequences, _PublicationInfo::puballtables, _PublicationInfo::pubdelete, _PublicationInfo::pubgencols_type, _PublicationInfo::pubinsert, _PublicationInfo::pubtruncate, _PublicationInfo::pubupdate, _PublicationInfo::pubviaroot, Archive::remoteVersion, _PublicationInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationTables()

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

Definition at line 4822 of file pg_dump.c.

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

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

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 98 of file common.c.

99{
100 TableInfo *tblinfo;
101 ExtensionInfo *extinfo;
102 InhInfo *inhinfo;
103 int numTables;
104 int numExtensions;
105 int numInherits;
106
107 /*
108 * We must read extensions and extension membership info first, because
109 * extension membership needs to be consultable during decisions about
110 * whether other objects are to be dumped.
111 */
112 pg_log_info("reading extensions");
113 extinfo = getExtensions(fout, &numExtensions);
114
115 pg_log_info("identifying extension members");
116 getExtensionMembership(fout, extinfo, numExtensions);
117
118 pg_log_info("reading schemas");
119 getNamespaces(fout);
120
121 /*
122 * getTables should be done as soon as possible, so as to minimize the
123 * window between starting our transaction and acquiring per-table locks.
124 * However, we have to do getNamespaces first because the tables get
125 * linked to their containing namespaces during getTables.
126 */
127 pg_log_info("reading user-defined tables");
128 tblinfo = getTables(fout, &numTables);
129
130 getOwnedSeqs(fout, tblinfo, numTables);
131
132 pg_log_info("reading user-defined functions");
133 getFuncs(fout);
134
135 /* this must be after getTables and getFuncs */
136 pg_log_info("reading user-defined types");
137 getTypes(fout);
138
139 /* this must be after getFuncs, too */
140 pg_log_info("reading procedural languages");
141 getProcLangs(fout);
142
143 pg_log_info("reading user-defined aggregate functions");
144 getAggregates(fout);
145
146 pg_log_info("reading user-defined operators");
147 getOperators(fout);
148
149 pg_log_info("reading user-defined access methods");
150 getAccessMethods(fout);
151
152 pg_log_info("reading user-defined operator classes");
153 getOpclasses(fout);
154
155 pg_log_info("reading user-defined operator families");
156 getOpfamilies(fout);
157
158 pg_log_info("reading user-defined text search parsers");
159 getTSParsers(fout);
160
161 pg_log_info("reading user-defined text search templates");
162 getTSTemplates(fout);
163
164 pg_log_info("reading user-defined text search dictionaries");
165 getTSDictionaries(fout);
166
167 pg_log_info("reading user-defined text search configurations");
169
170 pg_log_info("reading user-defined foreign-data wrappers");
172
173 pg_log_info("reading user-defined foreign servers");
174 getForeignServers(fout);
175
176 pg_log_info("reading default privileges");
177 getDefaultACLs(fout);
178
179 pg_log_info("reading user-defined collations");
180 getCollations(fout);
181
182 pg_log_info("reading user-defined conversions");
183 getConversions(fout);
184
185 pg_log_info("reading type casts");
186 getCasts(fout);
187
188 pg_log_info("reading transforms");
189 getTransforms(fout);
190
191 pg_log_info("reading table inheritance information");
192 inhinfo = getInherits(fout, &numInherits);
193
194 pg_log_info("reading event triggers");
195 getEventTriggers(fout);
196
197 /* Identify extension configuration tables that should be dumped */
198 pg_log_info("finding extension tables");
199 processExtensionTables(fout, extinfo, numExtensions);
200
201 /* Link tables to parents, mark parents of target tables interesting */
202 pg_log_info("finding inheritance relationships");
203 flagInhTables(fout, tblinfo, numTables, inhinfo, numInherits);
204
205 pg_log_info("reading column info for interesting tables");
206 getTableAttrs(fout, tblinfo, numTables);
207
208 pg_log_info("flagging inherited columns in subtables");
209 flagInhAttrs(fout, fout->dopt, tblinfo, numTables);
210
211 pg_log_info("reading partitioning data");
213
214 pg_log_info("reading indexes");
215 getIndexes(fout, tblinfo, numTables);
216
217 pg_log_info("flagging indexes in partitioned tables");
218 flagInhIndexes(fout, tblinfo, numTables);
219
220 pg_log_info("reading extended statistics");
222
223 pg_log_info("reading constraints");
224 getConstraints(fout, tblinfo, numTables);
225
226 pg_log_info("reading triggers");
227 getTriggers(fout, tblinfo, numTables);
228
229 pg_log_info("reading rewrite rules");
230 getRules(fout);
231
232 pg_log_info("reading policies");
233 getPolicies(fout, tblinfo, numTables);
234
235 pg_log_info("reading publications");
236 getPublications(fout);
237
238 pg_log_info("reading publication membership of tables");
239 getPublicationTables(fout, tblinfo, numTables);
240
241 pg_log_info("reading publication membership of schemas");
243
244 pg_log_info("reading subscriptions");
245 getSubscriptions(fout);
246
247 pg_log_info("reading subscription membership of relations");
249
250 free(inhinfo); /* not needed any longer */
251
252 *numTablesPtr = numTables;
253 return tblinfo;
254}
static void flagInhAttrs(Archive *fout, DumpOptions *dopt, TableInfo *tblinfo, int numTables)
Definition: common.c:478
static void flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables, InhInfo *inhinfo, int numInherits)
Definition: common.c:269
static void flagInhIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8277
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:6109
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4742
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7769
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7713
void getForeignDataWrappers(Archive *fout)
Definition: pg_dump.c:10397
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4233
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19672
void getTypes(Archive *fout)
Definition: pg_dump.c:6184
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7648
void getOpclasses(Archive *fout)
Definition: pg_dump.c:6630
void getForeignServers(Archive *fout)
Definition: pg_dump.c:10481
void getFuncs(Archive *fout)
Definition: pg_dump.c:6899
void getTSDictionaries(Archive *fout)
Definition: pg_dump.c:10213
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4822
void getCasts(Archive *fout)
Definition: pg_dump.c:9026
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7829
void getTSConfigurations(Archive *fout)
Definition: pg_dump.c:10338
void getAccessMethods(Archive *fout)
Definition: pg_dump.c:6556
void getConversions(Archive *fout)
Definition: pg_dump.c:6494
void getRules(Archive *fout)
Definition: pg_dump.c:8571
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:9220
void getCollations(Archive *fout)
Definition: pg_dump.c:6428
void getAggregates(Archive *fout)
Definition: pg_dump.c:6758
void getNamespaces(Archive *fout)
Definition: pg_dump.c:5977
void getPublications(Archive *fout)
Definition: pg_dump.c:4523
void getTSParsers(Archive *fout)
Definition: pg_dump.c:10139
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:7171
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:8198
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19765
void getDefaultACLs(Archive *fout)
Definition: pg_dump.c:10569
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:5093
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8668
void getTransforms(Archive *fout)
Definition: pg_dump.c:9136
void getEventTriggers(Archive *fout)
Definition: pg_dump.c:8864
void getTSTemplates(Archive *fout)
Definition: pg_dump.c:10279
void getProcLangs(Archive *fout)
Definition: pg_dump.c:8942
void getSubscriptionRelations(Archive *fout)
Definition: pg_dump.c:5313
void getOperators(Archive *fout)
Definition: pg_dump.c:6352
void getOpfamilies(Archive *fout)
Definition: pg_dump.c:6693

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(), getSubscriptionRelations(), getSubscriptions(), getTableAttrs(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), pg_log_info, and processExtensionTables().

Referenced by main().

◆ getSubscriptionRelations()

void getSubscriptionRelations ( Archive fout)

Definition at line 5313 of file pg_dump.c.

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

References AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, cleanup(), DO_SUBSCRIPTION_REL, _SubscriptionInfo::dobj, _SubRelInfo::dobj, Archive::dopt, ExecuteSqlQuery(), findSubscriptionByOid(), findTableByOid(), i, InvalidOid, _dumpableObject::name, _dumpOptions::no_subscriptions, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, Archive::remoteVersion, selectDumpableObject(), _SubRelInfo::srsublsn, _SubRelInfo::srsubstate, _SubRelInfo::subinfo, CatalogId::tableoid, and _SubRelInfo::tblinfo.

Referenced by getSchemaData().

◆ getSubscriptions()

void getSubscriptions ( Archive fout)

Definition at line 5093 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_SUBSCRIPTION, _SubscriptionInfo::dobj, Archive::dopt, ExecuteSqlQuery(), getRoleName(), i, is_superuser(), _dumpableObject::name, _dumpOptions::no_subscriptions, _dumpableObject::objType, CatalogId::oid, pg_log_warning, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, Archive::remoteVersion, _SubscriptionInfo::rolname, selectDumpableObject(), _SubscriptionInfo::subbinary, _SubscriptionInfo::subconninfo, _SubscriptionInfo::subdisableonerr, _SubscriptionInfo::subenabled, _SubscriptionInfo::subfailover, _SubscriptionInfo::submaxretention, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subretaindeadtuples, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, _SubscriptionInfo::subtwophasestate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTableAttrs()

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

Definition at line 9220 of file pg_dump.c.

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

References addObjectDependency(), _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attcompression, _tableInfo::attfdwoptions, _tableInfo::attgenerated, _tableInfo::attidentity, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attmissingval, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypnames, _dumpOptions::binary_upgrade, _dumpableObject::catId, _tableInfo::checkexprs, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), determineNotNullFlags(), DO_ATTRDEF, DO_CONSTRAINT, _tableInfo::dobj, _attrDefInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, _dumpableObject::dumpId, _dumpOptions::dumpSchema, ExecuteSqlQuery(), exit_nicely(), i, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull_comment, _tableInfo::notnull_constrs, _tableInfo::notnull_invalid, _tableInfo::notnull_islocal, _tableInfo::notnull_noinh, _tableInfo::numatts, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, resetPQExpBuffer(), _attrDefInfo::separate, _constraintInfo::separate, shouldPrintColumn(), CatalogId::tableoid, and _tableInfo::typstorage.

Referenced by getSchemaData().

◆ getTables()

TableInfo * getTables ( Archive fout,
int *  numTables 
)

Definition at line 7171 of file pg_dump.c.

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, _tableInfo::amname, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), AssignDumpId(), atooid, _dumpableObject::catId, _tableInfo::checkoption, _dumpableObject::components, CppAsString2, createPQExpBuffer(), _tableInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_TABLE, _tableInfo::dobj, Archive::dopt, _tableInfo::dummy_view, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DATA, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, DUMP_COMPONENT_STATISTICS, DUMP_COMPONENTS_REQUIRING_LOCK, ExecuteSqlQuery(), ExecuteSqlStatement(), findNamespace(), fmtQualifiedDumpable, _tableInfo::forcerowsec, _tableInfo::foreign_server, _tableInfo::frozenxid, GetConnection(), getRelationStatistics(), getRoleName(), _tableInfo::hascolumnACLs, _tableInfo::hasindex, _tableInfo::hasoids, _tableInfo::hasrules, _tableInfo::hastriggers, i, if(), _dumpableAcl::initprivs, _tableInfo::interesting, InvalidOid, _tableInfo::is_identity_sequence, _tableInfo::ispartition, PQExpBufferData::len, _dumpOptions::lockWaitTimeout, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, _dumpableObject::objType, CatalogId::oid, _tableInfo::owning_col, _tableInfo::owning_tab, pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, _tableInfo::postponed_def, PQclear, PQfnumber(), PQgetisnull, PQgetvalue, PQntuples, _dumpableAcl::privtype, _tableInfo::relispopulated, _tableInfo::relkind, _tableInfo::reloftype, _tableInfo::reloptions, _tableInfo::relpages, _tableInfo::relpersistence, _tableInfo::relreplident, _tableInfo::reltablespace, _tableInfo::reltype, Archive::remoteVersion, resetPQExpBuffer(), _tableInfo::rolname, _tableInfo::rowsec, selectDumpableTable(), _tableInfo::stats, CatalogId::tableoid, _tableInfo::toast_frozenxid, _tableInfo::toast_minmxid, _tableInfo::toast_oid, _tableInfo::toast_reloptions, and _tableInfo::toastpages.

Referenced by getSchemaData().

◆ getTransforms()

void getTransforms ( Archive fout)

Definition at line 9136 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TRANSFORM, _typeInfo::dobj, _transformInfo::dobj, ExecuteSqlQuery(), findTypeByOid(), free, get_language_name(), i, initPQExpBuffer(), _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, Archive::remoteVersion, selectDumpableObject(), CatalogId::tableoid, _transformInfo::trffromsql, _transformInfo::trflang, _transformInfo::trftosql, and _transformInfo::trftype.

Referenced by getSchemaData().

◆ getTriggers()

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

Definition at line 8668 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferChar(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TRIGGER, _tableInfo::dobj, _triggerInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, ExecuteSqlQuery(), _tableInfo::hastriggers, i, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::numTriggers, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, Archive::remoteVersion, CatalogId::tableoid, _triggerInfo::tgdef, _triggerInfo::tgenabled, _triggerInfo::tgispartition, _triggerInfo::tgtable, and _tableInfo::triggers.

Referenced by getSchemaData().

◆ getTSConfigurations()

void getTSConfigurations ( Archive fout)

Definition at line 10338 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getTSDictionaries()

void getTSDictionaries ( Archive fout)

Definition at line 10213 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getTSParsers()

void getTSParsers ( Archive fout)

Definition at line 10139 of file pg_dump.c.

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

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_TSPARSER, _prsInfo::dobj, ExecuteSqlQuery(), findNamespace(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear, PQfnumber(), PQgetvalue, PQntuples, _prsInfo::prsend, _prsInfo::prsheadline, _prsInfo::prslextype, _prsInfo::prsstart, _prsInfo::prstoken, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSTemplates()

void getTSTemplates ( Archive fout)

Definition at line 10279 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getTypes()

void getTypes ( Archive fout)

Definition at line 6184 of file pg_dump.c.

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

Referenced by getSchemaData().

◆ parseOidArray()

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

Definition at line 1111 of file common.c.

1112{
1113 int j,
1114 argNum;
1115 char temp[100];
1116 char s;
1117
1118 argNum = 0;
1119 j = 0;
1120 for (;;)
1121 {
1122 s = *str++;
1123 if (s == ' ' || s == '\0')
1124 {
1125 if (j > 0)
1126 {
1127 if (argNum >= arraysize)
1128 pg_fatal("could not parse numeric array \"%s\": too many numbers", str);
1129 temp[j] = '\0';
1130 array[argNum++] = atooid(temp);
1131 j = 0;
1132 }
1133 if (s == '\0')
1134 break;
1135 }
1136 else
1137 {
1138 if (!(isdigit((unsigned char) s) || s == '-') ||
1139 j >= sizeof(temp) - 1)
1140 pg_fatal("could not parse numeric array \"%s\": invalid character in number", str);
1141 temp[j++] = s;
1142 }
1143 }
1144
1145 while (argNum < arraysize)
1146 array[argNum++] = InvalidOid;
1147}
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 19765 of file pg_dump.c.

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

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 719 of file common.c.

720{
721 CatalogIdMapEntry *entry;
722 bool found;
723
724 /* CatalogId hash table must exist, if we have a DumpableObject */
725 Assert(catalogIdHash != NULL);
726
727 /* Add reference to CatalogId hash */
728 entry = catalogid_insert(catalogIdHash, catId, &found);
729 if (!found)
730 {
731 entry->dobj = NULL;
732 entry->ext = NULL;
733 }
734 Assert(entry->dobj == NULL);
735 entry->dobj = dobj;
736}

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

Referenced by getLOs().

◆ recordExtensionMembership()

void recordExtensionMembership ( CatalogId  catId,
ExtensionInfo ext 
)

Definition at line 1063 of file common.c.

1064{
1065 CatalogIdMapEntry *entry;
1066 bool found;
1067
1068 /* CatalogId hash table must exist, if we have an ExtensionInfo */
1069 Assert(catalogIdHash != NULL);
1070
1071 /* Add reference to CatalogId hash */
1072 entry = catalogid_insert(catalogIdHash, catId, &found);
1073 if (!found)
1074 {
1075 entry->dobj = NULL;
1076 entry->ext = NULL;
1077 }
1078 Assert(entry->ext == NULL);
1079 entry->ext = ext;
1080}

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

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

References _tableInfo::attisdropped, _tableInfo::attislocal, _dumpOptions::binary_upgrade, and _tableInfo::ispartition.

Referenced by dumpTableSchema(), flagInhAttrs(), and getTableAttrs().

◆ sortDumpableObjects()

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

Definition at line 548 of file pg_dump_sort.c.

550{
551 DumpableObject **ordering;
552 int nOrdering;
553
554 if (numObjs <= 0) /* can't happen anymore ... */
555 return;
556
557 /*
558 * Saving the boundary IDs in static variables is a bit grotty, but seems
559 * better than adding them to parameter lists of subsidiary functions.
560 */
561 preDataBoundId = preBoundaryId;
562 postDataBoundId = postBoundaryId;
563
564 ordering = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
565 while (!TopoSort(objs, numObjs, ordering, &nOrdering))
566 findDependencyLoops(ordering, nOrdering, numObjs);
567
568 memcpy(objs, ordering, numObjs * sizeof(DumpableObject *));
569
570 free(ordering);
571}
static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
Definition: pg_dump_sort.c:749
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:600
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 192 of file pg_dump_sort.c.

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

References DOTypeNameCompare(), and qsort.

Referenced by main().