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:858
#define OidIsValid(objectId)
Definition: c.h:775
#define DUMP_COMPONENT_ALL
Definition: pg_dump.h:104
#define DUMP_COMPONENT_DEFINITION
Definition: pg_dump.h:97
Oid tableoid
Definition: pg_backup.h:266
ExtensionInfo * ext
Definition: common.c:64
DumpableObject * dobj
Definition: common.c:63
DumpComponents dump
Definition: pg_dump.h:139
char * name
Definition: pg_dump.h:138
DumpId dumpId
Definition: pg_dump.h:137
bool ext_member
Definition: pg_dump.h:143
DumpComponents components
Definition: pg_dump.h:142
CatalogId catId
Definition: pg_dump.h:136
DumpComponents dump_contains
Definition: pg_dump.h:141
bool depends_on_ext
Definition: pg_dump.h:144

References _dumpableObject::allocDeps, allocedDumpIds, Assert, catalogIdHash, CATALOGIDHASH_INITIAL_SIZE, _dumpableObject::catId, _dumpableObject::components, _dumpableObject::dependencies, _dumpableObject::depends_on_ext, _catalogIdMapEntry::dobj, _dumpableObject::dump, DUMP_COMPONENT_ALL, DUMP_COMPONENT_DEFINITION, _dumpableObject::dump_contains, _dumpableObject::dumpId, dumpIdMap, _catalogIdMapEntry::ext, _dumpableObject::ext_member, lastDumpId, _dumpableObject::name, _dumpableObject::nDeps, OidIsValid, pg_malloc_array, pg_realloc_array, and CatalogId::tableoid.

Referenced by createBoundaryObjects(), flagInhAttrs(), flagInhIndexes(), flagInhTables(), getAccessMethods(), getAggregates(), getCasts(), getCollations(), getConstraints(), getConversions(), getDefaultACLs(), getDomainConstraints(), getEventTriggers(), getExtendedStatistics(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getIndexes(), getLOs(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getPolicies(), getProcLangs(), getPublicationNamespaces(), getPublications(), getPublicationTables(), getRules(), getSubscriptions(), getSubscriptionTables(), getTableAttrs(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), and makeTableDataInfo().

◆ createDumpId()

◆ findCollationByOid()

CollInfo* findCollationByOid ( Oid  oid)

Definition at line 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 collectComments(), collectSecLabels(), DOTypeNameCompare(), getCasts(), getFormattedTypeName(), and getTransforms().

◆ getAccessMethods()

void getAccessMethods ( Archive fout)

Definition at line 6160 of file pg_dump.c.

6161 {
6162  PGresult *res;
6163  int ntups;
6164  int i;
6165  PQExpBuffer query;
6166  AccessMethodInfo *aminfo;
6167  int i_tableoid;
6168  int i_oid;
6169  int i_amname;
6170  int i_amhandler;
6171  int i_amtype;
6172 
6173  /* Before 9.6, there are no user-defined access methods */
6174  if (fout->remoteVersion < 90600)
6175  return;
6176 
6177  query = createPQExpBuffer();
6178 
6179  /* Select all access methods from pg_am table */
6180  appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6181  "amhandler::pg_catalog.regproc AS amhandler "
6182  "FROM pg_am");
6183 
6184  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6185 
6186  ntups = PQntuples(res);
6187 
6188  aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
6189 
6190  i_tableoid = PQfnumber(res, "tableoid");
6191  i_oid = PQfnumber(res, "oid");
6192  i_amname = PQfnumber(res, "amname");
6193  i_amhandler = PQfnumber(res, "amhandler");
6194  i_amtype = PQfnumber(res, "amtype");
6195 
6196  for (i = 0; i < ntups; i++)
6197  {
6198  aminfo[i].dobj.objType = DO_ACCESS_METHOD;
6199  aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6200  aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6201  AssignDumpId(&aminfo[i].dobj);
6202  aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
6203  aminfo[i].dobj.namespace = NULL;
6204  aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
6205  aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
6206 
6207  /* Decide whether we want to dump it */
6208  selectDumpableAccessMethod(&(aminfo[i]), fout);
6209  }
6210 
6211  PQclear(res);
6212 
6213  destroyPQExpBuffer(query);
6214 }
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:102
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:2024
#define atooid(x)
Definition: postgres_ext.h:42
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
int remoteVersion
Definition: pg_backup.h:219
char * amhandler
Definition: pg_dump.h:253
DumpableObject dobj
Definition: pg_dump.h:251

References _accessMethodInfo::amhandler, _accessMethodInfo::amtype, appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_ACCESS_METHOD, _accessMethodInfo::dobj, ExecuteSqlQuery(), i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, selectDumpableAccessMethod(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getAggregates()

void getAggregates ( Archive fout)

Definition at line 6344 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpOptions::binary_upgrade, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_AGG, Archive::dopt, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findNamespace(), getRoleName(), i, InvalidOid, parseOidArray(), pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, and selectDumpableObject().

Referenced by getSchemaData().

◆ getCasts()

void getCasts ( Archive fout)

Definition at line 8427 of file pg_dump.c.

8428 {
8429  PGresult *res;
8430  int ntups;
8431  int i;
8432  PQExpBuffer query = createPQExpBuffer();
8433  CastInfo *castinfo;
8434  int i_tableoid;
8435  int i_oid;
8436  int i_castsource;
8437  int i_casttarget;
8438  int i_castfunc;
8439  int i_castcontext;
8440  int i_castmethod;
8441 
8442  if (fout->remoteVersion >= 140000)
8443  {
8444  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8445  "castsource, casttarget, castfunc, castcontext, "
8446  "castmethod "
8447  "FROM pg_cast c "
8448  "WHERE NOT EXISTS ( "
8449  "SELECT 1 FROM pg_range r "
8450  "WHERE c.castsource = r.rngtypid "
8451  "AND c.casttarget = r.rngmultitypid "
8452  ") "
8453  "ORDER BY 3,4");
8454  }
8455  else
8456  {
8457  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8458  "castsource, casttarget, castfunc, castcontext, "
8459  "castmethod "
8460  "FROM pg_cast ORDER BY 3,4");
8461  }
8462 
8463  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8464 
8465  ntups = PQntuples(res);
8466 
8467  castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
8468 
8469  i_tableoid = PQfnumber(res, "tableoid");
8470  i_oid = PQfnumber(res, "oid");
8471  i_castsource = PQfnumber(res, "castsource");
8472  i_casttarget = PQfnumber(res, "casttarget");
8473  i_castfunc = PQfnumber(res, "castfunc");
8474  i_castcontext = PQfnumber(res, "castcontext");
8475  i_castmethod = PQfnumber(res, "castmethod");
8476 
8477  for (i = 0; i < ntups; i++)
8478  {
8479  PQExpBufferData namebuf;
8480  TypeInfo *sTypeInfo;
8481  TypeInfo *tTypeInfo;
8482 
8483  castinfo[i].dobj.objType = DO_CAST;
8484  castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8485  castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8486  AssignDumpId(&castinfo[i].dobj);
8487  castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
8488  castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
8489  castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
8490  castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
8491  castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
8492 
8493  /*
8494  * Try to name cast as concatenation of typnames. This is only used
8495  * for purposes of sorting. If we fail to find either type, the name
8496  * will be an empty string.
8497  */
8498  initPQExpBuffer(&namebuf);
8499  sTypeInfo = findTypeByOid(castinfo[i].castsource);
8500  tTypeInfo = findTypeByOid(castinfo[i].casttarget);
8501  if (sTypeInfo && tTypeInfo)
8502  appendPQExpBuffer(&namebuf, "%s %s",
8503  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
8504  castinfo[i].dobj.name = namebuf.data;
8505 
8506  /* Decide whether we want to dump it */
8507  selectDumpableCast(&(castinfo[i]), fout);
8508  }
8509 
8510  PQclear(res);
8511 
8512  destroyPQExpBuffer(query);
8513 }
TypeInfo * findTypeByOid(Oid oid)
Definition: common.c:864
static void selectDumpableCast(CastInfo *cast, Archive *fout)
Definition: pg_dump.c:1966
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
char castmethod
Definition: pg_dump.h:499
Oid casttarget
Definition: pg_dump.h:496
char castcontext
Definition: pg_dump.h:498
DumpableObject dobj
Definition: pg_dump.h:494
Oid castsource
Definition: pg_dump.h:495
Oid castfunc
Definition: pg_dump.h:497
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 6036 of file pg_dump.c.

6037 {
6038  PGresult *res;
6039  int ntups;
6040  int i;
6041  PQExpBuffer query;
6042  CollInfo *collinfo;
6043  int i_tableoid;
6044  int i_oid;
6045  int i_collname;
6046  int i_collnamespace;
6047  int i_collowner;
6048 
6049  query = createPQExpBuffer();
6050 
6051  /*
6052  * find all collations, including builtin collations; we filter out
6053  * system-defined collations at dump-out time.
6054  */
6055 
6056  appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
6057  "collnamespace, "
6058  "collowner "
6059  "FROM pg_collation");
6060 
6061  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
6062 
6063  ntups = PQntuples(res);
6064 
6065  collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
6066 
6067  i_tableoid = PQfnumber(res, "tableoid");
6068  i_oid = PQfnumber(res, "oid");
6069  i_collname = PQfnumber(res, "collname");
6070  i_collnamespace = PQfnumber(res, "collnamespace");
6071  i_collowner = PQfnumber(res, "collowner");
6072 
6073  for (i = 0; i < ntups; i++)
6074  {
6075  collinfo[i].dobj.objType = DO_COLLATION;
6076  collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6077  collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6078  AssignDumpId(&collinfo[i].dobj);
6079  collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
6080  collinfo[i].dobj.namespace =
6081  findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
6082  collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6083 
6084  /* Decide whether we want to dump it */
6085  selectDumpableObject(&(collinfo[i].dobj), fout);
6086  }
6087 
6088  PQclear(res);
6089 
6090  destroyPQExpBuffer(query);
6091 }
const char * rolname
Definition: pg_dump.h:271
DumpableObject dobj
Definition: pg_dump.h:270

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

Referenced by getSchemaData().

◆ getConstraints()

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

Definition at line 7694 of file pg_dump.c.

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

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

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

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

Referenced by getSchemaData().

◆ getDefaultACLs()

void getDefaultACLs ( Archive fout)

Definition at line 9623 of file pg_dump.c.

9624 {
9625  DumpOptions *dopt = fout->dopt;
9626  DefaultACLInfo *daclinfo;
9627  PQExpBuffer query;
9628  PGresult *res;
9629  int i_oid;
9630  int i_tableoid;
9631  int i_defaclrole;
9632  int i_defaclnamespace;
9633  int i_defaclobjtype;
9634  int i_defaclacl;
9635  int i_acldefault;
9636  int i,
9637  ntups;
9638 
9639  query = createPQExpBuffer();
9640 
9641  /*
9642  * Global entries (with defaclnamespace=0) replace the hard-wired default
9643  * ACL for their object type. We should dump them as deltas from the
9644  * default ACL, since that will be used as a starting point for
9645  * interpreting the ALTER DEFAULT PRIVILEGES commands. On the other hand,
9646  * non-global entries can only add privileges not revoke them. We must
9647  * dump those as-is (i.e., as deltas from an empty ACL).
9648  *
9649  * We can use defaclobjtype as the object type for acldefault(), except
9650  * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
9651  * 's'.
9652  */
9653  appendPQExpBufferStr(query,
9654  "SELECT oid, tableoid, "
9655  "defaclrole, "
9656  "defaclnamespace, "
9657  "defaclobjtype, "
9658  "defaclacl, "
9659  "CASE WHEN defaclnamespace = 0 THEN "
9660  "acldefault(CASE WHEN defaclobjtype = 'S' "
9661  "THEN 's'::\"char\" ELSE defaclobjtype END, "
9662  "defaclrole) ELSE '{}' END AS acldefault "
9663  "FROM pg_default_acl");
9664 
9665  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9666 
9667  ntups = PQntuples(res);
9668 
9669  daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
9670 
9671  i_oid = PQfnumber(res, "oid");
9672  i_tableoid = PQfnumber(res, "tableoid");
9673  i_defaclrole = PQfnumber(res, "defaclrole");
9674  i_defaclnamespace = PQfnumber(res, "defaclnamespace");
9675  i_defaclobjtype = PQfnumber(res, "defaclobjtype");
9676  i_defaclacl = PQfnumber(res, "defaclacl");
9677  i_acldefault = PQfnumber(res, "acldefault");
9678 
9679  for (i = 0; i < ntups; i++)
9680  {
9681  Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
9682 
9683  daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
9684  daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9685  daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9686  AssignDumpId(&daclinfo[i].dobj);
9687  /* cheesy ... is it worth coming up with a better object name? */
9688  daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
9689 
9690  if (nspid != InvalidOid)
9691  daclinfo[i].dobj.namespace = findNamespace(nspid);
9692  else
9693  daclinfo[i].dobj.namespace = NULL;
9694 
9695  daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9696  daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9697  daclinfo[i].dacl.privtype = 0;
9698  daclinfo[i].dacl.initprivs = NULL;
9699  daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
9700  daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
9701 
9702  /* Default ACLs are ACLs, of course */
9703  daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9704 
9705  /* Decide whether we want to dump it */
9706  selectDumpableDefaultACL(&(daclinfo[i]), dopt);
9707  }
9708 
9709  PQclear(res);
9710 
9711  destroyPQExpBuffer(query);
9712 }
int nspid
static void selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
Definition: pg_dump.c:1944
DumpableObject dobj
Definition: pg_dump.h:573
DumpableAcl dacl
Definition: pg_dump.h:574
const char * defaclrole
Definition: pg_dump.h:575
char defaclobjtype
Definition: pg_dump.h:576
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 8265 of file pg_dump.c.

