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

6571{
6572 PGresult *res;
6573 int ntups;
6574 int i;
6575 PQExpBuffer query;
6576 AccessMethodInfo *aminfo;
6577 int i_tableoid;
6578 int i_oid;
6579 int i_amname;
6580 int i_amhandler;
6581 int i_amtype;
6582
6583 query = createPQExpBuffer();
6584
6585 /*
6586 * Select all access methods from pg_am table. v9.6 introduced CREATE
6587 * ACCESS METHOD, so earlier versions usually have only built-in access
6588 * methods. v9.6 also changed the access method API, replacing dozens of
6589 * pg_am columns with amhandler. Even if a user created an access method
6590 * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am
6591 * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read
6592 * pg_am just to facilitate findAccessMethodByOid() providing the
6593 * OID-to-name mapping.
6594 */
6595 appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, ");
6596 if (fout->remoteVersion >= 90600)
6598 "amtype, "
6599 "amhandler::pg_catalog.regproc AS amhandler ");
6600 else
6602 "'i'::pg_catalog.\"char\" AS amtype, "
6603 "'-'::pg_catalog.regproc AS amhandler ");
6604 appendPQExpBufferStr(query, "FROM pg_am");
6605
6606 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6607
6608 ntups = PQntuples(res);
6609
6610 aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6611
6612 i_tableoid = PQfnumber(res, "tableoid");
6613 i_oid = PQfnumber(res, "oid");
6614 i_amname = PQfnumber(res, "amname");
6615 i_amhandler = PQfnumber(res, "amhandler");
6616 i_amtype = PQfnumber(res, "amtype");
6617
6618 for (i = 0; i < ntups; i++)
6619 {
6620 aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6621 aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6622 aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6623 AssignDumpId(&aminfo[i].dobj);
6624 aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6625 aminfo[i].dobj.namespace = NULL;
6626 aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6627 aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6628
6629 /* Decide whether we want to dump it */
6630 selectDumpableAccessMethod(&(aminfo[i]), fout);
6631 }
6632
6633 PQclear(res);
6634
6635 destroyPQExpBuffer(query);
6636}
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:2248
#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 6772 of file pg_dump.c.

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

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

6443{
6444 PGresult *res;
6445 int ntups;
6446 int i;
6447 PQExpBuffer query;
6448 CollInfo *collinfo;
6449 int i_tableoid;
6450 int i_oid;
6451 int i_collname;
6452 int i_collnamespace;
6453 int i_collowner;
6454 int i_collencoding;
6455
6456 query = createPQExpBuffer();
6457
6458 /*
6459 * find all collations, including builtin collations; we filter out
6460 * system-defined collations at dump-out time.
6461 */
6462
6463 appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6464 "collnamespace, "
6465 "collowner, "
6466 "collencoding "
6467 "FROM pg_collation");
6468
6469 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6470
6471 ntups = PQntuples(res);
6472
6473 collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6474
6475 i_tableoid = PQfnumber(res, "tableoid");
6476 i_oid = PQfnumber(res, "oid");
6477 i_collname = PQfnumber(res, "collname");
6478 i_collnamespace = PQfnumber(res, "collnamespace");
6479 i_collowner = PQfnumber(res, "collowner");
6480 i_collencoding = PQfnumber(res, "collencoding");
6481
6482 for (i = 0; i < ntups; i++)
6483 {
6484 collinfo[i].dobj.objType = DO_COLLATION;
6485 collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6486 collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6487 AssignDumpId(&collinfo[i].dobj);
6488 collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6489 collinfo[i].dobj.namespace =
6490 findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6491 collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6492 collinfo[i].collencoding = atoi(PQgetvalue(res, i, i_collencoding));
6493
6494 /* Decide whether we want to dump it */
6495 selectDumpableObject(&(collinfo[i].dobj), fout);
6496 }
6497
6498 PQclear(res);
6499
6500 destroyPQExpBuffer(query);
6501}
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 8291 of file pg_dump.c.

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

6509{
6510 PGresult *res;
6511 int ntups;
6512 int i;
6513 PQExpBuffer query;
6514 ConvInfo *convinfo;
6515 int i_tableoid;
6516 int i_oid;
6517 int i_conname;
6518 int i_connamespace;
6519 int i_conowner;
6520
6521 query = createPQExpBuffer();
6522
6523 /*
6524 * find all conversions, including builtin conversions; we filter out
6525 * system-defined conversions at dump-out time.
6526 */
6527
6528 appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6529 "connamespace, "
6530 "conowner "
6531 "FROM pg_conversion");
6532
6533 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6534
6535 ntups = PQntuples(res);
6536
6537 convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6538
6539 i_tableoid = PQfnumber(res, "tableoid");
6540 i_oid = PQfnumber(res, "oid");
6541 i_conname = PQfnumber(res, "conname");
6542 i_connamespace = PQfnumber(res, "connamespace");
6543 i_conowner = PQfnumber(res, "conowner");
6544
6545 for (i = 0; i < ntups; i++)
6546 {
6547 convinfo[i].dobj.objType = DO_CONVERSION;
6548 convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6549 convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6550 AssignDumpId(&convinfo[i].dobj);
6551 convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6552 convinfo[i].dobj.namespace =
6553 findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6554 convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6555
6556 /* Decide whether we want to dump it */
6557 selectDumpableObject(&(convinfo[i].dobj), fout);
6558 }
6559
6560 PQclear(res);
6561
6562 destroyPQExpBuffer(query);
6563}
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 10583 of file pg_dump.c.

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

