From d390886c1bee2537203bd66d6be0eabfa48e4a51 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Sat, 24 Aug 1996 20:54:52 +0000 Subject: [PATCH] The patch does several things: It adds a WITH OIDS option to the copy command, which allows dumping and loading of oids. If a copy command tried to load in an oid that is greater than its current system max oid, the system max oid is incremented. No checking is done to see if other backends are running and have cached oids. pg_dump as its first step when using the -o (oid) option, will copy in a dummy row to set the system max oid value so as rows are loaded in, they are certain to be lower than the system oid. pg_dump now creates indexes at the end to speed loading Submitted by: Bruce Momjian --- src/backend/access/heap/heapam.c | 4 +- src/backend/access/transam.h | 11 ++- src/backend/access/transam/varsup.c | 69 ++++++++++++++--- src/backend/commands/copy.c | 52 ++++++++++--- src/backend/commands/copy.h | 4 +- src/backend/nodes/parsenodes.h | 3 +- src/backend/parser/gram.y | 25 +++--- src/backend/parser/keywords.c | 3 +- src/backend/tcop/utility.c | 6 +- src/bin/pg_dump/common.c | 37 ++++++--- src/bin/pg_dump/pg_dump.c | 113 +++++++++++++++++++++------- src/bin/pg_dump/pg_dump.h | 4 +- src/bin/psql/psqlHelp.h | 6 +- 13 files changed, 254 insertions(+), 83 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4bf31efd83..f472c7df83 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.1.1.1 1996/07/09 06:21:11 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.1.1.1.2.1 1996/08/24 20:53:09 scrappy Exp $ * * * INTERFACE ROUTINES @@ -1093,6 +1093,8 @@ heap_insert(Relation relation, HeapTuple tup) tup->t_oid = newoid(); LastOidProcessed = tup->t_oid; } + else + CheckMaxObjectId(tup->t_oid); TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin)); tup->t_cmin = GetCurrentCommandId(); diff --git a/src/backend/access/transam.h b/src/backend/access/transam.h index 0f5a9724dc..3f8f5ebb37 100644 --- a/src/backend/access/transam.h +++ b/src/backend/access/transam.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: transam.h,v 1.1.1.1 1996/07/09 06:21:09 scrappy Exp $ + * $Id: transam.h,v 1.1.1.1.2.1 1996/08/24 20:52:17 scrappy Exp $ * * NOTES * Transaction System Version 101 now support proper oid @@ -46,6 +46,14 @@ typedef unsigned char XidStatus; /* (2 bits) */ +/* ---------- + * note: we reserve the first 16384 object ids for internal use. + * oid's less than this appear in the .bki files. the choice of + * 16384 is completely arbitrary. + * ---------- + */ +#define BootstrapObjectIdData 16384 + /* ---------------- * BitIndexOf computes the index of the Nth xid on a given block * ---------------- @@ -182,6 +190,7 @@ extern void GetNewTransactionId(TransactionId *xid); extern void UpdateLastCommittedXid(TransactionId xid); extern void GetNewObjectIdBlock(Oid *oid_return, int oid_block_size); extern void GetNewObjectId(Oid *oid_return); +extern void CheckMaxObjectId(Oid assigned_oid); /* ---------------- * global variable extern declarations diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index a53cc7d35b..ef875e180b 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.1.1.1 1996/07/09 06:21:13 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.1.1.1.2.1 1996/08/24 20:53:26 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -28,14 +28,6 @@ #include "catalog/catname.h" -/* ---------- - * note: we reserve the first 16384 object ids for internal use. - * oid's less than this appear in the .bki files. the choice of - * 16384 is completely arbitrary. - * ---------- - */ -#define BootstrapObjectIdData 16384 - /* --------------------- * spin lock for oid generation * --------------------- @@ -604,3 +596,62 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */ next_prefetched_oid++; prefetched_oid_count--; } + +void +CheckMaxObjectId(Oid assigned_oid) +{ +Oid pass_oid; + + + if (prefetched_oid_count == 0) /* make sure next/max is set, or reload */ + GetNewObjectId(&pass_oid); + + /* ---------------- + * If we are below prefetched limits, do nothing + * ---------------- + */ + + if (assigned_oid < next_prefetched_oid) + return; + + /* ---------------- + * If we are here, we are coming from a 'copy from' with oid's + * + * If we are in the prefetched oid range, just bump it up + * + * ---------------- + */ + + if (assigned_oid <= next_prefetched_oid + prefetched_oid_count - 1) + { + prefetched_oid_count -= assigned_oid - next_prefetched_oid + 1; + next_prefetched_oid = assigned_oid + 1; + return; + } + + /* ---------------- + * We have exceeded the prefetch oid range + * + * We should lock the database and kill all other backends + * but we are loading oid's that we can not guarantee are unique + * anyway, so we must rely on the user + * + * + * We now: + * set the variable relation with the new max oid + * force the backend to reload its oid cache + * + * We use the oid cache so we don't have to update the variable + * relation every time + * + * ---------------- + */ + + pass_oid = assigned_oid; + VariableRelationPutNextOid(&pass_oid); /* not modified */ + prefetched_oid_count = 0; /* force reload */ + pass_oid = assigned_oid; + GetNewObjectId(&pass_oid); /* throw away returned oid */ + +} + diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index f6815a3631..296f0cd5c7 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.2 1996/07/23 02:23:15 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.2.2.1 1996/08/24 20:53:39 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -22,11 +22,13 @@ #include "catalog/pg_index.h" #include "catalog/index.h" +#include "storage/bufmgr.h" #include "access/heapam.h" #include "access/htup.h" #include "access/itup.h" #include "access/relscan.h" #include "access/funcindex.h" +#include "access/transam.h" #include "access/tupdesc.h" #include "nodes/execnodes.h" #include "nodes/plannodes.h" @@ -50,8 +52,8 @@ static bool reading_from_input = false; /* non-export function prototypes */ -static void CopyTo(Relation rel, bool binary, FILE *fp, char *delim); -static void CopyFrom(Relation rel, bool binary, FILE *fp, char *delim); +static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim); +static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim); static Oid GetOutputFunction(Oid type); static Oid GetTypeElement(Oid type); static Oid GetInputFunction(Oid type); @@ -59,14 +61,14 @@ static Oid IsTypeByVal(Oid type); static void GetIndexRelations(Oid main_relation_oid, int *n_indices, Relation **index_rels); -static char *CopyReadAttribute(int attno, FILE *fp, bool *isnull, char *delim); +static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim); static void CopyAttributeOut(FILE *fp, char *string, char *delim); static int CountTuples(Relation relation); extern FILE *Pfout, *Pfin; void -DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename, +DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, char *filename, char *delim) { FILE *fp; @@ -86,7 +88,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename, if (fp == NULL) { elog(WARN, "COPY: file %s could not be open for reading", filename); } - CopyFrom(rel, binary, fp, delim); + CopyFrom(rel, binary, oids, fp, delim); }else { mode_t oumask = umask((mode_t) 0); @@ -102,7 +104,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename, if (fp == NULL) { elog(WARN, "COPY: file %s could not be open for writing", filename); } - CopyTo(rel, binary, fp, delim); + CopyTo(rel, binary, oids, fp, delim); } if (!pipe) { fclose(fp); @@ -113,7 +115,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename, } static void -CopyTo(Relation rel, bool binary, FILE *fp, char *delim) +CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim) { HeapTuple tuple; HeapScanDesc scandesc; @@ -159,6 +161,11 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim) for (tuple = heap_getnext(scandesc, 0, NULL); tuple != NULL; tuple = heap_getnext(scandesc, 0, NULL)) { + + if (oids && !binary) { + fputs(oidout(tuple->t_oid),fp); + fputc(delim[0], fp); + } for (i = 0; i < attr_count; i++) { value = (Datum) @@ -194,6 +201,9 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim) length = tuple->t_len - tuple->t_hoff; fwrite(&length, sizeof(int32), 1, fp); + if (oids) + fwrite((char *) &tuple->t_oid, sizeof(int32), 1, fp); + fwrite(&null_ct, sizeof(int32), 1, fp); if (null_ct > 0) { for (i = 0; i < attr_count; i++) { @@ -219,7 +229,7 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim) } static void -CopyFrom(Relation rel, bool binary, FILE *fp, char *delim) +CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim) { HeapTuple tuple; IndexTuple ituple; @@ -257,7 +267,8 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim) int n_indices; InsertIndexResult indexRes; TupleDesc tupDesc; - + Oid loaded_oid; + tupDesc = RelationGetTupleDescriptor(rel); attr = tupDesc->attrs; attr_count = tupDesc->natts; @@ -371,8 +382,18 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim) while (!done) { if (!binary) { + if (oids) { + string = CopyReadAttribute(fp, &isnull, delim); + if (string == NULL) + done = 1; + else { + loaded_oid = oidin(string); + if (loaded_oid < BootstrapObjectIdData) + elog(WARN, "COPY TEXT: Invalid Oid"); + } + } for (i = 0; i < attr_count && !done; i++) { - string = CopyReadAttribute(i, fp, &isnull, delim); + string = CopyReadAttribute(fp, &isnull, delim); if (isnull) { values[i] = PointerGetDatum(NULL); nulls[i] = 'n'; @@ -398,6 +419,11 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim) if (feof(fp)) { done = 1; }else { + if (oids) { + fread(&loaded_oid, sizeof(int32), 1, fp); + if (loaded_oid < BootstrapObjectIdData) + elog(WARN, "COPY BINARY: Invalid Oid"); + } fread(&null_ct, sizeof(int32), 1, fp); if (null_ct > 0) { for (i = 0; i < null_ct; i++) { @@ -473,6 +499,8 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim) tupDesc = CreateTupleDesc(attr_count, attr); tuple = heap_formtuple(tupDesc, values, nulls); + if (oids) + tuple->t_oid = loaded_oid; heap_insert(rel, tuple); if (has_index) { @@ -696,7 +724,7 @@ inString(char c, char* s) */ static char * -CopyReadAttribute(int attno, FILE *fp, bool *isnull, char *delim) +CopyReadAttribute(FILE *fp, bool *isnull, char *delim) { static char attribute[EXT_ATTLEN]; char c; diff --git a/src/backend/commands/copy.h b/src/backend/commands/copy.h index ccd2955562..dd44f781a4 100644 --- a/src/backend/commands/copy.h +++ b/src/backend/commands/copy.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: copy.h,v 1.1.1.1 1996/07/09 06:21:19 scrappy Exp $ + * $Id: copy.h,v 1.1.1.1.2.1 1996/08/24 20:53:43 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ #include "postgres.h" -void DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename, +void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, char *filename, char *delim); #endif /* COPY_H */ diff --git a/src/backend/nodes/parsenodes.h b/src/backend/nodes/parsenodes.h index bc994bb1a0..b654948a04 100644 --- a/src/backend/nodes/parsenodes.h +++ b/src/backend/nodes/parsenodes.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $ + * $Id: parsenodes.h,v 1.1.1.1.2.1 1996/08/24 20:53:55 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -114,6 +114,7 @@ typedef struct CopyStmt { NodeTag type; bool binary; /* is a binary copy? */ char *relname; /* the relation to copy */ + bool oids; /* copy oid's? */ int direction; /* TO or FROM */ char *filename; /* if NULL, use stdin/stdout */ char *delimiter; /* delimiter character, \t by default*/ diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 4fbfbbc8ae..7c85373dc4 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.2 1996/07/23 02:23:33 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.2.2.1 1996/08/24 20:54:06 scrappy Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -122,14 +122,14 @@ static Node *makeA_Expr(int op, char *opname, Node *lexpr, Node *rexpr); %type queryblock, relation_name_list, OptTableElementList, tableElementList, OptInherit, definition, - opt_with, def_args, def_name_list, func_argtypes, oper_argtypes, + opt_with_func, def_args, def_name_list, func_argtypes, oper_argtypes, OptStmtList, OptStmtBlock, opt_column_list, columnList, exprList, sort_clause, sortby_list, index_params, name_list, from_clause, from_list, opt_array_bounds, nest_array_bounds, expr_list, attrs, res_target_list, res_target_list2, def_list, opt_indirection, group_clause, groupby_list, explain_options -%type opt_inh_star, opt_binary, opt_instead +%type opt_inh_star, opt_binary, opt_instead, opt_with_copy %type copy_dirn, archive_type, OptArchiveType, OptArchiveLocation, def_type, opt_direction, remove_type, opt_column, event @@ -176,7 +176,7 @@ static Node *makeA_Expr(int op, char *opname, Node *lexpr, Node *rexpr); HAVING, HEAVY, IN, INDEX, INHERITS, INSERT, INSTEAD, INTO, ISNULL, LANGUAGE, LIGHT, LISTEN, LOAD, MERGE, MOVE, NEW, NONE, NOT, NOTHING, NOTIFY, NOTNULL, - ON, OPERATOR, OPTION, OR, ORDER, + OIDS, ON, OPERATOR, OPTION, OR, ORDER, PNULL, PRIVILEGES, PUBLIC, PURGE, P_TYPE, RENAME, REPLACE, RETRIEVE, RETURNS, REVOKE, ROLLBACK, RULE, SELECT, SET, SETOF, STDIN, STDOUT, STORE, @@ -305,14 +305,15 @@ ClosePortalStmt: CLOSE opt_id * *****************************************************************************/ -CopyStmt: COPY opt_binary relation_name copy_dirn copy_file_name copy_delimiter +CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter { CopyStmt *n = makeNode(CopyStmt); n->binary = $2; n->relname = $3; - n->direction = $4; - n->filename = $5; - n->delimiter = $6; + n->oids = $4; + n->direction = $5; + n->filename = $6; + n->delimiter = $7; $$ = (Node *)n; } ; @@ -337,6 +338,10 @@ opt_binary: BINARY { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; +opt_with_copy: WITH OIDS { $$ = TRUE; } + | /* EMPTY */ { $$ = FALSE; } + ; + /* * the default copy delimiter is tab but the user can configure it */ @@ -720,7 +725,7 @@ RecipeStmt: EXECUTE RECIPE recipe_name *****************************************************************************/ ProcedureStmt: CREATE FUNCTION def_name def_args - RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst + RETURNS def_arg opt_with_func AS Sconst LANGUAGE Sconst { ProcedureStmt *n = makeNode(ProcedureStmt); n->funcname = $3; @@ -732,7 +737,7 @@ ProcedureStmt: CREATE FUNCTION def_name def_args $$ = (Node *)n; }; -opt_with: WITH definition { $$ = $2; } +opt_with_func: WITH definition { $$ = $2; } | /* EMPTY */ { $$ = NIL; } ; diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index b6cd549bf9..4424eda246 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.1.1.1 1996/07/09 06:21:40 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.1.1.1.2.1 1996/08/24 20:54:11 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -102,6 +102,7 @@ static ScanKeyword ScanKeywords[] = { { "notify", NOTIFY }, { "notnull", NOTNULL }, { "null", PNULL }, + { "oids", OIDS }, { "on", ON }, { "operator", OPERATOR }, { "option", OPTION }, diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index e12d18b91e..b789e4abac 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.1.1.1 1996/07/09 06:22:00 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.1.1.1.2.1 1996/08/24 20:54:23 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -199,6 +199,7 @@ ProcessUtility(Node *parsetree, char *filename; char *delim; bool isBinary; + bool isOids; bool isFrom; bool pipe = false; @@ -207,6 +208,7 @@ ProcessUtility(Node *parsetree, relname = stmt->relname; isBinary = stmt->binary; + isOids = stmt->oids; isFrom = (bool)(stmt->direction == FROM); filename = stmt->filename; @@ -234,7 +236,7 @@ ProcessUtility(Node *parsetree, if (pipe && IsUnderPostmaster) dest = CopyEnd; - DoCopy(relname, isBinary, isFrom, pipe, filename, delim); + DoCopy(relname, isBinary, isOids, isFrom, pipe, filename, delim); } break; diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index bcc84f21f7..5cf29b9c84 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.3 1996/07/22 08:36:59 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.3.2.1 1996/08/24 20:54:38 scrappy Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -210,7 +210,6 @@ dumpSchema(FILE *fout, int *numTablesPtr, char *tablename) int numFuncs; int numTables; int numInherits; - int numIndices; int numAggregates; int numOperators; TypeInfo *tinfo; @@ -218,7 +217,6 @@ dumpSchema(FILE *fout, int *numTablesPtr, char *tablename) AggInfo *agginfo; TableInfo *tblinfo; InhInfo *inhinfo; - IndInfo *indinfo; OprInfo *oprinfo; if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n", @@ -253,10 +251,6 @@ if (g_verbose) fprintf(stderr, "%s flagging inherited attributes in subtables %s 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); @@ -288,16 +282,35 @@ if (!tablename && fout) { 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; } +/* + * dumpSchemaIdx: + * dump indexes at the end for performance + * + */ + +extern void +dumpSchemaIdx(FILE *fout, int *numTablesPtr, char *tablename, + TableInfo* tblinfo, int numTables) +{ + int numIndices; + IndInfo *indinfo; + + if (g_verbose) fprintf(stderr,"%s reading indices information %s\n", + g_comment_start, g_comment_end); + indinfo = getIndices(&numIndices); + + 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); + } +} + /* 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 diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 85943a88b1..63c76497c3 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -20,7 +20,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.5 1996/07/31 06:09:46 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.5.2.1 1996/08/24 20:54:40 scrappy Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * @@ -80,14 +80,15 @@ usage(char* progname) fprintf(stderr, "%s - version 1.13.dhb.2\n\n",progname); fprintf(stderr, "usage: %s [options] [dbname]\n",progname); fprintf(stderr, "\t -f filename \t\t script output filename\n"); - fprintf(stderr, "\t -d[a] \t\t dump data as proper insert strings\n"); - fprintf(stderr, "\t \t\t (if 'a' then attribute names also)\n"); fprintf(stderr, "\t -H hostname \t\t server host name\n"); fprintf(stderr, "\t -p port \t\t server port number\n"); fprintf(stderr, "\t -v \t\t verbose\n"); + fprintf(stderr, "\t -d[a] \t\t dump data as proper insert strings\n"); + fprintf(stderr, "\t \t\t (if 'a' then attribute names also)\n"); fprintf(stderr, "\t -S \t\t dump out only the schema, no data\n"); fprintf(stderr, "\t -a \t\t dump out only the data, no schema\n"); fprintf(stderr, "\t -t table \t\t dump for this table only\n"); + fprintf(stderr, "\t -o \t\t dump object id's (oids)\n"); fprintf(stderr, "\n if dbname is not supplied, then the DATABASE environment name is used\n"); fprintf(stderr, "\n"); @@ -117,7 +118,7 @@ main(int argc, char** argv) char *pghost = NULL; char *pgport = NULL; char *tablename; - + int oids; TableInfo *tblinfo; int numTables; @@ -125,7 +126,8 @@ main(int argc, char** argv) filename = NULL; tablename = NULL; g_verbose = 0; - + oids = 0; + strcpy(g_comment_start,"-- "); g_comment_end[0] = '\0'; strcpy(g_opaque_type, "opaque"); @@ -134,7 +136,7 @@ main(int argc, char** argv) progname = *argv; - while ((c = getopt(argc, argv,"f:H:p:t:vSDd:a")) != EOF) { + while ((c = getopt(argc, argv,"f:H:p:t:vSDd:ao")) != EOF) { switch(c) { case 'f': /* output file name */ filename = optarg; @@ -161,6 +163,9 @@ main(int argc, char** argv) case 'a': /* Dump data only */ dataOnly = 1; break; + case 'o': /* Dump oids */ + oids = 1; + break; default: usage(progname); break; @@ -196,27 +201,27 @@ main(int argc, char** argv) g_last_builtin_oid = findLastBuiltinOid(); + if (oids) + setMaxOid(g_fout); if (!dataOnly) { - -if (g_verbose) - fprintf(stderr, "%s last builtin oid is %d %s\n", - g_comment_start, g_last_builtin_oid, g_comment_end); - - tblinfo = dumpSchema(g_fout, &numTables, tablename); - + if (g_verbose) + fprintf(stderr, "%s last builtin oid is %d %s\n", + g_comment_start, g_last_builtin_oid, g_comment_end); + tblinfo = dumpSchema(g_fout, &numTables, tablename); } - else { + else tblinfo = dumpSchema(NULL, &numTables, tablename); - } if (!schemaOnly) { - -if (g_verbose) fprintf(stderr,"%s dumping out the contents of each table %s\n", + if (g_verbose) + fprintf(stderr,"%s dumping out the contents of each table %s\n", g_comment_start, g_comment_end); - - dumpClasses(tblinfo, numTables, g_fout, tablename); + dumpClasses(tblinfo, numTables, g_fout, tablename, oids); } + if (!dataOnly) /* dump indexes at the end for performance */ + dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables); + fflush(g_fout); fclose(g_fout); @@ -771,11 +776,11 @@ getTableAttrs(TableInfo* tblinfo, int numTables) /* we must read the attribute names in attribute number order! */ /* because we will use the attnum to index into the attnames array later */ -if (g_verbose) - fprintf(stderr,"%s finding the attrs and types for table: %s %s\n", - g_comment_start, - tblinfo[i].relname, - g_comment_end); + if (g_verbose) + fprintf(stderr,"%s finding the attrs and types for table: %s %s\n", + g_comment_start, + tblinfo[i].relname, + g_comment_end); sprintf(q,"SELECT a.attnum, a.attname, t.typname, a.attlen from pg_attribute a, pg_type t where a.attrelid = '%s'::oid and a.atttypid = t.oid and a.attnum > 0 order by attnum",tblinfo[i].oid); res = PQexec(g_conn, q); @@ -1356,7 +1361,7 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, * dump the contents of all the classes. */ void -dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable) +dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable, int oids) { char query[255]; #define COPYBUFSIZ 8192 @@ -1371,7 +1376,7 @@ dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable) int field; int tuple; int copydone; - + for(i = 0; i < numTables; i++) { char *classname = tblinfo[i].relname; @@ -1382,8 +1387,14 @@ dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable) continue; if(!dumpData) { - fprintf(fout, "COPY %s from stdin;\n", classname); - sprintf(query, "COPY %s to stdout;\n", classname); + if (oids) { + fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n", classname); + sprintf(query, "COPY %s WITH OIDS TO stdout;\n", classname); + } + else { + fprintf(fout, "COPY %s FROM stdin;\n", classname); + sprintf(query, "COPY %s TO stdout;\n", classname); + } res = PQexec(g_conn, query); if (!res || PQresultStatus(res) != PGRES_COPY_OUT) { @@ -1536,7 +1547,53 @@ dumpTuples(PGresult *res, FILE *fout, int* attrmap) } } +/* + * setMaxOid - + * find the maximum oid and generate a COPY statement to set it +*/ +void +setMaxOid(FILE *fout) +{ + char query[255]; + PGresult *res; + Oid max_oid; + + res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) { + fprintf(stderr,"Can not create pgdump_oid table\n"); + exit_nicely(g_conn); + } + PQclear(res); + res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) { + fprintf(stderr,"Can not insert into pgdump_oid table\n"); + exit_nicely(g_conn); + } + max_oid = atol(PQoidStatus(res)); + if (max_oid == 0) { + fprintf(stderr,"Invalid max id in setMaxOid\n"); + exit_nicely(g_conn); + } + PQclear(res); + res = PQexec(g_conn, "DROP TABLE pgdump_oid;"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) { + fprintf(stderr,"Can not drop pgdump_oid table\n"); + exit_nicely(g_conn); + } + PQclear(res); + if (g_verbose) + fprintf(stderr, "%s maximum system oid is %d %s\n", + g_comment_start, max_oid, g_comment_end); + fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n"); + fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n"); + fprintf(fout, "%-ld\t0\n", max_oid); + fprintf(fout, "\\.\n"); + fprintf(fout, "DROP TABLE pgdump_oid;\n"); +} /* * findLastBuiltInOid - diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 3d0287fa58..15bb8bd0bc 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: pg_dump.h,v 1.3 1996/07/22 08:37:00 scrappy Exp $ + * $Id: pg_dump.h,v 1.3.2.1 1996/08/24 20:54:43 scrappy Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -142,6 +142,8 @@ extern char g_opaque_type[10]; /* name for the opaque type */ */ extern TableInfo* dumpSchema(FILE* fout, int *numTablesPtr, char *tablename); +extern void dumpSchemaIdx(FILE* fout, int *numTablesPtr, char *tablename, + TableInfo* tblinfo, int numTables); extern char* findTypeByOid(TypeInfo* tinfo, int numTypes, char* oid); extern char* findOprByOid(OprInfo *oprinfo, int numOprs, char *oid); diff --git a/src/bin/psql/psqlHelp.h b/src/bin/psql/psqlHelp.h index 2fbe50b02c..7ac008d812 100644 --- a/src/bin/psql/psqlHelp.h +++ b/src/bin/psql/psqlHelp.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: psqlHelp.h,v 1.2 1996/07/28 07:08:14 scrappy Exp $ + * $Id: psqlHelp.h,v 1.2.2.1 1996/08/24 20:54:52 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -49,7 +49,7 @@ static struct _helpStruct QL_HELP[] = { "commit [work]"}, { "copy", "copy data to and from a table", - "copy [binary] [nonulls] \n\t{to|from} {|stdin|stdout} [using delimiters ];"}, + "copy [binary] [with oids]\n\t{to|from} {|stdin|stdout} [using delimiters ];"}, { "create", "Please more be specific:", "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate table\n\tcreate type\n\tcreate view"}, @@ -64,7 +64,7 @@ static struct _helpStruct QL_HELP[] = { "create function ([,...]) returns \n\tas ''|''\n\tlanguage 'c'|'sql'|'internal';"}, { "create index", "construct an index", - "create index on using (|(,...) );"}, + "create index on [using ] (|(,...) []);"}, { "create operator", "create a user-defined operator", "create operator (\n\t[leftarg = ][,rightarg = ]\n\t,procedure = ,\n\t[,commutator = ][,negator = ]\n\t[,restrict = ][,hashes]\n\t[,join = ][,sort = ...]);"},