8266 {
8267  int i;
8268  PQExpBuffer query;
8269  PGresult *res;
8270  EventTriggerInfo *evtinfo;
8271  int i_tableoid,
8272  i_oid,
8273  i_evtname,
8274  i_evtevent,
8275  i_evtowner,
8276  i_evttags,
8277  i_evtfname,
8278  i_evtenabled;
8279  int ntups;
8280 
8281  /* Before 9.3, there are no event triggers */
8282  if (fout->remoteVersion < 90300)
8283  return;
8284 
8285  query = createPQExpBuffer();
8286 
8287  appendPQExpBufferStr(query,
8288  "SELECT e.tableoid, e.oid, evtname, evtenabled, "
8289  "evtevent, evtowner, "
8290  "array_to_string(array("
8291  "select quote_literal(x) "
8292  " from unnest(evttags) as t(x)), ', ') as evttags, "
8293  "e.evtfoid::regproc as evtfname "
8294  "FROM pg_event_trigger e "
8295  "ORDER BY e.oid");
8296 
8297  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8298 
8299  ntups = PQntuples(res);
8300 
8301  evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
8302 
8303  i_tableoid = PQfnumber(res, "tableoid");
8304  i_oid = PQfnumber(res, "oid");
8305  i_evtname = PQfnumber(res, "evtname");
8306  i_evtevent = PQfnumber(res, "evtevent");
8307  i_evtowner = PQfnumber(res, "evtowner");
8308  i_evttags = PQfnumber(res, "evttags");
8309  i_evtfname = PQfnumber(res, "evtfname");
8310  i_evtenabled = PQfnumber(res, "evtenabled");
8311 
8312  for (i = 0; i < ntups; i++)
8313  {
8314  evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
8315  evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8316  evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8317  AssignDumpId(&evtinfo[i].dobj);
8318  evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
8319  evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
8320  evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
8321  evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
8322  evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
8323  evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
8324  evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
8325 
8326  /* Decide whether we want to dump it */
8327  selectDumpableObject(&(evtinfo[i].dobj), fout);
8328  }
8329 
8330  PQclear(res);
8331 
8332  destroyPQExpBuffer(query);
8333 }
char * evtevent
Definition: pg_dump.h:451
char * evtfname
Definition: pg_dump.h:454
char evtenabled
Definition: pg_dump.h:455
char * evtname
Definition: pg_dump.h:450
const char * evtowner
Definition: pg_dump.h:452
char * evttags
Definition: pg_dump.h:453
DumpableObject dobj
Definition: pg_dump.h:449

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

7616 {
7617  PQExpBuffer query;
7618  PGresult *res;
7619  StatsExtInfo *statsextinfo;
7620  int ntups;
7621  int i_tableoid;
7622  int i_oid;
7623  int i_stxname;
7624  int i_stxnamespace;
7625  int i_stxowner;
7626  int i_stxrelid;
7627  int i_stattarget;
7628  int i;
7629 
7630  /* Extended statistics were new in v10 */
7631  if (fout->remoteVersion < 100000)
7632  return;
7633 
7634  query = createPQExpBuffer();
7635 
7636  if (fout->remoteVersion < 130000)
7637  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7638  "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
7639  "FROM pg_catalog.pg_statistic_ext");
7640  else
7641  appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7642  "stxnamespace, stxowner, stxrelid, stxstattarget "
7643  "FROM pg_catalog.pg_statistic_ext");
7644 
7645  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7646 
7647  ntups = PQntuples(res);
7648 
7649  i_tableoid = PQfnumber(res, "tableoid");
7650  i_oid = PQfnumber(res, "oid");
7651  i_stxname = PQfnumber(res, "stxname");
7652  i_stxnamespace = PQfnumber(res, "stxnamespace");
7653  i_stxowner = PQfnumber(res, "stxowner");
7654  i_stxrelid = PQfnumber(res, "stxrelid");
7655  i_stattarget = PQfnumber(res, "stxstattarget");
7656 
7657  statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
7658 
7659  for (i = 0; i < ntups; i++)
7660  {
7661  statsextinfo[i].dobj.objType = DO_STATSEXT;
7662  statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
7663  statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
7664  AssignDumpId(&statsextinfo[i].dobj);
7665  statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
7666  statsextinfo[i].dobj.namespace =
7667  findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
7668  statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
7669  statsextinfo[i].stattable =
7670  findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7671  if (PQgetisnull(res, i, i_stattarget))
7672  statsextinfo[i].stattarget = -1;
7673  else
7674  statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7675 
7676  /* Decide whether we want to dump it */
7677  selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
7678  }
7679 
7680  PQclear(res);
7681  destroyPQExpBuffer(query);
7682 }
static void selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
Definition: pg_dump.c:2109
TableInfo * stattable
Definition: pg_dump.h:423
int stattarget
Definition: pg_dump.h:424
const char * rolname
Definition: pg_dump.h:422
DumpableObject dobj
Definition: pg_dump.h:421

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

17893 {
17894  PQExpBuffer query;
17895  PGresult *res;
17896  int ntups,
17897  i;
17898  int i_classid,
17899  i_objid,
17900  i_refobjid;
17901  ExtensionInfo *ext;
17902 
17903  /* Nothing to do if no extensions */
17904  if (numExtensions == 0)
17905  return;
17906 
17907  query = createPQExpBuffer();
17908 
17909  /* refclassid constraint is redundant but may speed the search */
17910  appendPQExpBufferStr(query, "SELECT "
17911  "classid, objid, refobjid "
17912  "FROM pg_depend "
17913  "WHERE refclassid = 'pg_extension'::regclass "
17914  "AND deptype = 'e' "
17915  "ORDER BY 3");
17916 
17917  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
17918 
17919  ntups = PQntuples(res);
17920 
17921  i_classid = PQfnumber(res, "classid");
17922  i_objid = PQfnumber(res, "objid");
17923  i_refobjid = PQfnumber(res, "refobjid");
17924 
17925  /*
17926  * Since we ordered the SELECT by referenced ID, we can expect that
17927  * multiple entries for the same extension will appear together; this
17928  * saves on searches.
17929  */
17930  ext = NULL;
17931 
17932  for (i = 0; i < ntups; i++)
17933  {
17934  CatalogId objId;
17935  Oid extId;
17936 
17937  objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
17938  objId.oid = atooid(PQgetvalue(res, i, i_objid));
17939  extId = atooid(PQgetvalue(res, i, i_refobjid));
17940 
17941  if (ext == NULL ||
17942  ext->dobj.catId.oid != extId)
17943  ext = findExtensionByOid(extId);
17944 
17945  if (ext == NULL)
17946  {
17947  /* shouldn't happen */
17948  pg_log_warning("could not find referenced extension %u", extId);
17949  continue;
17950  }
17951 
17952  recordExtensionMembership(objId, ext);
17953  }
17954 
17955  PQclear(res);
17956 
17957  destroyPQExpBuffer(query);
17958 }
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 5733 of file pg_dump.c.

5734 {
5735  DumpOptions *dopt = fout->dopt;
5736  PGresult *res;
5737  int ntups;
5738  int i;
5739  PQExpBuffer query;
5740  ExtensionInfo *extinfo;
5741  int i_tableoid;
5742  int i_oid;
5743  int i_extname;
5744  int i_nspname;
5745  int i_extrelocatable;
5746  int i_extversion;
5747  int i_extconfig;
5748  int i_extcondition;
5749 
5750  query = createPQExpBuffer();
5751 
5752  appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
5753  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
5754  "FROM pg_extension x "
5755  "JOIN pg_namespace n ON n.oid = x.extnamespace");
5756 
5757  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5758 
5759  ntups = PQntuples(res);
5760 
5761  extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
5762 
5763  i_tableoid = PQfnumber(res, "tableoid");
5764  i_oid = PQfnumber(res, "oid");
5765  i_extname = PQfnumber(res, "extname");
5766  i_nspname = PQfnumber(res, "nspname");
5767  i_extrelocatable = PQfnumber(res, "extrelocatable");
5768  i_extversion = PQfnumber(res, "extversion");
5769  i_extconfig = PQfnumber(res, "extconfig");
5770  i_extcondition = PQfnumber(res, "extcondition");
5771 
5772  for (i = 0; i < ntups; i++)
5773  {
5774  extinfo[i].dobj.objType = DO_EXTENSION;
5775  extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5776  extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5777  AssignDumpId(&extinfo[i].dobj);
5778  extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
5779  extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
5780  extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
5781  extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
5782  extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
5783  extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
5784 
5785  /* Decide whether we want to dump it */
5786  selectDumpableExtension(&(extinfo[i]), dopt);
5787  }
5788 
5789  PQclear(res);
5790  destroyPQExpBuffer(query);
5791 
5792  *numExtensions = ntups;
5793 
5794  return extinfo;
5795 }
static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
Definition: pg_dump.c:2052
bool relocatable
Definition: pg_dump.h:182
char * extversion
Definition: pg_dump.h:184
char * extcondition
Definition: pg_dump.h:186
char * extconfig
Definition: pg_dump.h:185

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_EXTENSION, _extensionInfo::dobj, Archive::dopt, ExecuteSqlQuery(), _extensionInfo::extcondition, _extensionInfo::extconfig, _extensionInfo::extversion, i, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _extensionInfo::relocatable, res, selectDumpableExtension(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getForeignDataWrappers()

void getForeignDataWrappers ( Archive fout)

Definition at line 9451 of file pg_dump.c.

9452 {
9453  PGresult *res;
9454  int ntups;
9455  int i;
9456  PQExpBuffer query;
9457  FdwInfo *fdwinfo;
9458  int i_tableoid;
9459  int i_oid;
9460  int i_fdwname;
9461  int i_fdwowner;
9462  int i_fdwhandler;
9463  int i_fdwvalidator;
9464  int i_fdwacl;
9465  int i_acldefault;
9466  int i_fdwoptions;
9467 
9468  query = createPQExpBuffer();
9469 
9470  appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
9471  "fdwowner, "
9472  "fdwhandler::pg_catalog.regproc, "
9473  "fdwvalidator::pg_catalog.regproc, "
9474  "fdwacl, "
9475  "acldefault('F', fdwowner) AS acldefault, "
9476  "array_to_string(ARRAY("
9477  "SELECT quote_ident(option_name) || ' ' || "
9478  "quote_literal(option_value) "
9479  "FROM pg_options_to_table(fdwoptions) "
9480  "ORDER BY option_name"
9481  "), E',\n ') AS fdwoptions "
9482  "FROM pg_foreign_data_wrapper");
9483 
9484  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9485 
9486  ntups = PQntuples(res);
9487 
9488  fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
9489 
9490  i_tableoid = PQfnumber(res, "tableoid");
9491  i_oid = PQfnumber(res, "oid");
9492  i_fdwname = PQfnumber(res, "fdwname");
9493  i_fdwowner = PQfnumber(res, "fdwowner");
9494  i_fdwhandler = PQfnumber(res, "fdwhandler");
9495  i_fdwvalidator = PQfnumber(res, "fdwvalidator");
9496  i_fdwacl = PQfnumber(res, "fdwacl");
9497  i_acldefault = PQfnumber(res, "acldefault");
9498  i_fdwoptions = PQfnumber(res, "fdwoptions");
9499 
9500  for (i = 0; i < ntups; i++)
9501  {
9502  fdwinfo[i].dobj.objType = DO_FDW;
9503  fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9504  fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9505  AssignDumpId(&fdwinfo[i].dobj);
9506  fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
9507  fdwinfo[i].dobj.namespace = NULL;
9508  fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
9509  fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9510  fdwinfo[i].dacl.privtype = 0;
9511  fdwinfo[i].dacl.initprivs = NULL;
9512  fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
9513  fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
9514  fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
9515  fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
9516 
9517  /* Decide whether we want to dump it */
9518  selectDumpableObject(&(fdwinfo[i].dobj), fout);
9519 
9520  /* Mark whether FDW has an ACL */
9521  if (!PQgetisnull(res, i, i_fdwacl))
9522  fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9523  }
9524 
9525  PQclear(res);
9526 
9527  destroyPQExpBuffer(query);
9528 }
char * fdwhandler
Definition: pg_dump.h:555
const char * rolname
Definition: pg_dump.h:554
char * fdwvalidator
Definition: pg_dump.h:556
char * fdwoptions
Definition: pg_dump.h:557
DumpableAcl dacl
Definition: pg_dump.h:553
DumpableObject dobj
Definition: pg_dump.h:552

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