8879{
8880 int i;
8881 PQExpBuffer query;
8882 PGresult *res;
8883 EventTriggerInfo *evtinfo;
8884 int i_tableoid,
8885 i_oid,
8886 i_evtname,
8887 i_evtevent,
8888 i_evtowner,
8889 i_evttags,
8890 i_evtfname,
8891 i_evtenabled;
8892 int ntups;
8893
8894 /* Before 9.3, there are no event triggers */
8895 if (fout->remoteVersion < 90300)
8896 return;
8897
8898 query = createPQExpBuffer();
8899
8901 "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8902 "evtevent, evtowner, "
8903 "array_to_string(array("
8904 "select quote_literal(x) "
8905 " from unnest(evttags) as t(x)), ', ') as evttags, "
8906 "e.evtfoid::regproc as evtfname "
8907 "FROM pg_event_trigger e "
8908 "ORDER BY e.oid");
8909
8910 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8911
8912 ntups = PQntuples(res);
8913
8914 evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8915
8916 i_tableoid = PQfnumber(res, "tableoid");
8917 i_oid = PQfnumber(res, "oid");
8918 i_evtname = PQfnumber(res, "evtname");
8919 i_evtevent = PQfnumber(res, "evtevent");
8920 i_evtowner = PQfnumber(res, "evtowner");
8921 i_evttags = PQfnumber(res, "evttags");
8922 i_evtfname = PQfnumber(res, "evtfname");
8923 i_evtenabled = PQfnumber(res, "evtenabled");
8924
8925 for (i = 0; i < ntups; i++)
8926 {
8927 evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8928 evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8929 evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8930 AssignDumpId(&evtinfo[i].dobj);
8931 evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8932 evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8933 evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8934 evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8935 evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8936 evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8937 evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8938
8939 /* Decide whether we want to dump it */
8940 selectDumpableObject(&(evtinfo[i].dobj), fout);
8941 }
8942
8943 PQclear(res);
8944
8945 destroyPQExpBuffer(query);
8946}
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 8212 of file pg_dump.c.

8213{
8214 PQExpBuffer query;
8215 PGresult *res;
8216 StatsExtInfo *statsextinfo;
8217 int ntups;
8218 int i_tableoid;
8219 int i_oid;
8220 int i_stxname;
8221 int i_stxnamespace;
8222 int i_stxowner;
8223 int i_stxrelid;
8224 int i_stattarget;
8225 int i;
8226
8227 /* Extended statistics were new in v10 */
8228 if (fout->remoteVersion < 100000)
8229 return;
8230
8231 query = createPQExpBuffer();
8232
8233 if (fout->remoteVersion < 130000)
8234 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8235 "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
8236 "FROM pg_catalog.pg_statistic_ext");
8237 else
8238 appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
8239 "stxnamespace, stxowner, stxrelid, stxstattarget "
8240 "FROM pg_catalog.pg_statistic_ext");
8241
8242 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8243
8244 ntups = PQntuples(res);
8245
8246 i_tableoid = PQfnumber(res, "tableoid");
8247 i_oid = PQfnumber(res, "oid");
8248 i_stxname = PQfnumber(res, "stxname");
8249 i_stxnamespace = PQfnumber(res, "stxnamespace");
8250 i_stxowner = PQfnumber(res, "stxowner");
8251 i_stxrelid = PQfnumber(res, "stxrelid");
8252 i_stattarget = PQfnumber(res, "stxstattarget");
8253
8254 statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
8255
8256 for (i = 0; i < ntups; i++)
8257 {
8258 statsextinfo[i].dobj.objType = DO_STATSEXT;
8259 statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8260 statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8261 AssignDumpId(&statsextinfo[i].dobj);
8262 statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
8263 statsextinfo[i].dobj.namespace =
8264 findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
8265 statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
8266 statsextinfo[i].stattable =
8267 findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
8268 if (PQgetisnull(res, i, i_stattarget))
8269 statsextinfo[i].stattarget = -1;
8270 else
8271 statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
8272
8273 /* Decide whether we want to dump it */
8274 selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
8275 }
8276
8277 PQclear(res);
8278 destroyPQExpBuffer(query);
8279}
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2340
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 19686 of file pg_dump.c.

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

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

