PostgreSQL Source Code  git master
pg_dump.h File Reference
#include "pg_backup.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  _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 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_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 _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_SUBSCRIPTION , DO_SUBSCRIPTION_REL
}
 

Functions

TableInfogetSchemaData (Archive *fout, int *numTablesPtr)
 
void AssignDumpId (DumpableObject *dobj)
 
void recordAdditionalCatalogID (CatalogId catId, DumpableObject *dobj)
 
DumpId createDumpId (void)
 
DumpId getMaxDumpId (void)
 
DumpableObjectfindObjectByDumpId (DumpId dumpId)
 
DumpableObjectfindObjectByCatalogId (CatalogId catalogId)
 
void getDumpableObjects (DumpableObject ***objs, int *numObjs)
 
void addObjectDependency (DumpableObject *dobj, DumpId refId)
 
void removeObjectDependency (DumpableObject *dobj, DumpId refId)
 
TableInfofindTableByOid (Oid oid)
 
TypeInfofindTypeByOid (Oid oid)
 
FuncInfofindFuncByOid (Oid oid)
 
OprInfofindOprByOid (Oid oid)
 
CollInfofindCollationByOid (Oid oid)
 
NamespaceInfofindNamespaceByOid (Oid oid)
 
ExtensionInfofindExtensionByOid (Oid oid)
 
PublicationInfofindPublicationByOid (Oid oid)
 
SubscriptionInfofindSubscriptionByOid (Oid oid)
 
void recordExtensionMembership (CatalogId catId, ExtensionInfo *ext)
 
ExtensionInfofindOwningExtension (CatalogId catalogId)
 
void parseOidArray (const char *str, Oid *array, int arraysize)
 
void sortDumpableObjects (DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId)
 
void sortDumpableObjectsByTypeName (DumpableObject **objs, int numObjs)
 
NamespaceInfogetNamespaces (Archive *fout, int *numNamespaces)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
TypeInfogetTypes (Archive *fout, int *numTypes)
 
FuncInfogetFuncs (Archive *fout, int *numFuncs)
 
AggInfogetAggregates (Archive *fout, int *numAggs)
 
OprInfogetOperators (Archive *fout, int *numOprs)
 
AccessMethodInfogetAccessMethods (Archive *fout, int *numAccessMethods)
 
OpclassInfogetOpclasses (Archive *fout, int *numOpclasses)
 
OpfamilyInfogetOpfamilies (Archive *fout, int *numOpfamilies)
 
CollInfogetCollations (Archive *fout, int *numCollations)
 
ConvInfogetConversions (Archive *fout, int *numConversions)
 
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)
 
RuleInfogetRules (Archive *fout, int *numRules)
 
void getTriggers (Archive *fout, TableInfo tblinfo[], int numTables)
 
ProcLangInfogetProcLangs (Archive *fout, int *numProcLangs)
 
CastInfogetCasts (Archive *fout, int *numCasts)
 
TransformInfogetTransforms (Archive *fout, int *numTransforms)
 
void getTableAttrs (Archive *fout, TableInfo *tblinfo, int numTables)
 
