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

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

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

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

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

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

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

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

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

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

19713{
19714 PQExpBuffer query;
19715 PGresult *res;
19716 int ntups,
19717 i;
19718 int i_classid,
19719 i_objid,
19720 i_refobjid;
19721 ExtensionInfo *ext;
19722
19723 /* Nothing to do if no extensions */
19724 if (numExtensions == 0)
19725 return;
19726
19727 query = createPQExpBuffer();
19728
19729 /* refclassid constraint is redundant but may speed the search */
19730 appendPQExpBufferStr(query, "SELECT "
19731 "classid, objid, refobjid "
19732 "FROM pg_depend "
19733 "WHERE refclassid = 'pg_extension'::regclass "
19734 "AND deptype = 'e' "
19735 "ORDER BY 3");
19736
19737 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
19738
19739 ntups = PQntuples(res);
19740
19741 i_classid = PQfnumber(res, "classid");
19742 i_objid = PQfnumber(res, "objid");
19743 i_refobjid = PQfnumber(res, "refobjid");
19744
19745 /*
19746 * Since we ordered the SELECT by referenced ID, we can expect that
19747 * multiple entries for the same extension will appear together; this
19748 * saves on searches.
19749 */
19750 ext = NULL;
19751
19752 for (i = 0; i < ntups; i++)
19753 {
19754 CatalogId objId;
19755 Oid extId;
19756
19757 objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
19758 objId.oid = atooid(PQgetvalue(res, i, i_objid));
19759 extId = atooid(PQgetvalue(res, i, i_refobjid));
19760
19761 if (ext == NULL ||
19762 ext->dobj.catId.oid != extId)
19763 ext = findExtensionByOid(extId);
19764
19765 if (ext == NULL)
19766 {
19767 /* shouldn't happen */
19768 pg_log_warning("could not find referenced extension %u", extId);
19769 continue;
19770 }
19771
19772 recordExtensionMembership(objId, ext);
19773 }
19774
19775 PQclear(res);
19776
19777 destroyPQExpBuffer(query);
19778}
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 6135 of file pg_dump.c.

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

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

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

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

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

7740{
7741 PGresult *res;
7742 int ntups;
7743 int i;
7745 InhInfo *inhinfo;
7746
7747 int i_inhrelid;
7748 int i_inhparent;
7749
7750 /* find all the inheritance information */
7751 appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7752
7753 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7754
7755 ntups = PQntuples(res);
7756
7757 *numInherits = ntups;
7758
7759 inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7760
7761 i_inhrelid = PQfnumber(res, "inhrelid");
7762 i_inhparent = PQfnumber(res, "inhparent");
7763
7764 for (i = 0; i < ntups; i++)
7765 {
7766 inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7767 inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7768 }
7769
7770 PQclear(res);
7771
7772 destroyPQExpBuffer(query);
7773
7774 return inhinfo;
7775}
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 6003 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

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

