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)
 
void getNamespaces (Archive *fout)
 
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
 
void getTypes (Archive *fout)
 
void getFuncs (Archive *fout)
 
void getAggregates (Archive *fout)
 
void getOperators (Archive *fout)
 
void getAccessMethods (Archive *fout)
 
void getOpclasses (Archive *fout)
 
void getOpfamilies (Archive *fout)
 
void getCollations (Archive *fout)
 
void getConversions (Archive *fout)
 
TableInfogetTables (Archive *fout, int *numTables)
 
void getOwnedSeqs (Archive *fout, TableInfo tblinfo[], int numTables)
 
InhInfogetInherits (Archive *fout, int *numInherits)
 
void getPartitioningInfo (Archive *fout)
 
void getIndexes (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getExtendedStatistics (Archive *fout)
 
void getConstraints (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getRules (Archive *fout)
 
void getTriggers (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getProcLangs (Archive *fout)
 
void getCasts (Archive *fout)
 
void getTransforms (Archive *fout)
 
void getTableAttrs (Archive *fout, TableInfo *tblinfo, int numTables)
 
bool shouldPrintColumn (const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
 
void getTSParsers (Archive *fout)
 
void getTSDictionaries (Archive *fout)
 
void getTSTemplates (Archive *fout)
 
void getTSConfigurations (Archive *fout)
 
void getForeignDataWrappers (Archive *fout)
 
void getForeignServers (Archive *fout)
 
void getDefaultACLs (Archive *fout)
 
void getExtensionMembership (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void processExtensionTables (Archive *fout, ExtensionInfo extinfo[], int numExtensions)
 
void getEventTriggers (Archive *fout)
 
void getPolicies (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getPublications (Archive *fout)
 
void getPublicationNamespaces (Archive *fout)
 
void getPublicationTables (Archive *fout, TableInfo tblinfo[], int numTables)
 
void getSubscriptions (Archive *fout)
 
void 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 622 of file common.c.

623 {
624  dobj->dumpId = ++lastDumpId;
625  dobj->name = NULL; /* must be set later */
626  dobj->namespace = NULL; /* may be set later */
627  dobj->dump = DUMP_COMPONENT_ALL; /* default assumption */
628  dobj->dump_contains = DUMP_COMPONENT_ALL; /* default assumption */
629  /* All objects have definitions; we may set more components bits later */
631  dobj->ext_member = false; /* default assumption */
632  dobj->depends_on_ext = false; /* default assumption */
633  dobj->dependencies = NULL;
634  dobj->nDeps = 0;
635  dobj->allocDeps = 0;
636 
637  /* Add object to dumpIdMap[], enlarging that array if need be */
638  while (dobj->dumpId >= allocedDumpIds)
639  {
640  int newAlloc;
641 
642  if (allocedDumpIds <= 0)
643  {
644  newAlloc = 256;
646  }
647  else
648  {
649  newAlloc = allocedDumpIds * 2;
651  }
652  memset(dumpIdMap + allocedDumpIds, 0,
653  (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
654  allocedDumpIds = newAlloc;
655  }
656  dumpIdMap[dobj->dumpId] = dobj;
657 
658  /* If it has a valid CatalogId, enter it into the hash table */
659  if (OidIsValid(dobj->catId.tableoid))
660  {
661  CatalogIdMapEntry *entry;
662  bool found;
663 
664  /* Initialize CatalogId hash table if not done yet */
665  if (catalogIdHash == NULL)
666  catalogIdHash = catalogid_create(CATALOGIDHASH_INITIAL_SIZE, NULL);
667 
668  entry = catalogid_insert(catalogIdHash, dobj->catId, &found);
669  if (!found)
670  {
671  entry->dobj = NULL;
672  entry->ext = NULL;
673  }
674  Assert(entry->dobj == NULL);
675  entry->dobj = dobj;
676  }
677 }
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:849
#define OidIsValid(objectId)
Definition: c.h:766
#define DUMP_COMPONENT_ALL
Definition: pg_dump.h:104
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:97
Oid tableoid
Definition: pg_backup.h:267
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 919 of file common.c.

920 {
921  CatalogId catId;
922  DumpableObject *dobj;
923 
924  catId.tableoid = CollationRelationId;
925  catId.oid = oid;
926  dobj = findObjectByCatalogId(catId);
927  Assert(dobj == NULL || dobj->objType == DO_COLLATION);
928  return (CollInfo *) dobj;
929 }
DumpableObject * findObjectByCatalogId(CatalogId catalogId)
Definition: common.c:743
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 955 of file common.c.

956 {
957  CatalogId catId;
958  DumpableObject *dobj;
959 
960  catId.tableoid = ExtensionRelationId;
961  catId.oid = oid;
962  dobj = findObjectByCatalogId(catId);
963  Assert(dobj == NULL || dobj->objType == DO_EXTENSION);
964  return (ExtensionInfo *) dobj;
965 }

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

Referenced by getExtensionMembership().

◆ findFuncByOid()

FuncInfo* findFuncByOid ( Oid  oid)

Definition at line 883 of file common.c.

884 {
885  CatalogId catId;
886  DumpableObject *dobj;
887 
888  catId.tableoid = ProcedureRelationId;
889  catId.oid = oid;
890  dobj = findObjectByCatalogId(catId);
891  Assert(dobj == NULL || dobj->objType == DO_FUNC);
892  return (FuncInfo *) dobj;
893 }

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

938 {
939  CatalogId catId;
940  DumpableObject *dobj;
941 
942  catId.tableoid = NamespaceRelationId;
943  catId.oid = oid;
944  dobj = findObjectByCatalogId(catId);
945  Assert(dobj == NULL || dobj->objType == DO_NAMESPACE);
946  return (NamespaceInfo *) dobj;
947 }

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

744 {
745  CatalogIdMapEntry *entry;
746 
747  if (catalogIdHash == NULL)
748  return NULL; /* no objects exist yet */
749 
750  entry = catalogid_lookup(catalogIdHash, catalogId);
751  if (entry == NULL)
752  return NULL;
753  return entry->dobj;
754 }

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

731 {
732  if (dumpId <= 0 || dumpId >= allocedDumpIds)
733  return NULL; /* out of range? */
734  return dumpIdMap[dumpId];
735 }

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

902 {
903  CatalogId catId;
904  DumpableObject *dobj;
905 
906  catId.tableoid = OperatorRelationId;
907  catId.oid = oid;
908  dobj = findObjectByCatalogId(catId);
909  Assert(dobj == NULL || dobj->objType == DO_OPERATOR);
910  return (OprInfo *) dobj;
911 }

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

Referenced by getFormattedOperatorName().

◆ findOwningExtension()

ExtensionInfo* findOwningExtension ( CatalogId  catalogId)

Definition at line 1034 of file common.c.

1035 {
1036  CatalogIdMapEntry *entry;
1037 
1038  if (catalogIdHash == NULL)
1039  return NULL; /* no objects exist yet */
1040 
1041  entry = catalogid_lookup(catalogIdHash, catalogId);
1042  if (entry == NULL)
1043  return NULL;
1044  return entry->ext;
1045 }

References catalogIdHash, and _catalogIdMapEntry::ext.

Referenced by checkExtensionMembership().

◆ findPublicationByOid()

PublicationInfo* findPublicationByOid ( Oid  oid)

Definition at line 973 of file common.c.

974 {
975  CatalogId catId;
976  DumpableObject *dobj;
977 
978  catId.tableoid = PublicationRelationId;
979  catId.oid = oid;
980  dobj = findObjectByCatalogId(catId);
981  Assert(dobj == NULL || dobj->objType == DO_PUBLICATION);
982  return (PublicationInfo *) dobj;
983 }

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

992 {
993  CatalogId catId;
994  DumpableObject *dobj;
995 
996  catId.tableoid = SubscriptionRelationId;
997  catId.oid = oid;
998  dobj = findObjectByCatalogId(catId);
999  Assert(dobj == NULL || dobj->objType == DO_SUBSCRIPTION);
1000  return (SubscriptionInfo *) dobj;
1001 }

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

865 {
866  CatalogId catId;
867  DumpableObject *dobj;
868 
869  catId.tableoid = TypeRelationId;
870  catId.oid = oid;
871  dobj = findObjectByCatalogId(catId);
872  Assert(dobj == NULL ||
873  dobj->objType == DO_TYPE || dobj->objType == DO_DUMMY_TYPE);
874  return (TypeInfo *) dobj;
875 }

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

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

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6252 of file pg_dump.c.

6253 {
6254  PGresult *res;
6255  int ntups;
6256  int i;
6257  PQExpBuffer query;
6258  AccessMethodInfo *aminfo;
6259  int i_tableoid;
6260  int i_oid;
6261  int i_amname;
6262  int i_amhandler;
6263  int i_amtype;
6264 
6265  /* Before 9.6, there are no user-defined access methods */
6266  if (fout->remoteVersion < 90600)
6267  return;
6268 
6269  query = createPQExpBuffer();
6270 
6271  /* Select all access methods from pg_am table */
6272  appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6273  "amhandler::pg_catalog.regproc AS amhandler "
6274  "FROM pg_am");
6275 
6276  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6277 
6278  ntups = PQntuples(res);
6279 
6280  aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6281 
6282  i_tableoid = PQfnumber(res, "tableoid");
6283  i_oid = PQfnumber(res, "oid");
6284  i_amname = PQfnumber(res, "amname");
6285  i_amhandler = PQfnumber(res, "amhandler");
6286  i_amtype = PQfnumber(res, "amtype");
6287 
6288  for (i = 0; i < ntups; i++)
6289  {
6290  aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6291  aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6292  aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6293  AssignDumpId(&aminfo[i].dobj);
6294  aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6295  aminfo[i].dobj.namespace = NULL;
6296  aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6297  aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6298 
6299  /* Decide whether we want to dump it */
6300  selectDumpableAccessMethod(&(aminfo[i]), fout);
6301  }
6302 
6303  PQclear(res);
6304 
6305  destroyPQExpBuffer(query);
6306 }
void AssignDumpId(DumpableObject *dobj)
Definition: common.c:622
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:123
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:2072
#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:220
char * amhandler
Definition: pg_dump.h:254
DumpableObject dobj
Definition: pg_dump.h:252

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

void getAggregates ( Archive fout)

Definition at line 6436 of file pg_dump.c.

6437 {
6438  DumpOptions *dopt = fout->dopt;
6439  PGresult *res;
6440  int ntups;
6441  int i;
6442  PQExpBuffer query = createPQExpBuffer();
6443  AggInfo *agginfo;
6444  int i_tableoid;
6445  int i_oid;
6446  int i_aggname;
6447  int i_aggnamespace;
6448  int i_pronargs;
6449  int i_proargtypes;
6450  int i_proowner;
6451  int i_aggacl;
6452  int i_acldefault;
6453 
6454  /*
6455  * Find all interesting aggregates. See comment in getFuncs() for the
6456  * rationale behind the filtering logic.
6457  */
6458  if (fout->remoteVersion >= 90600)
6459  {
6460  const char *agg_check;
6461 
6462  agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
6463  : "p.proisagg");
6464 
6465  appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
6466  "p.proname AS aggname, "
6467  "p.pronamespace AS aggnamespace, "
6468  "p.pronargs, p.proargtypes, "
6469  "p.proowner, "
6470  "p.proacl AS aggacl, "
6471  "acldefault('f', p.proowner) AS acldefault "
6472  "FROM pg_proc p "
6473  "LEFT JOIN pg_init_privs pip ON "
6474  "(p.oid = pip.objoid "
6475  "AND pip.classoid = 'pg_proc'::regclass "
6476  "AND pip.objsubid = 0) "
6477  "WHERE %s AND ("
6478  "p.pronamespace != "
6479  "(SELECT oid FROM pg_namespace "
6480  "WHERE nspname = 'pg_catalog') OR "
6481  "p.proacl IS DISTINCT FROM pip.initprivs",
6482  agg_check);
6483  if (dopt->binary_upgrade)
6484  appendPQExpBufferStr(query,
6485  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6486  "classid = 'pg_proc'::regclass AND "
6487  "objid = p.oid AND "
6488  "refclassid = 'pg_extension'::regclass AND "
6489  "deptype = 'e')");
6490  appendPQExpBufferChar(query, ')');
6491  }
6492  else
6493  {
6494  appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
6495  "pronamespace AS aggnamespace, "
6496  "pronargs, proargtypes, "
6497  "proowner, "
6498  "proacl AS aggacl, "
6499  "acldefault('f', proowner) AS acldefault "
6500  "FROM pg_proc p "
6501  "WHERE proisagg AND ("
6502  "pronamespace != "
6503  "(SELECT oid FROM pg_namespace "
6504  "WHERE nspname = 'pg_catalog')");
6505  if (dopt->binary_upgrade)
6506  appendPQExpBufferStr(query,
6507  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6508  "classid = 'pg_proc'::regclass AND "
6509  "objid = p.oid AND "
6510  "refclassid = 'pg_extension'::regclass AND "
6511  "deptype = 'e')");
6512  appendPQExpBufferChar(query, ')');
6513  }
6514 
6515  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6516 
6517  ntups = PQntuples(res);
6518 
6519  agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
6520 
6521  i_tableoid = PQfnumber(res, "tableoid");
6522  i_oid = PQfnumber(res, "oid");
6523  i_aggname = PQfnumber(res, "aggname");
6524  i_aggnamespace = PQfnumber(res, "aggnamespace");
6525  i_pronargs = PQfnumber(res, "pronargs");
6526  i_proargtypes = PQfnumber(res, "proargtypes");
6527  i_proowner = PQfnumber(res, "proowner");
6528  i_aggacl = PQfnumber(res, "aggacl");
6529  i_acldefault = PQfnumber(res, "acldefault");
6530 
6531  for (i = 0; i < ntups; i++)
6532  {
6533  agginfo[i].aggfn.dobj.objType = DO_AGG;
6534  agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6535  agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6536  AssignDumpId(&agginfo[i].aggfn.dobj);
6537  agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
6538  agginfo[i].aggfn.dobj.namespace =
6539  findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
6540  agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
6541  agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6542  agginfo[i].aggfn.dacl.privtype = 0;
6543  agginfo[i].aggfn.dacl.initprivs = NULL;
6544  agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6545  agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
6546  agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
6547  agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
6548  if (agginfo[i].aggfn.nargs == 0)
6549  agginfo[i].aggfn.argtypes = NULL;
6550  else
6551  {
6552  agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
6553  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6554  agginfo[i].aggfn.argtypes,
6555  agginfo[i].aggfn.nargs);
6556  }
6557  agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
6558 
6559  /* Decide whether we want to dump it */
6560  selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
6561 
6562  /* Mark whether aggregate has an ACL */
6563  if (!PQgetisnull(res, i, i_aggacl))
6564  agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
6565  }
6566 
6567  PQclear(res);
6568 
6569  destroyPQExpBuffer(query);
6570 }
void parseOidArray(const char *str, Oid *array, int arraysize)
Definition: common.c:1058
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:9822
static void selectDumpableObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2175
static NamespaceInfo * findNamespace(Oid nsoid)
Definition: pg_dump.c:5800
#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:215
int binary_upgrade
Definition: pg_backup.h:167

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

void getCasts ( Archive fout)

Definition at line 8529 of file pg_dump.c.

8530 {
8531  PGresult *res;
8532  int ntups;
8533  int i;
8534  PQExpBuffer query = createPQExpBuffer();
8535  CastInfo *castinfo;
8536  int i_tableoid;
8537  int i_oid;
8538  int i_castsource;
8539  int i_casttarget;
8540  int i_castfunc;
8541  int i_castcontext;
8542  int i_castmethod;
8543 
8544  if (fout->remoteVersion >= 140000)
8545  {
8546  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8547  "castsource, casttarget, castfunc, castcontext, "
8548  "castmethod "
8549  "FROM pg_cast c "
8550  "WHERE NOT EXISTS ( "
8551  "SELECT 1 FROM pg_range r "
8552  "WHERE c.castsource = r.rngtypid "
8553  "AND c.casttarget = r.rngmultitypid "
8554  ") "
8555  "ORDER BY 3,4");
8556  }
8557  else
8558  {
8559  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8560  "castsource, casttarget, castfunc, castcontext, "
8561  "castmethod "
8562  "FROM pg_cast ORDER BY 3,4");
8563  }
8564 
8565  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8566 
8567  ntups = PQntuples(res);
8568 
8569  castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8570 
8571  i_tableoid = PQfnumber(res, "tableoid");
8572  i_oid = PQfnumber(res, "oid");
8573  i_castsource = PQfnumber(res, "castsource");
8574  i_casttarget = PQfnumber(res, "casttarget");
8575  i_castfunc = PQfnumber(res, "castfunc");
8576  i_castcontext = PQfnumber(res, "castcontext");
8577  i_castmethod = PQfnumber(res, "castmethod");
8578 
8579  for (i = 0; i < ntups; i++)
8580  {
8581  PQExpBufferData namebuf;
8582  TypeInfo *sTypeInfo;
8583  TypeInfo *tTypeInfo;
8584 
8585  castinfo[i].dobj.objType = DO_CAST;
8586  castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8587  castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8588  AssignDumpId(&castinfo[i].dobj);
8589  castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8590  castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8591  castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8592  castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8593  castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8594 
8595  /*
8596  * Try to name cast as concatenation of typnames. This is only used
8597  * for purposes of sorting. If we fail to find either type, the name
8598  * will be an empty string.
8599  */
8600  initPQExpBuffer(&namebuf);
8601  sTypeInfo = findTypeByOid(castinfo[i].castsource);
8602  tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8603  if (sTypeInfo && tTypeInfo)
8604  appendPQExpBuffer(&namebuf, "%s %s",
8605  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8606  castinfo[i].dobj.name = namebuf.data;
8607 
8608  /* Decide whether we want to dump it */
8609  selectDumpableCast(&(castinfo[i]), fout);
8610  }
8611 
8612  PQclear(res);
8613 
8614  destroyPQExpBuffer(query);
8615 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:864
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:2014
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
char castmethod
Definition: pg_dump.h:501
Oid casttarget
Definition: pg_dump.h:498
char castcontext
Definition: pg_dump.h:500
DumpableObject dobj
Definition: pg_dump.h:496
Oid castsource
Definition: pg_dump.h:497
Oid castfunc
Definition: pg_dump.h:499
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()

void getCollations ( Archive fout)

Definition at line 6128 of file pg_dump.c.

6129 {
6130  PGresult *res;
6131  int ntups;
6132  int i;
6133  PQExpBuffer query;
6134  CollInfo *collinfo;
6135  int i_tableoid;
6136  int i_oid;
6137  int i_collname;
6138  int i_collnamespace;
6139  int i_collowner;
6140 
6141  query = createPQExpBuffer();
6142 
6143  /*
6144  * find all collations, including builtin collations; we filter out
6145  * system-defined collations at dump-out time.
6146  */
6147 
6148  appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6149  "collnamespace, "
6150  "collowner "
6151  "FROM pg_collation");
6152 
6153  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6154 
6155  ntups = PQntuples(res);
6156 
6157  collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6158 
6159  i_tableoid = PQfnumber(res, "tableoid");
6160  i_oid = PQfnumber(res, "oid");
6161  i_collname = PQfnumber(res, "collname");
6162  i_collnamespace = PQfnumber(res, "collnamespace");
6163  i_collowner = PQfnumber(res, "collowner");
6164 
6165  for (i = 0; i < ntups; i++)
6166  {
6167  collinfo[i].dobj.objType = DO_COLLATION;
6168  collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6169  collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6170  AssignDumpId(&collinfo[i].dobj);
6171  collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6172  collinfo[i].dobj.namespace =
6173  findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6174  collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6175 
6176  /* Decide whether we want to dump it */
6177  selectDumpableObject(&(collinfo[i].dobj), fout);
6178  }
6179 
6180  PQclear(res);
6181 
6182  destroyPQExpBuffer(query);
6183 }
const char * rolname
Definition: pg_dump.h:272
DumpableObject dobj
Definition: pg_dump.h:271

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

7797 {
7798  PQExpBuffer query = createPQExpBuffer();
7799  PQExpBuffer tbloids = createPQExpBuffer();
7800  PGresult *res;
7801  int ntups;
7802  int curtblindx;
7803  TableInfo *tbinfo = NULL;
7804  ConstraintInfo *constrinfo;
7805  int i_contableoid,
7806  i_conoid,
7807  i_conrelid,
7808  i_conname,
7809  i_confrelid,
7810  i_conindid,
7811  i_condef;
7812 
7813  /*
7814  * We want to perform just one query against pg_constraint. However, we
7815  * mustn't try to select every row of the catalog and then sort it out on
7816  * the client side, because some of the server-side functions we need
7817  * would be unsafe to apply to tables we don't have lock on. Hence, we
7818  * build an array of the OIDs of tables we care about (and now have lock
7819  * on!), and use a WHERE clause to constrain which rows are selected.
7820  */
7821  appendPQExpBufferChar(tbloids, '{');
7822  for (int i = 0; i < numTables; i++)
7823  {
7824  TableInfo *tinfo = &tblinfo[i];
7825 
7826  /*
7827  * For partitioned tables, foreign keys have no triggers so they must
7828  * be included anyway in case some foreign keys are defined.
7829  */
7830  if ((!tinfo->hastriggers &&
7831  tinfo->relkind != RELKIND_PARTITIONED_TABLE) ||
7832  !(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
7833  continue;
7834 
7835  /* OK, we need info for this table */
7836  if (tbloids->len > 1) /* do we have more than the '{'? */
7837  appendPQExpBufferChar(tbloids, ',');
7838  appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
7839  }
7840  appendPQExpBufferChar(tbloids, '}');
7841 
7842  appendPQExpBufferStr(query,
7843  "SELECT c.tableoid, c.oid, "
7844  "conrelid, conname, confrelid, ");
7845  if (fout->remoteVersion >= 110000)
7846  appendPQExpBufferStr(query, "conindid, ");
7847  else
7848  appendPQExpBufferStr(query, "0 AS conindid, ");
7849  appendPQExpBuffer(query,
7850  "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
7851  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7852  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
7853  "WHERE contype = 'f' ",
7854  tbloids->data);
7855  if (fout->remoteVersion >= 110000)
7856  appendPQExpBufferStr(query,
7857  "AND conparentid = 0 ");
7858  appendPQExpBufferStr(query,
7859  "ORDER BY conrelid, conname");
7860 
7861  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7862 
7863  ntups = PQntuples(res);
7864 
7865  i_contableoid = PQfnumber(res, "tableoid");
7866  i_conoid = PQfnumber(res, "oid");
7867  i_conrelid = PQfnumber(res, "conrelid");
7868  i_conname = PQfnumber(res, "conname");
7869  i_confrelid = PQfnumber(res, "confrelid");
7870  i_conindid = PQfnumber(res, "conindid");
7871  i_condef = PQfnumber(res, "condef");
7872 
7873  constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
7874 
7875  curtblindx = -1;
7876  for (int j = 0; j < ntups; j++)
7877  {
7878  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
7879  TableInfo *reftable;
7880 
7881  /*
7882  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7883  * order.
7884  */
7885  if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
7886  {
7887  while (++curtblindx < numTables)
7888  {
7889  tbinfo = &tblinfo[curtblindx];
7890  if (tbinfo->dobj.catId.oid == conrelid)
7891  break;
7892  }
7893  if (curtblindx >= numTables)
7894  pg_fatal("unrecognized table OID %u", conrelid);
7895  }
7896 
7897  constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
7898  constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7899  constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7900  AssignDumpId(&constrinfo[j].dobj);
7901  constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7902  constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7903  constrinfo[j].contable = tbinfo;
7904  constrinfo[j].condomain = NULL;
7905  constrinfo[j].contype = 'f';
7906  constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
7907  constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
7908  constrinfo[j].conindex = 0;
7909  constrinfo[j].condeferrable = false;
7910  constrinfo[j].condeferred = false;
7911  constrinfo[j].conislocal = true;
7912  constrinfo[j].separate = true;
7913 
7914  /*
7915  * Restoring an FK that points to a partitioned table requires that
7916  * all partition indexes have been attached beforehand. Ensure that
7917  * happens by making the constraint depend on each index partition
7918  * attach object.
7919  */
7920  reftable = findTableByOid(constrinfo[j].confrelid);
7921  if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
7922  {
7923  Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
7924 
7925  if (indexOid != InvalidOid)
7926  {
7927  for (int k = 0; k < reftable->numIndexes; k++)
7928  {
7929  IndxInfo *refidx;
7930 
7931  /* not our index? */
7932  if (reftable->indexes[k].dobj.catId.oid != indexOid)
7933  continue;
7934 
7935  refidx = &reftable->indexes[k];
7936  addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
7937  break;
7938  }
7939  }
7940  }
7941  }
7942 
7943  PQclear(res);
7944 
7945  destroyPQExpBuffer(query);
7946  destroyPQExpBuffer(tbloids);
7947 }
TableInfo * findTableByOid(Oid oid)
Definition: common.c:828
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:7961
TypeInfo * condomain
Definition: pg_dump.h:471
TableInfo * contable
Definition: pg_dump.h:470
bool condeferred
Definition: pg_dump.h:477
bool conislocal
Definition: pg_dump.h:479
DumpableObject dobj
Definition: pg_dump.h:469
DumpId conindex
Definition: pg_dump.h:475
bool condeferrable
Definition: pg_dump.h:476
char * condef
Definition: pg_dump.h:473
DumpableObject dobj
Definition: pg_dump.h:392
struct _indxInfo * indexes
Definition: pg_dump.h:361
DumpableObject dobj
Definition: pg_dump.h:286
char relkind
Definition: pg_dump.h:289
int numIndexes
Definition: pg_dump.h:360

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

void getConversions ( Archive fout)

Definition at line 6190 of file pg_dump.c.

6191 {
6192  PGresult *res;
6193  int ntups;
6194  int i;
6195  PQExpBuffer query;
6196  ConvInfo *convinfo;
6197  int i_tableoid;
6198  int i_oid;
6199  int i_conname;
6200  int i_connamespace;
6201  int i_conowner;
6202 
6203  query = createPQExpBuffer();
6204 
6205  /*
6206  * find all conversions, including builtin conversions; we filter out
6207  * system-defined conversions at dump-out time.
6208  */
6209 
6210  appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
6211  "connamespace, "
6212  "conowner "
6213  "FROM pg_conversion");
6214 
6215  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6216 
6217  ntups = PQntuples(res);
6218 
6219  convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
6220 
6221  i_tableoid = PQfnumber(res, "tableoid");
6222  i_oid = PQfnumber(res, "oid");
6223  i_conname = PQfnumber(res, "conname");
6224  i_connamespace = PQfnumber(res, "connamespace");
6225  i_conowner = PQfnumber(res, "conowner");
6226 
6227  for (i = 0; i < ntups; i++)
6228  {
6229  convinfo[i].dobj.objType = DO_CONVERSION;
6230  convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6231  convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6232  AssignDumpId(&convinfo[i].dobj);
6233  convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
6234  convinfo[i].dobj.namespace =
6235  findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
6236  convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
6237 
6238  /* Decide whether we want to dump it */
6239  selectDumpableObject(&(convinfo[i].dobj), fout);
6240  }
6241 
6242  PQclear(res);
6243 
6244  destroyPQExpBuffer(query);
6245 }
DumpableObject dobj
Definition: pg_dump.h:277
const char * rolname
Definition: pg_dump.h:278

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

void getDefaultACLs ( Archive fout)

Definition at line 9725 of file pg_dump.c.

9726 {
9727  DumpOptions *dopt = fout->dopt;
9728  DefaultACLInfo *daclinfo;
9729  PQExpBuffer query;
9730  PGresult *res;
9731  int i_oid;
9732  int i_tableoid;
9733  int i_defaclrole;
9734  int i_defaclnamespace;
9735  int i_defaclobjtype;
9736  int i_defaclacl;
9737  int i_acldefault;
9738  int i,
9739  ntups;
9740 
9741  query = createPQExpBuffer();
9742 
9743  /*
9744  * Global entries (with defaclnamespace=0) replace the hard-wired default
9745  * ACL for their object type. We should dump them as deltas from the
9746  * default ACL, since that will be used as a starting point for
9747  * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
9748  * non-global entries can only add privileges not revoke them. We must
9749  * dump those as-is (i.e., as deltas from an empty ACL).
9750  *
9751  * We can use defaclobjtype as the object type for acldefault(), except
9752  * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
9753  * 's'.
9754  */
9755  appendPQExpBufferStr(query,
9756  "SELECT oid, tableoid, "
9757  "defaclrole, "
9758  "defaclnamespace, "
9759  "defaclobjtype, "
9760  "defaclacl, "
9761  "CASE WHEN defaclnamespace = 0 THEN "
9762  "acldefault(CASE WHEN defaclobjtype = 'S' "
9763  "THEN 's'::\"char\" ELSE defaclobjtype END, "
9764  "defaclrole) ELSE '{}' END AS acldefault "
9765  "FROM pg_default_acl");
9766 
9767  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9768 
9769  ntups = PQntuples(res);
9770 
9771  daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
9772 
9773  i_oid = PQfnumber(res, "oid");
9774  i_tableoid = PQfnumber(res, "tableoid");
9775  i_defaclrole = PQfnumber(res, "defaclrole");
9776  i_defaclnamespace = PQfnumber(res, "defaclnamespace");
9777  i_defaclobjtype = PQfnumber(res, "defaclobjtype");
9778  i_defaclacl = PQfnumber(res, "defaclacl");
9779  i_acldefault = PQfnumber(res, "acldefault");
9780 
9781  for (i = 0; i < ntups; i++)
9782  {
9783  Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
9784 
9785  daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
9786  daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9787  daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9788  AssignDumpId(&daclinfo[i].dobj);
9789  /* cheesy ... is it worth coming up with a better object name? */
9790  daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
9791 
9792  if (nspid != InvalidOid)
9793  daclinfo[i].dobj.namespace = findNamespace(nspid);
9794  else
9795  daclinfo[i].dobj.namespace = NULL;
9796 
9797  daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9798  daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9799  daclinfo[i].dacl.privtype = 0;
9800  daclinfo[i].dacl.initprivs = NULL;
9801  daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
9802  daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
9803 
9804  /* Default ACLs are ACLs, of course */
9805  daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9806 
9807  /* Decide whether we want to dump it */
9808  selectDumpableDefaultACL(&(daclinfo[i]), dopt);
9809  }
9810 
9811  PQclear(res);
9812 
9813  destroyPQExpBuffer(query);
9814 }
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:1992
DumpableObject dobj
Definition: pg_dump.h:575
DumpableAcl dacl
Definition: pg_dump.h:576
const char * defaclrole
Definition: pg_dump.h:577
char defaclobjtype
Definition: pg_dump.h:578
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 762 of file common.c.

763 {
764  int i,
765  j;
766 
768  j = 0;
769  for (i = 1; i < allocedDumpIds; i++)
770  {
771  if (dumpIdMap[i])
772  (*objs)[j++] = dumpIdMap[i];
773  }
774  *numObjs = j;
775 }

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

Referenced by getTableDataFKConstraints(), and main().

◆ getEventTriggers()

void getEventTriggers ( Archive fout)

Definition at line 8367 of file pg_dump.c.

8368 {
8369  int i;
8370  PQExpBuffer query;
8371  PGresult *res;
8372  EventTriggerInfo *evtinfo;
8373  int i_tableoid,
8374  i_oid,
8375  i_evtname,
8376  i_evtevent,
8377  i_evtowner,
8378  i_evttags,
8379  i_evtfname,
8380  i_evtenabled;
8381  int ntups;
8382 
8383  /* Before 9.3, there are no event triggers */
8384  if (fout->remoteVersion < 90300)
8385  return;
8386 
8387  query = createPQExpBuffer();
8388 
8389  appendPQExpBufferStr(query,
8390  "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8391  "evtevent, evtowner, "
8392  "array_to_string(array("
8393  "select quote_literal(x) "
8394  " from unnest(evttags) as t(x)), ', ') as evttags, "
8395  "e.evtfoid::regproc as evtfname "
8396  "FROM pg_event_trigger e "
8397  "ORDER BY e.oid");
8398 
8399  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8400 
8401  ntups = PQntuples(res);
8402 
8403  evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8404 
8405  i_tableoid = PQfnumber(res, "tableoid");
8406  i_oid = PQfnumber(res, "oid");
8407  i_evtname = PQfnumber(res, "evtname");
8408  i_evtevent = PQfnumber(res, "evtevent");
8409  i_evtowner = PQfnumber(res, "evtowner");
8410  i_evttags = PQfnumber(res, "evttags");
8411  i_evtfname = PQfnumber(res, "evtfname");
8412  i_evtenabled = PQfnumber(res, "evtenabled");
8413 
8414  for (i = 0; i < ntups; i++)
8415  {
8416  evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8417  evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8418  evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8419  AssignDumpId(&evtinfo[i].dobj);
8420  evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8421  evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8422  evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8423  evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8424  evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8425  evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8426  evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8427 
8428  /* Decide whether we want to dump it */
8429  selectDumpableObject(&(evtinfo[i].dobj), fout);
8430  }
8431 
8432  PQclear(res);
8433 
8434  destroyPQExpBuffer(query);
8435 }
char * evtevent
Definition: pg_dump.h:452
char * evtfname
Definition: pg_dump.h:455
char evtenabled
Definition: pg_dump.h:456
char * evtname
Definition: pg_dump.h:451
const char * evtowner
Definition: pg_dump.h:453
char * evttags
Definition: pg_dump.h:454
DumpableObject dobj
Definition: pg_dump.h:450

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

7718 {
7719  PQExpBuffer query;
7720  PGresult *res;
7721  StatsExtInfo *statsextinfo;
7722  int ntups;
7723  int i_tableoid;
7724  int i_oid;
7725  int i_stxname;
7726  int i_stxnamespace;
7727  int i_stxowner;
7728  int i_stxrelid;
7729  int i_stattarget;
7730  int i;
7731 
7732  /* Extended statistics were new in v10 */
7733  if (fout->remoteVersion < 100000)
7734  return;
7735 
7736  query = createPQExpBuffer();
7737 
7738  if (fout->remoteVersion < 130000)
7739  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7740  "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
7741  "FROM pg_catalog.pg_statistic_ext");
7742  else
7743  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7744  "stxnamespace, stxowner, stxrelid, stxstattarget "
7745  "FROM pg_catalog.pg_statistic_ext");
7746 
7747  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7748 
7749  ntups = PQntuples(res);
7750 
7751  i_tableoid = PQfnumber(res, "tableoid");
7752  i_oid = PQfnumber(res, "oid");
7753  i_stxname = PQfnumber(res, "stxname");
7754  i_stxnamespace = PQfnumber(res, "stxnamespace");
7755  i_stxowner = PQfnumber(res, "stxowner");
7756  i_stxrelid = PQfnumber(res, "stxrelid");
7757  i_stattarget = PQfnumber(res, "stxstattarget");
7758 
7759  statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
7760 
7761  for (i = 0; i < ntups; i++)
7762  {
7763  statsextinfo[i].dobj.objType = DO_STATSEXT;
7764  statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7765  statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7766  AssignDumpId(&statsextinfo[i].dobj);
7767  statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
7768  statsextinfo[i].dobj.namespace =
7769  findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
7770  statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
7771  statsextinfo[i].stattable =
7772  findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7773  if (PQgetisnull(res, i, i_stattarget))
7774  statsextinfo[i].stattarget = -1;
7775  else
7776  statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7777 
7778  /* Decide whether we want to dump it */
7779  selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
7780  }
7781 
7782  PQclear(res);
7783  destroyPQExpBuffer(query);
7784 }
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2157
TableInfo * stattable
Definition: pg_dump.h:424
int stattarget
Definition: pg_dump.h:425
const char * rolname
Definition: pg_dump.h:423
DumpableObject dobj
Definition: pg_dump.h:422

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

18167 {
18168  PQExpBuffer query;
18169  PGresult *res;
18170  int ntups,
18171  i;
18172  int i_classid,
18173  i_objid,
18174  i_refobjid;
18175  ExtensionInfo *ext;
18176 
18177  /* Nothing to do if no extensions */
18178  if (numExtensions == 0)
18179  return;
18180 
18181  query = createPQExpBuffer();
18182 
18183  /* refclassid constraint is redundant but may speed the search */
18184  appendPQExpBufferStr(query, "SELECT "
18185  "classid, objid, refobjid "
18186  "FROM pg_depend "
18187  "WHERE refclassid = 'pg_extension'::regclass "
18188  "AND deptype = 'e' "
18189  "ORDER BY 3");
18190 
18191  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18192 
18193  ntups = PQntuples(res);
18194 
18195  i_classid = PQfnumber(res, "classid");
18196  i_objid = PQfnumber(res, "objid");
18197  i_refobjid = PQfnumber(res, "refobjid");
18198 
18199  /*
18200  * Since we ordered the SELECT by referenced ID, we can expect that
18201  * multiple entries for the same extension will appear together; this
18202  * saves on searches.
18203  */
18204  ext = NULL;
18205 
18206  for (i = 0; i < ntups; i++)
18207  {
18208  CatalogId objId;
18209  Oid extId;
18210 
18211  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
18212  objId.oid = atooid(PQgetvalue(res, i, i_objid));
18213  extId = atooid(PQgetvalue(res, i, i_refobjid));
18214 
18215  if (ext == NULL ||
18216  ext->dobj.catId.oid != extId)
18217  ext = findExtensionByOid(extId);
18218 
18219  if (ext == NULL)
18220  {
18221  /* shouldn't happen */
18222  pg_log_warning("could not find referenced extension %u", extId);
18223  continue;
18224  }
18225 
18226  recordExtensionMembership(objId, ext);
18227  }
18228 
18229  PQclear(res);
18230 
18231  destroyPQExpBuffer(query);
18232 }
void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
Definition: common.c:1010
ExtensionInfo * findExtensionByOid(Oid oid)
Definition: common.c:955
#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 5818 of file pg_dump.c.

5819 {
5820  DumpOptions *dopt = fout->dopt;
5821  PGresult *res;
5822  int ntups;
5823  int i;
5824  PQExpBuffer query;
5825  ExtensionInfo *extinfo = NULL;
5826  int i_tableoid;
5827  int i_oid;
5828  int i_extname;
5829  int i_nspname;
5830  int i_extrelocatable;
5831  int i_extversion;
5832  int i_extconfig;
5833  int i_extcondition;
5834 
5835  query = createPQExpBuffer();
5836 
5837  appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5838  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5839  "FROM pg_extension x "
5840  "JOIN pg_namespace n ON n.oid = x.extnamespace");
5841 
5842  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5843 
5844  ntups = PQntuples(res);
5845  if (ntups == 0)
5846  goto cleanup;
5847 
5848  extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5849 
5850  i_tableoid = PQfnumber(res, "tableoid");
5851  i_oid = PQfnumber(res, "oid");
5852  i_extname = PQfnumber(res, "extname");
5853  i_nspname = PQfnumber(res, "nspname");
5854  i_extrelocatable = PQfnumber(res, "extrelocatable");
5855  i_extversion = PQfnumber(res, "extversion");
5856  i_extconfig = PQfnumber(res, "extconfig");
5857  i_extcondition = PQfnumber(res, "extcondition");
5858 
5859  for (i = 0; i < ntups; i++)
5860  {
5861  extinfo[i].dobj.objType = DO_EXTENSION;
5862  extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5863  extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5864  AssignDumpId(&extinfo[i].dobj);
5865  extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5866  extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5867  extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5868  extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5869  extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5870  extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5871 
5872  /* Decide whether we want to dump it */
5873  selectDumpableExtension(&(extinfo[i]), dopt);
5874  }
5875 
5876 cleanup:
5877  PQclear(res);
5878  destroyPQExpBuffer(query);
5879 
5880  *numExtensions = ntups;
5881 
5882  return extinfo;
5883 }
static void cleanup(void)
Definition: bootstrap.c:683
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2100
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, cleanup(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_EXTENSION, _extensionInfo::dobj, Archive::dopt, ExecuteSqlQuery(), _extensionInfo::extcondition, _extensionInfo::extconfig, _extensionInfo::extversion, i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _extensionInfo::relocatable, res, selectDumpableExtension(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignDataWrappers()

void getForeignDataWrappers ( Archive fout)

Definition at line 9553 of file pg_dump.c.

9554 {
9555  PGresult *res;
9556  int ntups;
9557  int i;
9558  PQExpBuffer query;
9559  FdwInfo *fdwinfo;
9560  int i_tableoid;
9561  int i_oid;
9562  int i_fdwname;
9563  int i_fdwowner;
9564  int i_fdwhandler;
9565  int i_fdwvalidator;
9566  int i_fdwacl;
9567  int i_acldefault;
9568  int i_fdwoptions;
9569 
9570  query = createPQExpBuffer();
9571 
9572  appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
9573  "fdwowner, "
9574  "fdwhandler::pg_catalog.regproc, "
9575  "fdwvalidator::pg_catalog.regproc, "
9576  "fdwacl, "
9577  "acldefault('F', fdwowner) AS acldefault, "
9578  "array_to_string(ARRAY("
9579  "SELECT quote_ident(option_name) || ' ' || "
9580  "quote_literal(option_value) "
9581  "FROM pg_options_to_table(fdwoptions) "
9582  "ORDER BY option_name"
9583  "), E',\n ') AS fdwoptions "
9584  "FROM pg_foreign_data_wrapper");
9585 
9586  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9587 
9588  ntups = PQntuples(res);
9589 
9590  fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
9591 
9592  i_tableoid = PQfnumber(res, "tableoid");
9593  i_oid = PQfnumber(res, "oid");
9594  i_fdwname = PQfnumber(res, "fdwname");
9595  i_fdwowner = PQfnumber(res, "fdwowner");
9596  i_fdwhandler = PQfnumber(res, "fdwhandler");
9597  i_fdwvalidator = PQfnumber(res, "fdwvalidator");
9598  i_fdwacl = PQfnumber(res, "fdwacl");
9599  i_acldefault = PQfnumber(res, "acldefault");
9600  i_fdwoptions = PQfnumber(res, "fdwoptions");
9601 
9602  for (i = 0; i < ntups; i++)
9603  {
9604  fdwinfo[i].dobj.objType = DO_FDW;
9605  fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9606  fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9607  AssignDumpId(&fdwinfo[i].dobj);
9608  fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
9609  fdwinfo[i].dobj.namespace = NULL;
9610  fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
9611  fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9612  fdwinfo[i].dacl.privtype = 0;
9613  fdwinfo[i].dacl.initprivs = NULL;
9614  fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
9615  fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
9616  fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
9617  fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
9618 
9619  /* Decide whether we want to dump it */
9620  selectDumpableObject(&(fdwinfo[i].dobj), fout);
9621 
9622  /* Mark whether FDW has an ACL */
9623  if (!PQgetisnull(res, i, i_fdwacl))
9624  fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9625  }
9626 
9627  PQclear(res);
9628 
9629  destroyPQExpBuffer(query);
9630 }
char * fdwhandler
Definition: pg_dump.h:557
const char * rolname
Definition: pg_dump.h:556
char * fdwvalidator
Definition: pg_dump.h:558
char * fdwoptions
Definition: pg_dump.h:559
DumpableAcl dacl
Definition: pg_dump.h:555
DumpableObject dobj
Definition: pg_dump.h:554

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

void getForeignServers ( Archive fout)

Definition at line 9637 of file pg_dump.c.

9638 {
9639  PGresult *res;
9640  int ntups;
9641  int i;
9642  PQExpBuffer query;
9643  ForeignServerInfo *srvinfo;
9644  int i_tableoid;
9645  int i_oid;
9646  int i_srvname;
9647  int i_srvowner;
9648  int i_srvfdw;
9649  int i_srvtype;
9650  int i_srvversion;
9651  int i_srvacl;
9652  int i_acldefault;
9653  int i_srvoptions;
9654 
9655  query = createPQExpBuffer();
9656 
9657  appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
9658  "srvowner, "
9659  "srvfdw, srvtype, srvversion, srvacl, "
9660  "acldefault('S', srvowner) AS acldefault, "
9661  "array_to_string(ARRAY("
9662  "SELECT quote_ident(option_name) || ' ' || "
9663  "quote_literal(option_value) "
9664  "FROM pg_options_to_table(srvoptions) "
9665  "ORDER BY option_name"
9666  "), E',\n ') AS srvoptions "
9667  "FROM pg_foreign_server");
9668 
9669  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9670 
9671  ntups = PQntuples(res);
9672 
9673  srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
9674 
9675  i_tableoid = PQfnumber(res, "tableoid");
9676  i_oid = PQfnumber(res, "oid");
9677  i_srvname = PQfnumber(res, "srvname");
9678  i_srvowner = PQfnumber(res, "srvowner");
9679  i_srvfdw = PQfnumber(res, "srvfdw");
9680  i_srvtype = PQfnumber(res, "srvtype");
9681  i_srvversion = PQfnumber(res, "srvversion");
9682  i_srvacl = PQfnumber(res, "srvacl");
9683  i_acldefault = PQfnumber(res, "acldefault");
9684  i_srvoptions = PQfnumber(res, "srvoptions");
9685 
9686  for (i = 0; i < ntups; i++)
9687  {
9688  srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
9689  srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9690  srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9691  AssignDumpId(&srvinfo[i].dobj);
9692  srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
9693  srvinfo[i].dobj.namespace = NULL;
9694  srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
9695  srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9696  srvinfo[i].dacl.privtype = 0;
9697  srvinfo[i].dacl.initprivs = NULL;
9698  srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
9699  srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
9700  srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
9701  srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
9702  srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
9703 
9704  /* Decide whether we want to dump it */
9705  selectDumpableObject(&(srvinfo[i].dobj), fout);
9706 
9707  /* Servers have user mappings */
9709 
9710  /* Mark whether server has an ACL */
9711  if (!PQgetisnull(res, i, i_srvacl))
9712  srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9713  }
9714 
9715  PQclear(res);
9716 
9717  destroyPQExpBuffer(query);
9718 }
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:103
DumpableAcl dacl
Definition: pg_dump.h:565
char * srvoptions
Definition: pg_dump.h:570
DumpableObject dobj
Definition: pg_dump.h:564
const char * rolname
Definition: pg_dump.h:566
char * srvversion
Definition: pg_dump.h:569

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