10412{
10413 PGresult *res;
10414 int ntups;
10415 int i;
10416 PQExpBuffer query;
10417 FdwInfo *fdwinfo;
10418 int i_tableoid;
10419 int i_oid;
10420 int i_fdwname;
10421 int i_fdwowner;
10422 int i_fdwhandler;
10423 int i_fdwvalidator;
10424 int i_fdwacl;
10425 int i_acldefault;
10426 int i_fdwoptions;
10427
10428 query = createPQExpBuffer();
10429
10430 appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
10431 "fdwowner, "
10432 "fdwhandler::pg_catalog.regproc, "
10433 "fdwvalidator::pg_catalog.regproc, "
10434 "fdwacl, "
10435 "acldefault('F', fdwowner) AS acldefault, "
10436 "array_to_string(ARRAY("
10437 "SELECT quote_ident(option_name) || ' ' || "
10438 "quote_literal(option_value) "
10439 "FROM pg_options_to_table(fdwoptions) "
10440 "ORDER BY option_name"
10441 "), E',\n ') AS fdwoptions "
10442 "FROM pg_foreign_data_wrapper");
10443
10444 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10445
10446 ntups = PQntuples(res);
10447
10448 fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
10449
10450 i_tableoid = PQfnumber(res, "tableoid");
10451 i_oid = PQfnumber(res, "oid");
10452 i_fdwname = PQfnumber(res, "fdwname");
10453 i_fdwowner = PQfnumber(res, "fdwowner");
10454 i_fdwhandler = PQfnumber(res, "fdwhandler");
10455 i_fdwvalidator = PQfnumber(res, "fdwvalidator");
10456 i_fdwacl = PQfnumber(res, "fdwacl");
10457 i_acldefault = PQfnumber(res, "acldefault");
10458 i_fdwoptions = PQfnumber(res, "fdwoptions");
10459
10460 for (i = 0; i < ntups; i++)
10461 {
10462 fdwinfo[i].dobj.objType = DO_FDW;
10463 fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10464 fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10465 AssignDumpId(&fdwinfo[i].dobj);
10466 fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
10467 fdwinfo[i].dobj.namespace = NULL;
10468 fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
10469 fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10470 fdwinfo[i].dacl.privtype = 0;
10471 fdwinfo[i].dacl.initprivs = NULL;
10472 fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
10473 fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
10474 fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
10475 fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
10476
10477 /* Decide whether we want to dump it */
10478 selectDumpableObject(&(fdwinfo[i].dobj), fout);
10479
10480 /* Mark whether FDW has an ACL */
10481 if (!PQgetisnull(res, i, i_fdwacl))
10482 fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10483 }
10484
10485 PQclear(res);
10486
10487 destroyPQExpBuffer(query);
10488}
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 10495 of file pg_dump.c.

10496{
10497 PGresult *res;
10498 int ntups;
10499 int i;
10500 PQExpBuffer query;
10501 ForeignServerInfo *srvinfo;
10502 int i_tableoid;
10503 int i_oid;
10504 int i_srvname;
10505 int i_srvowner;
10506 int i_srvfdw;
10507 int i_srvtype;
10508 int i_srvversion;
10509 int i_srvacl;
10510 int i_acldefault;
10511 int i_srvoptions;
10512
10513 query = createPQExpBuffer();
10514
10515 appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
10516 "srvowner, "
10517 "srvfdw, srvtype, srvversion, srvacl, "
10518 "acldefault('S', srvowner) AS acldefault, "
10519 "array_to_string(ARRAY("
10520 "SELECT quote_ident(option_name) || ' ' || "
10521 "quote_literal(option_value) "
10522 "FROM pg_options_to_table(srvoptions) "
10523 "ORDER BY option_name"
10524 "), E',\n ') AS srvoptions "
10525 "FROM pg_foreign_server");
10526
10527 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10528
10529 ntups = PQntuples(res);
10530
10531 srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
10532
10533 i_tableoid = PQfnumber(res, "tableoid");
10534 i_oid = PQfnumber(res, "oid");
10535 i_srvname = PQfnumber(res, "srvname");
10536 i_srvowner = PQfnumber(res, "srvowner");
10537 i_srvfdw = PQfnumber(res, "srvfdw");
10538 i_srvtype = PQfnumber(res, "srvtype");
10539 i_srvversion = PQfnumber(res, "srvversion");
10540 i_srvacl = PQfnumber(res, "srvacl");
10541 i_acldefault = PQfnumber(res, "acldefault");
10542 i_srvoptions = PQfnumber(res, "srvoptions");
10543
10544 for (i = 0; i < ntups; i++)
10545 {
10546 srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
10547 srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10548 srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10549 AssignDumpId(&srvinfo[i].dobj);
10550 srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
10551 srvinfo[i].dobj.namespace = NULL;
10552 srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
10553 srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
10554 srvinfo[i].dacl.privtype = 0;
10555 srvinfo[i].dacl.initprivs = NULL;
10556 srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
10557 srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
10558 srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
10559 srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
10560 srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
10561
10562 /* Decide whether we want to dump it */
10563 selectDumpableObject(&(srvinfo[i].dobj), fout);
10564
10565 /* Servers have user mappings */
10567
10568 /* Mark whether server has an ACL */
10569 if (!PQgetisnull(res, i, i_srvacl))
10570 srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10571 }
10572
10573 PQclear(res);
10574
10575 destroyPQExpBuffer(query);
10576}
#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 6913 of file pg_dump.c.

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

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

7728{
7729 PGresult *res;
7730 int ntups;
7731 int i;
7733 InhInfo *inhinfo;
7734
7735 int i_inhrelid;
7736 int i_inhparent;
7737
7738 /* find all the inheritance information */
7739 appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7740
7741 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7742
7743 ntups = PQntuples(res);
7744
7745 *numInherits = ntups;
7746
7747 inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7748
7749 i_inhrelid = PQfnumber(res, "inhrelid");
7750 i_inhparent = PQfnumber(res, "inhparent");
7751
7752 for (i = 0; i < ntups; i++)
7753 {
7754 inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7755 inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7756 }
7757
7758 PQclear(res);
7759
7760 destroyPQExpBuffer(query);
7761
7762 return inhinfo;
7763}
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 5991 of file pg_dump.c.

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