bool shouldPrintColumn (const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
 
TSParserInfogetTSParsers (Archive *fout, int *numTSParsers)
 
TSDictInfogetTSDictionaries (Archive *fout, int *numTSDicts)
 
TSTemplateInfogetTSTemplates (Archive *fout, int *numTSTemplates)
 
TSConfigInfogetTSConfigurations (Archive *fout, int *numTSConfigs)
 
FdwInfogetForeignDataWrappers (Archive *fout, int *numForeignDataWrappers)
 
ForeignServerInfogetForeignServers (Archive *fout, int *numForeignServers)
 
DefaultACLInfogetDefaultACLs (Archive *fout, int *numDefaultACLs)
 
void getExtensionMembership (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void processExtensionTables (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
EventTriggerInfogetEventTriggers (Archive *fout, int *numEventTriggers)
 
void getPolicies (Archive *fout, TableInfo tblinfo[], int numTables)
 
PublicationInfogetPublications (Archive *fout, int *numPublications)
 
void getPublicationNamespaces (Archive *fout)
 
void getPublicationTables (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getSubscriptions (Archive *fout)
 
void getSubscriptionTables (Archive *fout)
 

Macro Definition Documentation

◆ DUMP_COMPONENT_ACL

#define DUMP_COMPONENT_ACL   (1 << 4)

Definition at line 101 of file pg_dump.h.

◆ DUMP_COMPONENT_ALL

#define DUMP_COMPONENT_ALL   (0xFFFF)

Definition at line 104 of file pg_dump.h.

◆ DUMP_COMPONENT_COMMENT

#define DUMP_COMPONENT_COMMENT   (1 << 2)

Definition at line 99 of file pg_dump.h.

◆ DUMP_COMPONENT_DATA

#define DUMP_COMPONENT_DATA   (1 << 1)

Definition at line 98 of file pg_dump.h.

◆ DUMP_COMPONENT_DEFINITION

#define DUMP_COMPONENT_DEFINITION   (1 << 0)

Definition at line 97 of file pg_dump.h.

◆ DUMP_COMPONENT_NONE

#define DUMP_COMPONENT_NONE   (0)

Definition at line 96 of file pg_dump.h.

◆ DUMP_COMPONENT_POLICY

#define DUMP_COMPONENT_POLICY   (1 << 5)

Definition at line 102 of file pg_dump.h.

◆ DUMP_COMPONENT_SECLABEL

#define DUMP_COMPONENT_SECLABEL   (1 << 3)

Definition at line 100 of file pg_dump.h.

◆ DUMP_COMPONENT_USERMAP

#define DUMP_COMPONENT_USERMAP   (1 << 6)

Definition at line 103 of file pg_dump.h.

◆ DUMP_COMPONENTS_REQUIRING_LOCK

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

Definition at line 128 of file pg_dump.h.

◆ oidcmp

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

Definition at line 20 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 95 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

◆ 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_SUBSCRIPTION 
DO_SUBSCRIPTION_REL 

Definition at line 37 of file pg_dump.h.

38 {
39  /* When modifying this enum, update priority tables in pg_dump_sort.c! */
42  DO_TYPE,
44  DO_FUNC,
45  DO_AGG,
48  DO_OPCLASS,
52  DO_TABLE,
54  DO_ATTRDEF,
55  DO_INDEX,
58  DO_RULE,
59  DO_TRIGGER,
61  DO_FK_CONSTRAINT, /* see note for ConstraintInfo */
63  DO_CAST,
68  DO_TSDICT,
71  DO_FDW,
81  DO_POLICY,
86  DO_SUBSCRIPTION_REL, /* see note for SubRelInfo */
DumpableObjectType
Definition: pg_dump.h:38
@ DO_EVENT_TRIGGER
Definition: pg_dump.h:79
@ DO_REFRESH_MATVIEW
Definition: pg_dump.h:80
@ DO_POLICY
Definition: pg_dump.h:81
@ DO_CAST
Definition: pg_dump.h:63
@ DO_FOREIGN_SERVER
Definition: pg_dump.h:72
@ DO_PRE_DATA_BOUNDARY
Definition: pg_dump.h:77
@ DO_PROCLANG
Definition: pg_dump.h:62
@ DO_TYPE
Definition: pg_dump.h:42
@ DO_INDEX
Definition: pg_dump.h:55
@ DO_COLLATION
Definition: pg_dump.h:50
@ DO_LARGE_OBJECT
Definition: pg_dump.h:75
@ DO_TSCONFIG
Definition: pg_dump.h:70
@ DO_OPERATOR
Definition: pg_dump.h:46
@ DO_FK_CONSTRAINT
Definition: pg_dump.h:61
@ DO_CONSTRAINT
Definition: pg_dump.h:60
@ DO_SUBSCRIPTION
Definition: pg_dump.h:85
@ DO_DEFAULT_ACL
Definition: pg_dump.h:73
@ DO_FDW
Definition: pg_dump.h:71
@ DO_SUBSCRIPTION_REL
Definition: pg_dump.h:86
@ DO_SEQUENCE_SET
Definition: pg_dump.h:65
@ DO_ATTRDEF
Definition: pg_dump.h:54
@ DO_PUBLICATION_REL
Definition: pg_dump.h:83
@ DO_TABLE_ATTACH
Definition: pg_dump.h:53
@ DO_OPCLASS
Definition: pg_dump.h:48
@ DO_INDEX_ATTACH
Definition: pg_dump.h:56
@ DO_TSTEMPLATE
Definition: pg_dump.h:69
@ DO_STATSEXT
Definition: pg_dump.h:57
@ DO_FUNC
Definition: pg_dump.h:44
@ DO_POST_DATA_BOUNDARY
Definition: pg_dump.h:78
@ DO_LARGE_OBJECT_DATA
Definition: pg_dump.h:76
@ DO_OPFAMILY
Definition: pg_dump.h:49
@ DO_TRANSFORM
Definition: pg_dump.h:74
@ DO_ACCESS_METHOD
Definition: pg_dump.h:47
@ DO_PUBLICATION_TABLE_IN_SCHEMA
Definition: pg_dump.h:84
@ DO_CONVERSION
Definition: pg_dump.h:51
@ DO_TRIGGER
Definition: pg_dump.h:59
@ DO_RULE
Definition: pg_dump.h:58
@ DO_DUMMY_TYPE
Definition: pg_dump.h:66
@ DO_TSDICT
Definition: pg_dump.h:68
@ DO_TSPARSER
Definition: pg_dump.h:67
@ DO_EXTENSION
Definition: pg_dump.h:41
@ DO_TABLE_DATA
Definition: pg_dump.h:64
@ DO_PUBLICATION
Definition: pg_dump.h:82
@ DO_TABLE
Definition: pg_dump.h:52
@ DO_NAMESPACE
Definition: pg_dump.h:40
@ DO_AGG
Definition: pg_dump.h:45
@ DO_SHELL_TYPE
Definition: pg_dump.h:43

Function Documentation

◆ addObjectDependency()

void addObjectDependency ( DumpableObject dobj,
DumpId  refId 
)

◆ AssignDumpId()

void AssignDumpId ( DumpableObject dobj)

Definition at line 648 of file common.c.

649 {
650  dobj->dumpId = ++lastDumpId;
651  dobj->name = NULL; /* must be set later */
652  dobj->namespace = NULL; /* may be set later */
653  dobj->dump = DUMP_COMPONENT_ALL; /* default assumption */
654  dobj->dump_contains = DUMP_COMPONENT_ALL; /* default assumption */
655  /* All objects have definitions; we may set more components bits later */
657  dobj->ext_member = false; /* default assumption */
658  dobj->depends_on_ext = false; /* default assumption */
659  dobj->dependencies = NULL;
660  dobj->nDeps = 0;
661  dobj->allocDeps = 0;
662 
663  /* Add object to dumpIdMap[], enlarging that array if need be */
664  while (dobj->dumpId >= allocedDumpIds)
665  {
666  int newAlloc;
667 
668  if (allocedDumpIds <= 0)
669  {
670  newAlloc = 256;
672  }
673  else
674  {
675  newAlloc = allocedDumpIds * 2;
677  }
678  memset(dumpIdMap + allocedDumpIds, 0,
679  (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
680  allocedDumpIds = newAlloc;
681  }
682  dumpIdMap[dobj->dumpId] = dobj;
683 
684  /* If it has a valid CatalogId, enter it into the hash table */
685  if (OidIsValid(dobj->catId.tableoid))
686  {
687  CatalogIdMapEntry *entry;
688  bool found;
689 
690  /* Initialize CatalogId hash table if not done yet */
691  if (catalogIdHash == NULL)
692  catalogIdHash = catalogid_create(CATALOGIDHASH_INITIAL_SIZE, NULL);
693 
694  entry = catalogid_insert(catalogIdHash, dobj->catId, &found);
695  if (!found)
696  {
697  entry->dobj = NULL;
698  entry->ext = NULL;
699  }
700  Assert(entry->dobj == NULL);
701  entry->dobj = dobj;
702  }
703 }
static int allocedDumpIds
Definition: common.c:39
static DumpableObject ** dumpIdMap
Definition: common.c:38
#define CATALOGIDHASH_INITIAL_SIZE
Definition: common.c:81
static catalogid_hash * catalogIdHash
Definition: common.c:83
static DumpId lastDumpId
Definition: common.c:40
#define Assert(condition)
Definition: c.h:858
#define OidIsValid(objectId)
Definition: c.h:775
#define DUMP_COMPONENT_ALL
Definition: pg_dump.h:104
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:97
Oid tableoid
Definition: pg_backup.h:266
ExtensionInfo * ext
Definition: common.c:64
DumpableObject * dobj
Definition: common.c:63
DumpComponents dump
Definition: pg_dump.h:139
char * name
Definition: pg_dump.h:138
DumpId dumpId
Definition: pg_dump.h:137
bool ext_member
Definition: pg_dump.h:143
DumpComponents components
Definition: pg_dump.h:142
CatalogId catId
Definition: pg_dump.h:136
DumpComponents dump_contains
Definition: pg_dump.h:141
bool depends_on_ext
Definition: pg_dump.h:144

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(), getRules(), getSubscriptions(), getSubscriptionTables(), getTableAttrs(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), and makeTableDataInfo().

◆ createDumpId()

◆ findCollationByOid()

CollInfo* findCollationByOid ( Oid  oid)

Definition at line 945 of file common.c.

946 {
947  CatalogId catId;
948  DumpableObject *dobj;
949 
950  catId.tableoid = CollationRelationId;
951  catId.oid = oid;
952  dobj = findObjectByCatalogId(catId);
953  Assert(dobj == NULL || dobj->objType == DO_COLLATION);
954  return (CollInfo *) dobj;
955 }
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:769
DumpableObjectType objType
Definition: pg_dump.h:135

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

982 {
983  CatalogId catId;
984  DumpableObject *dobj;
985 
986  catId.tableoid = ExtensionRelationId;
987  catId.oid = oid;
988  dobj = findObjectByCatalogId(catId);
989  Assert(dobj == NULL || dobj->objType == DO_EXTENSION);
990  return (ExtensionInfo *) dobj;
991 }

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

Referenced by getExtensionMembership().

◆ findFuncByOid()

FuncInfo* findFuncByOid ( Oid  oid)

Definition at line 909 of file common.c.

910 {
911  CatalogId catId;
912  DumpableObject *dobj;
913 
914  catId.tableoid = ProcedureRelationId;
915  catId.oid = oid;
916  dobj = findObjectByCatalogId(catId);
917  Assert(dobj == NULL || dobj->objType == DO_FUNC);
918  return (FuncInfo *) dobj;
919 }

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

964 {
965  CatalogId catId;
966  DumpableObject *dobj;
967 
968  catId.tableoid = NamespaceRelationId;
969  catId.oid = oid;
970  dobj = findObjectByCatalogId(catId);
971  Assert(dobj == NULL || dobj->objType == DO_NAMESPACE);
972  return (NamespaceInfo *) dobj;
973 }

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

770 {
771  CatalogIdMapEntry *entry;
772 
773  if (catalogIdHash == NULL)
774  return NULL; /* no objects exist yet */
775 
776  entry = catalogid_lookup(catalogIdHash, catalogId);
777  if (entry == NULL)
778  return NULL;
779  return entry->dobj;
780 }

References catalogIdHash, and _catalogIdMapEntry::dobj.

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

◆ findObjectByDumpId()

DumpableObject* findObjectByDumpId ( DumpId  dumpId)

Definition at line 756 of file common.c.

757 {
758  if (dumpId <= 0 || dumpId >= allocedDumpIds)
759  return NULL; /* out of range? */
760  return dumpIdMap[dumpId];
761 }

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

928 {
929  CatalogId catId;
930  DumpableObject *dobj;
931 
932  catId.tableoid = OperatorRelationId;
933  catId.oid = oid;
934  dobj = findObjectByCatalogId(catId);
935  Assert(dobj == NULL || dobj->objType == DO_OPERATOR);
936  return (OprInfo *) dobj;
937 }

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

Referenced by getFormattedOperatorName().

◆ findOwningExtension()

ExtensionInfo* findOwningExtension ( CatalogId  catalogId)

Definition at line 1060 of file common.c.

1061 {
1062  CatalogIdMapEntry *entry;
1063 
1064  if (catalogIdHash == NULL)
1065  return NULL; /* no objects exist yet */
1066 
1067  entry = catalogid_lookup(catalogIdHash, catalogId);
1068  if (entry == NULL)
1069  return NULL;
1070  return entry->ext;
1071 }

References catalogIdHash, and _catalogIdMapEntry::ext.

Referenced by checkExtensionMembership().

◆ findPublicationByOid()

PublicationInfo* findPublicationByOid ( Oid  oid)

Definition at line 999 of file common.c.

1000 {
1001  CatalogId catId;
1002  DumpableObject *dobj;
1003 
1004  catId.tableoid = PublicationRelationId;
1005  catId.oid = oid;
1006  dobj = findObjectByCatalogId(catId);
1007  Assert(dobj == NULL || dobj->objType == DO_PUBLICATION);
1008  return (PublicationInfo *) dobj;
1009 }

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

1018 {
1019  CatalogId catId;
1020  DumpableObject *dobj;
1021 
1022  catId.tableoid = SubscriptionRelationId;
1023  catId.oid = oid;
1024  dobj = findObjectByCatalogId(catId);
1025  Assert(dobj == NULL || dobj->objType == DO_SUBSCRIPTION);
1026  return (SubscriptionInfo *) dobj;
1027 }

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

Referenced by getSubscriptionTables().

◆ findTableByOid()

TableInfo* findTableByOid ( Oid  oid)

◆ findTypeByOid()

TypeInfo* findTypeByOid ( Oid  oid)

Definition at line 890 of file common.c.

891 {
892  CatalogId catId;
893  DumpableObject *dobj;
894 
895  catId.tableoid = TypeRelationId;
896  catId.oid = oid;
897  dobj = findObjectByCatalogId(catId);
898  Assert(dobj == NULL ||
899  dobj->objType == DO_TYPE || dobj->objType == DO_DUMMY_TYPE);
900  return (TypeInfo *) dobj;
901 }

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

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

◆ getAccessMethods()

AccessMethodInfo* getAccessMethods ( Archive fout,
int *  numAccessMethods 
)

Definition at line 6150 of file pg_dump.c.

6151 {
6152  PGresult *res;
6153  int ntups;
6154  int i;
6155  PQExpBuffer query;
6156  AccessMethodInfo *aminfo;
6157  int i_tableoid;
6158  int i_oid;
6159  int i_amname;
6160  int i_amhandler;
6161  int i_amtype;
6162 
6163  /* Before 9.6, there are no user-defined access methods */
6164  if (fout->remoteVersion < 90600)
6165  {
6166  *numAccessMethods = 0;
6167  return NULL;
6168  }
6169 
6170  query = createPQExpBuffer();
6171 
6172  /* Select all access methods from pg_am table */
6173  appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6174  "amhandler::pg_catalog.regproc AS amhandler "
6175  "FROM pg_am");
6176 
6177  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6178 
6179  ntups = PQntuples(res);
6180  *numAccessMethods = ntups;
6181 
6182  aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6183 
6184  i_tableoid = PQfnumber(res, "tableoid");
6185  i_oid = PQfnumber(res, "oid");
6186  i_amname = PQfnumber(res, "amname");
6187  i_amhandler = PQfnumber(res, "amhandler");
6188  i_amtype = PQfnumber(res, "amtype");
6189 
6190  for (i = 0; i < ntups; i++)
6191  {
6192  aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6193  aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6194  aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6195  AssignDumpId(&aminfo[i].dobj);
6196  aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6197  aminfo[i].dobj.namespace = NULL;
6198  aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6199  aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6200 
6201  /* Decide whether we want to dump it */
6202  selectDumpableAccessMethod(&(aminfo[i]), fout);
6203  }
6204 
6205  PQclear(res);
6206 
6207  destroyPQExpBuffer(query);
6208 
6209  return aminfo;
6210 }
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:648
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3589
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int i
Definition: isn.c:73
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:103
PGresult * ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
Definition: pg_backup_db.c:290
static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
Definition: pg_dump.c:2003
#define atooid(x)
Definition: postgres_ext.h:42
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:219
char * amhandler
Definition: pg_dump.h:253
DumpableObject dobj
Definition: pg_dump.h:251

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, res, selectDumpableAccessMethod(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getAggregates()

AggInfo* getAggregates ( Archive fout,
int *  numAggs 
)

Definition at line 6355 of file pg_dump.c.

6356 {
6357  DumpOptions *dopt = fout->dopt;
6358  PGresult *res;
6359  int ntups;
6360  int i;
6361  PQExpBuffer query = createPQExpBuffer();
6362  AggInfo *agginfo;
6363  int i_tableoid;
6364  int i_oid;
6365  int i_aggname;
6366  int i_aggnamespace;
6367  int i_pronargs;
6368  int i_proargtypes;
6369  int i_proowner;
6370  int i_aggacl;
6371  int i_acldefault;
6372 
6373  /*
6374  * Find all interesting aggregates. See comment in getFuncs() for the
6375  * rationale behind the filtering logic.
6376  */
6377  if (fout->remoteVersion >= 90600)
6378  {
6379  const char *agg_check;
6380 
6381  agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
6382  : "p.proisagg");
6383 
6384  appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
6385  "p.proname AS aggname, "
6386  "p.pronamespace AS aggnamespace, "
6387  "p.pronargs, p.proargtypes, "
6388  "p.proowner, "
6389  "p.proacl AS aggacl, "
6390  "acldefault('f', p.proowner) AS acldefault "
6391  "FROM pg_proc p "
6392  "LEFT JOIN pg_init_privs pip ON "
6393  "(p.oid = pip.objoid "
6394  "AND pip.classoid = 'pg_proc'::regclass "
6395  "AND pip.objsubid = 0) "
6396  "WHERE %s AND ("
6397  "p.pronamespace != "
6398  "(SELECT oid FROM pg_namespace "
6399  "WHERE nspname = 'pg_catalog') OR "
6400  "p.proacl IS DISTINCT FROM pip.initprivs",
6401  agg_check);
6402  if (dopt->binary_upgrade)
6403  appendPQExpBufferStr(query,
6404  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6405  "classid = 'pg_proc'::regclass AND "
6406  "objid = p.oid AND "
6407  "refclassid = 'pg_extension'::regclass AND "
6408  "deptype = 'e')");
6409  appendPQExpBufferChar(query, ')');
6410  }
6411  else
6412  {
6413  appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
6414  "pronamespace AS aggnamespace, "
6415  "pronargs, proargtypes, "
6416  "proowner, "
6417  "proacl AS aggacl, "
6418  "acldefault('f', proowner) AS acldefault "
6419  "FROM pg_proc p "
6420  "WHERE proisagg AND ("
6421  "pronamespace != "
6422  "(SELECT oid FROM pg_namespace "
6423  "WHERE nspname = 'pg_catalog')");
6424  if (dopt->binary_upgrade)
6425  appendPQExpBufferStr(query,
6426  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6427  "classid = 'pg_proc'::regclass AND "
6428  "objid = p.oid AND "
6429  "refclassid = 'pg_extension'::regclass AND "
6430  "deptype = 'e')");
6431  appendPQExpBufferChar(query, ')');
6432  }
6433 
6434  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6435 
6436  ntups = PQntuples(res);
6437  *numAggs = ntups;
6438 
6439  agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
6440 
6441  i_tableoid = PQfnumber(res, "tableoid");
6442  i_oid = PQfnumber(res, "oid");
6443  i_aggname = PQfnumber(res, "aggname");
6444  i_aggnamespace = PQfnumber(res, "aggnamespace");
6445  i_pronargs = PQfnumber(res, "pronargs");
6446  i_proargtypes = PQfnumber(res, "proargtypes");
6447  i_proowner = PQfnumber(res, "proowner");
6448  i_aggacl = PQfnumber(res, "aggacl");
6449  i_acldefault = PQfnumber(res, "acldefault");
6450 
6451  for (i = 0; i < ntups; i++)
6452  {
6453  agginfo[i].aggfn.dobj.objType = DO_AGG;
6454  agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6455  agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6456  AssignDumpId(&agginfo[i].aggfn.dobj);
6457  agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
6458  agginfo[i].aggfn.dobj.namespace =
6459  findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
6460  agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
6461  agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6462  agginfo[i].aggfn.dacl.privtype = 0;
6463  agginfo[i].aggfn.dacl.initprivs = NULL;
6464  agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6465  agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
6466  agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
6467  agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
6468  if (agginfo[i].aggfn.nargs == 0)
6469  agginfo[i].aggfn.argtypes = NULL;
6470  else
6471  {
6472  agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
6473  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6474  agginfo[i].aggfn.argtypes,
6475  agginfo[i].aggfn.nargs);
6476  }
6477  agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
6478 
6479  /* Decide whether we want to dump it */
6480  selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
6481 
6482  /* Mark whether aggregate has an ACL */
6483  if (!PQgetisnull(res, i, i_aggacl))
6484  agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
6485  }
6486 
6487  PQclear(res);
6488 
6489  destroyPQExpBuffer(query);
6490 
6491  return agginfo;
6492 }
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1084
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
static const char * getRoleName(const char *roleoid_str)
Definition: pg_dump.c:10024
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2106
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:5677
#define DUMP_COMPONENT_ACL
Definition: pg_dump.h:101
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
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:214
int binary_upgrade
Definition: pg_backup.h:166

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, res, and selectDumpableObject().

Referenced by getSchemaData().

◆ getCasts()

CastInfo* getCasts ( Archive fout,
int *  numCasts 
)

Definition at line 8479 of file pg_dump.c.

8480 {
8481  PGresult *res;
8482  int ntups;
8483  int i;
8484  PQExpBuffer query = createPQExpBuffer();
8485  CastInfo *castinfo;
8486  int i_tableoid;
8487  int i_oid;
8488  int i_castsource;
8489  int i_casttarget;
8490  int i_castfunc;
8491  int i_castcontext;
8492  int i_castmethod;
8493 
8494  if (fout->remoteVersion >= 140000)
8495  {
8496  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8497  "castsource, casttarget, castfunc, castcontext, "
8498  "castmethod "
8499  "FROM pg_cast c "
8500  "WHERE NOT EXISTS ( "
8501  "SELECT 1 FROM pg_range r "
8502  "WHERE c.castsource = r.rngtypid "
8503  "AND c.casttarget = r.rngmultitypid "
8504  ") "
8505  "ORDER BY 3,4");
8506  }
8507  else
8508  {
8509  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8510  "castsource, casttarget, castfunc, castcontext, "
8511  "castmethod "
8512  "FROM pg_cast ORDER BY 3,4");
8513  }
8514 
8515  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8516 
8517  ntups = PQntuples(res);
8518 
8519  *numCasts = ntups;
8520 
8521  castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8522 
8523  i_tableoid = PQfnumber(res, "tableoid");
8524  i_oid = PQfnumber(res, "oid");
8525  i_castsource = PQfnumber(res, "castsource");
8526  i_casttarget = PQfnumber(res, "casttarget");
8527  i_castfunc = PQfnumber(res, "castfunc");
8528  i_castcontext = PQfnumber(res, "castcontext");
8529  i_castmethod = PQfnumber(res, "castmethod");
8530 
8531  for (i = 0; i < ntups; i++)
8532  {
8533  PQExpBufferData namebuf;
8534  TypeInfo *sTypeInfo;
8535  TypeInfo *tTypeInfo;
8536 
8537  castinfo[i].dobj.objType = DO_CAST;
8538  castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8539  castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8540  AssignDumpId(&castinfo[i].dobj);
8541  castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8542  castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8543  castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8544  castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8545  castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8546 
8547  /*
8548  * Try to name cast as concatenation of typnames. This is only used
8549  * for purposes of sorting. If we fail to find either type, the name
8550  * will be an empty string.
8551  */
8552  initPQExpBuffer(&namebuf);
8553  sTypeInfo = findTypeByOid(castinfo[i].castsource);
8554  tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8555  if (sTypeInfo && tTypeInfo)
8556  appendPQExpBuffer(&namebuf, "%s %s",
8557  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8558  castinfo[i].dobj.name = namebuf.data;
8559 
8560  /* Decide whether we want to dump it */
8561  selectDumpableCast(&(castinfo[i]), fout);
8562  }
8563 
8564  PQclear(res);
8565 
8566  destroyPQExpBuffer(query);
8567 
8568  return castinfo;
8569 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:890
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:1945
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
char castmethod
Definition: pg_dump.h:505
Oid casttarget
Definition: pg_dump.h:502
char castcontext
Definition: pg_dump.h:504
DumpableObject dobj
Definition: pg_dump.h:500
Oid castsource
Definition: pg_dump.h:501
Oid castfunc
Definition: pg_dump.h:503
DumpableObject dobj
Definition: pg_dump.h:191

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, res, selectDumpableCast(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getCollations()

CollInfo* getCollations ( Archive fout,
int *  numCollations 
)

Definition at line 6014 of file pg_dump.c.

6015 {
6016  PGresult *res;
6017  int ntups;
6018  int i;
6019  PQExpBuffer query;
6020  CollInfo *collinfo;
6021  int i_tableoid;
6022  int i_oid;
6023  int i_collname;
6024  int i_collnamespace;
6025  int i_collowner;
6026 
6027  query = createPQExpBuffer();
6028 
6029  /*
6030  * find all collations, including builtin collations; we filter out
6031  * system-defined collations at dump-out time.
6032  */
6033 
6034  appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6035  "collnamespace, "
6036  "collowner "
6037  "FROM pg_collation");
6038 
6039  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6040 
6041  ntups = PQntuples(res);
6042  *numCollations = ntups;
6043 
6044  collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6045 
6046  i_tableoid = PQfnumber(res, "tableoid");
6047  i_oid = PQfnumber(res, "oid");
6048  i_collname = PQfnumber(res, "collname");
6049  i_collnamespace = PQfnumber(res, "collnamespace");
6050  i_collowner = PQfnumber(res, "collowner");
6051 
6052  for (i = 0; i < ntups; i++)
6053  {
6054  collinfo[i].dobj.objType = DO_COLLATION;
6055  collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6056  collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6057  AssignDumpId(&collinfo[i].dobj);
6058  collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6059  collinfo[i].dobj.namespace =
6060  findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6061  collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6062 
6063  /* Decide whether we want to dump it */
6064  selectDumpableObject(&(collinfo[i].dobj), fout);
6065  }
6066 
6067  PQclear(res);
6068 
6069  destroyPQExpBuffer(query);
6070 
6071  return collinfo;
6072 }
const char * rolname
Definition: pg_dump.h:271
DumpableObject dobj
Definition: pg_dump.h:270

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

Referenced by getSchemaData().

◆ getConstraints()

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

Definition at line 7725 of file pg_dump.c.

7726 {
7727  PQExpBuffer query = createPQExpBuffer();
7728  PQExpBuffer tbloids = createPQExpBuffer();
7729  PGresult *res;
7730  int ntups;
7731  int curtblindx;
7732  TableInfo *tbinfo = NULL;
7733  ConstraintInfo *constrinfo;
7734  int i_contableoid,
7735  i_conoid,
7736  i_conrelid,
7737  i_conname,
7738  i_confrelid,
7739  i_conindid,
7740  i_condef;
7741 
7742  /*
7743  * We want to perform just one query against pg_constraint. However, we
7744  * mustn't try to select every row of the catalog and then sort it out on
7745  * the client side, because some of the server-side functions we need
7746  * would be unsafe to apply to tables we don't have lock on. Hence, we
7747  * build an array of the OIDs of tables we care about (and now have lock
7748  * on!), and use a WHERE clause to constrain which rows are selected.
7749  */
7750  appendPQExpBufferChar(tbloids, '{');
7751  for (int i = 0; i < numTables; i++)
7752  {
7753  TableInfo *tinfo = &tblinfo[i];
7754 
7755  /*
7756  * For partitioned tables, foreign keys have no triggers so they must
7757  * be included anyway in case some foreign keys are defined.
7758  */
7759  if ((!tinfo->hastriggers &&
7760  tinfo->relkind != RELKIND_PARTITIONED_TABLE) ||
7761  !(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
7762  continue;
7763 
7764  /* OK, we need info for this table */
7765  if (tbloids->len > 1) /* do we have more than the '{'? */
7766  appendPQExpBufferChar(tbloids, ',');
7767  appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
7768  }
7769  appendPQExpBufferChar(tbloids, '}');
7770 
7771  appendPQExpBufferStr(query,
7772  "SELECT c.tableoid, c.oid, "
7773  "conrelid, conname, confrelid, ");
7774  if (fout->remoteVersion >= 110000)
7775  appendPQExpBufferStr(query, "conindid, ");
7776  else
7777  appendPQExpBufferStr(query, "0 AS conindid, ");
7778  appendPQExpBuffer(query,
7779  "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
7780  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7781  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
7782  "WHERE contype = 'f' ",
7783  tbloids->data);
7784  if (fout->remoteVersion >= 110000)
7785  appendPQExpBufferStr(query,
7786  "AND conparentid = 0 ");
7787  appendPQExpBufferStr(query,
7788  "ORDER BY conrelid, conname");
7789 
7790  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7791 
7792  ntups = PQntuples(res);
7793 
7794  i_contableoid = PQfnumber(res, "tableoid");
7795  i_conoid = PQfnumber(res, "oid");
7796  i_conrelid = PQfnumber(res, "conrelid");
7797  i_conname = PQfnumber(res, "conname");
7798  i_confrelid = PQfnumber(res, "confrelid");
7799  i_conindid = PQfnumber(res, "conindid");
7800  i_condef = PQfnumber(res, "condef");
7801 
7802  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
7803 
7804  curtblindx = -1;
7805  for (int j = 0; j < ntups; j++)
7806  {
7807  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
7808  TableInfo *reftable;
7809 
7810  /*
7811  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7812  * order.
7813  */
7814  if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
7815  {
7816  while (++curtblindx < numTables)
7817  {
7818  tbinfo = &tblinfo[curtblindx];
7819  if (tbinfo->dobj.catId.oid == conrelid)
7820  break;
7821  }
7822  if (curtblindx >= numTables)
7823  pg_fatal("unrecognized table OID %u", conrelid);
7824  }
7825 
7826  constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
7827  constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7828  constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7829  AssignDumpId(&constrinfo[j].dobj);
7830  constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7831  constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7832  constrinfo[j].contable = tbinfo;
7833  constrinfo[j].condomain = NULL;
7834  constrinfo[j].contype = 'f';
7835  constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
7836  constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
7837  constrinfo[j].conindex = 0;
7838  constrinfo[j].condeferrable = false;
7839  constrinfo[j].condeferred = false;
7840  constrinfo[j].conislocal = true;
7841  constrinfo[j].separate = true;
7842 
7843  /*
7844  * Restoring an FK that points to a partitioned table requires that
7845  * all partition indexes have been attached beforehand. Ensure that
7846  * happens by making the constraint depend on each index partition
7847  * attach object.
7848  */
7849  reftable = findTableByOid(constrinfo[j].confrelid);
7850  if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
7851  {
7852  Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
7853 
7854  if (indexOid != InvalidOid)
7855  {
7856  for (int k = 0; k < reftable->numIndexes; k++)
7857  {
7858  IndxInfo *refidx;
7859 
7860  /* not our index? */
7861  if (reftable->indexes[k].dobj.catId.oid != indexOid)
7862  continue;
7863 
7864  refidx = &reftable->indexes[k];
7865  addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
7866  break;
7867  }
7868  }
7869  }
7870  }
7871 
7872  PQclear(res);
7873 
7874  destroyPQExpBuffer(query);
7875  destroyPQExpBuffer(tbloids);
7876 }
TableInfo * findTableByOid(Oid oid)
Definition: common.c:854
static const gbtree_vinfo tinfo
Definition: btree_bit.c:109
int j
Definition: isn.c:74
#define pg_fatal(...)
static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
Definition: pg_dump.c:7890
TypeInfo * condomain
Definition: pg_dump.h:475
TableInfo * contable
Definition: pg_dump.h:474
bool condeferred
Definition: pg_dump.h:481
bool conislocal
Definition: pg_dump.h:483
DumpableObject dobj
Definition: pg_dump.h:473
DumpId conindex
Definition: pg_dump.h:479
bool condeferrable
Definition: pg_dump.h:480
char * condef
Definition: pg_dump.h:477
DumpableObject dobj
Definition: pg_dump.h:396
struct _indxInfo * indexes
Definition: pg_dump.h:365
DumpableObject dobj
Definition: pg_dump.h:285
char relkind
Definition: pg_dump.h:288
int numIndexes
Definition: pg_dump.h:364

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, res, _constraintInfo::separate, CatalogId::tableoid, and tinfo.

Referenced by getSchemaData().

◆ getConversions()

ConvInfo* getConversions ( Archive fout,
int *  numConversions 
)

Definition at line 6082 of file pg_dump.c.

6083 {
6084  PGresult *res;
6085  int ntups;
6086  int i;
6087  PQExpBuffer query;
6088  ConvInfo *convinfo;
6089  int i_tableoid;
6090  int i_oid;
6091  int i_conname;
6092  int i_connamespace;
6093  int i_conowner;
6094 
6095  query = createPQExpBuffer();
6096 
6097  /*
6098  * find all conversions, including builtin conversions; we filter out
6099  * system-defined conversions at dump-out time.
6100  */
6101 
6102  appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6103  "connamespace, "
6104  "conowner "
6105  "FROM pg_conversion");
6106 
6107  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6108 
6109  ntups = PQntuples(res);
6110  *numConversions = ntups;
6111 
6112  convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6113 
6114  i_tableoid = PQfnumber(res, "tableoid");
6115  i_oid = PQfnumber(res, "oid");
6116  i_conname = PQfnumber(res, "conname");
6117  i_connamespace = PQfnumber(res, "connamespace");
6118  i_conowner = PQfnumber(res, "conowner");
6119 
6120  for (i = 0; i < ntups; i++)
6121  {
6122  convinfo[i].dobj.objType = DO_CONVERSION;
6123  convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6124  convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6125  AssignDumpId(&convinfo[i].dobj);
6126  convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6127  convinfo[i].dobj.namespace =
6128  findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6129  convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6130 
6131  /* Decide whether we want to dump it */
6132  selectDumpableObject(&(convinfo[i].dobj), fout);
6133  }
6134 
6135  PQclear(res);
6136 
6137  destroyPQExpBuffer(query);
6138 
6139  return convinfo;
6140 }
DumpableObject dobj
Definition: pg_dump.h:276
const char * rolname
Definition: pg_dump.h:277

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(), res, _convInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getDefaultACLs()

DefaultACLInfo* getDefaultACLs ( Archive fout,
int *  numDefaultACLs 
)

Definition at line 9924 of file pg_dump.c.

9925 {
9926  DumpOptions *dopt = fout->dopt;
9927  DefaultACLInfo *daclinfo;
9928  PQExpBuffer query;
9929  PGresult *res;
9930  int i_oid;
9931  int i_tableoid;
9932  int i_defaclrole;
9933  int i_defaclnamespace;
9934  int i_defaclobjtype;
9935  int i_defaclacl;
9936  int i_acldefault;
9937  int i,
9938  ntups;
9939 
9940  query = createPQExpBuffer();
9941 
9942  /*
9943  * Global entries (with defaclnamespace=0) replace the hard-wired default
9944  * ACL for their object type. We should dump them as deltas from the
9945  * default ACL, since that will be used as a starting point for
9946  * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
9947  * non-global entries can only add privileges not revoke them. We must
9948  * dump those as-is (i.e., as deltas from an empty ACL).
9949  *
9950  * We can use defaclobjtype as the object type for acldefault(), except
9951  * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
9952  * 's'.
9953  */
9954  appendPQExpBufferStr(query,
9955  "SELECT oid, tableoid, "
9956  "defaclrole, "
9957  "defaclnamespace, "
9958  "defaclobjtype, "
9959  "defaclacl, "
9960  "CASE WHEN defaclnamespace = 0 THEN "
9961  "acldefault(CASE WHEN defaclobjtype = 'S' "
9962  "THEN 's'::\"char\" ELSE defaclobjtype END, "
9963  "defaclrole) ELSE '{}' END AS acldefault "
9964  "FROM pg_default_acl");
9965 
9966  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9967 
9968  ntups = PQntuples(res);
9969  *numDefaultACLs = ntups;
9970 
9971  daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
9972 
9973  i_oid = PQfnumber(res, "oid");
9974  i_tableoid = PQfnumber(res, "tableoid");
9975  i_defaclrole = PQfnumber(res, "defaclrole");
9976  i_defaclnamespace = PQfnumber(res, "defaclnamespace");
9977  i_defaclobjtype = PQfnumber(res, "defaclobjtype");
9978  i_defaclacl = PQfnumber(res, "defaclacl");
9979  i_acldefault = PQfnumber(res, "acldefault");
9980 
9981  for (i = 0; i < ntups; i++)
9982  {
9983  Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
9984 
9985  daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
9986  daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9987  daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9988  AssignDumpId(&daclinfo[i].dobj);
9989  /* cheesy ... is it worth coming up with a better object name? */
9990  daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
9991 
9992  if (nspid != InvalidOid)
9993  daclinfo[i].dobj.namespace = findNamespace(nspid);
9994  else
9995  daclinfo[i].dobj.namespace = NULL;
9996 
9997  daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9998  daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9999  daclinfo[i].dacl.privtype = 0;
10000  daclinfo[i].dacl.initprivs = NULL;
10001  daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
10002  daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
10003 
10004  /* Default ACLs are ACLs, of course */
10005  daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
10006 
10007  /* Decide whether we want to dump it */
10008  selectDumpableDefaultACL(&(daclinfo[i]), dopt);
10009  }
10010 
10011  PQclear(res);
10012 
10013  destroyPQExpBuffer(query);
10014 
10015  return daclinfo;
10016 }
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:1923
DumpableObject dobj
Definition: pg_dump.h:579
DumpableAcl dacl
Definition: pg_dump.h:580
const char * defaclrole
Definition: pg_dump.h:581
char defaclobjtype
Definition: pg_dump.h:582
char privtype
Definition: pg_dump.h:159
char * acldefault
Definition: pg_dump.h:157
char * acl
Definition: pg_dump.h:156
char * initprivs
Definition: pg_dump.h:160

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, res, selectDumpableDefaultACL(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getDumpableObjects()

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

Definition at line 788 of file common.c.

789 {
790  int i,
791  j;
792 
794  j = 0;
795  for (i = 1; i < allocedDumpIds; i++)
796  {
797  if (dumpIdMap[i])
798  (*objs)[j++] = dumpIdMap[i];
799  }
800  *numObjs = j;
801 }

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

Referenced by getTableDataFKConstraints(), and main().

◆ getEventTriggers()

EventTriggerInfo* getEventTriggers ( Archive fout,
int *  numEventTriggers 
)

Definition at line 8302 of file pg_dump.c.

8303 {
8304  int i;
8305  PQExpBuffer query;
8306  PGresult *res;
8307  EventTriggerInfo *evtinfo;
8308  int i_tableoid,
8309  i_oid,
8310  i_evtname,
8311  i_evtevent,
8312  i_evtowner,
8313  i_evttags,
8314  i_evtfname,
8315  i_evtenabled;
8316  int ntups;
8317 
8318  /* Before 9.3, there are no event triggers */
8319  if (fout->remoteVersion < 90300)
8320  {
8321  *numEventTriggers = 0;
8322  return NULL;
8323  }
8324 
8325  query = createPQExpBuffer();
8326 
8327  appendPQExpBufferStr(query,
8328  "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8329  "evtevent, evtowner, "
8330  "array_to_string(array("
8331  "select quote_literal(x) "
8332  " from unnest(evttags) as t(x)), ', ') as evttags, "
8333  "e.evtfoid::regproc as evtfname "
8334  "FROM pg_event_trigger e "
8335  "ORDER BY e.oid");
8336 
8337  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8338 
8339  ntups = PQntuples(res);
8340 
8341  *numEventTriggers = ntups;
8342 
8343  evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8344 
8345  i_tableoid = PQfnumber(res, "tableoid");
8346  i_oid = PQfnumber(res, "oid");
8347  i_evtname = PQfnumber(res, "evtname");
8348  i_evtevent = PQfnumber(res, "evtevent");
8349  i_evtowner = PQfnumber(res, "evtowner");
8350  i_evttags = PQfnumber(res, "evttags");
8351  i_evtfname = PQfnumber(res, "evtfname");
8352  i_evtenabled = PQfnumber(res, "evtenabled");
8353 
8354  for (i = 0; i < ntups; i++)
8355  {
8356  evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8357  evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8358  evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8359  AssignDumpId(&evtinfo[i].dobj);
8360  evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8361  evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8362  evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8363  evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8364  evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8365  evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8366  evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8367 
8368  /* Decide whether we want to dump it */
8369  selectDumpableObject(&(evtinfo[i].dobj), fout);
8370  }
8371 
8372  PQclear(res);
8373 
8374  destroyPQExpBuffer(query);
8375 
8376  return evtinfo;
8377 }
char * evtevent
Definition: pg_dump.h:456
char * evtfname
Definition: pg_dump.h:459
char evtenabled
Definition: pg_dump.h:460
char * evtname
Definition: pg_dump.h:455
const char * evtowner
Definition: pg_dump.h:457
char * evttags
Definition: pg_dump.h:458
DumpableObject dobj
Definition: pg_dump.h:454

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, res, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtendedStatistics()

void getExtendedStatistics ( Archive fout)

Definition at line 7646 of file pg_dump.c.

7647 {
7648  PQExpBuffer query;
7649  PGresult *res;
7650  StatsExtInfo *statsextinfo;
7651  int ntups;
7652  int i_tableoid;
7653  int i_oid;
7654  int i_stxname;
7655  int i_stxnamespace;
7656  int i_stxowner;
7657  int i_stxrelid;
7658  int i_stattarget;
7659  int i;
7660 
7661  /* Extended statistics were new in v10 */
7662  if (fout->remoteVersion < 100000)
7663  return;
7664 
7665  query = createPQExpBuffer();
7666 
7667  if (fout->remoteVersion < 130000)
7668  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7669  "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
7670  "FROM pg_catalog.pg_statistic_ext");
7671  else
7672  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7673  "stxnamespace, stxowner, stxrelid, stxstattarget "
7674  "FROM pg_catalog.pg_statistic_ext");
7675 
7676  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7677 
7678  ntups = PQntuples(res);
7679 
7680  i_tableoid = PQfnumber(res, "tableoid");
7681  i_oid = PQfnumber(res, "oid");
7682  i_stxname = PQfnumber(res, "stxname");
7683  i_stxnamespace = PQfnumber(res, "stxnamespace");
7684  i_stxowner = PQfnumber(res, "stxowner");
7685  i_stxrelid = PQfnumber(res, "stxrelid");
7686  i_stattarget = PQfnumber(res, "stxstattarget");
7687 
7688  statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
7689 
7690  for (i = 0; i < ntups; i++)
7691  {
7692  statsextinfo[i].dobj.objType = DO_STATSEXT;
7693  statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7694  statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7695  AssignDumpId(&statsextinfo[i].dobj);
7696  statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
7697  statsextinfo[i].dobj.namespace =
7698  findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
7699  statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
7700  statsextinfo[i].stattable =
7701  findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7702  if (PQgetisnull(res, i, i_stattarget))
7703  statsextinfo[i].stattarget = -1;
7704  else
7705  statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7706 
7707  /* Decide whether we want to dump it */
7708  selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
7709  }
7710 
7711  PQclear(res);
7712  destroyPQExpBuffer(query);
7713 }
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2088
TableInfo * stattable
Definition: pg_dump.h:428
int stattarget
Definition: pg_dump.h:429
const char * rolname
Definition: pg_dump.h:427
DumpableObject dobj
Definition: pg_dump.h:426

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, res, _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 18249 of file pg_dump.c.

18251 {
18252  PQExpBuffer query;
18253  PGresult *res;
18254  int ntups,
18255  i;
18256  int i_classid,
18257  i_objid,
18258  i_refobjid;
18259  ExtensionInfo *ext;
18260 
18261  /* Nothing to do if no extensions */
18262  if (numExtensions == 0)
18263  return;
18264 
18265  query = createPQExpBuffer();
18266 
18267  /* refclassid constraint is redundant but may speed the search */
18268  appendPQExpBufferStr(query, "SELECT "
18269  "classid, objid, refobjid "
18270  "FROM pg_depend "
18271  "WHERE refclassid = 'pg_extension'::regclass "
18272  "AND deptype = 'e' "
18273  "ORDER BY 3");
18274 
18275  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18276 
18277  ntups = PQntuples(res);
18278 
18279  i_classid = PQfnumber(res, "classid");
18280  i_objid = PQfnumber(res, "objid");
18281  i_refobjid = PQfnumber(res, "refobjid");
18282 
18283  /*
18284  * Since we ordered the SELECT by referenced ID, we can expect that
18285  * multiple entries for the same extension will appear together; this
18286  * saves on searches.
18287  */
18288  ext = NULL;
18289 
18290  for (i = 0; i < ntups; i++)
18291  {
18292  CatalogId objId;
18293  Oid extId;
18294 
18295  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18296  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18297  extId = atooid(PQgetvalue(res, i, i_refobjid));
18298 
18299  if (ext == NULL ||
18300  ext->dobj.catId.oid != extId)
18301  ext = findExtensionByOid(extId);
18302 
18303  if (ext == NULL)
18304  {
18305  /* shouldn't happen */
18306  pg_log_warning("could not find referenced extension %u", extId);
18307  continue;
18308  }
18309 
18310  recordExtensionMembership(objId, ext);
18311  }
18312 
18313  PQclear(res);
18314 
18315  destroyPQExpBuffer(query);
18316 }
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1036
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:981
#define pg_log_warning(...)
Definition: pgfnames.c:24
DumpableObject dobj
Definition: pg_dump.h:181

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(), res, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getExtensions()

ExtensionInfo* getExtensions ( Archive fout,
int *  numExtensions 
)

Definition at line 5695 of file pg_dump.c.

5696 {
5697  DumpOptions *dopt = fout->dopt;
5698  PGresult *res;
5699  int ntups;
5700  int i;
5701  PQExpBuffer query;
5702  ExtensionInfo *extinfo;
5703  int i_tableoid;
5704  int i_oid;
5705  int i_extname;
5706  int i_nspname;
5707  int i_extrelocatable;
5708  int i_extversion;
5709  int i_extconfig;
5710  int i_extcondition;
5711 
5712  query = createPQExpBuffer();
5713 
5714  appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5715  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5716  "FROM pg_extension x "
5717  "JOIN pg_namespace n ON n.oid = x.extnamespace");
5718 
5719  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5720 
5721  ntups = PQntuples(res);
5722 
5723  extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5724 
5725  i_tableoid = PQfnumber(res, "tableoid");
5726  i_oid = PQfnumber(res, "oid");
5727  i_extname = PQfnumber(res, "extname");
5728  i_nspname = PQfnumber(res, "nspname");
5729  i_extrelocatable = PQfnumber(res, "extrelocatable");
5730  i_extversion = PQfnumber(res, "extversion");
5731  i_extconfig = PQfnumber(res, "extconfig");
5732  i_extcondition = PQfnumber(res, "extcondition");
5733 
5734  for (i = 0; i < ntups; i++)
5735  {
5736  extinfo[i].dobj.objType = DO_EXTENSION;
5737  extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5738  extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5739  AssignDumpId(&extinfo[i].dobj);
5740  extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5741  extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5742  extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5743  extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5744  extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5745  extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5746 
5747  /* Decide whether we want to dump it */
5748  selectDumpableExtension(&(extinfo[i]), dopt);
5749  }
5750 
5751  PQclear(res);
5752  destroyPQExpBuffer(query);
5753 
5754  *numExtensions = ntups;
5755 
5756  return extinfo;
5757 }
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2031
bool relocatable
Definition: pg_dump.h:182
char * extversion
Definition: pg_dump.h:184
char * extcondition
Definition: pg_dump.h:186
char * extconfig
Definition: pg_dump.h:185

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, 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, res, selectDumpableExtension(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignDataWrappers()

FdwInfo* getForeignDataWrappers ( Archive fout,
int *  numForeignDataWrappers 
)

Definition at line 9740 of file pg_dump.c.

9741 {
9742  PGresult *res;
9743  int ntups;
9744  int i;
9745  PQExpBuffer query;
9746  FdwInfo *fdwinfo;
9747  int i_tableoid;
9748  int i_oid;
9749  int i_fdwname;
9750  int i_fdwowner;
9751  int i_fdwhandler;
9752  int i_fdwvalidator;
9753  int i_fdwacl;
9754  int i_acldefault;
9755  int i_fdwoptions;
9756 
9757  query = createPQExpBuffer();
9758 
9759  appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
9760  "fdwowner, "
9761  "fdwhandler::pg_catalog.regproc, "
9762  "fdwvalidator::pg_catalog.regproc, "
9763  "fdwacl, "
9764  "acldefault('F', fdwowner) AS acldefault, "
9765  "array_to_string(ARRAY("
9766  "SELECT quote_ident(option_name) || ' ' || "
9767  "quote_literal(option_value) "
9768  "FROM pg_options_to_table(fdwoptions) "
9769  "ORDER BY option_name"
9770  "), E',\n ') AS fdwoptions "
9771  "FROM pg_foreign_data_wrapper");
9772 
9773  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9774 
9775  ntups = PQntuples(res);
9776  *numForeignDataWrappers = ntups;
9777 
9778  fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
9779 
9780  i_tableoid = PQfnumber(res, "tableoid");
9781  i_oid = PQfnumber(res, "oid");
9782  i_fdwname = PQfnumber(res, "fdwname");
9783  i_fdwowner = PQfnumber(res, "fdwowner");
9784  i_fdwhandler = PQfnumber(res, "fdwhandler");
9785  i_fdwvalidator = PQfnumber(res, "fdwvalidator");
9786  i_fdwacl = PQfnumber(res, "fdwacl");
9787  i_acldefault = PQfnumber(res, "acldefault");
9788  i_fdwoptions = PQfnumber(res, "fdwoptions");
9789 
9790  for (i = 0; i < ntups; i++)
9791  {
9792  fdwinfo[i].dobj.objType = DO_FDW;
9793  fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9794  fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9795  AssignDumpId(&fdwinfo[i].dobj);
9796  fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
9797  fdwinfo[i].dobj.namespace = NULL;
9798  fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
9799  fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9800  fdwinfo[i].dacl.privtype = 0;
9801  fdwinfo[i].dacl.initprivs = NULL;
9802  fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
9803  fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
9804  fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
9805  fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
9806 
9807  /* Decide whether we want to dump it */
9808  selectDumpableObject(&(fdwinfo[i].dobj), fout);
9809 
9810  /* Mark whether FDW has an ACL */
9811  if (!PQgetisnull(res, i, i_fdwacl))
9812  fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9813  }
9814 
9815  PQclear(res);
9816 
9817  destroyPQExpBuffer(query);
9818 
9819  return fdwinfo;
9820 }
char * fdwhandler
Definition: pg_dump.h:561
const char * rolname
Definition: pg_dump.h:560
char * fdwvalidator
Definition: pg_dump.h:562
char * fdwoptions
Definition: pg_dump.h:563
DumpableAcl dacl
Definition: pg_dump.h:559
DumpableObject dobj
Definition: pg_dump.h:558

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, res, _fdwInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignServers()

ForeignServerInfo* getForeignServers ( Archive fout,
int *  numForeignServers 
)

Definition at line 9830 of file pg_dump.c.

9831 {
9832  PGresult *res;
9833  int ntups;
9834  int i;
9835  PQExpBuffer query;
9836  ForeignServerInfo *srvinfo;
9837  int i_tableoid;
9838  int i_oid;
9839  int i_srvname;
9840  int i_srvowner;
9841  int i_srvfdw;
9842  int i_srvtype;
9843  int i_srvversion;
9844  int i_srvacl;
9845  int i_acldefault;
9846  int i_srvoptions;
9847 
9848  query = createPQExpBuffer();
9849 
9850  appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
9851  "srvowner, "
9852  "srvfdw, srvtype, srvversion, srvacl, "
9853  "acldefault('S', srvowner) AS acldefault, "
9854  "array_to_string(ARRAY("
9855  "SELECT quote_ident(option_name) || ' ' || "
9856  "quote_literal(option_value) "
9857  "FROM pg_options_to_table(srvoptions) "
9858  "ORDER BY option_name"
9859  "), E',\n ') AS srvoptions "
9860  "FROM pg_foreign_server");
9861 
9862  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9863 
9864  ntups = PQntuples(res);
9865  *numForeignServers = ntups;
9866 
9867  srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
9868 
9869  i_tableoid = PQfnumber(res, "tableoid");
9870  i_oid = PQfnumber(res, "oid");
9871  i_srvname = PQfnumber(res, "srvname");
9872  i_srvowner = PQfnumber(res, "srvowner");
9873  i_srvfdw = PQfnumber(res, "srvfdw");
9874  i_srvtype = PQfnumber(res, "srvtype");
9875  i_srvversion = PQfnumber(res, "srvversion");
9876  i_srvacl = PQfnumber(res, "srvacl");
9877  i_acldefault = PQfnumber(res, "acldefault");
9878  i_srvoptions = PQfnumber(res, "srvoptions");
9879 
9880  for (i = 0; i < ntups; i++)
9881  {
9882  srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
9883  srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9884  srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9885  AssignDumpId(&srvinfo[i].dobj);
9886  srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
9887  srvinfo[i].dobj.namespace = NULL;
9888  srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
9889  srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9890  srvinfo[i].dacl.privtype = 0;
9891  srvinfo[i].dacl.initprivs = NULL;
9892  srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
9893  srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
9894  srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
9895  srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
9896  srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
9897 
9898  /* Decide whether we want to dump it */
9899  selectDumpableObject(&(srvinfo[i].dobj), fout);
9900 
9901  /* Servers have user mappings */
9903 
9904  /* Mark whether server has an ACL */
9905  if (!PQgetisnull(res, i, i_srvacl))
9906  srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9907  }
9908 
9909  PQclear(res);
9910 
9911  destroyPQExpBuffer(query);
9912 
9913  return srvinfo;
9914 }
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:103
DumpableAcl dacl
Definition: pg_dump.h:569
char * srvoptions
Definition: pg_dump.h:574
DumpableObject dobj
Definition: pg_dump.h:568
const char * rolname
Definition: pg_dump.h:570
char * srvversion
Definition: pg_dump.h:573

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, res, _foreignServerInfo::rolname, selectDumpableObject(), _foreignServerInfo::srvfdw, _foreignServerInfo::srvoptions, _foreignServerInfo::srvtype, _foreignServerInfo::srvversion, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getFuncs()

FuncInfo* getFuncs ( Archive fout,
int *  numFuncs 
)

Definition at line 6502 of file pg_dump.c.

6503 {
6504  DumpOptions *dopt = fout->dopt;
6505  PGresult *res;
6506  int ntups;
6507  int i;
6508  PQExpBuffer query = createPQExpBuffer();
6509  FuncInfo *finfo;
6510  int i_tableoid;
6511  int i_oid;
6512  int i_proname;
6513  int i_pronamespace;
6514  int i_proowner;
6515  int i_prolang;
6516  int i_pronargs;
6517  int i_proargtypes;
6518  int i_prorettype;
6519  int i_proacl;
6520  int i_acldefault;
6521 
6522  /*
6523  * Find all interesting functions. This is a bit complicated:
6524  *
6525  * 1. Always exclude aggregates; those are handled elsewhere.
6526  *
6527  * 2. Always exclude functions that are internally dependent on something
6528  * else, since presumably those will be created as a result of creating
6529  * the something else. This currently acts only to suppress constructor
6530  * functions for range types. Note this is OK only because the
6531  * constructors don't have any dependencies the range type doesn't have;
6532  * otherwise we might not get creation ordering correct.
6533  *
6534  * 3. Otherwise, we normally exclude functions in pg_catalog. However, if
6535  * they're members of extensions and we are in binary-upgrade mode then
6536  * include them, since we want to dump extension members individually in
6537  * that mode. Also, if they are used by casts or transforms then we need
6538  * to gather the information about them, though they won't be dumped if
6539  * they are built-in. Also, in 9.6 and up, include functions in
6540  * pg_catalog if they have an ACL different from what's shown in
6541  * pg_init_privs (so we have to join to pg_init_privs; annoying).
6542  */
6543  if (fout->remoteVersion >= 90600)
6544  {
6545  const char *not_agg_check;
6546 
6547  not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
6548  : "NOT p.proisagg");
6549 
6550  appendPQExpBuffer(query,
6551  "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
6552  "p.pronargs, p.proargtypes, p.prorettype, "
6553  "p.proacl, "
6554  "acldefault('f', p.proowner) AS acldefault, "
6555  "p.pronamespace, "
6556  "p.proowner "
6557  "FROM pg_proc p "
6558  "LEFT JOIN pg_init_privs pip ON "
6559  "(p.oid = pip.objoid "
6560  "AND pip.classoid = 'pg_proc'::regclass "
6561  "AND pip.objsubid = 0) "
6562  "WHERE %s"
6563  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6564  "WHERE classid = 'pg_proc'::regclass AND "
6565  "objid = p.oid AND deptype = 'i')"
6566  "\n AND ("
6567  "\n pronamespace != "
6568  "(SELECT oid FROM pg_namespace "
6569  "WHERE nspname = 'pg_catalog')"
6570  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6571  "\n WHERE pg_cast.oid > %u "
6572  "\n AND p.oid = pg_cast.castfunc)"
6573  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6574  "\n WHERE pg_transform.oid > %u AND "
6575  "\n (p.oid = pg_transform.trffromsql"
6576  "\n OR p.oid = pg_transform.trftosql))",
6577  not_agg_check,
6580  if (dopt->binary_upgrade)
6581  appendPQExpBufferStr(query,
6582  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6583  "classid = 'pg_proc'::regclass AND "
6584  "objid = p.oid AND "
6585  "refclassid = 'pg_extension'::regclass AND "
6586  "deptype = 'e')");
6587  appendPQExpBufferStr(query,
6588  "\n OR p.proacl IS DISTINCT FROM pip.initprivs");
6589  appendPQExpBufferChar(query, ')');
6590  }
6591  else
6592  {
6593  appendPQExpBuffer(query,
6594  "SELECT tableoid, oid, proname, prolang, "
6595  "pronargs, proargtypes, prorettype, proacl, "
6596  "acldefault('f', proowner) AS acldefault, "
6597  "pronamespace, "
6598  "proowner "
6599  "FROM pg_proc p "
6600  "WHERE NOT proisagg"
6601  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6602  "WHERE classid = 'pg_proc'::regclass AND "
6603  "objid = p.oid AND deptype = 'i')"
6604  "\n AND ("
6605  "\n pronamespace != "
6606  "(SELECT oid FROM pg_namespace "
6607  "WHERE nspname = 'pg_catalog')"
6608  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6609  "\n WHERE pg_cast.oid > '%u'::oid"
6610  "\n AND p.oid = pg_cast.castfunc)",
6612 
6613  if (fout->remoteVersion >= 90500)
6614  appendPQExpBuffer(query,
6615  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6616  "\n WHERE pg_transform.oid > '%u'::oid"
6617  "\n AND (p.oid = pg_transform.trffromsql"
6618  "\n OR p.oid = pg_transform.trftosql))",
6620 
6621  if (dopt->binary_upgrade)
6622  appendPQExpBufferStr(query,
6623  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6624  "classid = 'pg_proc'::regclass AND "
6625  "objid = p.oid AND "
6626  "refclassid = 'pg_extension'::regclass AND "
6627  "deptype = 'e')");
6628  appendPQExpBufferChar(query, ')');
6629  }
6630 
6631  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6632 
6633  ntups = PQntuples(res);
6634 
6635  *numFuncs = ntups;
6636 
6637  finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
6638 
6639  i_tableoid = PQfnumber(res, "tableoid");
6640  i_oid = PQfnumber(res, "oid");
6641  i_proname = PQfnumber(res, "proname");
6642  i_pronamespace = PQfnumber(res, "pronamespace");
6643  i_proowner = PQfnumber(res, "proowner");
6644  i_prolang = PQfnumber(res, "prolang");
6645  i_pronargs = PQfnumber(res, "pronargs");
6646  i_proargtypes = PQfnumber(res, "proargtypes");
6647  i_prorettype = PQfnumber(res, "prorettype");
6648  i_proacl = PQfnumber(res, "proacl");
6649  i_acldefault = PQfnumber(res, "acldefault");
6650 
6651  for (i = 0; i < ntups; i++)
6652  {
6653  finfo[i].dobj.objType = DO_FUNC;
6654  finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6655  finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6656  AssignDumpId(&finfo[i].dobj);
6657  finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
6658  finfo[i].dobj.namespace =
6659  findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
6660  finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
6661  finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6662  finfo[i].dacl.privtype = 0;
6663  finfo[i].dacl.initprivs = NULL;
6664  finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6665  finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
6666  finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
6667  finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
6668  if (finfo[i].nargs == 0)
6669  finfo[i].argtypes = NULL;
6670  else
6671  {
6672  finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
6673  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6674  finfo[i].argtypes, finfo[i].nargs);
6675  }
6676  finfo[i].postponed_def = false; /* might get set during sort */
6677 
6678  /* Decide whether we want to dump it */
6679  selectDumpableObject(&(finfo[i].dobj), fout);
6680 
6681  /* Mark whether function has an ACL */
6682  if (!PQgetisnull(res, i, i_proacl))
6683  finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
6684  }
6685 
6686  PQclear(res);
6687 
6688  destroyPQExpBuffer(query);
6689 
6690  return finfo;
6691 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static Oid g_last_builtin_oid
Definition: pg_dump.c:105
bool postponed_def
Definition: pg_dump.h:231
Oid lang
Definition: pg_dump.h:227
const char * rolname
Definition: pg_dump.h:226
Oid * argtypes
Definition: pg_dump.h:229
Oid prorettype
Definition: pg_dump.h:230
DumpableObject dobj
Definition: pg_dump.h:224
int nargs
Definition: pg_dump.h:228
DumpableAcl dacl
Definition: pg_dump.h:225

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, res, _funcInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getIndexes()

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

Definition at line 7326 of file pg_dump.c.

7327 {
7328  PQExpBuffer query = createPQExpBuffer();
7329  PQExpBuffer tbloids = createPQExpBuffer();
7330  PGresult *res;
7331  int ntups;
7332  int curtblindx;
7333  IndxInfo *indxinfo;
7334  int i_tableoid,
7335  i_oid,
7336  i_indrelid,
7337  i_indexname,
7338  i_parentidx,
7339  i_indexdef,
7340  i_indnkeyatts,
7341  i_indnatts,
7342  i_indkey,
7343  i_indisclustered,
7344  i_indisreplident,
7345  i_indnullsnotdistinct,
7346  i_contype,
7347  i_conname,
7348  i_condeferrable,
7349  i_condeferred,
7350  i_conperiod,
7351  i_contableoid,
7352  i_conoid,
7353  i_condef,
7354  i_tablespace,
7355  i_indreloptions,
7356  i_indstatcols,
7357  i_indstatvals;
7358 
7359  /*
7360  * We want to perform just one query against pg_index. However, we
7361  * mustn't try to select every row of the catalog and then sort it out on
7362  * the client side, because some of the server-side functions we need
7363  * would be unsafe to apply to tables we don't have lock on. Hence, we
7364  * build an array of the OIDs of tables we care about (and now have lock
7365  * on!), and use a WHERE clause to constrain which rows are selected.
7366  */
7367  appendPQExpBufferChar(tbloids, '{');
7368  for (int i = 0; i < numTables; i++)
7369  {
7370  TableInfo *tbinfo = &tblinfo[i];
7371 
7372  if (!tbinfo->hasindex)
7373  continue;
7374 
7375  /*
7376  * We can ignore indexes of uninteresting tables.
7377  */
7378  if (!tbinfo->interesting)
7379  continue;
7380 
7381  /* OK, we need info for this table */
7382  if (tbloids->len > 1) /* do we have more than the '{'? */
7383  appendPQExpBufferChar(tbloids, ',');
7384  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
7385  }
7386  appendPQExpBufferChar(tbloids, '}');
7387 
7388  appendPQExpBufferStr(query,
7389  "SELECT t.tableoid, t.oid, i.indrelid, "
7390  "t.relname AS indexname, "
7391  "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7392  "i.indkey, i.indisclustered, "
7393  "c.contype, c.conname, "
7394  "c.condeferrable, c.condeferred, "
7395  "c.tableoid AS contableoid, "
7396  "c.oid AS conoid, "
7397  "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
7398  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
7399  "t.reloptions AS indreloptions, ");
7400 
7401 
7402  if (fout->remoteVersion >= 90400)
7403  appendPQExpBufferStr(query,
7404  "i.indisreplident, ");
7405  else
7406  appendPQExpBufferStr(query,
7407  "false AS indisreplident, ");
7408 
7409  if (fout->remoteVersion >= 110000)
7410  appendPQExpBufferStr(query,
7411  "inh.inhparent AS parentidx, "
7412  "i.indnkeyatts AS indnkeyatts, "
7413  "i.indnatts AS indnatts, "
7414  "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
7415  " FROM pg_catalog.pg_attribute "
7416  " WHERE attrelid = i.indexrelid AND "
7417  " attstattarget >= 0) AS indstatcols, "
7418  "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
7419  " FROM pg_catalog.pg_attribute "
7420  " WHERE attrelid = i.indexrelid AND "
7421  " attstattarget >= 0) AS indstatvals, ");
7422  else
7423  appendPQExpBufferStr(query,
7424  "0 AS parentidx, "
7425  "i.indnatts AS indnkeyatts, "
7426  "i.indnatts AS indnatts, "
7427  "'' AS indstatcols, "
7428  "'' AS indstatvals, ");
7429 
7430  if (fout->remoteVersion >= 150000)
7431  appendPQExpBufferStr(query,
7432  "i.indnullsnotdistinct, ");
7433  else
7434  appendPQExpBufferStr(query,
7435  "false AS indnullsnotdistinct, ");
7436 
7437  if (fout->remoteVersion >= 170000)
7438  appendPQExpBufferStr(query,
7439  "c.conperiod ");
7440  else
7441  appendPQExpBufferStr(query,
7442  "NULL AS conperiod ");
7443 
7444  /*
7445  * The point of the messy-looking outer join is to find a constraint that
7446  * is related by an internal dependency link to the index. If we find one,
7447  * create a CONSTRAINT entry linked to the INDEX entry. We assume an
7448  * index won't have more than one internal dependency.
7449  *
7450  * Note: the check on conrelid is redundant, but useful because that
7451  * column is indexed while conindid is not.
7452  */
7453  if (fout->remoteVersion >= 110000)
7454  {
7455  appendPQExpBuffer(query,
7456  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7457  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7458  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7459  "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
7460  "LEFT JOIN pg_catalog.pg_constraint c "
7461  "ON (i.indrelid = c.conrelid AND "
7462  "i.indexrelid = c.conindid AND "
7463  "c.contype IN ('p','u','x')) "
7464  "LEFT JOIN pg_catalog.pg_inherits inh "
7465  "ON (inh.inhrelid = indexrelid) "
7466  "WHERE (i.indisvalid OR t2.relkind = 'p') "
7467  "AND i.indisready "
7468  "ORDER BY i.indrelid, indexname",
7469  tbloids->data);
7470  }
7471  else
7472  {
7473  /*
7474  * the test on indisready is necessary in 9.2, and harmless in
7475  * earlier/later versions
7476  */
7477  appendPQExpBuffer(query,
7478  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7479  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7480  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7481  "LEFT JOIN pg_catalog.pg_constraint c "
7482  "ON (i.indrelid = c.conrelid AND "
7483  "i.indexrelid = c.conindid AND "
7484  "c.contype IN ('p','u','x')) "
7485  "WHERE i.indisvalid AND i.indisready "
7486  "ORDER BY i.indrelid, indexname",
7487  tbloids->data);
7488  }
7489 
7490  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7491 
7492  ntups = PQntuples(res);
7493 
7494  i_tableoid = PQfnumber(res, "tableoid");
7495  i_oid = PQfnumber(res, "oid");
7496  i_indrelid = PQfnumber(res, "indrelid");
7497  i_indexname = PQfnumber(res, "indexname");
7498  i_parentidx = PQfnumber(res, "parentidx");
7499  i_indexdef = PQfnumber(res, "indexdef");
7500  i_indnkeyatts = PQfnumber(res, "indnkeyatts");
7501  i_indnatts = PQfnumber(res, "indnatts");
7502  i_indkey = PQfnumber(res, "indkey");
7503  i_indisclustered = PQfnumber(res, "indisclustered");
7504  i_indisreplident = PQfnumber(res, "indisreplident");
7505  i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
7506  i_contype = PQfnumber(res, "contype");
7507  i_conname = PQfnumber(res, "conname");
7508  i_condeferrable = PQfnumber(res, "condeferrable");
7509  i_condeferred = PQfnumber(res, "condeferred");
7510  i_conperiod = PQfnumber(res, "conperiod");
7511  i_contableoid = PQfnumber(res, "contableoid");
7512  i_conoid = PQfnumber(res, "conoid");
7513  i_condef = PQfnumber(res, "condef");
7514  i_tablespace = PQfnumber(res, "tablespace");
7515  i_indreloptions = PQfnumber(res, "indreloptions");
7516  i_indstatcols = PQfnumber(res, "indstatcols");
7517  i_indstatvals = PQfnumber(res, "indstatvals");
7518 
7519  indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
7520 
7521  /*
7522  * Outer loop iterates once per table, not once per row. Incrementing of
7523  * j is handled by the inner loop.
7524  */
7525  curtblindx = -1;
7526  for (int j = 0; j < ntups;)
7527  {
7528  Oid indrelid = atooid(PQgetvalue(res, j, i_indrelid));
7529  TableInfo *tbinfo = NULL;
7530  int numinds;
7531 
7532  /* Count rows for this table */
7533  for (numinds = 1; numinds < ntups - j; numinds++)
7534  if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
7535  break;
7536 
7537  /*
7538  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7539  * order.
7540  */
7541  while (++curtblindx < numTables)
7542  {
7543  tbinfo = &tblinfo[curtblindx];
7544  if (tbinfo->dobj.catId.oid == indrelid)
7545  break;
7546  }
7547  if (curtblindx >= numTables)
7548  pg_fatal("unrecognized table OID %u", indrelid);
7549  /* cross-check that we only got requested tables */
7550  if (!tbinfo->hasindex ||
7551  !tbinfo->interesting)
7552  pg_fatal("unexpected index data for table \"%s\"",
7553  tbinfo->dobj.name);
7554 
7555  /* Save data for this table */
7556  tbinfo->indexes = indxinfo + j;
7557  tbinfo->numIndexes = numinds;
7558 
7559  for (int c = 0; c < numinds; c++, j++)
7560  {
7561  char contype;
7562 
7563  indxinfo[j].dobj.objType = DO_INDEX;
7564  indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
7565  indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
7566  AssignDumpId(&indxinfo[j].dobj);
7567  indxinfo[j].dobj.dump = tbinfo->dobj.dump;
7568  indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
7569  indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7570  indxinfo[j].indextable = tbinfo;
7571  indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
7572  indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
7573  indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
7574  indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
7575  indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
7576  indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
7577  indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
7578  indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
7579  parseOidArray(PQgetvalue(res, j, i_indkey),
7580  indxinfo[j].indkeys, indxinfo[j].indnattrs);
7581  indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
7582  indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
7583  indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
7584  indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
7585  indxinfo[j].partattaches = (SimplePtrList)
7586  {
7587  NULL, NULL
7588  };
7589  contype = *(PQgetvalue(res, j, i_contype));
7590 
7591  if (contype == 'p' || contype == 'u' || contype == 'x')
7592  {
7593  /*
7594  * If we found a constraint matching the index, create an
7595  * entry for it.
7596  */
7597  ConstraintInfo *constrinfo;
7598 
7599  constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
7600  constrinfo->dobj.objType = DO_CONSTRAINT;
7601  constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7602  constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7603  AssignDumpId(&constrinfo->dobj);
7604  constrinfo->dobj.dump = tbinfo->dobj.dump;
7605  constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7606  constrinfo->dobj.namespace = tbinfo->dobj.namespace;
7607  constrinfo->contable = tbinfo;
7608  constrinfo->condomain = NULL;
7609  constrinfo->contype = contype;
7610  if (contype == 'x')
7611  constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
7612  else
7613  constrinfo->condef = NULL;
7614  constrinfo->confrelid = InvalidOid;
7615  constrinfo->conindex = indxinfo[j].dobj.dumpId;
7616  constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
7617  constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
7618  constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
7619  constrinfo->conislocal = true;
7620  constrinfo->separate = true;
7621 
7622  indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
7623  }
7624  else
7625  {
7626  /* Plain secondary index */
7627  indxinfo[j].indexconstraint = 0;
7628  }
7629  }
7630  }
7631 
7632  PQclear(res);
7633 
7634  destroyPQExpBuffer(query);
7635  destroyPQExpBuffer(tbloids);
7636 }
char * c
struct SimplePtrList SimplePtrList
bool conperiod
Definition: pg_dump.h:482
bool indisreplident
Definition: pg_dump.h:408
int indnkeyattrs
Definition: pg_dump.h:403
char * indstatvals
Definition: pg_dump.h:402
char * indstatcols
Definition: pg_dump.h:401
int indnattrs
Definition: pg_dump.h:404
TableInfo * indextable
Definition: pg_dump.h:397
Oid parentidx
Definition: pg_dump.h:410
Oid * indkeys
Definition: pg_dump.h:405
char * indreloptions
Definition: pg_dump.h:400
DumpId indexconstraint
Definition: pg_dump.h:414
bool indisclustered
Definition: pg_dump.h:407
SimplePtrList partattaches
Definition: pg_dump.h:411
char * tablespace
Definition: pg_dump.h:399
bool indnullsnotdistinct
Definition: pg_dump.h:409
char * indexdef
Definition: pg_dump.h:398
bool interesting
Definition: pg_dump.h:319
bool hasindex
Definition: pg_dump.h:296

References 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, _constraintInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), _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(), _indxInfo::partattaches, pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _constraintInfo::separate, CatalogId::tableoid, and _indxInfo::tablespace.

Referenced by getSchemaData().

◆ getInherits()

InhInfo* getInherits ( Archive fout,
int *  numInherits 
)

Definition at line 7210 of file pg_dump.c.

7211 {
7212  PGresult *res;
7213  int ntups;
7214  int i;
7215  PQExpBuffer query = createPQExpBuffer();
7216  InhInfo *inhinfo;
7217 
7218  int i_inhrelid;
7219  int i_inhparent;
7220 
7221  /* find all the inheritance information */
7222  appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7223 
7224  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7225 
7226  ntups = PQntuples(res);
7227 
7228  *numInherits = ntups;
7229 
7230  inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7231 
7232  i_inhrelid = PQfnumber(res, "inhrelid");
7233  i_inhparent = PQfnumber(res, "inhparent");
7234 
7235  for (i = 0; i < ntups; i++)
7236  {
7237  inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7238  inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7239  }
7240 
7241  PQclear(res);
7242 
7243  destroyPQExpBuffer(query);
7244 
7245  return inhinfo;
7246 }
Oid inhparent
Definition: pg_dump.h:521
Oid inhrelid
Definition: pg_dump.h:520

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

Referenced by getSchemaData().

◆ getMaxDumpId()

DumpId getMaxDumpId ( void  )

Definition at line 745 of file common.c.

746 {
747  return lastDumpId;
748 }

References lastDumpId.

Referenced by findDependencyLoops(), and TopoSort().

◆ getNamespaces()

NamespaceInfo* getNamespaces ( Archive fout,
int *  numNamespaces 
)

Definition at line 5559 of file pg_dump.c.

5560 {
5561  PGresult *res;
5562  int ntups;
5563  int i;
5564  PQExpBuffer query;
5565  NamespaceInfo *nsinfo;
5566  int i_tableoid;
5567  int i_oid;
5568  int i_nspname;
5569  int i_nspowner;
5570  int i_nspacl;
5571  int i_acldefault;
5572 
5573  query = createPQExpBuffer();
5574 
5575  /*
5576  * we fetch all namespaces including system ones, so that every object we
5577  * read in can be linked to a containing namespace.
5578  */
5579  appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5580  "n.nspowner, "
5581  "n.nspacl, "
5582  "acldefault('n', n.nspowner) AS acldefault "
5583  "FROM pg_namespace n");
5584 
5585  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5586 
5587  ntups = PQntuples(res);
5588 
5589  nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5590 
5591  i_tableoid = PQfnumber(res, "tableoid");
5592  i_oid = PQfnumber(res, "oid");
5593  i_nspname = PQfnumber(res, "nspname");
5594  i_nspowner = PQfnumber(res, "nspowner");
5595  i_nspacl = PQfnumber(res, "nspacl");
5596  i_acldefault = PQfnumber(res, "acldefault");
5597 
5598  for (i = 0; i < ntups; i++)
5599  {
5600  const char *nspowner;
5601 
5602  nsinfo[i].dobj.objType = DO_NAMESPACE;
5603  nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5604  nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5605  AssignDumpId(&nsinfo[i].dobj);
5606  nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5607  nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5608  nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5609  nsinfo[i].dacl.privtype = 0;
5610  nsinfo[i].dacl.initprivs = NULL;
5611  nspowner = PQgetvalue(res, i, i_nspowner);
5612  nsinfo[i].nspowner = atooid(nspowner);
5613  nsinfo[i].rolname = getRoleName(nspowner);
5614 
5615  /* Decide whether to dump this namespace */
5616  selectDumpableNamespace(&nsinfo[i], fout);
5617 
5618  /* Mark whether namespace has an ACL */
5619  if (!PQgetisnull(res, i, i_nspacl))
5620  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5621 
5622  /*
5623  * We ignore any pg_init_privs.initprivs entry for the public schema
5624  * and assume a predetermined default, for several reasons. First,
5625  * dropping and recreating the schema removes its pg_init_privs entry,
5626  * but an empty destination database starts with this ACL nonetheless.
5627  * Second, we support dump/reload of public schema ownership changes.
5628  * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5629  * initprivs continues to reflect the initial owner. Hence,
5630  * synthesize the value that nspacl will have after the restore's
5631  * ALTER SCHEMA OWNER. Third, this makes the destination database
5632  * match the source's ACL, even if the latter was an initdb-default
5633  * ACL, which changed in v15. An upgrade pulls in changes to most
5634  * system object ACLs that the DBA had not customized. We've made the
5635  * public schema depart from that, because changing its ACL so easily
5636  * breaks applications.
5637  */
5638  if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5639  {
5640  PQExpBuffer aclarray = createPQExpBuffer();
5641  PQExpBuffer aclitem = createPQExpBuffer();
5642 
5643  /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5644  appendPQExpBufferChar(aclarray, '{');
5645  quoteAclUserName(aclitem, nsinfo[i].rolname);
5646  appendPQExpBufferStr(aclitem, "=UC/");
5647  quoteAclUserName(aclitem, nsinfo[i].rolname);
5648  appendPGArray(aclarray, aclitem->data);
5649  resetPQExpBuffer(aclitem);
5650  appendPQExpBufferStr(aclitem, "=U/");
5651  quoteAclUserName(aclitem, nsinfo[i].rolname);
5652  appendPGArray(aclarray, aclitem->data);
5653  appendPQExpBufferChar(aclarray, '}');
5654 
5655  nsinfo[i].dacl.privtype = 'i';
5656  nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5657  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5658 
5659  destroyPQExpBuffer(aclarray);
5660  destroyPQExpBuffer(aclitem);
5661  }
5662  }
5663 
5664  PQclear(res);
5665  destroyPQExpBuffer(query);
5666 
5667  *numNamespaces = ntups;
5668 
5669  return nsinfo;
5670 }
void quoteAclUserName(PQExpBuffer output, const char *input)
Definition: dumputils.c:544
char * pstrdup(const char *in)
Definition: mcxt.c:1695
NameData rolname
Definition: pg_authid.h:34
static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
Definition: pg_dump.c:1753
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPGArray(PQExpBuffer buffer, const char *value)
Definition: string_utils.c:740
DumpableObject dobj
Definition: pg_dump.h:172
DumpableAcl dacl
Definition: pg_dump.h:173
const char * rolname
Definition: pg_dump.h:176

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(), res, resetPQExpBuffer(), _namespaceInfo::rolname, rolname, selectDumpableNamespace(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getOpclasses()

OpclassInfo* getOpclasses ( Archive fout,
int *  numOpclasses 
)

Definition at line 6221 of file pg_dump.c.

6222 {
6223  PGresult *res;
6224  int ntups;
6225  int i;
6226  PQExpBuffer query = createPQExpBuffer();
6227  OpclassInfo *opcinfo;
6228  int i_tableoid;
6229  int i_oid;
6230  int i_opcname;
6231  int i_opcnamespace;
6232  int i_opcowner;
6233 
6234  /*
6235  * find all opclasses, including builtin opclasses; we filter out
6236  * system-defined opclasses at dump-out time.
6237  */
6238 
6239  appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
6240  "opcnamespace, "
6241  "opcowner "
6242  "FROM pg_opclass");
6243 
6244  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6245 
6246  ntups = PQntuples(res);
6247  *numOpclasses = ntups;
6248 
6249  opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6250 
6251  i_tableoid = PQfnumber(res, "tableoid");
6252  i_oid = PQfnumber(res, "oid");
6253  i_opcname = PQfnumber(res, "opcname");
6254  i_opcnamespace = PQfnumber(res, "opcnamespace");
6255  i_opcowner = PQfnumber(res, "opcowner");
6256 
6257  for (i = 0; i < ntups; i++)
6258  {
6259  opcinfo[i].dobj.objType = DO_OPCLASS;
6260  opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6261  opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6262  AssignDumpId(&opcinfo[i].dobj);
6263  opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6264  opcinfo[i].dobj.namespace =
6265  findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6266  opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6267 
6268  /* Decide whether we want to dump it */
6269  selectDumpableObject(&(opcinfo[i].dobj), fout);
6270  }
6271 
6272  PQclear(res);
6273 
6274  destroyPQExpBuffer(query);
6275 
6276  return opcinfo;
6277 }
DumpableObject dobj
Definition: pg_dump.h:258
const char * rolname
Definition: pg_dump.h:259

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

Referenced by getSchemaData().

◆ getOperators()

OprInfo* getOperators ( Archive fout,
int *  numOprs 
)

Definition at line 5940 of file pg_dump.c.

5941 {
5942  PGresult *res;
5943  int ntups;
5944  int i;
5945  PQExpBuffer query = createPQExpBuffer();
5946  OprInfo *oprinfo;
5947  int i_tableoid;
5948  int i_oid;
5949  int i_oprname;
5950  int i_oprnamespace;
5951  int i_oprowner;
5952  int i_oprkind;
5953  int i_oprcode;
5954 
5955  /*
5956  * find all operators, including builtin operators; we filter out
5957  * system-defined operators at dump-out time.
5958  */
5959 
5960  appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
5961  "oprnamespace, "
5962  "oprowner, "
5963  "oprkind, "
5964  "oprcode::oid AS oprcode "
5965  "FROM pg_operator");
5966 
5967  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5968 
5969  ntups = PQntuples(res);
5970  *numOprs = ntups;
5971 
5972  oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
5973 
5974  i_tableoid = PQfnumber(res, "tableoid");
5975  i_oid = PQfnumber(res, "oid");
5976  i_oprname = PQfnumber(res, "oprname");
5977  i_oprnamespace = PQfnumber(res, "oprnamespace");
5978  i_oprowner = PQfnumber(res, "oprowner");
5979  i_oprkind = PQfnumber(res, "oprkind");
5980  i_oprcode = PQfnumber(res, "oprcode");
5981 
5982  for (i = 0; i < ntups; i++)
5983  {
5984  oprinfo[i].dobj.objType = DO_OPERATOR;
5985  oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5986  oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5987  AssignDumpId(&oprinfo[i].dobj);
5988  oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
5989  oprinfo[i].dobj.namespace =
5990  findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
5991  oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
5992  oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
5993  oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
5994 
5995  /* Decide whether we want to dump it */
5996  selectDumpableObject(&(oprinfo[i].dobj), fout);
5997  }
5998 
5999  PQclear(res);
6000 
6001  destroyPQExpBuffer(query);
6002 
6003  return oprinfo;
6004 }
DumpableObject dobj
Definition: pg_dump.h:243
char oprkind
Definition: pg_dump.h:245
Oid oprcode
Definition: pg_dump.h:246
const char * rolname
Definition: pg_dump.h:244

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