9536 {
9537  PGresult *res;
9538  int ntups;
9539  int i;
9540  PQExpBuffer query;
9541  ForeignServerInfo *srvinfo;
9542  int i_tableoid;
9543  int i_oid;
9544  int i_srvname;
9545  int i_srvowner;
9546  int i_srvfdw;
9547  int i_srvtype;
9548  int i_srvversion;
9549  int i_srvacl;
9550  int i_acldefault;
9551  int i_srvoptions;
9552 
9553  query = createPQExpBuffer();
9554 
9555  appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
9556  "srvowner, "
9557  "srvfdw, srvtype, srvversion, srvacl, "
9558  "acldefault('S', srvowner) AS acldefault, "
9559  "array_to_string(ARRAY("
9560  "SELECT quote_ident(option_name) || ' ' || "
9561  "quote_literal(option_value) "
9562  "FROM pg_options_to_table(srvoptions) "
9563  "ORDER BY option_name"
9564  "), E',\n ') AS srvoptions "
9565  "FROM pg_foreign_server");
9566 
9567  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9568 
9569  ntups = PQntuples(res);
9570 
9571  srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
9572 
9573  i_tableoid = PQfnumber(res, "tableoid");
9574  i_oid = PQfnumber(res, "oid");
9575  i_srvname = PQfnumber(res, "srvname");
9576  i_srvowner = PQfnumber(res, "srvowner");
9577  i_srvfdw = PQfnumber(res, "srvfdw");
9578  i_srvtype = PQfnumber(res, "srvtype");
9579  i_srvversion = PQfnumber(res, "srvversion");
9580  i_srvacl = PQfnumber(res, "srvacl");
9581  i_acldefault = PQfnumber(res, "acldefault");
9582  i_srvoptions = PQfnumber(res, "srvoptions");
9583 
9584  for (i = 0; i < ntups; i++)
9585  {
9586  srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
9587  srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9588  srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9589  AssignDumpId(&srvinfo[i].dobj);
9590  srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
9591  srvinfo[i].dobj.namespace = NULL;
9592  srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
9593  srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
9594  srvinfo[i].dacl.privtype = 0;
9595  srvinfo[i].dacl.initprivs = NULL;
9596  srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
9597  srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
9598  srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
9599  srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
9600  srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
9601 
9602  /* Decide whether we want to dump it */
9603  selectDumpableObject(&(srvinfo[i].dobj), fout);
9604 
9605  /* Servers have user mappings */
9607 
9608  /* Mark whether server has an ACL */
9609  if (!PQgetisnull(res, i, i_srvacl))
9610  srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
9611  }
9612 
9613  PQclear(res);
9614 
9615  destroyPQExpBuffer(query);
9616 }
#define DUMP_COMPONENT_USERMAP
Definition: pg_dump.h:103
DumpableAcl dacl
Definition: pg_dump.h:563
char * srvoptions
Definition: pg_dump.h:568
DumpableObject dobj
Definition: pg_dump.h:562
const char * rolname
Definition: pg_dump.h:564
char * srvversion
Definition: pg_dump.h:567

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

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), _funcInfo::argtypes, AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _funcInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_FUNC, _funcInfo::dobj, Archive::dopt, DUMP_COMPONENT_ACL, ExecuteSqlQuery(), findNamespace(), g_last_builtin_oid, getRoleName(), i, _dumpableAcl::initprivs, _funcInfo::lang, _dumpableObject::name, _funcInfo::nargs, _dumpableObject::objType, CatalogId::oid, parseOidArray(), pg_malloc(), pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, _funcInfo::postponed_def, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, _funcInfo::prorettype, Archive::remoteVersion, res, _funcInfo::rolname, selectDumpableObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getIndexes()

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

Definition at line 7305 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::confrelid, _constraintInfo::conindex, _constraintInfo::conislocal, _constraintInfo::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 7189 of file pg_dump.c.

7190 {
7191  PGresult *res;
7192  int ntups;
7193  int i;
7194  PQExpBuffer query = createPQExpBuffer();
7195  InhInfo *inhinfo;
7196 
7197  int i_inhrelid;
7198  int i_inhparent;
7199 
7200  /* find all the inheritance information */
7201  appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
7202 
7203  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7204 
7205  ntups = PQntuples(res);
7206 
7207  *numInherits = ntups;
7208 
7209  inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
7210 
7211  i_inhrelid = PQfnumber(res, "inhrelid");
7212  i_inhparent = PQfnumber(res, "inhparent");
7213 
7214  for (i = 0; i < ntups; i++)
7215  {
7216  inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
7217  inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
7218  }
7219 
7220  PQclear(res);
7221 
7222  destroyPQExpBuffer(query);
7223 
7224  return inhinfo;
7225 }
Oid inhparent
Definition: pg_dump.h:515
Oid inhrelid
Definition: pg_dump.h:514

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

5602 {
5603  PGresult *res;
5604  int ntups;
5605  int i;
5606  PQExpBuffer query;
5607  NamespaceInfo *nsinfo;
5608  int i_tableoid;
5609  int i_oid;
5610  int i_nspname;
5611  int i_nspowner;
5612  int i_nspacl;
5613  int i_acldefault;
5614 
5615  query = createPQExpBuffer();
5616 
5617  /*
5618  * we fetch all namespaces including system ones, so that every object we
5619  * read in can be linked to a containing namespace.
5620  */
5621  appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
5622  "n.nspowner, "
5623  "n.nspacl, "
5624  "acldefault('n', n.nspowner) AS acldefault "
5625  "FROM pg_namespace n");
5626 
5627  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5628 
5629  ntups = PQntuples(res);
5630 
5631  nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
5632 
5633  i_tableoid = PQfnumber(res, "tableoid");
5634  i_oid = PQfnumber(res, "oid");
5635  i_nspname = PQfnumber(res, "nspname");
5636  i_nspowner = PQfnumber(res, "nspowner");
5637  i_nspacl = PQfnumber(res, "nspacl");
5638  i_acldefault = PQfnumber(res, "acldefault");
5639 
5640  for (i = 0; i < ntups; i++)
5641  {
5642  const char *nspowner;
5643 
5644  nsinfo[i].dobj.objType = DO_NAMESPACE;
5645  nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
5646  nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
5647  AssignDumpId(&nsinfo[i].dobj);
5648  nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
5649  nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
5650  nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
5651  nsinfo[i].dacl.privtype = 0;
5652  nsinfo[i].dacl.initprivs = NULL;
5653  nspowner = PQgetvalue(res, i, i_nspowner);
5654  nsinfo[i].nspowner = atooid(nspowner);
5655  nsinfo[i].rolname = getRoleName(nspowner);
5656 
5657  /* Decide whether to dump this namespace */
5658  selectDumpableNamespace(&nsinfo[i], fout);
5659 
5660  /* Mark whether namespace has an ACL */
5661  if (!PQgetisnull(res, i, i_nspacl))
5662  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5663 
5664  /*
5665  * We ignore any pg_init_privs.initprivs entry for the public schema
5666  * and assume a predetermined default, for several reasons. First,
5667  * dropping and recreating the schema removes its pg_init_privs entry,
5668  * but an empty destination database starts with this ACL nonetheless.
5669  * Second, we support dump/reload of public schema ownership changes.
5670  * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
5671  * initprivs continues to reflect the initial owner. Hence,
5672  * synthesize the value that nspacl will have after the restore's
5673  * ALTER SCHEMA OWNER. Third, this makes the destination database
5674  * match the source's ACL, even if the latter was an initdb-default
5675  * ACL, which changed in v15. An upgrade pulls in changes to most
5676  * system object ACLs that the DBA had not customized. We've made the
5677  * public schema depart from that, because changing its ACL so easily
5678  * breaks applications.
5679  */
5680  if (strcmp(nsinfo[i].dobj.name, "public") == 0)
5681  {
5682  PQExpBuffer aclarray = createPQExpBuffer();
5683  PQExpBuffer aclitem = createPQExpBuffer();
5684 
5685  /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
5686  appendPQExpBufferChar(aclarray, '{');
5687  quoteAclUserName(aclitem, nsinfo[i].rolname);
5688  appendPQExpBufferStr(aclitem, "=UC/");
5689  quoteAclUserName(aclitem, nsinfo[i].rolname);
5690  appendPGArray(aclarray, aclitem->data);
5691  resetPQExpBuffer(aclitem);
5692  appendPQExpBufferStr(aclitem, "=U/");
5693  quoteAclUserName(aclitem, nsinfo[i].rolname);
5694  appendPGArray(aclarray, aclitem->data);
5695  appendPQExpBufferChar(aclarray, '}');
5696 
5697  nsinfo[i].dacl.privtype = 'i';
5698  nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
5699  nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
5700 
5701  destroyPQExpBuffer(aclarray);
5702  destroyPQExpBuffer(aclitem);
5703  }
5704  }
5705 
5706  PQclear(res);
5707  destroyPQExpBuffer(query);
5708 }
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:1774
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 6222 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getOperators()

void getOperators ( Archive fout)

Definition at line 5968 of file pg_dump.c.

5969 {
5970  PGresult *res;
5971  int ntups;
5972  int i;
5973  PQExpBuffer query = createPQExpBuffer();
5974  OprInfo *oprinfo;
5975  int i_tableoid;
5976  int i_oid;
5977  int i_oprname;
5978  int i_oprnamespace;
5979  int i_oprowner;
5980  int i_oprkind;
5981  int i_oprcode;
5982 
5983  /*
5984  * find all operators, including builtin operators; we filter out
5985  * system-defined operators at dump-out time.
5986  */
5987 
5988  appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
5989  "oprnamespace, "
5990  "oprowner, "
5991  "oprkind, "
5992  "oprcode::oid AS oprcode "
5993  "FROM pg_operator");
5994 
5995  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
5996 
5997  ntups = PQntuples(res);
5998 
5999  oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
6000 
6001  i_tableoid = PQfnumber(res, "tableoid");
6002  i_oid = PQfnumber(res, "oid");
6003  i_oprname = PQfnumber(res, "oprname");
6004  i_oprnamespace = PQfnumber(res, "oprnamespace");
6005  i_oprowner = PQfnumber(res, "oprowner");
6006  i_oprkind = PQfnumber(res, "oprkind");
6007  i_oprcode = PQfnumber(res, "oprcode");
6008 
6009  for (i = 0; i < ntups; i++)
6010  {
6011  oprinfo[i].dobj.objType = DO_OPERATOR;
6012  oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
6013  oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
6014  AssignDumpId(&oprinfo[i].dobj);
6015  oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
6016  oprinfo[i].dobj.namespace =
6017  findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
6018  oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
6019  oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6020  oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
6021 
6022  /* Decide whether we want to dump it */
6023  selectDumpableObject(&(oprinfo[i].dobj), fout);
6024  }
6025 
6026  PQclear(res);
6027 
6028  destroyPQExpBuffer(query);
6029 }
DumpableObject dobj
Definition: pg_dump.h:243
char oprkind
Definition: pg_dump.h:245
Oid oprcode
Definition: pg_dump.h:246
const char * rolname
Definition: pg_dump.h:244

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

Referenced by getSchemaData().

◆ getOpfamilies()

void getOpfamilies ( Archive fout)

Definition at line 6282 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getOwnedSeqs()

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

Definition at line 7126 of file pg_dump.c.

