mirror of
https://github.com/postgres/postgres.git
synced 2025-06-23 14:01:44 +03:00
Move pg_dump memory routines into pg_dumpmem.c/h and restore common.c
with its original functions. The previous function migration would cause too many difficulties in back-patching.
This commit is contained in:
@ -20,7 +20,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
|
|||||||
|
|
||||||
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
|
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
|
||||||
pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
|
pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
|
||||||
pg_backup_directory.o common.o dumputils.o compress_io.o $(WIN32RES)
|
pg_backup_directory.o dumpmem.o dumputils.o compress_io.o $(WIN32RES)
|
||||||
|
|
||||||
KEYWRDOBJS = keywords.o kwlookup.o
|
KEYWRDOBJS = keywords.o kwlookup.o
|
||||||
|
|
||||||
@ -29,8 +29,8 @@ kwlookup.c: % : $(top_srcdir)/src/backend/parser/%
|
|||||||
|
|
||||||
all: pg_dump pg_restore pg_dumpall
|
all: pg_dump pg_restore pg_dumpall
|
||||||
|
|
||||||
pg_dump: pg_dump.o dumpcatalog.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
|
pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
|
||||||
$(CC) $(CFLAGS) pg_dump.o dumpcatalog.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
|
$(CC) $(CFLAGS) pg_dump.o common.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
|
||||||
|
|
||||||
pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
|
pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
|
||||||
$(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
|
$(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "compress_io.h"
|
#include "compress_io.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
|
|
||||||
/*----------------------
|
/*----------------------
|
||||||
* Compressor API
|
* Compressor API
|
||||||
|
@ -1,978 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* common.c
|
|
||||||
* catalog routines used by pg_dump
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* IDENTIFICATION
|
|
||||||
* src/bin/pg_dump/dumpcatalog.c
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#include "postgres_fe.h"
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "catalog/pg_class.h"
|
|
||||||
|
|
||||||
#include "pg_backup_archiver.h"
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Variables for mapping DumpId to DumpableObject
|
|
||||||
*/
|
|
||||||
static DumpableObject **dumpIdMap = NULL;
|
|
||||||
static int allocedDumpIds = 0;
|
|
||||||
static DumpId lastDumpId = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Variables for mapping CatalogId to DumpableObject
|
|
||||||
*/
|
|
||||||
static bool catalogIdMapValid = false;
|
|
||||||
static DumpableObject **catalogIdMap = NULL;
|
|
||||||
static int numCatalogIds = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These variables are static to avoid the notational cruft of having to pass
|
|
||||||
* them into findTableByOid() and friends. For each of these arrays, we
|
|
||||||
* build a sorted-by-OID index array immediately after it's built, and then
|
|
||||||
* we use binary search in findTableByOid() and friends. (qsort'ing the base
|
|
||||||
* arrays themselves would be simpler, but it doesn't work because pg_dump.c
|
|
||||||
* may have already established pointers between items.)
|
|
||||||
*/
|
|
||||||
static TableInfo *tblinfo;
|
|
||||||
static TypeInfo *typinfo;
|
|
||||||
static FuncInfo *funinfo;
|
|
||||||
static OprInfo *oprinfo;
|
|
||||||
static int numTables;
|
|
||||||
static int numTypes;
|
|
||||||
static int numFuncs;
|
|
||||||
static int numOperators;
|
|
||||||
static int numCollations;
|
|
||||||
static DumpableObject **tblinfoindex;
|
|
||||||
static DumpableObject **typinfoindex;
|
|
||||||
static DumpableObject **funinfoindex;
|
|
||||||
static DumpableObject **oprinfoindex;
|
|
||||||
static DumpableObject **collinfoindex;
|
|
||||||
|
|
||||||
|
|
||||||
static void flagInhTables(TableInfo *tbinfo, int numTables,
|
|
||||||
InhInfo *inhinfo, int numInherits);
|
|
||||||
static void flagInhAttrs(TableInfo *tblinfo, int numTables);
|
|
||||||
static DumpableObject **buildIndexArray(void *objArray, int numObjs,
|
|
||||||
Size objSize);
|
|
||||||
static int DOCatalogIdCompare(const void *p1, const void *p2);
|
|
||||||
static void findParentsByOid(TableInfo *self,
|
|
||||||
InhInfo *inhinfo, int numInherits);
|
|
||||||
static int strInArray(const char *pattern, char **arr, int arr_size);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getSchemaData
|
|
||||||
* Collect information about all potentially dumpable objects
|
|
||||||
*/
|
|
||||||
TableInfo *
|
|
||||||
getSchemaData(int *numTablesPtr)
|
|
||||||
{
|
|
||||||
ExtensionInfo *extinfo;
|
|
||||||
InhInfo *inhinfo;
|
|
||||||
CollInfo *collinfo;
|
|
||||||
int numNamespaces;
|
|
||||||
int numExtensions;
|
|
||||||
int numAggregates;
|
|
||||||
int numInherits;
|
|
||||||
int numRules;
|
|
||||||
int numProcLangs;
|
|
||||||
int numCasts;
|
|
||||||
int numOpclasses;
|
|
||||||
int numOpfamilies;
|
|
||||||
int numConversions;
|
|
||||||
int numTSParsers;
|
|
||||||
int numTSTemplates;
|
|
||||||
int numTSDicts;
|
|
||||||
int numTSConfigs;
|
|
||||||
int numForeignDataWrappers;
|
|
||||||
int numForeignServers;
|
|
||||||
int numDefaultACLs;
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading schemas\n");
|
|
||||||
getNamespaces(&numNamespaces);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getTables should be done as soon as possible, so as to minimize the
|
|
||||||
* window between starting our transaction and acquiring per-table locks.
|
|
||||||
* However, we have to do getNamespaces first because the tables get
|
|
||||||
* linked to their containing namespaces during getTables.
|
|
||||||
*/
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined tables\n");
|
|
||||||
tblinfo = getTables(&numTables);
|
|
||||||
tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading extensions\n");
|
|
||||||
extinfo = getExtensions(&numExtensions);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined functions\n");
|
|
||||||
funinfo = getFuncs(&numFuncs);
|
|
||||||
funinfoindex = buildIndexArray(funinfo, numFuncs, sizeof(FuncInfo));
|
|
||||||
|
|
||||||
/* this must be after getTables and getFuncs */
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined types\n");
|
|
||||||
typinfo = getTypes(&numTypes);
|
|
||||||
typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo));
|
|
||||||
|
|
||||||
/* this must be after getFuncs, too */
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading procedural languages\n");
|
|
||||||
getProcLangs(&numProcLangs);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined aggregate functions\n");
|
|
||||||
getAggregates(&numAggregates);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined operators\n");
|
|
||||||
oprinfo = getOperators(&numOperators);
|
|
||||||
oprinfoindex = buildIndexArray(oprinfo, numOperators, sizeof(OprInfo));
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined operator classes\n");
|
|
||||||
getOpclasses(&numOpclasses);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined operator families\n");
|
|
||||||
getOpfamilies(&numOpfamilies);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined text search parsers\n");
|
|
||||||
getTSParsers(&numTSParsers);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined text search templates\n");
|
|
||||||
getTSTemplates(&numTSTemplates);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined text search dictionaries\n");
|
|
||||||
getTSDictionaries(&numTSDicts);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined text search configurations\n");
|
|
||||||
getTSConfigurations(&numTSConfigs);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined foreign-data wrappers\n");
|
|
||||||
getForeignDataWrappers(&numForeignDataWrappers);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined foreign servers\n");
|
|
||||||
getForeignServers(&numForeignServers);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading default privileges\n");
|
|
||||||
getDefaultACLs(&numDefaultACLs);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined collations\n");
|
|
||||||
collinfo = getCollations(&numCollations);
|
|
||||||
collinfoindex = buildIndexArray(collinfo, numCollations, sizeof(CollInfo));
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading user-defined conversions\n");
|
|
||||||
getConversions(&numConversions);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading type casts\n");
|
|
||||||
getCasts(&numCasts);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading table inheritance information\n");
|
|
||||||
inhinfo = getInherits(&numInherits);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading rewrite rules\n");
|
|
||||||
getRules(&numRules);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Identify extension member objects and mark them as not to be dumped.
|
|
||||||
* This must happen after reading all objects that can be direct members
|
|
||||||
* of extensions, but before we begin to process table subsidiary objects.
|
|
||||||
*/
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "finding extension members\n");
|
|
||||||
getExtensionMembership(extinfo, numExtensions);
|
|
||||||
|
|
||||||
/* Link tables to parents, mark parents of target tables interesting */
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "finding inheritance relationships\n");
|
|
||||||
flagInhTables(tblinfo, numTables, inhinfo, numInherits);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading column info for interesting tables\n");
|
|
||||||
getTableAttrs(tblinfo, numTables);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "flagging inherited columns in subtables\n");
|
|
||||||
flagInhAttrs(tblinfo, numTables);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading indexes\n");
|
|
||||||
getIndexes(tblinfo, numTables);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading constraints\n");
|
|
||||||
getConstraints(tblinfo, numTables);
|
|
||||||
|
|
||||||
if (g_verbose)
|
|
||||||
write_msg(NULL, "reading triggers\n");
|
|
||||||
getTriggers(tblinfo, numTables);
|
|
||||||
|
|
||||||
*numTablesPtr = numTables;
|
|
||||||
return tblinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flagInhTables -
|
|
||||||
* Fill in parent link fields of every target table, and mark
|
|
||||||
* parents of target tables as interesting
|
|
||||||
*
|
|
||||||
* Note that only direct ancestors of targets are marked interesting.
|
|
||||||
* This is sufficient; we don't much care whether they inherited their
|
|
||||||
* attributes or not.
|
|
||||||
*
|
|
||||||
* modifies tblinfo
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
flagInhTables(TableInfo *tblinfo, int numTables,
|
|
||||||
InhInfo *inhinfo, int numInherits)
|
|
||||||
{
|
|
||||||
int i,
|
|
||||||
j;
|
|
||||||
int numParents;
|
|
||||||
TableInfo **parents;
|
|
||||||
|
|
||||||
for (i = 0; i < numTables; i++)
|
|
||||||
{
|
|
||||||
/* Sequences and views never have parents */
|
|
||||||
if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
|
|
||||||
tblinfo[i].relkind == RELKIND_VIEW)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Don't bother computing anything for non-target tables, either */
|
|
||||||
if (!tblinfo[i].dobj.dump)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Find all the immediate parent tables */
|
|
||||||
findParentsByOid(&tblinfo[i], inhinfo, numInherits);
|
|
||||||
|
|
||||||
/* Mark the parents as interesting for getTableAttrs */
|
|
||||||
numParents = tblinfo[i].numParents;
|
|
||||||
parents = tblinfo[i].parents;
|
|
||||||
for (j = 0; j < numParents; j++)
|
|
||||||
parents[j]->interesting = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flagInhAttrs -
|
|
||||||
* for each dumpable table in tblinfo, flag its inherited attributes
|
|
||||||
* so when we dump the table out, we don't dump out the inherited attributes
|
|
||||||
*
|
|
||||||
* modifies tblinfo
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
flagInhAttrs(TableInfo *tblinfo, int numTables)
|
|
||||||
{
|
|
||||||
int i,
|
|
||||||
j,
|
|
||||||
k;
|
|
||||||
|
|
||||||
for (i = 0; i < numTables; i++)
|
|
||||||
{
|
|
||||||
TableInfo *tbinfo = &(tblinfo[i]);
|
|
||||||
int numParents;
|
|
||||||
TableInfo **parents;
|
|
||||||
TableInfo *parent;
|
|
||||||
|
|
||||||
/* Sequences and views never have parents */
|
|
||||||
if (tbinfo->relkind == RELKIND_SEQUENCE ||
|
|
||||||
tbinfo->relkind == RELKIND_VIEW)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Don't bother computing anything for non-target tables, either */
|
|
||||||
if (!tbinfo->dobj.dump)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
numParents = tbinfo->numParents;
|
|
||||||
parents = tbinfo->parents;
|
|
||||||
|
|
||||||
if (numParents == 0)
|
|
||||||
continue; /* nothing to see here, move along */
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
|
||||||
* For each attr, check the parent info: if no parent has an attr
|
|
||||||
* with the same name, then it's not inherited. If there *is* an
|
|
||||||
* attr with the same name, then only dump it if:
|
|
||||||
*
|
|
||||||
* - it is NOT NULL and zero parents are NOT NULL
|
|
||||||
* OR
|
|
||||||
* - it has a default value AND the default value does not match
|
|
||||||
* all parent default values, or no parents specify a default.
|
|
||||||
*
|
|
||||||
* See discussion on -hackers around 2-Apr-2001.
|
|
||||||
*----------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
for (j = 0; j < tbinfo->numatts; j++)
|
|
||||||
{
|
|
||||||
bool foundAttr; /* Attr was found in a parent */
|
|
||||||
bool foundNotNull; /* Attr was NOT NULL in a parent */
|
|
||||||
bool defaultsMatch; /* All non-empty defaults match */
|
|
||||||
bool defaultsFound; /* Found a default in a parent */
|
|
||||||
AttrDefInfo *attrDef;
|
|
||||||
|
|
||||||
foundAttr = false;
|
|
||||||
foundNotNull = false;
|
|
||||||
defaultsMatch = true;
|
|
||||||
defaultsFound = false;
|
|
||||||
|
|
||||||
attrDef = tbinfo->attrdefs[j];
|
|
||||||
|
|
||||||
for (k = 0; k < numParents; k++)
|
|
||||||
{
|
|
||||||
int inhAttrInd;
|
|
||||||
|
|
||||||
parent = parents[k];
|
|
||||||
inhAttrInd = strInArray(tbinfo->attnames[j],
|
|
||||||
parent->attnames,
|
|
||||||
parent->numatts);
|
|
||||||
|
|
||||||
if (inhAttrInd != -1)
|
|
||||||
{
|
|
||||||
AttrDefInfo *inhDef = parent->attrdefs[inhAttrInd];
|
|
||||||
|
|
||||||
foundAttr = true;
|
|
||||||
foundNotNull |= parent->notnull[inhAttrInd];
|
|
||||||
if (inhDef != NULL)
|
|
||||||
{
|
|
||||||
defaultsFound = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If any parent has a default and the child doesn't,
|
|
||||||
* we have to emit an explicit DEFAULT NULL clause for
|
|
||||||
* the child, else the parent's default will win.
|
|
||||||
*/
|
|
||||||
if (attrDef == NULL)
|
|
||||||
{
|
|
||||||
attrDef = (AttrDefInfo *) pg_malloc(sizeof(AttrDefInfo));
|
|
||||||
attrDef->dobj.objType = DO_ATTRDEF;
|
|
||||||
attrDef->dobj.catId.tableoid = 0;
|
|
||||||
attrDef->dobj.catId.oid = 0;
|
|
||||||
AssignDumpId(&attrDef->dobj);
|
|
||||||
attrDef->adtable = tbinfo;
|
|
||||||
attrDef->adnum = j + 1;
|
|
||||||
attrDef->adef_expr = pg_strdup("NULL");
|
|
||||||
|
|
||||||
attrDef->dobj.name = pg_strdup(tbinfo->dobj.name);
|
|
||||||
attrDef->dobj.namespace = tbinfo->dobj.namespace;
|
|
||||||
|
|
||||||
attrDef->dobj.dump = tbinfo->dobj.dump;
|
|
||||||
|
|
||||||
attrDef->separate = false;
|
|
||||||
addObjectDependency(&tbinfo->dobj,
|
|
||||||
attrDef->dobj.dumpId);
|
|
||||||
|
|
||||||
tbinfo->attrdefs[j] = attrDef;
|
|
||||||
}
|
|
||||||
if (strcmp(attrDef->adef_expr, inhDef->adef_expr) != 0)
|
|
||||||
{
|
|
||||||
defaultsMatch = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Whenever there is a non-matching parent
|
|
||||||
* default, add a dependency to force the parent
|
|
||||||
* default to be dumped first, in case the
|
|
||||||
* defaults end up being dumped as separate
|
|
||||||
* commands. Otherwise the parent default will
|
|
||||||
* override the child's when it is applied.
|
|
||||||
*/
|
|
||||||
addObjectDependency(&attrDef->dobj,
|
|
||||||
inhDef->dobj.dumpId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Based on the scan of the parents, decide if we can rely on the
|
|
||||||
* inherited attr
|
|
||||||
*/
|
|
||||||
if (foundAttr) /* Attr was inherited */
|
|
||||||
{
|
|
||||||
/* Set inherited flag by default */
|
|
||||||
tbinfo->inhAttrs[j] = true;
|
|
||||||
tbinfo->inhAttrDef[j] = true;
|
|
||||||
tbinfo->inhNotNull[j] = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clear it if attr had a default, but parents did not, or
|
|
||||||
* mismatch
|
|
||||||
*/
|
|
||||||
if ((attrDef != NULL) && (!defaultsFound || !defaultsMatch))
|
|
||||||
{
|
|
||||||
tbinfo->inhAttrs[j] = false;
|
|
||||||
tbinfo->inhAttrDef[j] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clear it if NOT NULL and none of the parents were NOT NULL
|
|
||||||
*/
|
|
||||||
if (tbinfo->notnull[j] && !foundNotNull)
|
|
||||||
{
|
|
||||||
tbinfo->inhAttrs[j] = false;
|
|
||||||
tbinfo->inhNotNull[j] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear it if attr has local definition */
|
|
||||||
if (tbinfo->attislocal[j])
|
|
||||||
tbinfo->inhAttrs[j] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AssignDumpId
|
|
||||||
* Given a newly-created dumpable object, assign a dump ID,
|
|
||||||
* and enter the object into the lookup table.
|
|
||||||
*
|
|
||||||
* The caller is expected to have filled in objType and catId,
|
|
||||||
* but not any of the other standard fields of a DumpableObject.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
AssignDumpId(DumpableObject *dobj)
|
|
||||||
{
|
|
||||||
dobj->dumpId = ++lastDumpId;
|
|
||||||
dobj->name = NULL; /* must be set later */
|
|
||||||
dobj->namespace = NULL; /* may be set later */
|
|
||||||
dobj->dump = true; /* default assumption */
|
|
||||||
dobj->ext_member = false; /* default assumption */
|
|
||||||
dobj->dependencies = NULL;
|
|
||||||
dobj->nDeps = 0;
|
|
||||||
dobj->allocDeps = 0;
|
|
||||||
|
|
||||||
while (dobj->dumpId >= allocedDumpIds)
|
|
||||||
{
|
|
||||||
int newAlloc;
|
|
||||||
|
|
||||||
if (allocedDumpIds <= 0)
|
|
||||||
{
|
|
||||||
newAlloc = 256;
|
|
||||||
dumpIdMap = (DumpableObject **)
|
|
||||||
pg_malloc(newAlloc * sizeof(DumpableObject *));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newAlloc = allocedDumpIds * 2;
|
|
||||||
dumpIdMap = (DumpableObject **)
|
|
||||||
pg_realloc(dumpIdMap, newAlloc * sizeof(DumpableObject *));
|
|
||||||
}
|
|
||||||
memset(dumpIdMap + allocedDumpIds, 0,
|
|
||||||
(newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
|
|
||||||
allocedDumpIds = newAlloc;
|
|
||||||
}
|
|
||||||
dumpIdMap[dobj->dumpId] = dobj;
|
|
||||||
|
|
||||||
/* mark catalogIdMap invalid, but don't rebuild it yet */
|
|
||||||
catalogIdMapValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Assign a DumpId that's not tied to a DumpableObject.
|
|
||||||
*
|
|
||||||
* This is used when creating a "fixed" ArchiveEntry that doesn't need to
|
|
||||||
* participate in the sorting logic.
|
|
||||||
*/
|
|
||||||
DumpId
|
|
||||||
createDumpId(void)
|
|
||||||
{
|
|
||||||
return ++lastDumpId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the largest DumpId so far assigned
|
|
||||||
*/
|
|
||||||
DumpId
|
|
||||||
getMaxDumpId(void)
|
|
||||||
{
|
|
||||||
return lastDumpId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find a DumpableObject by dump ID
|
|
||||||
*
|
|
||||||
* Returns NULL for invalid ID
|
|
||||||
*/
|
|
||||||
DumpableObject *
|
|
||||||
findObjectByDumpId(DumpId dumpId)
|
|
||||||
{
|
|
||||||
if (dumpId <= 0 || dumpId >= allocedDumpIds)
|
|
||||||
return NULL; /* out of range? */
|
|
||||||
return dumpIdMap[dumpId];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find a DumpableObject by catalog ID
|
|
||||||
*
|
|
||||||
* Returns NULL for unknown ID
|
|
||||||
*
|
|
||||||
* We use binary search in a sorted list that is built on first call.
|
|
||||||
* If AssignDumpId() and findObjectByCatalogId() calls were freely intermixed,
|
|
||||||
* the code would work, but possibly be very slow. In the current usage
|
|
||||||
* pattern that does not happen, indeed we build the list at most twice.
|
|
||||||
*/
|
|
||||||
DumpableObject *
|
|
||||||
findObjectByCatalogId(CatalogId catalogId)
|
|
||||||
{
|
|
||||||
DumpableObject **low;
|
|
||||||
DumpableObject **high;
|
|
||||||
|
|
||||||
if (!catalogIdMapValid)
|
|
||||||
{
|
|
||||||
if (catalogIdMap)
|
|
||||||
free(catalogIdMap);
|
|
||||||
getDumpableObjects(&catalogIdMap, &numCatalogIds);
|
|
||||||
if (numCatalogIds > 1)
|
|
||||||
qsort((void *) catalogIdMap, numCatalogIds,
|
|
||||||
sizeof(DumpableObject *), DOCatalogIdCompare);
|
|
||||||
catalogIdMapValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We could use bsearch() here, but the notational cruft of calling
|
|
||||||
* bsearch is nearly as bad as doing it ourselves; and the generalized
|
|
||||||
* bsearch function is noticeably slower as well.
|
|
||||||
*/
|
|
||||||
if (numCatalogIds <= 0)
|
|
||||||
return NULL;
|
|
||||||
low = catalogIdMap;
|
|
||||||
high = catalogIdMap + (numCatalogIds - 1);
|
|
||||||
while (low <= high)
|
|
||||||
{
|
|
||||||
DumpableObject **middle;
|
|
||||||
int difference;
|
|
||||||
|
|
||||||
middle = low + (high - low) / 2;
|
|
||||||
/* comparison must match DOCatalogIdCompare, below */
|
|
||||||
difference = oidcmp((*middle)->catId.oid, catalogId.oid);
|
|
||||||
if (difference == 0)
|
|
||||||
difference = oidcmp((*middle)->catId.tableoid, catalogId.tableoid);
|
|
||||||
if (difference == 0)
|
|
||||||
return *middle;
|
|
||||||
else if (difference < 0)
|
|
||||||
low = middle + 1;
|
|
||||||
else
|
|
||||||
high = middle - 1;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find a DumpableObject by OID, in a pre-sorted array of one type of object
|
|
||||||
*
|
|
||||||
* Returns NULL for unknown OID
|
|
||||||
*/
|
|
||||||
static DumpableObject *
|
|
||||||
findObjectByOid(Oid oid, DumpableObject **indexArray, int numObjs)
|
|
||||||
{
|
|
||||||
DumpableObject **low;
|
|
||||||
DumpableObject **high;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the same as findObjectByCatalogId except we assume we need not
|
|
||||||
* look at table OID because the objects are all the same type.
|
|
||||||
*
|
|
||||||
* We could use bsearch() here, but the notational cruft of calling
|
|
||||||
* bsearch is nearly as bad as doing it ourselves; and the generalized
|
|
||||||
* bsearch function is noticeably slower as well.
|
|
||||||
*/
|
|
||||||
if (numObjs <= 0)
|
|
||||||
return NULL;
|
|
||||||
low = indexArray;
|
|
||||||
high = indexArray + (numObjs - 1);
|
|
||||||
while (low <= high)
|
|
||||||
{
|
|
||||||
DumpableObject **middle;
|
|
||||||
int difference;
|
|
||||||
|
|
||||||
middle = low + (high - low) / 2;
|
|
||||||
difference = oidcmp((*middle)->catId.oid, oid);
|
|
||||||
if (difference == 0)
|
|
||||||
return *middle;
|
|
||||||
else if (difference < 0)
|
|
||||||
low = middle + 1;
|
|
||||||
else
|
|
||||||
high = middle - 1;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build an index array of DumpableObject pointers, sorted by OID
|
|
||||||
*/
|
|
||||||
static DumpableObject **
|
|
||||||
buildIndexArray(void *objArray, int numObjs, Size objSize)
|
|
||||||
{
|
|
||||||
DumpableObject **ptrs;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
ptrs = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
|
|
||||||
for (i = 0; i < numObjs; i++)
|
|
||||||
ptrs[i] = (DumpableObject *) ((char *) objArray + i * objSize);
|
|
||||||
|
|
||||||
/* We can use DOCatalogIdCompare to sort since its first key is OID */
|
|
||||||
if (numObjs > 1)
|
|
||||||
qsort((void *) ptrs, numObjs, sizeof(DumpableObject *),
|
|
||||||
DOCatalogIdCompare);
|
|
||||||
|
|
||||||
return ptrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* qsort comparator for pointers to DumpableObjects
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
DOCatalogIdCompare(const void *p1, const void *p2)
|
|
||||||
{
|
|
||||||
const DumpableObject *obj1 = *(DumpableObject * const *) p1;
|
|
||||||
const DumpableObject *obj2 = *(DumpableObject * const *) p2;
|
|
||||||
int cmpval;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compare OID first since it's usually unique, whereas there will only be
|
|
||||||
* a few distinct values of tableoid.
|
|
||||||
*/
|
|
||||||
cmpval = oidcmp(obj1->catId.oid, obj2->catId.oid);
|
|
||||||
if (cmpval == 0)
|
|
||||||
cmpval = oidcmp(obj1->catId.tableoid, obj2->catId.tableoid);
|
|
||||||
return cmpval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build an array of pointers to all known dumpable objects
|
|
||||||
*
|
|
||||||
* This simply creates a modifiable copy of the internal map.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getDumpableObjects(DumpableObject ***objs, int *numObjs)
|
|
||||||
{
|
|
||||||
int i,
|
|
||||||
j;
|
|
||||||
|
|
||||||
*objs = (DumpableObject **)
|
|
||||||
pg_malloc(allocedDumpIds * sizeof(DumpableObject *));
|
|
||||||
j = 0;
|
|
||||||
for (i = 1; i < allocedDumpIds; i++)
|
|
||||||
{
|
|
||||||
if (dumpIdMap[i])
|
|
||||||
(*objs)[j++] = dumpIdMap[i];
|
|
||||||
}
|
|
||||||
*numObjs = j;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add a dependency link to a DumpableObject
|
|
||||||
*
|
|
||||||
* Note: duplicate dependencies are currently not eliminated
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
addObjectDependency(DumpableObject *dobj, DumpId refId)
|
|
||||||
{
|
|
||||||
if (dobj->nDeps >= dobj->allocDeps)
|
|
||||||
{
|
|
||||||
if (dobj->allocDeps <= 0)
|
|
||||||
{
|
|
||||||
dobj->allocDeps = 16;
|
|
||||||
dobj->dependencies = (DumpId *)
|
|
||||||
pg_malloc(dobj->allocDeps * sizeof(DumpId));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dobj->allocDeps *= 2;
|
|
||||||
dobj->dependencies = (DumpId *)
|
|
||||||
pg_realloc(dobj->dependencies,
|
|
||||||
dobj->allocDeps * sizeof(DumpId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dobj->dependencies[dobj->nDeps++] = refId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove a dependency link from a DumpableObject
|
|
||||||
*
|
|
||||||
* If there are multiple links, all are removed
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
removeObjectDependency(DumpableObject *dobj, DumpId refId)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < dobj->nDeps; i++)
|
|
||||||
{
|
|
||||||
if (dobj->dependencies[i] != refId)
|
|
||||||
dobj->dependencies[j++] = dobj->dependencies[i];
|
|
||||||
}
|
|
||||||
dobj->nDeps = j;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* findTableByOid
|
|
||||||
* finds the entry (in tblinfo) of the table with the given oid
|
|
||||||
* returns NULL if not found
|
|
||||||
*/
|
|
||||||
TableInfo *
|
|
||||||
findTableByOid(Oid oid)
|
|
||||||
{
|
|
||||||
return (TableInfo *) findObjectByOid(oid, tblinfoindex, numTables);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* findTypeByOid
|
|
||||||
* finds the entry (in typinfo) of the type with the given oid
|
|
||||||
* returns NULL if not found
|
|
||||||
*/
|
|
||||||
TypeInfo *
|
|
||||||
findTypeByOid(Oid oid)
|
|
||||||
{
|
|
||||||
return (TypeInfo *) findObjectByOid(oid, typinfoindex, numTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* findFuncByOid
|
|
||||||
* finds the entry (in funinfo) of the function with the given oid
|
|
||||||
* returns NULL if not found
|
|
||||||
*/
|
|
||||||
FuncInfo *
|
|
||||||
findFuncByOid(Oid oid)
|
|
||||||
{
|
|
||||||
return (FuncInfo *) findObjectByOid(oid, funinfoindex, numFuncs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* findOprByOid
|
|
||||||
* finds the entry (in oprinfo) of the operator with the given oid
|
|
||||||
* returns NULL if not found
|
|
||||||
*/
|
|
||||||
OprInfo *
|
|
||||||
findOprByOid(Oid oid)
|
|
||||||
{
|
|
||||||
return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* findCollationByOid
|
|
||||||
* finds the entry (in collinfo) of the collation with the given oid
|
|
||||||
* returns NULL if not found
|
|
||||||
*/
|
|
||||||
CollInfo *
|
|
||||||
findCollationByOid(Oid oid)
|
|
||||||
{
|
|
||||||
return (CollInfo *) findObjectByOid(oid, collinfoindex, numCollations);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* findParentsByOid
|
|
||||||
* find a table's parents in tblinfo[]
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
findParentsByOid(TableInfo *self,
|
|
||||||
InhInfo *inhinfo, int numInherits)
|
|
||||||
{
|
|
||||||
Oid oid = self->dobj.catId.oid;
|
|
||||||
int i,
|
|
||||||
j;
|
|
||||||
int numParents;
|
|
||||||
|
|
||||||
numParents = 0;
|
|
||||||
for (i = 0; i < numInherits; i++)
|
|
||||||
{
|
|
||||||
if (inhinfo[i].inhrelid == oid)
|
|
||||||
numParents++;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->numParents = numParents;
|
|
||||||
|
|
||||||
if (numParents > 0)
|
|
||||||
{
|
|
||||||
self->parents = (TableInfo **)
|
|
||||||
pg_malloc(sizeof(TableInfo *) * numParents);
|
|
||||||
j = 0;
|
|
||||||
for (i = 0; i < numInherits; i++)
|
|
||||||
{
|
|
||||||
if (inhinfo[i].inhrelid == oid)
|
|
||||||
{
|
|
||||||
TableInfo *parent;
|
|
||||||
|
|
||||||
parent = findTableByOid(inhinfo[i].inhparent);
|
|
||||||
if (parent == NULL)
|
|
||||||
{
|
|
||||||
write_msg(NULL, "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n",
|
|
||||||
inhinfo[i].inhparent,
|
|
||||||
self->dobj.name,
|
|
||||||
oid);
|
|
||||||
exit_nicely();
|
|
||||||
}
|
|
||||||
self->parents[j++] = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
self->parents = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* parseOidArray
|
|
||||||
* parse a string of numbers delimited by spaces into a character array
|
|
||||||
*
|
|
||||||
* Note: actually this is used for both Oids and potentially-signed
|
|
||||||
* attribute numbers. This should cause no trouble, but we could split
|
|
||||||
* the function into two functions with different argument types if it does.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
parseOidArray(const char *str, Oid *array, int arraysize)
|
|
||||||
{
|
|
||||||
int j,
|
|
||||||
argNum;
|
|
||||||
char temp[100];
|
|
||||||
char s;
|
|
||||||
|
|
||||||
argNum = 0;
|
|
||||||
j = 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
s = *str++;
|
|
||||||
if (s == ' ' || s == '\0')
|
|
||||||
{
|
|
||||||
if (j > 0)
|
|
||||||
{
|
|
||||||
if (argNum >= arraysize)
|
|
||||||
{
|
|
||||||
write_msg(NULL, "could not parse numeric array \"%s\": too many numbers\n", str);
|
|
||||||
exit_nicely();
|
|
||||||
}
|
|
||||||
temp[j] = '\0';
|
|
||||||
array[argNum++] = atooid(temp);
|
|
||||||
j = 0;
|
|
||||||
}
|
|
||||||
if (s == '\0')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(isdigit((unsigned char) s) || s == '-') ||
|
|
||||||
j >= sizeof(temp) - 1)
|
|
||||||
{
|
|
||||||
write_msg(NULL, "could not parse numeric array \"%s\": invalid character in number\n", str);
|
|
||||||
exit_nicely();
|
|
||||||
}
|
|
||||||
temp[j++] = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (argNum < arraysize)
|
|
||||||
array[argNum++] = InvalidOid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* strInArray:
|
|
||||||
* takes in a string and a string array and the number of elements in the
|
|
||||||
* string array.
|
|
||||||
* returns the index if the string is somewhere in the array, -1 otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
strInArray(const char *pattern, char **arr, int arr_size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < arr_size; i++)
|
|
||||||
{
|
|
||||||
if (strcmp(pattern, arr[i]) == 0)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Support for simple list operations
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
simple_oid_list_append(SimpleOidList *list, Oid val)
|
|
||||||
{
|
|
||||||
SimpleOidListCell *cell;
|
|
||||||
|
|
||||||
cell = (SimpleOidListCell *) pg_malloc(sizeof(SimpleOidListCell));
|
|
||||||
cell->next = NULL;
|
|
||||||
cell->val = val;
|
|
||||||
|
|
||||||
if (list->tail)
|
|
||||||
list->tail->next = cell;
|
|
||||||
else
|
|
||||||
list->head = cell;
|
|
||||||
list->tail = cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
simple_string_list_append(SimpleStringList *list, const char *val)
|
|
||||||
{
|
|
||||||
SimpleStringListCell *cell;
|
|
||||||
|
|
||||||
/* this calculation correctly accounts for the null trailing byte */
|
|
||||||
cell = (SimpleStringListCell *)
|
|
||||||
pg_malloc(sizeof(SimpleStringListCell) + strlen(val));
|
|
||||||
cell->next = NULL;
|
|
||||||
strcpy(cell->val, val);
|
|
||||||
|
|
||||||
if (list->tail)
|
|
||||||
list->tail->next = cell;
|
|
||||||
else
|
|
||||||
list->head = cell;
|
|
||||||
list->tail = cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
simple_oid_list_member(SimpleOidList *list, Oid val)
|
|
||||||
{
|
|
||||||
SimpleOidListCell *cell;
|
|
||||||
|
|
||||||
for (cell = list->head; cell; cell = cell->next)
|
|
||||||
{
|
|
||||||
if (cell->val == val)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
simple_string_list_member(SimpleStringList *list, const char *val)
|
|
||||||
{
|
|
||||||
SimpleStringListCell *cell;
|
|
||||||
|
|
||||||
for (cell = list->head; cell; cell = cell->next)
|
|
||||||
{
|
|
||||||
if (strcmp(cell->val, val) == 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
73
src/bin/pg_dump/dumpmem.c
Normal file
73
src/bin/pg_dump/dumpmem.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* dumpmem.c
|
||||||
|
* memory routines used by pg_dump and pg_restore (but not pg_dumpall
|
||||||
|
* because there is no failure location to report).
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/bin/pg_dump/dumpmem.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres_fe.h"
|
||||||
|
#include "pg_backup.h"
|
||||||
|
#include "dumpmem.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Safer versions of some standard C library functions. If an
|
||||||
|
* out-of-memory condition occurs, these functions will bail out
|
||||||
|
* safely; therefore, their return value is guaranteed to be non-NULL.
|
||||||
|
* We also report the program name and close the database connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
pg_strdup(const char *string)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
if (!string)
|
||||||
|
exit_horribly(NULL, NULL, "cannot duplicate null pointer\n");
|
||||||
|
tmp = strdup(string);
|
||||||
|
if (!tmp)
|
||||||
|
exit_horribly(NULL, NULL, "out of memory\n");
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
pg_malloc(size_t size)
|
||||||
|
{
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
tmp = malloc(size);
|
||||||
|
if (!tmp)
|
||||||
|
exit_horribly(NULL, NULL, "out of memory\n");
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
pg_calloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
tmp = calloc(nmemb, size);
|
||||||
|
if (!tmp)
|
||||||
|
exit_horribly(NULL, NULL, _("out of memory\n"));
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
pg_realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
tmp = realloc(ptr, size);
|
||||||
|
if (!tmp)
|
||||||
|
exit_horribly(NULL, NULL, _("out of memory\n"));
|
||||||
|
return tmp;
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* common.h
|
* dumpmem.h
|
||||||
* Common header file for the pg_dump, pg_dumpall, and pg_restore
|
* Common header file for the pg_dump and pg_restore
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* src/bin/pg_dump/common.h
|
* src/bin/pg_dump/dumpmem.h
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMMON_H
|
#ifndef DUMPMEM_H
|
||||||
#define COMMON_H
|
#define DUMPMEM_H
|
||||||
|
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
@ -21,4 +21,4 @@ extern void *pg_malloc(size_t size);
|
|||||||
extern void *pg_calloc(size_t nmemb, size_t size);
|
extern void *pg_calloc(size_t nmemb, size_t size);
|
||||||
extern void *pg_realloc(void *ptr, size_t size);
|
extern void *pg_realloc(void *ptr, size_t size);
|
||||||
|
|
||||||
#endif /* COMMON_H */
|
#endif /* DUMPMEM_H */
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include "parser/keywords.h"
|
#include "parser/keywords.h"
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pg_backup_db.h"
|
#include "pg_backup_db.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "compress_io.h"
|
#include "compress_io.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
|
|
||||||
/*--------
|
/*--------
|
||||||
* Routines in the format interface
|
* Routines in the format interface
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pg_backup_db.h"
|
#include "pg_backup_db.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "compress_io.h"
|
#include "compress_io.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
|
|
||||||
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
||||||
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include <unistd.h> /* for dup */
|
#include <unistd.h> /* for dup */
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "pg_backup.h"
|
#include "pg_backup.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "pg_backup_tar.h"
|
#include "pg_backup_tar.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
#include "libpq/libpq-fs.h"
|
#include "libpq/libpq-fs.h"
|
||||||
|
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
|
|
||||||
static const char *modulename = gettext_noop("sorter");
|
static const char *modulename = gettext_noop("sorter");
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "dumpmem.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user