Referenced by getSchemaData().

◆ getOpfamilies()

OpfamilyInfo* getOpfamilies ( Archive fout,
int *  numOpfamilies 
)

Definition at line 6287 of file pg_dump.c.

6288 {
6289  PGresult *res;
6290  int ntups;
6291  int i;
6292  PQExpBuffer query;
6293  OpfamilyInfo *opfinfo;
6294  int i_tableoid;
6295  int i_oid;
6296  int i_opfname;
6297  int i_opfnamespace;
6298  int i_opfowner;
6299 
6300  query = createPQExpBuffer();
6301 
6302  /*
6303  * find all opfamilies, including builtin opfamilies; we filter out
6304  * system-defined opfamilies at dump-out time.
6305  */
6306 
6307  appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
6308  "opfnamespace, "
6309  "opfowner "
6310  "FROM pg_opfamily");
6311 
6312  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6313 
6314  ntups = PQntuples(res);
6315  *numOpfamilies = ntups;
6316 
6317  opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6318 
6319  i_tableoid = PQfnumber(res, "tableoid");
6320  i_oid = PQfnumber(res, "oid");
6321  i_opfname = PQfnumber(res, "opfname");
6322  i_opfnamespace = PQfnumber(res, "opfnamespace");
6323  i_opfowner = PQfnumber(res, "opfowner");
6324 
6325  for (i = 0; i < ntups; i++)
6326  {
6327  opfinfo[i].dobj.objType = DO_OPFAMILY;
6328  opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6329  opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6330  AssignDumpId(&opfinfo[i].dobj);
6331  opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6332  opfinfo[i].dobj.namespace =
6333  findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6334  opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6335 
6336  /* Decide whether we want to dump it */
6337  selectDumpableObject(&(opfinfo[i].dobj), fout);
6338  }
6339 
6340  PQclear(res);
6341 
6342  destroyPQExpBuffer(query);
6343 
6344  return opfinfo;
6345 }
const char * rolname
Definition: pg_dump.h:265
DumpableObject dobj
Definition: pg_dump.h:264

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