void getFuncs ( Archive fout)

Definition at line 6577 of file pg_dump.c.

6578 {
6579  DumpOptions *dopt = fout->dopt;
6580  PGresult *res;
6581  int ntups;
6582  int i;
6583  PQExpBuffer query = createPQExpBuffer();
6584  FuncInfo *finfo;
6585  int i_tableoid;
6586  int i_oid;
6587  int i_proname;
6588  int i_pronamespace;
6589  int i_proowner;
6590  int i_prolang;
6591  int i_pronargs;
6592  int i_proargtypes;
6593  int i_prorettype;
6594  int i_proacl;
6595  int i_acldefault;
6596 
6597  /*
6598  * Find all interesting functions. This is a bit complicated:
6599  *
6600  * 1. Always exclude aggregates; those are handled elsewhere.
6601  *
6602  * 2. Always exclude functions that are internally dependent on something
6603  * else, since presumably those will be created as a result of creating
6604  * the something else. This currently acts only to suppress constructor
6605  * functions for range types. Note this is OK only because the
6606  * constructors don't have any dependencies the range type doesn't have;
6607  * otherwise we might not get creation ordering correct.
6608  *
6609  * 3. Otherwise, we normally exclude functions in pg_catalog. However, if
6610  * they're members of extensions and we are in binary-upgrade mode then
6611  * include them, since we want to dump extension members individually in
6612  * that mode. Also, if they are used by casts or transforms then we need
6613  * to gather the information about them, though they won't be dumped if
6614  * they are built-in. Also, in 9.6 and up, include functions in
6615  * pg_catalog if they have an ACL different from what's shown in
6616  * pg_init_privs (so we have to join to pg_init_privs; annoying).
6617  */
6618  if (fout->remoteVersion >= 90600)
6619  {
6620  const char *not_agg_check;
6621 
6622  not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
6623  : "NOT p.proisagg");
6624 
6625  appendPQExpBuffer(query,
6626  "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
6627  "p.pronargs, p.proargtypes, p.prorettype, "
6628  "p.proacl, "
6629  "acldefault('f', p.proowner) AS acldefault, "
6630  "p.pronamespace, "
6631  "p.proowner "
6632  "FROM pg_proc p "
6633  "LEFT JOIN pg_init_privs pip ON "
6634  "(p.oid = pip.objoid "
6635  "AND pip.classoid = 'pg_proc'::regclass "
6636  "AND pip.objsubid = 0) "
6637  "WHERE %s"
6638  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6639  "WHERE classid = 'pg_proc'::regclass AND "
6640  "objid = p.oid AND deptype = 'i')"
6641  "\n AND ("
6642  "\n pronamespace != "
6643  "(SELECT oid FROM pg_namespace "
6644  "WHERE nspname = 'pg_catalog')"
6645  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6646  "\n WHERE pg_cast.oid > %u "
6647  "\n AND p.oid = pg_cast.castfunc)"
6648  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6649  "\n WHERE pg_transform.oid > %u AND "
6650  "\n (p.oid = pg_transform.trffromsql"
6651  "\n OR p.oid = pg_transform.trftosql))",
6652  not_agg_check,
6655  if (dopt->binary_upgrade)
6656  appendPQExpBufferStr(query,
6657  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6658  "classid = 'pg_proc'::regclass AND "
6659  "objid = p.oid AND "
6660  "refclassid = 'pg_extension'::regclass AND "
6661  "deptype = 'e')");
6662  appendPQExpBufferStr(query,
6663  "\n OR p.proacl IS DISTINCT FROM pip.initprivs");
6664  appendPQExpBufferChar(query, ')');
6665  }
6666  else
6667  {
6668  appendPQExpBuffer(query,
6669  "SELECT tableoid, oid, proname, prolang, "
6670  "pronargs, proargtypes, prorettype, proacl, "
6671  "acldefault('f', proowner) AS acldefault, "
6672  "pronamespace, "
6673  "proowner "
6674  "FROM pg_proc p "
6675  "WHERE NOT proisagg"
6676  "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
6677  "WHERE classid = 'pg_proc'::regclass AND "
6678  "objid = p.oid AND deptype = 'i')"
6679  "\n AND ("
6680  "\n pronamespace != "
6681  "(SELECT oid FROM pg_namespace "
6682  "WHERE nspname = 'pg_catalog')"
6683  "\n OR EXISTS (SELECT 1 FROM pg_cast"
6684  "\n WHERE pg_cast.oid > '%u'::oid"
6685  "\n AND p.oid = pg_cast.castfunc)",
6687 
6688  if (fout->remoteVersion >= 90500)
6689  appendPQExpBuffer(query,
6690  "\n OR EXISTS (SELECT 1 FROM pg_transform"
6691  "\n WHERE pg_transform.oid > '%u'::oid"
6692  "\n AND (p.oid = pg_transform.trffromsql"
6693  "\n OR p.oid = pg_transform.trftosql))",
6695 
6696  if (dopt->binary_upgrade)
6697  appendPQExpBufferStr(query,
6698  "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
6699  "classid = 'pg_proc'::regclass AND "
6700  "objid = p.oid AND "
6701  "refclassid = 'pg_extension'::regclass AND "
6702  "deptype = 'e')");
6703  appendPQExpBufferChar(query, ')');
6704  }
6705 
6706  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6707 
6708  ntups = PQntuples(res);
6709 
6710  finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
6711 
6712  i_tableoid = PQfnumber(res, "tableoid");
6713  i_oid = PQfnumber(res, "oid");
6714  i_proname = PQfnumber(res, "proname");
6715  i_pronamespace = PQfnumber(res, "pronamespace");
6716  i_proowner = PQfnumber(res, "proowner");
6717  i_prolang = PQfnumber(res, "prolang");
6718  i_pronargs = PQfnumber(res, "pronargs");
6719  i_proargtypes = PQfnumber(res, "proargtypes");
6720  i_prorettype = PQfnumber(res, "prorettype");
6721  i_proacl = PQfnumber(res, "proacl");
6722  i_acldefault = PQfnumber(res, "acldefault");
6723 
6724  for (i = 0; i < ntups; i++)
6725  {
6726  finfo[i].dobj.objType = DO_FUNC;
6727  finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6728  finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6729  AssignDumpId(&finfo[i].dobj);
6730  finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
6731  finfo[i].dobj.namespace =
6732  findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
6733  finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
6734  finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
6735  finfo[i].dacl.privtype = 0;
6736  finfo[i].dacl.initprivs = NULL;
6737  finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
6738  finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
6739  finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
6740  finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
6741  if (finfo[i].nargs == 0)
6742  finfo[i].argtypes = NULL;
6743  else
6744  {
6745  finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
6746  parseOidArray(PQgetvalue(res, i, i_proargtypes),
6747  finfo[i].argtypes, finfo[i].nargs);
6748  }
6749  finfo[i].postponed_def = false; /* might get set during sort */
6750 
6751  /* Decide whether we want to dump it */
6752  selectDumpableObject(&(finfo[i].dobj), fout);
6753 
6754  /* Mark whether function has an ACL */
6755  if (!PQgetisnull(res, i, i_proacl))
6756  finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
6757  }
6758 
6759  PQclear(res);
6760 
6761  destroyPQExpBuffer(query);
6762 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static Oid g_last_builtin_oid
Definition: pg_dump.c:149
bool postponed_def
Definition: pg_dump.h:232
Oid lang
Definition: pg_dump.h:228
const char * rolname
Definition: pg_dump.h:227
Oid * argtypes
Definition: pg_dump.h:230
Oid prorettype
Definition: pg_dump.h:231
DumpableObject dobj
Definition: pg_dump.h:225
int nargs
Definition: pg_dump.h:229
DumpableAcl dacl
Definition: pg_dump.h:226

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

7398 {
7399  PQExpBuffer query = createPQExpBuffer();
7400  PQExpBuffer tbloids = createPQExpBuffer();
7401  PGresult *res;
7402  int ntups;
7403  int curtblindx;
7404  IndxInfo *indxinfo;
7405  int i_tableoid,
7406  i_oid,
7407  i_indrelid,
7408  i_indexname,
7409  i_parentidx,
7410  i_indexdef,
7411  i_indnkeyatts,
7412  i_indnatts,
7413  i_indkey,
7414  i_indisclustered,
7415  i_indisreplident,
7416  i_indnullsnotdistinct,
7417  i_contype,
7418  i_conname,
7419  i_condeferrable,
7420  i_condeferred,
7421  i_conperiod,
7422  i_contableoid,
7423  i_conoid,
7424  i_condef,
7425  i_tablespace,
7426  i_indreloptions,
7427  i_indstatcols,
7428  i_indstatvals;
7429 
7430  /*
7431  * We want to perform just one query against pg_index. However, we
7432  * mustn't try to select every row of the catalog and then sort it out on
7433  * the client side, because some of the server-side functions we need
7434  * would be unsafe to apply to tables we don't have lock on. Hence, we
7435  * build an array of the OIDs of tables we care about (and now have lock
7436  * on!), and use a WHERE clause to constrain which rows are selected.
7437  */
7438  appendPQExpBufferChar(tbloids, '{');
7439  for (int i = 0; i < numTables; i++)
7440  {
7441  TableInfo *tbinfo = &tblinfo[i];
7442 
7443  if (!tbinfo->hasindex)
7444  continue;
7445 
7446  /*
7447  * We can ignore indexes of uninteresting tables.
7448  */
7449  if (!tbinfo->interesting)
7450  continue;
7451 
7452  /* OK, we need info for this table */
7453  if (tbloids->len > 1) /* do we have more than the '{'? */
7454  appendPQExpBufferChar(tbloids, ',');
7455  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
7456  }
7457  appendPQExpBufferChar(tbloids, '}');
7458 
7459  appendPQExpBufferStr(query,
7460  "SELECT t.tableoid, t.oid, i.indrelid, "
7461  "t.relname AS indexname, "
7462  "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7463  "i.indkey, i.indisclustered, "
7464  "c.contype, c.conname, "
7465  "c.condeferrable, c.condeferred, "
7466  "c.tableoid AS contableoid, "
7467  "c.oid AS conoid, "
7468  "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
7469  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
7470  "t.reloptions AS indreloptions, ");
7471 
7472 
7473  if (fout->remoteVersion >= 90400)
7474  appendPQExpBufferStr(query,
7475  "i.indisreplident, ");
7476  else
7477  appendPQExpBufferStr(query,
7478  "false AS indisreplident, ");
7479 
7480  if (fout->remoteVersion >= 110000)
7481  appendPQExpBufferStr(query,
7482  "inh.inhparent AS parentidx, "
7483  "i.indnkeyatts AS indnkeyatts, "
7484  "i.indnatts AS indnatts, "
7485  "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
7486  " FROM pg_catalog.pg_attribute "
7487  " WHERE attrelid = i.indexrelid AND "
7488  " attstattarget >= 0) AS indstatcols, "
7489  "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
7490  " FROM pg_catalog.pg_attribute "
7491  " WHERE attrelid = i.indexrelid AND "
7492  " attstattarget >= 0) AS indstatvals, ");
7493  else
7494  appendPQExpBufferStr(query,
7495  "0 AS parentidx, "
7496  "i.indnatts AS indnkeyatts, "
7497  "i.indnatts AS indnatts, "
7498  "'' AS indstatcols, "
7499  "'' AS indstatvals, ");
7500 
7501  if (fout->remoteVersion >= 150000)
7502  appendPQExpBufferStr(query,
7503  "i.indnullsnotdistinct, ");
7504  else
7505  appendPQExpBufferStr(query,
7506  "false AS indnullsnotdistinct, ");
7507 
7508  if (fout->remoteVersion >= 180000)
7509  appendPQExpBufferStr(query,
7510  "c.conperiod ");
7511  else
7512  appendPQExpBufferStr(query,
7513  "NULL AS conperiod ");
7514 
7515  /*
7516  * The point of the messy-looking outer join is to find a constraint that
7517  * is related by an internal dependency link to the index. If we find one,
7518  * create a CONSTRAINT entry linked to the INDEX entry. We assume an
7519  * index won't have more than one internal dependency.
7520  *
7521  * Note: the check on conrelid is redundant, but useful because that
7522  * column is indexed while conindid is not.
7523  */
7524  if (fout->remoteVersion >= 110000)
7525  {
7526  appendPQExpBuffer(query,
7527  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7528  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7529  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7530  "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
7531  "LEFT JOIN pg_catalog.pg_constraint c "
7532  "ON (i.indrelid = c.conrelid AND "
7533  "i.indexrelid = c.conindid AND "
7534  "c.contype IN ('p','u','x')) "
7535  "LEFT JOIN pg_catalog.pg_inherits inh "
7536  "ON (inh.inhrelid = indexrelid) "
7537  "WHERE (i.indisvalid OR t2.relkind = 'p') "
7538  "AND i.indisready "
7539  "ORDER BY i.indrelid, indexname",
7540  tbloids->data);
7541  }
7542  else
7543  {
7544  /*
7545  * the test on indisready is necessary in 9.2, and harmless in
7546  * earlier/later versions
7547  */
7548  appendPQExpBuffer(query,
7549  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
7550  "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
7551  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
7552  "LEFT JOIN pg_catalog.pg_constraint c "
7553  "ON (i.indrelid = c.conrelid AND "
7554  "i.indexrelid = c.conindid AND "
7555  "c.contype IN ('p','u','x')) "
7556  "WHERE i.indisvalid AND i.indisready "
7557  "ORDER BY i.indrelid, indexname",
7558  tbloids->data);
7559  }
7560 
7561  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7562 
7563  ntups = PQntuples(res);
7564 
7565  i_tableoid = PQfnumber(res, "tableoid");
7566  i_oid = PQfnumber(res, "oid");
7567  i_indrelid = PQfnumber(res, "indrelid");
7568  i_indexname = PQfnumber(res, "indexname");
7569  i_parentidx = PQfnumber(res, "parentidx");
7570  i_indexdef = PQfnumber(res, "indexdef");
7571  i_indnkeyatts = PQfnumber(res, "indnkeyatts");
7572  i_indnatts = PQfnumber(res, "indnatts");
7573  i_indkey = PQfnumber(res, "indkey");
7574  i_indisclustered = PQfnumber(res, "indisclustered");
7575  i_indisreplident = PQfnumber(res, "indisreplident");
7576  i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
7577  i_contype = PQfnumber(res, "contype");
7578  i_conname = PQfnumber(res, "conname");
7579  i_condeferrable = PQfnumber(res, "condeferrable");
7580  i_condeferred = PQfnumber(res, "condeferred");
7581  i_conperiod = PQfnumber(res, "conperiod");
7582  i_contableoid = PQfnumber(res, "contableoid");
7583  i_conoid = PQfnumber(res, "conoid");
7584  i_condef = PQfnumber(res, "condef");
7585  i_tablespace = PQfnumber(res, "tablespace");
7586  i_indreloptions = PQfnumber(res, "indreloptions");
7587  i_indstatcols = PQfnumber(res, "indstatcols");
7588  i_indstatvals = PQfnumber(res, "indstatvals");
7589 
7590  indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
7591 
7592  /*
7593  * Outer loop iterates once per table, not once per row. Incrementing of
7594  * j is handled by the inner loop.
7595  */
7596  curtblindx = -1;
7597  for (int j = 0; j < ntups;)
7598  {
7599  Oid indrelid = atooid(PQgetvalue(res, j, i_indrelid));
7600  TableInfo *tbinfo = NULL;
7601  int numinds;
7602 
7603  /* Count rows for this table */
7604  for (numinds = 1; numinds < ntups - j; numinds++)
7605  if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
7606  break;
7607 
7608  /*
7609  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
7610  * order.
7611  */
7612  while (++curtblindx < numTables)
7613  {
7614  tbinfo = &tblinfo[curtblindx];
7615  if (tbinfo->dobj.catId.oid == indrelid)
7616  break;
7617  }
7618  if (curtblindx >= numTables)
7619  pg_fatal("unrecognized table OID %u", indrelid);
7620  /* cross-check that we only got requested tables */
7621  if (!tbinfo->hasindex ||
7622  !tbinfo->interesting)
7623  pg_fatal("unexpected index data for table \"%s\"",
7624  tbinfo->dobj.name);
7625 
7626  /* Save data for this table */
7627  tbinfo->indexes = indxinfo + j;
7628  tbinfo->numIndexes = numinds;
7629 
7630  for (int c = 0; c < numinds; c++, j++)
7631  {
7632  char contype;
7633 
7634  indxinfo[j].dobj.objType = DO_INDEX;
7635  indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
7636  indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
7637  AssignDumpId(&indxinfo[j].dobj);
7638  indxinfo[j].dobj.dump = tbinfo->dobj.dump;
7639  indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
7640  indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
7641  indxinfo[j].indextable = tbinfo;
7642  indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
7643  indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
7644  indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
7645  indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
7646  indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
7647  indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
7648  indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
7649  indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
7650  parseOidArray(PQgetvalue(res, j, i_indkey),
7651  indxinfo[j].indkeys, indxinfo[j].indnattrs);
7652  indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
7653  indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
7654  indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
7655  indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
7656  indxinfo[j].partattaches = (SimplePtrList)
7657  {
7658  NULL, NULL
7659  };
7660  contype = *(PQgetvalue(res, j, i_contype));
7661 
7662  if (contype == 'p' || contype == 'u' || contype == 'x')
7663  {
7664  /*
7665  * If we found a constraint matching the index, create an
7666  * entry for it.
7667  */
7668  ConstraintInfo *constrinfo;
7669 
7670  constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
7671  constrinfo->dobj.objType = DO_CONSTRAINT;
7672  constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
7673  constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
7674  AssignDumpId(&constrinfo->dobj);
7675  constrinfo->dobj.dump = tbinfo->dobj.dump;
7676  constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
7677  constrinfo->dobj.namespace = tbinfo->dobj.namespace;
7678  constrinfo->contable = tbinfo;
7679  constrinfo->condomain = NULL;
7680  constrinfo->contype = contype;
7681  if (contype == 'x')
7682  constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
7683  else
7684  constrinfo->condef = NULL;
7685  constrinfo->confrelid = InvalidOid;
7686  constrinfo->conindex = indxinfo[j].dobj.dumpId;
7687  constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
7688  constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
7689  constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
7690  constrinfo->conislocal = true;
7691  constrinfo->separate = true;
7692 
7693  indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
7694  }
7695  else
7696  {
7697  /* Plain secondary index */
7698  indxinfo[j].indexconstraint = 0;
7699  }
7700  }
7701  }
7702 
7703  PQclear(res);
7704 
7705  destroyPQExpBuffer(query);
7706  destroyPQExpBuffer(tbloids);
7707 }
char * c
struct SimplePtrList SimplePtrList
bool conperiod
Definition: pg_dump.h:478
bool indisreplident
Definition: pg_dump.h:404
int indnkeyattrs
Definition: pg_dump.h:399
char * indstatvals
Definition: pg_dump.h:398
char * indstatcols
Definition: pg_dump.h:397
int indnattrs
Definition: pg_dump.h:400
TableInfo * indextable
Definition: pg_dump.h:393
Oid parentidx
Definition: pg_dump.h:406
Oid * indkeys
Definition: pg_dump.h:401
char * indreloptions
Definition: pg_dump.h:396
DumpId indexconstraint
Definition: pg_dump.h:410
bool indisclustered
Definition: pg_dump.h:403
SimplePtrList partattaches
Definition: pg_dump.h:407
char * tablespace
Definition: pg_dump.h:395
bool indnullsnotdistinct
Definition: pg_dump.h:405
char * indexdef
Definition: pg_dump.h:394
bool interesting
Definition: pg_dump.h:320
bool hasindex
Definition: pg_dump.h:297

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

7282 {
7283  PGresult *res;
7284  int ntups;
7285  int i;
7286  PQExpBuffer query = createPQExpBuffer();
7287  InhInfo *inhinfo;
7288 
7289  int i_inhrelid;
7290  int i_inhparent;
7291 
7292  /* find all the inheritance information */
7293  appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7294 
7295  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7296 
7297  ntups = PQntuples(res);
7298 
7299  *numInherits = ntups;
7300 
7301  inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7302 
7303  i_inhrelid = PQfnumber(res, "inhrelid");
7304  i_inhparent = PQfnumber(res, "inhparent");
7305 
7306  for (i = 0; i < ntups; i++)
7307  {
7308  inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7309  inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7310  }
7311 
7312  PQclear(res);
7313 
7314  destroyPQExpBuffer(query);
7315 
7316  return inhinfo;
7317 }
Oid inhparent
Definition: pg_dump.h:517
Oid inhrelid
Definition: pg_dump.h:516

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

720 {
721  return lastDumpId;
722 }

References lastDumpId.

Referenced by findDependencyLoops(), and TopoSort().

◆ getNamespaces()

void getNamespaces ( Archive fout)

Definition at line 5686 of file pg_dump.c.

5687 {
5688  PGresult *res;
5689  int ntups;
5690  int i;
5691  PQExpBuffer query;
5692  NamespaceInfo *nsinfo;
5693  int i_tableoid;
5694  int i_oid;
5695  int i_nspname;
5696  int i_nspowner;
5697  int i_nspacl;
5698  int i_acldefault;
5699 
5700  query = createPQExpBuffer();
5701 
5702  /*
5703  * we fetch all namespaces including system ones, so that every object we
5704  * read in can be linked to a containing namespace.
5705  */
5706  appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5707  "n.nspowner, "
5708  "n.nspacl, "
5709  "acldefault('n', n.nspowner) AS acldefault "
5710  "FROM pg_namespace n");
5711 
5712  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5713 
5714  ntups = PQntuples(res);
5715 
5716  nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5717 
5718  i_tableoid = PQfnumber(res, "tableoid");
5719  i_oid = PQfnumber(res, "oid");
5720  i_nspname = PQfnumber(res, "nspname");
5721  i_nspowner = PQfnumber(res, "nspowner");
5722  i_nspacl = PQfnumber(res, "nspacl");
5723  i_acldefault = PQfnumber(res, "acldefault");
5724 
5725  for (i = 0; i < ntups; i++)
5726  {
5727  const char *nspowner;
5728 
5729  nsinfo[i].dobj.objType = DO_NAMESPACE;
5730  nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5731  nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5732  AssignDumpId(&nsinfo[i].dobj);
5733  nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5734  nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5735  nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5736  nsinfo[i].dacl.privtype = 0;
5737  nsinfo[i].dacl.initprivs = NULL;
5738  nspowner = PQgetvalue(res, i, i_nspowner);
5739  nsinfo[i].nspowner = atooid(nspowner);
5740  nsinfo[i].rolname = getRoleName(nspowner);
5741 
5742  /* Decide whether to dump this namespace */
5743  selectDumpableNamespace(&nsinfo[i], fout);
5744 
5745  /* Mark whether namespace has an ACL */
5746  if (!PQgetisnull(res, i, i_nspacl))
5747  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5748 
5749  /*
5750  * We ignore any pg_init_privs.initprivs entry for the public schema
5751  * and assume a predetermined default, for several reasons. First,
5752  * dropping and recreating the schema removes its pg_init_privs entry,
5753  * but an empty destination database starts with this ACL nonetheless.
5754  * Second, we support dump/reload of public schema ownership changes.
5755  * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5756  * initprivs continues to reflect the initial owner. Hence,
5757  * synthesize the value that nspacl will have after the restore's
5758  * ALTER SCHEMA OWNER. Third, this makes the destination database
5759  * match the source's ACL, even if the latter was an initdb-default
5760  * ACL, which changed in v15. An upgrade pulls in changes to most
5761  * system object ACLs that the DBA had not customized. We've made the
5762  * public schema depart from that, because changing its ACL so easily
5763  * breaks applications.
5764  */
5765  if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5766  {
5767  PQExpBuffer aclarray = createPQExpBuffer();
5768  PQExpBuffer aclitem = createPQExpBuffer();
5769 
5770  /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5771  appendPQExpBufferChar(aclarray, '{');
5772  quoteAclUserName(aclitem, nsinfo[i].rolname);
5773  appendPQExpBufferStr(aclitem, "=UC/");
5774  quoteAclUserName(aclitem, nsinfo[i].rolname);
5775  appendPGArray(aclarray, aclitem->data);
5776  resetPQExpBuffer(aclitem);
5777  appendPQExpBufferStr(aclitem, "=U/");
5778  quoteAclUserName(aclitem, nsinfo[i].rolname);
5779  appendPGArray(aclarray, aclitem->data);
5780  appendPQExpBufferChar(aclarray, '}');
5781 
5782  nsinfo[i].dacl.privtype = 'i';
5783  nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5784  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5785 
5786  destroyPQExpBuffer(aclarray);
5787  destroyPQExpBuffer(aclitem);
5788  }
5789  }
5790 
5791  PQclear(res);
5792  destroyPQExpBuffer(query);
5793 }
void quoteAclUserName(PQExpBuffer output, const char *input)
Definition: dumputils.c:544
char * pstrdup(const char *in)
Definition: mcxt.c:1696
NameData rolname
Definition: pg_authid.h:34
static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
Definition: pg_dump.c:1822
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()

void getOpclasses ( Archive fout)

Definition at line 6314 of file pg_dump.c.

6315 {
6316  PGresult *res;
6317  int ntups;
6318  int i;
6319  PQExpBuffer query = createPQExpBuffer();
6320  OpclassInfo *opcinfo;
6321  int i_tableoid;
6322  int i_oid;
6323  int i_opcname;
6324  int i_opcnamespace;
6325  int i_opcowner;
6326 
6327  /*
6328  * find all opclasses, including builtin opclasses; we filter out
6329  * system-defined opclasses at dump-out time.
6330  */
6331 
6332  appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
6333  "opcnamespace, "
6334  "opcowner "
6335  "FROM pg_opclass");
6336 
6337  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6338 
6339  ntups = PQntuples(res);
6340 
6341  opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
6342 
6343  i_tableoid = PQfnumber(res, "tableoid");
6344  i_oid = PQfnumber(res, "oid");
6345  i_opcname = PQfnumber(res, "opcname");
6346  i_opcnamespace = PQfnumber(res, "opcnamespace");
6347  i_opcowner = PQfnumber(res, "opcowner");
6348 
6349  for (i = 0; i < ntups; i++)
6350  {
6351  opcinfo[i].dobj.objType = DO_OPCLASS;
6352  opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6353  opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6354  AssignDumpId(&opcinfo[i].dobj);
6355  opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
6356  opcinfo[i].dobj.namespace =
6357  findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6358  opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
6359 
6360  /* Decide whether we want to dump it */
6361  selectDumpableObject(&(opcinfo[i].dobj), fout);
6362  }
6363 
6364  PQclear(res);
6365 
6366  destroyPQExpBuffer(query);
6367 }
DumpableObject dobj
Definition: pg_dump.h:259
const char * rolname
Definition: pg_dump.h:260

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

void getOperators ( Archive fout)

Definition at line 6060 of file pg_dump.c.

6061 {
6062  PGresult *res;
6063  int ntups;
6064  int i;
6065  PQExpBuffer query = createPQExpBuffer();
6066  OprInfo *oprinfo;
6067  int i_tableoid;
6068  int i_oid;
6069  int i_oprname;
6070  int i_oprnamespace;
6071  int i_oprowner;
6072  int i_oprkind;
6073  int i_oprcode;
6074 
6075  /*
6076  * find all operators, including builtin operators; we filter out
6077  * system-defined operators at dump-out time.
6078  */
6079 
6080  appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
6081  "oprnamespace, "
6082  "oprowner, "
6083  "oprkind, "
6084  "oprcode::oid AS oprcode "
6085  "FROM pg_operator");
6086 
6087  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6088 
6089  ntups = PQntuples(res);
6090 
6091  oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6092 
6093  i_tableoid = PQfnumber(res, "tableoid");
6094  i_oid = PQfnumber(res, "oid");
6095  i_oprname = PQfnumber(res, "oprname");
6096  i_oprnamespace = PQfnumber(res, "oprnamespace");
6097  i_oprowner = PQfnumber(res, "oprowner");
6098  i_oprkind = PQfnumber(res, "oprkind");
6099  i_oprcode = PQfnumber(res, "oprcode");
6100 
6101  for (i = 0; i < ntups; i++)
6102  {
6103  oprinfo[i].dobj.objType = DO_OPERATOR;
6104  oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6105  oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6106  AssignDumpId(&oprinfo[i].dobj);
6107  oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6108  oprinfo[i].dobj.namespace =
6109  findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6110  oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6111  oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6112  oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6113 
6114  /* Decide whether we want to dump it */
6115  selectDumpableObject(&(oprinfo[i].dobj), fout);
6116  }
6117 
6118  PQclear(res);
6119 
6120  destroyPQExpBuffer(query);
6121 }
DumpableObject dobj
Definition: pg_dump.h:244
char oprkind
Definition: pg_dump.h:246
Oid oprcode
Definition: pg_dump.h:247
const char * rolname
Definition: pg_dump.h:245

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

