aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/copy.c43
-rw-r--r--src/backend/commands/user.c3
-rw-r--r--src/backend/parser/gram.y9
-rw-r--r--src/backend/tcop/utility.c3
-rw-r--r--src/include/commands/copy.h4
-rw-r--r--src/include/nodes/parsenodes.h3
6 files changed, 40 insertions, 25 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 5f3f2455acd..04ee4fc8708 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.92 1999/11/27 21:52:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.93 1999/12/14 00:08:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,8 +43,8 @@
/* non-export function prototypes */
-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 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 Oid GetOutputFunction(Oid type);
static Oid GetTypeElement(Oid type);
static Oid GetInputFunction(Oid type);
@@ -54,7 +54,7 @@ static void GetIndexRelations(Oid main_relation_oid,
Relation **index_rels);
static void CopyReadNewline(FILE *fp, int *newline);
-static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, 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 int CountTuples(Relation relation);
@@ -219,7 +219,7 @@ CopyDonePeek(FILE *fp, int c, int pickup)
void
DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
- char *filename, char *delim, int fileumask)
+ char *filename, char *delim, char *null_print, int fileumask)
{
/*----------------------------------------------------------------------------
Either unload or reload contents of class <relname>, depending on <from>.
@@ -232,7 +232,8 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
Iff <binary>, unload or reload in the binary format, as opposed to the
more wasteful but more robust and portable text format.
- If in the text format, delimit columns with delimiter <delim>.
+ If in the text format, delimit columns with delimiter <delim> and print
+ NULL values as <null_print>.
<fileumask> is the umask(2) setting to use while creating an output file.
This should usually be more liberal than the backend's normal 077 umask,
@@ -304,7 +305,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
"reading. Errno = %s (%d).",
geteuid(), filename, strerror(errno), errno);
}
- CopyFrom(rel, binary, oids, fp, delim);
+ CopyFrom(rel, binary, oids, fp, delim, null_print);
}
else
{ /* copy from database to file */
@@ -336,7 +337,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
"writing. Errno = %s (%d).",
geteuid(), filename, strerror(errno), errno);
}
- CopyTo(rel, binary, oids, fp, delim);
+ CopyTo(rel, binary, oids, fp, delim, null_print);
}
if (!pipe)
{
@@ -362,7 +363,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
static void
-CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
+CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print)
{
HeapTuple tuple;
HeapScanDesc scandesc;
@@ -449,7 +450,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
pfree(string);
}
else
- CopySendString("\\N", fp); /* null indicator */
+ CopySendString(null_print, fp); /* null indicator */
if (i == attr_count - 1)
CopySendChar('\n', fp);
@@ -520,7 +521,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
}
static void
-CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
+CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print)
{
HeapTuple tuple;
AttrNumber attr_count;
@@ -711,7 +712,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
lineno++;
if (oids)
{
- string = CopyReadAttribute(fp, &isnull, delim, &newline);
+ string = CopyReadAttribute(fp, &isnull, delim, &newline, null_print);
if (string == NULL)
done = 1;
else
@@ -724,7 +725,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
}
for (i = 0; i < attr_count && !done; i++)
{
- string = CopyReadAttribute(fp, &isnull, delim, &newline);
+ string = CopyReadAttribute(fp, &isnull, delim, &newline, null_print);
if (isnull)
{
values[i] = PointerGetDatum(NULL);
@@ -1122,10 +1123,11 @@ CopyReadNewline(FILE *fp, int *newline)
*
* delim is the string of acceptable delimiter characters(s).
* *newline remembers whether we've seen a newline ending this tuple.
+ * null_print says how NULL values are represented
*/
static char *
-CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
+CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print)
{
StringInfoData attribute_buf;
char c;
@@ -1207,6 +1209,13 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
c = val & 0377;
}
break;
+ /* This is a special hack to parse `\N' as <backslash-N>
+ rather then just 'N' to provide compatibility with
+ the default NULL output. -- pe */
+ case 'N':
+ appendStringInfoChar(&attribute_buf, '\\');
+ c = 'N';
+ break;
case 'b':
c = '\b';
break;
@@ -1225,9 +1234,6 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
case 'v':
c = '\v';
break;
- case 'N':
- *isnull = (bool) true;
- break;
case '.':
c = CopyGetChar(fp);
if (c != '\n')
@@ -1266,6 +1272,9 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
return cvt;
}
#endif
+ if (strcmp(attribute_buf.data, null_print)==0)
+ *isnull = true;
+
return attribute_buf.data;
endOfFile:
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 1cf07325473..56dce87f7e0 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: user.c,v 1.41 1999/12/12 05:57:28 momjian Exp $
+ * $Id: user.c,v 1.42 1999/12/14 00:08:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -77,6 +77,7 @@ update_pg_pwd()
false, /* pipe */
tempname, /* filename */
CRYPT_PWD_FILE_SEPSTR, /* delim */
+ "", /* nulls */
0077); /* fileumask */
/*
* And rename the temp file to its final name, deleting the old pg_pwd.
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index d3fb6291806..25f8dd02bb8 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.121 1999/12/10 07:37:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.122 1999/12/14 00:08:15 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -147,7 +147,7 @@ static Node *doNegate(Node *n);
%type <str> TriggerEvents, TriggerFuncArg
-%type <str> relation_name, copy_file_name, copy_delimiter, def_name,
+%type <str> relation_name, copy_file_name, copy_delimiter, copy_null, def_name,
database_name, access_method_clause, access_method, attr_name,
class, index_name, name, func_name, file_name, aggr_argtype
@@ -802,7 +802,7 @@ opt_id: ColId { $$ = $1; }
*
*****************************************************************************/
-CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
+CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
{
CopyStmt *n = makeNode(CopyStmt);
n->binary = $2;
@@ -811,6 +811,7 @@ CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name
n->direction = $5;
n->filename = $6;
n->delimiter = $7;
+ n->null_print = $8;
$$ = (Node *)n;
}
;
@@ -850,6 +851,8 @@ opt_using: USING { $$ = TRUE; }
| /*EMPTY*/ { $$ = TRUE; }
;
+copy_null: WITH NULL_P AS Sconst { $$ = $4; }
+ | /*EMPTY*/ { $$ = "\\N"; }
/*****************************************************************************
*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 6c22afa5458..bfc114ba2f7 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.73 1999/12/10 03:55:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.74 1999/12/14 00:08:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -269,6 +269,7 @@ ProcessUtility(Node *parsetree,
*/
stmt->filename,
stmt->delimiter,
+ stmt->null_print,
/*
* specify 022 umask while writing files with COPY.
*/
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index 5e7355b7e91..1f2af72122b 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: copy.h,v 1.6 1999/11/21 04:16:17 tgl Exp $
+ * $Id: copy.h,v 1.7 1999/12/14 00:08:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,6 +15,6 @@
void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
- char *filename, char *delim, int fileumask);
+ char *filename, char *delim, char *null_print, int fileumask);
#endif /* COPY_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index df0cb5c4e54..45e586aad0c 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.90 1999/12/10 07:37:32 tgl Exp $
+ * $Id: parsenodes.h,v 1.91 1999/12/14 00:08:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -130,6 +130,7 @@ typedef struct CopyStmt
int direction; /* 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 */
} CopyStmt;
/* ----------------------