6645{
6646 PGresult *res;
6647 int ntups;
6648 int i;
6650 OpclassInfo *opcinfo;
6651 int i_tableoid;
6652 int i_oid;
6653 int i_opcmethod;
6654 int i_opcname;
6655 int i_opcnamespace;
6656 int i_opcowner;
6657
6658 /*
6659 * find all opclasses, including builtin opclasses; we filter out
6660 * system-defined opclasses at dump-out time.
6661 */
6662
6663 appendPQExpBufferStr(query, "SELECT tableoid, oid, opcmethod, opcname, "
6664 "opcnamespace, "
6665 "opcowner "
6666 "FROM pg_opclass");
6667
6668 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6669
6670 ntups = PQntuples(res);
6671
6672 opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6673
6674 i_tableoid = PQfnumber(res, "tableoid");
6675 i_oid = PQfnumber(res, "oid");
6676 i_opcmethod = PQfnumber(res, "opcmethod");
6677 i_opcname = PQfnumber(res, "opcname");
6678 i_opcnamespace = PQfnumber(res, "opcnamespace");
6679 i_opcowner = PQfnumber(res, "opcowner");
6680
6681 for (i = 0; i < ntups; i++)
6682 {
6683 opcinfo[i].dobj.objType = DO_OPCLASS;
6684 opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6685 opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6686 AssignDumpId(&opcinfo[i].dobj);
6687 opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6688 opcinfo[i].dobj.namespace =
6689 findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6690 opcinfo[i].opcmethod = atooid(PQgetvalue(res, i, i_opcmethod));
6691 opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6692
6693 /* Decide whether we want to dump it */
6694 selectDumpableObject(&(opcinfo[i].dobj), fout);
6695 }
6696
6697 PQclear(res);
6698
6699 destroyPQExpBuffer(query);
6700}
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 6366 of file pg_dump.c.

6367{
6368 PGresult *res;
6369 int ntups;
6370 int i;
6372 OprInfo *oprinfo;
6373 int i_tableoid;
6374 int i_oid;
6375 int i_oprname;
6376 int i_oprnamespace;
6377 int i_oprowner;
6378 int i_oprkind;
6379 int i_oprleft;
6380 int i_oprright;
6381 int i_oprcode;
6382
6383 /*
6384 * find all operators, including builtin operators; we filter out
6385 * system-defined operators at dump-out time.
6386 */
6387
6388 appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
6389 "oprnamespace, "
6390 "oprowner, "
6391 "oprkind, "
6392 "oprleft, "
6393 "oprright, "
6394 "oprcode::oid AS oprcode "
6395 "FROM pg_operator");
6396
6397 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6398
6399 ntups = PQntuples(res);
6400
6401 oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6402
6403 i_tableoid = PQfnumber(res, "tableoid");
6404 i_oid = PQfnumber(res, "oid");
6405 i_oprname = PQfnumber(res, "oprname");
6406 i_oprnamespace = PQfnumber(res, "oprnamespace");
6407 i_oprowner = PQfnumber(res, "oprowner");
6408 i_oprkind = PQfnumber(res, "oprkind");
6409 i_oprleft = PQfnumber(res, "oprleft");
6410 i_oprright = PQfnumber(res, "oprright");
6411 i_oprcode = PQfnumber(res, "oprcode");
6412
6413 for (i = 0; i < ntups; i++)
6414 {
6415 oprinfo[i].dobj.objType = DO_OPERATOR;
6416 oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6417 oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6418 AssignDumpId(&oprinfo[i].dobj);
6419 oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6420 oprinfo[i].dobj.namespace =
6421 findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6422 oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6423 oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6424 oprinfo[i].oprleft = atooid(PQgetvalue(res, i, i_oprleft));
6425 oprinfo[i].oprright = atooid(PQgetvalue(res, i, i_oprright));
6426 oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6427
6428 /* Decide whether we want to dump it */
6429 selectDumpableObject(&(oprinfo[i].dobj), fout);
6430 }
6431
6432 PQclear(res);
6433
6434 destroyPQExpBuffer(query);
6435}
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 6707 of file pg_dump.c.