void getOpfamilies ( Archive fout)

Definition at line 6374 of file pg_dump.c.

6375 {
6376  PGresult *res;
6377  int ntups;
6378  int i;
6379  PQExpBuffer query;
6380  OpfamilyInfo *opfinfo;
6381  int i_tableoid;
6382  int i_oid;
6383  int i_opfname;
6384  int i_opfnamespace;
6385  int i_opfowner;
6386 
6387  query = createPQExpBuffer();
6388 
6389  /*
6390  * find all opfamilies, including builtin opfamilies; we filter out
6391  * system-defined opfamilies at dump-out time.
6392  */
6393 
6394  appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
6395  "opfnamespace, "
6396  "opfowner "
6397  "FROM pg_opfamily");
6398 
6399  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6400 
6401  ntups = PQntuples(res);
6402 
6403  opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
6404 
6405  i_tableoid = PQfnumber(res, "tableoid");
6406  i_oid = PQfnumber(res, "oid");
6407  i_opfname = PQfnumber(res, "opfname");
6408  i_opfnamespace = PQfnumber(res, "opfnamespace");
6409  i_opfowner = PQfnumber(res, "opfowner");
6410 
6411  for (i = 0; i < ntups; i++)
6412  {
6413  opfinfo[i].dobj.objType = DO_OPFAMILY;
6414  opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6415  opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6416  AssignDumpId(&opfinfo[i].dobj);
6417  opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
6418  opfinfo[i].dobj.namespace =
6419  findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6420  opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
6421 
6422  /* Decide whether we want to dump it */
6423  selectDumpableObject(&(opfinfo[i].dobj), fout);
6424  }
6425 
6426  PQclear(res);
6427 
6428  destroyPQExpBuffer(query);
6429 }
const char * rolname
Definition: pg_dump.h:266
DumpableObject dobj
Definition: pg_dump.h:265

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

