diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 28ca264c65..a1a5e9baa7 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -1,5 +1,5 @@ @@ -21,7 +21,8 @@ PostgreSQL documentation 1999-12-11 -COPY table +COPY table + [ ( column [, ...] ) ] FROM { 'filename' | stdin } [ [ WITH ] [ BINARY ] @@ -29,6 +30,7 @@ COPY table [ DELIMITER [ AS ] 'delimiter' ] [ NULL [ AS ] 'null string' ] ] COPY table + [ ( column [, ...] ) ] TO { 'filename' | stdout } [ [ WITH ] [ BINARY ] @@ -55,6 +57,16 @@ COPY table + + + column list + + + An optional list of columns to be copied. If no column list is + specified, all columns will be used. + + + filename @@ -187,6 +199,14 @@ ERROR: reason whatever is in the table already). + + When using the optional column list syntax, COPY TO + and COPY FROM will only copy the specified + columns' values to/from the table. If a column in the table + is not in the column list, COPY FROM will insert + default values for that column if a default value is defined. + + COPY with a file name instructs the PostgreSQL backend to directly read from diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 7410bff04b..438126a3e1 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.158 2002/06/20 20:29:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.159 2002/07/18 04:43:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,6 +28,7 @@ #include "commands/copy.h" #include "commands/trigger.h" #include "executor/executor.h" +#include "rewrite/rewriteHandler.h" #include "libpq/libpq.h" #include "miscadmin.h" #include "tcop/pquery.h" @@ -46,13 +47,14 @@ /* non-export function prototypes */ -static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print); -static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print); +static void CopyTo(Relation rel, List *attlist, bool binary, bool oids, FILE *fp, char *delim, char *null_print); +static void CopyFrom(Relation rel, List *attlist, bool binary, bool oids, FILE *fp, char *delim, char *null_print); static Oid GetInputFunction(Oid type); static Oid GetTypeElement(Oid type); static void CopyReadNewline(FILE *fp, int *newline); static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print); static void CopyAttributeOut(FILE *fp, char *string, char *delim); +static void CopyAssertAttlist(Relation rel, List* attlist, bool from); static const char BinarySignature[12] = "PGBCOPY\n\377\r\n\0"; @@ -267,7 +269,8 @@ DoCopy(const CopyStmt *stmt) char *filename = stmt->filename; bool is_from = stmt->is_from; bool pipe = (stmt->filename == NULL); - List *option; + List *option; + List *attlist = stmt->attlist; DefElem *dbinary = NULL; DefElem *doids = NULL; DefElem *ddelim = NULL; @@ -289,25 +292,27 @@ DoCopy(const CopyStmt *stmt) if (strcmp(defel->defname, "binary") == 0) { if (dbinary) - elog(ERROR, "COPY: conflicting options"); + /* should this really be an error? */ + elog(ERROR, "COPY: BINARY option appears more than once"); dbinary = defel; } else if (strcmp(defel->defname, "oids") == 0) { if (doids) - elog(ERROR, "COPY: conflicting options"); + /* should this really be an error? */ + elog(ERROR, "COPY: OIDS option appears more than once"); doids = defel; } else if (strcmp(defel->defname, "delimiter") == 0) { if (ddelim) - elog(ERROR, "COPY: conflicting options"); + elog(ERROR, "COPY: DELIMITER string may only be defined once in query"); ddelim = defel; } else if (strcmp(defel->defname, "null") == 0) { if (dnull) - elog(ERROR, "COPY: conflicting options"); + elog(ERROR, "COPY: NULL representation may only be defined once in query"); dnull = defel; } else @@ -367,6 +372,24 @@ DoCopy(const CopyStmt *stmt) server_encoding = GetDatabaseEncoding(); #endif + if( attlist == NIL ){ + /* get list of attributes in the relation */ + TupleDesc desc = RelationGetDescr(rel); + int i; + for(i = 0; i < desc->natts; ++i){ + Ident* id = makeNode(Ident); + id->name = NameStr(desc->attrs[i]->attname); + attlist = lappend(attlist,id); + } + } + else{ + if( binary ){ + elog(ERROR,"COPY: BINARY format cannot be used with specific column list"); + } + /* verify that any user-specified attributes exist in the relation */ + CopyAssertAttlist(rel,attlist,is_from); + } + if (is_from) { /* copy from file to database */ if (rel->rd_rel->relkind != RELKIND_RELATION) @@ -410,7 +433,7 @@ DoCopy(const CopyStmt *stmt) elog(ERROR, "COPY: %s is a directory.", filename); } } - CopyFrom(rel, binary, oids, fp, delim, null_print); + CopyFrom(rel, attlist, binary, oids, fp, delim, null_print); } else { /* copy from database to file */ @@ -466,7 +489,7 @@ DoCopy(const CopyStmt *stmt) elog(ERROR, "COPY: %s is a directory.", filename); } } - CopyTo(rel, binary, oids, fp, delim, null_print); + CopyTo(rel, attlist, binary, oids, fp, delim, null_print); } if (!pipe) @@ -494,8 +517,8 @@ DoCopy(const CopyStmt *stmt) * Copy from relation TO file. */ static void -CopyTo(Relation rel, bool binary, bool oids, FILE *fp, - char *delim, char *null_print) +CopyTo(Relation rel, List *attlist, bool binary, bool oids, + FILE *fp, char *delim, char *null_print) { HeapTuple tuple; TupleDesc tupDesc; @@ -509,6 +532,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, int16 fld_size; char *string; Snapshot mySnapshot; + int copy_attr_count; + int* attmap; + int p = 0; + List* cur; if (oids && !rel->rd_rel->relhasoids) elog(ERROR, "COPY: table %s does not have OIDs", @@ -517,6 +544,18 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, tupDesc = rel->rd_att; attr_count = rel->rd_att->natts; attr = rel->rd_att->attrs; + copy_attr_count = length(attlist); + { + attmap = (int*)palloc(copy_attr_count * sizeof(int)); + foreach(cur,attlist){ + for (i = 0; i < attr_count; i++){ + if( strcmp(strVal(lfirst(cur)),NameStr(attr[i]->attname)) == 0){ + attmap[p++] = i; + continue; + } + } + } + } /* * For binary copy we really only need isvarlena, but compute it @@ -593,13 +632,14 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, } } - for (i = 0; i < attr_count; i++) + for (i = 0; i < copy_attr_count; i++) { Datum origvalue, value; bool isnull; + int mi = attmap[i]; - origvalue = heap_getattr(tuple, i + 1, tupDesc, &isnull); + origvalue = heap_getattr(tuple, mi + 1, tupDesc, &isnull); if (!binary) { @@ -628,25 +668,25 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, * (or for binary case, becase we must output untoasted * value). */ - if (isvarlena[i]) + if (isvarlena[mi]) value = PointerGetDatum(PG_DETOAST_DATUM(origvalue)); else value = origvalue; if (!binary) { - string = DatumGetCString(FunctionCall3(&out_functions[i], + string = DatumGetCString(FunctionCall3(&out_functions[mi], value, - ObjectIdGetDatum(elements[i]), - Int32GetDatum(attr[i]->atttypmod))); + ObjectIdGetDatum(elements[mi]), + Int32GetDatum(attr[mi]->atttypmod))); CopyAttributeOut(fp, string, delim); pfree(string); } else { - fld_size = attr[i]->attlen; + fld_size = attr[mi]->attlen; CopySendData(&fld_size, sizeof(int16), fp); - if (isvarlena[i]) + if (isvarlena[mi]) { /* varlena */ Assert(fld_size == -1); @@ -654,7 +694,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, VARSIZE(value), fp); } - else if (!attr[i]->attbyval) + else if (!attr[mi]->attbyval) { /* fixed-length pass-by-reference */ Assert(fld_size > 0); @@ -709,13 +749,13 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, * Copy FROM file to relation. */ static void -CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, - char *delim, char *null_print) +CopyFrom(Relation rel, List *attlist, bool binary, bool oids, + FILE *fp, char *delim, char *null_print) { HeapTuple tuple; TupleDesc tupDesc; Form_pg_attribute *attr; - AttrNumber attr_count; + AttrNumber attr_count, copy_attr_count, def_attr_count; FmgrInfo *in_functions; Oid *elements; int i; @@ -732,10 +772,17 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, Oid loaded_oid = InvalidOid; bool skip_tuple = false; bool file_has_oids; + int* attmap = NULL; + int* defmap = NULL; + Node** defexprs = NULL; /* array of default att expressions */ + ExprContext *econtext; /* used for ExecEvalExpr for default atts */ + ExprDoneCond isdone; tupDesc = RelationGetDescr(rel); attr = tupDesc->attrs; attr_count = tupDesc->natts; + copy_attr_count = length(attlist); + def_attr_count = 0; /* * We need a ResultRelInfo so we can use the regular executor's @@ -758,15 +805,42 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, slot = ExecAllocTableSlot(tupleTable); ExecSetSlotDescriptor(slot, tupDesc, false); + if (!binary) { + /* + * pick up the input function and default expression (if any) for + * each attribute in the relation. + */ + List* cur; + attmap = (int*)palloc(sizeof(int) * attr_count); + defmap = (int*)palloc(sizeof(int) * attr_count); + defexprs = (Node**)palloc(sizeof(Node*) * attr_count); in_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo)); elements = (Oid *) palloc(attr_count * sizeof(Oid)); for (i = 0; i < attr_count; i++) { + int p = 0; + bool specified = false; in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid); fmgr_info(in_func_oid, &in_functions[i]); elements[i] = GetTypeElement(attr[i]->atttypid); + foreach(cur,attlist){ + if( strcmp(strVal(lfirst(cur)),NameStr(attr[i]->attname)) == 0){ + attmap[p] = i; + specified = true; + continue; + } + ++p; + } + if( ! specified ){ + /* column not specified, try to get a default */ + defexprs[def_attr_count] = build_column_default(rel,i+1); + if( defexprs[def_attr_count] != NULL ){ + defmap[def_attr_count] = i; + ++def_attr_count; + } + } } file_has_oids = oids; /* must rely on user to tell us this... */ } @@ -821,12 +895,14 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, copy_lineno = 0; fe_eof = false; + econtext = GetPerTupleExprContext(estate); + while (!done) { CHECK_FOR_INTERRUPTS(); copy_lineno++; - + /* Reset the per-output-tuple exprcontext */ ResetPerTupleExprContext(estate); @@ -854,26 +930,42 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, elog(ERROR, "COPY TEXT: Invalid Oid"); } } - - for (i = 0; i < attr_count && !done; i++) + + /* + * here, we only try to read as many attributes as + * were specified. + */ + for (i = 0; i < copy_attr_count && !done; i++) { + int m = attmap[i]; string = CopyReadAttribute(fp, &isnull, delim, &newline, null_print); - if (isnull) - { - /* already set values[i] and nulls[i] */ + + if( isnull ){ + /* nothing */ } else if (string == NULL) done = 1; /* end of file */ else { - values[i] = FunctionCall3(&in_functions[i], - CStringGetDatum(string), - ObjectIdGetDatum(elements[i]), - Int32GetDatum(attr[i]->atttypmod)); - nulls[i] = ' '; + values[m] = FunctionCall3(&in_functions[m], + CStringGetDatum(string), + ObjectIdGetDatum(elements[m]), + Int32GetDatum(attr[m]->atttypmod)); + nulls[m] = ' '; } } + + /* + * as above, we only try a default lookup if one is + * known to be available + */ + for (i = 0; i < def_attr_count && !done; i++){ + bool isnull; + values[defmap[i]] = ExecEvalExpr(defexprs[i],econtext,&isnull,&isdone); + if( ! isnull ) + nulls[defmap[i]] = ' '; + } if (!done) CopyReadNewline(fp, &newline); } @@ -975,7 +1067,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, break; tuple = heap_formtuple(tupDesc, values, nulls); - + if (oids && file_has_oids) tuple->t_data->t_oid = loaded_oid; @@ -1021,12 +1113,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, ExecARInsertTriggers(estate, resultRelInfo, tuple); } - for (i = 0; i < attr_count; i++) - { - if (!attr[i]->attbyval && nulls[i] != 'n') - pfree(DatumGetPointer(values[i])); - } - heap_freetuple(tuple); } @@ -1361,3 +1447,51 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim) pfree(string_start); /* pfree pg_server_to_client result */ #endif } + +/* + * CopyAssertAttlist: elog(ERROR,...) if the specified attlist + * is not valid for the Relation + */ +static void +CopyAssertAttlist(Relation rel, List* attlist, bool from) +{ + TupleDesc tupDesc; + List* cur; + char* illegalattname = NULL; + int attr_count; + const char* to_or_from; + + if( attlist == NIL ) + return; + + to_or_from = (from == true ? "FROM" : "TO"); + + tupDesc = RelationGetDescr(rel); + Assert(tupDesc != NULL); + + /* + * make sure there aren't more columns specified than are in the table + */ + attr_count = tupDesc->natts; + if( attr_count < length(attlist) ) + elog(ERROR,"More columns specified in COPY %s command than in target relation",to_or_from); + + /* + * make sure no columns are specified that don't exist in the table + */ + foreach(cur,attlist) + { + int found = 0; + int i = 0; + for(;iattrs[i]->attname)) == 0) + ++found; + } + if( ! found ) + illegalattname = strVal(lfirst(cur)); + } + if( illegalattname ) + elog(ERROR,"Attribute referenced in COPY %s command does not exist: \"%s.%s\"",to_or_from,RelationGetRelationName(rel),illegalattname); +} + diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index f2220aa00b..17a3b61e76 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.343 2002/07/18 04:41:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.344 2002/07/18 04:43:50 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -1262,31 +1262,32 @@ opt_id: ColId { $$ = $1; } /***************************************************************************** * * QUERY : - * COPY FROM/TO [WITH options] + * COPY ['(' columnList ')'] FROM/TO [WITH options] * * BINARY, OIDS, and DELIMITERS kept in old locations * for backward compatibility. 2002-06-18 * *****************************************************************************/ -CopyStmt: COPY opt_binary qualified_name opt_oids copy_from - copy_file_name copy_delimiter opt_with copy_opt_list +CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids + copy_from copy_file_name copy_delimiter opt_with copy_opt_list { CopyStmt *n = makeNode(CopyStmt); n->relation = $3; - n->is_from = $5; - n->filename = $6; + n->attlist = $4; + n->is_from = $6; + n->filename = $7; n->options = NIL; /* Concatenate user-supplied flags */ if ($2) n->options = lappend(n->options, $2); - if ($4) - n->options = lappend(n->options, $4); - if ($7) - n->options = lappend(n->options, $7); - if ($9) - n->options = nconc(n->options, $9); + if ($5) + n->options = lappend(n->options, $5); + if ($8) + n->options = lappend(n->options, $8); + if ($10) + n->options = nconc(n->options, $10); $$ = (Node *)n; } ; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index ae199d51ce..0ae1e223ba 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.103 2002/06/20 20:29:34 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.104 2002/07/18 04:43:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -43,7 +43,6 @@ static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index); static void rewriteTargetList(Query *parsetree, Relation target_relation); static TargetEntry *process_matched_tle(TargetEntry *src_tle, TargetEntry *prior_tle); -static Node *build_column_default(Relation rel, int attrno); static void markQueryForUpdate(Query *qry, bool skipOldNew); static List *matchLocks(CmdType event, RuleLock *rulelocks, int varno, Query *parsetree); @@ -411,7 +410,7 @@ process_matched_tle(TargetEntry *src_tle, * * If there is no default, return a NULL instead. */ -static Node * +Node * build_column_default(Relation rel, int attrno) { TupleDesc rd_att = rel->rd_att; diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index dd6aad5503..7f263c3eb4 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.271 2002/07/12 18:43:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.272 2002/07/18 04:43:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -133,6 +133,7 @@ static char *GetPrivileges(Archive *AH, const char *s, const char *type); static int dumpBlobs(Archive *AH, char *, void *); static int dumpDatabase(Archive *AH); static const char *getAttrName(int attrnum, TableInfo *tblInfo); +static const char* fmtCopyColumnList(const TableInfo* ti); extern char *optarg; extern int optind, @@ -842,6 +843,7 @@ dumpClasses_nodumpData(Archive *fout, char *oid, void *dctxv) int ret; bool copydone; char copybuf[COPYBUFSIZ]; + const char* column_list; if (g_verbose) write_msg(NULL, "dumping out the contents of table %s\n", classname); @@ -854,17 +856,19 @@ dumpClasses_nodumpData(Archive *fout, char *oid, void *dctxv) */ selectSourceSchema(tbinfo->relnamespace->nspname); + column_list = fmtCopyColumnList(tbinfo); + if (oids && hasoids) { - appendPQExpBuffer(q, "COPY %s WITH OIDS TO stdout;", + appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;", fmtQualifiedId(tbinfo->relnamespace->nspname, - classname)); + classname),column_list); } else { - appendPQExpBuffer(q, "COPY %s TO stdout;", + appendPQExpBuffer(q, "COPY %s %s TO stdout;", fmtQualifiedId(tbinfo->relnamespace->nspname, - classname)); + classname), column_list); } res = PQexec(g_conn, q->data); if (!res || @@ -1189,8 +1193,9 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout, { /* Dump/restore using COPY */ dumpFn = dumpClasses_nodumpData; - sprintf(copyBuf, "COPY %s %sFROM stdin;\n", - fmtId(tblinfo[i].relname, force_quotes), + sprintf(copyBuf, "COPY %s %s %sFROM stdin;\n", + fmtQualifiedId(tblinfo[i].relnamespace->nspname,tblinfo[i].relname), + fmtCopyColumnList(&(tblinfo[i])), (oids && tblinfo[i].hasoids) ? "WITH OIDS " : ""); copyStmt = copyBuf; } @@ -5860,3 +5865,38 @@ fmtQualifiedId(const char *schema, const char *id) return id_return->data; } + +/* + * return a column list clause for the qualified relname. + * returns an empty string if the remote server is older than + * 7.3. + */ +static const char* +fmtCopyColumnList(const TableInfo* ti) +{ + static PQExpBuffer q = NULL; + int numatts = ti->numatts; + char** attnames = ti->attnames; + int i; + + if (g_fout->remoteVersion < 70300 ) + return ""; + + if (q) /* first time through? */ + resetPQExpBuffer(q); + else + q = createPQExpBuffer(); + + resetPQExpBuffer(q); + + appendPQExpBuffer(q,"("); + for (i = 0; i < numatts; i++) + { + if( i > 0 ) + appendPQExpBuffer(q,","); + appendPQExpBuffer(q, fmtId(attnames[i], force_quotes)); + } + appendPQExpBuffer(q, ")"); + return q->data; +} + diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index f64f1b3d74..e6b27d03af 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.189 2002/07/18 04:42:29 momjian Exp $ + * $Id: parsenodes.h,v 1.190 2002/07/18 04:43:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -884,6 +884,7 @@ typedef struct CopyStmt { NodeTag type; RangeVar *relation; /* the relation to copy */ + List *attlist; bool is_from; /* TO or FROM */ char *filename; /* if NULL, use stdin/stdout */ List *options; /* List of DefElem nodes */ diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h index 900ffca658..69fecc8142 100644 --- a/src/include/rewrite/rewriteHandler.h +++ b/src/include/rewrite/rewriteHandler.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: rewriteHandler.h,v 1.19 2002/06/20 20:29:52 momjian Exp $ + * $Id: rewriteHandler.h,v 1.20 2002/07/18 04:43:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -16,7 +16,7 @@ #include "nodes/parsenodes.h" - extern List *QueryRewrite(Query *parsetree); +extern Node *build_column_default(Relation rel, int attrno); #endif /* REWRITEHANDLER_H */ diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 1a72d1bc6e..919c37e13f 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -74,4 +74,4 @@ test: select_views alter_table portals_p2 rules foreign_key # The sixth group of parallel test # ---------- # "plpgsql" cannot run concurrently with "rules" -test: limit plpgsql temp domain rangefuncs +test: limit plpgsql temp domain rangefuncs copy2 diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 87afc7c451..552d63f9e3 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -1,4 +1,4 @@ -# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.10 2002/06/20 17:09:42 momjian Exp $ +# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.11 2002/07/18 04:43:51 momjian Exp $ # This should probably be in an order similar to parallel_schedule. test: boolean test: char @@ -80,6 +80,7 @@ test: rules test: foreign_key test: limit test: plpgsql +test: copy2 test: temp test: domain test: rangefuncs