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

6148 {
6149  PGresult *res;
6150  int ntups;
6151  int i;
6152  PQExpBuffer query;
6153  AccessMethodInfo *aminfo;
6154  int i_tableoid;
6155  int i_oid;
6156  int i_amname;
6157  int i_amhandler;
6158  int i_amtype;
6159 
6160  /* Before 9.6, there are no user-defined access methods */
6161  if (fout->remoteVersion < 90600)
6162  {
6163  *numAccessMethods = 0;
6164  return NULL;
6165  }
6166 
6167  query = createPQExpBuffer();
6168 
6169  /* Select all access methods from pg_am table */
6170  appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6171  "amhandler::pg_catalog.regproc AS amhandler "
6172  "FROM pg_am");
6173 
6174  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6175 
6176  ntups = PQntuples(res);
6177  *numAccessMethods = ntups;
6178 
6179  aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6180 
6181  i_tableoid = PQfnumber(res, "tableoid");
6182  i_oid = PQfnumber(res, "oid");
6183  i_amname = PQfnumber(res, "amname");
6184  i_amhandler = PQfnumber(res, "amhandler");
6185  i_amtype = PQfnumber(res, "amtype");
6186 
6187  for (i = 0; i < ntups; i++)
6188  {
6189  aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6190  aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6191  aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6192  AssignDumpId(&aminfo[i].dobj);
6193  aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6194  aminfo[i].dobj.namespace = NULL;
6195  aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6196  aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6197 
6198  /* Decide whether we want to dump it */
6199  selectDumpableAccessMethod(&(aminfo[i]), fout);
6200  }
6201 
6202  PQclear(res);
6203 
6204  destroyPQExpBuffer(query);
6205 
6206  return aminfo;
6207 }
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 6352 of file pg_dump.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

