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 = ...]);"},