Referenced by getSchemaData().

◆ getOwnedSeqs()

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

Definition at line 7147 of file pg_dump.c.

7148 {
7149  int i;
7150 
7151  /*
7152  * Force sequences that are "owned" by table columns to be dumped whenever
7153  * their owning table is being dumped.
7154  */
7155  for (i = 0; i < numTables; i++)
7156  {
7157  TableInfo *seqinfo = &tblinfo[i];
7158  TableInfo *owning_tab;
7159 
7160  if (!OidIsValid(seqinfo->owning_tab))
7161  continue; /* not an owned sequence */
7162 
7163  owning_tab = findTableByOid(seqinfo->owning_tab);
7164  if (owning_tab == NULL)
7165  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7166  seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7167 
7168  /*
7169  * Only dump identity sequences if we're going to dump the table that
7170  * it belongs to.
7171  */
7172  if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
7173  seqinfo->is_identity_sequence)
7174  {
7175  seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
7176  continue;
7177  }
7178 
7179  /*
7180  * Otherwise we need to dump the components that are being dumped for
7181  * the table and any components which the sequence is explicitly
7182  * marked with.
7183  *
7184  * We can't simply use the set of components which are being dumped
7185  * for the table as the table might be in an extension (and only the
7186  * non-extension components, eg: ACLs if changed, security labels, and
7187  * policies, are being dumped) while the sequence is not (and
7188  * therefore the definition and other components should also be
7189  * dumped).
7190  *
7191  * If the sequence is part of the extension then it should be properly
7192  * marked by checkExtensionMembership() and this will be a no-op as
7193  * the table will be equivalently marked.
7194  */
7195  seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
7196 
7197  if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7198  seqinfo->interesting = true;
7199  }
7200 }
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:96
bool is_identity_sequence
Definition: pg_dump.h:315
Oid owning_tab
Definition: pg_dump.h:313

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

7267 {
7268  PQExpBuffer query;
7269  PGresult *res;
7270  int ntups;
7271 
7272  /* hash partitioning didn't exist before v11 */
7273  if (fout->remoteVersion < 110000)
7274  return;
7275  /* needn't bother if schema-only dump */
7276  if (fout->dopt->schemaOnly)
7277  return;
7278 
7279  query = createPQExpBuffer();
7280 
7281  /*
7282  * Unsafe partitioning schemes are exactly those for which hash enum_ops
7283  * appears among the partition opclasses. We needn't check partstrat.
7284  *
7285  * Note that this query may well retrieve info about tables we aren't
7286  * going to dump and hence have no lock on. That's okay since we need not
7287  * invoke any unsafe server-side functions.
7288  */
7289  appendPQExpBufferStr(query,
7290  "SELECT partrelid FROM pg_partitioned_table WHERE\n"
7291  "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
7292  "ON c.opcmethod = a.oid\n"
7293  "WHERE opcname = 'enum_ops' "
7294  "AND opcnamespace = 'pg_catalog'::regnamespace "
7295  "AND amname = 'hash') = ANY(partclass)");
7296 
7297  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7298 
7299  ntups = PQntuples(res);
7300 
7301  for (int i = 0; i < ntups; i++)
7302  {
7303  Oid tabrelid = atooid(PQgetvalue(res, i, 0));
7304  TableInfo *tbinfo;
7305 
7306  tbinfo = findTableByOid(tabrelid);
7307  if (tbinfo == NULL)
7308  pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
7309  tabrelid);
7310  tbinfo->unsafe_partitions = true;
7311  }
7312 
7313  PQclear(res);
7314 
7315  destroyPQExpBuffer(query);
7316 }
bool schemaOnly
Definition: pg_backup.h:169
bool unsafe_partitions
Definition: pg_dump.h:323

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

Referenced by getSchemaData().

◆ getPolicies()

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

Definition at line 3892 of file pg_dump.c.