7127 {
7128  int i;
7129 
7130  /*
7131  * Force sequences that are "owned" by table columns to be dumped whenever
7132  * their owning table is being dumped.
7133  */
7134  for (i = 0; i < numTables; i++)
7135  {
7136  TableInfo *seqinfo = &tblinfo[i];
7137  TableInfo *owning_tab;
7138 
7139  if (!OidIsValid(seqinfo->owning_tab))
7140  continue; /* not an owned sequence */
7141 
7142  owning_tab = findTableByOid(seqinfo->owning_tab);
7143  if (owning_tab == NULL)
7144  pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
7145  seqinfo->owning_tab, seqinfo->dobj.catId.oid);
7146 
7147  /*
7148  * Only dump identity sequences if we're going to dump the table that
7149  * it belongs to.
7150  */
7151  if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
7152  seqinfo->is_identity_sequence)
7153  {
7154  seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
7155  continue;
7156  }
7157 
7158  /*
7159  * Otherwise we need to dump the components that are being dumped for
7160  * the table and any components which the sequence is explicitly
7161  * marked with.
7162  *
7163  * We can't simply use the set of components which are being dumped
7164  * for the table as the table might be in an extension (and only the
7165  * non-extension components, eg: ACLs if changed, security labels, and
7166  * policies, are being dumped) while the sequence is not (and
7167  * therefore the definition and other components should also be
7168  * dumped).
7169  *
7170  * If the sequence is part of the extension then it should be properly
7171  * marked by checkExtensionMembership() and this will be a no-op as
7172  * the table will be equivalently marked.
7173  */
7174  seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
7175 
7176  if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7177  seqinfo->interesting = true;
7178  }
7179 }
#define DUMP_COMPONENT_NONE
Definition: pg_dump.h:96
bool is_identity_sequence
Definition: pg_dump.h:315
Oid owning_tab
Definition: pg_dump.h:313

References _dumpableObject::catId, _tableInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_NONE, findTableByOid(), i, _tableInfo::interesting, _tableInfo::is_identity_sequence, CatalogId::oid, OidIsValid, _tableInfo::owning_tab, and pg_fatal.

Referenced by getSchemaData().

◆ getPartitioningInfo()

void getPartitioningInfo ( Archive fout)

Definition at line 7245 of file pg_dump.c.

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

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

Referenced by getSchemaData().

◆ getPolicies()

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

Definition at line 3919 of file pg_dump.c.

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

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_POLICY, _tableInfo::dobj, _policyInfo::dobj, _dumpableObject::dump, DUMP_COMPONENT_POLICY, ExecuteSqlQuery(), findTableByOid(), i, j, PQExpBufferData::len, _dumpableObject::name, _dumpableObject::objType, CatalogId::oid, pg_log_info, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, _policyInfo::polcmd, _policyInfo::polname, _policyInfo::polpermissive, _policyInfo::polqual, _policyInfo::polroles, _policyInfo::poltable, _policyInfo::polwithcheck, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _tableInfo::relkind, Archive::remoteVersion, res, _tableInfo::rowsec, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getProcLangs()

void getProcLangs ( Archive fout)

Definition at line 8343 of file pg_dump.c.

8344 {
8345  PGresult *res;
8346  int ntups;
8347  int i;
8348  PQExpBuffer query = createPQExpBuffer();
8349  ProcLangInfo *planginfo;
8350  int i_tableoid;
8351  int i_oid;
8352  int i_lanname;
8353  int i_lanpltrusted;
8354  int i_lanplcallfoid;
8355  int i_laninline;
8356  int i_lanvalidator;
8357  int i_lanacl;
8358  int i_acldefault;
8359  int i_lanowner;
8360 
8361  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8362  "lanname, lanpltrusted, lanplcallfoid, "
8363  "laninline, lanvalidator, "
8364  "lanacl, "
8365  "acldefault('l', lanowner) AS acldefault, "
8366  "lanowner "
8367  "FROM pg_language "
8368  "WHERE lanispl "
8369  "ORDER BY oid");
8370 
8371  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8372 
8373  ntups = PQntuples(res);
8374 
8375  planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
8376 
8377  i_tableoid = PQfnumber(res, "tableoid");
8378  i_oid = PQfnumber(res, "oid");
8379  i_lanname = PQfnumber(res, "lanname");
8380  i_lanpltrusted = PQfnumber(res, "lanpltrusted");
8381  i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
8382  i_laninline = PQfnumber(res, "laninline");
8383  i_lanvalidator = PQfnumber(res, "lanvalidator");
8384  i_lanacl = PQfnumber(res, "lanacl");
8385  i_acldefault = PQfnumber(res, "acldefault");
8386  i_lanowner = PQfnumber(res, "lanowner");
8387 
8388  for (i = 0; i < ntups; i++)
8389  {
8390  planginfo[i].dobj.objType = DO_PROCLANG;
8391  planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8392  planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8393  AssignDumpId(&planginfo[i].dobj);
8394 
8395  planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
8396  planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
8397  planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
8398  planginfo[i].dacl.privtype = 0;
8399  planginfo[i].dacl.initprivs = NULL;
8400  planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
8401  planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
8402  planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
8403  planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
8404  planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
8405 
8406  /* Decide whether we want to dump it */
8407  selectDumpableProcLang(&(planginfo[i]), fout);
8408 
8409  /* Mark whether language has an ACL */
8410  if (!PQgetisnull(res, i, i_lanacl))
8411  planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
8412  }
8413 
8414  PQclear(res);
8415 
8416  destroyPQExpBuffer(query);
8417 }
static void selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
Definition: pg_dump.c:1991
Oid lanvalidator
Definition: pg_dump.h:488
DumpableAcl dacl
Definition: pg_dump.h:484
DumpableObject dobj
Definition: pg_dump.h:483
Oid laninline
Definition: pg_dump.h:487
const char * lanowner
Definition: pg_dump.h:489
Oid lanplcallfoid
Definition: pg_dump.h:486
bool lanpltrusted
Definition: pg_dump.h:485

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

4399 {
4400  PQExpBuffer query;
4401  PGresult *res;
4402  PublicationSchemaInfo *pubsinfo;
4403  DumpOptions *dopt = fout->dopt;
4404  int i_tableoid;
4405  int i_oid;
4406  int i_pnpubid;
4407  int i_pnnspid;
4408  int i,
4409  j,
4410  ntups;
4411 
4412  if (dopt->no_publications || fout->remoteVersion < 150000)
4413  return;
4414 
4415  query = createPQExpBuffer();
4416 
4417  /* Collect all publication membership info. */
4418  appendPQExpBufferStr(query,
4419  "SELECT tableoid, oid, pnpubid, pnnspid "
4420  "FROM pg_catalog.pg_publication_namespace");
4421  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4422 
4423  ntups = PQntuples(res);
4424 
4425  i_tableoid = PQfnumber(res, "tableoid");
4426  i_oid = PQfnumber(res, "oid");
4427  i_pnpubid = PQfnumber(res, "pnpubid");
4428  i_pnnspid = PQfnumber(res, "pnnspid");
4429 
4430  /* this allocation may be more than we need */
4431  pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
4432  j = 0;
4433 
4434  for (i = 0; i < ntups; i++)
4435  {
4436  Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
4437  Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
4438  PublicationInfo *pubinfo;
4439  NamespaceInfo *nspinfo;
4440 
4441  /*
4442  * Ignore any entries for which we aren't interested in either the
4443  * publication or the rel.
4444  */
4445  pubinfo = findPublicationByOid(pnpubid);
4446  if (pubinfo == NULL)
4447  continue;
4448  nspinfo = findNamespaceByOid(pnnspid);
4449  if (nspinfo == NULL)
4450  continue;
4451 
4452  /*
4453  * We always dump publication namespaces unless the corresponding
4454  * namespace is excluded from the dump.
4455  */
4456  if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
4457  continue;
4458 
4459  /* OK, make a DumpableObject for this relationship */
4461  pubsinfo[j].dobj.catId.tableoid =
4462  atooid(PQgetvalue(res, i, i_tableoid));
4463  pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4464  AssignDumpId(&pubsinfo[j].dobj);
4465  pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
4466  pubsinfo[j].dobj.name = nspinfo->dobj.name;
4467  pubsinfo[j].publication = pubinfo;
4468  pubsinfo[j].pubschema = nspinfo;
4469 
4470  /* Decide whether we want to dump it */
4471  selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
4472 
4473  j++;
4474  }
4475 
4476  PQclear(res);
4477  destroyPQExpBuffer(query);
4478 }
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:2091
NamespaceInfo * pubschema
Definition: pg_dump.h:650
DumpableObject dobj
Definition: pg_dump.h:648
PublicationInfo * publication
Definition: pg_dump.h:649
int no_publications
Definition: pg_backup.h:182

References appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_PUBLICATION_TABLE_IN_SCHEMA, _namespaceInfo::dobj, _PublicationSchemaInfo::dobj, Archive::dopt, _dumpableObject::dump, DUMP_COMPONENT_NONE, ExecuteSqlQuery(), findNamespaceByOid(), findPublicationByOid(), i, j, _dumpableObject::name, _dumpOptions::no_publications, _dumpableObject::objType, CatalogId::oid, pg_malloc(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _PublicationSchemaInfo::publication, _PublicationSchemaInfo::pubschema, Archive::remoteVersion, res, selectDumpablePublicationObject(), and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getPublications()

void getPublications ( Archive fout)

Definition at line 4204 of file pg_dump.c.

4205 {
4206  DumpOptions *dopt = fout->dopt;
4207  PQExpBuffer query;
4208  PGresult *res;
4209  PublicationInfo *pubinfo;
4210  int i_tableoid;
4211  int i_oid;
4212  int i_pubname;
4213  int i_pubowner;
4214  int i_puballtables;
4215  int i_pubinsert;
4216  int i_pubupdate;
4217  int i_pubdelete;
4218  int i_pubtruncate;
4219  int i_pubviaroot;
4220  int i,
4221  ntups;
4222 
4223  if (dopt->no_publications || fout->remoteVersion < 100000)
4224  return;
4225 
4226  query = createPQExpBuffer();
4227 
4228  resetPQExpBuffer(query);
4229 
4230  /* Get the publications. */
4231  if (fout->remoteVersion >= 130000)
4232  appendPQExpBufferStr(query,
4233  "SELECT p.tableoid, p.oid, p.pubname, "
4234  "p.pubowner, "
4235  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
4236  "FROM pg_publication p");
4237  else if (fout->remoteVersion >= 110000)
4238  appendPQExpBufferStr(query,
4239  "SELECT p.tableoid, p.oid, p.pubname, "
4240  "p.pubowner, "
4241  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
4242  "FROM pg_publication p");
4243  else
4244  appendPQExpBufferStr(query,
4245  "SELECT p.tableoid, p.oid, p.pubname, "
4246  "p.pubowner, "
4247  "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot "
4248  "FROM pg_publication p");
4249 
4250  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4251 
4252  ntups = PQntuples(res);
4253 
4254  i_tableoid = PQfnumber(res, "tableoid");
4255  i_oid = PQfnumber(res, "oid");
4256  i_pubname = PQfnumber(res, "pubname");
4257  i_pubowner = PQfnumber(res, "pubowner");
4258  i_puballtables = PQfnumber(res, "puballtables");
4259  i_pubinsert = PQfnumber(res, "pubinsert");
4260  i_pubupdate = PQfnumber(res, "pubupdate");
4261  i_pubdelete = PQfnumber(res, "pubdelete");
4262  i_pubtruncate = PQfnumber(res, "pubtruncate");
4263  i_pubviaroot = PQfnumber(res, "pubviaroot");
4264 
4265  pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
4266 
4267  for (i = 0; i < ntups; i++)
4268  {
4269  pubinfo[i].dobj.objType = DO_PUBLICATION;
4270  pubinfo[i].dobj.catId.tableoid =
4271  atooid(PQgetvalue(res, i, i_tableoid));
4272  pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4273  AssignDumpId(&pubinfo[i].dobj);
4274  pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
4275  pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
4276  pubinfo[i].puballtables =
4277  (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
4278  pubinfo[i].pubinsert =
4279  (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
4280  pubinfo[i].pubupdate =
4281  (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
4282  pubinfo[i].pubdelete =
4283  (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
4284  pubinfo[i].pubtruncate =
4285  (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
4286  pubinfo[i].pubviaroot =
4287  (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
4288 
4289  /* Decide whether we want to dump it */
4290  selectDumpableObject(&(pubinfo[i].dobj), fout);
4291  }
4292  PQclear(res);
4293 
4294  destroyPQExpBuffer(query);
4295 }
const char * rolname
Definition: pg_dump.h:620
bool puballtables
Definition: pg_dump.h:621
bool pubtruncate
Definition: pg_dump.h:625
DumpableObject dobj
Definition: pg_dump.h:619

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

Referenced by getSchemaData().

◆ getPublicationTables()

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

Definition at line 4485 of file pg_dump.c.

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

7973 {
7974  PGresult *res;
7975  int ntups;
7976  int i;
7977  PQExpBuffer query = createPQExpBuffer();
7978  RuleInfo *ruleinfo;
7979  int i_tableoid;
7980  int i_oid;
7981  int i_rulename;
7982  int i_ruletable;
7983  int i_ev_type;
7984  int i_is_instead;
7985  int i_ev_enabled;
7986 
7987  appendPQExpBufferStr(query, "SELECT "
7988  "tableoid, oid, rulename, "
7989  "ev_class AS ruletable, ev_type, is_instead, "
7990  "ev_enabled "
7991  "FROM pg_rewrite "
7992  "ORDER BY oid");
7993 
7994  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
7995 
7996  ntups = PQntuples(res);
7997 
7998  ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
7999 
8000  i_tableoid = PQfnumber(res, "tableoid");
8001  i_oid = PQfnumber(res, "oid");
8002  i_rulename = PQfnumber(res, "rulename");
8003  i_ruletable = PQfnumber(res, "ruletable");
8004  i_ev_type = PQfnumber(res, "ev_type");
8005  i_is_instead = PQfnumber(res, "is_instead");
8006  i_ev_enabled = PQfnumber(res, "ev_enabled");
8007 
8008  for (i = 0; i < ntups; i++)
8009  {
8010  Oid ruletableoid;
8011 
8012  ruleinfo[i].dobj.objType = DO_RULE;
8013  ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8014  ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8015  AssignDumpId(&ruleinfo[i].dobj);
8016  ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
8017  ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
8018  ruleinfo[i].ruletable = findTableByOid(ruletableoid);
8019  if (ruleinfo[i].ruletable == NULL)
8020  pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
8021  ruletableoid, ruleinfo[i].dobj.catId.oid);
8022  ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
8023  ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
8024  ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
8025  ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
8026  ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
8027  if (ruleinfo[i].ruletable)
8028  {
8029  /*
8030  * If the table is a view or materialized view, force its ON
8031  * SELECT rule to be sorted before the view itself --- this
8032  * ensures that any dependencies for the rule affect the table's
8033  * positioning. Other rules are forced to appear after their
8034  * table.
8035  */
8036  if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
8037  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
8038  ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
8039  {
8040  addObjectDependency(&ruleinfo[i].ruletable->dobj,
8041  ruleinfo[i].dobj.dumpId);
8042  /* We'll merge the rule into CREATE VIEW, if possible */
8043  ruleinfo[i].separate = false;
8044  }
8045  else
8046  {
8047  addObjectDependency(&ruleinfo[i].dobj,
8048  ruleinfo[i].ruletable->dobj.dumpId);
8049  ruleinfo[i].separate = true;
8050  }
8051  }
8052  else
8053  ruleinfo[i].separate = true;
8054  }
8055 
8056  PQclear(res);
8057 
8058  destroyPQExpBuffer(query);
8059 }
void addObjectDependency(DumpableObject *dobj, DumpId refId)
Definition: common.c:783
DumpableObject dobj
Definition: pg_dump.h:429
bool separate
Definition: pg_dump.h:434
char ev_enabled
Definition: pg_dump.h:433
bool is_instead
Definition: pg_dump.h:432
TableInfo * ruletable
Definition: pg_dump.h:430
char ev_type
Definition: pg_dump.h:431

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:7694
void getPublicationNamespaces(Archive *fout)
Definition: pg_dump.c:4398
void getPartitioningInfo(Archive *fout)
Definition: pg_dump.c:7245
void getForeignDataWrappers(Archive *fout)
Definition: pg_dump.c:9451
void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:3919
void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:17891
void getTypes(Archive *fout)
Definition: pg_dump.c:5805
void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7126
void getOpclasses(Archive *fout)
Definition: pg_dump.c:6222
void getForeignServers(Archive *fout)
Definition: pg_dump.c:9535
void getFuncs(Archive *fout)
Definition: pg_dump.c:6485
void getTSDictionaries(Archive *fout)
Definition: pg_dump.c:9267
void getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:4485
void getCasts(Archive *fout)
Definition: pg_dump.c:8427
void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:7305
void getTSConfigurations(Archive *fout)
Definition: pg_dump.c:9392
void getAccessMethods(Archive *fout)
Definition: pg_dump.c:6160
void getConversions(Archive *fout)
Definition: pg_dump.c:6098
void getRules(Archive *fout)
Definition: pg_dump.c:7972
InhInfo * getInherits(Archive *fout, int *numInherits)
Definition: pg_dump.c:7189
void getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
Definition: pg_dump.c:8621
void getSubscriptionTables(Archive *fout)
Definition: pg_dump.c:4939
void getCollations(Archive *fout)
Definition: pg_dump.c:6036
void getAggregates(Archive *fout)
Definition: pg_dump.c:6344
void getNamespaces(Archive *fout)
Definition: pg_dump.c:5601
void getPublications(Archive *fout)
Definition: pg_dump.c:4204
void getTSParsers(Archive *fout)
Definition: pg_dump.c:9193
void getExtendedStatistics(Archive *fout)
Definition: pg_dump.c:7615
void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], int numExtensions)
Definition: pg_dump.c:17984
void getDefaultACLs(Archive *fout)
Definition: pg_dump.c:9623
void getSubscriptions(Archive *fout)
Definition: pg_dump.c:4739
ExtensionInfo * getExtensions(Archive *fout, int *numExtensions)
Definition: pg_dump.c:5733
void getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
Definition: pg_dump.c:8069
void getTransforms(Archive *fout)
Definition: pg_dump.c:8537
void getEventTriggers(Archive *fout)
Definition: pg_dump.c:8265
TableInfo * getTables(Archive *fout, int *numTables)
Definition: pg_dump.c:6680
void getTSTemplates(Archive *fout)
Definition: pg_dump.c:9333
void getProcLangs(Archive *fout)
Definition: pg_dump.c:8343
void getOperators(Archive *fout)
Definition: pg_dump.c:5968
void getOpfamilies(Archive *fout)
Definition: pg_dump.c:6282

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

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

References appendPQExpBuffer(), appendPQExpBufferStr(), AssignDumpId(), atooid, _dumpOptions::binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), DO_SUBSCRIPTION, _SubscriptionInfo::dobj, Archive::dopt, ExecuteSqlQuery(), getRoleName(), i, is_superuser(), LOGICALREP_ORIGIN_ANY, LOGICALREP_TWOPHASE_STATE_DISABLED, _dumpableObject::name, _dumpOptions::no_subscriptions, _dumpableObject::objType, CatalogId::oid, pg_log_warning, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, res, _SubscriptionInfo::rolname, selectDumpableObject(), _SubscriptionInfo::subbinary, _SubscriptionInfo::subconninfo, _SubscriptionInfo::subdisableonerr, _SubscriptionInfo::subenabled, _SubscriptionInfo::subfailover, _SubscriptionInfo::suborigin, _SubscriptionInfo::suboriginremotelsn, _SubscriptionInfo::subpasswordrequired, _SubscriptionInfo::subpublications, _SubscriptionInfo::subrunasowner, _SubscriptionInfo::subslotname, _SubscriptionInfo::substream, _SubscriptionInfo::subsynccommit, _SubscriptionInfo::subtwophasestate, and CatalogId::tableoid.

Referenced by getSchemaData().

◆ getSubscriptionTables()

void getSubscriptionTables ( Archive fout)

Definition at line 4939 of file pg_dump.c.

4940 {
4941  DumpOptions *dopt = fout->dopt;
4942  SubscriptionInfo *subinfo = NULL;
4943  SubRelInfo *subrinfo;
4944  PGresult *res;
4945  int i_srsubid;
4946  int i_srrelid;
4947  int i_srsubstate;
4948  int i_srsublsn;
4949  int ntups;
4950  Oid last_srsubid = InvalidOid;
4951 
4952  if (dopt->no_subscriptions || !dopt->binary_upgrade ||
4953  fout->remoteVersion < 170000)
4954  return;
4955 
4956  res = ExecuteSqlQuery(fout,
4957  "SELECT srsubid, srrelid, srsubstate, srsublsn "
4958  "FROM pg_catalog.pg_subscription_rel "
4959  "ORDER BY srsubid",
4960  PGRES_TUPLES_OK);
4961  ntups = PQntuples(res);
4962  if (ntups == 0)
4963  goto cleanup;
4964 
4965  /* Get pg_subscription_rel attributes */
4966  i_srsubid = PQfnumber(res, "srsubid");
4967  i_srrelid = PQfnumber(res, "srrelid");
4968  i_srsubstate = PQfnumber(res, "srsubstate");
4969  i_srsublsn = PQfnumber(res, "srsublsn");
4970 
4971  subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
4972  for (int i = 0; i < ntups; i++)
4973  {
4974  Oid cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
4975  Oid relid = atooid(PQgetvalue(res, i, i_srrelid));
4976  TableInfo *tblinfo;
4977 
4978  /*
4979  * If we switched to a new subscription, check if the subscription
4980  * exists.
4981  */
4982  if (cur_srsubid != last_srsubid)
4983  {
4984  subinfo = findSubscriptionByOid(cur_srsubid);
4985  if (subinfo == NULL)
4986  pg_fatal("subscription with OID %u does not exist", cur_srsubid);
4987 
4988  last_srsubid = cur_srsubid;
4989  }
4990 
4991  tblinfo = findTableByOid(relid);
4992  if (tblinfo == NULL)
4993  pg_fatal("failed sanity check, table with OID %u not found",
4994  relid);
4995 
4996  /* OK, make a DumpableObject for this relationship */
4997  subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
4998  subrinfo[i].dobj.catId.tableoid = relid;
4999  subrinfo[i].dobj.catId.oid = cur_srsubid;
5000  AssignDumpId(&subrinfo[i].dobj);
5001  subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
5002  subrinfo[i].tblinfo = tblinfo;
5003  subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
5004  if (PQgetisnull(res, i, i_srsublsn))
5005  subrinfo[i].srsublsn = NULL;
5006  else
5007  subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
5008 
5009  subrinfo[i].subinfo = subinfo;
5010 
5011  /* Decide whether we want to dump it */
5012  selectDumpableObject(&(subrinfo[i].dobj), fout);
5013  }
5014 
5015 cleanup:
5016  PQclear(res);
5017 }
SubscriptionInfo * findSubscriptionByOid(Oid oid)
Definition: common.c:991
static void cleanup(void)
Definition: bootstrap.c:681
DumpableObject dobj
Definition: pg_dump.h:688
char * srsublsn
Definition: pg_dump.h:692
SubscriptionInfo * subinfo
Definition: pg_dump.h:689
TableInfo * tblinfo
Definition: pg_dump.h:690
char srsubstate
Definition: pg_dump.h:691

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

8622 {
8623  DumpOptions *dopt = fout->dopt;
8625  PQExpBuffer tbloids = createPQExpBuffer();
8626  PQExpBuffer checkoids = createPQExpBuffer();
8627  PGresult *res;
8628  int ntups;
8629  int curtblindx;
8630  int i_attrelid;
8631  int i_attnum;
8632  int i_attname;
8633  int i_atttypname;
8634  int i_attstattarget;
8635  int i_attstorage;
8636  int i_typstorage;
8637  int i_attidentity;
8638  int i_attgenerated;
8639  int i_attisdropped;
8640  int i_attlen;
8641  int i_attalign;
8642  int i_attislocal;
8643  int i_attnotnull;
8644  int i_attoptions;
8645  int i_attcollation;
8646  int i_attcompression;
8647  int i_attfdwoptions;
8648  int i_attmissingval;
8649  int i_atthasdef;
8650 
8651  /*
8652  * We want to perform just one query against pg_attribute, and then just
8653  * one against pg_attrdef (for DEFAULTs) and one against pg_constraint
8654  * (for CHECK constraints). However, we mustn't try to select every row
8655  * of those catalogs and then sort it out on the client side, because some
8656  * of the server-side functions we need would be unsafe to apply to tables
8657  * we don't have lock on. Hence, we build an array of the OIDs of tables
8658  * we care about (and now have lock on!), and use a WHERE clause to
8659  * constrain which rows are selected.
8660  */
8661  appendPQExpBufferChar(tbloids, '{');
8662  appendPQExpBufferChar(checkoids, '{');
8663  for (int i = 0; i < numTables; i++)
8664  {
8665  TableInfo *tbinfo = &tblinfo[i];
8666 
8667  /* Don't bother to collect info for sequences */
8668  if (tbinfo->relkind == RELKIND_SEQUENCE)
8669  continue;
8670 
8671  /* Don't bother with uninteresting tables, either */
8672  if (!tbinfo->interesting)
8673  continue;
8674 
8675  /* OK, we need info for this table */
8676  if (tbloids->len > 1) /* do we have more than the '{'? */
8677  appendPQExpBufferChar(tbloids, ',');
8678  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8679 
8680  if (tbinfo->ncheck > 0)
8681  {
8682  /* Also make a list of the ones with check constraints */
8683  if (checkoids->len > 1) /* do we have more than the '{'? */
8684  appendPQExpBufferChar(checkoids, ',');
8685  appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
8686  }
8687  }
8688  appendPQExpBufferChar(tbloids, '}');
8689  appendPQExpBufferChar(checkoids, '}');
8690 
8691  /*
8692  * Find all the user attributes and their types.
8693  *
8694  * Since we only want to dump COLLATE clauses for attributes whose
8695  * collation is different from their type's default, we use a CASE here to
8696  * suppress uninteresting attcollations cheaply.
8697  */
8699  "SELECT\n"
8700  "a.attrelid,\n"
8701  "a.attnum,\n"
8702  "a.attname,\n"
8703  "a.attstattarget,\n"
8704  "a.attstorage,\n"
8705  "t.typstorage,\n"
8706  "a.attnotnull,\n"
8707  "a.atthasdef,\n"
8708  "a.attisdropped,\n"
8709  "a.attlen,\n"
8710  "a.attalign,\n"
8711  "a.attislocal,\n"
8712  "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
8713  "array_to_string(a.attoptions, ', ') AS attoptions,\n"
8714  "CASE WHEN a.attcollation <> t.typcollation "
8715  "THEN a.attcollation ELSE 0 END AS attcollation,\n"
8716  "pg_catalog.array_to_string(ARRAY("
8717  "SELECT pg_catalog.quote_ident(option_name) || "
8718  "' ' || pg_catalog.quote_literal(option_value) "
8719  "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8720  "ORDER BY option_name"
8721  "), E',\n ') AS attfdwoptions,\n");
8722 
8723  if (fout->remoteVersion >= 140000)
8725  "a.attcompression AS attcompression,\n");
8726  else
8728  "'' AS attcompression,\n");
8729 
8730  if (fout->remoteVersion >= 100000)
8732  "a.attidentity,\n");
8733  else
8735  "'' AS attidentity,\n");
8736 
8737  if (fout->remoteVersion >= 110000)
8739  "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8740  "THEN a.attmissingval ELSE null END AS attmissingval,\n");
8741  else
8743  "NULL AS attmissingval,\n");
8744 
8745  if (fout->remoteVersion >= 120000)
8747  "a.attgenerated\n");
8748  else
8750  "'' AS attgenerated\n");
8751 
8752  /* need left join to pg_type to not fail on dropped columns ... */
8754  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8755  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
8756  "LEFT JOIN pg_catalog.pg_type t "
8757  "ON (a.atttypid = t.oid)\n"
8758  "WHERE a.attnum > 0::pg_catalog.int2\n"
8759  "ORDER BY a.attrelid, a.attnum",
8760  tbloids->data);
8761 
8762  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8763 
8764  ntups = PQntuples(res);
8765 
8766  i_attrelid = PQfnumber(res, "attrelid");
8767  i_attnum = PQfnumber(res, "attnum");
8768  i_attname = PQfnumber(res, "attname");
8769  i_atttypname = PQfnumber(res, "atttypname");
8770  i_attstattarget = PQfnumber(res, "attstattarget");
8771  i_attstorage = PQfnumber(res, "attstorage");
8772  i_typstorage = PQfnumber(res, "typstorage");
8773  i_attidentity = PQfnumber(res, "attidentity");
8774  i_attgenerated = PQfnumber(res, "attgenerated");
8775  i_attisdropped = PQfnumber(res, "attisdropped");
8776  i_attlen = PQfnumber(res, "attlen");
8777  i_attalign = PQfnumber(res, "attalign");
8778  i_attislocal = PQfnumber(res, "attislocal");
8779  i_attnotnull = PQfnumber(res, "attnotnull");
8780  i_attoptions = PQfnumber(res, "attoptions");
8781  i_attcollation = PQfnumber(res, "attcollation");
8782  i_attcompression = PQfnumber(res, "attcompression");
8783  i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8784  i_attmissingval = PQfnumber(res, "attmissingval");
8785  i_atthasdef = PQfnumber(res, "atthasdef");
8786 
8787  /* Within the next loop, we'll accumulate OIDs of tables with defaults */
8788  resetPQExpBuffer(tbloids);
8789  appendPQExpBufferChar(tbloids, '{');
8790 
8791  /*
8792  * Outer loop iterates once per table, not once per row. Incrementing of
8793  * r is handled by the inner loop.
8794  */
8795  curtblindx = -1;
8796  for (int r = 0; r < ntups;)
8797  {
8798  Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid));
8799  TableInfo *tbinfo = NULL;
8800  int numatts;
8801  bool hasdefaults;
8802 
8803  /* Count rows for this table */
8804  for (numatts = 1; numatts < ntups - r; numatts++)
8805  if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
8806  break;
8807 
8808  /*
8809  * Locate the associated TableInfo; we rely on tblinfo[] being in OID
8810  * order.
8811  */
8812  while (++curtblindx < numTables)
8813  {
8814  tbinfo = &tblinfo[curtblindx];
8815  if (tbinfo->dobj.catId.oid == attrelid)
8816  break;
8817  }
8818  if (curtblindx >= numTables)
8819  pg_fatal("unrecognized table OID %u", attrelid);
8820  /* cross-check that we only got requested tables */
8821  if (tbinfo->relkind == RELKIND_SEQUENCE ||
8822  !tbinfo->interesting)
8823  pg_fatal("unexpected column data for table \"%s\"",
8824  tbinfo->dobj.name);
8825 
8826  /* Save data for this table */
8827  tbinfo->numatts = numatts;
8828  tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
8829  tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
8830  tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
8831  tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
8832  tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
8833  tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
8834  tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
8835  tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
8836  tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
8837  tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
8838  tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
8839  tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
8840  tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
8841  tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
8842  tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
8843  tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
8844  tbinfo->notnull = (bool *) pg_malloc(numatts * sizeof(bool));
8845  tbinfo->inhNotNull = (bool *) pg_malloc(numatts * sizeof(bool));
8846  tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
8847  hasdefaults = false;
8848 
8849  for (int j = 0; j < numatts; j++, r++)
8850  {
8851  if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
8852  pg_fatal("invalid column numbering in table \"%s\"",
8853  tbinfo->dobj.name);
8854  tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
8855  tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
8856  if (PQgetisnull(res, r, i_attstattarget))
8857  tbinfo->attstattarget[j] = -1;
8858  else
8859  tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
8860  tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
8861  tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
8862  tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
8863  tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
8864  tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
8865  tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
8866  tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
8867  tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
8868  tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
8869  tbinfo->notnull[j] = (PQgetvalue(res, r, i_attnotnull)[0] == 't');
8870  tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
8871  tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
8872  tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
8873  tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
8874  tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
8875  tbinfo->attrdefs[j] = NULL; /* fix below */
8876  if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
8877  hasdefaults = true;
8878  /* these flags will be set in flagInhAttrs() */
8879  tbinfo->inhNotNull[j] = false;
8880  }
8881 
8882  if (hasdefaults)
8883  {
8884  /* Collect OIDs of interesting tables that have defaults */
8885  if (tbloids->len > 1) /* do we have more than the '{'? */
8886  appendPQExpBufferChar(tbloids, ',');
8887  appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
8888  }
8889  }
8890 
8891  PQclear(res);
8892 
8893  /*
8894  * Now get info about column defaults. This is skipped for a data-only
8895  * dump, as it is only needed for table schemas.
8896  */
8897  if (!dopt->dataOnly && tbloids->len > 1)
8898  {
8899  AttrDefInfo *attrdefs;
8900  int numDefaults;
8901  TableInfo *tbinfo = NULL;
8902 
8903  pg_log_info("finding table default expressions");
8904 
8905  appendPQExpBufferChar(tbloids, '}');
8906 
8907  printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
8908  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
8909  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
8910  "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
8911  "ORDER BY a.adrelid, a.adnum",
8912  tbloids->data);
8913 
8914  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
8915 
8916  numDefaults = PQntuples(res);
8917  attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
8918 
8919  curtblindx = -1;
8920  for (int j = 0; j < numDefaults; j++)
8921  {
8922  Oid adtableoid = atooid(PQgetvalue(res, j, 0));
8923  Oid adoid = atooid(PQgetvalue(res, j, 1));
8924  Oid adrelid = atooid(PQgetvalue(res, j, 2));
8925  int adnum = atoi(PQgetvalue(res, j, 3));
8926  char *adsrc = PQgetvalue(res, j, 4);
8927 
8928  /*
8929  * Locate the associated TableInfo; we rely on tblinfo[] being in
8930  * OID order.
8931  */
8932  if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
8933  {
8934  while (++curtblindx < numTables)
8935  {
8936  tbinfo = &tblinfo[curtblindx];
8937  if (tbinfo->dobj.catId.oid == adrelid)
8938  break;
8939  }
8940  if (curtblindx >= numTables)
8941  pg_fatal("unrecognized table OID %u", adrelid);
8942  }
8943 
8944  if (adnum <= 0 || adnum > tbinfo->numatts)
8945  pg_fatal("invalid adnum value %d for table \"%s\"",
8946  adnum, tbinfo->dobj.name);
8947 
8948  /*
8949  * dropped columns shouldn't have defaults, but just in case,
8950  * ignore 'em
8951  */
8952  if (tbinfo->attisdropped[adnum - 1])
8953  continue;
8954 
8955  attrdefs[j].dobj.objType = DO_ATTRDEF;
8956  attrdefs[j].dobj.catId.tableoid = adtableoid;
8957  attrdefs[j].dobj.catId.oid = adoid;
8958  AssignDumpId(&attrdefs[j].dobj);
8959  attrdefs[j].adtable = tbinfo;
8960  attrdefs[j].adnum = adnum;
8961  attrdefs[j].adef_expr = pg_strdup(adsrc);
8962 
8963  attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
8964  attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
8965 
8966  attrdefs[j].dobj.dump = tbinfo->dobj.dump;
8967 
8968  /*
8969  * Figure out whether the default/generation expression should be
8970  * dumped as part of the main CREATE TABLE (or similar) command or
8971  * as a separate ALTER TABLE (or similar) command. The preference
8972  * is to put it into the CREATE command, but in some cases that's
8973  * not possible.
8974  */
8975  if (tbinfo->attgenerated[adnum - 1])
8976  {
8977  /*
8978  * Column generation expressions cannot be dumped separately,
8979  * because there is no syntax for it. By setting separate to
8980  * false here we prevent the "default" from being processed as
8981  * its own dumpable object. Later, flagInhAttrs() will mark
8982  * it as not to be dumped at all, if possible (that is, if it
8983  * can be inherited from a parent).
8984  */
8985  attrdefs[j].separate = false;
8986  }
8987  else if (tbinfo->relkind == RELKIND_VIEW)
8988  {
8989  /*
8990  * Defaults on a VIEW must always be dumped as separate ALTER
8991  * TABLE commands.
8992  */
8993  attrdefs[j].separate = true;
8994  }
8995  else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
8996  {
8997  /* column will be suppressed, print default separately */
8998  attrdefs[j].separate = true;
8999  }
9000  else
9001  {
9002  attrdefs[j].separate = false;
9003  }
9004 
9005  if (!attrdefs[j].separate)
9006  {
9007  /*
9008  * Mark the default as needing to appear before the table, so
9009  * that any dependencies it has must be emitted before the
9010  * CREATE TABLE. If this is not possible, we'll change to
9011  * "separate" mode while sorting dependencies.
9012  */
9013  addObjectDependency(&tbinfo->dobj,
9014  attrdefs[j].dobj.dumpId);
9015  }
9016 
9017  tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
9018  }
9019 
9020  PQclear(res);
9021  }
9022 
9023  /*
9024  * Get info about table CHECK constraints. This is skipped for a
9025  * data-only dump, as it is only needed for table schemas.
9026  */
9027  if (!dopt->dataOnly && checkoids->len > 2)
9028  {
9029  ConstraintInfo *constrs;
9030  int numConstrs;
9031  int i_tableoid;
9032  int i_oid;
9033  int i_conrelid;
9034  int i_conname;
9035  int i_consrc;
9036  int i_conislocal;
9037  int i_convalidated;
9038 
9039  pg_log_info("finding table check constraints");
9040 
9041  resetPQExpBuffer(q);
9043  "SELECT c.tableoid, c.oid, conrelid, conname, "
9044  "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
9045  "conislocal, convalidated "
9046  "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
9047  "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
9048  "WHERE contype = 'c' "
9049  "ORDER BY c.conrelid, c.conname",
9050  checkoids->data);
9051 
9052  res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
9053 
9054  numConstrs = PQntuples(res);
9055  constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
9056 
9057  i_tableoid = PQfnumber(res, "tableoid");
9058  i_oid = PQfnumber(res, "oid");
9059  i_conrelid = PQfnumber(res, "conrelid");
9060  i_conname = PQfnumber(res, "conname");
9061  i_consrc = PQfnumber(res, "consrc");
9062  i_conislocal = PQfnumber(res, "conislocal");
9063  i_convalidated = PQfnumber(res, "convalidated");
9064 
9065  /* As above, this loop iterates once per table, not once per row */
9066  curtblindx = -1;
9067  for (int j = 0; j < numConstrs;)
9068  {
9069  Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid));
9070  TableInfo *tbinfo = NULL;
9071  int numcons;
9072 
9073  /* Count rows for this table */
9074  for (numcons = 1; numcons < numConstrs - j; numcons++)
9075  if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
9076  break;
9077 
9078  /*
9079  * Locate the associated TableInfo; we rely on tblinfo[] being in
9080  * OID order.
9081  */
9082  while (++curtblindx < numTables)
9083  {
9084  tbinfo = &tblinfo[curtblindx];
9085  if (tbinfo->dobj.catId.oid == conrelid)
9086  break;
9087  }
9088  if (curtblindx >= numTables)
9089  pg_fatal("unrecognized table OID %u", conrelid);
9090 
9091  if (numcons != tbinfo->ncheck)
9092  {
9093  pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
9094  "expected %d check constraints on table \"%s\" but found %d",
9095  tbinfo->ncheck),
9096  tbinfo->ncheck, tbinfo->dobj.name, numcons);
9097  pg_log_error_hint("The system catalogs might be corrupted.");
9098  exit_nicely(1);
9099  }
9100 
9101  tbinfo->checkexprs = constrs + j;
9102 
9103  for (int c = 0; c < numcons; c++, j++)
9104  {
9105  bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
9106 
9107  constrs[j].dobj.objType = DO_CONSTRAINT;
9108  constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
9109  constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
9110  AssignDumpId(&constrs[j].dobj);
9111  constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
9112  constrs[j].dobj.namespace = tbinfo->dobj.namespace;
9113  constrs[j].contable = tbinfo;
9114  constrs[j].condomain = NULL;
9115  constrs[j].contype = 'c';
9116  constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
9117  constrs[j].confrelid = InvalidOid;
9118  constrs[j].conindex = 0;
9119  constrs[j].condeferrable = false;
9120  constrs[j].condeferred = false;
9121  constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
9122 
9123  /*
9124  * An unvalidated constraint needs to be dumped separately, so
9125  * that potentially-violating existing data is loaded before
9126  * the constraint.
9127  */
9128  constrs[j].separate = !validated;
9129 
9130  constrs[j].dobj.dump = tbinfo->dobj.dump;
9131 
9132  /*
9133  * Mark the constraint as needing to appear before the table
9134  * --- this is so that any other dependencies of the
9135  * constraint will be emitted before we try to create the
9136  * table. If the constraint is to be dumped separately, it
9137  * will be dumped after data is loaded anyway, so don't do it.
9138  * (There's an automatic dependency in the opposite direction
9139  * anyway, so don't need to add one manually here.)
9140  */
9141  if (!constrs[j].separate)
9142  addObjectDependency(&tbinfo->dobj,
9143  constrs[j].dobj.dumpId);
9144 
9145  /*
9146  * We will detect later whether the constraint must be split
9147  * out from the table definition.
9148  */
9149  }
9150  }
9151 
9152  PQclear(res);
9153  }
9154 
9155  destroyPQExpBuffer(q);
9156  destroyPQExpBuffer(tbloids);
9157  destroyPQExpBuffer(checkoids);
9158 }
#define ngettext(s, p, n)
Definition: c.h:1181
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
Definition: pg_dump.c:9178
#define exit_nicely(code)
Definition: pg_dumpall.c:124
DumpableObject dobj
Definition: pg_dump.h:375
char * adef_expr
Definition: pg_dump.h:378
TableInfo * adtable
Definition: pg_dump.h:376
bool separate
Definition: pg_dump.h:379
bool dataOnly
Definition: pg_backup.h:170
char * attidentity
Definition: pg_dump.h:339
int ncheck
Definition: pg_dump.h:308
bool * attislocal
Definition: pg_dump.h:343
char * attgenerated
Definition: pg_dump.h:340
int * attlen
Definition: pg_dump.h:341
char ** attfdwoptions
Definition: pg_dump.h:347
bool * attisdropped
Definition: pg_dump.h:338
bool needs_override
Definition: pg_dump.h:353
struct _constraintInfo * checkexprs
Definition: pg_dump.h:352
int * attstattarget
Definition: pg_dump.h:335
char * typstorage
Definition: pg_dump.h:337
int numatts
Definition: pg_dump.h:332
struct _attrDefInfo ** attrdefs
Definition: pg_dump.h:351
char ** attoptions
Definition: pg_dump.h:344
Oid * attcollation
Definition: pg_dump.h:345
char * attstorage
Definition: pg_dump.h:336
bool * notnull
Definition: pg_dump.h:349
char ** atttypnames
Definition: pg_dump.h:334
char ** attmissingval
Definition: pg_dump.h:348
char ** attnames
Definition: pg_dump.h:333
char * attalign
Definition: pg_dump.h:342
char * attcompression
Definition: pg_dump.h:346
bool * inhNotNull
Definition: pg_dump.h:350

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

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, _tableInfo::amname, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), AssignDumpId(), atooid, _dumpableObject::catId, _tableInfo::checkoption, _dumpableObject::components, CppAsString2, createPQExpBuffer(), _tableInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_TABLE, _tableInfo::dobj, Archive::dopt, _tableInfo::dummy_view, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DATA, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, DUMP_COMPONENTS_REQUIRING_LOCK, ExecuteSqlQuery(), ExecuteSqlStatement(), findNamespace(), fmtQualifiedDumpable, _tableInfo::forcerowsec, _tableInfo::foreign_server, _tableInfo::frozenxid, GetConnection(), getRoleName(), _tableInfo::hascolumnACLs, _tableInfo::hasindex, _tableInfo::hasoids, _tableInfo::hasrules, _tableInfo::hastriggers, i, if(), _dumpableAcl::initprivs, _tableInfo::interesting, InvalidOid, _tableInfo::is_identity_sequence, _tableInfo::ispartition, PQExpBufferData::len, _dumpOptions::lockWaitTimeout, _tableInfo::minmxid, _dumpableObject::name, _tableInfo::ncheck, _dumpableObject::objType, CatalogId::oid, _tableInfo::owning_col, _tableInfo::owning_tab, pg_malloc0(), pg_strdup(), PGRES_TUPLES_OK, _tableInfo::postponed_def, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, _tableInfo::relispopulated, _tableInfo::relkind, _tableInfo::reloftype, _tableInfo::reloptions, _tableInfo::relpages, _tableInfo::relpersistence, _tableInfo::relreplident, _tableInfo::reltablespace, _tableInfo::reltype, Archive::remoteVersion, res, resetPQExpBuffer(), _tableInfo::rolname, _tableInfo::rowsec, selectDumpableTable(), CatalogId::tableoid, _tableInfo::toast_frozenxid, _tableInfo::toast_minmxid, _tableInfo::toast_oid, _tableInfo::toast_reloptions, and _tableInfo::toastpages.