8003 {
8004  PGresult *res;
8005  int ntups;
8006  int i;
8007  PQExpBuffer query = createPQExpBuffer();
8008  RuleInfo *ruleinfo;
8009  int i_tableoid;
8010  int i_oid;
8011  int i_rulename;
8012  int i_ruletable;
8013  int i_ev_type;
8014  int i_is_instead;
8015  int i_ev_enabled;
8016 
8017  appendPQExpBufferStr(query, "SELECT "
8018  "tableoid, oid, rulename, "
8019  "ev_class AS ruletable, ev_type, is_instead, "
8020  "ev_enabled "
8021  "FROM pg_rewrite "
8022  "ORDER BY oid");
8023 
8024  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8025 
8026  ntups = PQntuples(res);
8027 
8028  *numRules = ntups;
8029 
8030  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8031 
8032  i_tableoid = PQfnumber(res, "tableoid");
8033  i_oid = PQfnumber(res, "oid");
8034  i_rulename = PQfnumber(res, "rulename");
8035  i_ruletable = PQfnumber(res, "ruletable");
8036  i_ev_type = PQfnumber(res, "ev_type");
8037  i_is_instead = PQfnumber(res, "is_instead");
8038  i_ev_enabled = PQfnumber(res, "ev_enabled");
8039 
8040  for (i = 0; i < ntups; i++)
8041  {
8042  Oid ruletableoid;
8043 
8044  ruleinfo[i].dobj.objType = DO_RULE;
8045  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8046  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8047  AssignDumpId(&ruleinfo[i].dobj);
8048  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8049  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8050  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8051  if (ruleinfo[i].ruletable == NULL)
8052  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8053  ruletableoid, ruleinfo[i].dobj.catId.oid);
8054  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8055  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8056  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8057  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8058  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8059  if (ruleinfo[i].ruletable)
8060  {
8061  /*
8062  * If the table is a view or materialized view, force its ON
8063  * SELECT rule to be sorted before the view itself --- this
8064  * ensures that any dependencies for the rule affect the table's
8065  * positioning. Other rules are forced to appear after their
8066  * table.
8067  */
8068  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8069  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8070  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8071  {
8072  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8073  ruleinfo[i].dobj.dumpId);
8074  /* We'll merge the rule into CREATE VIEW, if possible */
8075  ruleinfo[i].separate = false;
8076  }
8077  else
8078  {
8079  addObjectDependency(&ruleinfo[i].dobj,
8080  ruleinfo[i].ruletable->dobj.dumpId);
8081  ruleinfo[i].separate = true;
8082  }
8083  }
8084  else
8085  ruleinfo[i].separate = true;
8086  }
8087 
8088  PQclear(res);
8089 
8090  destroyPQExpBuffer(query);
8091 
8092  return ruleinfo;
8093 }
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:5556
void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7722
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4377
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7263
DefaultACLInfo * getDefaultACLs(Archive *fout, int *numDefaultACLs)
Definition: pg_dump.c:9933
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:18259
ForeignServerInfo * getForeignServers(Archive *fout, int *numForeignServers)
Definition: pg_dump.c:9839
AccessMethodInfo * getAccessMethods(Archive *fout, int *numAccessMethods)
Definition: pg_dump.c:6147
FdwInfo * getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
Definition: pg_dump.c:9749
FuncInfo * getFuncs(Archive *fout, int *numFuncs)
Definition: pg_dump.c:6499
TSConfigInfo * getTSConfigurations(Archive *fout, int *numTSConfigs)
Definition: pg_dump.c:9684
ConvInfo * getConversions(Archive *fout, int *numConversions)
Definition: pg_dump.c:6079
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7144
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4464
AggInfo * getAggregates(Archive *fout, int *numAggs)
Definition: pg_dump.c:6352
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7323
TSDictInfo * getTSDictionaries(Archive *fout, int *numTSDicts)
Definition: pg_dump.c:9547
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7207
OpfamilyInfo * getOpfamilies(Archive *fout, int *numOpfamilies)
Definition: pg_dump.c:6284
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:8683
void getSubscriptionTables(Archive *fout)
Definition: pg_dump.c:4918
PublicationInfo * getPublications(Archive *fout, int *numPublications)
Definition: pg_dump.c:4177
TSTemplateInfo * getTSTemplates(Archive *fout, int *numTSTemplates)
Definition: pg_dump.c:9619
ProcLangInfo * getProcLangs(Archive *fout, int *numProcLangs)
Definition: pg_dump.c:8386
TypeInfo * getTypes(Archive *fout, int *numTypes)
Definition: pg_dump.c:5767
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:7643
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:18352
OpclassInfo * getOpclasses(Archive *fout, int *numOpclasses)
Definition: pg_dump.c:6218
CollInfo * getCollations(Archive *fout, int *numCollations)
Definition: pg_dump.c:6011
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:4718
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:5692
TSParserInfo * getTSParsers(Archive *fout, int *numTSParsers)
Definition: pg_dump.c:9467
TransformInfo * getTransforms(Archive *fout, int *numTransforms)
Definition: pg_dump.c:8592
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8103
OprInfo * getOperators(Archive *fout, int *numOprs)
Definition: pg_dump.c:5937
RuleInfo * getRules(Archive *fout, int *numRules)
Definition: pg_dump.c:8002
EventTriggerInfo * getEventTriggers(Archive *fout, int *numEventTriggers)
Definition: pg_dump.c:8299
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:6698
CastInfo * getCasts(Archive *fout, int *numCasts)
Definition: pg_dump.c:8476

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  else
4809  appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
4810  " false AS subenabled,\n");
4811 
4812  if (fout->remoteVersion >= 170000)
4813  appendPQExpBufferStr(query,
4814  " s.subfailover\n");
4815  else
4816  appendPQExpBuffer(query,
4817  " false AS subfailover\n");
4818 
4819  appendPQExpBufferStr(query,
4820  "FROM pg_subscription s\n");
4821 
4822  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4823  appendPQExpBufferStr(query,
4824  "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
4825  " ON o.external_id = 'pg_' || s.oid::text \n");
4826 
4827  appendPQExpBufferStr(query,
4828  "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
4829  " WHERE datname = current_database())");
4830 
4831  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4832 
4833  ntups = PQntuples(res);
4834 
4835  /*
4836  * Get subscription fields. We don't include subskiplsn in the dump as
4837  * after restoring the dump this value may no longer be relevant.
4838  */
4839  i_tableoid = PQfnumber(res, "tableoid");
4840  i_oid = PQfnumber(res, "oid");
4841  i_subname = PQfnumber(res, "subname");
4842  i_subowner = PQfnumber(res, "subowner");
4843  i_subbinary = PQfnumber(res, "subbinary");
4844  i_substream = PQfnumber(res, "substream");
4845  i_subtwophasestate = PQfnumber(res, "subtwophasestate");
4846  i_subdisableonerr = PQfnumber(res, "subdisableonerr");
4847  i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
4848  i_subrunasowner = PQfnumber(res, "subrunasowner");
4849  i_subconninfo = PQfnumber(res, "subconninfo");
4850  i_subslotname = PQfnumber(res, "subslotname");
4851  i_subsynccommit = PQfnumber(res, "subsynccommit");
4852  i_subpublications = PQfnumber(res, "subpublications");
4853  i_suborigin = PQfnumber(res, "suborigin");
4854  i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
4855  i_subenabled = PQfnumber(res, "subenabled");
4856  i_subfailover = PQfnumber(res, "subfailover");
4857 
4858  subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
4859 
4860  for (i = 0; i < ntups; i++)
4861  {
4862  subinfo[i].dobj.objType = DO_SUBSCRIPTION;
4863  subinfo[i].dobj.catId.tableoid =
4864  atooid(PQgetvalue(res, i, i_tableoid));
4865  subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4866  AssignDumpId(&subinfo[i].dobj);
4867  subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
4868  subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
4869 
4870  subinfo[i].subbinary =
4871  pg_strdup(PQgetvalue(res, i, i_subbinary));
4872  subinfo[i].substream =
4873  pg_strdup(PQgetvalue(res, i, i_substream));
4874  subinfo[i].subtwophasestate =
4875  pg_strdup(PQgetvalue(res, i, i_subtwophasestate));
4876  subinfo[i].subdisableonerr =
4877  pg_strdup(PQgetvalue(res, i, i_subdisableonerr));
4878  subinfo[i].subpasswordrequired =
4879  pg_strdup(PQgetvalue(res, i, i_subpasswordrequired));
4880  subinfo[i].subrunasowner =
4881  pg_strdup(PQgetvalue(res, i, i_subrunasowner));
4882  subinfo[i].subconninfo =
4883  pg_strdup(PQgetvalue(res, i, i_subconninfo));
4884  if (PQgetisnull(res, i, i_subslotname))
4885  subinfo[i].subslotname = NULL;
4886  else
4887  subinfo[i].subslotname =
4888  pg_strdup(PQgetvalue(res, i, i_subslotname));
4889  subinfo[i].subsynccommit =
4890  pg_strdup(PQgetvalue(res, i, i_subsynccommit));
4891  subinfo[i].subpublications =
4892  pg_strdup(PQgetvalue(res, i, i_subpublications));
4893  subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
4894  if (PQgetisnull(res, i, i_suboriginremotelsn))
4895  subinfo[i].suboriginremotelsn = NULL;
4896  else
4897  subinfo[i].suboriginremotelsn =
4898  pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
4899  subinfo[i].subenabled =
4900  pg_strdup(PQgetvalue(res, i, i_subenabled));
4901  subinfo[i].subfailover =
4902  pg_strdup(PQgetvalue(res, i, i_subfailover));
4903 
4904  /* Decide whether we want to dump it */
4905  selectDumpableObject(&(subinfo[i].dobj), fout);
4906  }
4907  PQclear(res);
4908 
4909  destroyPQExpBuffer(query);
4910 }
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 4918 of file pg_dump.c.

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

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

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

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

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