3893 {
3894  PQExpBuffer query;
3895  PQExpBuffer tbloids;
3896  PGresult *res;
3897  PolicyInfo *polinfo;
3898  int i_oid;
3899  int i_tableoid;
3900  int i_polrelid;
3901  int i_polname;
3902  int i_polcmd;
3903  int i_polpermissive;
3904  int i_polroles;
3905  int i_polqual;
3906  int i_polwithcheck;
3907  int i,
3908  j,
3909  ntups;
3910 
3911  /* No policies before 9.5 */
3912  if (fout->remoteVersion < 90500)
3913  return;
3914 
3915  query = createPQExpBuffer();
3916  tbloids = createPQExpBuffer();
3917 
3918  /*
3919  * Identify tables of interest, and check which ones have RLS enabled.
3920  */
3921  appendPQExpBufferChar(tbloids, '{');
3922  for (i = 0; i < numTables; i++)
3923  {
3924  TableInfo *tbinfo = &tblinfo[i];
3925 
3926  /* Ignore row security on tables not to be dumped */
3927  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3928  continue;
3929 
3930  /* It can't have RLS or policies if it's not a table */
3931  if (tbinfo->relkind != RELKIND_RELATION &&
3932  tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
3933  continue;
3934 
3935  /* Add it to the list of table OIDs to be probed below */
3936  if (tbloids->len > 1) /* do we have more than the '{'? */
3937  appendPQExpBufferChar(tbloids, ',');
3938  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
3939 
3940  /* Is RLS enabled? (That's separate from whether it has policies) */
3941  if (tbinfo->rowsec)
3942  {
3944 
3945  /*
3946  * We represent RLS being enabled on a table by creating a
3947  * PolicyInfo object with null polname.
3948  *
3949  * Note: use tableoid 0 so that this object won't be mistaken for
3950  * something that pg_depend entries apply to.
3951  */
3952  polinfo = pg_malloc(sizeof(PolicyInfo));
3953  polinfo->dobj.objType = DO_POLICY;
3954  polinfo->dobj.catId.tableoid = 0;
3955  polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
3956  AssignDumpId(&polinfo->dobj);
3957  polinfo->dobj.namespace = tbinfo->dobj.namespace;
3958  polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
3959  polinfo->poltable = tbinfo;
3960  polinfo->polname = NULL;
3961  polinfo->polcmd = '\0';
3962  polinfo->polpermissive = 0;
3963  polinfo->polroles = NULL;
3964  polinfo->polqual = NULL;
3965  polinfo->polwithcheck = NULL;
3966  }
3967  }
3968  appendPQExpBufferChar(tbloids, '}');
3969 
3970  /*
3971  * Now, read all RLS policies belonging to the tables of interest, and
3972  * create PolicyInfo objects for them. (Note that we must filter the
3973  * results server-side not locally, because we dare not apply pg_get_expr
3974  * to tables we don't have lock on.)
3975  */
3976  pg_log_info("reading row-level security policies");
3977 
3978  printfPQExpBuffer(query,
3979  "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3980  if (fout->remoteVersion >= 100000)
3981  appendPQExpBufferStr(query, "pol.polpermissive, ");
3982  else
3983  appendPQExpBufferStr(query, "'t' as polpermissive, ");
3984  appendPQExpBuffer(query,
3985  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
3986  " 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, "
3987  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
3988  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
3989  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
3990  "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
3991  tbloids->data);
3992 
3993  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3994 
3995  ntups = PQntuples(res);
3996  if (ntups > 0)
3997  {
3998  i_oid = PQfnumber(res, "oid");
3999  i_tableoid = PQfnumber(res, "tableoid");
4000  i_polrelid = PQfnumber(res, "polrelid");
4001  i_polname = PQfnumber(res, "polname");
4002  i_polcmd = PQfnumber(res, "polcmd");
4003  i_polpermissive = PQfnumber(res, "polpermissive");
4004  i_polroles = PQfnumber(res, "polroles");
4005  i_polqual = PQfnumber(res, "polqual");
4006  i_polwithcheck = PQfnumber(res, "polwithcheck");
4007 
4008  polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
4009 
4010  for (j = 0; j < ntups; j++)
4011  {
4012  Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
4013  TableInfo *tbinfo = findTableByOid(polrelid);
4014 
4016 
4017  polinfo[j].dobj.objType = DO_POLICY;
4018  polinfo[j].dobj.catId.tableoid =
4019  atooid(PQgetvalue(res, j, i_tableoid));
4020  polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4021  AssignDumpId(&polinfo[j].dobj);
4022  polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4023  polinfo[j].poltable = tbinfo;
4024  polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
4025  polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
4026 
4027  polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
4028  polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
4029 
4030  if (PQgetisnull(res, j, i_polroles))
4031  polinfo[j].polroles = NULL;
4032  else
4033  polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
4034 
4035  if (PQgetisnull(res, j, i_polqual))
4036  polinfo[j].polqual = NULL;
4037  else
4038  polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
4039 
4040  if (PQgetisnull(res, j, i_polwithcheck))
4041  polinfo[j].polwithcheck = NULL;
4042  else
4043  polinfo[j].polwithcheck
4044  = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
4045  }
4046  }
4047 
4048  PQclear(res);
4049 
4050  destroyPQExpBuffer(query);
4051  destroyPQExpBuffer(tbloids);
4052 }
#define pg_log_info(...)
Definition: logging.h:124
#define DUMP_COMPONENT_POLICY
Definition: pg_dump.h:102
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
TableInfo * poltable
Definition: pg_dump.h:611
char * polqual
Definition: pg_dump.h:616
char polcmd
Definition: pg_dump.h:613
char * polroles
Definition: pg_dump.h:615
char * polwithcheck
Definition: pg_dump.h:617
DumpableObject dobj
Definition: pg_dump.h:610
bool polpermissive
Definition: pg_dump.h:614
char * polname
Definition: pg_dump.h:612
bool rowsec
Definition: pg_dump.h:300

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_POLICY, _tableInfo::dobj, _policyInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_POLICY, ExecuteSqlQuery(), findTableByOid(), i, j, PQExpBufferData::len, _dumpableObject::name, _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, res, _tableInfo::rowsec, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getProcLangs()

ProcLangInfo* getProcLangs ( Archive fout,
int *  numProcLangs 
)

Definition at line 8389 of file pg_dump.c.

8390 {
8391  PGresult *res;
8392  int ntups;
8393  int i;
8394  PQExpBuffer query = createPQExpBuffer();
8395  ProcLangInfo *planginfo;
8396  int i_tableoid;
8397  int i_oid;
8398  int i_lanname;
8399  int i_lanpltrusted;
8400  int i_lanplcallfoid;
8401  int i_laninline;
8402  int i_lanvalidator;
8403  int i_lanacl;
8404  int i_acldefault;
8405  int i_lanowner;
8406 
8407  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8408  "lanname, lanpltrusted, lanplcallfoid, "
8409  "laninline, lanvalidator, "
8410  "lanacl, "
8411  "acldefault('l', lanowner) AS acldefault, "
8412  "lanowner "
8413  "FROM pg_language "
8414  "WHERE lanispl "
8415  "ORDER BY oid");
8416 
8417  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8418 
8419  ntups = PQntuples(res);
8420 
8421  *numProcLangs = ntups;
8422 
8423  planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8424 
8425  i_tableoid = PQfnumber(res, "tableoid");
8426  i_oid = PQfnumber(res, "oid");
8427  i_lanname = PQfnumber(res, "lanname");
8428  i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8429  i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8430  i_laninline = PQfnumber(res, "laninline");
8431  i_lanvalidator = PQfnumber(res, "lanvalidator");
8432  i_lanacl = PQfnumber(res, "lanacl");
8433  i_acldefault = PQfnumber(res, "acldefault");
8434  i_lanowner = PQfnumber(res, "lanowner");
8435 
8436  for (i = 0; i < ntups; i++)
8437  {
8438  planginfo[i].dobj.objType = DO_PROCLANG;
8439  planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8440  planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8441  AssignDumpId(&planginfo[i].dobj);
8442 
8443  planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8444  planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8445  planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8446  planginfo[i].dacl.privtype = 0;
8447  planginfo[i].dacl.initprivs = NULL;
8448  planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8449  planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8450  planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8451  planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8452  planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8453 
8454  /* Decide whether we want to dump it */
8455  selectDumpableProcLang(&(planginfo[i]), fout);
8456 
8457  /* Mark whether language has an ACL */
8458  if (!PQgetisnull(res, i, i_lanacl))
8459  planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8460  }
8461 
8462  PQclear(res);
8463 
8464  destroyPQExpBuffer(query);
8465 
8466  return planginfo;
8467 }
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:1970
Oid lanvalidator
Definition: pg_dump.h:494
DumpableAcl dacl
Definition: pg_dump.h:490
DumpableObject dobj
Definition: pg_dump.h:489
Oid laninline
Definition: pg_dump.h:493
const char * lanowner
Definition: pg_dump.h:495
Oid lanplcallfoid
Definition: pg_dump.h:492
bool lanpltrusted
Definition: pg_dump.h:491

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, res, selectDumpableProcLang(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublicationNamespaces()

void getPublicationNamespaces ( Archive fout)

Definition at line 4377 of file pg_dump.c.

4378 {
4379  PQExpBuffer query;
4380  PGresult *res;
4381  PublicationSchemaInfo *pubsinfo;
4382  DumpOptions *dopt = fout->dopt;
4383  int i_tableoid;
4384  int i_oid;
4385  int i_pnpubid;
4386  int i_pnnspid;
4387  int i,
4388  j,
4389  ntups;
4390 
4391  if (dopt->no_publications || fout->remoteVersion < 150000)
4392  return;
4393 
4394  query = createPQExpBuffer();
4395 
4396  /* Collect all publication membership info. */
4397  appendPQExpBufferStr(query,
4398  "SELECT tableoid, oid, pnpubid, pnnspid "
4399  "FROM pg_catalog.pg_publication_namespace");
4400  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4401 
4402  ntups = PQntuples(res);
4403 
4404  i_tableoid = PQfnumber(res, "tableoid");
4405  i_oid = PQfnumber(res, "oid");
4406  i_pnpubid = PQfnumber(res, "pnpubid");
4407  i_pnnspid = PQfnumber(res, "pnnspid");
4408 
4409  /* this allocation may be more than we need */
4410  pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4411  j = 0;
4412 
4413  for (i = 0; i < ntups; i++)
4414  {
4415  Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4416  Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4417  PublicationInfo *pubinfo;
4418  NamespaceInfo *nspinfo;
4419 
4420  /*
4421  * Ignore any entries for which we aren't interested in either the
4422  * publication or the rel.
4423  */
4424  pubinfo = findPublicationByOid(pnpubid);
4425  if (pubinfo == NULL)
4426  continue;
4427  nspinfo = findNamespaceByOid(pnnspid);
4428  if (nspinfo == NULL)
4429  continue;
4430 
4431  /*
4432  * We always dump publication namespaces unless the corresponding
4433  * namespace is excluded from the dump.
4434  */
4435  if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
4436  continue;
4437 
4438  /* OK, make a DumpableObject for this relationship */
4440  pubsinfo[j].dobj.catId.tableoid =
4441  atooid(PQgetvalue(res, i, i_tableoid));
4442  pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4443  AssignDumpId(&pubsinfo[j].dobj);
4444  pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4445  pubsinfo[j].dobj.name = nspinfo->dobj.name;
4446  pubsinfo[j].publication = pubinfo;
4447  pubsinfo[j].pubschema = nspinfo;
4448 
4449  /* Decide whether we want to dump it */
4450  selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4451 
4452  j++;
4453  }
4454 
4455  PQclear(res);
4456  destroyPQExpBuffer(query);
4457 }
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:963
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:999
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2070
NamespaceInfo * pubschema
Definition: pg_dump.h:656
DumpableObject dobj
Definition: pg_dump.h:654
PublicationInfo * publication
Definition: pg_dump.h:655
int no_publications
Definition: pg_backup.h:182

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_TABLE_IN_SCHEMA, _namespaceInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_NONE, 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, res, selectDumpablePublicationObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublications()

PublicationInfo* getPublications ( Archive fout,
int *  numPublications 
)

Definition at line 4177 of file pg_dump.c.

4178 {
4179  DumpOptions *dopt = fout->dopt;
4180  PQExpBuffer query;
4181  PGresult *res;
4182  PublicationInfo *pubinfo;
4183  int i_tableoid;
4184  int i_oid;
4185  int i_pubname;
4186  int i_pubowner;
4187  int i_puballtables;
4188  int i_pubinsert;
4189  int i_pubupdate;
4190  int i_pubdelete;
4191  int i_pubtruncate;
4192  int i_pubviaroot;
4193  int i,
4194  ntups;
4195 
4196  if (dopt->no_publications || fout->remoteVersion < 100000)
4197  {
4198  *numPublications = 0;
4199  return NULL;
4200  }
4201 
4202  query = createPQExpBuffer();
4203 
4204  resetPQExpBuffer(query);
4205 
4206  /* Get the publications. */
4207  if (fout->remoteVersion >= 130000)
4208  appendPQExpBufferStr(query,
4209  "SELECT p.tableoid, p.oid, p.pubname, "
4210  "p.pubowner, "
4211  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
4212  "FROM pg_publication p");
4213  else if (fout->remoteVersion >= 110000)
4214  appendPQExpBufferStr(query,
4215  "SELECT p.tableoid, p.oid, p.pubname, "
4216  "p.pubowner, "
4217  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
4218  "FROM pg_publication p");
4219  else
4220  appendPQExpBufferStr(query,
4221  "SELECT p.tableoid, p.oid, p.pubname, "
4222  "p.pubowner, "
4223  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot "
4224  "FROM pg_publication p");
4225 
4226  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4227 
4228  ntups = PQntuples(res);
4229 
4230  i_tableoid = PQfnumber(res, "tableoid");
4231  i_oid = PQfnumber(res, "oid");
4232  i_pubname = PQfnumber(res, "pubname");
4233  i_pubowner = PQfnumber(res, "pubowner");
4234  i_puballtables = PQfnumber(res, "puballtables");
4235  i_pubinsert = PQfnumber(res, "pubinsert");
4236  i_pubupdate = PQfnumber(res, "pubupdate");
4237  i_pubdelete = PQfnumber(res, "pubdelete");
4238  i_pubtruncate = PQfnumber(res, "pubtruncate");
4239  i_pubviaroot = PQfnumber(res, "pubviaroot");
4240 
4241  pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4242 
4243  for (i = 0; i < ntups; i++)
4244  {
4245  pubinfo[i].dobj.objType = DO_PUBLICATION;
4246  pubinfo[i].dobj.catId.tableoid =
4247  atooid(PQgetvalue(res, i, i_tableoid));
4248  pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4249  AssignDumpId(&pubinfo[i].dobj);
4250  pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4251  pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4252  pubinfo[i].puballtables =
4253  (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4254  pubinfo[i].pubinsert =
4255  (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4256  pubinfo[i].pubupdate =
4257  (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4258  pubinfo[i].pubdelete =
4259  (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4260  pubinfo[i].pubtruncate =
4261  (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4262  pubinfo[i].pubviaroot =
4263  (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4264 
4265  /* Decide whether we want to dump it */
4266  selectDumpableObject(&(pubinfo[i].dobj), fout);
4267  }
4268  PQclear(res);
4269 
4270  destroyPQExpBuffer(query);
4271 
4272  *numPublications = ntups;
4273  return pubinfo;
4274 }
const char * rolname
Definition: pg_dump.h:626
bool puballtables
Definition: pg_dump.h:627
bool pubtruncate
Definition: pg_dump.h:631
DumpableObject dobj
Definition: pg_dump.h:625

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

Referenced by getSchemaData().

◆ getPublicationTables()

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

Definition at line 4464 of file pg_dump.c.

4465 {
4466  PQExpBuffer query;
4467  PGresult *res;
4468  PublicationRelInfo *pubrinfo;
4469  DumpOptions *dopt = fout->dopt;
4470  int i_tableoid;
4471  int i_oid;
4472  int i_prpubid;
4473  int i_prrelid;
4474  int i_prrelqual;
4475  int i_prattrs;
4476  int i,
4477  j,
4478  ntups;
4479 
4480  if (dopt->no_publications || fout->remoteVersion < 100000)
4481  return;
4482 
4483  query = createPQExpBuffer();
4484 
4485  /* Collect all publication membership info. */
4486  if (fout->remoteVersion >= 150000)
4487  appendPQExpBufferStr(query,
4488  "SELECT tableoid, oid, prpubid, prrelid, "
4489  "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
4490  "(CASE\n"
4491  " WHEN pr.prattrs IS NOT NULL THEN\n"
4492  " (SELECT array_agg(attname)\n"
4493  " FROM\n"
4494  " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
4495  " pg_catalog.pg_attribute\n"
4496  " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
4497  " ELSE NULL END) prattrs "
4498  "FROM pg_catalog.pg_publication_rel pr");
4499  else
4500  appendPQExpBufferStr(query,
4501  "SELECT tableoid, oid, prpubid, prrelid, "
4502  "NULL AS prrelqual, NULL AS prattrs "
4503  "FROM pg_catalog.pg_publication_rel");
4504  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4505 
4506  ntups = PQntuples(res);
4507 
4508  i_tableoid = PQfnumber(res, "tableoid");
4509  i_oid = PQfnumber(res, "oid");
4510  i_prpubid = PQfnumber(res, "prpubid");
4511  i_prrelid = PQfnumber(res, "prrelid");
4512  i_prrelqual = PQfnumber(res, "prrelqual");
4513  i_prattrs = PQfnumber(res, "prattrs");
4514 
4515  /* this allocation may be more than we need */
4516  pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4517  j = 0;
4518 
4519  for (i = 0; i < ntups; i++)
4520  {
4521  Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4522  Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4523  PublicationInfo *pubinfo;
4524  TableInfo *tbinfo;
4525 
4526  /*
4527  * Ignore any entries for which we aren't interested in either the
4528  * publication or the rel.
4529  */
4530  pubinfo = findPublicationByOid(prpubid);
4531  if (pubinfo == NULL)
4532  continue;
4533  tbinfo = findTableByOid(prrelid);
4534  if (tbinfo == NULL)
4535  continue;
4536 
4537  /*
4538  * Ignore publication membership of tables whose definitions are not
4539  * to be dumped.
4540  */
4541  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
4542  continue;
4543 
4544  /* OK, make a DumpableObject for this relationship */
4545  pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4546  pubrinfo[j].dobj.catId.tableoid =
4547  atooid(PQgetvalue(res, i, i_tableoid));
4548  pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4549  AssignDumpId(&pubrinfo[j].dobj);
4550  pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4551  pubrinfo[j].dobj.name = tbinfo->dobj.name;
4552  pubrinfo[j].publication = pubinfo;
4553  pubrinfo[j].pubtable = tbinfo;
4554  if (PQgetisnull(res, i, i_prrelqual))
4555  pubrinfo[j].pubrelqual = NULL;
4556  else
4557  pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
4558 
4559  if (!PQgetisnull(res, i, i_prattrs))
4560  {
4561  char **attnames;
4562  int nattnames;
4563  PQExpBuffer attribs;
4564 
4565  if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
4566  &attnames, &nattnames))
4567  pg_fatal("could not parse %s array", "prattrs");
4568  attribs = createPQExpBuffer();
4569  for (int k = 0; k < nattnames; k++)
4570  {
4571  if (k > 0)
4572  appendPQExpBufferStr(attribs, ", ");
4573 
4574  appendPQExpBufferStr(attribs, fmtId(attnames[k]));
4575  }
4576  pubrinfo[j].pubrattrs = attribs->data;
4577  }
4578  else
4579  pubrinfo[j].pubrattrs = NULL;
4580 
4581  /* Decide whether we want to dump it */
4582  selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
4583 
4584  j++;
4585  }
4586 
4587  PQclear(res);
4588  destroyPQExpBuffer(query);
4589 }
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
bool parsePGArray(const char *atext, char ***itemarray, int *nitems)
Definition: string_utils.c:657

References appendPQExpBufferStr(), AssignDumpId(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_REL, _tableInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_DEFINITION, ExecuteSqlQuery(), findPublicationByOid(), findTableByOid(), fmtId(), i, j, _dumpableObject::name, _dumpOptions::no_publications, parsePGArray(), pg_fatal, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, and selectDumpablePublicationObject().

Referenced by getSchemaData().

◆ getRules()

RuleInfo* getRules ( Archive fout,
int *  numRules 
)

Definition at line 8005 of file pg_dump.c.

8006 {
8007  PGresult *res;
8008  int ntups;
8009  int i;
8010  PQExpBuffer query = createPQExpBuffer();
8011  RuleInfo *ruleinfo;
8012  int i_tableoid;
8013  int i_oid;
8014  int i_rulename;
8015  int i_ruletable;
8016  int i_ev_type;
8017  int i_is_instead;
8018  int i_ev_enabled;
8019 
8020  appendPQExpBufferStr(query, "SELECT "
8021  "tableoid, oid, rulename, "
8022  "ev_class AS ruletable, ev_type, is_instead, "
8023  "ev_enabled "
8024  "FROM pg_rewrite "
8025  "ORDER BY oid");
8026 
8027  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8028 
8029  ntups = PQntuples(res);
8030 
8031  *numRules = ntups;
8032 
8033  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8034 
8035  i_tableoid = PQfnumber(res, "tableoid");
8036  i_oid = PQfnumber(res, "oid");
8037  i_rulename = PQfnumber(res, "rulename");
8038  i_ruletable = PQfnumber(res, "ruletable");
8039  i_ev_type = PQfnumber(res, "ev_type");
8040  i_is_instead = PQfnumber(res, "is_instead");
8041  i_ev_enabled = PQfnumber(res, "ev_enabled");
8042 
8043  for (i = 0; i < ntups; i++)
8044  {
8045  Oid ruletableoid;
8046 
8047  ruleinfo[i].dobj.objType = DO_RULE;
8048  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8049  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8050  AssignDumpId(&ruleinfo[i].dobj);
8051  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8052  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8053  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8054  if (ruleinfo[i].ruletable == NULL)
8055  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8056  ruletableoid, ruleinfo[i].dobj.catId.oid);
8057  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8058  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8059  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8060  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8061  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8062  if (ruleinfo[i].ruletable)
8063  {
8064  /*
8065  * If the table is a view or materialized view, force its ON
8066  * SELECT rule to be sorted before the view itself --- this
8067  * ensures that any dependencies for the rule affect the table's
8068  * positioning. Other rules are forced to appear after their
8069  * table.
8070  */
8071  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8072  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8073  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8074  {
8075  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8076  ruleinfo[i].dobj.dumpId);
8077  /* We'll merge the rule into CREATE VIEW, if possible */
8078  ruleinfo[i].separate = false;
8079  }
8080  else
8081  {
8082  addObjectDependency(&ruleinfo[i].dobj,
8083  ruleinfo[i].ruletable->dobj.dumpId);
8084  ruleinfo[i].separate = true;
8085  }
8086  }
8087  else
8088  ruleinfo[i].separate = true;
8089  }
8090 
8091  PQclear(res);
8092 
8093  destroyPQExpBuffer(query);
8094 
8095  return ruleinfo;
8096 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:809
DumpableObject dobj
Definition: pg_dump.h:434
bool separate
Definition: pg_dump.h:439
char ev_enabled
Definition: pg_dump.h:438
bool is_instead
Definition: pg_dump.h:437
TableInfo * ruletable
Definition: pg_dump.h:435
char ev_type
Definition: pg_dump.h:436

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, res, _ruleInfo::ruletable, _ruleInfo::separate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSchemaData()

TableInfo* getSchemaData ( Archive fout,
int *  numTablesPtr 
)

Definition at line 99 of file common.c.

100 {
101  TableInfo *tblinfo;
102  ExtensionInfo *extinfo;
103  InhInfo *inhinfo;
104  int numTables;
105  int numTypes;
106  int numFuncs;
107  int numOperators;
108  int numCollations;
109  int numNamespaces;
110  int numExtensions;
111  int numPublications;
112  int numAggregates;
113  int numInherits;
114  int numRules;
115  int numProcLangs;
116  int numCasts;
117  int numTransforms;
118  int numAccessMethods;
119  int numOpclasses;
120  int numOpfamilies;
121  int numConversions;
122  int numTSParsers;
123  int numTSTemplates;
124  int numTSDicts;
125  int numTSConfigs;
126  int numForeignDataWrappers;
127  int numForeignServers;
128  int numDefaultACLs;
129  int numEventTriggers;
130 
131  /*
132  * We must read extensions and extension membership info first, because
133  * extension membership needs to be consultable during decisions about
134  * whether other objects are to be dumped.
135  */
136  pg_log_info("reading extensions");
137  extinfo = getExtensions(fout, &numExtensions);
138 
139  pg_log_info("identifying extension members");
140  getExtensionMembership(fout, extinfo, numExtensions);
141 
142  pg_log_info("reading schemas");
143  (void) getNamespaces(fout, &numNamespaces);
144 
145  /*
146  * getTables should be done as soon as possible, so as to minimize the
147  * window between starting our transaction and acquiring per-table locks.
148  * However, we have to do getNamespaces first because the tables get
149  * linked to their containing namespaces during getTables.
150  */
151  pg_log_info("reading user-defined tables");
152  tblinfo = getTables(fout, &numTables);
153 
154  getOwnedSeqs(fout, tblinfo, numTables);
155 
156  pg_log_info("reading user-defined functions");
157  (void) getFuncs(fout, &numFuncs);
158 
159  /* this must be after getTables and getFuncs */
160  pg_log_info("reading user-defined types");
161  (void) getTypes(fout, &numTypes);
162 
163  /* this must be after getFuncs, too */
164  pg_log_info("reading procedural languages");
165  getProcLangs(fout, &numProcLangs);
166 
167  pg_log_info("reading user-defined aggregate functions");
168  getAggregates(fout, &numAggregates);
169 
170  pg_log_info("reading user-defined operators");
171  (void) getOperators(fout, &numOperators);
172 
173  pg_log_info("reading user-defined access methods");
174  getAccessMethods(fout, &numAccessMethods);
175 
176  pg_log_info("reading user-defined operator classes");
177  getOpclasses(fout, &numOpclasses);
178 
179  pg_log_info("reading user-defined operator families");
180  getOpfamilies(fout, &numOpfamilies);
181 
182  pg_log_info("reading user-defined text search parsers");
183  getTSParsers(fout, &numTSParsers);
184 
185  pg_log_info("reading user-defined text search templates");
186  getTSTemplates(fout, &numTSTemplates);
187 
188  pg_log_info("reading user-defined text search dictionaries");
189  getTSDictionaries(fout, &numTSDicts);
190 
191  pg_log_info("reading user-defined text search configurations");
192  getTSConfigurations(fout, &numTSConfigs);
193 
194  pg_log_info("reading user-defined foreign-data wrappers");
195  getForeignDataWrappers(fout, &numForeignDataWrappers);
196 
197  pg_log_info("reading user-defined foreign servers");
198  getForeignServers(fout, &numForeignServers);
199 
200  pg_log_info("reading default privileges");
201  getDefaultACLs(fout, &numDefaultACLs);
202 
203  pg_log_info("reading user-defined collations");
204  (void) getCollations(fout, &numCollations);
205 
206  pg_log_info("reading user-defined conversions");
207  getConversions(fout, &numConversions);
208 
209  pg_log_info("reading type casts");
210  getCasts(fout, &numCasts);
211 
212  pg_log_info("reading transforms");
213  getTransforms(fout, &numTransforms);
214 
215  pg_log_info("reading table inheritance information");
216  inhinfo = getInherits(fout, &numInherits);
217 
218  pg_log_info("reading event triggers");
219  getEventTriggers(fout, &numEventTriggers);
220 
221  /* Identify extension configuration tables that should be dumped */
222  pg_log_info("finding extension tables");
223  processExtensionTables(fout, extinfo, numExtensions);
224 
225  /* Link tables to parents, mark parents of target tables interesting */
226  pg_log_info("finding inheritance relationships");
227  flagInhTables(fout, tblinfo, numTables, inhinfo, numInherits);
228 
229  pg_log_info("reading column info for interesting tables");
230  getTableAttrs(fout, tblinfo, numTables);
231 
232  pg_log_info("flagging inherited columns in subtables");
233  flagInhAttrs(fout, fout->dopt, tblinfo, numTables);
234 
235  pg_log_info("reading partitioning data");
236  getPartitioningInfo(fout);
237 
238  pg_log_info("reading indexes");
239  getIndexes(fout, tblinfo, numTables);
240 
241  pg_log_info("flagging indexes in partitioned tables");
242  flagInhIndexes(fout, tblinfo, numTables);
243 
244  pg_log_info("reading extended statistics");
245  getExtendedStatistics(fout);
246 
247  pg_log_info("reading constraints");
248  getConstraints(fout, tblinfo, numTables);
249 
250  pg_log_info("reading triggers");
251  getTriggers(fout, tblinfo, numTables);
252 
253  pg_log_info("reading rewrite rules");
254  getRules(fout, &numRules);
255 
256  pg_log_info("reading policies");
257  getPolicies(fout, tblinfo, numTables);
258 
259  pg_log_info("reading publications");
260  (void) getPublications(fout, &numPublications);
261 
262  pg_log_info("reading publication membership of tables");
263  getPublicationTables(fout, tblinfo, numTables);
264 
265  pg_log_info("reading publication membership of schemas");
267 
268  pg_log_info("reading subscriptions");
269  getSubscriptions(fout);
270 
271  pg_log_info("reading subscription membership of tables");
272  getSubscriptionTables(fout);
273 
274  free(inhinfo); /* not needed any longer */
275 
276  *numTablesPtr = numTables;
277  return tblinfo;
278 }
static void flagInhAttrs(Archive *fout, DumpOptions *dopt, TableInfo *tblinfo, int numTables)
Definition: common.c:502
static void flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables, InhInfo *inhinfo, int numInherits)
Definition: common.c:293
static void flagInhIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
#define free(a)
Definition: header.h:65
NamespaceInfo * getNamespaces(Archive *fout, int *numNamespaces)
Definition: pg_dump.c:5559
void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7725
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4377
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7266
DefaultACLInfo * getDefaultACLs(Archive *fout, int *numDefaultACLs)
Definition: pg_dump.c:9924
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:3892
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:18249
ForeignServerInfo * getForeignServers(Archive *fout, int *numForeignServers)
Definition: pg_dump.c:9830
AccessMethodInfo * getAccessMethods(Archive *fout, int *numAccessMethods)
Definition: pg_dump.c:6150
FdwInfo * getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
Definition: pg_dump.c:9740
FuncInfo * getFuncs(Archive *fout, int *numFuncs)
Definition: pg_dump.c:6502
TSConfigInfo * getTSConfigurations(Archive *fout, int *numTSConfigs)
Definition: pg_dump.c:9675
ConvInfo * getConversions(Archive *fout, int *numConversions)
Definition: pg_dump.c:6082
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7147
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4464
AggInfo * getAggregates(Archive *fout, int *numAggs)
Definition: pg_dump.c:6355
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7326
TSDictInfo * getTSDictionaries(Archive *fout, int *numTSDicts)
Definition: pg_dump.c:9538
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7210
OpfamilyInfo * getOpfamilies(Archive *fout, int *numOpfamilies)
Definition: pg_dump.c:6287
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:8686
void getSubscriptionTables(Archive *fout)
Definition: pg_dump.c:4913
PublicationInfo * getPublications(Archive *fout, int *numPublications)
Definition: pg_dump.c:4177
TSTemplateInfo * getTSTemplates(Archive *fout, int *numTSTemplates)
Definition: pg_dump.c:9610
ProcLangInfo * getProcLangs(Archive *fout, int *numProcLangs)
Definition: pg_dump.c:8389
TypeInfo * getTypes(Archive *fout, int *numTypes)
Definition: pg_dump.c:5770
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:7646
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:18342
OpclassInfo * getOpclasses(Archive *fout, int *numOpclasses)
Definition: pg_dump.c:6221
CollInfo * getCollations(Archive *fout, int *numCollations)
Definition: pg_dump.c:6014
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:4718
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:5695
TSParserInfo * getTSParsers(Archive *fout, int *numTSParsers)
Definition: pg_dump.c:9458
TransformInfo * getTransforms(Archive *fout, int *numTransforms)
Definition: pg_dump.c:8595
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8106
OprInfo * getOperators(Archive *fout, int *numOprs)
Definition: pg_dump.c:5940
RuleInfo * getRules(Archive *fout, int *numRules)
Definition: pg_dump.c:8005
EventTriggerInfo * getEventTriggers(Archive *fout, int *numEventTriggers)
Definition: pg_dump.c:8302
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:6701
CastInfo * getCasts(Archive *fout, int *numCasts)
Definition: pg_dump.c:8479

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

Referenced by main().

◆ getSubscriptions()

void getSubscriptions ( Archive fout)

Definition at line 4718 of file pg_dump.c.

4719 {
4720  DumpOptions *dopt = fout->dopt;
4721  PQExpBuffer query;
4722  PGresult *res;
4723  SubscriptionInfo *subinfo;
4724  int i_tableoid;
4725  int i_oid;
4726  int i_subname;
4727  int i_subowner;
4728  int i_subbinary;
4729  int i_substream;
4730  int i_subtwophasestate;
4731  int i_subdisableonerr;
4732  int i_subpasswordrequired;
4733  int i_subrunasowner;
4734  int i_subconninfo;
4735  int i_subslotname;
4736  int i_subsynccommit;
4737  int i_subpublications;
4738  int i_suborigin;
4739  int i_suboriginremotelsn;
4740  int i_subenabled;
4741  int i_subfailover;
4742  int i,
4743  ntups;
4744 
4745  if (dopt->no_subscriptions || fout->remoteVersion < 100000)
4746  return;
4747 
4748  if (!is_superuser(fout))
4749  {
4750  int n;
4751 
4752  res = ExecuteSqlQuery(fout,
4753  "SELECT count(*) FROM pg_subscription "
4754  "WHERE subdbid = (SELECT oid FROM pg_database"
4755  " WHERE datname = current_database())",
4756  PGRES_TUPLES_OK);
4757  n = atoi(PQgetvalue(res, 0, 0));
4758  if (n > 0)
4759  pg_log_warning("subscriptions not dumped because current user is not a superuser");
4760  PQclear(res);
4761  return;
4762  }
4763 
4764  query = createPQExpBuffer();
4765 
4766  /* Get the subscriptions in current database. */
4767  appendPQExpBufferStr(query,
4768  "SELECT s.tableoid, s.oid, s.subname,\n"
4769  " s.subowner,\n"
4770  " s.subconninfo, s.subslotname, s.subsynccommit,\n"
4771  " s.subpublications,\n");
4772 
4773  if (fout->remoteVersion >= 140000)
4774  appendPQExpBufferStr(query, " s.subbinary,\n");
4775  else
4776  appendPQExpBufferStr(query, " false AS subbinary,\n");
4777 
4778  if (fout->remoteVersion >= 140000)
4779  appendPQExpBufferStr(query, " s.substream,\n");
4780  else
4781  appendPQExpBufferStr(query, " 'f' AS substream,\n");
4782 
4783  if (fout->remoteVersion >= 150000)
4784  appendPQExpBufferStr(query,
4785  " s.subtwophasestate,\n"
4786  " s.subdisableonerr,\n");
4787  else
4788  appendPQExpBuffer(query,
4789  " '%c' AS subtwophasestate,\n"
4790  " false AS subdisableonerr,\n",
4792 
4793  if (fout->remoteVersion >= 160000)
4794  appendPQExpBufferStr(query,
4795  " s.subpasswordrequired,\n"
4796  " s.subrunasowner,\n"
4797  " s.suborigin,\n");
4798  else
4799  appendPQExpBuffer(query,
4800  " 't' AS subpasswordrequired,\n"
4801  " 't' AS subrunasowner,\n"
4802  " '%s' AS suborigin,\n",
4804 
4805  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4806  appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
4807  " s.subenabled,\n"
4808  " s.subfailover\n");
4809  else
4810  appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
4811  " false AS subenabled,\n"
4812  " false AS subfailover\n");
4813 
4814  appendPQExpBufferStr(query,
4815  "FROM pg_subscription s\n");
4816 
4817  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4818  appendPQExpBufferStr(query,
4819  "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
4820  " ON o.external_id = 'pg_' || s.oid::text \n");
4821 
4822  appendPQExpBufferStr(query,
4823  "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
4824  " WHERE datname = current_database())");
4825 
4826  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4827 
4828  ntups = PQntuples(res);
4829 
4830  /*
4831  * Get subscription fields. We don't include subskiplsn in the dump as
4832  * after restoring the dump this value may no longer be relevant.
4833  */
4834  i_tableoid = PQfnumber(res, "tableoid");
4835  i_oid = PQfnumber(res, "oid");
4836  i_subname = PQfnumber(res, "subname");
4837  i_subowner = PQfnumber(res, "subowner");
4838  i_subbinary = PQfnumber(res, "subbinary");
4839  i_substream = PQfnumber(res, "substream");
4840  i_subtwophasestate = PQfnumber(res, "subtwophasestate");
4841  i_subdisableonerr = PQfnumber(res, "subdisableonerr");
4842  i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
4843  i_subrunasowner = PQfnumber(res, "subrunasowner");
4844  i_subconninfo = PQfnumber(res, "subconninfo");
4845  i_subslotname = PQfnumber(res, "subslotname");
4846  i_subsynccommit = PQfnumber(res, "subsynccommit");
4847  i_subpublications = PQfnumber(res, "subpublications");
4848  i_suborigin = PQfnumber(res, "suborigin");
4849  i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
4850  i_subenabled = PQfnumber(res, "subenabled");
4851  i_subfailover = PQfnumber(res, "subfailover");
4852 
4853  subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
4854 
4855  for (i = 0; i < ntups; i++)
4856  {
4857  subinfo[i].dobj.objType = DO_SUBSCRIPTION;
4858  subinfo[i].dobj.catId.tableoid =
4859  atooid(PQgetvalue(res, i, i_tableoid));
4860  subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4861  AssignDumpId(&subinfo[i].dobj);
4862  subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
4863  subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
4864 
4865  subinfo[i].subbinary =
4866  pg_strdup(PQgetvalue(res, i, i_subbinary));
4867  subinfo[i].substream =
4868  pg_strdup(PQgetvalue(res, i, i_substream));
4869  subinfo[i].subtwophasestate =
4870  pg_strdup(PQgetvalue(res, i, i_subtwophasestate));
4871  subinfo[i].subdisableonerr =
4872  pg_strdup(PQgetvalue(res, i, i_subdisableonerr));
4873  subinfo[i].subpasswordrequired =
4874  pg_strdup(PQgetvalue(res, i, i_subpasswordrequired));
4875  subinfo[i].subrunasowner =
4876  pg_strdup(PQgetvalue(res, i, i_subrunasowner));
4877  subinfo[i].subconninfo =
4878  pg_strdup(PQgetvalue(res, i, i_subconninfo));
4879  if (PQgetisnull(res, i, i_subslotname))
4880  subinfo[i].subslotname = NULL;
4881  else
4882  subinfo[i].subslotname =
4883  pg_strdup(PQgetvalue(res, i, i_subslotname));
4884  subinfo[i].subsynccommit =
4885  pg_strdup(PQgetvalue(res, i, i_subsynccommit));
4886  subinfo[i].subpublications =
4887  pg_strdup(PQgetvalue(res, i, i_subpublications));
4888  subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
4889  if (PQgetisnull(res, i, i_suboriginremotelsn))
4890  subinfo[i].suboriginremotelsn = NULL;
4891  else
4892  subinfo[i].suboriginremotelsn =
4893  pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
4894  subinfo[i].subenabled =
4895  pg_strdup(PQgetvalue(res, i, i_subenabled));
4896  subinfo[i].subfailover =
4897  pg_strdup(PQgetvalue(res, i, i_subfailover));
4898 
4899  /* Decide whether we want to dump it */
4900  selectDumpableObject(&(subinfo[i].dobj), fout);
4901  }
4902  PQclear(res);
4903 
4904  destroyPQExpBuffer(query);
4905 }
static bool is_superuser(Archive *fout)
Definition: pg_dump.c:4700
#define LOGICALREP_ORIGIN_ANY
#define LOGICALREP_TWOPHASE_STATE_DISABLED
char * suboriginremotelsn
Definition: pg_dump.h:678
char * suborigin
Definition: pg_dump.h:677
char * subbinary
Definition: pg_dump.h:667
const char * rolname
Definition: pg_dump.h:665
char * subrunasowner
Definition: pg_dump.h:672
char * subsynccommit
Definition: pg_dump.h:675
char * subpublications
Definition: pg_dump.h:676
char * subtwophasestate
Definition: pg_dump.h:669
char * subfailover
Definition: pg_dump.h:679
char * subenabled
Definition: pg_dump.h:666
char * substream
Definition: pg_dump.h:668
char * subpasswordrequired
Definition: pg_dump.h:671
char * subslotname
Definition: pg_dump.h:674
char * subdisableonerr
Definition: pg_dump.h:670
char * subconninfo
Definition: pg_dump.h:673
DumpableObject dobj
Definition: pg_dump.h:664
int no_subscriptions
Definition: pg_backup.h:183

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(), LOGICALREP_ORIGIN_ANY, LOGICALREP_TWOPHASE_STATE_DISABLED, _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, res, _SubscriptionInfo::rolname, selectDumpableObject(), _SubscriptionInfo::subbinary, _SubscriptionInfo::subconninfo, _SubscriptionInfo::subdisableonerr, _SubscriptionInfo::subenabled, _SubscriptionInfo::subfailover, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, _SubscriptionInfo::subtwophasestate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSubscriptionTables()

void getSubscriptionTables ( Archive fout)

Definition at line 4913 of file pg_dump.c.

4914 {
4915  DumpOptions *dopt = fout->dopt;
4916  SubscriptionInfo *subinfo = NULL;
4917  SubRelInfo *subrinfo;
4918  PGresult *res;
4919  int i_srsubid;
4920  int i_srrelid;
4921  int i_srsubstate;
4922  int i_srsublsn;
4923  int ntups;
4924  Oid last_srsubid = InvalidOid;
4925 
4926  if (dopt->no_subscriptions || !dopt->binary_upgrade ||
4927  fout->remoteVersion < 170000)
4928  return;
4929 
4930  res = ExecuteSqlQuery(fout,
4931  "SELECT srsubid, srrelid, srsubstate, srsublsn "
4932  "FROM pg_catalog.pg_subscription_rel "
4933  "ORDER BY srsubid",
4934  PGRES_TUPLES_OK);
4935  ntups = PQntuples(res);
4936  if (ntups == 0)
4937  goto cleanup;
4938 
4939  /* Get pg_subscription_rel attributes */
4940  i_srsubid = PQfnumber(res, "srsubid");
4941  i_srrelid = PQfnumber(res, "srrelid");
4942  i_srsubstate = PQfnumber(res, "srsubstate");
4943  i_srsublsn = PQfnumber(res, "srsublsn");
4944 
4945  subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
4946  for (int i = 0; i < ntups; i++)
4947  {
4948  Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
4949  Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
4950  TableInfo *tblinfo;
4951 
4952  /*
4953  * If we switched to a new subscription, check if the subscription
4954  * exists.
4955  */
4956  if (cur_srsubid != last_srsubid)
4957  {
4958  subinfo = findSubscriptionByOid(cur_srsubid);
4959  if (subinfo == NULL)
4960  pg_fatal("subscription with OID %u does not exist", cur_srsubid);
4961 
4962  last_srsubid = cur_srsubid;
4963  }
4964 
4965  tblinfo = findTableByOid(relid);
4966  if (tblinfo == NULL)
4967  pg_fatal("failed sanity check, table with OID %u not found",
4968  relid);
4969 
4970  /* OK, make a DumpableObject for this relationship */
4971  subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
4972  subrinfo[i].dobj.catId.tableoid = relid;
4973  subrinfo[i].dobj.catId.oid = cur_srsubid;
4974  AssignDumpId(&subrinfo[i].dobj);
4975  subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
4976  subrinfo[i].tblinfo = tblinfo;
4977  subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
4978  if (PQgetisnull(res, i, i_srsublsn))
4979  subrinfo[i].srsublsn = NULL;
4980  else
4981  subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
4982 
4983  subrinfo[i].subinfo = subinfo;
4984 
4985  /* Decide whether we want to dump it */
4986  selectDumpableObject(&(subrinfo[i].dobj), fout);
4987  }
4988 
4989 cleanup:
4990  PQclear(res);
4991 }
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:1017
static void cleanup(void)
Definition: bootstrap.c:682
DumpableObject dobj
Definition: pg_dump.h:694
char * srsublsn
Definition: pg_dump.h:698
SubscriptionInfo * subinfo
Definition: pg_dump.h:695
TableInfo * tblinfo
Definition: pg_dump.h:696
char srsubstate
Definition: pg_dump.h:697

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

Referenced by getSchemaData().

◆ getTableAttrs()

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

Definition at line 8686 of file pg_dump.c.

8687 {
8688  DumpOptions *dopt = fout->dopt;
8690  PQExpBuffer tbloids = createPQExpBuffer();
8691  PQExpBuffer checkoids = createPQExpBuffer();
8692  PGresult *res;
8693  int ntups;
8694  int curtblindx;
8695  int i_attrelid;
8696  int i_attnum;
8697  int i_attname;
8698  int i_atttypname;
8699  int i_attstattarget;
8700  int i_attstorage;
8701  int i_typstorage;
8702  int i_attidentity;
8703  int i_attgenerated;
8704  int i_attisdropped;
8705  int i_attlen;
8706  int i_attalign;
8707  int i_attislocal;
8708  int i_notnull_name;
8709  int i_notnull_noinherit;
8710  int i_notnull_is_pk;
8711  int i_notnull_inh;
8712  int i_attoptions;
8713  int i_attcollation;
8714  int i_attcompression;
8715  int i_attfdwoptions;
8716  int i_attmissingval;
8717  int i_atthasdef;
8718 
8719  /*
8720  * We want to perform just one query against pg_attribute, and then just
8721  * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
8722  * (for CHECK constraints and for NOT NULL constraints). However, we
8723  * mustn't try to select every row of those catalogs and then sort it out
8724  * on the client side, because some of the server-side functions we need
8725  * would be unsafe to apply to tables we don't have lock on. Hence, we
8726  * build an array of the OIDs of tables we care about (and now have lock
8727  * on!), and use a WHERE clause to constrain which rows are selected.
8728  */
8729  appendPQExpBufferChar(tbloids, '{');
8730  appendPQExpBufferChar(checkoids, '{');
8731  for (int i = 0; i < numTables; i++)
8732  {
8733  TableInfo *tbinfo = &tblinfo[i];
8734 
8735  /* Don't bother to collect info for sequences */
8736  if (tbinfo->relkind == RELKIND_SEQUENCE)
8737  continue;
8738 
8739  /* Don't bother with uninteresting tables, either */
8740  if (!tbinfo->interesting)
8741  continue;
8742 
8743  /* OK, we need info for this table */
8744  if (tbloids->len > 1) /* do we have more than the '{'? */
8745  appendPQExpBufferChar(tbloids, ',');
8746  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8747 
8748  if (tbinfo->ncheck > 0)
8749  {
8750  /* Also make a list of the ones with check constraints */
8751  if (checkoids->len > 1) /* do we have more than the '{'? */
8752  appendPQExpBufferChar(checkoids, ',');
8753  appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
8754  }
8755  }
8756  appendPQExpBufferChar(tbloids, '}');
8757  appendPQExpBufferChar(checkoids, '}');
8758 
8759  /*
8760  * Find all the user attributes and their types.
8761  *
8762  * Since we only want to dump COLLATE clauses for attributes whose
8763  * collation is different from their type's default, we use a CASE here to
8764  * suppress uninteresting attcollations cheaply.
8765  */
8767  "SELECT\n"
8768  "a.attrelid,\n"
8769  "a.attnum,\n"
8770  "a.attname,\n"
8771  "a.attstattarget,\n"
8772  "a.attstorage,\n"
8773  "t.typstorage,\n"
8774  "a.atthasdef,\n"
8775  "a.attisdropped,\n"
8776  "a.attlen,\n"
8777  "a.attalign,\n"
8778  "a.attislocal,\n"
8779  "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
8780  "array_to_string(a.attoptions, ', ') AS attoptions,\n"
8781  "CASE WHEN a.attcollation <> t.typcollation "
8782  "THEN a.attcollation ELSE 0 END AS attcollation,\n"
8783  "pg_catalog.array_to_string(ARRAY("
8784  "SELECT pg_catalog.quote_ident(option_name) || "
8785  "' ' || pg_catalog.quote_literal(option_value) "
8786  "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8787  "ORDER BY option_name"
8788  "), E',\n ') AS attfdwoptions,\n");
8789 
8790  /*
8791  * Find out any NOT NULL markings for each column. In 17 and up we read
8792  * pg_constraint to obtain the constraint name. notnull_noinherit is set
8793  * according to the NO INHERIT property. For versions prior to 17, we
8794  * store an empty string as the name when a constraint is marked as
8795  * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
8796  * without a name); also, such cases are never NO INHERIT.
8797  *
8798  * We track in notnull_inh whether the constraint was defined directly in
8799  * this table or via an ancestor, for binary upgrade.
8800  *
8801  * Lastly, we need to know if the PK for the table involves each column;
8802  * for columns that are there we need a NOT NULL marking even if there's
8803  * no explicit constraint, to avoid the table having to be scanned for
8804  * NULLs after the data is loaded when the PK is created, later in the
8805  * dump; for this case we add throwaway constraints that are dropped once
8806  * the PK is created.
8807  *
8808  * Another complication arises from columns that have attnotnull set, but
8809  * for which no corresponding not-null nor PK constraint exists. This can
8810  * happen if, for example, a primary key is dropped indirectly -- say,
8811  * because one of its columns is dropped. This is an irregular condition,
8812  * so we don't work hard to preserve it, and instead act as though an
8813  * unnamed not-null constraint exists.
8814  */
8815  if (fout->remoteVersion >= 170000)
8817  "CASE WHEN co.conname IS NOT NULL THEN co.conname "
8818  " WHEN a.attnotnull AND copk.conname IS NULL THEN '' ELSE NULL END AS notnull_name,\n"
8819  "CASE WHEN co.conname IS NOT NULL THEN co.connoinherit "
8820  " WHEN a.attnotnull THEN false ELSE NULL END AS notnull_noinherit,\n"
8821  "copk.conname IS NOT NULL as notnull_is_pk,\n"
8822  "CASE WHEN co.conname IS NOT NULL THEN "
8823  " coalesce(NOT co.conislocal, true) "
8824  "ELSE false END as notnull_inh,\n");
8825  else
8827  "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
8828  "false AS notnull_noinherit,\n"
8829  "copk.conname IS NOT NULL AS notnull_is_pk,\n"
8830  "NOT a.attislocal AS notnull_inh,\n");
8831 
8832  if (fout->remoteVersion >= 140000)
8834  "a.attcompression AS attcompression,\n");
8835  else
8837  "'' AS attcompression,\n");
8838 
8839  if (fout->remoteVersion >= 100000)
8841  "a.attidentity,\n");
8842  else
8844  "'' AS attidentity,\n");
8845 
8846  if (fout->remoteVersion >= 110000)
8848  "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8849  "THEN a.attmissingval ELSE null END AS attmissingval,\n");
8850  else
8852  "NULL AS attmissingval,\n");
8853 
8854  if (fout->remoteVersion >= 120000)
8856  "a.attgenerated\n");
8857  else
8859  "'' AS attgenerated\n");
8860 
8861  /* need left join to pg_type to not fail on dropped columns ... */
8863  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8864  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
8865  "LEFT JOIN pg_catalog.pg_type t "
8866  "ON (a.atttypid = t.oid)\n",
8867  tbloids->data);
8868 
8869  /*
8870  * In versions 16 and up, we need pg_constraint for explicit NOT NULL
8871  * entries. Also, we need to know if the NOT NULL for each column is
8872  * backing a primary key.
8873  */
8874  if (fout->remoteVersion >= 170000)
8876  " LEFT JOIN pg_catalog.pg_constraint co ON "
8877  "(a.attrelid = co.conrelid\n"
8878  " AND co.contype = 'n' AND "
8879  "co.conkey = array[a.attnum])\n");
8880 
8882  "LEFT JOIN pg_catalog.pg_constraint copk ON "
8883  "(copk.conrelid = src.tbloid\n"
8884  " AND copk.contype = 'p' AND "
8885  "copk.conkey @> array[a.attnum])\n"
8886  "WHERE a.attnum > 0::pg_catalog.int2\n"
8887  "ORDER BY a.attrelid, a.attnum");
8888 
8889  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8890 
8891  ntups = PQntuples(res);
8892 
8893  i_attrelid = PQfnumber(res, "attrelid");
8894  i_attnum = PQfnumber(res, "attnum");
8895  i_attname = PQfnumber(res, "attname");
8896  i_atttypname = PQfnumber(res, "atttypname");
8897  i_attstattarget = PQfnumber(res, "attstattarget");
8898  i_attstorage = PQfnumber(res, "attstorage");
8899  i_typstorage = PQfnumber(res, "typstorage");
8900  i_attidentity = PQfnumber(res, "attidentity");
8901  i_attgenerated = PQfnumber(res, "attgenerated");
8902  i_attisdropped = PQfnumber(res, "attisdropped");
8903  i_attlen = PQfnumber(res, "attlen");
8904  i_attalign = PQfnumber(res, "attalign");
8905  i_attislocal = PQfnumber(res, "attislocal");
8906  i_notnull_name = PQfnumber(res, "notnull_name");
8907  i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
8908  i_notnull_is_pk = PQfnumber(res, "notnull_is_pk");
8909  i_notnull_inh = PQfnumber(res, "notnull_inh");
8910  i_attoptions = PQfnumber(res, "attoptions");
8911  i_attcollation = PQfnumber(res, "attcollation");
8912  i_attcompression = PQfnumber(res, "attcompression");
8913  i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8914  i_attmissingval = PQfnumber(res, "attmissingval");
8915  i_atthasdef = PQfnumber(res, "atthasdef");
8916 
8917  /* Within the next loop, we'll accumulate OIDs of tables with defaults */
8918  resetPQExpBuffer(tbloids);
8919  appendPQExpBufferChar(tbloids, '{');
8920 
8921  /*
8922  * Outer loop iterates once per table, not once per row. Incrementing of
8923  * r is handled by the inner loop.
8924  */
8925  curtblindx = -1;
8926  for (int r = 0; r < ntups;)
8927  {
8928  Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
8929  TableInfo *tbinfo = NULL;
8930  int numatts;
8931  bool hasdefaults;
8932  int notnullcount;
8933 
8934  /* Count rows for this table */
8935  for (numatts = 1; numatts < ntups - r; numatts++)
8936  if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
8937  break;
8938 
8939  /*
8940  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8941  * order.
8942  */
8943  while (++curtblindx < numTables)
8944  {
8945  tbinfo = &tblinfo[curtblindx];
8946  if (tbinfo->dobj.catId.oid == attrelid)
8947  break;
8948  }
8949  if (curtblindx >= numTables)
8950  pg_fatal("unrecognized table OID %u", attrelid);
8951  /* cross-check that we only got requested tables */
8952  if (tbinfo->relkind == RELKIND_SEQUENCE ||
8953  !tbinfo->interesting)
8954  pg_fatal("unexpected column data for table \"%s\"",
8955  tbinfo->dobj.name);
8956 
8957  notnullcount = 0;
8958 
8959  /* Save data for this table */
8960  tbinfo->numatts = numatts;
8961  tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
8962  tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
8963  tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
8964  tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
8965  tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
8966  tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
8967  tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
8968  tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
8969  tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
8970  tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
8971  tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
8972  tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
8973  tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
8974  tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
8975  tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
8976  tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
8977  tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
8978  tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
8979  tbinfo->notnull_throwaway = (bool *) pg_malloc(numatts * sizeof(bool));
8980  tbinfo->notnull_inh = (bool *) pg_malloc(numatts * sizeof(bool));
8981  tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
8982  hasdefaults = false;
8983 
8984  for (int j = 0; j < numatts; j++, r++)
8985  {
8986  bool use_named_notnull = false;
8987  bool use_unnamed_notnull = false;
8988  bool use_throwaway_notnull = false;
8989 
8990  if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
8991  pg_fatal("invalid column numbering in table \"%s\"",
8992  tbinfo->dobj.name);
8993  tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
8994  tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
8995  if (PQgetisnull(res, r, i_attstattarget))
8996  tbinfo->attstattarget[j] = -1;
8997  else
8998  tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
8999  tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
9000  tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
9001  tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
9002  tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
9003  tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
9004  tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
9005  tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
9006  tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
9007  tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
9008 
9009  /*
9010  * Not-null constraints require a jumping through a few hoops.
9011  * First, if the user has specified a constraint name that's not
9012  * the system-assigned default name, then we need to preserve
9013  * that. But if they haven't, then we don't want to use the
9014  * verbose syntax in the dump output. (Also, in versions prior to
9015  * 17, there was no constraint name at all.)
9016  *
9017  * (XXX Comparing the name this way to a supposed default name is
9018  * a bit of a hack, but it beats having to store a boolean flag in
9019  * pg_constraint just for this, or having to compute the knowledge
9020  * at pg_dump time from the server.)
9021  *
9022  * We also need to know if a column is part of the primary key. In
9023  * that case, we want to mark the column as not-null at table
9024  * creation time, so that the table doesn't have to be scanned to
9025  * check for nulls when the PK is created afterwards; this is
9026  * especially critical during pg_upgrade (where the data would not
9027  * be scanned at all otherwise.) If the column is part of the PK
9028  * and does not have any other not-null constraint, then we
9029  * fabricate a throwaway constraint name that we later use to
9030  * remove the constraint after the PK has been created.
9031  *
9032  * For inheritance child tables, we don't want to print not-null
9033  * when the constraint was defined at the parent level instead of
9034  * locally.
9035  */
9036 
9037  /*
9038  * We use notnull_inh to suppress unwanted not-null constraints in
9039  * inheritance children, when said constraints come from the
9040  * parent(s).
9041  */
9042  tbinfo->notnull_inh[j] = PQgetvalue(res, r, i_notnull_inh)[0] == 't';
9043 
9044  if (fout->remoteVersion < 170000)
9045  {
9046  if (!PQgetisnull(res, r, i_notnull_name) &&
9047  dopt->binary_upgrade &&
9048  !tbinfo->ispartition &&
9049  tbinfo->notnull_inh[j])
9050  {
9051  use_named_notnull = true;
9052  /* XXX should match ChooseConstraintName better */
9053  tbinfo->notnull_constrs[j] =
9054  psprintf("%s_%s_not_null", tbinfo->dobj.name,
9055  tbinfo->attnames[j]);
9056  }
9057  else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
9058  use_throwaway_notnull = true;
9059  else if (!PQgetisnull(res, r, i_notnull_name))
9060  use_unnamed_notnull = true;
9061  }
9062  else
9063  {
9064  if (!PQgetisnull(res, r, i_notnull_name))
9065  {
9066  /*
9067  * In binary upgrade of inheritance child tables, must
9068  * have a constraint name that we can UPDATE later.
9069  */
9070  if (dopt->binary_upgrade &&
9071  !tbinfo->ispartition &&
9072  tbinfo->notnull_inh[j])
9073  {
9074  use_named_notnull = true;
9075  tbinfo->notnull_constrs[j] =
9076  pstrdup(PQgetvalue(res, r, i_notnull_name));
9077 
9078  }
9079  else
9080  {
9081  char *default_name;
9082 
9083  /* XXX should match ChooseConstraintName better */
9084  default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
9085  tbinfo->attnames[j]);
9086  if (strcmp(default_name,
9087  PQgetvalue(res, r, i_notnull_name)) == 0)
9088  use_unnamed_notnull = true;
9089  else
9090  {
9091  use_named_notnull = true;
9092  tbinfo->notnull_constrs[j] =
9093  pstrdup(PQgetvalue(res, r, i_notnull_name));
9094  }
9095  }
9096  }
9097  else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
9098  use_throwaway_notnull = true;
9099  }
9100 
9101  if (use_unnamed_notnull)
9102  {
9103  tbinfo->notnull_constrs[j] = "";
9104  tbinfo->notnull_throwaway[j] = false;
9105  }
9106  else if (use_named_notnull)
9107  {
9108  /* The name itself has already been determined */
9109  tbinfo->notnull_throwaway[j] = false;
9110  }
9111  else if (use_throwaway_notnull)
9112  {
9113  /*
9114  * Give this constraint a throwaway name.
9115  */
9116  tbinfo->notnull_constrs[j] =
9117  psprintf("pgdump_throwaway_notnull_%d", notnullcount++);
9118  tbinfo->notnull_throwaway[j] = true;
9119  tbinfo->notnull_inh[j] = false;
9120  }
9121  else
9122  {
9123  tbinfo->notnull_constrs[j] = NULL;
9124  tbinfo->notnull_throwaway[j] = false;
9125  }
9126 
9127  /*
9128  * Throwaway constraints must always be NO INHERIT; otherwise do
9129  * what the catalog says.
9130  */
9131  tbinfo->notnull_noinh[j] = use_throwaway_notnull ||
9132  PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
9133 
9134  tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
9135  tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
9136  tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
9137  tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
9138  tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
9139  tbinfo->attrdefs[j] = NULL; /* fix below */
9140  if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
9141  hasdefaults = true;
9142  }
9143 
9144  if (hasdefaults)
9145  {
9146  /* Collect OIDs of interesting tables that have defaults */
9147  if (tbloids->len > 1) /* do we have more than the '{'? */
9148  appendPQExpBufferChar(tbloids, ',');
9149  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
9150  }
9151  }
9152 
9153  PQclear(res);
9154 
9155  /*
9156  * Now get info about column defaults. This is skipped for a data-only
9157  * dump, as it is only needed for table schemas.
9158  */
9159  if (!dopt->dataOnly && tbloids->len > 1)
9160  {
9161  AttrDefInfo *attrdefs;
9162  int numDefaults;
9163  TableInfo *tbinfo = NULL;
9164 
9165  pg_log_info("finding table default expressions");
9166 
9167  appendPQExpBufferChar(tbloids, '}');
9168 
9169  printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9170  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9171  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9172  "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9173  "ORDER BY a.adrelid, a.adnum",
9174  tbloids->data);
9175 
9176  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9177 
9178  numDefaults = PQntuples(res);
9179  attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9180 
9181  curtblindx = -1;
9182  for (int j = 0; j < numDefaults; j++)
9183  {
9184  Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9185  Oid adoid = atooid(PQgetvalue(res, j, 1));
9186  Oid adrelid = atooid(PQgetvalue(res, j, 2));
9187  int adnum = atoi(PQgetvalue(res, j, 3));
9188  char *adsrc = PQgetvalue(res, j, 4);
9189 
9190  /*
9191  * Locate the associated TableInfo; we rely on tblinfo[] being in
9192  * OID order.
9193  */
9194  if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9195  {
9196  while (++curtblindx < numTables)
9197  {
9198  tbinfo = &tblinfo[curtblindx];
9199  if (tbinfo->dobj.catId.oid == adrelid)
9200  break;
9201  }
9202  if (curtblindx >= numTables)
9203  pg_fatal("unrecognized table OID %u", adrelid);
9204  }
9205 
9206  if (adnum <= 0 || adnum > tbinfo->numatts)
9207  pg_fatal("invalid adnum value %d for table \"%s\"",
9208  adnum, tbinfo->dobj.name);
9209 
9210  /*
9211  * dropped columns shouldn't have defaults, but just in case,
9212  * ignore 'em
9213  */
9214  if (tbinfo->attisdropped[adnum - 1])
9215  continue;
9216 
9217  attrdefs[j].dobj.objType = DO_ATTRDEF;
9218  attrdefs[j].dobj.catId.tableoid = adtableoid;
9219  attrdefs[j].dobj.catId.oid = adoid;
9220  AssignDumpId(&attrdefs[j].dobj);
9221  attrdefs[j].adtable = tbinfo;
9222  attrdefs[j].adnum = adnum;
9223  attrdefs[j].adef_expr = pg_strdup(adsrc);
9224 
9225  attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9226  attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9227 
9228  attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9229 
9230  /*
9231  * Figure out whether the default/generation expression should be
9232  * dumped as part of the main CREATE TABLE (or similar) command or
9233  * as a separate ALTER TABLE (or similar) command. The preference
9234  * is to put it into the CREATE command, but in some cases that's
9235  * not possible.
9236  */
9237  if (tbinfo->attgenerated[adnum - 1])
9238  {
9239  /*
9240  * Column generation expressions cannot be dumped separately,
9241  * because there is no syntax for it. By setting separate to
9242  * false here we prevent the "default" from being processed as
9243  * its own dumpable object. Later, flagInhAttrs() will mark
9244  * it as not to be dumped at all, if possible (that is, if it
9245  * can be inherited from a parent).
9246  */
9247  attrdefs[j].separate = false;
9248  }
9249  else if (tbinfo->relkind == RELKIND_VIEW)
9250  {
9251  /*
9252  * Defaults on a VIEW must always be dumped as separate ALTER
9253  * TABLE commands.
9254  */
9255  attrdefs[j].separate = true;
9256  }
9257  else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9258  {
9259  /* column will be suppressed, print default separately */
9260  attrdefs[j].separate = true;
9261  }
9262  else
9263  {
9264  attrdefs[j].separate = false;
9265  }
9266 
9267  if (!attrdefs[j].separate)
9268  {
9269  /*
9270  * Mark the default as needing to appear before the table, so
9271  * that any dependencies it has must be emitted before the
9272  * CREATE TABLE. If this is not possible, we'll change to
9273  * "separate" mode while sorting dependencies.
9274  */
9275  addObjectDependency(&tbinfo->dobj,
9276  attrdefs[j].dobj.dumpId);
9277  }
9278 
9279  tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9280  }
9281 
9282  PQclear(res);
9283  }
9284 
9285  /*
9286  * Get info about table CHECK constraints. This is skipped for a
9287  * data-only dump, as it is only needed for table schemas.
9288  */
9289  if (!dopt->dataOnly && checkoids->len > 2)
9290  {
9291  ConstraintInfo *constrs;
9292  int numConstrs;
9293  int i_tableoid;
9294  int i_oid;
9295  int i_conrelid;
9296  int i_conname;
9297  int i_consrc;
9298  int i_conislocal;
9299  int i_convalidated;
9300 
9301  pg_log_info("finding table check constraints");
9302 
9303  resetPQExpBuffer(q);
9305  "SELECT c.tableoid, c.oid, conrelid, conname, "
9306  "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9307  "conislocal, convalidated "
9308  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9309  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9310  "WHERE contype = 'c' "
9311  "ORDER BY c.conrelid, c.conname",
9312  checkoids->data);
9313 
9314  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9315 
9316  numConstrs = PQntuples(res);
9317  constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9318 
9319  i_tableoid = PQfnumber(res, "tableoid");
9320  i_oid = PQfnumber(res, "oid");
9321  i_conrelid = PQfnumber(res, "conrelid");
9322  i_conname = PQfnumber(res, "conname");
9323  i_consrc = PQfnumber(res, "consrc");
9324  i_conislocal = PQfnumber(res, "conislocal");
9325  i_convalidated = PQfnumber(res, "convalidated");
9326 
9327  /* As above, this loop iterates once per table, not once per row */
9328  curtblindx = -1;
9329  for (int j = 0; j < numConstrs;)
9330  {
9331  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9332  TableInfo *tbinfo = NULL;
9333  int numcons;
9334 
9335  /* Count rows for this table */
9336  for (numcons = 1; numcons < numConstrs - j; numcons++)
9337  if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9338  break;
9339 
9340  /*
9341  * Locate the associated TableInfo; we rely on tblinfo[] being in
9342  * OID order.
9343  */
9344  while (++curtblindx < numTables)
9345  {
9346  tbinfo = &tblinfo[curtblindx];
9347  if (tbinfo->dobj.catId.oid == conrelid)
9348  break;
9349  }
9350  if (curtblindx >= numTables)
9351  pg_fatal("unrecognized table OID %u", conrelid);
9352 
9353  if (numcons != tbinfo->ncheck)
9354  {
9355  pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9356  "expected %d check constraints on table \"%s\" but found %d",
9357  tbinfo->ncheck),
9358  tbinfo->ncheck, tbinfo->dobj.name, numcons);
9359  pg_log_error_hint("The system catalogs might be corrupted.");
9360  exit_nicely(1);
9361  }
9362 
9363  tbinfo->checkexprs = constrs + j;
9364 
9365  for (int c = 0; c < numcons; c++, j++)
9366  {
9367  bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9368 
9369  constrs[j].dobj.objType = DO_CONSTRAINT;
9370  constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9371  constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9372  AssignDumpId(&constrs[j].dobj);
9373  constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9374  constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9375  constrs[j].contable = tbinfo;
9376  constrs[j].condomain = NULL;
9377  constrs[j].contype = 'c';
9378  constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9379  constrs[j].confrelid = InvalidOid;
9380  constrs[j].conindex = 0;
9381  constrs[j].condeferrable = false;
9382  constrs[j].condeferred = false;
9383  constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9384 
9385  /*
9386  * An unvalidated constraint needs to be dumped separately, so
9387  * that potentially-violating existing data is loaded before
9388  * the constraint.
9389  */
9390  constrs[j].separate = !validated;
9391 
9392  constrs[j].dobj.dump = tbinfo->dobj.dump;
9393 
9394  /*
9395  * Mark the constraint as needing to appear before the table
9396  * --- this is so that any other dependencies of the
9397  * constraint will be emitted before we try to create the
9398  * table. If the constraint is to be dumped separately, it
9399  * will be dumped after data is loaded anyway, so don't do it.
9400  * (There's an automatic dependency in the opposite direction
9401  * anyway, so don't need to add one manually here.)
9402  */
9403  if (!constrs[j].separate)
9404  addObjectDependency(&tbinfo->dobj,
9405  constrs[j].dobj.dumpId);
9406 
9407  /*
9408  * We will detect later whether the constraint must be split
9409  * out from the table definition.
9410  */
9411  }
9412  }
9413 
9414  PQclear(res);
9415  }
9416 
9417  destroyPQExpBuffer(q);
9418  destroyPQExpBuffer(tbloids);
9419  destroyPQExpBuffer(checkoids);
9420 }
#define ngettext(s, p, n)
Definition: c.h:1181
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
Definition: pg_dump.c:9440
#define exit_nicely(code)
Definition: pg_dumpall.c:124
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
DumpableObject dobj
Definition: pg_dump.h:380
char * adef_expr
Definition: pg_dump.h:383
TableInfo * adtable
Definition: pg_dump.h:381
bool separate
Definition: pg_dump.h:384
bool dataOnly
Definition: pg_backup.h:170
char * attidentity
Definition: pg_dump.h:339
char ** notnull_constrs
Definition: pg_dump.h:349
int ncheck
Definition: pg_dump.h:308
bool ispartition
Definition: pg_dump.h:322
bool * attislocal
Definition: pg_dump.h:343
char * attgenerated
Definition: pg_dump.h:340
int * attlen
Definition: pg_dump.h:341
char ** attfdwoptions
Definition: pg_dump.h:347
bool * attisdropped
Definition: pg_dump.h:338
bool needs_override
Definition: pg_dump.h:358
struct _constraintInfo * checkexprs
Definition: pg_dump.h:357
int * attstattarget
Definition: pg_dump.h:335
char * typstorage
Definition: pg_dump.h:337
int numatts
Definition: pg_dump.h:332
struct _attrDefInfo ** attrdefs
Definition: pg_dump.h:356
char ** attoptions
Definition: pg_dump.h:344
bool * notnull_throwaway
Definition: pg_dump.h:354
Oid * attcollation
Definition: pg_dump.h:345
bool * notnull_noinh
Definition: pg_dump.h:353
char * attstorage
Definition: pg_dump.h:336
char ** atttypnames
Definition: pg_dump.h:334
char ** attmissingval
Definition: pg_dump.h:348
char ** attnames
Definition: pg_dump.h:333
char * attalign
Definition: pg_dump.h:342
char * attcompression
Definition: pg_dump.h:346
bool * notnull_inh
Definition: pg_dump.h:355

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, _dumpOptions::dataOnly, destroyPQExpBuffer(), DO_ATTRDEF, DO_CONSTRAINT, _tableInfo::dobj, _attrDefInfo::dobj, _constraintInfo::dobj, Archive::dopt, _dumpableObject::dump, _dumpableObject::dumpId, ExecuteSqlQuery(), exit_nicely, i, _tableInfo::interesting, InvalidOid, _tableInfo::ispartition, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull_constrs, _tableInfo::notnull_inh, _tableInfo::notnull_noinh, _tableInfo::notnull_throwaway, _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(), psprintf(), pstrdup(), _tableInfo::relkind, Archive::remoteVersion, res, resetPQExpBuffer(), _attrDefInfo::separate, _constraintInfo::separate, shouldPrintColumn(), CatalogId::tableoid, and _tableInfo::typstorage.