Referenced by getSchemaData().

◆ getTransforms()

void getTransforms ( Archive fout)

Definition at line 8537 of file pg_dump.c.

8538 {
8539  PGresult *res;
8540  int ntups;
8541  int i;
8542  PQExpBuffer query;
8543  TransformInfo *transforminfo;
8544  int i_tableoid;
8545  int i_oid;
8546  int i_trftype;
8547  int i_trflang;
8548  int i_trffromsql;
8549  int i_trftosql;
8550 
8551  /* Transforms didn't exist pre-9.5 */
8552  if (fout->remoteVersion < 90500)
8553  return;
8554 
8555  query = createPQExpBuffer();
8556 
8557  appendPQExpBufferStr(query, "SELECT tableoid, oid, "
8558  "trftype, trflang, trffromsql::oid, trftosql::oid "
8559  "FROM pg_transform "
8560  "ORDER BY 3,4");
8561 
8562  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
8563 
8564  ntups = PQntuples(res);
8565 
8566  transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
8567 
8568  i_tableoid = PQfnumber(res, "tableoid");
8569  i_oid = PQfnumber(res, "oid");
8570  i_trftype = PQfnumber(res, "trftype");
8571  i_trflang = PQfnumber(res, "trflang");
8572  i_trffromsql = PQfnumber(res, "trffromsql");
8573  i_trftosql = PQfnumber(res, "trftosql");
8574 
8575  for (i = 0; i < ntups; i++)
8576  {
8577  PQExpBufferData namebuf;
8578  TypeInfo *typeInfo;
8579  char *lanname;
8580 
8581  transforminfo[i].dobj.objType = DO_TRANSFORM;
8582  transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
8583  transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
8584  AssignDumpId(&transforminfo[i].dobj);
8585  transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
8586  transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
8587  transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
8588  transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
8589 
8590  /*
8591  * Try to name transform as concatenation of type and language name.
8592  * This is only used for purposes of sorting. If we fail to find
8593  * either, the name will be an empty string.
8594  */
8595  initPQExpBuffer(&namebuf);
8596  typeInfo = findTypeByOid(transforminfo[i].trftype);
8597  lanname = get_language_name(fout, transforminfo[i].trflang);
8598  if (typeInfo && lanname)
8599  appendPQExpBuffer(&namebuf, "%s %s",
8600  typeInfo->dobj.name, lanname);
8601  transforminfo[i].dobj.name = namebuf.data;
8602  free(lanname);
8603 
8604  /* Decide whether we want to dump it */
8605  selectDumpableObject(&(transforminfo[i].dobj), fout);
8606  }
8607 
8608  PQclear(res);
8609 
8610  destroyPQExpBuffer(query);
8611 }
static char * get_language_name(Archive *fout, Oid langid)
Definition: pg_dump.c:8516
DumpableObject dobj
Definition: pg_dump.h:504
Oid trffromsql
Definition: pg_dump.h:507

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

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

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