9685 {
9686  PGresult *res;
9687  int ntups;
9688  int i;
9689  PQExpBuffer query;
9690  TSConfigInfo *cfginfo;
9691  int i_tableoid;
9692  int i_oid;
9693  int i_cfgname;
9694  int i_cfgnamespace;
9695  int i_cfgowner;
9696  int i_cfgparser;
9697 
9698  query = createPQExpBuffer();
9699 
9700  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9701  "cfgnamespace, cfgowner, cfgparser "
9702  "FROM pg_ts_config");
9703 
9704  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9705 
9706  ntups = PQntuples(res);
9707  *numTSConfigs = ntups;
9708 
9709  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9710 
9711  i_tableoid = PQfnumber(res, "tableoid");
9712  i_oid = PQfnumber(res, "oid");
9713  i_cfgname = PQfnumber(res, "cfgname");
9714  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9715  i_cfgowner = PQfnumber(res, "cfgowner");
9716  i_cfgparser = PQfnumber(res, "cfgparser");
9717 
9718  for (i = 0; i < ntups; i++)
9719  {
9720  cfginfo[i].dobj.objType = DO_TSCONFIG;
9721  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9722  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9723  AssignDumpId(&cfginfo[i].dobj);
9724  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9725  cfginfo[i].dobj.namespace =
9726  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9727  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9728  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9729 
9730  /* Decide whether we want to dump it */
9731  selectDumpableObject(&(cfginfo[i].dobj), fout);
9732  }
9733 
9734  PQclear(res);
9735 
9736  destroyPQExpBuffer(query);
9737 
9738  return cfginfo;
9739 }
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 9547 of file pg_dump.c.

