diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/commands/copy.c | 77 | ||||
-rw-r--r-- | src/backend/commands/dbcommands.c | 4 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 11 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 12 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 134 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 3 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 18 |
7 files changed, 179 insertions, 80 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; |