9393 {
9394  PGresult *res;
9395  int ntups;
9396  int i;
9397  PQExpBuffer query;
9398  TSConfigInfo *cfginfo;
9399  int i_tableoid;
9400  int i_oid;
9401  int i_cfgname;
9402  int i_cfgnamespace;
9403  int i_cfgowner;
9404  int i_cfgparser;
9405 
9406  query = createPQExpBuffer();
9407 
9408  appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
9409  "cfgnamespace, cfgowner, cfgparser "
9410  "FROM pg_ts_config");
9411 
9412  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9413 
9414  ntups = PQntuples(res);
9415 
9416  cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
9417 
9418  i_tableoid = PQfnumber(res, "tableoid");
9419  i_oid = PQfnumber(res, "oid");
9420  i_cfgname = PQfnumber(res, "cfgname");
9421  i_cfgnamespace = PQfnumber(res, "cfgnamespace");
9422  i_cfgowner = PQfnumber(res, "cfgowner");
9423  i_cfgparser = PQfnumber(res, "cfgparser");
9424 
9425  for (i = 0; i < ntups; i++)
9426  {
9427  cfginfo[i].dobj.objType = DO_TSCONFIG;
9428  cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9429  cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9430  AssignDumpId(&cfginfo[i].dobj);
9431  cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
9432  cfginfo[i].dobj.namespace =
9433  findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
9434  cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
9435  cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
9436 
9437  /* Decide whether we want to dump it */
9438  selectDumpableObject(&(cfginfo[i].dobj), fout);
9439  }
9440 
9441  PQclear(res);
9442 
9443  destroyPQExpBuffer(query);
9444 }
Oid cfgparser
Definition: pg_dump.h:547
DumpableObject dobj
Definition: pg_dump.h:545
const char * rolname
Definition: pg_dump.h:546

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

9268 {
9269  PGresult *res;
9270  int ntups;
9271  int i;
9272  PQExpBuffer query;
9273  TSDictInfo *dictinfo;
9274  int i_tableoid;
9275  int i_oid;
9276  int i_dictname;
9277  int i_dictnamespace;
9278  int i_dictowner;
9279  int i_dicttemplate;
9280  int i_dictinitoption;
9281 
9282  query = createPQExpBuffer();
9283 
9284  appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
9285  "dictnamespace, dictowner, "
9286  "dicttemplate, dictinitoption "
9287  "FROM pg_ts_dict");
9288 
9289  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9290 
9291  ntups = PQntuples(res);
9292 
9293  dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
9294 
9295  i_tableoid = PQfnumber(res, "tableoid");
9296  i_oid = PQfnumber(res, "oid");
9297  i_dictname = PQfnumber(res, "dictname");
9298  i_dictnamespace = PQfnumber(res, "dictnamespace");
9299  i_dictowner = PQfnumber(res, "dictowner");
9300  i_dictinitoption = PQfnumber(res, "dictinitoption");
9301  i_dicttemplate = PQfnumber(res, "dicttemplate");
9302 
9303  for (i = 0; i < ntups; i++)
9304  {
9305  dictinfo[i].dobj.objType = DO_TSDICT;
9306  dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9307  dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9308  AssignDumpId(&dictinfo[i].dobj);
9309  dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
9310  dictinfo[i].dobj.namespace =
9311  findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
9312  dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
9313  dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
9314  if (PQgetisnull(res, i, i_dictinitoption))
9315  dictinfo[i].dictinitoption = NULL;
9316  else
9317  dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
9318 
9319  /* Decide whether we want to dump it */
9320  selectDumpableObject(&(dictinfo[i].dobj), fout);
9321  }
9322 
9323  PQclear(res);
9324 
9325  destroyPQExpBuffer(query);
9326 }
char * dictinitoption
Definition: pg_dump.h:533
DumpableObject dobj
Definition: pg_dump.h:530
const char * rolname
Definition: pg_dump.h:531
Oid dicttemplate
Definition: pg_dump.h:532

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

