diff options
Diffstat (limited to 'src/bin/pg_dump/common.c')
-rw-r--r-- | src/bin/pg_dump/common.c | 615 |
1 files changed, 283 insertions, 332 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 4188746471e..47692bdeac4 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -3,30 +3,15 @@ * common.c * common routines between pg_dump and pg4_dump * + * Since pg4_dump is long-dead code, there is no longer any useful distinction + * between this file and pg_dump.c. + * * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.63 2002/04/24 02:44:19 momjian 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. - * - * Modifications 14-Sep-2000 - pjw@rhyme.com.au - * - Added enum for findTypeByOid to specify how to handle OID and which - * string to return - formatted type, or base type. If the base type - * is returned then fmtId is called on the string. - * - * Modifications 4-Apr-2001 - pjw@rhyme.com.au - * - Changed flagInhAttrs to check all parent tables for overridden settings - * and set flags accordingly. - * - * BEWARE: Since fmtId uses a static buffer, using 'useBaseTypeName' on more - * than one call in a line will cause problems. + * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.64 2002/05/10 22:36:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -44,255 +29,48 @@ #include "strdup.h" #endif -static char **findParentsByOid(TableInfo *tbinfo, int numTables, - InhInfo *inhinfo, int numInherits, - const char *oid, - int *numParents, - int (**parentIndexes)[]); -static int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid); +static void findParentsByOid(TableInfo *tblinfo, int numTables, + InhInfo *inhinfo, int numInherits, + const char *oid, + int *numParentsPtr, int **parentIndexes); +static void flagInhTables(TableInfo *tbinfo, int numTables, + InhInfo *inhinfo, int numInherits); static void flagInhAttrs(TableInfo *tbinfo, int numTables, InhInfo *inhinfo, int numInherits); static int strInArray(const char *pattern, char **arr, int arr_size); -/* - * findTypeByOid - * given an oid of a type, return its typename - * - * Can return various special cases for oid 0. - * - * NOTE: should hash this, but just do linear search for now - */ - -char * -findTypeByOid(TypeInfo *tinfo, int numTypes, const char *oid, OidOptions opts) -{ - int i; - - if (strcmp(oid, "0") == 0) - { - if ((opts & zeroAsOpaque) != 0) - return g_opaque_type; - else if ((opts & zeroAsAny) != 0) - return "'any'"; - else if ((opts & zeroAsStar) != 0) - return "*"; - else if ((opts & zeroAsNone) != 0) - return "NONE"; - } - - for (i = 0; i < numTypes; i++) - { - if (strcmp(tinfo[i].oid, oid) == 0) - { - if ((opts & useBaseTypeName) != 0) - return (char *) fmtId(tinfo[i].typname, false); - else - return tinfo[i].typedefn; - } - } - - /* no suitable type name was found */ - return (NULL); -} - -/* - * 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, const 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 */ - write_msg(NULL, "failed sanity check, operator with oid %s not found\n", oid); - - /* no suitable operator name was found */ - return (NULL); -} - - -/* - * findParentsByOid - * given the oid of a class, return the names of its parent classes - * and assign the number of parents, and parent indexes to the last arguments. - * - * - * returns NULL if none - */ - -static char ** -findParentsByOid(TableInfo *tblinfo, int numTables, - InhInfo *inhinfo, int numInherits, const char *oid, - int *numParentsPtr, int (**parentIndexes)[]) -{ - int i, - j; - int parentInd, - selfInd; - char **result; - int numParents; - - numParents = 0; - for (i = 0; i < numInherits; i++) - { - if (strcmp(inhinfo[i].inhrelid, oid) == 0) - numParents++; - } - - *numParentsPtr = numParents; - - if (numParents > 0) - { - result = (char **) malloc(sizeof(char *) * numParents); - (*parentIndexes) = malloc(sizeof(int) * numParents); - j = 0; - for (i = 0; i < numInherits; i++) - { - if (strcmp(inhinfo[i].inhrelid, oid) == 0) - { - parentInd = findTableByOid(tblinfo, numTables, - inhinfo[i].inhparent); - if (parentInd < 0) - { - selfInd = findTableByOid(tblinfo, numTables, oid); - if (selfInd >= 0) - write_msg(NULL, "failed sanity check, parent oid %s of table %s (oid %s) not found\n", - inhinfo[i].inhparent, - tblinfo[selfInd].relname, - oid); - else - write_msg(NULL, "failed sanity check, parent oid %s of table (oid %s) not found\n", - inhinfo[i].inhparent, - oid); - - exit_nicely(); - } - (**parentIndexes)[j] = parentInd; - result[j++] = tblinfo[parentInd].relname; - } - } - return result; - } - else - { - (*parentIndexes) = NULL; - return NULL; - } -} - -/* - * parseNumericArray - * parse a string of numbers delimited by spaces into a character array - */ - -void -parseNumericArray(const char *str, char **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, "parseNumericArray: too many numbers\n"); - exit_nicely(); - } - temp[j] = '\0'; - array[argNum++] = strdup(temp); - j = 0; - } - if (s == '\0') - break; - } - else - { - if (!(isdigit((unsigned char) s) || s == '-') || - j >= sizeof(temp) - 1) - { - write_msg(NULL, "parseNumericArray: bogus number\n"); - exit_nicely(); - } - temp[j++] = s; - } - } - - while (argNum < arraysize) - array[argNum++] = strdup("0"); -} - - -/* - * 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; -} /* * dumpSchema: * we have a valid connection, we are now going to dump the schema * into the file - * */ TableInfo * dumpSchema(Archive *fout, int *numTablesPtr, - const char *tablename, const bool aclsSkip, - const bool oids, const bool schemaOnly, const bool dataOnly) { + int numNamespaces; int numTypes; int numFuncs; int numTables; int numInherits; int numAggregates; int numOperators; - int numIndexes; - TypeInfo *tinfo = NULL; - FuncInfo *finfo = NULL; - AggInfo *agginfo = NULL; - TableInfo *tblinfo = NULL; - InhInfo *inhinfo = NULL; - OprInfo *oprinfo = NULL; - IndInfo *indinfo = NULL; + NamespaceInfo *nsinfo; + TypeInfo *tinfo; + FuncInfo *finfo; + AggInfo *agginfo; + TableInfo *tblinfo; + InhInfo *inhinfo; + OprInfo *oprinfo; + + if (g_verbose) + write_msg(NULL, "reading namespaces\n"); + nsinfo = getNamespaces(&numNamespaces); if (g_verbose) write_msg(NULL, "reading user-defined types\n"); @@ -312,32 +90,40 @@ dumpSchema(Archive *fout, if (g_verbose) write_msg(NULL, "reading user-defined tables\n"); - tblinfo = getTables(&numTables, finfo, numFuncs, tablename); - - if (g_verbose) - write_msg(NULL, "reading index information\n"); - indinfo = getIndexes(&numIndexes); + tblinfo = getTables(&numTables); if (g_verbose) write_msg(NULL, "reading table inheritance information\n"); inhinfo = getInherits(&numInherits); + /* Link tables to parents, mark parents of target tables interesting */ if (g_verbose) - write_msg(NULL, "finding the column names and types for each table\n"); + 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, inhinfo, numInherits); - if (!tablename && !dataOnly) + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out database comment\n"); dumpDBComment(fout); } - if (!tablename && fout) + if (!dataOnly) + { + if (g_verbose) + write_msg(NULL, "dumping out user-defined namespaces\n"); + dumpNamespaces(fout, nsinfo, numNamespaces); + } + + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out user-defined types\n"); @@ -346,63 +132,102 @@ dumpSchema(Archive *fout, if (g_verbose) write_msg(NULL, "dumping out tables\n"); - - dumpTables(fout, tblinfo, numTables, tablename, + dumpTables(fout, tblinfo, numTables, aclsSkip, schemaOnly, dataOnly); - if (fout && !dataOnly) + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out indexes\n"); - dumpIndexes(fout, indinfo, numIndexes, tblinfo, numTables, tablename); + dumpIndexes(fout, tblinfo, numTables); } - if (!tablename && !dataOnly) + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out user-defined procedural languages\n"); - dumpProcLangs(fout, finfo, numFuncs, tinfo, numTypes); + dumpProcLangs(fout, finfo, numFuncs); } - if (!tablename && !dataOnly) + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out user-defined functions\n"); - dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes); + dumpFuncs(fout, finfo, numFuncs); } - if (!tablename && !dataOnly) + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out user-defined aggregate functions\n"); - dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes); + dumpAggs(fout, agginfo, numAggregates); } - if (!tablename && !dataOnly) + if (!dataOnly) { if (g_verbose) write_msg(NULL, "dumping out user-defined operators\n"); - dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes); + dumpOprs(fout, oprinfo, numOperators); } *numTablesPtr = numTables; - clearAggInfo(agginfo, numAggregates); - clearOprInfo(oprinfo, numOperators); - clearTypeInfo(tinfo, numTypes); - clearFuncInfo(finfo, numFuncs); - clearInhInfo(inhinfo, numInherits); - clearIndInfo(indinfo, numIndexes); 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 +/* flagInhTables - + * Fill in parentIndexes fields of every target table, and mark + * parents of target tables as interesting * - * initializes the parentRels field of each table + * 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; + int *parentIndexes; + + 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].dump) + continue; + + /* Find all the immediate parent tables */ + findParentsByOid(tblinfo, numTables, + inhinfo, numInherits, + tblinfo[i].oid, + &tblinfo[i].numParents, + &tblinfo[i].parentIndexes); + numParents = tblinfo[i].numParents; + parentIndexes = tblinfo[i].parentIndexes; + + /* Mark the parents as interesting for getTableAttrs */ + for (j = 0; j < numParents; j++) + { + int parentInd = parentIndexes[j]; + + tblinfo[parentInd].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, @@ -413,7 +238,8 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, k; int parentInd; int inhAttrInd; - int (*parentIndexes)[]; + int numParents; + int *parentIndexes; bool foundAttr; /* Attr was found in a parent */ bool foundNotNull; /* Attr was NOT NULL in a parent */ bool defaultsMatch; /* All non-empty defaults match */ @@ -421,23 +247,22 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, char *attrDef; char *inhDef; - /* - * 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--) + for (i = 0; i < numTables; i++) { - /* Sequences can never have parents, and attr info is undefined */ - if (tblinfo[i].relkind == RELKIND_SEQUENCE) + /* 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].dump) continue; - /* Get all the parents and their indexes. */ - tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables, - inhinfo, numInherits, - tblinfo[i].oid, - &tblinfo[i].numParents, - &parentIndexes); + numParents = tblinfo[i].numParents; + parentIndexes = tblinfo[i].parentIndexes; + + if (numParents == 0) + continue; /* nothing to see here, move along */ /* * For each attr, check the parent info: if no parent has an attr @@ -459,18 +284,9 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, attrDef = tblinfo[i].adef_expr[j]; - for (k = 0; k < tblinfo[i].numParents; k++) + for (k = 0; k < numParents; k++) { - parentInd = (*parentIndexes)[k]; - - if (parentInd < 0) - { - /* shouldn't happen unless findParentsByOid is broken */ - write_msg(NULL, "failed sanity check, table \"%s\" not found by flagInhAttrs\n", - tblinfo[i].parentRels[k]); - exit_nicely(); - }; - + parentInd = parentIndexes[k]; inhAttrInd = strInArray(tblinfo[i].attnames[j], tblinfo[parentInd].attnames, tblinfo[parentInd].numatts); @@ -479,7 +295,7 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, { foundAttr = true; foundNotNull |= tblinfo[parentInd].notnull[inhAttrInd]; - if (attrDef != NULL) /* It we have a default, + if (attrDef != NULL) /* If we have a default, * check parent */ { inhDef = tblinfo[parentInd].adef_expr[inhAttrInd]; @@ -488,10 +304,10 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, { defaultsFound = true; defaultsMatch &= (strcmp(attrDef, inhDef) == 0); - }; - }; - }; - }; + } + } + } + } /* * Based on the scan of the parents, decide if we can rely on @@ -500,9 +316,9 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, if (foundAttr) /* Attr was inherited */ { /* Set inherited flag by default */ - tblinfo[i].inhAttrs[j] = 1; - tblinfo[i].inhAttrDef[j] = 1; - tblinfo[i].inhNotNull[j] = 1; + tblinfo[i].inhAttrs[j] = true; + tblinfo[i].inhAttrDef[j] = true; + tblinfo[i].inhNotNull[j] = true; /* * Clear it if attr had a default, but parents did not, or @@ -510,8 +326,8 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, */ if ((attrDef != NULL) && (!defaultsFound || !defaultsMatch)) { - tblinfo[i].inhAttrs[j] = 0; - tblinfo[i].inhAttrDef[j] = 0; + tblinfo[i].inhAttrs[j] = false; + tblinfo[i].inhAttrDef[j] = false; } /* @@ -520,8 +336,8 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, */ if (tblinfo[i].notnull[j] && !foundNotNull) { - tblinfo[i].inhAttrs[j] = 0; - tblinfo[i].inhNotNull[j] = 0; + tblinfo[i].inhAttrs[j] = false; + tblinfo[i].inhNotNull[j] = false; } } } @@ -530,64 +346,199 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, /* - * findTableByName - * finds the index (in tblinfo) of the table with the given relname + * 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 -findTableByName(TableInfo *tblinfo, int numTables, const char *relname) +findTableByOid(TableInfo *tblinfo, int numTables, const char *oid) { int i; for (i = 0; i < numTables; i++) { - if (strcmp(tblinfo[i].relname, relname) == 0) + if (strcmp(tblinfo[i].oid, oid) == 0) return i; } return -1; } + /* - * findTableByOid - * finds the index (in tblinfo) of the table with the given oid + * findFuncByOid + * finds the index (in finfo) of the function with the given OID * returns -1 if not found * * NOTE: should hash this, but just do linear search for now */ - -static int -findTableByOid(TableInfo *tblinfo, int numTables, const char *oid) +int +findFuncByOid(FuncInfo *finfo, int numFuncs, const char *oid) { int i; - for (i = 0; i < numTables; i++) + for (i = 0; i < numFuncs; i++) { - if (strcmp(tblinfo[i].oid, oid) == 0) + if (strcmp(finfo[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 + * 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, const char *oid) +{ + int i; -int -findFuncByName(FuncInfo *finfo, int numFuncs, const char *name) + for (i = 0; i < numOprs; i++) + { + if (strcmp(oprinfo[i].oid, oid) == 0) + return oprinfo[i].oprname; + } + + /* should never get here */ + write_msg(NULL, "failed sanity check, operator with oid %s not found\n", oid); + + /* no suitable operator name was found */ + return (NULL); +} + + +/* + * findParentsByOid + * given the oid of a class, find its parent classes in tblinfo[] + * + * Returns the number of parents and their array indexes into the + * last two arguments. + */ + +static void +findParentsByOid(TableInfo *tblinfo, int numTables, + InhInfo *inhinfo, int numInherits, + const char *oid, + int *numParentsPtr, int **parentIndexes) +{ + int i, + j; + int parentInd, + selfInd; + int numParents; + + numParents = 0; + for (i = 0; i < numInherits; i++) + { + if (strcmp(inhinfo[i].inhrelid, oid) == 0) + numParents++; + } + + *numParentsPtr = numParents; + + if (numParents > 0) + { + *parentIndexes = (int *) malloc(sizeof(int) * numParents); + j = 0; + for (i = 0; i < numInherits; i++) + { + if (strcmp(inhinfo[i].inhrelid, oid) == 0) + { + parentInd = findTableByOid(tblinfo, numTables, + inhinfo[i].inhparent); + if (parentInd < 0) + { + selfInd = findTableByOid(tblinfo, numTables, oid); + if (selfInd >= 0) + write_msg(NULL, "failed sanity check, parent oid %s of table %s (oid %s) not found\n", + inhinfo[i].inhparent, + tblinfo[selfInd].relname, + oid); + else + write_msg(NULL, "failed sanity check, parent oid %s of table (oid %s) not found\n", + inhinfo[i].inhparent, + oid); + + exit_nicely(); + } + (*parentIndexes)[j++] = parentInd; + } + } + } + else + *parentIndexes = NULL; +} + +/* + * parseNumericArray + * parse a string of numbers delimited by spaces into a character array + */ + +void +parseNumericArray(const char *str, char **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, "parseNumericArray: too many numbers\n"); + exit_nicely(); + } + temp[j] = '\0'; + array[argNum++] = strdup(temp); + j = 0; + } + if (s == '\0') + break; + } + else + { + if (!(isdigit((unsigned char) s) || s == '-') || + j >= sizeof(temp) - 1) + { + write_msg(NULL, "parseNumericArray: bogus number\n"); + exit_nicely(); + } + temp[j++] = s; + } + } + + while (argNum < arraysize) + array[argNum++] = strdup("0"); +} + + +/* + * 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 < numFuncs; i++) + for (i = 0; i < arr_size; i++) { - if (strcmp(finfo[i].proname, name) == 0) + if (strcmp(pattern, arr[i]) == 0) return i; } return -1; |