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 <maillist@candle.pha.pa.us>
This commit is contained in:
Marc G. Fournier 1996-08-24 20:54:52 +00:00
parent 83a0ad2623
commit d390886c1b
13 changed files with 254 additions and 83 deletions

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
@ -1093,6 +1093,8 @@ heap_insert(Relation relation, HeapTuple tup)
tup->t_oid = newoid(); tup->t_oid = newoid();
LastOidProcessed = tup->t_oid; LastOidProcessed = tup->t_oid;
} }
else
CheckMaxObjectId(tup->t_oid);
TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin)); TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
tup->t_cmin = GetCurrentCommandId(); tup->t_cmin = GetCurrentCommandId();

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* Transaction System Version 101 now support proper oid * Transaction System Version 101 now support proper oid
@ -46,6 +46,14 @@
typedef unsigned char XidStatus; /* (2 bits) */ 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 * 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 UpdateLastCommittedXid(TransactionId xid);
extern void GetNewObjectIdBlock(Oid *oid_return, int oid_block_size); extern void GetNewObjectIdBlock(Oid *oid_return, int oid_block_size);
extern void GetNewObjectId(Oid *oid_return); extern void GetNewObjectId(Oid *oid_return);
extern void CheckMaxObjectId(Oid assigned_oid);
/* ---------------- /* ----------------
* global variable extern declarations * global variable extern declarations

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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" #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 * spin lock for oid generation
* --------------------- * ---------------------
@ -604,3 +596,62 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */
next_prefetched_oid++; next_prefetched_oid++;
prefetched_oid_count--; 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 */
}

View File