6708{
6709 PGresult *res;
6710 int ntups;
6711 int i;
6712 PQExpBuffer query;
6713 OpfamilyInfo *opfinfo;
6714 int i_tableoid;
6715 int i_oid;
6716 int i_opfmethod;
6717 int i_opfname;
6718 int i_opfnamespace;
6719 int i_opfowner;
6720
6721 query = createPQExpBuffer();
6722
6723 /*
6724 * find all opfamilies, including builtin opfamilies; we filter out
6725 * system-defined opfamilies at dump-out time.
6726 */
6727
6728 appendPQExpBufferStr(query, "SELECT tableoid, oid, opfmethod, opfname, "
6729 "opfnamespace, "
6730 "opfowner "
6731 "FROM pg_opfamily");
6732
6733 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6734
6735 ntups = PQntuples(res);
6736
6737 opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6738
6739 i_tableoid = PQfnumber(res, "tableoid");
6740 i_oid = PQfnumber(res, "oid");
6741 i_opfname = PQfnumber(res, "opfname");
6742 i_opfmethod = PQfnumber(res, "opfmethod");
6743 i_opfnamespace = PQfnumber(res, "opfnamespace");
6744 i_opfowner = PQfnumber(res, "opfowner");
6745
6746 for (i = 0; i < ntups; i++)
6747 {
6748 opfinfo[i].dobj.objType = DO_OPFAMILY;
6749 opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6750 opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6751 AssignDumpId(&opfinfo[i].dobj);
6752 opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6753 opfinfo[i].dobj.namespace =
6754 findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6755 opfinfo[i].opfmethod = atooid(PQgetvalue(res, i, i_opfmethod));
6756 opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6757
6758 /* Decide whether we want to dump it */
6759 selectDumpableObject(&(opfinfo[i].dobj), fout);
6760 }
6761
6762 PQclear(res);
6763
6764 destroyPQExpBuffer(query);
6765}
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 7662 of file pg_dump.c.

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

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

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

8957{
8958 PGresult *res;
8959 int ntups;
8960 int i;
8962 ProcLangInfo *planginfo;
8963 int i_tableoid;
8964 int i_oid;
8965 int i_lanname;
8966 int i_lanpltrusted;
8967 int i_lanplcallfoid;
8968 int i_laninline;
8969 int i_lanvalidator;
8970 int i_lanacl;
8971 int i_acldefault;
8972 int i_lanowner;
8973
8974 appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8975 "lanname, lanpltrusted, lanplcallfoid, "
8976 "laninline, lanvalidator, "
8977 "lanacl, "
8978 "acldefault('l', lanowner) AS acldefault, "
8979 "lanowner "
8980 "FROM pg_language "
8981 "WHERE lanispl "
8982 "ORDER BY oid");
8983
8984 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8985
8986 ntups = PQntuples(res);
8987
8988 planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8989
8990 i_tableoid = PQfnumber(res, "tableoid");
8991 i_oid = PQfnumber(res, "oid");
8992 i_lanname = PQfnumber(res, "lanname");
8993 i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8994 i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8995 i_laninline = PQfnumber(res, "laninline");
8996 i_lanvalidator = PQfnumber(res, "lanvalidator");
8997 i_lanacl = PQfnumber(res, "lanacl");
8998 i_acldefault = PQfnumber(res, "acldefault");
8999 i_lanowner = PQfnumber(res, "lanowner");
9000
9001 for (i = 0; i < ntups; i++)
9002 {
9003 planginfo[i].dobj.objType = DO_PROCLANG;
9004 planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9005 planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9006 AssignDumpId(&planginfo[i].dobj);
9007
9008 planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
9009 planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
9010 planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9011 planginfo[i].dacl.privtype = 0;
9012 planginfo[i].dacl.initprivs = NULL;
9013 planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
9014 planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
9015 planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
9016 planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
9017 planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
9018
9019 /* Decide whether we want to dump it */
9020 selectDumpableProcLang(&(planginfo[i]), fout);
9021
9022 /* Mark whether language has an ACL */
9023 if (!PQgetisnull(res, i, i_lanacl))
9024 planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9025 }
9026
9027 PQclear(res);
9028
9029 destroyPQExpBuffer(query);
9030}
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:2215
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 4756 of file pg_dump.c.

4757{
4758 PQExpBuffer query;
4759 PGresult *res;
4760 PublicationSchemaInfo *pubsinfo;
4761 DumpOptions *dopt = fout->dopt;
4762 int i_tableoid;
4763 int i_oid;
4764 int i_pnpubid;
4765 int i_pnnspid;
4766 int i,
4767 j,
4768 ntups;
4769
4770 if (dopt->no_publications || fout->remoteVersion < 150000)
4771 return;
4772
4773 query = createPQExpBuffer();
4774
4775 /* Collect all publication membership info. */
4777 "SELECT tableoid, oid, pnpubid, pnnspid "
4778 "FROM pg_catalog.pg_publication_namespace");
4779 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4780
4781 ntups = PQntuples(res);
4782
4783 i_tableoid = PQfnumber(res, "tableoid");
4784 i_oid = PQfnumber(res, "oid");
4785 i_pnpubid = PQfnumber(res, "pnpubid");
4786 i_pnnspid = PQfnumber(res, "pnnspid");
4787
4788 /* this allocation may be more than we need */
4789 pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4790 j = 0;
4791
4792 for (i = 0; i < ntups; i++)
4793 {
4794 Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4795 Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4796 PublicationInfo *pubinfo;
4797 NamespaceInfo *nspinfo;
4798
4799 /*
4800 * Ignore any entries for which we aren't interested in either the
4801 * publication or the rel.
4802 */
4803 pubinfo = findPublicationByOid(pnpubid);
4804 if (pubinfo == NULL)
4805 continue;
4806 nspinfo = findNamespaceByOid(pnnspid);
4807 if (nspinfo == NULL)
4808 continue;
4809
4810 /* OK, make a DumpableObject for this relationship */
4812 pubsinfo[j].dobj.catId.tableoid =
4813 atooid(PQgetvalue(res, i, i_tableoid));
4814 pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4815 AssignDumpId(&pubsinfo[j].dobj);
4816 pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4817 pubsinfo[j].dobj.name = nspinfo->dobj.name;
4818 pubsinfo[j].publication = pubinfo;
4819 pubsinfo[j].pubschema = nspinfo;
4820
4821 /* Decide whether we want to dump it */
4822 selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4823
4824 j++;
4825 }
4826
4827 PQclear(res);
4828 destroyPQExpBuffer(query);
4829}
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:2322
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 4537 of file pg_dump.c.

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

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

