diff options
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r-- | src/backend/commands/copy.c | 43 |
1 files changed, 26 insertions, 17 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: |