8598{
8599 PGresult *res;
8600 int ntups;
8601 int i;
8603 RuleInfo *ruleinfo;
8604 int i_tableoid;
8605 int i_oid;
8606 int i_rulename;
8607 int i_ruletable;
8608 int i_ev_type;
8609 int i_is_instead;
8610 int i_ev_enabled;
8611
8612 appendPQExpBufferStr(query, "SELECT "
8613 "tableoid, oid, rulename, "
8614 "ev_class AS ruletable, ev_type, is_instead, "
8615 "ev_enabled "
8616 "FROM pg_rewrite "
8617 "ORDER BY oid");
8618
8619 res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8620
8621 ntups = PQntuples(res);
8622
8623 ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8624
8625 i_tableoid = PQfnumber(res, "tableoid");
8626 i_oid = PQfnumber(res, "oid");
8627 i_rulename = PQfnumber(res, "rulename");
8628 i_ruletable = PQfnumber(res, "ruletable");
8629 i_ev_type = PQfnumber(res, "ev_type");
8630 i_is_instead = PQfnumber(res, "is_instead");
8631 i_ev_enabled = PQfnumber(res, "ev_enabled");
8632
8633 for (i = 0; i < ntups; i++)
8634 {
8635 Oid ruletableoid;
8636
8637 ruleinfo[i].dobj.objType = DO_RULE;
8638 ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8639 ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8640 AssignDumpId(&ruleinfo[i].dobj);
8641 ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8642 ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8643 ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8644 if (ruleinfo[i].ruletable == NULL)
8645 pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8646 ruletableoid, ruleinfo[i].dobj.catId.oid);
8647 ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8648 ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8649 ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8650 ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8651 ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8652 if (ruleinfo[i].ruletable)
8653 {
8654 /*
8655 * If the table is a view or materialized view, force its ON
8656 * SELECT rule to be sorted before the view itself --- this
8657 * ensures that any dependencies for the rule affect the table's
8658 * positioning. Other rules are forced to appear after their
8659 * table.
8660 */
8661 if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8662 ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8663 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8664 {
8665 addObjectDependency(&ruleinfo[i].ruletable->dobj,
8666 ruleinfo[i].dobj.dumpId);
8667 /* We'll merge the rule into CREATE VIEW, if possible */
8668 ruleinfo[i].separate = false;
8669 }
8670 else
8671 {
8672 addObjectDependency(&ruleinfo[i].dobj,
8673 ruleinfo[i].ruletable->dobj.dumpId);
8674 ruleinfo[i].separate = true;
8675 }
8676 }
8677 else
8678 ruleinfo[i].separate = true;
8679 }
8680
8681 PQclear(res);
8682
8683 destroyPQExpBuffer(query);
8684}
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:8303
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:6135
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4768
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7795
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7739
void getForeignDataWrappers(Archive *fout)
Definition: pg_dump.c:10423
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4259
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19711
void getTypes(Archive *fout)
Definition: pg_dump.c:6210
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7674
void getOpclasses(Archive *fout)
Definition: pg_dump.c:6656
void getForeignServers(Archive *fout)
Definition: pg_dump.c:10507
void getFuncs(Archive *fout)
Definition: pg_dump.c:6925
void getTSDictionaries(Archive *fout)
Definition: pg_dump.c:10239
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4848
void getCasts(Archive *fout)
Definition: pg_dump.c:9052
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7855
void getTSConfigurations(Archive *fout)
Definition: pg_dump.c:10364
void getAccessMethods(Archive *fout)
Definition: pg_dump.c:6582
void getConversions(Archive *fout)
Definition: pg_dump.c:6520
void getRules(Archive *fout)
Definition: pg_dump.c:8597
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:9246
void getCollations(Archive *fout)
Definition: pg_dump.c:6454
void getAggregates(Archive *fout)
Definition: pg_dump.c:6784
void getNamespaces(Archive *fout)
Definition: pg_dump.c:6003
void getPublications(Archive *fout)
Definition: pg_dump.c:4549
void getTSParsers(Archive *fout)
Definition: pg_dump.c:10165
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:7197
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:8224
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:19804
void getDefaultACLs(Archive *fout)
Definition: pg_dump.c:10595
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:5119
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8694
void getTransforms(Archive *fout)
Definition: pg_dump.c:9162
void getEventTriggers(Archive *fout)
Definition: pg_dump.c:8890
void getTSTemplates(Archive *fout)
Definition: pg_dump.c:10305
void getProcLangs(Archive *fout)
Definition: pg_dump.c:8968
void getSubscriptionRelations(Archive *fout)
Definition: pg_dump.c:5339
void getOperators(Archive *fout)
Definition: pg_dump.c:6378
void getOpfamilies(Archive *fout)
Definition: pg_dump.c:6719

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

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

References AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, cleanup(), DO_SUBSCRIPTION_REL, _tableInfo::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 5119 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

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

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

10151{
10152 if (dopt->binary_upgrade)
10153 return true;
10154 if (tbinfo->attisdropped[colno])
10155 return false;
10156 return (tbinfo->attislocal[colno] || tbinfo->ispartition);
10157}

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 559 of file pg_dump_sort.c.

561{
562 DumpableObject **ordering;
563 int nOrdering;
564
565 if (numObjs <= 0) /* can't happen anymore ... */
566 return;
567
568 /*
569 * Saving the boundary IDs in static variables is a bit grotty, but seems
570 * better than adding them to parameter lists of subsidiary functions.
571 */
572 preDataBoundId = preBoundaryId;
573 postDataBoundId = postBoundaryId;
574
575 ordering = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
576 while (!TopoSort(objs, numObjs, ordering, &nOrdering))
577 findDependencyLoops(ordering, nOrdering, numObjs);
578
579 memcpy(objs, ordering, numObjs * sizeof(DumpableObject *));
580
581 free(ordering);
582}
static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
Definition: pg_dump_sort.c:760
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:611
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:495

References DOTypeNameCompare(), and qsort.

Referenced by main().