8586{
8587 PGresult *res;
8588 int ntups;
8589 int i;
8591 RuleInfo *ruleinfo;
8592 int i_tableoid;
8593 int i_oid;
8594 int i_rulename;
8595 int i_ruletable;
8596 int i_ev_type;
8597 int i_is_instead;
8598 int i_ev_enabled;
8599
8600 appendPQExpBufferStr(query, "SELECT "
8601 "tableoid, oid, rulename, "
8602 "ev_class AS ruletable, ev_type, is_instead, "
8603 "ev_enabled "
8604 "FROM pg_rewrite "
8605 "ORDER BY oid");
8606
8607 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8608
8609 ntups = PQntuples(res);
8610
8611 ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8612
8613 i_tableoid = PQfnumber(res, "tableoid");
8614 i_oid = PQfnumber(res, "oid");
8615 i_rulename = PQfnumber(res, "rulename");
8616 i_ruletable = PQfnumber(res, "ruletable");
8617 i_ev_type = PQfnumber(res, "ev_type");
8618 i_is_instead = PQfnumber(res, "is_instead");
8619 i_ev_enabled = PQfnumber(res, "ev_enabled");
8620
8621 for (i = 0; i < ntups; i++)
8622 {
8623 Oid ruletableoid;
8624
8625 ruleinfo[i].dobj.objType = DO_RULE;
8626 ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8627 ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8628 AssignDumpId(&ruleinfo[i].dobj);
8629 ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8630 ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8631 ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8632 if (ruleinfo[i].ruletable == NULL)
8633 pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8634 ruletableoid, ruleinfo[i].dobj.catId.oid);
8635 ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8636 ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8637 ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8638 ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8639 ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8640 if (ruleinfo[i].ruletable)
8641 {
8642 /*
8643 * If the table is a view or materialized view, force its ON
8644 * SELECT rule to be sorted before the view itself --- this
8645 * ensures that any dependencies for the rule affect the table's
8646 * positioning. Other rules are forced to appear after their
8647 * table.
8648 */
8649 if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8650 ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8651 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8652 {
8653 addObjectDependency(&ruleinfo[i].ruletable->dobj,
8654 ruleinfo[i].dobj.dumpId);
8655 /* We'll merge the rule into CREATE VIEW, if possible */
8656 ruleinfo[i].separate = false;
8657 }
8658 else
8659 {
8660 addObjectDependency(&ruleinfo[i].dobj,
8661 ruleinfo[i].ruletable->dobj.dumpId);
8662 ruleinfo[i].separate = true;
8663 }
8664 }
8665 else
8666 ruleinfo[i].separate = true;
8667 }
8668
8669 PQclear(res);
8670
8671 destroyPQExpBuffer(query);
8672}
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:8291
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:6123
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4756
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7783
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7727
void getForeignDataWrappers(Archive *fout)
Definition: pg_dump.c:10411
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4247
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19686
void getTypes(Archive *fout)
Definition: pg_dump.c:6198
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7662
void getOpclasses(Archive *fout)
Definition: pg_dump.c:6644
void getForeignServers(Archive *fout)
Definition: pg_dump.c:10495
void getFuncs(Archive *fout)
Definition: pg_dump.c:6913
void getTSDictionaries(Archive *fout)
Definition: pg_dump.c:10227
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4836
void getCasts(Archive *fout)
Definition: pg_dump.c:9040
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7843
void getTSConfigurations(Archive *fout)
Definition: pg_dump.c:10352
void getAccessMethods(Archive *fout)
Definition: pg_dump.c:6570
void getConversions(Archive *fout)
Definition: pg_dump.c:6508
void getRules(Archive *fout)
Definition: pg_dump.c:8585
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:9234
void getCollations(Archive *fout)
Definition: pg_dump.c:6442
void getAggregates(Archive *fout)
Definition: pg_dump.c:6772
void getNamespaces(Archive *fout)
Definition: pg_dump.c:5991
void getPublications(Archive *fout)
Definition: pg_dump.c:4537
void getTSParsers(Archive *fout)
Definition: pg_dump.c:10153
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:7185
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:8212
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19779
void getDefaultACLs(Archive *fout)
Definition: pg_dump.c:10583
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:5107
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8682
void getTransforms(Archive *fout)
Definition: pg_dump.c:9150
void getEventTriggers(Archive *fout)
Definition: pg_dump.c:8878
void getTSTemplates(Archive *fout)
Definition: pg_dump.c:10293
void getProcLangs(Archive *fout)
Definition: pg_dump.c:8956
void getSubscriptionRelations(Archive *fout)
Definition: pg_dump.c:5327
void getOperators(Archive *fout)
Definition: pg_dump.c:6366
void getOpfamilies(Archive *fout)
Definition: pg_dump.c:6707

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

