postgresql/src/bin/pg_dump/common.c

414 lines
9.6 KiB
C

/*-------------------------------------------------------------------------
*
* common.c--
* common routines between pg_dump and pg4_dump
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.3 1996/07/22 08:36:59 scrappy Exp $
*
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
*
* - Fixed dumpTable output to output lengths for char and varchar types!
* - Added single. quote to twin single quote expansion for 'insert' string
* mode.
*
*-------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifdef PORTNAME_sparc_solaris
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include "postgres.h"
#include "libpq-fe.h"
#include "pg_dump.h"
/* dupstr : copies a string, while allocating space for it.
the CALLER is responsible for freeing the space
returns NULL if the argument is NULL*/
char*
dupstr(char *s)
{
char* result;
if (s == NULL)
return NULL;
result = (char*)malloc(strlen(s)+1);
strcpy(result, s);
return result;
}
/*
* findTypeByOid
* given an oid of a type, return its typename
*
* if oid is "0", return "opaque" -- this is a special case
*
* NOTE: should hash this, but just do linear search for now
*/
char*
findTypeByOid(TypeInfo* tinfo, int numTypes, char* oid)
{
int i;
if (strcmp(oid, "0") == 0) return g_opaque_type;
for (i=0;i<numTypes;i++) {
if (strcmp(tinfo[i].oid, oid) == 0)
return tinfo[i].typname;
}
/* should never get here */
fprintf(stderr,"failed sanity check, type with oid %s was not found\n",
oid);
exit(2);
}
/*
* findOprByOid
* given the oid of an operator, return the name of the operator
*
*
* NOTE: should hash this, but just do linear search for now
*
*/
char*
findOprByOid(OprInfo *oprinfo, int numOprs, char *oid)
{
int i;
for (i=0;i<numOprs;i++) {
if (strcmp(oprinfo[i].oid, oid) == 0)
return oprinfo[i].oprname;
}
/* should never get here */
fprintf(stderr,"failed sanity check, opr with oid %s was not found\n",
oid);
exit(2);
}
/*
* findParentsByOid --
* given the oid of a class, return the names of its parent classes
* and assign the number of parents to the last argument.
*
*
* returns NULL if none
*/
char**
findParentsByOid(TableInfo* tblinfo, int numTables,
InhInfo* inhinfo, int numInherits, char *oid,
int *numParentsPtr)
{
int i,j;
int parentInd;
char** result;
int numParents;
numParents = 0;
for (i=0;i<numInherits;i++) {
if ( strcmp(inhinfo[i].inhrel, oid) == 0) {
numParents++;
}
}
*numParentsPtr = numParents;
if (numParents > 0) {
result = (char**)malloc(sizeof(char*) * numParents);
j = 0;
for (i=0;i<numInherits;i++) {
if ( strcmp(inhinfo[i].inhrel, oid) == 0) {
parentInd = findTableByOid(tblinfo, numTables,
inhinfo[i].inhparent);
result[j++] = tblinfo[parentInd].relname;
}
}
return result;
}
else
return NULL;
}
/*
* parseArgTypes
* parse a string of eight numbers delimited by spaces
* into a character array
*/
void
parseArgTypes(char **argtypes, char* str)
{
int j, argNum;
char temp[100];
char s;
argNum = 0;
j = 0;
while ( (s = *str) != '\0') {
if (s == ' ') {
temp[j] = '\0';
argtypes[argNum] = dupstr(temp);
argNum++;
j = 0;
} else {
temp[j] = s;
j++;
}
str++;
}
if (j != 0) {
temp[j] = '\0';
argtypes[argNum] = dupstr(temp);
}
}
/*
* 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
*
*/
int
strInArray(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;
}
/*
* dumpSchema:
* we have a valid connection, we are now going to dump the schema
* into the file
*
*/
TableInfo *
dumpSchema(FILE *fout, int *numTablesPtr, char *tablename)
{
int numTypes;
int numFuncs;
int numTables;
int numInherits;
int numIndices;
int numAggregates;
int numOperators;
TypeInfo *tinfo;
FuncInfo *finfo;
AggInfo *agginfo;
TableInfo *tblinfo;
InhInfo *inhinfo;
IndInfo *indinfo;
OprInfo *oprinfo;
if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n",
g_comment_start, g_comment_end);
tinfo = getTypes(&numTypes);
if (g_verbose) fprintf(stderr,"%s reading user-defined functions %s\n",
g_comment_start, g_comment_end);
finfo = getFuncs(&numFuncs);
if (g_verbose) fprintf(stderr,"%s reading user-defined aggregates %s\n",
g_comment_start, g_comment_end);
agginfo = getAggregates(&numAggregates);
if (g_verbose) fprintf(stderr,"%s reading user-defined operators %s\n",
g_comment_start, g_comment_end);
oprinfo = getOperators(&numOperators);
if (g_verbose) fprintf(stderr,"%s reading user-defined tables %s\n",
g_comment_start, g_comment_end);
tblinfo = getTables(&numTables);
if (g_verbose) fprintf(stderr,"%s reading table inheritance information %s\n",
g_comment_start, g_comment_end);
inhinfo = getInherits(&numInherits);
if (g_verbose) fprintf(stderr, "%s finding the attribute names and types for each table %s\n",
g_comment_start, g_comment_end);
getTableAttrs(tblinfo, numTables);
if (g_verbose) fprintf(stderr, "%s flagging inherited attributes in subtables %s\n",
g_comment_start, g_comment_end);
flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
if (g_verbose) fprintf(stderr,"%s reading indices information %s\n",
g_comment_start, g_comment_end);
indinfo = getIndices(&numIndices);
if (!tablename && fout) {
if (g_verbose) fprintf(stderr,"%s dumping out user-defined types %s\n",
g_comment_start, g_comment_end);
dumpTypes(fout, finfo, numFuncs, tinfo, numTypes);
}
if (fout) {
if (g_verbose) fprintf(stderr,"%s dumping out tables %s\n",
g_comment_start, g_comment_end);
dumpTables(fout, tblinfo, numTables, inhinfo, numInherits,
tinfo, numTypes, tablename);
}
if (!tablename && fout) {
if (g_verbose) fprintf(stderr,"%s dumping out user-defined functions %s\n",
g_comment_start, g_comment_end);
dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes);
}
if (!tablename && fout) {
if (g_verbose) fprintf(stderr,"%s dumping out user-defined functions %s\n",
g_comment_start, g_comment_end);
dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes);
}
if (!tablename && fout) {
if (g_verbose) fprintf(stderr,"%s dumping out user-defined operators %s\n",
g_comment_start, g_comment_end);
dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes);
}
if (fout) {
if (g_verbose) fprintf(stderr,"%s dumping out indices %s\n",
g_comment_start, g_comment_end);
dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
}
*numTablesPtr = numTables;
return tblinfo;
}
/* flagInhAttrs -
* for each table in tblinfo, flag its inherited attributes
* so when we dump the table out, we don't dump out the inherited attributes
*
* initializes the parentRels field of each table
*
* modifies tblinfo
*
*/
void
flagInhAttrs(TableInfo* tblinfo, int numTables,
InhInfo* inhinfo, int numInherits)
{
int i,j,k;
int parentInd;
/* we go backwards because the tables in tblinfo are in OID
order, meaning the subtables are after the parent tables
we flag inherited attributes from child tables first */
for (i = numTables-1; i >= 0; i--) {
tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables,
inhinfo, numInherits,
tblinfo[i].oid,
&tblinfo[i].numParents);
for (k=0;k<tblinfo[i].numParents;k++) {
parentInd = findTableByName(tblinfo, numTables,
tblinfo[i].parentRels[k]);
for (j=0;j<tblinfo[i].numatts;j++) {
if (strInArray(tblinfo[i].attnames[j],
tblinfo[parentInd].attnames,
tblinfo[parentInd].numatts) != -1) {
tblinfo[i].inhAttrs[j] = 1;
}
}
}
}
}
/*
* findTableByName
* finds the index (in tblinfo) of the table with the given relname
* returns -1 if not found
*
* NOTE: should hash this, but just do linear search for now
*/
int
findTableByName(TableInfo* tblinfo, int numTables, char* relname)
{
int i;
for (i=0;i<numTables;i++) {
if (strcmp(tblinfo[i].relname, relname) == 0)
return i;
}
return -1;
}
/*
* findTableByOid
* finds the index (in tblinfo) of the table with the given oid
* returns -1 if not found
*
* NOTE: should hash this, but just do linear search for now
*/
int
findTableByOid(TableInfo* tblinfo, int numTables, char* oid)
{
int i;
for (i=0;i<numTables;i++) {
if (strcmp(tblinfo[i].oid, oid) == 0)
return i;
}
return -1;
}
/*
* findFuncByName
* finds the index (in finfo) of the function with the given name
* returns -1 if not found
*
* NOTE: should hash this, but just do linear search for now
*/
int
findFuncByName(FuncInfo* finfo, int numFuncs, char* name)
{
int i;
for (i=0;i<numFuncs;i++) {
if (strcmp(finfo[i].proname, name) == 0)
return i;
}
return -1;
}
/*
* isArchiveName
*
* returns true if the relation name is an archive name, false otherwise
*/
int
isArchiveName(char* relname)
{
return (strlen(relname) > 1 && relname[1] == ',');
}