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:49:41 +00:00
parent 2adb6d703b
commit 208a30f23d
13 changed files with 254 additions and 83 deletions

View File

@ -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.2 1996/08/24 20:47:54 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();

View File

@ -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.2 1996/08/24 20:47:42 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

View File

@ -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.2 1996/08/24 20:48:04 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 */
}

View File

@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.3 1996/08/14 05:33:04 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.4 1996/08/24 20:48:14 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)
@ -197,6 +204,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++) {
@ -222,7 +232,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;
@ -260,7 +270,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;
@ -374,8 +385,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';
@ -401,6 +422,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++) {
@ -476,6 +502,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) {
@ -699,7 +727,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;

View File

@ -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.2 1996/08/24 20:48:16 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 */

View File

@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.3 1996/08/06 16:37:53 scrappy Exp $
* $Id: parsenodes.h,v 1.4 1996/08/24 20:48:31 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*/

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.7 1996/08/15 07:42:29 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.8 1996/08/24 20:48:44 scrappy Exp $
*
* HISTORY
* 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,
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 <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,
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, IS,
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,
@ -306,14 +306,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;
}
;
@ -338,6 +339,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
*/
@ -725,7 +730,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;
@ -737,7 +742,7 @@ ProcedureStmt: CREATE FUNCTION def_name def_args
$$ = (Node *)n;
};
opt_with: WITH definition { $$ = $2; }
opt_with_func: WITH definition { $$ = $2; }
| /* EMPTY */ { $$ = NIL; }
;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.2 1996/08/06 16:43:08 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.3 1996/08/24 20:48:46 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -103,6 +103,7 @@ static ScanKeyword ScanKeywords[] = {
{ "notify", NOTIFY },
{ "notnull", NOTNULL },
{ "null", PNULL },
{ "oids", OIDS },
{ "on", ON },
{ "operator", OPERATOR },
{ "option", OPTION },

View File

@ -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.2 1996/08/24 20:49:03 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;

View File

@ -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.4 1996/08/24 20:49:17 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

View File

@ -20,7 +20,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.6 1996/08/14 05:33:11 scrappy Exp $
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.7 1996/08/24 20:49:22 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) {
@ -1538,7 +1549,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 -

View File

@ -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.4 1996/08/24 20:49:25 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);

View File

@ -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.3 1996/08/24 20:49:41 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -49,7 +49,7 @@ static struct _helpStruct QL_HELP[] = {
"commit [work]"},
{ "copy",
"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",
"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 <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"},
{ "create 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 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>]);"},