5328{
5329 DumpOptions *dopt = fout->dopt;
5330 SubscriptionInfo *subinfo = NULL;
5331 SubRelInfo *subrinfo;
5332 PGresult *res;
5333 int i_srsubid;
5334 int i_srrelid;
5335 int i_srsubstate;
5336 int i_srsublsn;
5337 int ntups;
5338 Oid last_srsubid = InvalidOid;
5339
5340 if (dopt->no_subscriptions || !dopt->binary_upgrade ||
5341 fout->remoteVersion < 170000)
5342 return;
5343
5344 res = ExecuteSqlQuery(fout,
5345 "SELECT srsubid, srrelid, srsubstate, srsublsn "
5346 "FROM pg_catalog.pg_subscription_rel "
5347 "ORDER BY srsubid",
5349 ntups = PQntuples(res);
5350 if (ntups == 0)
5351 goto cleanup;
5352
5353 /* Get pg_subscription_rel attributes */
5354 i_srsubid = PQfnumber(res, "srsubid");
5355 i_srrelid = PQfnumber(res, "srrelid");
5356 i_srsubstate = PQfnumber(res, "srsubstate");
5357 i_srsublsn = PQfnumber(res, "srsublsn");
5358
5359 subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
5360 for (int i = 0; i < ntups; i++)
5361 {
5362 Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
5363 Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
5364 TableInfo *tblinfo;
5365
5366 /*
5367 * If we switched to a new subscription, check if the subscription
5368 * exists.
5369 */
5370 if (cur_srsubid != last_srsubid)
5371 {
5372 subinfo = findSubscriptionByOid(cur_srsubid);
5373 if (subinfo == NULL)
5374 pg_fatal("subscription with OID %u does not exist", cur_srsubid);
5375
5376 last_srsubid = cur_srsubid;
5377 }
5378
5379 tblinfo = findTableByOid(relid);
5380 if (tblinfo == NULL)
5381 pg_fatal("failed sanity check, relation with OID %u not found",
5382 relid);
5383
5384 /* OK, make a DumpableObject for this relationship */
5385 subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
5386 subrinfo[i].dobj.catId.tableoid = relid;
5387 subrinfo[i].dobj.catId.oid = cur_srsubid;
5388 AssignDumpId(&subrinfo[i].dobj);
5389 subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
5390 subrinfo[i].tblinfo = tblinfo;
5391 subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
5392 if (PQgetisnull(res, i, i_srsublsn))
5393 subrinfo[i].srsublsn = NULL;
5394 else
5395 subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
5396
5397 subrinfo[i].subinfo = subinfo;
5398
5399 /* Decide whether we want to dump it */
5400 selectDumpableObject(&(subrinfo[i].dobj), fout);
5401 }
5402
5403cleanup:
5404 PQclear(res);
5405}
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 5107 of file pg_dump.c.

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

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

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

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

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

10353{
10354 PGresult *res;
10355 int ntups;
10356 int i;
10357 PQExpBuffer query;
10358 TSConfigInfo *cfginfo;
10359 int i_tableoid;
10360 int i_oid;
10361 int i_cfgname;
10362 int i_cfgnamespace;
10363 int i_cfgowner;
10364 int i_cfgparser;
10365
10366 query = createPQExpBuffer();
10367
10368 appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
10369 "cfgnamespace, cfgowner, cfgparser "
10370 "FROM pg_ts_config");
10371
10372 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10373
10374 ntups = PQntuples(res);
10375
10376 cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
10377
10378 i_tableoid = PQfnumber(res, "tableoid");
10379 i_oid = PQfnumber(res, "oid");
10380 i_cfgname = PQfnumber(res, "cfgname");
10381 i_cfgnamespace = PQfnumber(res, "cfgnamespace");
10382 i_cfgowner = PQfnumber(res, "cfgowner");
10383 i_cfgparser = PQfnumber(res, "cfgparser");
10384
10385 for (i = 0; i < ntups; i++)
10386 {
10387 cfginfo[i].dobj.objType = DO_TSCONFIG;
10388 cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10389 cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10390 AssignDumpId(&cfginfo[i].dobj);
10391 cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
10392 cfginfo[i].dobj.namespace =
10393 findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
10394 cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
10395 cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
10396
10397 /* Decide whether we want to dump it */
10398 selectDumpableObject(&(cfginfo[i].dobj), fout);
10399 }
10400
10401 PQclear(res);
10402
10403 destroyPQExpBuffer(query);
10404}
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 10227 of file pg_dump.c.