Referenced by getSchemaData().

◆ getTables()

TableInfo* getTables ( Archive fout,
int *  numTables 
)

Definition at line 6701 of file pg_dump.c.

6702 {
6703  DumpOptions *dopt = fout->dopt;
6704  PGresult *res;
6705  int ntups;
6706  int i;
6707  PQExpBuffer query = createPQExpBuffer();
6708  TableInfo *tblinfo;
6709  int i_reltableoid;
6710  int i_reloid;
6711  int i_relname;
6712  int i_relnamespace;
6713  int i_relkind;
6714  int i_reltype;
6715  int i_relowner;
6716  int i_relchecks;
6717  int i_relhasindex;
6718  int i_relhasrules;
6719  int i_relpages;
6720  int i_toastpages;
6721  int i_owning_tab;
6722  int i_owning_col;
6723  int i_reltablespace;
6724  int i_relhasoids;
6725  int i_relhastriggers;
6726  int i_relpersistence;
6727  int i_relispopulated;
6728  int i_relreplident;
6729  int i_relrowsec;
6730  int i_relforcerowsec;
6731  int i_relfrozenxid;
6732  int i_toastfrozenxid;
6733  int i_toastoid;
6734  int i_relminmxid;
6735  int i_toastminmxid;
6736  int i_reloptions;
6737  int i_checkoption;
6738  int i_toastreloptions;
6739  int i_reloftype;
6740  int i_foreignserver;
6741  int i_amname;
6742  int i_is_identity_sequence;
6743  int i_relacl;
6744  int i_acldefault;
6745  int i_ispartition;
6746 
6747  /*
6748  * Find all the tables and table-like objects.
6749  *
6750  * We must fetch all tables in this phase because otherwise we cannot
6751  * correctly identify inherited columns, owned sequences, etc.
6752  *
6753  * We include system catalogs, so that we can work if a user table is
6754  * defined to inherit from a system catalog (pretty weird, but...)
6755  *
6756  * Note: in this phase we should collect only a minimal amount of
6757  * information about each table, basically just enough to decide if it is
6758  * interesting. In particular, since we do not yet have lock on any user
6759  * table, we MUST NOT invoke any server-side data collection functions
6760  * (for instance, pg_get_partkeydef()). Those are likely to fail or give
6761  * wrong answers if any concurrent DDL is happening.
6762  */
6763 
6764  appendPQExpBufferStr(query,
6765  "SELECT c.tableoid, c.oid, c.relname, "
6766  "c.relnamespace, c.relkind, c.reltype, "
6767  "c.relowner, "
6768  "c.relchecks, "
6769  "c.relhasindex, c.relhasrules, c.relpages, "
6770  "c.relhastriggers, "
6771  "c.relpersistence, "
6772  "c.reloftype, "
6773  "c.relacl, "
6774  "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
6775  " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
6776  "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
6777  "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
6778  "ELSE 0 END AS foreignserver, "
6779  "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
6780  "tc.oid AS toid, "
6781  "tc.relpages AS toastpages, "
6782  "tc.reloptions AS toast_reloptions, "
6783  "d.refobjid AS owning_tab, "
6784  "d.refobjsubid AS owning_col, "
6785  "tsp.spcname AS reltablespace, ");
6786 
6787  if (fout->remoteVersion >= 120000)
6788  appendPQExpBufferStr(query,
6789  "false AS relhasoids, ");
6790  else
6791  appendPQExpBufferStr(query,
6792  "c.relhasoids, ");
6793 
6794  if (fout->remoteVersion >= 90300)
6795  appendPQExpBufferStr(query,
6796  "c.relispopulated, ");
6797  else
6798  appendPQExpBufferStr(query,
6799  "'t' as relispopulated, ");
6800 
6801  if (fout->remoteVersion >= 90400)
6802  appendPQExpBufferStr(query,
6803  "c.relreplident, ");
6804  else
6805  appendPQExpBufferStr(query,
6806  "'d' AS relreplident, ");
6807 
6808  if (fout->remoteVersion >= 90500)
6809  appendPQExpBufferStr(query,
6810  "c.relrowsecurity, c.relforcerowsecurity, ");
6811  else
6812  appendPQExpBufferStr(query,
6813  "false AS relrowsecurity, "
6814  "false AS relforcerowsecurity, ");
6815 
6816  if (fout->remoteVersion >= 90300)
6817  appendPQExpBufferStr(query,
6818  "c.relminmxid, tc.relminmxid AS tminmxid, ");
6819  else
6820  appendPQExpBufferStr(query,
6821  "0 AS relminmxid, 0 AS tminmxid, ");
6822 
6823  if (fout->remoteVersion >= 90300)
6824  appendPQExpBufferStr(query,
6825  "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
6826  "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
6827  "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
6828  else
6829  appendPQExpBufferStr(query,
6830  "c.reloptions, NULL AS checkoption, ");
6831 
6832  if (fout->remoteVersion >= 90600)
6833  appendPQExpBufferStr(query,
6834  "am.amname, ");
6835  else
6836  appendPQExpBufferStr(query,
6837  "NULL AS amname, ");
6838 
6839  if (fout->remoteVersion >= 90600)
6840  appendPQExpBufferStr(query,
6841  "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
6842  else
6843  appendPQExpBufferStr(query,
6844  "false AS is_identity_sequence, ");
6845 
6846  if (fout->remoteVersion >= 100000)
6847  appendPQExpBufferStr(query,
6848  "c.relispartition AS ispartition ");
6849  else
6850  appendPQExpBufferStr(query,
6851  "false AS ispartition ");
6852 
6853  /*
6854  * Left join to pg_depend to pick up dependency info linking sequences to
6855  * their owning column, if any (note this dependency is AUTO except for
6856  * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
6857  * collect the spcname.
6858  */
6859  appendPQExpBufferStr(query,
6860  "\nFROM pg_class c\n"
6861  "LEFT JOIN pg_depend d ON "
6862  "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
6863  "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
6864  "d.objsubid = 0 AND "
6865  "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
6866  "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
6867 
6868  /*
6869  * In 9.6 and up, left join to pg_am to pick up the amname.
6870  */
6871  if (fout->remoteVersion >= 90600)
6872  appendPQExpBufferStr(query,
6873  "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
6874 
6875  /*
6876  * We purposefully ignore toast OIDs for partitioned tables; the reason is
6877  * that versions 10 and 11 have them, but later versions do not, so
6878  * emitting them causes the upgrade to fail.
6879  */
6880  appendPQExpBufferStr(query,
6881  "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
6882  " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
6883  " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
6884 
6885  /*
6886  * Restrict to interesting relkinds (in particular, not indexes). Not all
6887  * relkinds are possible in older servers, but it's not worth the trouble
6888  * to emit a version-dependent list.
6889  *
6890  * Composite-type table entries won't be dumped as such, but we have to
6891  * make a DumpableObject for them so that we can track dependencies of the
6892  * composite type (pg_depend entries for columns of the composite type
6893  * link to the pg_class entry not the pg_type entry).
6894  */
6895  appendPQExpBufferStr(query,
6896  "WHERE c.relkind IN ("
6897  CppAsString2(RELKIND_RELATION) ", "
6898  CppAsString2(RELKIND_SEQUENCE) ", "
6899  CppAsString2(RELKIND_VIEW) ", "
6900  CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
6901  CppAsString2(RELKIND_MATVIEW) ", "
6902  CppAsString2(RELKIND_FOREIGN_TABLE) ", "
6903  CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
6904  "ORDER BY c.oid");
6905 
6906  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6907 
6908  ntups = PQntuples(res);
6909 
6910  *numTables = ntups;
6911 
6912  /*
6913  * Extract data from result and lock dumpable tables. We do the locking
6914  * before anything else, to minimize the window wherein a table could
6915  * disappear under us.
6916  *
6917  * Note that we have to save info about all tables here, even when dumping
6918  * only one, because we don't yet know which tables might be inheritance
6919  * ancestors of the target table.
6920  */
6921  tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
6922 
6923  i_reltableoid = PQfnumber(res, "tableoid");
6924  i_reloid = PQfnumber(res, "oid");
6925  i_relname = PQfnumber(res, "relname");
6926  i_relnamespace = PQfnumber(res, "relnamespace");
6927  i_relkind = PQfnumber(res, "relkind");
6928  i_reltype = PQfnumber(res, "reltype");
6929  i_relowner = PQfnumber(res, "relowner");
6930  i_relchecks = PQfnumber(res, "relchecks");
6931  i_relhasindex = PQfnumber(res, "relhasindex");
6932  i_relhasrules = PQfnumber(res, "relhasrules");
6933  i_relpages = PQfnumber(res, "relpages");
6934  i_toastpages = PQfnumber(res, "toastpages");
6935  i_owning_tab = PQfnumber(res, "owning_tab");
6936  i_owning_col = PQfnumber(res, "owning_col");
6937  i_reltablespace = PQfnumber(res, "reltablespace");
6938  i_relhasoids = PQfnumber(res, "relhasoids");
6939  i_relhastriggers = PQfnumber(res, "relhastriggers");
6940  i_relpersistence = PQfnumber(res, "relpersistence");
6941  i_relispopulated = PQfnumber(res, "relispopulated");
6942  i_relreplident = PQfnumber(res, "relreplident");
6943  i_relrowsec = PQfnumber(res, "relrowsecurity");
6944  i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
6945  i_relfrozenxid = PQfnumber(res, "relfrozenxid");
6946  i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
6947  i_toastoid = PQfnumber(res, "toid");
6948  i_relminmxid = PQfnumber(res, "relminmxid");
6949  i_toastminmxid = PQfnumber(res, "tminmxid");
6950  i_reloptions = PQfnumber(res, "reloptions");
6951  i_checkoption = PQfnumber(res, "checkoption");
6952  i_toastreloptions = PQfnumber(res, "toast_reloptions");
6953  i_reloftype = PQfnumber(res, "reloftype");
6954  i_foreignserver = PQfnumber(res, "foreignserver");
6955  i_amname = PQfnumber(res, "amname");
6956  i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
6957  i_relacl = PQfnumber(res, "relacl");
6958  i_acldefault = PQfnumber(res, "acldefault");
6959  i_ispartition = PQfnumber(res, "ispartition");
6960 
6961  if (dopt->lockWaitTimeout)
6962  {
6963  /*
6964  * Arrange to fail instead of waiting forever for a table lock.
6965  *
6966  * NB: this coding assumes that the only queries issued within the
6967  * following loop are LOCK TABLEs; else the timeout may be undesirably
6968  * applied to other things too.
6969  */
6970  resetPQExpBuffer(query);
6971  appendPQExpBufferStr(query, "SET statement_timeout = ");
6973  ExecuteSqlStatement(fout, query->data);
6974  }
6975 
6976  resetPQExpBuffer(query);
6977 
6978  for (i = 0; i < ntups; i++)
6979  {
6980  tblinfo[i].dobj.objType = DO_TABLE;
6981  tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
6982  tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
6983  AssignDumpId(&tblinfo[i].dobj);
6984  tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
6985  tblinfo[i].dobj.namespace =
6986  findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
6987  tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
6988  tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6989  tblinfo[i].dacl.privtype = 0;
6990  tblinfo[i].dacl.initprivs = NULL;
6991  tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
6992  tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
6993  tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
6994  tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
6995  tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
6996  tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
6997  tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
6998  if (PQgetisnull(res, i, i_toastpages))
6999  tblinfo[i].toastpages = 0;
7000  else
7001  tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
7002  if (PQgetisnull(res, i, i_owning_tab))
7003  {
7004  tblinfo[i].owning_tab = InvalidOid;
7005  tblinfo[i].owning_col = 0;
7006  }
7007  else
7008  {
7009  tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
7010  tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
7011  }
7012  tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
7013  tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
7014  tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
7015  tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
7016  tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
7017  tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
7018  tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
7019  tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
7020  tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
7021  tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
7022  tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
7023  tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
7024  tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
7025  tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
7026  if (PQgetisnull(res, i, i_checkoption))
7027  tblinfo[i].checkoption = NULL;
7028  else
7029  tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
7030  tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
7031  tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
7032  tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
7033  if (PQgetisnull(res, i, i_amname))
7034  tblinfo[i].amname = NULL;
7035  else
7036  tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
7037  tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
7038  tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
7039 
7040  /* other fields were zeroed above */
7041 
7042  /*
7043  * Decide whether we want to dump this table.
7044  */
7045  if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
7046  tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
7047  else
7048  selectDumpableTable(&tblinfo[i], fout);
7049 
7050  /*
7051  * Now, consider the table "interesting" if we need to dump its
7052  * definition or its data. Later on, we'll skip a lot of data
7053  * collection for uninteresting tables.
7054  *
7055  * Note: the "interesting" flag will also be set by flagInhTables for
7056  * parents of interesting tables, so that we collect necessary
7057  * inheritance info even when the parents are not themselves being
7058  * dumped. This is the main reason why we need an "interesting" flag
7059  * that's separate from the components-to-dump bitmask.
7060  */
7061  tblinfo[i].interesting = (tblinfo[i].dobj.dump &
7063  DUMP_COMPONENT_DATA)) != 0;
7064 
7065  tblinfo[i].dummy_view = false; /* might get set during sort */
7066  tblinfo[i].postponed_def = false; /* might get set during sort */
7067 
7068  /* Tables have data */
7069  tblinfo[i].dobj.components |= DUMP_COMPONENT_DATA;
7070 
7071  /* Mark whether table has an ACL */
7072  if (!PQgetisnull(res, i, i_relacl))
7073  tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
7074  tblinfo[i].hascolumnACLs = false; /* may get set later */
7075 
7076  /*
7077  * Read-lock target tables to make sure they aren't DROPPED or altered
7078  * in schema before we get around to dumping them.
7079  *
7080  * Note that we don't explicitly lock parents of the target tables; we
7081  * assume our lock on the child is enough to prevent schema
7082  * alterations to parent tables.
7083  *
7084  * NOTE: it'd be kinda nice to lock other relations too, not only
7085  * plain or partitioned tables, but the backend doesn't presently
7086  * allow that.
7087  *
7088  * We only need to lock the table for certain components; see
7089  * pg_dump.h
7090  */
7091  if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
7092  (tblinfo[i].relkind == RELKIND_RELATION ||
7093  tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
7094  {
7095  /*
7096  * Tables are locked in batches. When dumping from a remote
7097  * server this can save a significant amount of time by reducing
7098  * the number of round trips.
7099  */
7100  if (query->len == 0)
7101  appendPQExpBuffer(query, "LOCK TABLE %s",
7102  fmtQualifiedDumpable(&tblinfo[i]));
7103  else
7104  {
7105  appendPQExpBuffer(query, ", %s",
7106  fmtQualifiedDumpable(&tblinfo[i]));
7107 
7108  /* Arbitrarily end a batch when query length reaches 100K. */
7109  if (query->len >= 100000)
7110  {
7111  /* Lock another batch of tables. */
7112  appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7113  ExecuteSqlStatement(fout, query->data);
7114  resetPQExpBuffer(query);
7115  }
7116  }
7117  }
7118  }
7119 
7120  if (query->len != 0)
7121  {
7122  /* Lock the tables in the last batch. */
7123  appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
7124  ExecuteSqlStatement(fout, query->data);
7125  }
7126 
7127  if (dopt->lockWaitTimeout)
7128  {
7129  ExecuteSqlStatement(fout, "SET statement_timeout = 0");
7130  }
7131 
7132  PQclear(res);
7133 
7134  destroyPQExpBuffer(query);
7135 
7136  return tblinfo;
7137 }
#define CppAsString2(x)
Definition: c.h:327
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
Definition: connection.c:177
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
void ExecuteSqlStatement(Archive *AHX, const char *query)
Definition: pg_backup_db.c:278
static void selectDumpableTable(TableInfo *tbinfo, Archive *fout)
Definition: pg_dump.c:1839
#define fmtQualifiedDumpable(obj)
Definition: pg_dump.c:176
#define DUMP_COMPONENT_DATA
Definition: pg_dump.h:98
#define DUMP_COMPONENTS_REQUIRING_LOCK
Definition: pg_dump.h:128
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
const char * lockWaitTimeout
Definition: pg_backup.h:173
char * reltablespace
Definition: pg_dump.h:292
Oid reloftype
Definition: pg_dump.h:310
char * toast_reloptions
Definition: pg_dump.h:295
DumpableAcl dacl
Definition: pg_dump.h:286
bool relispopulated
Definition: pg_dump.h:290
Oid reltype
Definition: pg_dump.h:309
bool hasoids
Definition: pg_dump.h:302
Oid toast_oid
Definition: pg_dump.h:305
Oid foreign_server
Definition: pg_dump.h:311
bool hasrules
Definition: pg_dump.h:297
uint32 frozenxid
Definition: pg_dump.h:303
int owning_col
Definition: pg_dump.h:314
char * checkoption
Definition: pg_dump.h:294
bool hastriggers
Definition: pg_dump.h:298
const char * rolname
Definition: pg_dump.h:287
char relreplident
Definition: pg_dump.h:291
uint32 minmxid
Definition: pg_dump.h:304
int toastpages
Definition: pg_dump.h:317
char * amname
Definition: pg_dump.h:359
bool dummy_view
Definition: pg_dump.h:320
bool forcerowsec
Definition: pg_dump.h:301
char relpersistence
Definition: pg_dump.h:289
char * reloptions
Definition: pg_dump.h:293
int relpages
Definition: pg_dump.h:316
uint32 toast_frozenxid
Definition: pg_dump.h:306
uint32 toast_minmxid
Definition: pg_dump.h:307
bool postponed_def
Definition: pg_dump.h:321

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_COMPONENTS_REQUIRING_LOCK, ExecuteSqlQuery(), ExecuteSqlStatement(), findNamespace(), fmtQualifiedDumpable, _tableInfo::forcerowsec, _tableInfo::foreign_server, _tableInfo::frozenxid, GetConnection(), 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, res, resetPQExpBuffer(), _tableInfo::rolname, _tableInfo::rowsec, selectDumpableTable(), CatalogId::tableoid, _tableInfo::toast_frozenxid, _tableInfo::toast_minmxid, _tableInfo::toast_oid, _tableInfo::toast_reloptions, and _tableInfo::toastpages.

Referenced by getSchemaData().

◆ getTransforms()

TransformInfo* getTransforms ( Archive fout,
int *  numTransforms 
)

Definition at line 8595 of file pg_dump.c.

8596 {
8597  PGresult *res;
8598  int ntups;
8599  int i;
8600  PQExpBuffer query;
8601  TransformInfo *transforminfo;
8602  int i_tableoid;
8603  int i_oid;
8604  int i_trftype;
8605  int i_trflang;
8606  int i_trffromsql;
8607  int i_trftosql;
8608 
8609  /* Transforms didn't exist pre-9.5 */
8610  if (fout->remoteVersion < 90500)
8611  {
8612  *numTransforms = 0;
8613  return NULL;
8614  }
8615 
8616  query = createPQExpBuffer();
8617 
8618  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8619  "trftype, trflang, trffromsql::oid, trftosql::oid "
8620  "FROM pg_transform "
8621  "ORDER BY 3,4");
8622 
8623  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8624 
8625  ntups = PQntuples(res);
8626 
8627  *numTransforms = ntups;
8628 
8629  transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8630 
8631  i_tableoid = PQfnumber(res, "tableoid");
8632  i_oid = PQfnumber(res, "oid");
8633  i_trftype = PQfnumber(res, "trftype");
8634  i_trflang = PQfnumber(res, "trflang");
8635  i_trffromsql = PQfnumber(res, "trffromsql");
8636  i_trftosql = PQfnumber(res, "trftosql");
8637 
8638  for (i = 0; i < ntups; i++)
8639  {
8640  PQExpBufferData namebuf;
8641  TypeInfo *typeInfo;
8642  char *lanname;
8643 
8644  transforminfo[i].dobj.objType = DO_TRANSFORM;
8645  transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8646  transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8647  AssignDumpId(&transforminfo[i].dobj);
8648  transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8649  transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8650  transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8651  transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8652 
8653  /*
8654  * Try to name transform as concatenation of type and language name.
8655  * This is only used for purposes of sorting. If we fail to find
8656  * either, the name will be an empty string.
8657  */
8658  initPQExpBuffer(&namebuf);
8659  typeInfo = findTypeByOid(transforminfo[i].trftype);
8660  lanname = get_language_name(fout, transforminfo[i].trflang);
8661  if (typeInfo && lanname)
8662  appendPQExpBuffer(&namebuf, "%s %s",
8663  typeInfo->dobj.name, lanname);
8664  transforminfo[i].dobj.name = namebuf.data;
8665  free(lanname);
8666 
8667  /* Decide whether we want to dump it */
8668  selectDumpableObject(&(transforminfo[i].dobj), fout);
8669  }
8670 
8671  PQclear(res);
8672 
8673  destroyPQExpBuffer(query);
8674 
8675  return transforminfo;
8676 }
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8572
DumpableObject dobj
Definition: pg_dump.h:510
Oid trffromsql
Definition: pg_dump.h:513

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, res, 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 8106 of file pg_dump.c.

8107 {
8108  PQExpBuffer query = createPQExpBuffer();
8109  PQExpBuffer tbloids = createPQExpBuffer();
8110  PGresult *res;
8111  int ntups;
8112  int curtblindx;
8113  TriggerInfo *tginfo;
8114  int i_tableoid,
8115  i_oid,
8116  i_tgrelid,
8117  i_tgname,
8118  i_tgenabled,
8119  i_tgispartition,
8120  i_tgdef;
8121 
8122  /*
8123  * We want to perform just one query against pg_trigger. However, we
8124  * mustn't try to select every row of the catalog and then sort it out on
8125  * the client side, because some of the server-side functions we need
8126  * would be unsafe to apply to tables we don't have lock on. Hence, we
8127  * build an array of the OIDs of tables we care about (and now have lock
8128  * on!), and use a WHERE clause to constrain which rows are selected.
8129  */
8130  appendPQExpBufferChar(tbloids, '{');
8131  for (int i = 0; i < numTables; i++)
8132  {
8133  TableInfo *tbinfo = &tblinfo[i];
8134 
8135  if (!tbinfo->hastriggers ||
8136  !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8137  continue;
8138 
8139  /* OK, we need info for this table */
8140  if (tbloids->len > 1) /* do we have more than the '{'? */
8141  appendPQExpBufferChar(tbloids, ',');
8142  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8143  }
8144  appendPQExpBufferChar(tbloids, '}');
8145 
8146  if (fout->remoteVersion >= 150000)
8147  {
8148  /*
8149  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8150  * result in non-forward-compatible dumps of WHEN clauses due to
8151  * under-parenthesization.
8152  *
8153  * NB: We need to see partition triggers in case the tgenabled flag
8154  * has been changed from the parent.
8155  */
8156  appendPQExpBuffer(query,
8157  "SELECT t.tgrelid, t.tgname, "
8158  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8159  "t.tgenabled, t.tableoid, t.oid, "
8160  "t.tgparentid <> 0 AS tgispartition\n"
8161  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8162  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8163  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8164  "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
8165  "OR t.tgenabled != u.tgenabled) "
8166  "ORDER BY t.tgrelid, t.tgname",
8167  tbloids->data);
8168  }
8169  else if (fout->remoteVersion >= 130000)
8170  {
8171  /*
8172  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8173  * result in non-forward-compatible dumps of WHEN clauses due to
8174  * under-parenthesization.
8175  *
8176  * NB: We need to see tgisinternal triggers in partitions, in case the
8177  * tgenabled flag has been changed from the parent.
8178  */
8179  appendPQExpBuffer(query,
8180  "SELECT t.tgrelid, t.tgname, "
8181  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8182  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
8183  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8184  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8185  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8186  "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
8187  "ORDER BY t.tgrelid, t.tgname",
8188  tbloids->data);
8189  }
8190  else if (fout->remoteVersion >= 110000)
8191  {
8192  /*
8193  * NB: We need to see tgisinternal triggers in partitions, in case the
8194  * tgenabled flag has been changed from the parent. No tgparentid in
8195  * version 11-12, so we have to match them via pg_depend.
8196  *
8197  * See above about pretty=true in pg_get_triggerdef.
8198  */
8199  appendPQExpBuffer(query,
8200  "SELECT t.tgrelid, t.tgname, "
8201  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8202  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
8203  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8204  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8205  "LEFT JOIN pg_catalog.pg_depend AS d ON "
8206  " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8207  " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8208  " d.objid = t.oid "
8209  "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8210  "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
8211  "ORDER BY t.tgrelid, t.tgname",
8212  tbloids->data);
8213  }
8214  else
8215  {
8216  /* See above about pretty=true in pg_get_triggerdef */
8217  appendPQExpBuffer(query,
8218  "SELECT t.tgrelid, t.tgname, "
8219  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8220  "t.tgenabled, false as tgispartition, "
8221  "t.tableoid, t.oid "
8222  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8223  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8224  "WHERE NOT tgisinternal "
8225  "ORDER BY t.tgrelid, t.tgname",
8226  tbloids->data);
8227  }
8228 
8229  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8230 
8231  ntups = PQntuples(res);
8232 
8233  i_tableoid = PQfnumber(res, "tableoid");
8234  i_oid = PQfnumber(res, "oid");
8235  i_tgrelid = PQfnumber(res, "tgrelid");
8236  i_tgname = PQfnumber(res, "tgname");
8237  i_tgenabled = PQfnumber(res, "tgenabled");
8238  i_tgispartition = PQfnumber(res, "tgispartition");
8239  i_tgdef = PQfnumber(res, "tgdef");
8240 
8241  tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
8242 
8243  /*
8244  * Outer loop iterates once per table, not once per row. Incrementing of
8245  * j is handled by the inner loop.
8246  */
8247  curtblindx = -1;
8248  for (int j = 0; j < ntups;)
8249  {
8250  Oid tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
8251  TableInfo *tbinfo = NULL;
8252  int numtrigs;
8253 
8254  /* Count rows for this table */
8255  for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
8256  if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
8257  break;
8258 
8259  /*
8260  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8261  * order.
8262  */
8263  while (++curtblindx < numTables)
8264  {
8265  tbinfo = &tblinfo[curtblindx];
8266  if (tbinfo->dobj.catId.oid == tgrelid)
8267  break;
8268  }
8269  if (curtblindx >= numTables)
8270  pg_fatal("unrecognized table OID %u", tgrelid);
8271 
8272  /* Save data for this table */
8273  tbinfo->triggers = tginfo + j;
8274  tbinfo->numTriggers = numtrigs;
8275 
8276  for (int c = 0; c < numtrigs; c++, j++)
8277  {
8278  tginfo[j].dobj.objType = DO_TRIGGER;
8279  tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8280  tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8281  AssignDumpId(&tginfo[j].dobj);
8282  tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
8283  tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8284  tginfo[j].tgtable = tbinfo;
8285  tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8286  tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
8287  tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
8288  }
8289  }
8290 
8291  PQclear(res);
8292 
8293  destroyPQExpBuffer(query);
8294  destroyPQExpBuffer(tbloids);
8295 }
struct _triggerInfo * triggers
Definition: pg_dump.h:368
int numTriggers
Definition: pg_dump.h:367
TableInfo * tgtable
Definition: pg_dump.h:446
DumpableObject dobj
Definition: pg_dump.h:445
char tgenabled
Definition: pg_dump.h:447
char * tgdef
Definition: pg_dump.h:449
bool tgispartition
Definition: pg_dump.h:448

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, res, CatalogId::tableoid, _triggerInfo::tgdef, _triggerInfo::tgenabled, _triggerInfo::tgispartition, _triggerInfo::tgtable, and _tableInfo::triggers.

Referenced by getSchemaData().

◆ getTSConfigurations()

TSConfigInfo* getTSConfigurations ( Archive fout,
int *  numTSConfigs 
)

Definition at line 9675 of file pg_dump.c.

9676 {
9677  PGresult *res;
9678  int ntups;
9679  int i;
9680  PQExpBuffer query;
9681  TSConfigInfo *cfginfo;
9682  int i_tableoid;
9683  int i_oid;
9684  int i_cfgname;
9685  int i_cfgnamespace;
9686  int i_cfgowner;
9687  int i_cfgparser;
9688 
9689  query = createPQExpBuffer();
9690 
9691  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9692  "cfgnamespace, cfgowner, cfgparser "
9693  "FROM pg_ts_config");
9694 
9695  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9696 
9697  ntups = PQntuples(res);
9698  *numTSConfigs = ntups;
9699 
9700  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9701 
9702  i_tableoid = PQfnumber(res, "tableoid");
9703  i_oid = PQfnumber(res, "oid");
9704  i_cfgname = PQfnumber(res, "cfgname");
9705  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9706  i_cfgowner = PQfnumber(res, "cfgowner");
9707  i_cfgparser = PQfnumber(res, "cfgparser");
9708 
9709  for (i = 0; i < ntups; i++)
9710  {
9711  cfginfo[i].dobj.objType = DO_TSCONFIG;
9712  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9713  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9714  AssignDumpId(&cfginfo[i].dobj);
9715  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9716  cfginfo[i].dobj.namespace =
9717  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9718  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9719  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9720 
9721  /* Decide whether we want to dump it */
9722  selectDumpableObject(&(cfginfo[i].dobj), fout);
9723  }
9724 
9725  PQclear(res);
9726 
9727  destroyPQExpBuffer(query);
9728 
9729  return cfginfo;
9730 }
Oid cfgparser
Definition: pg_dump.h:553
DumpableObject dobj
Definition: pg_dump.h:551
const char * rolname
Definition: pg_dump.h:552

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(), res, _cfgInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSDictionaries()

TSDictInfo* getTSDictionaries ( Archive fout,
int *  numTSDicts 
)

Definition at line 9538 of file pg_dump.c.

9539 {
9540  PGresult *res;
9541  int ntups;
9542  int i;
9543  PQExpBuffer query;
9544  TSDictInfo *dictinfo;
9545  int i_tableoid;
9546  int i_oid;
9547  int i_dictname;
9548  int i_dictnamespace;
9549  int i_dictowner;
9550  int i_dicttemplate;
9551  int i_dictinitoption;
9552 
9553  query = createPQExpBuffer();
9554 
9555  appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9556  "dictnamespace, dictowner, "
9557  "dicttemplate, dictinitoption "
9558  "FROM pg_ts_dict");
9559 
9560  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9561 
9562  ntups = PQntuples(res);
9563  *numTSDicts = ntups;
9564 
9565  dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9566 
9567  i_tableoid = PQfnumber(res, "tableoid");
9568  i_oid = PQfnumber(res, "oid");
9569  i_dictname = PQfnumber(res, "dictname");
9570  i_dictnamespace = PQfnumber(res, "dictnamespace");
9571  i_dictowner = PQfnumber(res, "dictowner");
9572  i_dictinitoption = PQfnumber(res, "dictinitoption");
9573  i_dicttemplate = PQfnumber(res, "dicttemplate");
9574 
9575  for (i = 0; i < ntups; i++)
9576  {
9577  dictinfo[i].dobj.objType = DO_TSDICT;
9578  dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9579  dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9580  AssignDumpId(&dictinfo[i].dobj);
9581  dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9582  dictinfo[i].dobj.namespace =
9583  findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9584  dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9585  dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9586  if (PQgetisnull(res, i, i_dictinitoption))
9587  dictinfo[i].dictinitoption = NULL;
9588  else
9589  dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9590 
9591  /* Decide whether we want to dump it */
9592  selectDumpableObject(&(dictinfo[i].dobj), fout);
9593  }
9594 
9595  PQclear(res);
9596 
9597  destroyPQExpBuffer(query);
9598 
9599  return dictinfo;
9600 }
char * dictinitoption
Definition: pg_dump.h:539
DumpableObject dobj
Definition: pg_dump.h:536
const char * rolname
Definition: pg_dump.h:537
Oid dicttemplate
Definition: pg_dump.h:538

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(), res, _dictInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSParsers()

TSParserInfo* getTSParsers ( Archive fout,
int *  numTSParsers 
)

Definition at line 9458 of file pg_dump.c.

9459 {
9460  PGresult *res;
9461  int ntups;
9462  int i;
9463  PQExpBuffer query;
9464  TSParserInfo *prsinfo;
9465  int i_tableoid;
9466  int i_oid;
9467  int i_prsname;
9468  int i_prsnamespace;
9469  int i_prsstart;
9470  int i_prstoken;
9471  int i_prsend;
9472  int i_prsheadline;
9473  int i_prslextype;
9474 
9475  query = createPQExpBuffer();
9476 
9477  /*
9478  * find all text search objects, including builtin ones; we filter out
9479  * system-defined objects at dump-out time.
9480  */
9481 
9482  appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
9483  "prsstart::oid, prstoken::oid, "
9484  "prsend::oid, prsheadline::oid, prslextype::oid "
9485  "FROM pg_ts_parser");
9486 
9487  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9488 
9489  ntups = PQntuples(res);
9490  *numTSParsers = ntups;
9491 
9492  prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
9493 
9494  i_tableoid = PQfnumber(res, "tableoid");
9495  i_oid = PQfnumber(res, "oid");
9496  i_prsname = PQfnumber(res, "prsname");
9497  i_prsnamespace = PQfnumber(res, "prsnamespace");
9498  i_prsstart = PQfnumber(res, "prsstart");
9499  i_prstoken = PQfnumber(res, "prstoken");
9500  i_prsend = PQfnumber(res, "prsend");
9501  i_prsheadline = PQfnumber(res, "prsheadline");
9502  i_prslextype = PQfnumber(res, "prslextype");
9503 
9504  for (i = 0; i < ntups; i++)
9505  {
9506  prsinfo[i].dobj.objType = DO_TSPARSER;
9507  prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9508  prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9509  AssignDumpId(&prsinfo[i].dobj);
9510  prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
9511  prsinfo[i].dobj.namespace =
9512  findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
9513  prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
9514  prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
9515  prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
9516  prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
9517  prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
9518 
9519  /* Decide whether we want to dump it */
9520  selectDumpableObject(&(prsinfo[i].dobj), fout);
9521  }
9522 
9523  PQclear(res);
9524 
9525  destroyPQExpBuffer(query);
9526 
9527  return prsinfo;
9528 }
DumpableObject dobj
Definition: pg_dump.h:526
Oid prstoken
Definition: pg_dump.h:528
Oid prslextype
Definition: pg_dump.h:531
Oid prsheadline
Definition: pg_dump.h:530
Oid prsstart
Definition: pg_dump.h:527
Oid prsend
Definition: pg_dump.h:529

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, res, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getTSTemplates()

TSTemplateInfo* getTSTemplates ( Archive fout,
int *  numTSTemplates 
)

Definition at line 9610 of file pg_dump.c.

9611 {
9612  PGresult *res;
9613  int ntups;
9614  int i;
9615  PQExpBuffer query;
9616  TSTemplateInfo *tmplinfo;
9617  int i_tableoid;
9618  int i_oid;
9619  int i_tmplname;
9620  int i_tmplnamespace;
9621  int i_tmplinit;
9622  int i_tmpllexize;
9623 
9624  query = createPQExpBuffer();
9625 
9626  appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
9627  "tmplnamespace, tmplinit::oid, tmpllexize::oid "
9628  "FROM pg_ts_template");
9629 
9630  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9631 
9632  ntups = PQntuples(res);
9633  *numTSTemplates = ntups;
9634 
9635  tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
9636 
9637  i_tableoid = PQfnumber(res, "tableoid");
9638  i_oid = PQfnumber(res, "oid");
9639  i_tmplname = PQfnumber(res, "tmplname");
9640  i_tmplnamespace = PQfnumber(res, "tmplnamespace");
9641  i_tmplinit = PQfnumber(res, "tmplinit");
9642  i_tmpllexize = PQfnumber(res, "tmpllexize");
9643 
9644  for (i = 0; i < ntups; i++)
9645  {
9646  tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
9647  tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9648  tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9649  AssignDumpId(&tmplinfo[i].dobj);
9650  tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
9651  tmplinfo[i].dobj.namespace =
9652  findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
9653  tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
9654  tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
9655 
9656  /* Decide whether we want to dump it */
9657  selectDumpableObject(&(tmplinfo[i].dobj), fout);
9658  }
9659 
9660  PQclear(res);
9661 
9662  destroyPQExpBuffer(query);
9663 
9664  return tmplinfo;
9665 }
Oid tmpllexize
Definition: pg_dump.h:546
Oid tmplinit
Definition: pg_dump.h:545
DumpableObject dobj
Definition: pg_dump.h:544

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(), res, selectDumpableObject(), CatalogId::tableoid, _tmplInfo::tmplinit, and _tmplInfo::tmpllexize.

Referenced by getSchemaData().

◆ getTypes()

TypeInfo* getTypes ( Archive fout,
int *  numTypes 
)

Definition at line 5770 of file pg_dump.c.

5771 {
5772  PGresult *res;
5773  int ntups;
5774  int i;
5775  PQExpBuffer query = createPQExpBuffer();
5776  TypeInfo *tyinfo;
5777  ShellTypeInfo *stinfo;
5778  int i_tableoid;
5779  int i_oid;
5780  int i_typname;
5781  int i_typnamespace;
5782  int i_typacl;
5783  int i_acldefault;
5784  int i_typowner;
5785  int i_typelem;
5786  int i_typrelid;
5787  int i_typrelkind;
5788  int i_typtype;
5789  int i_typisdefined;
5790  int i_isarray;
5791 
5792  /*
5793  * we include even the built-in types because those may be used as array
5794  * elements by user-defined types
5795  *
5796  * we filter out the built-in types when we dump out the types
5797  *
5798  * same approach for undefined (shell) types and array types
5799  *
5800  * Note: as of 8.3 we can reliably detect whether a type is an
5801  * auto-generated array type by checking the element type's typarray.
5802  * (Before that the test is capable of generating false positives.) We
5803  * still check for name beginning with '_', though, so as to avoid the
5804  * cost of the subselect probe for all standard types. This would have to
5805  * be revisited if the backend ever allows renaming of array types.
5806  */
5807  appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
5808  "typnamespace, typacl, "
5809  "acldefault('T', typowner) AS acldefault, "
5810  "typowner, "
5811  "typelem, typrelid, "
5812  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
5813  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
5814  "typtype, typisdefined, "
5815  "typname[0] = '_' AND typelem != 0 AND "
5816  "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
5817  "FROM pg_type");
5818 
5819  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5820 
5821  ntups = PQntuples(res);
5822 
5823  tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
5824 
5825  i_tableoid = PQfnumber(res, "tableoid");
5826  i_oid = PQfnumber(res, "oid");
5827  i_typname = PQfnumber(res, "typname");
5828  i_typnamespace = PQfnumber(res, "typnamespace");
5829  i_typacl = PQfnumber(res, "typacl");
5830  i_acldefault = PQfnumber(res, "acldefault");
5831  i_typowner = PQfnumber(res, "typowner");
5832  i_typelem = PQfnumber(res, "typelem");
5833  i_typrelid = PQfnumber(res, "typrelid");
5834  i_typrelkind = PQfnumber(res, "typrelkind");
5835  i_typtype = PQfnumber(res, "typtype");
5836  i_typisdefined = PQfnumber(res, "typisdefined");
5837  i_isarray = PQfnumber(res, "isarray");
5838 
5839  for (i = 0; i < ntups; i++)
5840  {
5841  tyinfo[i].dobj.objType = DO_TYPE;
5842  tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5843  tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5844  AssignDumpId(&tyinfo[i].dobj);
5845  tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
5846  tyinfo[i].dobj.namespace =
5847  findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
5848  tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
5849  tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5850  tyinfo[i].dacl.privtype = 0;
5851  tyinfo[i].dacl.initprivs = NULL;
5852  tyinfo[i].ftypname = NULL; /* may get filled later */
5853  tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
5854  tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
5855  tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
5856  tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
5857  tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
5858  tyinfo[i].shellType = NULL;
5859 
5860  if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
5861  tyinfo[i].isDefined = true;
5862  else
5863  tyinfo[i].isDefined = false;
5864 
5865  if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
5866  tyinfo[i].isArray = true;
5867  else
5868  tyinfo[i].isArray = false;
5869 
5870  if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
5871  tyinfo[i].isMultirange = true;
5872  else
5873  tyinfo[i].isMultirange = false;
5874 
5875  /* Decide whether we want to dump it */
5876  selectDumpableType(&tyinfo[i], fout);
5877 
5878  /* Mark whether type has an ACL */
5879  if (!PQgetisnull(res, i, i_typacl))
5880  tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5881 
5882  /*
5883  * If it's a domain, fetch info about its constraints, if any
5884  */
5885  tyinfo[i].nDomChecks = 0;
5886  tyinfo[i].domChecks = NULL;
5887  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
5888  tyinfo[i].typtype == TYPTYPE_DOMAIN)
5889  getDomainConstraints(fout, &(tyinfo[i]));
5890 
5891  /*
5892  * If it's a base type, make a DumpableObject representing a shell
5893  * definition of the type. We will need to dump that ahead of the I/O
5894  * functions for the type. Similarly, range types need a shell
5895  * definition in case they have a canonicalize function.
5896  *
5897  * Note: the shell type doesn't have a catId. You might think it
5898  * should copy the base type's catId, but then it might capture the
5899  * pg_depend entries for the type, which we don't want.
5900  */
5901  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
5902  (tyinfo[i].typtype == TYPTYPE_BASE ||
5903  tyinfo[i].typtype == TYPTYPE_RANGE))
5904  {
5905  stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
5906  stinfo->dobj.objType = DO_SHELL_TYPE;
5907  stinfo->dobj.catId = nilCatalogId;
5908  AssignDumpId(&stinfo->dobj);
5909  stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
5910  stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
5911  stinfo->baseType = &(tyinfo[i]);
5912  tyinfo[i].shellType = stinfo;
5913 
5914  /*
5915  * Initially mark the shell type as not to be dumped. We'll only
5916  * dump it if the I/O or canonicalize functions need to be dumped;
5917  * this is taken care of while sorting dependencies.
5918  */
5919  stinfo->dobj.dump = DUMP_COMPONENT_NONE;
5920  }
5921  }
5922 
5923  *numTypes = ntups;
5924 
5925  PQclear(res);
5926 
5927  destroyPQExpBuffer(query);
5928 
5929  return tyinfo;
5930 }
static const CatalogId nilCatalogId
Definition: pg_dump.c:142
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:7913
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:1878
TypeInfo * baseType
Definition: pg_dump.h:219
DumpableObject dobj
Definition: pg_dump.h:217
bool isMultirange
Definition: pg_dump.h:206
struct _constraintInfo * domChecks
Definition: pg_dump.h:212
DumpableAcl dacl
Definition: pg_dump.h:192
bool isDefined
Definition: pg_dump.h:207
char * ftypname
Definition: pg_dump.h:199
char typrelkind
Definition: pg_dump.h:203
Oid typelem
Definition: pg_dump.h:201
struct _shellTypeInfo * shellType
Definition: pg_dump.h:209
int nDomChecks
Definition: pg_dump.h:211
char typtype
Definition: pg_dump.h:204
const char * rolname
Definition: pg_dump.h:200
Oid typrelid
Definition: pg_dump.h:202
bool isArray
Definition: pg_dump.h:205

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _shellTypeInfo::baseType, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_SHELL_TYPE, DO_TYPE, _typeInfo::dobj, _shellTypeInfo::dobj, _typeInfo::domChecks, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, ExecuteSqlQuery(), findNamespace(), _typeInfo::ftypname, getDomainConstraints(), getRoleName(), i, _dumpableAcl::initprivs, _typeInfo::isArray, _typeInfo::isDefined, _typeInfo::isMultirange, _dumpableObject::name, _typeInfo::nDomChecks, nilCatalogId, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, _typeInfo::rolname, selectDumpableType(), _typeInfo::shellType, CatalogId::tableoid, _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 1084 of file common.c.