7219 {
7220  int i;
7221 
7222  /*
7223  * Force sequences that are "owned" by table columns to be dumped whenever
7224  * their owning table is being dumped.
7225  */
7226  for (i = 0; i < numTables; i++)
7227  {
7228  TableInfo *seqinfo = &tblinfo[i];
7229  TableInfo *owning_tab;
7230 
7231  if (!OidIsValid(seqinfo->owning_tab))
7232  continue; /* not an owned sequence */
7233 
7234  owning_tab = findTableByOid(seqinfo->owning_tab);
7235  if (owning_tab == NULL)
7236  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7237  seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7238 
7239  /*
7240  * Only dump identity sequences if we're going to dump the table that
7241  * it belongs to.
7242  */
7243  if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
7244  seqinfo->is_identity_sequence)
7245  {
7246  seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
7247  continue;
7248  }
7249 
7250  /*
7251  * Otherwise we need to dump the components that are being dumped for
7252  * the table and any components which the sequence is explicitly
7253  * marked with.
7254  *
7255  * We can't simply use the set of components which are being dumped
7256  * for the table as the table might be in an extension (and only the
7257  * non-extension components, eg: ACLs if changed, security labels, and
7258  * policies, are being dumped) while the sequence is not (and
7259  * therefore the definition and other components should also be
7260  * dumped).
7261  *
7262  * If the sequence is part of the extension then it should be properly
7263  * marked by checkExtensionMembership() and this will be a no-op as
7264  * the table will be equivalently marked.
7265  */
7266  seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
7267 
7268  if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7269  seqinfo->interesting = true;
7270  }
7271 }
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:96
bool is_identity_sequence
Definition: pg_dump.h:316
Oid owning_tab
Definition: pg_dump.h:314

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

7338 {
7339  PQExpBuffer query;
7340  PGresult *res;
7341  int ntups;
7342 
7343  /* hash partitioning didn't exist before v11 */
7344  if (fout->remoteVersion < 110000)
7345  return;
7346  /* needn't bother if schema-only dump */
7347  if (fout->dopt->schemaOnly)
7348  return;
7349 
7350  query = createPQExpBuffer();
7351 
7352  /*
7353  * Unsafe partitioning schemes are exactly those for which hash enum_ops
7354  * appears among the partition opclasses. We needn't check partstrat.
7355  *
7356  * Note that this query may well retrieve info about tables we aren't
7357  * going to dump and hence have no lock on. That's okay since we need not
7358  * invoke any unsafe server-side functions.
7359  */
7360  appendPQExpBufferStr(query,
7361  "SELECT partrelid FROM pg_partitioned_table WHERE\n"
7362  "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
7363  "ON c.opcmethod = a.oid\n"
7364  "WHERE opcname = 'enum_ops' "
7365  "AND opcnamespace = 'pg_catalog'::regnamespace "
7366  "AND amname = 'hash') = ANY(partclass)");
7367 
7368  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7369 
7370  ntups = PQntuples(res);
7371 
7372  for (int i = 0; i < ntups; i++)
7373  {
7374  Oid tabrelid = atooid(PQgetvalue(res, i, 0));
7375  TableInfo *tbinfo;
7376 
7377  tbinfo = findTableByOid(tabrelid);
7378  if (tbinfo == NULL)
7379  pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
7380  tabrelid);
7381  tbinfo->unsafe_partitions = true;
7382  }
7383 
7384  PQclear(res);
7385 
7386  destroyPQExpBuffer(query);
7387 }
bool schemaOnly
Definition: pg_backup.h:170
bool unsafe_partitions
Definition: pg_dump.h:324

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