10228{
10229 PGresult *res;
10230 int ntups;
10231 int i;
10232 PQExpBuffer query;
10233 TSDictInfo *dictinfo;
10234 int i_tableoid;
10235 int i_oid;
10236 int i_dictname;
10237 int i_dictnamespace;
10238 int i_dictowner;
10239 int i_dicttemplate;
10240 int i_dictinitoption;
10241
10242 query = createPQExpBuffer();
10243
10244 appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
10245 "dictnamespace, dictowner, "
10246 "dicttemplate, dictinitoption "
10247 "FROM pg_ts_dict");
10248
10249 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10250
10251 ntups = PQntuples(res);
10252
10253 dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
10254
10255 i_tableoid = PQfnumber(res, "tableoid");
10256 i_oid = PQfnumber(res, "oid");
10257 i_dictname = PQfnumber(res, "dictname");
10258 i_dictnamespace = PQfnumber(res, "dictnamespace");
10259 i_dictowner = PQfnumber(res, "dictowner");
10260 i_dictinitoption = PQfnumber(res, "dictinitoption");
10261 i_dicttemplate = PQfnumber(res, "dicttemplate");
10262
10263 for (i = 0; i < ntups; i++)
10264 {
10265 dictinfo[i].dobj.objType = DO_TSDICT;
10266 dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10267 dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10268 AssignDumpId(&dictinfo[i].dobj);
10269 dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
10270 dictinfo[i].dobj.namespace =
10271 findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
10272 dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
10273 dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
10274 if (PQgetisnull(res, i, i_dictinitoption))
10275 dictinfo[i].dictinitoption = NULL;
10276 else
10277 dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
10278
10279 /* Decide whether we want to dump it */
10280 selectDumpableObject(&(dictinfo[i].dobj), fout);
10281 }
10282
10283 PQclear(res);
10284
10285 destroyPQExpBuffer(query);
10286}
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 10153 of file pg_dump.c.

10154{
10155 PGresult *res;
10156 int ntups;
10157 int i;
10158 PQExpBuffer query;
10159 TSParserInfo *prsinfo;
10160 int i_tableoid;
10161 int i_oid;
10162 int i_prsname;
10163 int i_prsnamespace;
10164 int i_prsstart;
10165 int i_prstoken;
10166 int i_prsend;
10167 int i_prsheadline;
10168 int i_prslextype;
10169
10170 query = createPQExpBuffer();
10171
10172 /*
10173 * find all text search objects, including builtin ones; we filter out
10174 * system-defined objects at dump-out time.
10175 */
10176
10177 appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
10178 "prsstart::oid, prstoken::oid, "
10179 "prsend::oid, prsheadline::oid, prslextype::oid "
10180 "FROM pg_ts_parser");
10181
10182 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10183
10184 ntups = PQntuples(res);
10185
10186 prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
10187
10188 i_tableoid = PQfnumber(res, "tableoid");
10189 i_oid = PQfnumber(res, "oid");
10190 i_prsname = PQfnumber(res, "prsname");
10191 i_prsnamespace = PQfnumber(res, "prsnamespace");
10192 i_prsstart = PQfnumber(res, "prsstart");
10193 i_prstoken = PQfnumber(res, "prstoken");
10194 i_prsend = PQfnumber(res, "prsend");
10195 i_prsheadline = PQfnumber(res, "prsheadline");
10196 i_prslextype = PQfnumber(res, "prslextype");
10197
10198 for (i = 0; i < ntups; i++)
10199 {
10200 prsinfo[i].dobj.objType = DO_TSPARSER;
10201 prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10202 prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10203 AssignDumpId(&prsinfo[i].dobj);
10204 prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
10205 prsinfo[i].dobj.namespace =
10206 findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
10207 prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
10208 prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
10209 prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
10210 prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
10211 prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
10212
10213 /* Decide whether we want to dump it */
10214 selectDumpableObject(&(prsinfo[i].dobj), fout);
10215 }
10216
10217 PQclear(res);
10218
10219 destroyPQExpBuffer(query);
10220}
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 10293 of file pg_dump.c.

10294{
10295 PGresult *res;
10296 int ntups;
10297 int i;
10298 PQExpBuffer query;
10299 TSTemplateInfo *tmplinfo;
10300 int i_tableoid;
10301 int i_oid;
10302 int i_tmplname;
10303 int i_tmplnamespace;
10304 int i_tmplinit;
10305 int i_tmpllexize;
10306
10307 query = createPQExpBuffer();
10308
10309 appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
10310 "tmplnamespace, tmplinit::oid, tmpllexize::oid "
10311 "FROM pg_ts_template");
10312
10313 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10314
10315 ntups = PQntuples(res);
10316
10317 tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
10318
10319 i_tableoid = PQfnumber(res, "tableoid");
10320 i_oid = PQfnumber(res, "oid");
10321 i_tmplname = PQfnumber(res, "tmplname");
10322 i_tmplnamespace = PQfnumber(res, "tmplnamespace");
10323 i_tmplinit = PQfnumber(res, "tmplinit");
10324 i_tmpllexize = PQfnumber(res, "tmpllexize");
10325
10326 for (i = 0; i < ntups; i++)
10327 {
10328 tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
10329 tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
10330 tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
10331 AssignDumpId(&tmplinfo[i].dobj);
10332 tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
10333 tmplinfo[i].dobj.namespace =
10334 findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
10335 tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
10336 tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
10337
10338 /* Decide whether we want to dump it */
10339 selectDumpableObject(&(tmplinfo[i].dobj), fout);
10340 }
10341
10342 PQclear(res);
10343
10344 destroyPQExpBuffer(query);
10345}
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 6198 of file pg_dump.c.

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

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

10139{
10140 if (dopt->binary_upgrade)
10141 return true;
10142 if (tbinfo->attisdropped[colno])
10143 return false;
10144 return (tbinfo->attislocal[colno] || tbinfo->ispartition);
10145}

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

References DOTypeNameCompare(), and qsort.

Referenced by main().