1085 {
1086  int j,
1087  argNum;
1088  char temp[100];
1089  char s;
1090 
1091  argNum = 0;
1092  j = 0;
1093  for (;;)
1094  {
1095  s = *str++;
1096  if (s == ' ' || s == '\0')
1097  {
1098  if (j > 0)
1099  {
1100  if (argNum >= arraysize)
1101  pg_fatal("could not parse numeric array \"%s\": too many numbers", str);
1102  temp[j] = '\0';
1103  array[argNum++] = atooid(temp);
1104  j = 0;
1105  }
1106  if (s == '\0')
1107  break;
1108  }
1109  else
1110  {
1111  if (!(isdigit((unsigned char) s) || s == '-') ||
1112  j >= sizeof(temp) - 1)
1113  pg_fatal("could not parse numeric array \"%s\": invalid character in number", str);
1114  temp[j++] = s;
1115  }
1116  }
1117 
1118  while (argNum < arraysize)
1119  array[argNum++] = InvalidOid;
1120 }
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 18342 of file pg_dump.c.

18344 {
18345  DumpOptions *dopt = fout->dopt;
18346  PQExpBuffer query;
18347  PGresult *res;
18348  int ntups,
18349  i;
18350  int i_conrelid,
18351  i_confrelid;
18352 
18353  /* Nothing to do if no extensions */
18354  if (numExtensions == 0)
18355  return;
18356 
18357  /*
18358  * Identify extension configuration tables and create TableDataInfo
18359  * objects for them, ensuring their data will be dumped even though the
18360  * tables themselves won't be.
18361  *
18362  * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
18363  * user data in a configuration table is treated like schema data. This
18364  * seems appropriate since system data in a config table would get
18365  * reloaded by CREATE EXTENSION. If the extension is not listed in the
18366  * list of extensions to be included, none of its data is dumped.
18367  */
18368  for (i = 0; i < numExtensions; i++)
18369  {
18370  ExtensionInfo *curext = &(extinfo[i]);
18371  char *extconfig = curext->extconfig;
18372  char *extcondition = curext->extcondition;
18373  char **extconfigarray = NULL;
18374  char **extconditionarray = NULL;
18375  int nconfigitems = 0;
18376  int nconditionitems = 0;
18377 
18378  /*
18379  * Check if this extension is listed as to include in the dump. If
18380  * not, any table data associated with it is discarded.
18381  */
18382  if (extension_include_oids.head != NULL &&
18384  curext->dobj.catId.oid))
18385  continue;
18386 
18387  /*
18388  * Check if this extension is listed as to exclude in the dump. If
18389  * yes, any table data associated with it is discarded.
18390  */
18391  if (extension_exclude_oids.head != NULL &&
18393  curext->dobj.catId.oid))
18394  continue;
18395 
18396  if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
18397  {
18398  int j;
18399 
18400  if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
18401  pg_fatal("could not parse %s array", "extconfig");
18402  if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
18403  pg_fatal("could not parse %s array", "extcondition");
18404  if (nconfigitems != nconditionitems)
18405  pg_fatal("mismatched number of configurations and conditions for extension");
18406 
18407  for (j = 0; j < nconfigitems; j++)
18408  {
18409  TableInfo *configtbl;
18410  Oid configtbloid = atooid(extconfigarray[j]);
18411  bool dumpobj =
18413 
18414  configtbl = findTableByOid(configtbloid);
18415  if (configtbl == NULL)
18416  continue;
18417 
18418  /*
18419  * Tables of not-to-be-dumped extensions shouldn't be dumped
18420  * unless the table or its schema is explicitly included
18421  */
18422  if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
18423  {
18424  /* check table explicitly requested */
18425  if (table_include_oids.head != NULL &&
18427  configtbloid))
18428  dumpobj = true;
18429 
18430  /* check table's schema explicitly requested */
18431  if (configtbl->dobj.namespace->dobj.dump &
18433  dumpobj = true;
18434  }
18435 
18436  /* check table excluded by an exclusion switch */
18437  if (table_exclude_oids.head != NULL &&
18439  configtbloid))
18440  dumpobj = false;
18441 
18442  /* check schema excluded by an exclusion switch */
18444  configtbl->dobj.namespace->dobj.catId.oid))
18445  dumpobj = false;
18446 
18447  if (dumpobj)
18448  {
18449  makeTableDataInfo(dopt, configtbl);
18450  if (configtbl->dataObj != NULL)
18451  {
18452  if (strlen(extconditionarray[j]) > 0)
18453  configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
18454  }
18455  }
18456  }
18457  }
18458  if (extconfigarray)
18459  free(extconfigarray);
18460  if (extconditionarray)
18461  free(extconditionarray);
18462  }
18463 
18464  /*
18465  * Now that all the TableDataInfo objects have been created for all the
18466  * extensions, check their FK dependencies and register them to try and
18467  * dump the data out in an order that they can be restored in.
18468  *
18469  * Note that this is not a problem for user tables as their FKs are
18470  * recreated after the data has been loaded.
18471  */
18472 
18473  query = createPQExpBuffer();
18474 
18475  printfPQExpBuffer(query,
18476  "SELECT conrelid, confrelid "
18477  "FROM pg_constraint "
18478  "JOIN pg_depend ON (objid = confrelid) "
18479  "WHERE contype = 'f' "
18480  "AND refclassid = 'pg_extension'::regclass "
18481  "AND classid = 'pg_class'::regclass;");
18482 
18483  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18484  ntups = PQntuples(res);
18485 
18486  i_conrelid = PQfnumber(res, "conrelid");
18487  i_confrelid = PQfnumber(res, "confrelid");
18488 
18489  /* Now get the dependencies and register them */
18490  for (i = 0; i < ntups; i++)
18491  {
18492  Oid conrelid,
18493  confrelid;
18494  TableInfo *reftable,
18495  *contable;
18496 
18497  conrelid = atooid(PQgetvalue(res, i, i_conrelid));
18498  confrelid = atooid(PQgetvalue(res, i, i_confrelid));
18499  contable = findTableByOid(conrelid);
18500  reftable = findTableByOid(confrelid);
18501 
18502  if (reftable == NULL ||
18503  reftable->dataObj == NULL ||
18504  contable == NULL ||
18505  contable->dataObj == NULL)
18506  continue;
18507 
18508  /*
18509  * Make referencing TABLE_DATA object depend on the referenced table's
18510  * TABLE_DATA object.
18511  */
18512  addObjectDependency(&contable->dataObj->dobj,
18513  reftable->dataObj->dobj.dumpId);
18514  }
18515  PQclear(res);
18516  destroyPQExpBuffer(query);
18517 }
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:121
static SimpleOidList extension_include_oids
Definition: pg_dump.c:137
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:140
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2767
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:128
static SimpleOidList table_include_oids
Definition: pg_dump.c:125
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:389
char * filtercond
Definition: pg_dump.h:391
struct _tableDataInfo * dataObj
Definition: pg_dump.h:366

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(), res, 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 710 of file common.c.