9548 {
9549  PGresult *res;
9550  int ntups;
9551  int i;
9552  PQExpBuffer query;
9553  TSDictInfo *dictinfo;
9554  int i_tableoid;
9555  int i_oid;
9556  int i_dictname;
9557  int i_dictnamespace;
9558  int i_dictowner;
9559  int i_dicttemplate;
9560  int i_dictinitoption;
9561 
9562  query = createPQExpBuffer();
9563 
9564  appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9565  "dictnamespace, dictowner, "
9566  "dicttemplate, dictinitoption "
9567  "FROM pg_ts_dict");
9568 
9569  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9570 
9571  ntups = PQntuples(res);
9572  *numTSDicts = ntups;
9573 
9574  dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9575 
9576  i_tableoid = PQfnumber(res, "tableoid");
9577  i_oid = PQfnumber(res, "oid");
9578  i_dictname = PQfnumber(res, "dictname");
9579  i_dictnamespace = PQfnumber(res, "dictnamespace");
9580  i_dictowner = PQfnumber(res, "dictowner");
9581  i_dictinitoption = PQfnumber(res, "dictinitoption");
9582  i_dicttemplate = PQfnumber(res, "dicttemplate");
9583 
9584  for (i = 0; i < ntups; i++)
9585  {
9586  dictinfo[i].dobj.objType = DO_TSDICT;
9587  dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9588  dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9589  AssignDumpId(&dictinfo[i].dobj);
9590  dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9591  dictinfo[i].dobj.namespace =
9592  findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9593  dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9594  dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9595  if (PQgetisnull(res, i, i_dictinitoption))
9596  dictinfo[i].dictinitoption = NULL;
9597  else
9598  dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9599 
9600  /* Decide whether we want to dump it */
9601  selectDumpableObject(&(dictinfo[i].dobj), fout);
9602  }
9603 
9604  PQclear(res);
9605 
9606  destroyPQExpBuffer(query);
9607 
9608  return dictinfo;
9609 }
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 9467 of file pg_dump.c.

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

9620 {
9621  PGresult *res;
9622  int ntups;
9623  int i;
9624  PQExpBuffer query;
9625  TSTemplateInfo *tmplinfo;
9626  int i_tableoid;
9627  int i_oid;
9628  int i_tmplname;
9629  int i_tmplnamespace;
9630  int i_tmplinit;
9631  int i_tmpllexize;
9632 
9633  query = createPQExpBuffer();
9634 
9635  appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
9636  "tmplnamespace, tmplinit::oid, tmpllexize::oid "
9637  "FROM pg_ts_template");
9638 
9639  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9640 
9641  ntups = PQntuples(res);
9642  *numTSTemplates = ntups;
9643 
9644  tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
9645 
9646  i_tableoid = PQfnumber(res, "tableoid");
9647  i_oid = PQfnumber(res, "oid");
9648  i_tmplname = PQfnumber(res, "tmplname");
9649  i_tmplnamespace = PQfnumber(res, "tmplnamespace");
9650  i_tmplinit = PQfnumber(res, "tmplinit");
9651  i_tmpllexize = PQfnumber(res, "tmpllexize");
9652 
9653  for (i = 0; i < ntups; i++)
9654  {
9655  tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
9656  tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9657  tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9658  AssignDumpId(&tmplinfo[i].dobj);
9659  tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
9660  tmplinfo[i].dobj.namespace =
9661  findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
9662  tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
9663  tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
9664 
9665  /* Decide whether we want to dump it */
9666  selectDumpableObject(&(tmplinfo[i].dobj), fout);
9667  }
9668 
9669  PQclear(res);
9670 
9671  destroyPQExpBuffer(query);
9672 
9673  return tmplinfo;
9674 }
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 5767 of file pg_dump.c.

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

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

9450 {
9451  if (dopt->binary_upgrade)
9452  return true;
9453  if (tbinfo->attisdropped[colno])
9454  return false;
9455  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9456 }

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