diff options
Diffstat (limited to 'src')
21 files changed, 242 insertions, 131 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 16c23d320ee..cfc8a5c0703 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.156 2002/05/21 22:59:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.157 2002/06/20 16:00:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -261,18 +261,79 @@ CopyDonePeek(FILE *fp, int c, bool pickup) * the table. */ void -DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe, - char *filename, char *delim, char *null_print) +DoCopy(const CopyStmt *stmt) { + RangeVar *relation = stmt->relation; + char *filename = stmt->filename; + bool is_from = stmt->is_from; + bool pipe = (stmt->filename == NULL); + List *option; + DefElem *dbinary = NULL; + DefElem *doids = NULL; + DefElem *ddelim = NULL; + DefElem *dnull = NULL; + bool binary = false; + bool oids = false; + char *delim = "\t"; + char *null_print = "\\N"; FILE *fp; Relation rel; - AclMode required_access = (from ? ACL_INSERT : ACL_SELECT); + AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT); AclResult aclresult; + /* Extract options from the statement node tree */ + foreach(option, stmt->options) + { + DefElem *defel = (DefElem *) lfirst(option); + + if (strcmp(defel->defname, "binary") == 0) + { + if (dbinary) + elog(ERROR, "COPY: conflicting options"); + dbinary = defel; + } + else if (strcmp(defel->defname, "oids") == 0) + { + if (doids) + elog(ERROR, "COPY: conflicting options"); + doids = defel; + } + else if (strcmp(defel->defname, "delimiter") == 0) + { + if (ddelim) + elog(ERROR, "COPY: conflicting options"); + ddelim = defel; + } + else if (strcmp(defel->defname, "null") == 0) + { + if (dnull) + elog(ERROR, "COPY: conflicting options"); + dnull = defel; + } + else + elog(ERROR, "COPY: option \"%s\" not recognized", + defel->defname); + } + + if (dbinary) + binary = intVal(dbinary->arg); + if (doids) + oids = intVal(doids->arg); + if (ddelim) + delim = strVal(ddelim->arg); + if (dnull) + null_print = strVal(dnull->arg); + + if (binary && ddelim) + elog(ERROR, "You can not specify the DELIMITER in BINARY mode."); + + if (binary && dnull) + elog(ERROR, "You can not specify NULL in BINARY mode."); + /* * Open and lock the relation, using the appropriate lock type. */ - rel = heap_openrv(relation, (from ? RowExclusiveLock : AccessShareLock)); + rel = heap_openrv(relation, (is_from ? RowExclusiveLock : AccessShareLock)); /* Check permissions. */ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), @@ -306,7 +367,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe, server_encoding = GetDatabaseEncoding(); #endif - if (from) + if (is_from) { /* copy from file to database */ if (rel->rd_rel->relkind != RELKIND_RELATION) { @@ -410,7 +471,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe, if (!pipe) FreeFile(fp); - else if (!from) + else if (!is_from) { if (!binary) CopySendData("\\.\n", 3, fp); @@ -425,7 +486,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe, * transaction to ensure that updates will be committed before lock is * released. */ - heap_close(rel, (from ? NoLock : AccessShareLock)); + heap_close(rel, (is_from ? NoLock : AccessShareLock)); } diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index ae4e52f42a4..4e9fe90e360 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.93 2002/06/18 17:27:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.94 2002/06/20 16:00:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -58,7 +58,7 @@ static bool remove_dbdirs(const char *real_loc, const char *altloc); */ void -createdb(CreatedbStmt *stmt) +createdb(const CreatedbStmt *stmt) { char *nominal_loc; char *alt_loc; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index d2a3f40a348..37da8612a4c 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.189 2002/06/18 17:27:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.190 2002/06/20 16:00:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1992,16 +1992,11 @@ _copyCopyStmt(CopyStmt *from) { CopyStmt *newnode = makeNode(CopyStmt); - newnode->binary = from->binary; Node_Copy(from, newnode, relation); - newnode->oids = from->oids; - newnode->direction = from->direction; + newnode->is_from = from->is_from; if (from->filename) newnode->filename = pstrdup(from->filename); - if (from->delimiter) - newnode->delimiter = pstrdup(from->delimiter); - if (from->null_print) - newnode->null_print = pstrdup(from->null_print); + Node_Copy(from, newnode, options); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 85ff384479d..55f0be05582 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.136 2002/06/18 17:27:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.137 2002/06/20 16:00:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -799,19 +799,13 @@ _equalClusterStmt(ClusterStmt *a, ClusterStmt *b) static bool _equalCopyStmt(CopyStmt *a, CopyStmt *b) { - if (a->binary != b->binary) - return false; if (!equal(a->relation, b->relation)) return false; - if (a->oids != b->oids) - return false; - if (a->direction != b->direction) + if (a->is_from != b->is_from) return false; if (!equalstr(a->filename, b->filename)) return false; - if (!equalstr(a->delimiter, b->delimiter)) - return false; - if (!equalstr(a->null_print, b->null_print)) + if (!equal(a->options, b->options)) return false; return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1c499f417d9..b7b2f6a693d 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.331 2002/06/19 15:40:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.332 2002/06/20 16:00:43 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -159,8 +159,8 @@ static void doNegateFloat(Value *v); %type <node> alter_column_default %type <ival> add_drop, drop_behavior, opt_drop_behavior -%type <list> createdb_opt_list -%type <defelt> createdb_opt_item +%type <list> createdb_opt_list, copy_opt_list +%type <defelt> createdb_opt_item, copy_opt_item %type <ival> opt_lock, lock_type %type <boolean> opt_force, opt_or_replace @@ -182,7 +182,7 @@ static void doNegateFloat(Value *v); %type <str> TriggerEvents %type <value> TriggerFuncArg -%type <str> relation_name, copy_file_name, copy_delimiter, copy_null, +%type <str> relation_name, copy_file_name, database_name, access_method_clause, access_method, attr_name, index_name, name, function_name, file_name @@ -236,11 +236,14 @@ static void doNegateFloat(Value *v); %type <ival> opt_interval %type <node> overlay_placing, substr_from, substr_for -%type <boolean> opt_binary, opt_instead, opt_cursor -%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, opt_full +%type <boolean> opt_instead, opt_cursor +%type <boolean> index_opt_unique, opt_verbose, opt_full %type <boolean> opt_freeze +%type <defelt> opt_binary, opt_oids, copy_delimiter -%type <ival> copy_dirn, direction, reindex_type, drop_type, +%type <boolean> copy_from + +%type <ival> direction, reindex_type, drop_type, opt_column, event, comment_type %type <ival> fetch_how_many @@ -330,8 +333,8 @@ static void doNegateFloat(Value *v); CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, CYCLE, DATABASE, DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, - DEFERRABLE, DEFERRED, DEFINER, DELETE_P, DELIMITERS, DESC, - DISTINCT, DO, DOMAIN_P, DOUBLE, DROP, + DEFERRABLE, DEFERRED, DEFINER, DELETE_P, DELIMITER, DELIMITERS, + DESC, DISTINCT, DO, DOMAIN_P, DOUBLE, DROP, EACH, ELSE, ENCODING, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT, EXCLUSIVE, EXECUTE, EXISTS, EXPLAIN, EXTERNAL, EXTRACT, @@ -1293,27 +1296,38 @@ opt_id: ColId { $$ = $1; } /***************************************************************************** * * QUERY : - * COPY [BINARY] <relname> FROM/TO - * [USING DELIMITERS <delimiter>] + * COPY <relname> 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_with_copy copy_dirn copy_file_name copy_delimiter copy_null +CopyStmt: COPY opt_binary qualified_name opt_oids copy_from + copy_file_name copy_delimiter opt_with copy_opt_list { CopyStmt *n = makeNode(CopyStmt); - n->binary = $2; n->relation = $3; - n->oids = $4; - n->direction = $5; + n->is_from = $5; n->filename = $6; - n->delimiter = $7; - n->null_print = $8; + + 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); $$ = (Node *)n; } ; -copy_dirn: TO { $$ = TO; } - | FROM { $$ = FROM; } +copy_from: + FROM { $$ = TRUE; } + | TO { $$ = FALSE; } ; /* @@ -1327,30 +1341,79 @@ copy_file_name: | STDOUT { $$ = NULL; } ; -opt_binary: BINARY { $$ = TRUE; } - | /*EMPTY*/ { $$ = FALSE; } + + +copy_opt_list: + copy_opt_list copy_opt_item { $$ = lappend($1, $2); } + | /* EMPTY */ { $$ = NIL; } ; -opt_with_copy: - WITH OIDS { $$ = TRUE; } - | /*EMPTY*/ { $$ = FALSE; } + +copy_opt_item: + BINARY + { + $$ = makeNode(DefElem); + $$->defname = "binary"; + $$->arg = (Node *)makeInteger(TRUE); + } + | OIDS + { + $$ = makeNode(DefElem); + $$->defname = "oids"; + $$->arg = (Node *)makeInteger(TRUE); + } + | DELIMITER opt_as Sconst + { + $$ = makeNode(DefElem); + $$->defname = "delimiter"; + $$->arg = (Node *)makeString($3); + } + | NULL_P opt_as Sconst + { + $$ = makeNode(DefElem); + $$->defname = "null"; + $$->arg = (Node *)makeString($3); + } + ; + +/* The following exist for backward compatibility */ + +opt_binary: + BINARY + { + $$ = makeNode(DefElem); + $$->defname = "binary"; + $$->arg = (Node *)makeInteger(TRUE); + } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_oids: + WITH OIDS + { + $$ = makeNode(DefElem); + $$->defname = "oids"; + $$->arg = (Node *)makeInteger(TRUE); + } + | /*EMPTY*/ { $$ = NULL; } ; -/* - * the default copy delimiter is tab but the user can configure it - */ copy_delimiter: - opt_using DELIMITERS Sconst { $$ = $3; } - | /*EMPTY*/ { $$ = "\t"; } + /* USING DELIMITERS kept for backward compatibility. 2002-06-15 */ + opt_using DELIMITERS Sconst + { + $$ = makeNode(DefElem); + $$->defname = "delimiter"; + $$->arg = (Node *)makeString($3); + } + | /*EMPTY*/ { $$ = NULL; } ; -opt_using: USING {} +opt_using: + USING {} | /*EMPTY*/ {} ; -copy_null: WITH NULL_P AS Sconst { $$ = $4; } - | /*EMPTY*/ { $$ = "\\N"; } - ; /***************************************************************************** * @@ -3422,10 +3485,6 @@ createdb_opt_list: | /* EMPTY */ { $$ = NIL; } ; -/* - * createdb_opt_item returns 2-element lists, with the first element - * being an integer code to indicate which item was specified. - */ createdb_opt_item: LOCATION opt_equal Sconst { @@ -6529,6 +6588,7 @@ unreserved_keyword: | DEFERRED | DEFINER | DELETE_P + | DELIMITER | DELIMITERS | DOMAIN_P | DOUBLE diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 0f441290ea8..c125cc79fbb 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.114 2002/06/15 03:00:03 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.115 2002/06/20 16:00:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -98,6 +98,7 @@ static const ScanKeyword ScanKeywords[] = { {"deferred", DEFERRED}, {"definer", DEFINER}, {"delete", DELETE_P}, + {"delimiter", DELIMITER}, {"delimiters", DELIMITERS}, {"desc", DESC}, {"distinct", DISTINCT}, diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 4e23a6d9190..c0f480085cc 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.157 2002/06/18 17:27:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.158 2002/06/20 16:00:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -347,22 +347,10 @@ ProcessUtility(Node *parsetree, { CopyStmt *stmt = (CopyStmt *) parsetree; - if (stmt->direction != FROM) + if (!stmt->is_from) SetQuerySnapshot(); - DoCopy(stmt->relation, - stmt->binary, - stmt->oids, - (bool) (stmt->direction == FROM), - (bool) (stmt->filename == NULL), - - /* - * null filename means copy to/from stdout/stdin, rather - * than to/from a file. - */ - stmt->filename, - stmt->delimiter, - stmt->null_print); + DoCopy(stmt); } break; diff --git a/src/bin/pgaccess/doc/html/tutorial/tut_edit.html b/src/bin/pgaccess/doc/html/tutorial/tut_edit.html index 8282fb9a422..a4e75b17791 100644 --- a/src/bin/pgaccess/doc/html/tutorial/tut_edit.html +++ b/src/bin/pgaccess/doc/html/tutorial/tut_edit.html @@ -29,7 +29,7 @@ a text file named <samp>newref.txt</samp> that starts like this:<p> Notice that there are two consecutive tildes to allow for the fact that this particular entry doesn't have anything in the <b>Editor</b> field. You can then perform a <em>Query</em> as follows:<p> -<samp>COPY psyref FROM '/home/jim/newref.txt' USING DELIMITERS +<samp>COPY psyref FROM '/home/jim/newref.txt' WITH DELIMITER '~';</samp><p> This will read the records from <samp>newref.txt</samp> and insert them into the table <samp>psyref</samp>. See the PostgreSQL documentation under the headings diff --git a/src/bin/pgaccess/lib/help/copy.hlp b/src/bin/pgaccess/lib/help/copy.hlp index eaf77a3ccab..88dd77e255b 100644 --- a/src/bin/pgaccess/lib/help/copy.hlp +++ b/src/bin/pgaccess/lib/help/copy.hlp @@ -5,10 +5,10 @@ and the name must be specified from the viewpoint of the backend. If stdin or st " {} " COPY \[ BINARY \] table \[ WITH OIDS \] FROM { 'filename' | stdin } - \[ USING DELIMITERS 'delimiter' \] + \[ WITH DELIMITER 'delimiter' \] COPY \[ BINARY \] table \[ WITH OIDS \] TO { 'filename' | stdout } - \[ USING DELIMITERS 'delimiter' \] + \[ WITH DELIMITER 'delimiter' \] " {code} "Inputs" {bold} " @@ -44,7 +44,7 @@ COPY \[ BINARY \] table \[ WITH OIDS \] " {} "Usage" {bold} " The following example copies a table to standard output, using a vertical bar \(\"|\"\) as the field delimiter: -COPY country TO stdout USING DELIMITERS '|'; +COPY country TO stdout WITH DELIMITER '|'; To copy data from a Unix file into a table \"country\": COPY country FROM '/usr1/proj/bray/sql/country_data'; @@ -93,13 +93,12 @@ The format for each instance in the file is as follows. Note that this format mu The " {} "BINARY" {bold} " keyword will force all data to be stored/read as binary objects rather than as text. It is somewhat faster than the normal copy command, but is not generally portable, and the files \ generated are somewhat larger, although this factor is highly dependent on the data itself. By default, a text copy uses a tab \ -\(\"\\t\"\) character as a delimiter. The delimiter may also be changed to any other single character with the keyword phrase USING DELIMITERS. Characters in data fields which happen to match the delimiter character will be quoted. +\(\"\\t\"\) character as a delimiter. The delimiter may also be changed to any other single character with the keyword phrase WITH DELIMITER. Characters in data fields which happen to match the delimiter character will be quoted. You must have select access on any table whose values are read by " {} "COPY" {bold} ", and either insert or update access to a table into which values are being inserted by \ " {} "COPY" {bold} ". The backend also needs appropriate Unix permissions for any file read or written by \ " {} "COPY" {bold} ". -The keyword phrase " {} "USING DELIMITERS" {bold} " specifies a single character to be used for all delimiters between columns. If multiple characters are specified in the delimiter string, only the first \ -character is used. +The keyword phrase " {} "WITH DELIMITER" {bold} " specifies a single character to be used for all delimiters between columns. Tip: Do not confuse " {} "COPY" {bold} " with the psql instruction \\copy. " diff --git a/src/bin/pgaccess/lib/mainlib.tcl b/src/bin/pgaccess/lib/mainlib.tcl index 781989cc7b4..5021d021db8 100644 --- a/src/bin/pgaccess/lib/mainlib.tcl +++ b/src/bin/pgaccess/lib/mainlib.tcl @@ -636,6 +636,8 @@ proc vTclWindow.pgaw:ImportExport {base} { if {$PgAcVar(impexp,delimiter)==""} { set sup "" } else { + # now we use WITH DELIMITER, but keep old syntax for + # backward compatibility. 2002-06-15 set sup " USING DELIMITERS '$PgAcVar(impexp,delimiter)'" } if {[.pgaw:ImportExport.expbtn cget -text]=="Import"} { diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index fb07b872795..32f875db84d 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.22 2002/04/24 21:00:10 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.23 2002/06/20 16:00:44 momjian Exp $ */ #include "postgres_fe.h" #include "copy.h" @@ -36,9 +36,12 @@ bool copy_in_state; * parse_slash_copy * -- parses \copy command line * - * Accepted syntax: \copy [binary] table|"table" [with oids] from|to filename|'filename' [ using delimiters '<char>'] [ with null as 'string' ] + * Accepted syntax: \copy table|"table" [with oids] from|to filename|'filename' [with ] [ oids ] [ delimiter '<char>'] [ null as 'string' ] * (binary is not here yet) * + * Old syntax for backward compatibility: (2002-06-19): + * \copy table|"table" [with oids] from|to filename|'filename' [ using delimiters '<char>'] [ with null as 'string' ] + * * returns a malloc'ed structure with the options, or NULL on parsing error */ @@ -120,6 +123,7 @@ parse_slash_copy(const char *args) error = true; else { + /* Allows old COPY syntax for backward compatibility 2002-06-19 */ if (strcasecmp(token, "with") == 0) { token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding); @@ -161,12 +165,11 @@ parse_slash_copy(const char *args) token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding); if (token) { + /* Allows old COPY syntax for backward compatibility 2002-06-19 */ if (strcasecmp(token, "using") == 0) { token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding); - if (!token || strcasecmp(token, "delimiters") != 0) - error = true; - else + if (token && strcasecmp(token, "delimiters") == 0) { token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding); if (token) @@ -177,32 +180,42 @@ parse_slash_copy(const char *args) else error = true; } + else + error = true; } + } + } - if (!error && token) + if (!error && token) + { + if (strcasecmp(token, "with") == 0) + { + while (!error && (token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding))) { - if (strcasecmp(token, "with") == 0) + if (strcasecmp(token, "delimiter") == 0) { - token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding); - if (!token || strcasecmp(token, "null") != 0) + token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding); + if (token && strcasecmp(token, "as") == 0) + token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding); + if (token) + result->delim = xstrdup(token); + else error = true; + } + else if (strcasecmp(token, "null") == 0) + { + token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding); + if (token && strcasecmp(token, "as") == 0) + token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding); + if (token) + result->null = xstrdup(token); else - { - token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding); - if (!token || strcasecmp(token, "as") != 0) - error = true; - else - { - token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding); - if (token) - result->null = xstrdup(token); - } - } + error = true; } - else - error = true; + else error = true; } } + else error = true; } free(line); @@ -250,6 +263,7 @@ do_copy(const char *args) appendPQExpBuffer(&query, "BINARY "); appendPQExpBuffer(&query, "\"%s\" ", options->table); + /* Uses old COPY syntax for backward compatibility 2002-06-19 */ if (options->oids) appendPQExpBuffer(&query, "WITH OIDS "); @@ -259,6 +273,7 @@ do_copy(const char *args) appendPQExpBuffer(&query, "TO STDOUT"); + /* Uses old COPY syntax for backward compatibility 2002-06-19 */ if (options->delim) appendPQExpBuffer(&query, " USING DELIMITERS '%s'", options->delim); @@ -298,7 +313,7 @@ do_copy(const char *args) free_copy_options(options); return false; } - + result = PSQLexec(query.data); termPQExpBuffer(&query); diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h index e0a4ecdcd40..40cbb351957 100644 --- a/src/include/commands/copy.h +++ b/src/include/commands/copy.h @@ -7,19 +7,18 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: copy.h,v 1.17 2002/03/29 19:06:21 tgl Exp $ + * $Id: copy.h,v 1.18 2002/06/20 16:00:44 momjian Exp $ * *------------------------------------------------------------------------- */ #ifndef COPY_H #define COPY_H +#include "nodes/parsenodes.h" #include "nodes/primnodes.h" extern int copy_lineno; -void DoCopy(const RangeVar *relation, bool binary, bool oids, - bool from, bool pipe, - char *filename, char *delim, char *null_print); +void DoCopy(const CopyStmt *stmt); #endif /* COPY_H */ diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index 1a99da6d4da..c4c9f56eece 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: dbcommands.h,v 1.22 2002/06/18 17:27:58 momjian Exp $ + * $Id: dbcommands.h,v 1.23 2002/06/20 16:00:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -16,7 +16,7 @@ #include <nodes/parsenodes.h> -extern void createdb(CreatedbStmt *stmt); +extern void createdb(const CreatedbStmt *stmt); extern void dropdb(const char *dbname); extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 01b90ce0285..627c30c6441 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.180 2002/06/18 17:27:58 momjian Exp $ + * $Id: parsenodes.h,v 1.181 2002/06/20 16:00:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -851,13 +851,10 @@ typedef struct ClosePortalStmt typedef struct CopyStmt { NodeTag type; - bool binary; /* is a binary copy? */ RangeVar *relation; /* the relation to copy */ - bool oids; /* copy oid's? */ - int direction; /* TO or FROM */ + bool is_from; /* TO or FROM */ char *filename; /* if NULL, use stdin/stdout */ - char *delimiter; /* delimiter character, \t by default */ - char *null_print; /* how to print NULLs, `\N' by default */ + List *options; /* List of DefElem nodes */ } CopyStmt; /* ---------------------- diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java index 3c447a88b4b..5fba1d68c00 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java @@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException; /* * This class provides information about the database as a whole. * - * $Id: DatabaseMetaData.java,v 1.46 2002/06/11 02:55:16 barry Exp $ + * $Id: DatabaseMetaData.java,v 1.47 2002/06/20 16:00:44 momjian Exp $ * * <p>Many of the methods here return lists of information in ResultSets. You * can use the normal ResultSet methods such as getString and getInt to @@ -370,7 +370,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData */ public String getSQLKeywords() throws SQLException { - return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version"; + return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiter,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version"; } public String getNumericFunctions() throws SQLException diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java index a6130720ddb..e38f4c18e5a 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java @@ -15,7 +15,7 @@ import org.postgresql.util.PSQLException; /* * This class provides information about the database as a whole. * - * $Id: DatabaseMetaData.java,v 1.55 2002/06/11 02:55:16 barry Exp $ + * $Id: DatabaseMetaData.java,v 1.56 2002/06/20 16:00:44 momjian Exp $ * * <p>Many of the methods here return lists of information in ResultSets. You * can use the normal ResultSet methods such as getString and getInt to @@ -409,7 +409,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData public String getSQLKeywords() throws SQLException { if (Driver.logDebug) Driver.debug("getSQLKeyWords"); - return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version"; + return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiter,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version"; } public String getNumericFunctions() throws SQLException diff --git a/src/test/locale/de_DE.ISO8859-1/test-de-upper.sql.in b/src/test/locale/de_DE.ISO8859-1/test-de-upper.sql.in index 5b2b32750e7..5149f8cd672 100644 --- a/src/test/locale/de_DE.ISO8859-1/test-de-upper.sql.in +++ b/src/test/locale/de_DE.ISO8859-1/test-de-upper.sql.in @@ -1,4 +1,4 @@ -COPY wordlist FROM stdin USING DELIMITERS '|'; +COPY wordlist FROM stdin WITH DELIMITER '|'; AAA |ÄÄÄ AAAAa |ÄÄÄÄä BBBB |BBBB diff --git a/src/test/locale/de_DE.ISO8859-1/test-de.sql.in b/src/test/locale/de_DE.ISO8859-1/test-de.sql.in index c0b0dbd4952..7108d0290ef 100644 --- a/src/test/locale/de_DE.ISO8859-1/test-de.sql.in +++ b/src/test/locale/de_DE.ISO8859-1/test-de.sql.in @@ -1,4 +1,4 @@ -COPY wordlist FROM stdin USING DELIMITERS '|'; +COPY wordlist FROM stdin WITH DELIMITER '|'; AAA |ÄÄÄ AAAAa |ÄÄÄÄä BBBB |BBBB diff --git a/src/test/locale/gr_GR.ISO8859-7/test-gr.sql.in b/src/test/locale/gr_GR.ISO8859-7/test-gr.sql.in index 8cb638882e0..781f4efcadd 100644 --- a/src/test/locale/gr_GR.ISO8859-7/test-gr.sql.in +++ b/src/test/locale/gr_GR.ISO8859-7/test-gr.sql.in @@ -1,4 +1,4 @@ -COPY usastates FROM stdin USING DELIMITERS '|'; +COPY usastates FROM stdin WITH DELIMITER '|'; AK|Alaska |ÁëÜóêá WA|Washington |Ãïõüóéíãêôïí OR|Oregon |Ïñåãêïí diff --git a/src/test/locale/koi8-r/test-koi8.sql.in b/src/test/locale/koi8-r/test-koi8.sql.in index 784d440d2f3..6be83923bee 100644 --- a/src/test/locale/koi8-r/test-koi8.sql.in +++ b/src/test/locale/koi8-r/test-koi8.sql.in @@ -1,4 +1,4 @@ -COPY usastates FROM stdin USING DELIMITERS '|'; +COPY usastates FROM stdin WITH DELIMITER '|'; AK|Alaska |áÌÑÓËÁ WA|Washington |÷ÁÛÉÎÇÔÏÎ OR|Oregon |ïÒÅÇÏÎ diff --git a/src/test/locale/koi8-to-win1251/test-koi8.sql.in b/src/test/locale/koi8-to-win1251/test-koi8.sql.in index 2a5e8175f5f..244e495176a 100644 --- a/src/test/locale/koi8-to-win1251/test-koi8.sql.in +++ b/src/test/locale/koi8-to-win1251/test-koi8.sql.in @@ -1,4 +1,4 @@ -COPY usastates FROM stdin USING DELIMITERS '|'; +COPY usastates FROM stdin WITH DELIMITER '|'; AK|Alaska |Àëÿñêà WA|Washington |Âàøèíãòîí OR|Oregon |Îðåãîí |