9194 {
9195  PGresult *res;
9196  int ntups;
9197  int i;
9198  PQExpBuffer query;
9199  TSParserInfo *prsinfo;
9200  int i_tableoid;
9201  int i_oid;
9202  int i_prsname;
9203  int i_prsnamespace;
9204  int i_prsstart;
9205  int i_prstoken;
9206  int i_prsend;
9207  int i_prsheadline;
9208  int i_prslextype;
9209 
9210  query = createPQExpBuffer();
9211 
9212  /*
9213  * find all text search objects, including builtin ones; we filter out
9214  * system-defined objects at dump-out time.
9215  */
9216 
9217  appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
9218  "prsstart::oid, prstoken::oid, "
9219  "prsend::oid, prsheadline::oid, prslextype::oid "
9220  "FROM pg_ts_parser");
9221 
9222  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9223 
9224  ntups = PQntuples(res);
9225 
9226  prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
9227 
9228  i_tableoid = PQfnumber(res, "tableoid");
9229  i_oid = PQfnumber(res, "oid");
9230  i_prsname = PQfnumber(res, "prsname");
9231  i_prsnamespace = PQfnumber(res, "prsnamespace");
9232  i_prsstart = PQfnumber(res, "prsstart");
9233  i_prstoken = PQfnumber(res, "prstoken");
9234  i_prsend = PQfnumber(res, "prsend");
9235  i_prsheadline = PQfnumber(res, "prsheadline");
9236  i_prslextype = PQfnumber(res, "prslextype");
9237 
9238  for (i = 0; i < ntups; i++)
9239  {
9240  prsinfo[i].dobj.objType = DO_TSPARSER;
9241  prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9242  prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9243  AssignDumpId(&prsinfo[i].dobj);
9244  prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
9245  prsinfo[i].dobj.namespace =
9246  findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
9247  prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
9248  prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
9249  prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
9250  prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
9251  prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
9252 
9253  /* Decide whether we want to dump it */
9254  selectDumpableObject(&(prsinfo[i].dobj), fout);
9255  }
9256 
9257  PQclear(res);
9258 
9259  destroyPQExpBuffer(query);
9260 }
DumpableObject dobj
Definition: pg_dump.h:520
Oid prstoken
Definition: pg_dump.h:522
Oid prslextype
Definition: pg_dump.h:525
Oid prsheadline
Definition: pg_dump.h:524
Oid prsstart
Definition: pg_dump.h:521
Oid prsend
Definition: pg_dump.h:523

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

9334 {
9335  PGresult *res;
9336  int ntups;
9337  int i;
9338  PQExpBuffer query;
9339  TSTemplateInfo *tmplinfo;
9340  int i_tableoid;
9341  int i_oid;
9342  int i_tmplname;
9343  int i_tmplnamespace;
9344  int i_tmplinit;
9345  int i_tmpllexize;
9346 
9347  query = createPQExpBuffer();
9348 
9349  appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
9350  "tmplnamespace, tmplinit::oid, tmpllexize::oid "
9351  "FROM pg_ts_template");
9352 
9353  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
9354 
9355  ntups = PQntuples(res);
9356 
9357  tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
9358 
9359  i_tableoid = PQfnumber(res, "tableoid");
9360  i_oid = PQfnumber(res, "oid");
9361  i_tmplname = PQfnumber(res, "tmplname");
9362  i_tmplnamespace = PQfnumber(res, "tmplnamespace");
9363  i_tmplinit = PQfnumber(res, "tmplinit");
9364  i_tmpllexize = PQfnumber(res, "tmpllexize");
9365 
9366  for (i = 0; i < ntups; i++)
9367  {
9368  tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
9369  tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
9370  tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
9371  AssignDumpId(&tmplinfo[i].dobj);
9372  tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
9373  tmplinfo[i].dobj.namespace =
9374  findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
9375  tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
9376  tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
9377 
9378  /* Decide whether we want to dump it */
9379  selectDumpableObject(&(tmplinfo[i].dobj), fout);
9380  }
9381 
9382  PQclear(res);
9383 
9384  destroyPQExpBuffer(query);
9385 }
Oid tmpllexize
Definition: pg_dump.h:540
Oid tmplinit
Definition: pg_dump.h:539
DumpableObject dobj
Definition: pg_dump.h:538

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

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

References _dumpableAcl::acl, _dumpableAcl::acldefault, appendPQExpBufferStr(), AssignDumpId(), atooid, _shellTypeInfo::baseType, _dumpableObject::catId, _dumpableObject::components, createPQExpBuffer(), _typeInfo::dacl, PQExpBufferData::data, destroyPQExpBuffer(), DO_SHELL_TYPE, DO_TYPE, _typeInfo::dobj, _shellTypeInfo::dobj, _typeInfo::domChecks, _dumpableObject::dump, DUMP_COMPONENT_ACL, DUMP_COMPONENT_DEFINITION, DUMP_COMPONENT_NONE, ExecuteSqlQuery(), findNamespace(), _typeInfo::ftypname, getDomainConstraints(), getRoleName(), i, _dumpableAcl::initprivs, _typeInfo::isArray, _typeInfo::isDefined, _typeInfo::isMultirange, _dumpableObject::name, _typeInfo::nDomChecks, nilCatalogId, _dumpableObject::objType, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), PQntuples(), _dumpableAcl::privtype, res, _typeInfo::rolname, selectDumpableType(), _typeInfo::shellType, CatalogId::tableoid, _typeInfo::typelem, _typeInfo::typrelid, _typeInfo::typrelkind, and _typeInfo::typtype.

Referenced by getSchemaData().

◆ parseOidArray()

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

Definition at line 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 17984 of file pg_dump.c.

17986 {
17987  DumpOptions *dopt = fout->dopt;
17988  PQExpBuffer query;
17989  PGresult *res;
17990  int ntups,
17991  i;
17992  int i_conrelid,
17993  i_confrelid;
17994 
17995  /* Nothing to do if no extensions */
17996  if (numExtensions == 0)
17997  return;
17998 
17999  /*
18000  * Identify extension configuration tables and create TableDataInfo
18001  * objects for them, ensuring their data will be dumped even though the
18002  * tables themselves won't be.
18003  *
18004  * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
18005  * user data in a configuration table is treated like schema data. This
18006  * seems appropriate since system data in a config table would get
18007  * reloaded by CREATE EXTENSION. If the extension is not listed in the
18008  * list of extensions to be included, none of its data is dumped.
18009  */
18010  for (i = 0; i < numExtensions; i++)
18011  {
18012  ExtensionInfo *curext = &(extinfo[i]);
18013  char *extconfig = curext->extconfig;
18014  char *extcondition = curext->extcondition;
18015  char **extconfigarray = NULL;
18016  char **extconditionarray = NULL;
18017  int nconfigitems = 0;
18018  int nconditionitems = 0;
18019 
18020  /*
18021  * Check if this extension is listed as to include in the dump. If
18022  * not, any table data associated with it is discarded.
18023  */
18024  if (extension_include_oids.head != NULL &&
18026  curext->dobj.catId.oid))
18027  continue;
18028 
18029  /*
18030  * Check if this extension is listed as to exclude in the dump. If
18031  * yes, any table data associated with it is discarded.
18032  */
18033  if (extension_exclude_oids.head != NULL &&
18035  curext->dobj.catId.oid))
18036  continue;
18037 
18038  if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
18039  {
18040  int j;
18041 
18042  if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
18043  pg_fatal("could not parse %s array", "extconfig");
18044  if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
18045  pg_fatal("could not parse %s array", "extcondition");
18046  if (nconfigitems != nconditionitems)
18047  pg_fatal("mismatched number of configurations and conditions for extension");
18048 
18049  for (j = 0; j < nconfigitems; j++)
18050  {
18051  TableInfo *configtbl;
18052  Oid configtbloid = atooid(extconfigarray[j]);
18053  bool dumpobj =
18055 
18056  configtbl = findTableByOid(configtbloid);
18057  if (configtbl == NULL)
18058  continue;
18059 
18060  /*
18061  * Tables of not-to-be-dumped extensions shouldn't be dumped
18062  * unless the table or its schema is explicitly included
18063  */
18064  if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
18065  {
18066  /* check table explicitly requested */
18067  if (table_include_oids.head != NULL &&
18069  configtbloid))
18070  dumpobj = true;
18071 
18072  /* check table's schema explicitly requested */
18073  if (configtbl->dobj.namespace->dobj.dump &
18075  dumpobj = true;
18076  }
18077 
18078  /* check table excluded by an exclusion switch */
18079  if (table_exclude_oids.head != NULL &&
18081  configtbloid))
18082  dumpobj = false;
18083 
18084  /* check schema excluded by an exclusion switch */
18086  configtbl->dobj.namespace->dobj.catId.oid))
18087  dumpobj = false;
18088 
18089  if (dumpobj)
18090  {
18091  makeTableDataInfo(dopt, configtbl);
18092  if (configtbl->dataObj != NULL)
18093  {
18094  if (strlen(extconditionarray[j]) > 0)
18095  configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
18096  }
18097  }
18098  }
18099  }
18100  if (extconfigarray)
18101  free(extconfigarray);
18102  if (extconditionarray)
18103  free(extconditionarray);
18104  }
18105 
18106  /*
18107  * Now that all the TableDataInfo objects have been created for all the
18108  * extensions, check their FK dependencies and register them to try and
18109  * dump the data out in an order that they can be restored in.
18110  *
18111  * Note that this is not a problem for user tables as their FKs are
18112  * recreated after the data has been loaded.
18113  */
18114 
18115  query = createPQExpBuffer();
18116 
18117  printfPQExpBuffer(query,
18118  "SELECT conrelid, confrelid "
18119  "FROM pg_constraint "
18120  "JOIN pg_depend ON (objid = confrelid) "
18121  "WHERE contype = 'f' "
18122  "AND refclassid = 'pg_extension'::regclass "
18123  "AND classid = 'pg_class'::regclass;");
18124 
18125  res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
18126  ntups = PQntuples(res);
18127 
18128  i_conrelid = PQfnumber(res, "conrelid");
18129  i_confrelid = PQfnumber(res, "confrelid");
18130 
18131  /* Now get the dependencies and register them */
18132  for (i = 0; i < ntups; i++)
18133  {
18134  Oid conrelid,
18135  confrelid;
18136  TableInfo *reftable,
18137  *contable;
18138 
18139  conrelid = atooid(PQgetvalue(res, i, i_conrelid));
18140  confrelid = atooid(PQgetvalue(res, i, i_confrelid));
18141  contable = findTableByOid(conrelid);
18142  reftable = findTableByOid(confrelid);
18143 
18144  if (reftable == NULL ||
18145  reftable->dataObj == NULL ||
18146  contable == NULL ||
18147  contable->dataObj == NULL)
18148  continue;
18149 
18150  /*
18151  * Make referencing TABLE_DATA object depend on the referenced table's
18152  * TABLE_DATA object.
18153  */
18154  addObjectDependency(&contable->dataObj->dobj,
18155  reftable->dataObj->dobj.dumpId);
18156  }
18157  PQclear(res);
18158  destroyPQExpBuffer(query);
18159 }
static SimpleOidList schema_exclude_oids
Definition: pg_dump.c:133
static SimpleOidList extension_include_oids
Definition: pg_dump.c:149
static SimpleOidList extension_exclude_oids
Definition: pg_dump.c:152
static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
Definition: pg_dump.c:2788
static SimpleOidList table_exclude_oids
Definition: pg_dump.c:140
static SimpleOidList table_include_oids
Definition: pg_dump.c:137
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:384
char * filtercond
Definition: pg_dump.h:386
struct _tableDataInfo * dataObj
Definition: pg_dump.h:361

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

9179 {
9180  if (dopt->binary_upgrade)
9181  return true;
9182  if (tbinfo->attisdropped[colno])
9183  return false;
9184  return (tbinfo->attislocal[colno] || tbinfo->ispartition);
9185 }

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

References DOTypeNameCompare(), and qsort.

Referenced by main().