711 {
712  CatalogIdMapEntry *entry;
713  bool found;
714 
715  /* CatalogId hash table must exist, if we have a DumpableObject */
716  Assert(catalogIdHash != NULL);
717 
718  /* Add reference to CatalogId hash */
719  entry = catalogid_insert(catalogIdHash, catId, &found);
720  if (!found)
721  {
722  entry->dobj = NULL;
723  entry->ext = NULL;
724  }
725  Assert(entry->dobj == NULL);
726  entry->dobj = dobj;
727 }

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

Referenced by getLOs().

◆ recordExtensionMembership()

void recordExtensionMembership ( CatalogId  catId,
ExtensionInfo ext 
)

Definition at line 1036 of file common.c.

1037 {
1038  CatalogIdMapEntry *entry;
1039  bool found;
1040 
1041  /* CatalogId hash table must exist, if we have an ExtensionInfo */
1042  Assert(catalogIdHash != NULL);
1043 
1044  /* Add reference to CatalogId hash */
1045  entry = catalogid_insert(catalogIdHash, catId, &found);
1046  if (!found)
1047  {
1048  entry->dobj = NULL;
1049  entry->ext = NULL;
1050  }
1051  Assert(entry->ext == NULL);
1052  entry->ext = ext;
1053 }

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

Referenced by getExtensionMembership().

◆ removeObjectDependency()

void removeObjectDependency ( DumpableObject dobj,
DumpId  refId 
)

◆ shouldPrintColumn()

bool shouldPrintColumn ( const DumpOptions dopt,
const TableInfo tbinfo,
int  colno 
)

Definition at line 9440 of file pg_dump.c.

9441 {
9442  if (dopt->binary_upgrade)
9443  return true;
9444  if (tbinfo->attisdropped[colno])
9445  return false;
9446  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9447 }

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

324 {
325  DumpableObject **ordering;
326  int nOrdering;
327 
328  if (numObjs <= 0) /* can't happen anymore ... */
329  return;
330 
331  /*
332  * Saving the boundary IDs in static variables is a bit grotty, but seems
333  * better than adding them to parameter lists of subsidiary functions.
334  */
335  preDataBoundId = preBoundaryId;
336  postDataBoundId = postBoundaryId;
337 
338  ordering = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
339  while (!TopoSort(objs, numObjs, ordering, &nOrdering))
340  findDependencyLoops(ordering, nOrdering, numObjs);
341 
342  memcpy(objs, ordering, numObjs * sizeof(DumpableObject *));
343 
344  free(ordering);
345 }
static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
Definition: pg_dump_sort.c:523
static DumpId preDataBoundId
Definition: pg_dump_sort.c:159
static bool TopoSort(DumpableObject **objs, int numObjs, DumpableObject **ordering, int *nOrdering)
Definition: pg_dump_sort.c:374
static DumpId postDataBoundId
Definition: pg_dump_sort.c:160

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

Referenced by main().

◆ sortDumpableObjectsByTypeName()

void sortDumpableObjectsByTypeName ( DumpableObject **  objs,
int  numObjs 
)

Definition at line 189 of file pg_dump_sort.c.

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

References DOTypeNameCompare(), and qsort.

Referenced by main().