3985 {
3986  PQExpBuffer query;
3987  PQExpBuffer tbloids;
3988  PGresult *res;
3989  PolicyInfo *polinfo;
3990  int i_oid;
3991  int i_tableoid;
3992  int i_polrelid;
3993  int i_polname;
3994  int i_polcmd;
3995  int i_polpermissive;
3996  int i_polroles;
3997  int i_polqual;
3998  int i_polwithcheck;
3999  int i,
4000  j,
4001  ntups;
4002 
4003  /* No policies before 9.5 */
4004  if (fout->remoteVersion < 90500)
4005  return;
4006 
4007  query = createPQExpBuffer();
4008  tbloids = createPQExpBuffer();
4009 
4010  /*
4011  * Identify tables of interest, and check which ones have RLS enabled.
4012  */
4013  appendPQExpBufferChar(tbloids, '{');
4014  for (i = 0; i < numTables; i++)
4015  {
4016  TableInfo *tbinfo = &tblinfo[i];
4017 
4018  /* Ignore row security on tables not to be dumped */
4019  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
4020  continue;
4021 
4022  /* It can't have RLS or policies if it's not a table */
4023  if (tbinfo->relkind != RELKIND_RELATION &&
4024  tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
4025  continue;
4026 
4027  /* Add it to the list of table OIDs to be probed below */
4028  if (tbloids->len > 1) /* do we have more than the '{'? */
4029  appendPQExpBufferChar(tbloids, ',');
4030  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
4031 
4032  /* Is RLS enabled? (That's separate from whether it has policies) */
4033  if (tbinfo->rowsec)
4034  {
4036 
4037  /*
4038  * We represent RLS being enabled on a table by creating a
4039  * PolicyInfo object with null polname.
4040  *
4041  * Note: use tableoid 0 so that this object won't be mistaken for
4042  * something that pg_depend entries apply to.
4043  */
4044  polinfo = pg_malloc(sizeof(PolicyInfo));
4045  polinfo->dobj.objType = DO_POLICY;
4046  polinfo->dobj.catId.tableoid = 0;
4047  polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
4048  AssignDumpId(&polinfo->dobj);
4049  polinfo->dobj.namespace = tbinfo->dobj.namespace;
4050  polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
4051  polinfo->poltable = tbinfo;
4052  polinfo->polname = NULL;
4053  polinfo->polcmd = '\0';
4054  polinfo->polpermissive = 0;
4055  polinfo->polroles = NULL;
4056  polinfo->polqual = NULL;
4057  polinfo->polwithcheck = NULL;
4058  }
4059  }
4060  appendPQExpBufferChar(tbloids, '}');
4061 
4062  /*
4063  * Now, read all RLS policies belonging to the tables of interest, and
4064  * create PolicyInfo objects for them. (Note that we must filter the
4065  * results server-side not locally, because we dare not apply pg_get_expr
4066  * to tables we don't have lock on.)
4067  */
4068  pg_log_info("reading row-level security policies");
4069 
4070  printfPQExpBuffer(query,
4071  "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
4072  if (fout->remoteVersion >= 100000)
4073  appendPQExpBufferStr(query, "pol.polpermissive, ");
4074  else
4075  appendPQExpBufferStr(query, "'t' as polpermissive, ");
4076  appendPQExpBuffer(query,
4077  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
4078  " 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, "
4079  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
4080  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
4081  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
4082  "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
4083  tbloids->data);
4084 
4085  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4086 
4087  ntups = PQntuples(res);
4088  if (ntups > 0)
4089  {
4090  i_oid = PQfnumber(res, "oid");
4091  i_tableoid = PQfnumber(res, "tableoid");
4092  i_polrelid = PQfnumber(res, "polrelid");
4093  i_polname = PQfnumber(res, "polname");
4094  i_polcmd = PQfnumber(res, "polcmd");
4095  i_polpermissive = PQfnumber(res, "polpermissive");
4096  i_polroles = PQfnumber(res, "polroles");
4097  i_polqual = PQfnumber(res, "polqual");
4098  i_polwithcheck = PQfnumber(res, "polwithcheck");
4099 
4100  polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
4101 
4102  for (j = 0; j < ntups; j++)
4103  {
4104  Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
4105  TableInfo *tbinfo = findTableByOid(polrelid);
4106 
4108 
4109  polinfo[j].dobj.objType = DO_POLICY;
4110  polinfo[j].dobj.catId.tableoid =
4111  atooid(PQgetvalue(res, j, i_tableoid));
4112  polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4113  AssignDumpId(&polinfo[j].dobj);
4114  polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4115  polinfo[j].poltable = tbinfo;
4116  polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
4117  polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
4118 
4119  polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
4120  polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
4121 
4122  if (PQgetisnull(res, j, i_polroles))
4123  polinfo[j].polroles = NULL;
4124  else
4125  polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
4126 
4127  if (PQgetisnull(res, j, i_polqual))
4128  polinfo[j].polqual = NULL;
4129  else
4130  polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
4131 
4132  if (PQgetisnull(res, j, i_polwithcheck))
4133  polinfo[j].polwithcheck = NULL;
4134  else
4135  polinfo[j].polwithcheck
4136  = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
4137  }
4138  }
4139 
4140  PQclear(res);
4141 
4142  destroyPQExpBuffer(query);
4143  destroyPQExpBuffer(tbloids);
4144 }
#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:607
char * polqual
Definition: pg_dump.h:612
char polcmd
Definition: pg_dump.h:609
char * polroles
Definition: pg_dump.h:611
char * polwithcheck
Definition: pg_dump.h:613
DumpableObject dobj
Definition: pg_dump.h:606
bool polpermissive
Definition: pg_dump.h:610
char * polname
Definition: pg_dump.h:608
bool rowsec
Definition: pg_dump.h:301

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

void getProcLangs ( Archive fout)

Definition at line 8445 of file pg_dump.c.

8446 {
8447  PGresult *res;
8448  int ntups;
8449  int i;
8450  PQExpBuffer query = createPQExpBuffer();
8451  ProcLangInfo *planginfo;
8452  int i_tableoid;
8453  int i_oid;
8454  int i_lanname;
8455  int i_lanpltrusted;
8456  int i_lanplcallfoid;
8457  int i_laninline;
8458  int i_lanvalidator;
8459  int i_lanacl;
8460  int i_acldefault;
8461  int i_lanowner;
8462 
8463  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8464  "lanname, lanpltrusted, lanplcallfoid, "
8465  "laninline, lanvalidator, "
8466  "lanacl, "
8467  "acldefault('l', lanowner) AS acldefault, "
8468  "lanowner "
8469  "FROM pg_language "
8470  "WHERE lanispl "
8471  "ORDER BY oid");
8472 
8473  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8474 
8475  ntups = PQntuples(res);
8476 
8477  planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8478 
8479  i_tableoid = PQfnumber(res, "tableoid");
8480  i_oid = PQfnumber(res, "oid");
8481  i_lanname = PQfnumber(res, "lanname");
8482  i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8483  i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8484  i_laninline = PQfnumber(res, "laninline");
8485  i_lanvalidator = PQfnumber(res, "lanvalidator");
8486  i_lanacl = PQfnumber(res, "lanacl");
8487  i_acldefault = PQfnumber(res, "acldefault");
8488  i_lanowner = PQfnumber(res, "lanowner");
8489 
8490  for (i = 0; i < ntups; i++)
8491  {
8492  planginfo[i].dobj.objType = DO_PROCLANG;
8493  planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8494  planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8495  AssignDumpId(&planginfo[i].dobj);
8496 
8497  planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8498  planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8499  planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8500  planginfo[i].dacl.privtype = 0;
8501  planginfo[i].dacl.initprivs = NULL;
8502  planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8503  planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8504  planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8505  planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8506  planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8507 
8508  /* Decide whether we want to dump it */
8509  selectDumpableProcLang(&(planginfo[i]), fout);
8510 
8511  /* Mark whether language has an ACL */
8512  if (!PQgetisnull(res, i, i_lanacl))
8513  planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8514  }
8515 
8516  PQclear(res);
8517 
8518  destroyPQExpBuffer(query);
8519 }
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:2039
Oid lanvalidator
Definition: pg_dump.h:490
DumpableAcl dacl
Definition: pg_dump.h:486
DumpableObject dobj
Definition: pg_dump.h:485
Oid laninline
Definition: pg_dump.h:489
const char * lanowner
Definition: pg_dump.h:491
Oid lanplcallfoid
Definition: pg_dump.h:488
bool lanpltrusted
Definition: pg_dump.h:487

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

4467 {
4468  PQExpBuffer query;
4469  PGresult *res;
4470  PublicationSchemaInfo *pubsinfo;
4471  DumpOptions *dopt = fout->dopt;
4472  int i_tableoid;
4473  int i_oid;
4474  int i_pnpubid;
4475  int i_pnnspid;
4476  int i,
4477  j,
4478  ntups;
4479 
4480  if (dopt->no_publications || fout->remoteVersion < 150000)
4481  return;
4482 
4483  query = createPQExpBuffer();
4484 
4485  /* Collect all publication membership info. */
4486  appendPQExpBufferStr(query,
4487  "SELECT tableoid, oid, pnpubid, pnnspid "
4488  "FROM pg_catalog.pg_publication_namespace");
4489  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4490 
4491  ntups = PQntuples(res);
4492 
4493  i_tableoid = PQfnumber(res, "tableoid");
4494  i_oid = PQfnumber(res, "oid");
4495  i_pnpubid = PQfnumber(res, "pnpubid");
4496  i_pnnspid = PQfnumber(res, "pnnspid");
4497 
4498  /* this allocation may be more than we need */
4499  pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4500  j = 0;
4501 
4502  for (i = 0; i < ntups; i++)
4503  {
4504  Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4505  Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4506  PublicationInfo *pubinfo;
4507  NamespaceInfo *nspinfo;
4508 
4509  /*
4510  * Ignore any entries for which we aren't interested in either the
4511  * publication or the rel.
4512  */
4513  pubinfo = findPublicationByOid(pnpubid);
4514  if (pubinfo == NULL)
4515  continue;
4516  nspinfo = findNamespaceByOid(pnnspid);
4517  if (nspinfo == NULL)
4518  continue;
4519 
4520  /*
4521  * We always dump publication namespaces unless the corresponding
4522  * namespace is excluded from the dump.
4523  */
4524  if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
4525  continue;
4526 
4527  /* OK, make a DumpableObject for this relationship */
4529  pubsinfo[j].dobj.catId.tableoid =
4530  atooid(PQgetvalue(res, i, i_tableoid));
4531  pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4532  AssignDumpId(&pubsinfo[j].dobj);
4533  pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4534  pubsinfo[j].dobj.name = nspinfo->dobj.name;
4535  pubsinfo[j].publication = pubinfo;
4536  pubsinfo[j].pubschema = nspinfo;
4537 
4538  /* Decide whether we want to dump it */
4539  selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4540 
4541  j++;
4542  }
4543 
4544  PQclear(res);
4545  destroyPQExpBuffer(query);
4546 }
NamespaceInfo * findNamespaceByOid(Oid oid)
Definition: common.c:937
PublicationInfo * findPublicationByOid(Oid oid)
Definition: common.c:973
static void selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
Definition: pg_dump.c:2139
NamespaceInfo * pubschema
Definition: pg_dump.h:652
DumpableObject dobj
Definition: pg_dump.h:650
PublicationInfo * publication
Definition: pg_dump.h:651
int no_publications
Definition: pg_backup.h:183

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

void getPublications ( Archive fout)

Definition at line 4269 of file pg_dump.c.

4270 {
4271  DumpOptions *dopt = fout->dopt;
4272  PQExpBuffer query;
4273  PGresult *res;
4274  PublicationInfo *pubinfo;
4275  int i_tableoid;
4276  int i_oid;
4277  int i_pubname;
4278  int i_pubowner;
4279  int i_puballtables;
4280  int i_pubinsert;
4281  int i_pubupdate;
4282  int i_pubdelete;
4283  int i_pubtruncate;
4284  int i_pubviaroot;
4285  int i,
4286  ntups;
4287 
4288  if (dopt->no_publications || fout->remoteVersion < 100000)
4289  return;
4290 
4291  query = createPQExpBuffer();
4292 
4293  /* Get the publications. */
4294  if (fout->remoteVersion >= 130000)
4295  appendPQExpBufferStr(query,
4296  "SELECT p.tableoid, p.oid, p.pubname, "
4297  "p.pubowner, "
4298  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
4299  "FROM pg_publication p");
4300  else if (fout->remoteVersion >= 110000)
4301  appendPQExpBufferStr(query,
4302  "SELECT p.tableoid, p.oid, p.pubname, "
4303  "p.pubowner, "
4304  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
4305  "FROM pg_publication p");
4306  else
4307  appendPQExpBufferStr(query,
4308  "SELECT p.tableoid, p.oid, p.pubname, "
4309  "p.pubowner, "
4310  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot "
4311  "FROM pg_publication p");
4312 
4313  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4314 
4315  ntups = PQntuples(res);
4316 
4317  if (ntups == 0)
4318  goto cleanup;
4319 
4320  i_tableoid = PQfnumber(res, "tableoid");
4321  i_oid = PQfnumber(res, "oid");
4322  i_pubname = PQfnumber(res, "pubname");
4323  i_pubowner = PQfnumber(res, "pubowner");
4324  i_puballtables = PQfnumber(res, "puballtables");
4325  i_pubinsert = PQfnumber(res, "pubinsert");
4326  i_pubupdate = PQfnumber(res, "pubupdate");
4327  i_pubdelete = PQfnumber(res, "pubdelete");
4328  i_pubtruncate = PQfnumber(res, "pubtruncate");
4329  i_pubviaroot = PQfnumber(res, "pubviaroot");
4330 
4331  pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4332 
4333  for (i = 0; i < ntups; i++)
4334  {
4335  pubinfo[i].dobj.objType = DO_PUBLICATION;
4336  pubinfo[i].dobj.catId.tableoid =
4337  atooid(PQgetvalue(res, i, i_tableoid));
4338  pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4339  AssignDumpId(&pubinfo[i].dobj);
4340  pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4341  pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4342  pubinfo[i].puballtables =
4343  (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4344  pubinfo[i].pubinsert =
4345  (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4346  pubinfo[i].pubupdate =
4347  (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4348  pubinfo[i].pubdelete =
4349  (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4350  pubinfo[i].pubtruncate =
4351  (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4352  pubinfo[i].pubviaroot =
4353  (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4354 
4355  /* Decide whether we want to dump it */
4356  selectDumpableObject(&(pubinfo[i].dobj), fout);
4357  }
4358 
4359 cleanup:
4360  PQclear(res);
4361 
4362  destroyPQExpBuffer(query);
4363 }
const char * rolname
Definition: pg_dump.h:622
bool puballtables
Definition: pg_dump.h:623
bool pubtruncate
Definition: pg_dump.h:627
DumpableObject dobj
Definition: pg_dump.h:621

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

Referenced by getSchemaData().

◆ getPublicationTables()

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

Definition at line 4553 of file pg_dump.c.

4554 {
4555  PQExpBuffer query;
4556  PGresult *res;
4557  PublicationRelInfo *pubrinfo;
4558  DumpOptions *dopt = fout->dopt;
4559  int i_tableoid;
4560  int i_oid;
4561  int i_prpubid;
4562  int i_prrelid;
4563  int i_prrelqual;
4564  int i_prattrs;
4565  int i,
4566  j,
4567  ntups;
4568 
4569  if (dopt->no_publications || fout->remoteVersion < 100000)
4570  return;
4571 
4572  query = createPQExpBuffer();
4573 
4574  /* Collect all publication membership info. */
4575  if (fout->remoteVersion >= 150000)
4576  appendPQExpBufferStr(query,
4577  "SELECT tableoid, oid, prpubid, prrelid, "
4578  "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
4579  "(CASE\n"
4580  " WHEN pr.prattrs IS NOT NULL THEN\n"
4581  " (SELECT array_agg(attname)\n"
4582  " FROM\n"
4583  " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
4584  " pg_catalog.pg_attribute\n"
4585  " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
4586  " ELSE NULL END) prattrs "
4587  "FROM pg_catalog.pg_publication_rel pr");
4588  else
4589  appendPQExpBufferStr(query,
4590  "SELECT tableoid, oid, prpubid, prrelid, "
4591  "NULL AS prrelqual, NULL AS prattrs "
4592  "FROM pg_catalog.pg_publication_rel");
4593  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4594 
4595  ntups = PQntuples(res);
4596 
4597  i_tableoid = PQfnumber(res, "tableoid");
4598  i_oid = PQfnumber(res, "oid");
4599  i_prpubid = PQfnumber(res, "prpubid");
4600  i_prrelid = PQfnumber(res, "prrelid");
4601  i_prrelqual = PQfnumber(res, "prrelqual");
4602  i_prattrs = PQfnumber(res, "prattrs");
4603 
4604  /* this allocation may be more than we need */
4605  pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4606  j = 0;
4607 
4608  for (i = 0; i < ntups; i++)
4609  {
4610  Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4611  Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4612  PublicationInfo *pubinfo;
4613  TableInfo *tbinfo;
4614 
4615  /*
4616  * Ignore any entries for which we aren't interested in either the
4617  * publication or the rel.
4618  */
4619  pubinfo = findPublicationByOid(prpubid);
4620  if (pubinfo == NULL)
4621  continue;
4622  tbinfo = findTableByOid(prrelid);
4623  if (tbinfo == NULL)
4624  continue;
4625 
4626  /*
4627  * Ignore publication membership of tables whose definitions are not
4628  * to be dumped.
4629  */
4630  if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
4631  continue;
4632 
4633  /* OK, make a DumpableObject for this relationship */
4634  pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4635  pubrinfo[j].dobj.catId.tableoid =
4636  atooid(PQgetvalue(res, i, i_tableoid));
4637  pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4638  AssignDumpId(&pubrinfo[j].dobj);
4639  pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4640  pubrinfo[j].dobj.name = tbinfo->dobj.name;
4641  pubrinfo[j].publication = pubinfo;
4642  pubrinfo[j].pubtable = tbinfo;
4643  if (PQgetisnull(res, i, i_prrelqual))
4644  pubrinfo[j].pubrelqual = NULL;
4645  else
4646  pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
4647 
4648  if (!PQgetisnull(res, i, i_prattrs))
4649  {
4650  char **attnames;
4651  int nattnames;
4652  PQExpBuffer attribs;
4653 
4654  if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
4655  &attnames, &nattnames))
4656  pg_fatal("could not parse %s array", "prattrs");
4657  attribs = createPQExpBuffer();
4658  for (int k = 0; k < nattnames; k++)
4659  {
4660  if (k > 0)
4661  appendPQExpBufferStr(attribs, ", ");
4662 
4663  appendPQExpBufferStr(attribs, fmtId(attnames[k]));
4664  }
4665  pubrinfo[j].pubrattrs = attribs->data;
4666  }
4667  else
4668  pubrinfo[j].pubrattrs = NULL;
4669 
4670  /* Decide whether we want to dump it */
4671  selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
4672 
4673  j++;
4674  }
4675 
4676  PQclear(res);
4677  destroyPQExpBuffer(query);
4678 }
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()

void getRules ( Archive fout)

Definition at line 8074 of file pg_dump.c.

8075 {
8076  PGresult *res;
8077  int ntups;
8078  int i;
8079  PQExpBuffer query = createPQExpBuffer();
8080  RuleInfo *ruleinfo;
8081  int i_tableoid;
8082  int i_oid;
8083  int i_rulename;
8084  int i_ruletable;
8085  int i_ev_type;
8086  int i_is_instead;
8087  int i_ev_enabled;
8088 
8089  appendPQExpBufferStr(query, "SELECT "
8090  "tableoid, oid, rulename, "
8091  "ev_class AS ruletable, ev_type, is_instead, "
8092  "ev_enabled "
8093  "FROM pg_rewrite "
8094  "ORDER BY oid");
8095 
8096  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8097 
8098  ntups = PQntuples(res);
8099 
8100  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
8101 
8102  i_tableoid = PQfnumber(res, "tableoid");
8103  i_oid = PQfnumber(res, "oid");
8104  i_rulename = PQfnumber(res, "rulename");
8105  i_ruletable = PQfnumber(res, "ruletable");
8106  i_ev_type = PQfnumber(res, "ev_type");
8107  i_is_instead = PQfnumber(res, "is_instead");
8108  i_ev_enabled = PQfnumber(res, "ev_enabled");
8109 
8110  for (i = 0; i < ntups; i++)
8111  {
8112  Oid ruletableoid;
8113 
8114  ruleinfo[i].dobj.objType = DO_RULE;
8115  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8116  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8117  AssignDumpId(&ruleinfo[i].dobj);
8118  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8119  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8120  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8121  if (ruleinfo[i].ruletable == NULL)
8122  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8123  ruletableoid, ruleinfo[i].dobj.catId.oid);
8124  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8125  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8126  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8127  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8128  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8129  if (ruleinfo[i].ruletable)
8130  {
8131  /*
8132  * If the table is a view or materialized view, force its ON
8133  * SELECT rule to be sorted before the view itself --- this
8134  * ensures that any dependencies for the rule affect the table's
8135  * positioning. Other rules are forced to appear after their
8136  * table.
8137  */
8138  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8139  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8140  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8141  {
8142  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8143  ruleinfo[i].dobj.dumpId);
8144  /* We'll merge the rule into CREATE VIEW, if possible */
8145  ruleinfo[i].separate = false;
8146  }
8147  else
8148  {
8149  addObjectDependency(&ruleinfo[i].dobj,
8150  ruleinfo[i].ruletable->dobj.dumpId);
8151  ruleinfo[i].separate = true;
8152  }
8153  }
8154  else
8155  ruleinfo[i].separate = true;
8156  }
8157 
8158  PQclear(res);
8159 
8160  destroyPQExpBuffer(query);
8161 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:783
DumpableObject dobj
Definition: pg_dump.h:430
bool separate
Definition: pg_dump.h:435
char ev_enabled
Definition: pg_dump.h:434
bool is_instead
Definition: pg_dump.h:433
TableInfo * ruletable
Definition: pg_dump.h:431
char ev_type
Definition: pg_dump.h:432

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

99 {
100  TableInfo *tblinfo;
101  ExtensionInfo *extinfo;
102  InhInfo *inhinfo;
103  int numTables;
104  int numExtensions;
105  int numInherits;
106 
107  /*
108  * We must read extensions and extension membership info first, because
109  * extension membership needs to be consultable during decisions about
110  * whether other objects are to be dumped.
111  */
112  pg_log_info("reading extensions");
113  extinfo = getExtensions(fout, &numExtensions);
114 
115  pg_log_info("identifying extension members");
116  getExtensionMembership(fout, extinfo, numExtensions);
117 
118  pg_log_info("reading schemas");
119  getNamespaces(fout);
120 
121  /*
122  * getTables should be done as soon as possible, so as to minimize the
123  * window between starting our transaction and acquiring per-table locks.
124  * However, we have to do getNamespaces first because the tables get
125  * linked to their containing namespaces during getTables.
126  */
127  pg_log_info("reading user-defined tables");
128  tblinfo = getTables(fout, &numTables);
129 
130  getOwnedSeqs(fout, tblinfo, numTables);
131 
132  pg_log_info("reading user-defined functions");
133  getFuncs(fout);
134 
135  /* this must be after getTables and getFuncs */
136  pg_log_info("reading user-defined types");
137  getTypes(fout);
138 
139  /* this must be after getFuncs, too */
140  pg_log_info("reading procedural languages");
141  getProcLangs(fout);
142 
143  pg_log_info("reading user-defined aggregate functions");
144  getAggregates(fout);
145 
146  pg_log_info("reading user-defined operators");
147  getOperators(fout);
148 
149  pg_log_info("reading user-defined access methods");
150  getAccessMethods(fout);
151 
152  pg_log_info("reading user-defined operator classes");
153  getOpclasses(fout);
154 
155  pg_log_info("reading user-defined operator families");
156  getOpfamilies(fout);
157 
158  pg_log_info("reading user-defined text search parsers");
159  getTSParsers(fout);
160 
161  pg_log_info("reading user-defined text search templates");
162  getTSTemplates(fout);
163 
164  pg_log_info("reading user-defined text search dictionaries");
165  getTSDictionaries(fout);
166 
167  pg_log_info("reading user-defined text search configurations");
168  getTSConfigurations(fout);
169 
170  pg_log_info("reading user-defined foreign-data wrappers");
172 
173  pg_log_info("reading user-defined foreign servers");
174  getForeignServers(fout);
175 
176  pg_log_info("reading default privileges");
177  getDefaultACLs(fout);
178 
179  pg_log_info("reading user-defined collations");
180  getCollations(fout);
181 
182  pg_log_info("reading user-defined conversions");
183  getConversions(fout);
184 
185  pg_log_info("reading type casts");
186  getCasts(fout);
187 
188  pg_log_info("reading transforms");
189  getTransforms(fout);
190 
191  pg_log_info("reading table inheritance information");
192  inhinfo = getInherits(fout, &numInherits);
193 
194  pg_log_info("reading event triggers");
195  getEventTriggers(fout);
196 
197  /* Identify extension configuration tables that should be dumped */
198  pg_log_info("finding extension tables");
199  processExtensionTables(fout, extinfo, numExtensions);
200 
201  /* Link tables to parents, mark parents of target tables interesting */
202  pg_log_info("finding inheritance relationships");
203  flagInhTables(fout, tblinfo, numTables, inhinfo, numInherits);
204 
205  pg_log_info("reading column info for interesting tables");
206  getTableAttrs(fout, tblinfo, numTables);
207 
208  pg_log_info("flagging inherited columns in subtables");
209  flagInhAttrs(fout, tblinfo, numTables);
210 
211  pg_log_info("reading partitioning data");
212  getPartitioningInfo(fout);
213 
214  pg_log_info("reading indexes");
215  getIndexes(fout, tblinfo, numTables);
216 
217  pg_log_info("flagging indexes in partitioned tables");
218  flagInhIndexes(fout, tblinfo, numTables);
219 
220  pg_log_info("reading extended statistics");
221  getExtendedStatistics(fout);
222 
223  pg_log_info("reading constraints");
224  getConstraints(fout, tblinfo, numTables);
225 
226  pg_log_info("reading triggers");
227  getTriggers(fout, tblinfo, numTables);
228 
229  pg_log_info("reading rewrite rules");
230  getRules(fout);
231 
232  pg_log_info("reading policies");
233  getPolicies(fout, tblinfo, numTables);
234 
235  pg_log_info("reading publications");
236  getPublications(fout);
237 
238  pg_log_info("reading publication membership of tables");
239  getPublicationTables(fout, tblinfo, numTables);
240 
241  pg_log_info("reading publication membership of schemas");
243 
244  pg_log_info("reading subscriptions");
245  getSubscriptions(fout);
246 
247  pg_log_info("reading subscription membership of tables");
248  getSubscriptionTables(fout);
249 
250  free(inhinfo); /* not needed any longer */
251 
252  *numTablesPtr = numTables;
253  return tblinfo;
254 }
static void flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables, InhInfo *inhinfo, int numInherits)
Definition: common.c:269
static void flagInhIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
static void flagInhAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: common.c:477
#define free(a)
Definition: header.h:65
void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7796
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4466
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7337
void getForeignDataWrappers(Archive *fout)
Definition: pg_dump.c:9553
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:3984
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:18165
void getTypes(Archive *fout)
Definition: pg_dump.c:5893
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7218
void getOpclasses(Archive *fout)
Definition: pg_dump.c:6314
void getForeignServers(Archive *fout)
Definition: pg_dump.c:9637
void getFuncs(Archive *fout)
Definition: pg_dump.c:6577
void getTSDictionaries(Archive *fout)
Definition: pg_dump.c:9369
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4553
void getCasts(Archive *fout)
Definition: pg_dump.c:8529
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7397
void getTSConfigurations(Archive *fout)
Definition: pg_dump.c:9494
void getAccessMethods(Archive *fout)
Definition: pg_dump.c:6252
void getConversions(Archive *fout)
Definition: pg_dump.c:6190
void getRules(Archive *fout)
Definition: pg_dump.c:8074
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7281
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:8723
void getSubscriptionTables(Archive *fout)
Definition: pg_dump.c:5029
void getCollations(Archive *fout)
Definition: pg_dump.c:6128
void getAggregates(Archive *fout)
Definition: pg_dump.c:6436
void getNamespaces(Archive *fout)
Definition: pg_dump.c:5686
void getPublications(Archive *fout)
Definition: pg_dump.c:4269
void getTSParsers(Archive *fout)
Definition: pg_dump.c:9295
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:7717
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:18258
void getDefaultACLs(Archive *fout)
Definition: pg_dump.c:9725
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:4829
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:5818
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8171
void getTransforms(Archive *fout)
Definition: pg_dump.c:8639
void getEventTriggers(Archive *fout)
Definition: pg_dump.c:8367
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:6772
void getTSTemplates(Archive *fout)
Definition: pg_dump.c:9435
void getProcLangs(Archive *fout)
Definition: pg_dump.c:8445
void getOperators(Archive *fout)
Definition: pg_dump.c:6060
void getOpfamilies(Archive *fout)
Definition: pg_dump.c:6374

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

4830 {
4831  DumpOptions *dopt = fout->dopt;
4832  PQExpBuffer query;
4833  PGresult *res;
4834  SubscriptionInfo *subinfo;
4835  int i_tableoid;
4836  int i_oid;
4837  int i_subname;
4838  int i_subowner;
4839  int i_subbinary;
4840  int i_substream;
4841  int i_subtwophasestate;
4842  int i_subdisableonerr;
4843  int i_subpasswordrequired;
4844  int i_subrunasowner;
4845  int i_subconninfo;
4846  int i_subslotname;
4847  int i_subsynccommit;
4848  int i_subpublications;
4849  int i_suborigin;
4850  int i_suboriginremotelsn;
4851  int i_subenabled;
4852  int i_subfailover;
4853  int i,
4854  ntups;
4855 
4856  if (dopt->no_subscriptions || fout->remoteVersion < 100000)
4857  return;
4858 
4859  if (!is_superuser(fout))
4860  {
4861  int n;
4862 
4863  res = ExecuteSqlQuery(fout,
4864  "SELECT count(*) FROM pg_subscription "
4865  "WHERE subdbid = (SELECT oid FROM pg_database"
4866  " WHERE datname = current_database())",
4867  PGRES_TUPLES_OK);
4868  n = atoi(PQgetvalue(res, 0, 0));
4869  if (n > 0)
4870  pg_log_warning("subscriptions not dumped because current user is not a superuser");
4871  PQclear(res);
4872  return;
4873  }
4874 
4875  query = createPQExpBuffer();
4876 
4877  /* Get the subscriptions in current database. */
4878  appendPQExpBufferStr(query,
4879  "SELECT s.tableoid, s.oid, s.subname,\n"
4880  " s.subowner,\n"
4881  " s.subconninfo, s.subslotname, s.subsynccommit,\n"
4882  " s.subpublications,\n");
4883 
4884  if (fout->remoteVersion >= 140000)
4885  appendPQExpBufferStr(query, " s.subbinary,\n");
4886  else
4887  appendPQExpBufferStr(query, " false AS subbinary,\n");
4888 
4889  if (fout->remoteVersion >= 140000)
4890  appendPQExpBufferStr(query, " s.substream,\n");
4891  else
4892  appendPQExpBufferStr(query, " 'f' AS substream,\n");
4893 
4894  if (fout->remoteVersion >= 150000)
4895  appendPQExpBufferStr(query,
4896  " s.subtwophasestate,\n"
4897  " s.subdisableonerr,\n");
4898  else
4899  appendPQExpBuffer(query,
4900  " '%c' AS subtwophasestate,\n"
4901  " false AS subdisableonerr,\n",
4903 
4904  if (fout->remoteVersion >= 160000)
4905  appendPQExpBufferStr(query,
4906  " s.subpasswordrequired,\n"
4907  " s.subrunasowner,\n"
4908  " s.suborigin,\n");
4909  else
4910  appendPQExpBuffer(query,
4911  " 't' AS subpasswordrequired,\n"
4912  " 't' AS subrunasowner,\n"
4913  " '%s' AS suborigin,\n",
4915 
4916  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4917  appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
4918  " s.subenabled,\n");
4919  else
4920  appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
4921  " false AS subenabled,\n");
4922 
4923  if (fout->remoteVersion >= 170000)
4924  appendPQExpBufferStr(query,
4925  " s.subfailover\n");
4926  else
4927  appendPQExpBuffer(query,
4928  " false AS subfailover\n");
4929 
4930  appendPQExpBufferStr(query,
4931  "FROM pg_subscription s\n");
4932 
4933  if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
4934  appendPQExpBufferStr(query,
4935  "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
4936  " ON o.external_id = 'pg_' || s.oid::text \n");
4937 
4938  appendPQExpBufferStr(query,
4939  "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
4940  " WHERE datname = current_database())");
4941 
4942  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4943 
4944  ntups = PQntuples(res);
4945 
4946  /*
4947  * Get subscription fields. We don't include subskiplsn in the dump as
4948  * after restoring the dump this value may no longer be relevant.
4949  */
4950  i_tableoid = PQfnumber(res, "tableoid");
4951  i_oid = PQfnumber(res, "oid");
4952  i_subname = PQfnumber(res, "subname");
4953  i_subowner = PQfnumber(res, "subowner");
4954  i_subbinary = PQfnumber(res, "subbinary");
4955  i_substream = PQfnumber(res, "substream");
4956  i_subtwophasestate = PQfnumber(res, "subtwophasestate");
4957  i_subdisableonerr = PQfnumber(res, "subdisableonerr");
4958  i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
4959  i_subrunasowner = PQfnumber(res, "subrunasowner");
4960  i_subconninfo = PQfnumber(res, "subconninfo");
4961  i_subslotname = PQfnumber(res, "subslotname");
4962  i_subsynccommit = PQfnumber(res, "subsynccommit");
4963  i_subpublications = PQfnumber(res, "subpublications");
4964  i_suborigin = PQfnumber(res, "suborigin");
4965  i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
4966  i_subenabled = PQfnumber(res, "subenabled");
4967  i_subfailover = PQfnumber(res, "subfailover");
4968 
4969  subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
4970 
4971  for (i = 0; i < ntups; i++)
4972  {
4973  subinfo[i].dobj.objType = DO_SUBSCRIPTION;
4974  subinfo[i].dobj.catId.tableoid =
4975  atooid(PQgetvalue(res, i, i_tableoid));
4976  subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4977  AssignDumpId(&subinfo[i].dobj);
4978  subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
4979  subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
4980 
4981  subinfo[i].subbinary =
4982  pg_strdup(PQgetvalue(res, i, i_subbinary));
4983  subinfo[i].substream =
4984  pg_strdup(PQgetvalue(res, i, i_substream));
4985  subinfo[i].subtwophasestate =
4986  pg_strdup(PQgetvalue(res, i, i_subtwophasestate));
4987  subinfo[i].subdisableonerr =
4988  pg_strdup(PQgetvalue(res, i, i_subdisableonerr));
4989  subinfo[i].subpasswordrequired =
4990  pg_strdup(PQgetvalue(res, i, i_subpasswordrequired));
4991  subinfo[i].subrunasowner =
4992  pg_strdup(PQgetvalue(res, i, i_subrunasowner));
4993  subinfo[i].subconninfo =
4994  pg_strdup(PQgetvalue(res, i, i_subconninfo));
4995  if (PQgetisnull(res, i, i_subslotname))
4996  subinfo[i].subslotname = NULL;
4997  else
4998  subinfo[i].subslotname =
4999  pg_strdup(PQgetvalue(res, i, i_subslotname));
5000  subinfo[i].subsynccommit =
5001  pg_strdup(PQgetvalue(res, i, i_subsynccommit));
5002  subinfo[i].subpublications =
5003  pg_strdup(PQgetvalue(res, i, i_subpublications));
5004  subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
5005  if (PQgetisnull(res, i, i_suboriginremotelsn))
5006  subinfo[i].suboriginremotelsn = NULL;
5007  else
5008  subinfo[i].suboriginremotelsn =
5009  pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
5010  subinfo[i].subenabled =
5011  pg_strdup(PQgetvalue(res, i, i_subenabled));
5012  subinfo[i].subfailover =
5013  pg_strdup(PQgetvalue(res, i, i_subfailover));
5014 
5015  /* Decide whether we want to dump it */
5016  selectDumpableObject(&(subinfo[i].dobj), fout);
5017  }
5018  PQclear(res);
5019 
5020  destroyPQExpBuffer(query);
5021 }
static bool is_superuser(Archive *fout)
Definition: pg_dump.c:4789
#define LOGICALREP_ORIGIN_ANY
#define LOGICALREP_TWOPHASE_STATE_DISABLED
char * suboriginremotelsn
Definition: pg_dump.h:674
char * suborigin
Definition: pg_dump.h:673
char * subbinary
Definition: pg_dump.h:663
const char * rolname
Definition: pg_dump.h:661
char * subrunasowner
Definition: pg_dump.h:668
char * subsynccommit
Definition: pg_dump.h:671
char * subpublications
Definition: pg_dump.h:672
char * subtwophasestate
Definition: pg_dump.h:665
char * subfailover
Definition: pg_dump.h:675
char * subenabled
Definition: pg_dump.h:662
char * substream
Definition: pg_dump.h:664
char * subpasswordrequired
Definition: pg_dump.h:667
char * subslotname
Definition: pg_dump.h:670
char * subdisableonerr
Definition: pg_dump.h:666
char * subconninfo
Definition: pg_dump.h:669
DumpableObject dobj
Definition: pg_dump.h:660
int no_subscriptions
Definition: pg_backup.h:184

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

5030 {
5031  DumpOptions *dopt = fout->dopt;
5032  SubscriptionInfo *subinfo = NULL;
5033  SubRelInfo *subrinfo;
5034  PGresult *res;
5035  int i_srsubid;
5036  int i_srrelid;
5037  int i_srsubstate;
5038  int i_srsublsn;
5039  int ntups;
5040  Oid last_srsubid = InvalidOid;
5041 
5042  if (dopt->no_subscriptions || !dopt->binary_upgrade ||
5043  fout->remoteVersion < 170000)
5044  return;
5045 
5046  res = ExecuteSqlQuery(fout,
5047  "SELECT srsubid, srrelid, srsubstate, srsublsn "
5048  "FROM pg_catalog.pg_subscription_rel "
5049  "ORDER BY srsubid",
5050  PGRES_TUPLES_OK);
5051  ntups = PQntuples(res);
5052  if (ntups == 0)
5053  goto cleanup;
5054 
5055  /* Get pg_subscription_rel attributes */
5056  i_srsubid = PQfnumber(res, "srsubid");
5057  i_srrelid = PQfnumber(res, "srrelid");
5058  i_srsubstate = PQfnumber(res, "srsubstate");
5059  i_srsublsn = PQfnumber(res, "srsublsn");
5060 
5061  subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
5062  for (int i = 0; i < ntups; i++)
5063  {
5064  Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
5065  Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
5066  TableInfo *tblinfo;
5067 
5068  /*
5069  * If we switched to a new subscription, check if the subscription
5070  * exists.
5071  */
5072  if (cur_srsubid != last_srsubid)
5073  {
5074  subinfo = findSubscriptionByOid(cur_srsubid);
5075  if (subinfo == NULL)
5076  pg_fatal("subscription with OID %u does not exist", cur_srsubid);
5077 
5078  last_srsubid = cur_srsubid;
5079  }
5080 
5081  tblinfo = findTableByOid(relid);
5082  if (tblinfo == NULL)
5083  pg_fatal("failed sanity check, table with OID %u not found",
5084  relid);
5085 
5086  /* OK, make a DumpableObject for this relationship */
5087  subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
5088  subrinfo[i].dobj.catId.tableoid = relid;
5089  subrinfo[i].dobj.catId.oid = cur_srsubid;
5090  AssignDumpId(&subrinfo[i].dobj);
5091  subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
5092  subrinfo[i].tblinfo = tblinfo;
5093  subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
5094  if (PQgetisnull(res, i, i_srsublsn))
5095  subrinfo[i].srsublsn = NULL;
5096  else
5097  subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
5098 
5099  subrinfo[i].subinfo = subinfo;
5100 
5101  /* Decide whether we want to dump it */
5102  selectDumpableObject(&(subrinfo[i].dobj), fout);
5103  }
5104 
5105 cleanup:
5106  PQclear(res);
5107 }
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:991
DumpableObject dobj
Definition: pg_dump.h:690
char * srsublsn
Definition: pg_dump.h:694
SubscriptionInfo * subinfo
Definition: pg_dump.h:691
TableInfo * tblinfo
Definition: pg_dump.h:692
char srsubstate
Definition: pg_dump.h:693

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

8724 {
8725  DumpOptions *dopt = fout->dopt;
8727  PQExpBuffer tbloids = createPQExpBuffer();
8728  PQExpBuffer checkoids = createPQExpBuffer();
8729  PGresult *res;
8730  int ntups;
8731  int curtblindx;
8732  int i_attrelid;
8733  int i_attnum;
8734  int i_attname;
8735  int i_atttypname;
8736  int i_attstattarget;
8737  int i_attstorage;
8738  int i_typstorage;
8739  int i_attidentity;
8740  int i_attgenerated;
8741  int i_attisdropped;
8742  int i_attlen;
8743  int i_attalign;
8744  int i_attislocal;
8745  int i_attnotnull;
8746  int i_attoptions;
8747  int i_attcollation;
8748  int i_attcompression;
8749  int i_attfdwoptions;
8750  int i_attmissingval;
8751  int i_atthasdef;
8752 
8753  /*
8754  * We want to perform just one query against pg_attribute, and then just
8755  * one against pg_attrdef (for DEFAULTs) and one against pg_constraint
8756  * (for CHECK constraints). However, we mustn't try to select every row
8757  * of those catalogs and then sort it out on the client side, because some
8758  * of the server-side functions we need would be unsafe to apply to tables
8759  * we don't have lock on. Hence, we build an array of the OIDs of tables
8760  * we care about (and now have lock on!), and use a WHERE clause to
8761  * constrain which rows are selected.
8762  */
8763  appendPQExpBufferChar(tbloids, '{');
8764  appendPQExpBufferChar(checkoids, '{');
8765  for (int i = 0; i < numTables; i++)
8766  {
8767  TableInfo *tbinfo = &tblinfo[i];
8768 
8769  /* Don't bother to collect info for sequences */
8770  if (tbinfo->relkind == RELKIND_SEQUENCE)
8771  continue;
8772 
8773  /* Don't bother with uninteresting tables, either */
8774  if (!tbinfo->interesting)
8775  continue;
8776 
8777  /* OK, we need info for this table */
8778  if (tbloids->len > 1) /* do we have more than the '{'? */
8779  appendPQExpBufferChar(tbloids, ',');
8780  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8781 
8782  if (tbinfo->ncheck > 0)
8783  {
8784  /* Also make a list of the ones with check constraints */
8785  if (checkoids->len > 1) /* do we have more than the '{'? */
8786  appendPQExpBufferChar(checkoids, ',');
8787  appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
8788  }
8789  }
8790  appendPQExpBufferChar(tbloids, '}');
8791  appendPQExpBufferChar(checkoids, '}');
8792 
8793  /*
8794  * Find all the user attributes and their types.
8795  *
8796  * Since we only want to dump COLLATE clauses for attributes whose
8797  * collation is different from their type's default, we use a CASE here to
8798  * suppress uninteresting attcollations cheaply.
8799  */
8801  "SELECT\n"
8802  "a.attrelid,\n"
8803  "a.attnum,\n"
8804  "a.attname,\n"
8805  "a.attstattarget,\n"
8806  "a.attstorage,\n"
8807  "t.typstorage,\n"
8808  "a.attnotnull,\n"
8809  "a.atthasdef,\n"
8810  "a.attisdropped,\n"
8811  "a.attlen,\n"
8812  "a.attalign,\n"
8813  "a.attislocal,\n"
8814  "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
8815  "array_to_string(a.attoptions, ', ') AS attoptions,\n"
8816  "CASE WHEN a.attcollation <> t.typcollation "
8817  "THEN a.attcollation ELSE 0 END AS attcollation,\n"
8818  "pg_catalog.array_to_string(ARRAY("
8819  "SELECT pg_catalog.quote_ident(option_name) || "
8820  "' ' || pg_catalog.quote_literal(option_value) "
8821  "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8822  "ORDER BY option_name"
8823  "), E',\n ') AS attfdwoptions,\n");
8824 
8825  if (fout->remoteVersion >= 140000)
8827  "a.attcompression AS attcompression,\n");
8828  else
8830  "'' AS attcompression,\n");
8831 
8832  if (fout->remoteVersion >= 100000)
8834  "a.attidentity,\n");
8835  else
8837  "'' AS attidentity,\n");
8838 
8839  if (fout->remoteVersion >= 110000)
8841  "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8842  "THEN a.attmissingval ELSE null END AS attmissingval,\n");
8843  else
8845  "NULL AS attmissingval,\n");
8846 
8847  if (fout->remoteVersion >= 120000)
8849  "a.attgenerated\n");
8850  else
8852  "'' AS attgenerated\n");
8853 
8854  /* need left join to pg_type to not fail on dropped columns ... */
8856  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8857  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
8858  "LEFT JOIN pg_catalog.pg_type t "
8859  "ON (a.atttypid = t.oid)\n"
8860  "WHERE a.attnum > 0::pg_catalog.int2\n"
8861  "ORDER BY a.attrelid, a.attnum",
8862  tbloids->data);
8863 
8864  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8865 
8866  ntups = PQntuples(res);
8867 
8868  i_attrelid = PQfnumber(res, "attrelid");
8869  i_attnum = PQfnumber(res, "attnum");
8870  i_attname = PQfnumber(res, "attname");
8871  i_atttypname = PQfnumber(res, "atttypname");
8872  i_attstattarget = PQfnumber(res, "attstattarget");
8873  i_attstorage = PQfnumber(res, "attstorage");
8874  i_typstorage = PQfnumber(res, "typstorage");
8875  i_attidentity = PQfnumber(res, "attidentity");
8876  i_attgenerated = PQfnumber(res, "attgenerated");
8877  i_attisdropped = PQfnumber(res, "attisdropped");
8878  i_attlen = PQfnumber(res, "attlen");
8879  i_attalign = PQfnumber(res, "attalign");
8880  i_attislocal = PQfnumber(res, "attislocal");
8881  i_attnotnull = PQfnumber(res, "attnotnull");
8882  i_attoptions = PQfnumber(res, "attoptions");
8883  i_attcollation = PQfnumber(res, "attcollation");
8884  i_attcompression = PQfnumber(res, "attcompression");
8885  i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8886  i_attmissingval = PQfnumber(res, "attmissingval");
8887  i_atthasdef = PQfnumber(res, "atthasdef");
8888 
8889  /* Within the next loop, we'll accumulate OIDs of tables with defaults */
8890  resetPQExpBuffer(tbloids);
8891  appendPQExpBufferChar(tbloids, '{');
8892 
8893  /*
8894  * Outer loop iterates once per table, not once per row. Incrementing of
8895  * r is handled by the inner loop.
8896  */
8897  curtblindx = -1;
8898  for (int r = 0; r < ntups;)
8899  {
8900  Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
8901  TableInfo *tbinfo = NULL;
8902  int numatts;
8903  bool hasdefaults;
8904 
8905  /* Count rows for this table */
8906  for (numatts = 1; numatts < ntups - r; numatts++)
8907  if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
8908  break;
8909 
8910  /*
8911  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8912  * order.
8913  */
8914  while (++curtblindx < numTables)
8915  {
8916  tbinfo = &tblinfo[curtblindx];
8917  if (tbinfo->dobj.catId.oid == attrelid)
8918  break;
8919  }
8920  if (curtblindx >= numTables)
8921  pg_fatal("unrecognized table OID %u", attrelid);
8922  /* cross-check that we only got requested tables */
8923  if (tbinfo->relkind == RELKIND_SEQUENCE ||
8924  !tbinfo->interesting)
8925  pg_fatal("unexpected column data for table \"%s\"",
8926  tbinfo->dobj.name);
8927 
8928  /* Save data for this table */
8929  tbinfo->numatts = numatts;
8930  tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
8931  tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
8932  tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
8933  tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
8934  tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
8935  tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
8936  tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
8937  tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
8938  tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
8939  tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
8940  tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
8941  tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
8942  tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
8943  tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
8944  tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
8945  tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
8946  tbinfo->notnull = (bool *) pg_malloc(numatts * sizeof(bool));
8947  tbinfo->inhNotNull = (bool *) pg_malloc(numatts * sizeof(bool));
8948  tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
8949  hasdefaults = false;
8950 
8951  for (int j = 0; j < numatts; j++, r++)
8952  {
8953  if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
8954  pg_fatal("invalid column numbering in table \"%s\"",
8955  tbinfo->dobj.name);
8956  tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
8957  tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
8958  if (PQgetisnull(res, r, i_attstattarget))
8959  tbinfo->attstattarget[j] = -1;
8960  else
8961  tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
8962  tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
8963  tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
8964  tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
8965  tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
8966  tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
8967  tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
8968  tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
8969  tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
8970  tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
8971  tbinfo->notnull[j] = (PQgetvalue(res, r, i_attnotnull)[0] == 't');
8972  tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
8973  tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
8974  tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
8975  tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
8976  tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
8977  tbinfo->attrdefs[j] = NULL; /* fix below */
8978  if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
8979  hasdefaults = true;
8980  /* these flags will be set in flagInhAttrs() */
8981  tbinfo->inhNotNull[j] = false;
8982  }
8983 
8984  if (hasdefaults)
8985  {
8986  /* Collect OIDs of interesting tables that have defaults */
8987  if (tbloids->len > 1) /* do we have more than the '{'? */
8988  appendPQExpBufferChar(tbloids, ',');
8989  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8990  }
8991  }
8992 
8993  PQclear(res);
8994 
8995  /*
8996  * Now get info about column defaults. This is skipped for a data-only
8997  * dump, as it is only needed for table schemas.
8998  */
8999  if (!dopt->dataOnly && tbloids->len > 1)
9000  {
9001  AttrDefInfo *attrdefs;
9002  int numDefaults;
9003  TableInfo *tbinfo = NULL;
9004 
9005  pg_log_info("finding table default expressions");
9006 
9007  appendPQExpBufferChar(tbloids, '}');
9008 
9009  printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
9010  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
9011  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9012  "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
9013  "ORDER BY a.adrelid, a.adnum",
9014  tbloids->data);
9015 
9016  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9017 
9018  numDefaults = PQntuples(res);
9019  attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
9020 
9021  curtblindx = -1;
9022  for (int j = 0; j < numDefaults; j++)
9023  {
9024  Oid adtableoid = atooid(PQgetvalue(res, j, 0));
9025  Oid adoid = atooid(PQgetvalue(res, j, 1));
9026  Oid adrelid = atooid(PQgetvalue(res, j, 2));
9027  int adnum = atoi(PQgetvalue(res, j, 3));
9028  char *adsrc = PQgetvalue(res, j, 4);
9029 
9030  /*
9031  * Locate the associated TableInfo; we rely on tblinfo[] being in
9032  * OID order.
9033  */
9034  if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
9035  {
9036  while (++curtblindx < numTables)
9037  {
9038  tbinfo = &tblinfo[curtblindx];
9039  if (tbinfo->dobj.catId.oid == adrelid)
9040  break;
9041  }
9042  if (curtblindx >= numTables)
9043  pg_fatal("unrecognized table OID %u", adrelid);
9044  }
9045 
9046  if (adnum <= 0 || adnum > tbinfo->numatts)
9047  pg_fatal("invalid adnum value %d for table \"%s\"",
9048  adnum, tbinfo->dobj.name);
9049 
9050  /*
9051  * dropped columns shouldn't have defaults, but just in case,
9052  * ignore 'em
9053  */
9054  if (tbinfo->attisdropped[adnum - 1])
9055  continue;
9056 
9057  attrdefs[j].dobj.objType = DO_ATTRDEF;
9058  attrdefs[j].dobj.catId.tableoid = adtableoid;
9059  attrdefs[j].dobj.catId.oid = adoid;
9060  AssignDumpId(&attrdefs[j].dobj);
9061  attrdefs[j].adtable = tbinfo;
9062  attrdefs[j].adnum = adnum;
9063  attrdefs[j].adef_expr = pg_strdup(adsrc);
9064 
9065  attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
9066  attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
9067 
9068  attrdefs[j].dobj.dump = tbinfo->dobj.dump;
9069 
9070  /*
9071  * Figure out whether the default/generation expression should be
9072  * dumped as part of the main CREATE TABLE (or similar) command or
9073  * as a separate ALTER TABLE (or similar) command. The preference
9074  * is to put it into the CREATE command, but in some cases that's
9075  * not possible.
9076  */
9077  if (tbinfo->attgenerated[adnum - 1])
9078  {
9079  /*
9080  * Column generation expressions cannot be dumped separately,
9081  * because there is no syntax for it. By setting separate to
9082  * false here we prevent the "default" from being processed as
9083  * its own dumpable object. Later, flagInhAttrs() will mark
9084  * it as not to be dumped at all, if possible (that is, if it
9085  * can be inherited from a parent).
9086  */
9087  attrdefs[j].separate = false;
9088  }
9089  else if (tbinfo->relkind == RELKIND_VIEW)
9090  {
9091  /*
9092  * Defaults on a VIEW must always be dumped as separate ALTER
9093  * TABLE commands.
9094  */
9095  attrdefs[j].separate = true;
9096  }
9097  else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
9098  {
9099  /* column will be suppressed, print default separately */
9100  attrdefs[j].separate = true;
9101  }
9102  else
9103  {
9104  attrdefs[j].separate = false;
9105  }
9106 
9107  if (!attrdefs[j].separate)
9108  {
9109  /*
9110  * Mark the default as needing to appear before the table, so
9111  * that any dependencies it has must be emitted before the
9112  * CREATE TABLE. If this is not possible, we'll change to
9113  * "separate" mode while sorting dependencies.
9114  */
9115  addObjectDependency(&tbinfo->dobj,
9116  attrdefs[j].dobj.dumpId);
9117  }
9118 
9119  tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9120  }
9121 
9122  PQclear(res);
9123  }
9124 
9125  /*
9126  * Get info about table CHECK constraints. This is skipped for a
9127  * data-only dump, as it is only needed for table schemas.
9128  */
9129  if (!dopt->dataOnly && checkoids->len > 2)
9130  {
9131  ConstraintInfo *constrs;
9132  int numConstrs;
9133  int i_tableoid;
9134  int i_oid;
9135  int i_conrelid;
9136  int i_conname;
9137  int i_consrc;
9138  int i_conislocal;
9139  int i_convalidated;
9140 
9141  pg_log_info("finding table check constraints");
9142 
9143  resetPQExpBuffer(q);
9145  "SELECT c.tableoid, c.oid, conrelid, conname, "
9146  "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9147  "conislocal, convalidated "
9148  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9149  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9150  "WHERE contype = 'c' "
9151  "ORDER BY c.conrelid, c.conname",
9152  checkoids->data);
9153 
9154  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9155 
9156  numConstrs = PQntuples(res);
9157  constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9158 
9159  i_tableoid = PQfnumber(res, "tableoid");
9160  i_oid = PQfnumber(res, "oid");
9161  i_conrelid = PQfnumber(res, "conrelid");
9162  i_conname = PQfnumber(res, "conname");
9163  i_consrc = PQfnumber(res, "consrc");
9164  i_conislocal = PQfnumber(res, "conislocal");
9165  i_convalidated = PQfnumber(res, "convalidated");
9166 
9167  /* As above, this loop iterates once per table, not once per row */
9168  curtblindx = -1;
9169  for (int j = 0; j < numConstrs;)
9170  {
9171  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9172  TableInfo *tbinfo = NULL;
9173  int numcons;
9174 
9175  /* Count rows for this table */
9176  for (numcons = 1; numcons < numConstrs - j; numcons++)
9177  if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9178  break;
9179 
9180  /*
9181  * Locate the associated TableInfo; we rely on tblinfo[] being in
9182  * OID order.
9183  */
9184  while (++curtblindx < numTables)
9185  {
9186  tbinfo = &tblinfo[curtblindx];
9187  if (tbinfo->dobj.catId.oid == conrelid)
9188  break;
9189  }
9190  if (curtblindx >= numTables)
9191  pg_fatal("unrecognized table OID %u", conrelid);
9192 
9193  if (numcons != tbinfo->ncheck)
9194  {
9195  pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9196  "expected %d check constraints on table \"%s\" but found %d",
9197  tbinfo->ncheck),
9198  tbinfo->ncheck, tbinfo->dobj.name, numcons);
9199  pg_log_error_hint("The system catalogs might be corrupted.");
9200  exit_nicely(1);
9201  }
9202 
9203  tbinfo->checkexprs = constrs + j;
9204 
9205  for (int c = 0; c < numcons; c++, j++)
9206  {
9207  bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9208 
9209  constrs[j].dobj.objType = DO_CONSTRAINT;
9210  constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9211  constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9212  AssignDumpId(&constrs[j].dobj);
9213  constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9214  constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9215  constrs[j].contable = tbinfo;
9216  constrs[j].condomain = NULL;
9217  constrs[j].contype = 'c';
9218  constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9219  constrs[j].confrelid = InvalidOid;
9220  constrs[j].conindex = 0;
9221  constrs[j].condeferrable = false;
9222  constrs[j].condeferred = false;
9223  constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9224 
9225  /*
9226  * An unvalidated constraint needs to be dumped separately, so
9227  * that potentially-violating existing data is loaded before
9228  * the constraint.
9229  */
9230  constrs[j].separate = !validated;
9231 
9232  constrs[j].dobj.dump = tbinfo->dobj.dump;
9233 
9234  /*
9235  * Mark the constraint as needing to appear before the table
9236  * --- this is so that any other dependencies of the
9237  * constraint will be emitted before we try to create the
9238  * table. If the constraint is to be dumped separately, it
9239  * will be dumped after data is loaded anyway, so don't do it.
9240  * (There's an automatic dependency in the opposite direction
9241  * anyway, so don't need to add one manually here.)
9242  */
9243  if (!constrs[j].separate)
9244  addObjectDependency(&tbinfo->dobj,
9245  constrs[j].dobj.dumpId);
9246 
9247  /*
9248  * We will detect later whether the constraint must be split
9249  * out from the table definition.
9250  */
9251  }
9252  }
9253 
9254  PQclear(res);
9255  }
9256 
9257  destroyPQExpBuffer(q);
9258  destroyPQExpBuffer(tbloids);
9259  destroyPQExpBuffer(checkoids);
9260 }
#define ngettext(s, p, n)
Definition: c.h:1172
#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:9280
#define exit_nicely(code)
Definition: pg_dumpall.c:124
DumpableObject dobj
Definition: pg_dump.h:376
char * adef_expr
Definition: pg_dump.h:379
TableInfo * adtable
Definition: pg_dump.h:377
bool separate
Definition: pg_dump.h:380
bool dataOnly
Definition: pg_backup.h:171
char * attidentity
Definition: pg_dump.h:340
int ncheck
Definition: pg_dump.h:309
bool * attislocal
Definition: pg_dump.h:344
char * attgenerated
Definition: pg_dump.h:341
int * attlen
Definition: pg_dump.h:342
char ** attfdwoptions
Definition: pg_dump.h:348
bool * attisdropped
Definition: pg_dump.h:339
bool needs_override
Definition: pg_dump.h:354
struct _constraintInfo * checkexprs
Definition: pg_dump.h:353
int * attstattarget
Definition: pg_dump.h:336
char * typstorage
Definition: pg_dump.h:338
int numatts
Definition: pg_dump.h:333
struct _attrDefInfo ** attrdefs
Definition: pg_dump.h:352
char ** attoptions
Definition: pg_dump.h:345
Oid * attcollation
Definition: pg_dump.h:346
char * attstorage
Definition: pg_dump.h:337
bool * notnull
Definition: pg_dump.h:350
char ** atttypnames
Definition: pg_dump.h:335
char ** attmissingval
Definition: pg_dump.h:349
char ** attnames
Definition: pg_dump.h:334
char * attalign
Definition: pg_dump.h:343
char * attcompression
Definition: pg_dump.h:347
bool * inhNotNull
Definition: pg_dump.h:351

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, _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::inhNotNull, _tableInfo::interesting, InvalidOid, j, PQExpBufferData::len, _dumpableObject::name, _tableInfo::ncheck, _tableInfo::needs_override, ngettext, _tableInfo::notnull, _tableInfo::numatts, _dumpableObject::objType, CatalogId::oid, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, 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 6772 of file pg_dump.c.

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

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