@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * 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/pg_index.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "storage/bufmgr.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/htup.h" #include "access/htup.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/relscan.h" #include "access/relscan.h"
#include "access/funcindex.h" #include "access/funcindex.h"
#include "access/transam.h"
#include "access/tupdesc.h" #include "access/tupdesc.h"
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
#include "nodes/plannodes.h" #include "nodes/plannodes.h"
@ -50,8 +52,8 @@
static bool reading_from_input = false; static bool reading_from_input = false;
/* non-export function prototypes */ /* non-export function prototypes */
static void CopyTo(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, FILE *fp, char *delim); static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
static Oid GetOutputFunction(Oid type); static Oid GetOutputFunction(Oid type);
static Oid GetTypeElement(Oid type); static Oid GetTypeElement(Oid type);
static Oid GetInputFunction(Oid type); static Oid GetInputFunction(Oid type);
@ -59,14 +61,14 @@ static Oid IsTypeByVal(Oid type);
static void GetIndexRelations(Oid main_relation_oid, static void GetIndexRelations(Oid main_relation_oid,
int *n_indices, int *n_indices,
Relation **index_rels); 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 void CopyAttributeOut(FILE *fp, char *string, char *delim);
static int CountTuples(Relation relation); static int CountTuples(Relation relation);
extern FILE *Pfout, *Pfin; extern FILE *Pfout, *Pfin;
void 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) char *delim)
{ {
FILE *fp; FILE *fp;
@ -86,7 +88,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename,
if (fp == NULL) { if (fp == NULL) {
elog(WARN, "COPY: file %s could not be open for reading", filename); elog(WARN, "COPY: file %s could not be open for reading", filename);
} }
CopyFrom(rel, binary, fp, delim); CopyFrom(rel, binary, oids, fp, delim);
}else { }else {
mode_t oumask = umask((mode_t) 0); 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) { if (fp == NULL) {
elog(WARN, "COPY: file %s could not be open for writing", filename); 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) { if (!pipe) {
fclose(fp); fclose(fp);
@ -113,7 +115,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename,
} }
static void static void
CopyTo(Relation rel, bool binary, FILE *fp, char *delim) CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
{ {
HeapTuple tuple; HeapTuple tuple;
HeapScanDesc scandesc; HeapScanDesc scandesc;
@ -160,6 +162,11 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
tuple != NULL; tuple != NULL;
tuple = heap_getnext(scandesc, 0, 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++) { for (i = 0; i < attr_count; i++) {
value = (Datum) value = (Datum)
heap_getattr(tuple, InvalidBuffer, i+1, tupDesc, &isnull); heap_getattr(tuple, InvalidBuffer, i+1, tupDesc, &isnull);
@ -194,6 +201,9 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
length = tuple->t_len - tuple->t_hoff; length = tuple->t_len - tuple->t_hoff;
fwrite(&length, sizeof(int32), 1, fp); fwrite(&length, sizeof(int32), 1, fp);
if (oids)
fwrite((char *) &tuple->t_oid, sizeof(int32), 1, fp);
fwrite(&null_ct, sizeof(int32), 1, fp); fwrite(&null_ct, sizeof(int32), 1, fp);
if (null_ct > 0) { if (null_ct > 0) {
for (i = 0; i < attr_count; i++) { for (i = 0; i < attr_count; i++) {
@ -219,7 +229,7 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
} }
static void static void
CopyFrom(Relation rel, bool binary, FILE *fp, char *delim) CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
{ {
HeapTuple tuple; HeapTuple tuple;
IndexTuple ituple; IndexTuple ituple;
@ -257,6 +267,7 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
int n_indices; int n_indices;
InsertIndexResult indexRes; InsertIndexResult indexRes;
TupleDesc tupDesc; TupleDesc tupDesc;
Oid loaded_oid;
tupDesc = RelationGetTupleDescriptor(rel); tupDesc = RelationGetTupleDescriptor(rel);
attr = tupDesc->attrs; attr = tupDesc->attrs;
@ -371,8 +382,18 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
while (!done) { while (!done) {
if (!binary) { 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++) { for (i = 0; i < attr_count && !done; i++) {
string = CopyReadAttribute(i, fp, &isnull, delim); string = CopyReadAttribute(fp, &isnull, delim);
if (isnull) { if (isnull) {
values[i] = PointerGetDatum(NULL); values[i] = PointerGetDatum(NULL);
nulls[i] = 'n'; nulls[i] = 'n';
@ -398,6 +419,11 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
if (feof(fp)) { if (feof(fp)) {
done = 1; done = 1;
}else { }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); fread(&null_ct, sizeof(int32), 1, fp);
if (null_ct > 0) { if (null_ct > 0) {
for (i = 0; i < null_ct; i++) { 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); tupDesc = CreateTupleDesc(attr_count, attr);
tuple = heap_formtuple(tupDesc, values, nulls); tuple = heap_formtuple(tupDesc, values, nulls);
if (oids)
tuple->t_oid = loaded_oid;
heap_insert(rel, tuple); heap_insert(rel, tuple);
if (has_index) { if (has_index) {
@ -696,7 +724,7 @@ inString(char c, char* s)
*/ */
static char * static char *
CopyReadAttribute(int attno, FILE *fp, bool *isnull, char *delim) CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
{ {
static char attribute[EXT_ATTLEN]; static char attribute[EXT_ATTLEN];
char c; char c;

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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" #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); char *delim);
#endif /* COPY_H */ #endif /* COPY_H */

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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; NodeTag type;
bool binary; /* is a binary copy? */ bool binary; /* is a binary copy? */
char *relname; /* the relation to copy */ char *relname; /* the relation to copy */
bool oids; /* copy oid's? */
int direction; /* TO or FROM */ int direction; /* TO or FROM */
char *filename; /* if NULL, use stdin/stdout */ char *filename; /* if NULL, use stdin/stdout */
char *delimiter; /* delimiter character, \t by default*/ char *delimiter; /* delimiter character, \t by default*/

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -122,14 +122,14 @@ static Node *makeA_Expr(int op, char *opname, Node *lexpr, Node *rexpr);
%type <list> queryblock, relation_name_list, OptTableElementList, %type <list> queryblock, relation_name_list, OptTableElementList,
tableElementList, OptInherit, definition, 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, OptStmtList, OptStmtBlock, opt_column_list, columnList,
exprList, sort_clause, sortby_list, index_params, exprList, sort_clause, sortby_list, index_params,
name_list, from_clause, from_list, opt_array_bounds, nest_array_bounds, name_list, from_clause, from_list, opt_array_bounds, nest_array_bounds,
expr_list, attrs, res_target_list, res_target_list2, def_list, expr_list, attrs, res_target_list, res_target_list2, def_list,
opt_indirection, group_clause, groupby_list, explain_options opt_indirection, group_clause, groupby_list, explain_options
%type <boolean> opt_inh_star, opt_binary, opt_instead %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy
%type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation, %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation,
def_type, opt_direction, remove_type, opt_column, event 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, HAVING, HEAVY, IN, INDEX, INHERITS, INSERT, INSTEAD, INTO,
ISNULL, LANGUAGE, LIGHT, LISTEN, LOAD, MERGE, MOVE, NEW, ISNULL, LANGUAGE, LIGHT, LISTEN, LOAD, MERGE, MOVE, NEW,
NONE, NOT, NOTHING, NOTIFY, NOTNULL, NONE, NOT, NOTHING, NOTIFY, NOTNULL,
ON, OPERATOR, OPTION, OR, ORDER, OIDS, ON, OPERATOR, OPTION, OR, ORDER,
PNULL, PRIVILEGES, PUBLIC, PURGE, P_TYPE, PNULL, PRIVILEGES, PUBLIC, PURGE, P_TYPE,
RENAME, REPLACE, RETRIEVE, RETURNS, REVOKE, ROLLBACK, RULE, RENAME, REPLACE, RETRIEVE, RETURNS, REVOKE, ROLLBACK, RULE,
SELECT, SET, SETOF, STDIN, STDOUT, STORE, 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); CopyStmt *n = makeNode(CopyStmt);
n->binary = $2; n->binary = $2;
n->relname = $3; n->relname = $3;
n->direction = $4; n->oids = $4;
n->filename = $5; n->direction = $5;
n->delimiter = $6; n->filename = $6;
n->delimiter = $7;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
@ -337,6 +338,10 @@ opt_binary: BINARY { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; }
; ;
opt_with_copy: WITH OIDS { $$ = TRUE; }
| /* EMPTY */ { $$ = FALSE; }
;
/* /*
* the default copy delimiter is tab but the user can configure it * 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 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); ProcedureStmt *n = makeNode(ProcedureStmt);
n->funcname = $3; n->funcname = $3;
@ -732,7 +737,7 @@ ProcedureStmt: CREATE FUNCTION def_name def_args
$$ = (Node *)n; $$ = (Node *)n;
}; };
opt_with: WITH definition { $$ = $2; } opt_with_func: WITH definition { $$ = $2; }
| /* EMPTY */ { $$ = NIL; } | /* EMPTY */ { $$ = NIL; }
; ;

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 }, { "notify", NOTIFY },
{ "notnull", NOTNULL }, { "notnull", NOTNULL },
{ "null", PNULL }, { "null", PNULL },
{ "oids", OIDS },
{ "on", ON }, { "on", ON },
{ "operator", OPERATOR }, { "operator", OPERATOR },
{ "option", OPTION }, { "option", OPTION },

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 *filename;
char *delim; char *delim;
bool isBinary; bool isBinary;
bool isOids;
bool isFrom; bool isFrom;
bool pipe = false; bool pipe = false;
@ -207,6 +208,7 @@ ProcessUtility(Node *parsetree,
relname = stmt->relname; relname = stmt->relname;
isBinary = stmt->binary; isBinary = stmt->binary;
isOids = stmt->oids;
isFrom = (bool)(stmt->direction == FROM); isFrom = (bool)(stmt->direction == FROM);
filename = stmt->filename; filename = stmt->filename;
@ -234,7 +236,7 @@ ProcessUtility(Node *parsetree,
if (pipe && IsUnderPostmaster) dest = CopyEnd; if (pipe && IsUnderPostmaster) dest = CopyEnd;
DoCopy(relname, isBinary, isFrom, pipe, filename, delim); DoCopy(relname, isBinary, isOids, isFrom, pipe, filename, delim);
} }
break; break;

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * 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 numFuncs;
int numTables; int numTables;
int numInherits; int numInherits;
int numIndices;
int numAggregates; int numAggregates;
int numOperators; int numOperators;
TypeInfo *tinfo; TypeInfo *tinfo;
@ -218,7 +217,6 @@ dumpSchema(FILE *fout, int *numTablesPtr, char *tablename)
AggInfo *agginfo; AggInfo *agginfo;
TableInfo *tblinfo; TableInfo *tblinfo;
InhInfo *inhinfo; InhInfo *inhinfo;
IndInfo *indinfo;
OprInfo *oprinfo; OprInfo *oprinfo;
if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n", 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); g_comment_start, g_comment_end);
flagInhAttrs(tblinfo, numTables, inhinfo, numInherits); 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 (!tablename && fout) {
if (g_verbose) fprintf(stderr,"%s dumping out user-defined types %s\n", if (g_verbose) fprintf(stderr,"%s dumping out user-defined types %s\n",
g_comment_start, g_comment_end); g_comment_start, g_comment_end);
@ -288,16 +282,35 @@ if (!tablename && fout) {
dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes); 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; *numTablesPtr = numTables;
return tblinfo; 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 - /* flagInhAttrs -
* for each table in tblinfo, flag its inherited attributes * for each table in tblinfo, flag its inherited attributes
* so when we dump the table out, we don't dump out the inherited attributes * so when we dump the table out, we don't dump out the inherited attributes

View File

@ -20,7 +20,7 @@
* *
* *
* IDENTIFICATION * 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 * 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, "%s - version 1.13.dhb.2\n\n",progname);
fprintf(stderr, "usage: %s [options] [dbname]\n",progname); fprintf(stderr, "usage: %s [options] [dbname]\n",progname);
fprintf(stderr, "\t -f filename \t\t script output filename\n"); 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 -H hostname \t\t server host name\n");
fprintf(stderr, "\t -p port \t\t server port number\n"); fprintf(stderr, "\t -p port \t\t server port number\n");
fprintf(stderr, "\t -v \t\t verbose\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 -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 -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 -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 if dbname is not supplied, then the DATABASE environment name is used\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -117,7 +118,7 @@ main(int argc, char** argv)
char *pghost = NULL; char *pghost = NULL;
char *pgport = NULL; char *pgport = NULL;
char *tablename; char *tablename;
int oids;
TableInfo *tblinfo; TableInfo *tblinfo;
int numTables; int numTables;
@ -125,6 +126,7 @@ main(int argc, char** argv)
filename = NULL; filename = NULL;
tablename = NULL; tablename = NULL;
g_verbose = 0; g_verbose = 0;
oids = 0;
strcpy(g_comment_start,"-- "); strcpy(g_comment_start,"-- ");
g_comment_end[0] = '\0'; g_comment_end[0] = '\0';
@ -134,7 +136,7 @@ main(int argc, char** argv)
progname = *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) { switch(c) {
case 'f': /* output file name */ case 'f': /* output file name */
filename = optarg; filename = optarg;
@ -161,6 +163,9 @@ main(int argc, char** argv)
case 'a': /* Dump data only */ case 'a': /* Dump data only */
dataOnly = 1; dataOnly = 1;
break; break;
case 'o': /* Dump oids */
oids = 1;
break;
default: default:
usage(progname); usage(progname);
break; break;
@ -196,27 +201,27 @@ main(int argc, char** argv)
g_last_builtin_oid = findLastBuiltinOid(); g_last_builtin_oid = findLastBuiltinOid();
if (oids)
setMaxOid(g_fout);
if (!dataOnly) { if (!dataOnly) {
if (g_verbose)
if (g_verbose)
fprintf(stderr, "%s last builtin oid is %d %s\n", fprintf(stderr, "%s last builtin oid is %d %s\n",
g_comment_start, g_last_builtin_oid, g_comment_end); g_comment_start, g_last_builtin_oid, g_comment_end);
tblinfo = dumpSchema(g_fout, &numTables, tablename); tblinfo = dumpSchema(g_fout, &numTables, tablename);
} }
else { else
tblinfo = dumpSchema(NULL, &numTables, tablename); tblinfo = dumpSchema(NULL, &numTables, tablename);
}
if (!schemaOnly) { if (!schemaOnly) {
if (g_verbose)
if (g_verbose) fprintf(stderr,"%s dumping out the contents of each table %s\n", fprintf(stderr,"%s dumping out the contents of each table %s\n",
g_comment_start, g_comment_end); g_comment_start, g_comment_end);
dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
dumpClasses(tblinfo, numTables, g_fout, tablename);
} }
if (!dataOnly) /* dump indexes at the end for performance */
dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables);
fflush(g_fout); fflush(g_fout);
fclose(g_fout); fclose(g_fout);
@ -771,7 +776,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables)
/* we must read the attribute names in attribute number order! */ /* we must read the attribute names in attribute number order! */
/* because we will use the attnum to index into the attnames array /* because we will use the attnum to index into the attnames array
later */ later */
if (g_verbose) if (g_verbose)
fprintf(stderr,"%s finding the attrs and types for table: %s %s\n", fprintf(stderr,"%s finding the attrs and types for table: %s %s\n",
g_comment_start, g_comment_start,
tblinfo[i].relname, tblinfo[i].relname,
@ -1356,7 +1361,7 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
* dump the contents of all the classes. * dump the contents of all the classes.
*/ */
void void
dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable) dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable, int oids)
{ {
char query[255]; char query[255];
#define COPYBUFSIZ 8192 #define COPYBUFSIZ 8192
@ -1382,8 +1387,14 @@ dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable)
continue; continue;
if(!dumpData) { if(!dumpData) {
fprintf(fout, "COPY %s from stdin;\n", classname); if (oids) {
sprintf(query, "COPY %s to stdout;\n", classname); 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); res = PQexec(g_conn, query);
if (!res || if (!res ||
PQresultStatus(res) != PGRES_COPY_OUT) { 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 - * findLastBuiltInOid -

View File

@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * 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 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* findTypeByOid(TypeInfo* tinfo, int numTypes, char* oid);
extern char* findOprByOid(OprInfo *oprinfo, int numOprs, char *oid); extern char* findOprByOid(OprInfo *oprinfo, int numOprs, char *oid);

View File

@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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]"}, "commit [work]"},
{ "copy", { "copy",
"copy data to and from a table", "copy data to and from a table",
"copy [binary] [nonulls] <relname>\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"}, "copy [binary] <relname> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"},
{ "create", { "create",
"Please more be specific:", "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"}, "\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 <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"}, "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"},
{ "create index", { "create index",
"construct an index", "construct an index",
"create index <indexname> on <relname> using <access_method> (<attr1>|<funcname>(<attr1>,...) <type_class1>);"}, "create index <indexname> on <relname> [using <access_method>] (<attr1>|<funcname>(<attr1>,...) [<type_class1>]);"},
{ "create operator", { "create operator",
"create a user-defined operator", "create a user-defined operator",
"create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"}, "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"},