void getTransforms ( Archive fout)

Definition at line 8639 of file pg_dump.c.

8640 {
8641  PGresult *res;
8642  int ntups;
8643  int i;
8644  PQExpBuffer query;
8645  TransformInfo *transforminfo;
8646  int i_tableoid;
8647  int i_oid;
8648  int i_trftype;
8649  int i_trflang;
8650  int i_trffromsql;
8651  int i_trftosql;
8652 
8653  /* Transforms didn't exist pre-9.5 */
8654  if (fout->remoteVersion < 90500)
8655  return;
8656 
8657  query = createPQExpBuffer();
8658 
8659  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8660  "trftype, trflang, trffromsql::oid, trftosql::oid "
8661  "FROM pg_transform "
8662  "ORDER BY 3,4");
8663 
8664  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8665 
8666  ntups = PQntuples(res);
8667 
8668  transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8669 
8670  i_tableoid = PQfnumber(res, "tableoid");
8671  i_oid = PQfnumber(res, "oid");
8672  i_trftype = PQfnumber(res, "trftype");
8673  i_trflang = PQfnumber(res, "trflang");
8674  i_trffromsql = PQfnumber(res, "trffromsql");
8675  i_trftosql = PQfnumber(res, "trftosql");
8676 
8677  for (i = 0; i < ntups; i++)
8678  {
8679  PQExpBufferData namebuf;
8680  TypeInfo *typeInfo;
8681  char *lanname;
8682 
8683  transforminfo[i].dobj.objType = DO_TRANSFORM;
8684  transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8685  transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8686  AssignDumpId(&transforminfo[i].dobj);
8687  transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8688  transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8689  transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8690  transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8691 
8692  /*
8693  * Try to name transform as concatenation of type and language name.
8694  * This is only used for purposes of sorting. If we fail to find
8695  * either, the name will be an empty string.
8696  */
8697  initPQExpBuffer(&namebuf);
8698  typeInfo = findTypeByOid(transforminfo[i].trftype);
8699  lanname = get_language_name(fout, transforminfo[i].trflang);
8700  if (typeInfo && lanname)
8701  appendPQExpBuffer(&namebuf, "%s %s",
8702  typeInfo->dobj.name, lanname);
8703  transforminfo[i].dobj.name = namebuf.data;
8704  free(lanname);
8705 
8706  /* Decide whether we want to dump it */
8707  selectDumpableObject(&(transforminfo[i].dobj), fout);
8708  }
8709 
8710  PQclear(res);
8711 
8712  destroyPQExpBuffer(query);
8713 }
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8618
DumpableObject dobj
Definition: pg_dump.h:506
Oid trffromsql
Definition: pg_dump.h:509

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

8172 {
8173  PQExpBuffer query = createPQExpBuffer();
8174  PQExpBuffer tbloids = createPQExpBuffer();
8175  PGresult *res;
8176  int ntups;
8177  int curtblindx;
8178  TriggerInfo *tginfo;
8179  int i_tableoid,
8180  i_oid,
8181  i_tgrelid,
8182  i_tgname,
8183  i_tgenabled,
8184  i_tgispartition,
8185  i_tgdef;
8186 
8187  /*
8188  * We want to perform just one query against pg_trigger. However, we
8189  * mustn't try to select every row of the catalog and then sort it out on
8190  * the client side, because some of the server-side functions we need
8191  * would be unsafe to apply to tables we don't have lock on. Hence, we
8192  * build an array of the OIDs of tables we care about (and now have lock
8193  * on!), and use a WHERE clause to constrain which rows are selected.
8194  */
8195  appendPQExpBufferChar(tbloids, '{');
8196  for (int i = 0; i < numTables; i++)
8197  {
8198  TableInfo *tbinfo = &tblinfo[i];
8199 
8200  if (!tbinfo->hastriggers ||
8201  !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
8202  continue;
8203 
8204  /* OK, we need info for this table */
8205  if (tbloids->len > 1) /* do we have more than the '{'? */
8206  appendPQExpBufferChar(tbloids, ',');
8207  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8208  }
8209  appendPQExpBufferChar(tbloids, '}');
8210 
8211  if (fout->remoteVersion >= 150000)
8212  {
8213  /*
8214  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8215  * result in non-forward-compatible dumps of WHEN clauses due to
8216  * under-parenthesization.
8217  *
8218  * NB: We need to see partition triggers in case the tgenabled flag
8219  * has been changed from the parent.
8220  */
8221  appendPQExpBuffer(query,
8222  "SELECT t.tgrelid, t.tgname, "
8223  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8224  "t.tgenabled, t.tableoid, t.oid, "
8225  "t.tgparentid <> 0 AS tgispartition\n"
8226  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8227  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8228  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8229  "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
8230  "OR t.tgenabled != u.tgenabled) "
8231  "ORDER BY t.tgrelid, t.tgname",
8232  tbloids->data);
8233  }
8234  else if (fout->remoteVersion >= 130000)
8235  {
8236  /*
8237  * NB: think not to use pretty=true in pg_get_triggerdef. It could
8238  * result in non-forward-compatible dumps of WHEN clauses due to
8239  * under-parenthesization.
8240  *
8241  * NB: We need to see tgisinternal triggers in partitions, in case the
8242  * tgenabled flag has been changed from the parent.
8243  */
8244  appendPQExpBuffer(query,
8245  "SELECT t.tgrelid, t.tgname, "
8246  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8247  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
8248  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8249  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8250  "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
8251  "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
8252  "ORDER BY t.tgrelid, t.tgname",
8253  tbloids->data);
8254  }
8255  else if (fout->remoteVersion >= 110000)
8256  {
8257  /*
8258  * NB: We need to see tgisinternal triggers in partitions, in case the
8259  * tgenabled flag has been changed from the parent. No tgparentid in
8260  * version 11-12, so we have to match them via pg_depend.
8261  *
8262  * See above about pretty=true in pg_get_triggerdef.
8263  */
8264  appendPQExpBuffer(query,
8265  "SELECT t.tgrelid, t.tgname, "
8266  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8267  "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
8268  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8269  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8270  "LEFT JOIN pg_catalog.pg_depend AS d ON "
8271  " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8272  " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8273  " d.objid = t.oid "
8274  "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8275  "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
8276  "ORDER BY t.tgrelid, t.tgname",
8277  tbloids->data);
8278  }
8279  else
8280  {
8281  /* See above about pretty=true in pg_get_triggerdef */
8282  appendPQExpBuffer(query,
8283  "SELECT t.tgrelid, t.tgname, "
8284  "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8285  "t.tgenabled, false as tgispartition, "
8286  "t.tableoid, t.oid "
8287  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8288  "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
8289  "WHERE NOT tgisinternal "
8290  "ORDER BY t.tgrelid, t.tgname",
8291  tbloids->data);
8292  }
8293 
8294  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8295 
8296  ntups = PQntuples(res);
8297 
8298  i_tableoid = PQfnumber(res, "tableoid");
8299  i_oid = PQfnumber(res, "oid");
8300  i_tgrelid = PQfnumber(res, "tgrelid");
8301  i_tgname = PQfnumber(res, "tgname");
8302  i_tgenabled = PQfnumber(res, "tgenabled");
8303  i_tgispartition = PQfnumber(res, "tgispartition");
8304  i_tgdef = PQfnumber(res, "tgdef");
8305 
8306  tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
8307 
8308  /*
8309  * Outer loop iterates once per table, not once per row. Incrementing of
8310  * j is handled by the inner loop.
8311  */
8312  curtblindx = -1;
8313  for (int j = 0; j < ntups;)
8314  {
8315  Oid tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
8316  TableInfo *tbinfo = NULL;
8317  int numtrigs;
8318 
8319  /* Count rows for this table */
8320  for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
8321  if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
8322  break;
8323 
8324  /*
8325  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8326  * order.
8327  */
8328  while (++curtblindx < numTables)
8329  {
8330  tbinfo = &tblinfo[curtblindx];
8331  if (tbinfo->dobj.catId.oid == tgrelid)
8332  break;
8333  }
8334  if (curtblindx >= numTables)
8335  pg_fatal("unrecognized table OID %u", tgrelid);
8336 
8337  /* Save data for this table */
8338  tbinfo->triggers = tginfo + j;
8339  tbinfo->numTriggers = numtrigs;
8340 
8341  for (int c = 0; c < numtrigs; c++, j++)
8342  {
8343  tginfo[j].dobj.objType = DO_TRIGGER;
8344  tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
8345  tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
8346  AssignDumpId(&tginfo[j].dobj);
8347  tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
8348  tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8349  tginfo[j].tgtable = tbinfo;
8350  tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8351  tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
8352  tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
8353  }
8354  }
8355 
8356  PQclear(res);
8357 
8358  destroyPQExpBuffer(query);
8359  destroyPQExpBuffer(tbloids);
8360 }
struct _triggerInfo * triggers
Definition: pg_dump.h:364
int numTriggers
Definition: pg_dump.h:363
TableInfo * tgtable
Definition: pg_dump.h:442
DumpableObject dobj
Definition: pg_dump.h:441
char tgenabled
Definition: pg_dump.h:443
char * tgdef
Definition: pg_dump.h:445
bool tgispartition
Definition: pg_dump.h:444

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

void getTSConfigurations ( Archive fout)

Definition at line 9494 of file pg_dump.c.

9495 {
9496  PGresult *res;
9497  int ntups;
9498  int i;
9499  PQExpBuffer query;
9500  TSConfigInfo *cfginfo;
9501  int i_tableoid;
9502  int i_oid;
9503  int i_cfgname;
9504  int i_cfgnamespace;
9505  int i_cfgowner;
9506  int i_cfgparser;
9507 
9508  query = createPQExpBuffer();
9509 
9510  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9511  "cfgnamespace, cfgowner, cfgparser "
9512  "FROM pg_ts_config");
9513 
9514  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9515 
9516  ntups = PQntuples(res);
9517 
9518  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9519 
9520  i_tableoid = PQfnumber(res, "tableoid");
9521  i_oid = PQfnumber(res, "oid");
9522  i_cfgname = PQfnumber(res, "cfgname");
9523  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9524  i_cfgowner = PQfnumber(res, "cfgowner");
9525  i_cfgparser = PQfnumber(res, "cfgparser");
9526 
9527  for (i = 0; i < ntups; i++)
9528  {
9529  cfginfo[i].dobj.objType = DO_TSCONFIG;
9530  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9531  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9532  AssignDumpId(&cfginfo[i].dobj);
9533  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9534  cfginfo[i].dobj.namespace =
9535  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9536  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9537  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9538 
9539  /* Decide whether we want to dump it */
9540  selectDumpableObject(&(cfginfo[i].dobj), fout);
9541  }
9542 
9543  PQclear(res);
9544 
9545  destroyPQExpBuffer(query);
9546 }
Oid cfgparser
Definition: pg_dump.h:549
DumpableObject dobj
Definition: pg_dump.h:547
const char * rolname
Definition: pg_dump.h:548

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

void getTSDictionaries ( Archive fout)

Definition at line 9369 of file pg_dump.c.

9370 {
9371  PGresult *res;
9372  int ntups;
9373  int i;
9374  PQExpBuffer query;
9375  TSDictInfo *dictinfo;
9376  int i_tableoid;
9377  int i_oid;
9378  int i_dictname;
9379  int i_dictnamespace;
9380  int i_dictowner;
9381  int i_dicttemplate;
9382  int i_dictinitoption;
9383 
9384  query = createPQExpBuffer();
9385 
9386  appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9387  "dictnamespace, dictowner, "
9388  "dicttemplate, dictinitoption "
9389  "FROM pg_ts_dict");
9390 
9391  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9392 
9393  ntups = PQntuples(res);
9394 
9395  dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9396 
9397  i_tableoid = PQfnumber(res, "tableoid");
9398  i_oid = PQfnumber(res, "oid");
9399  i_dictname = PQfnumber(res, "dictname");
9400  i_dictnamespace = PQfnumber(res, "dictnamespace");
9401  i_dictowner = PQfnumber(res, "dictowner");
9402  i_dictinitoption = PQfnumber(res, "dictinitoption");
9403  i_dicttemplate = PQfnumber(res, "dicttemplate");
9404 
9405  for (i = 0; i < ntups; i++)
9406  {
9407  dictinfo[i].dobj.objType = DO_TSDICT;
9408  dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9409  dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9410  AssignDumpId(&dictinfo[i].dobj);
9411  dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9412  dictinfo[i].dobj.namespace =
9413  findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9414  dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9415  dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9416  if (PQgetisnull(res, i, i_dictinitoption))
9417  dictinfo[i].dictinitoption = NULL;
9418  else
9419  dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9420 
9421  /* Decide whether we want to dump it */
9422  selectDumpableObject(&(dictinfo[i].dobj), fout);
9423  }
9424 
9425  PQclear(res);
9426 
9427  destroyPQExpBuffer(query);
9428 }
char * dictinitoption
Definition: pg_dump.h:535
DumpableObject dobj
Definition: pg_dump.h:532
const char * rolname
Definition: pg_dump.h:533
Oid dicttemplate
Definition: pg_dump.h:534

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

void getTSParsers ( Archive fout)

Definition at line 9295 of file pg_dump.c.

9296 {
9297  PGresult *res;
9298  int ntups;
9299  int i;
9300  PQExpBuffer query;
9301  TSParserInfo *prsinfo;
9302  int i_tableoid;
9303  int i_oid;
9304  int i_prsname;
9305  int i_prsnamespace;
9306  int i_prsstart;
9307  int i_prstoken;
9308  int i_prsend;
9309  int i_prsheadline;
9310  int i_prslextype;
9311 
9312  query = createPQExpBuffer();
9313 
9314  /*
9315  * find all text search objects, including builtin ones; we filter out
9316  * system-defined objects at dump-out time.
9317  */
9318 
9319  appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
9320  "prsstart::oid, prstoken::oid, "
9321  "prsend::oid, prsheadline::oid, prslextype::oid "
9322  "FROM pg_ts_parser");
9323 
9324  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9325 
9326  ntups = PQntuples(res);
9327 
9328  prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
9329 
9330  i_tableoid = PQfnumber(res, "tableoid");
9331  i_oid = PQfnumber(res, "oid");
9332  i_prsname = PQfnumber(res, "prsname");
9333  i_prsnamespace = PQfnumber(res, "prsnamespace");
9334  i_prsstart = PQfnumber(res, "prsstart");
9335  i_prstoken = PQfnumber(res, "prstoken");
9336  i_prsend = PQfnumber(res, "prsend");
9337  i_prsheadline = PQfnumber(res, "prsheadline");
9338  i_prslextype = PQfnumber(res, "prslextype");
9339 
9340  for (i = 0; i < ntups; i++)
9341  {
9342  prsinfo[i].dobj.objType = DO_TSPARSER;
9343  prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9344  prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9345  AssignDumpId(&prsinfo[i].dobj);
9346  prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
9347  prsinfo[i].dobj.namespace =
9348  findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
9349  prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
9350  prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
9351  prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
9352  prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
9353  prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
9354 
9355  /* Decide whether we want to dump it */
9356  selectDumpableObject(&(prsinfo[i].dobj), fout);
9357  }
9358 
9359  PQclear(res);
9360 
9361  destroyPQExpBuffer(query);
9362 }
DumpableObject dobj
Definition: pg_dump.h:522
Oid prstoken
Definition: pg_dump.h:524
Oid prslextype
Definition: pg_dump.h:527
Oid prsheadline
Definition: pg_dump.h:526
Oid prsstart
Definition: pg_dump.h:523
Oid prsend
Definition: pg_dump.h:525

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

void getTSTemplates ( Archive fout)

Definition at line 9435 of file pg_dump.c.

9436 {
9437  PGresult *res;
9438  int ntups;
9439  int i;
9440  PQExpBuffer query;
9441  TSTemplateInfo *tmplinfo;
9442  int i_tableoid;
9443  int i_oid;
9444  int i_tmplname;
9445  int i_tmplnamespace;
9446  int i_tmplinit;
9447  int i_tmpllexize;
9448 
9449  query = createPQExpBuffer();
9450 
9451  appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
9452  "tmplnamespace, tmplinit::oid, tmpllexize::oid "
9453  "FROM pg_ts_template");
9454 
9455  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9456 
9457  ntups = PQntuples(res);
9458 
9459  tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
9460 
9461  i_tableoid = PQfnumber(res, "tableoid");
9462  i_oid = PQfnumber(res, "oid");
9463  i_tmplname = PQfnumber(res, "tmplname");
9464  i_tmplnamespace = PQfnumber(res, "tmplnamespace");
9465  i_tmplinit = PQfnumber(res, "tmplinit");
9466  i_tmpllexize = PQfnumber(res, "tmpllexize");
9467 
9468  for (i = 0; i < ntups; i++)
9469  {
9470  tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
9471  tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9472  tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9473  AssignDumpId(&tmplinfo[i].dobj);
9474  tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
9475  tmplinfo[i].dobj.namespace =
9476  findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
9477  tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
9478  tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
9479 
9480  /* Decide whether we want to dump it */
9481  selectDumpableObject(&(tmplinfo[i].dobj), fout);
9482  }
9483 
9484  PQclear(res);
9485 
9486  destroyPQExpBuffer(query);
9487 }
Oid tmpllexize
Definition: pg_dump.h:542
Oid tmplinit
Definition: pg_dump.h:541
DumpableObject dobj
Definition: pg_dump.h:540

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

void getTypes ( Archive fout)

Definition at line 5893 of file pg_dump.c.

5894 {
5895  PGresult *res;
5896  int ntups;
5897  int i;
5898  PQExpBuffer query = createPQExpBuffer();
5899  TypeInfo *tyinfo;
5900  ShellTypeInfo *stinfo;
5901  int i_tableoid;
5902  int i_oid;
5903  int i_typname;
5904  int i_typnamespace;
5905  int i_typacl;
5906  int i_acldefault;
5907  int i_typowner;
5908  int i_typelem;
5909  int i_typrelid;
5910  int i_typrelkind;
5911  int i_typtype;
5912  int i_typisdefined;
5913  int i_isarray;
5914  int i_typarray;
5915 
5916  /*
5917  * we include even the built-in types because those may be used as array
5918  * elements by user-defined types
5919  *
5920  * we filter out the built-in types when we dump out the types
5921  *
5922  * same approach for undefined (shell) types and array types
5923  *
5924  * Note: as of 8.3 we can reliably detect whether a type is an
5925  * auto-generated array type by checking the element type's typarray.
5926  * (Before that the test is capable of generating false positives.) We
5927  * still check for name beginning with '_', though, so as to avoid the
5928  * cost of the subselect probe for all standard types. This would have to
5929  * be revisited if the backend ever allows renaming of array types.
5930  */
5931  appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
5932  "typnamespace, typacl, "
5933  "acldefault('T', typowner) AS acldefault, "
5934  "typowner, "
5935  "typelem, typrelid, typarray, "
5936  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
5937  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
5938  "typtype, typisdefined, "
5939  "typname[0] = '_' AND typelem != 0 AND "
5940  "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
5941  "FROM pg_type");
5942 
5943  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5944 
5945  ntups = PQntuples(res);
5946 
5947  tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
5948 
5949  i_tableoid = PQfnumber(res, "tableoid");
5950  i_oid = PQfnumber(res, "oid");
5951  i_typname = PQfnumber(res, "typname");
5952  i_typnamespace = PQfnumber(res, "typnamespace");
5953  i_typacl = PQfnumber(res, "typacl");
5954  i_acldefault = PQfnumber(res, "acldefault");
5955  i_typowner = PQfnumber(res, "typowner");
5956  i_typelem = PQfnumber(res, "typelem");
5957  i_typrelid = PQfnumber(res, "typrelid");
5958  i_typrelkind = PQfnumber(res, "typrelkind");
5959  i_typtype = PQfnumber(res, "typtype");
5960  i_typisdefined = PQfnumber(res, "typisdefined");
5961  i_isarray = PQfnumber(res, "isarray");
5962  i_typarray = PQfnumber(res, "typarray");
5963 
5964  for (i = 0; i < ntups; i++)
5965  {
5966  tyinfo[i].dobj.objType = DO_TYPE;
5967  tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5968  tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5969  AssignDumpId(&tyinfo[i].dobj);
5970  tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
5971  tyinfo[i].dobj.namespace =
5972  findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
5973  tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
5974  tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5975  tyinfo[i].dacl.privtype = 0;
5976  tyinfo[i].dacl.initprivs = NULL;
5977  tyinfo[i].ftypname = NULL; /* may get filled later */
5978  tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
5979  tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
5980  tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
5981  tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
5982  tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
5983  tyinfo[i].shellType = NULL;
5984 
5985  if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
5986  tyinfo[i].isDefined = true;
5987  else
5988  tyinfo[i].isDefined = false;
5989 
5990  if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
5991  tyinfo[i].isArray = true;
5992  else
5993  tyinfo[i].isArray = false;
5994 
5995  tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
5996 
5997  if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
5998  tyinfo[i].isMultirange = true;
5999  else
6000  tyinfo[i].isMultirange = false;
6001 
6002  /* Decide whether we want to dump it */
6003  selectDumpableType(&tyinfo[i], fout);
6004 
6005  /* Mark whether type has an ACL */
6006  if (!PQgetisnull(res, i, i_typacl))
6007  tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
6008 
6009  /*
6010  * If it's a domain, fetch info about its constraints, if any
6011  */
6012  tyinfo[i].nDomChecks = 0;
6013  tyinfo[i].domChecks = NULL;
6014  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6015  tyinfo[i].typtype == TYPTYPE_DOMAIN)
6016  getDomainConstraints(fout, &(tyinfo[i]));
6017 
6018  /*
6019  * If it's a base type, make a DumpableObject representing a shell
6020  * definition of the type. We will need to dump that ahead of the I/O
6021  * functions for the type. Similarly, range types need a shell
6022  * definition in case they have a canonicalize function.
6023  *
6024  * Note: the shell type doesn't have a catId. You might think it
6025  * should copy the base type's catId, but then it might capture the
6026  * pg_depend entries for the type, which we don't want.
6027  */
6028  if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
6029  (tyinfo[i].typtype == TYPTYPE_BASE ||
6030  tyinfo[i].typtype == TYPTYPE_RANGE))
6031  {
6032  stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
6033  stinfo->dobj.objType = DO_SHELL_TYPE;
6034  stinfo->dobj.catId = nilCatalogId;
6035  AssignDumpId(&stinfo->dobj);
6036  stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
6037  stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
6038  stinfo->baseType = &(tyinfo[i]);
6039  tyinfo[i].shellType = stinfo;
6040 
6041  /*
6042  * Initially mark the shell type as not to be dumped. We'll only
6043  * dump it if the I/O or canonicalize functions need to be dumped;
6044  * this is taken care of while sorting dependencies.
6045  */
6046  stinfo->dobj.dump = DUMP_COMPONENT_NONE;
6047  }
6048  }
6049 
6050  PQclear(res);
6051 
6052  destroyPQExpBuffer(query);
6053 }
static const CatalogId nilCatalogId
Definition: pg_dump.c:186
static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
Definition: pg_dump.c:7984
static void selectDumpableType(TypeInfo *tyinfo, Archive *fout)
Definition: pg_dump.c:1947
TypeInfo * baseType
Definition: pg_dump.h:220
DumpableObject dobj
Definition: pg_dump.h:218
bool isMultirange
Definition: pg_dump.h:207
struct _constraintInfo * domChecks
Definition: pg_dump.h:213
DumpableAcl dacl
Definition: pg_dump.h:192
bool isDefined
Definition: pg_dump.h:208
char * ftypname
Definition: pg_dump.h:199
char typrelkind
Definition: pg_dump.h:204
Oid typarray
Definition: pg_dump.h:203
Oid typelem
Definition: pg_dump.h:201
struct _shellTypeInfo * shellType
Definition: pg_dump.h:210
int nDomChecks
Definition: pg_dump.h:212
char typtype
Definition: pg_dump.h:205
const char * rolname
Definition: pg_dump.h:200
Oid typrelid
Definition: pg_dump.h:202
bool isArray
Definition: pg_dump.h:206

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::typarray, _typeInfo::typelem, _typeInfo::typrelid, _typeInfo::typrelkind, and _typeInfo::typtype.

Referenced by getSchemaData().

◆ parseOidArray()

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

Definition at line 1058 of file common.c.

1059 {
1060  int j,
1061  argNum;
1062  char temp[100];
1063  char s;
1064 
1065  argNum = 0;
1066  j = 0;
1067  for (;;)
1068  {
1069  s = *str++;
1070  if (s == ' ' || s == '\0')
1071  {
1072  if (j > 0)
1073  {
1074  if (argNum >= arraysize)
1075  pg_fatal("could not parse numeric array \"%s\": too many numbers", str);
1076  temp[j] = '\0';
1077  array[argNum++] = atooid(temp);
1078  j = 0;
1079  }
1080  if (s == '\0')
1081  break;
1082  }
1083  else
1084  {
1085  if (!(isdigit((unsigned char) s) || s == '-') ||
1086  j >= sizeof(temp) - 1)
1087  pg_fatal("could not parse numeric array \"%s\": invalid character in number", str);
1088  temp[j++] = s;
1089  }
1090  }
1091 
1092  while (argNum < arraysize)
1093  array[argNum++] = InvalidOid;
1094 }
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 18258 of file pg_dump.c.

18260 {
18261  DumpOptions *dopt = fout->dopt;
18262  PQExpBuffer query;
18263  PGresult *res;
18264  int ntups,
18265  i;
18266  int i_conrelid,
18267  i_confrelid;
18268 
18269  /* Nothing to do if no extensions */
18270  if (numExtensions == 0)
18271  return;
18272 
18273  /*
18274  * Identify extension configuration tables and create TableDataInfo
18275  * objects for them, ensuring their data will be dumped even though the
18276  * tables themselves won't be.
18277  *
18278  * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
18279  * user data in a configuration table is treated like schema data. This
18280  * seems appropriate since system data in a config table would get
18281  * reloaded by CREATE EXTENSION. If the extension is not listed in the
18282  * list of extensions to be included, none of its data is dumped.
18283  */
18284  for (i = 0; i < numExtensions; i++)
18285  {
18286  ExtensionInfo *curext = &(extinfo[i]);
18287  char *extconfig = curext->extconfig;
18288  char *extcondition = curext->extcondition;
18289  char **extconfigarray = NULL;
18290  char **extconditionarray = NULL;
18291  int nconfigitems = 0;
18292  int nconditionitems = 0;
18293 
18294  /*
18295  * Check if this extension is listed as to include in the dump. If
18296  * not, any table data associated with it is discarded.
18297  */
18298  if (extension_include_oids.head != NULL &&
18300  curext->dobj.catId.oid))
18301  continue;
18302 
18303  /*
18304  * Check if this extension is listed as to exclude in the dump. If
18305  * yes, any table data associated with it is discarded.
18306  */
18307  if (extension_exclude_oids.head != NULL &&
18309  curext->dobj.catId.oid))
18310  continue;
18311 
18312  if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
18313  {
18314  int j;
18315 
18316  if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
18317  pg_fatal("could not parse %s array", "extconfig");
18318  if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
18319  pg_fatal("could not parse %s array", "extcondition");
18320  if (nconfigitems != nconditionitems)
18321  pg_fatal("mismatched number of configurations and conditions for extension");
18322 
18323  for (j = 0; j < nconfigitems; j++)
18324  {
18325  TableInfo *configtbl;
18326  Oid configtbloid = atooid(extconfigarray[j]);
18327  bool dumpobj =
18329 
18330  configtbl = findTableByOid(configtbloid);
18331  if (configtbl == NULL)
18332  continue;
18333 
18334  /*
18335  * Tables of not-to-be-dumped extensions shouldn't be dumped
18336  * unless the table or its schema is explicitly included
18337  */
18338  if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
18339  {
18340  /* check table explicitly requested */
18341  if (table_include_oids.head != NULL &&
18343  configtbloid))
18344  dumpobj = true;
18345 
18346  /* check table's schema explicitly requested */
18347  if (configtbl->dobj.namespace->dobj.dump &
18349  dumpobj = true;
18350  }
18351 
18352  /* check table excluded by an exclusion switch */
18353  if (table_exclude_oids.head != NULL &&
18355  configtbloid))
18356  dumpobj = false;
18357 
18358  /* check schema excluded by an exclusion switch */
18360  configtbl->dobj.namespace->dobj.catId.oid))
18361  dumpobj = false;
18362 
18363  if (dumpobj)
18364  {
18365  makeTableDataInfo(dopt, configtbl);
18366  if (configtbl->dataObj != NULL)
18367  {
18368  if (strlen(extconditionarray[j]) > 0)
18369  configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
18370  }
18371  }
18372  }
18373  }
18374  if (extconfigarray)
18375  free(extconfigarray);
18376  if (extconditionarray)
18377  free(extconditionarray);
18378  }
18379 
18380  /*
18381  * Now that all the TableDataInfo objects have been created for all the
18382  * extensions, check their FK dependencies and register them to try and
18383  * dump the data out in an order that they can be restored in.
18384  *
18385  * Note that this is not a problem for user tables as their FKs are
18386  * recreated after the data has been loaded.
18387  */
18388 
18389  query = createPQExpBuffer();
18390 
18391  printfPQExpBuffer(query,
18392  "SELECT conrelid, confrelid "
18393  "FROM pg_constraint "
18394  "JOIN pg_depend ON (objid = confrelid) "
18395  "WHERE contype = 'f' "
18396  "AND refclassid = 'pg_extension'::regclass "
18397  "AND classid = 'pg_class'::regclass;");
18398 
18399  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18400  ntups = PQntuples(res);
18401 
18402  i_conrelid = PQfnumber(res, "conrelid");
18403  i_confrelid = PQfnumber(res, "confrelid");
18404 
18405  /* Now get the dependencies and register them */
18406  for (i = 0; i < ntups; i++)
18407  {
18408  Oid conrelid,
18409  confrelid;
18410  TableInfo *reftable,
18411  *contable;
18412 
18413  conrelid = atooid(PQgetvalue(res, i, i_conrelid));
18414  confrelid = atooid(PQgetvalue(res, i, i_confrelid));
18415  contable = findTableByOid(conrelid);
18416  reftable = findTableByOid(confrelid);
18417 
18418  if (reftable == NULL ||
18419  reftable->dataObj == NULL ||
18420  contable == NULL ||
18421  contable->dataObj == NULL)
18422  continue;
18423 
18424  /*
18425  * Make referencing TABLE_DATA object depend on the referenced table's
18426  * TABLE_DATA object.
18427  */
18428  addObjectDependency(&contable->dataObj->dobj,
18429  reftable->dataObj->dobj.dumpId);
18430  }
18431  PQclear(res);
18432  destroyPQExpBuffer(query);
18433 }
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:165
static SimpleOidList extension_include_oids
Definition: pg_dump.c:181
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:184
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2853
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:172
static SimpleOidList table_include_oids
Definition: pg_dump.c:169
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:385
char * filtercond
Definition: pg_dump.h:387
struct _tableDataInfo * dataObj
Definition: pg_dump.h:362

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

685 {
686  CatalogIdMapEntry *entry;
687  bool found;
688 
689  /* CatalogId hash table must exist, if we have a DumpableObject */
690  Assert(catalogIdHash != NULL);
691 
692  /* Add reference to CatalogId hash */
693  entry = catalogid_insert(catalogIdHash, catId, &found);
694  if (!found)
695  {
696  entry->dobj = NULL;
697  entry->ext = NULL;
698  }
699  Assert(entry->dobj == NULL);
700  entry->dobj = dobj;
701 }

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

Referenced by getLOs().

◆ recordExtensionMembership()

void recordExtensionMembership ( CatalogId  catId,
ExtensionInfo ext 
)

Definition at line 1010 of file common.c.

1011 {
1012  CatalogIdMapEntry *entry;
1013  bool found;
1014 
1015  /* CatalogId hash table must exist, if we have an ExtensionInfo */
1016  Assert(catalogIdHash != NULL);
1017 
1018  /* Add reference to CatalogId hash */
1019  entry = catalogid_insert(catalogIdHash, catId, &found);
1020  if (!found)
1021  {
1022  entry->dobj = NULL;
1023  entry->ext = NULL;
1024  }
1025  Assert(entry->ext == NULL);
1026  entry->ext = ext;
1027 }

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

9281 {
9282  if (dopt->binary_upgrade)
9283  return true;
9284  if (tbinfo->attisdropped[colno])
9285  return false;
9286  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9287 }

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

References DOTypeNameCompare(), and qsort.

Referenced by main().