6
6
*
7
7
*
8
8
* IDENTIFICATION
9
- * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.92 1999/11/27 21:52:53 tgl Exp $
9
+ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.93 1999/12/14 00:08:13 momjian Exp $
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
43
43
44
44
45
45
/* non-export function prototypes */
46
- static void CopyTo (Relation rel , bool binary , bool oids , FILE * fp , char * delim );
47
- static void CopyFrom (Relation rel , bool binary , bool oids , FILE * fp , char * delim );
46
+ static void CopyTo (Relation rel , bool binary , bool oids , FILE * fp , char * delim , char * null_print );
47
+ static void CopyFrom (Relation rel , bool binary , bool oids , FILE * fp , char * delim , char * null_print );
48
48
static Oid GetOutputFunction (Oid type );
49
49
static Oid GetTypeElement (Oid type );
50
50
static Oid GetInputFunction (Oid type );
@@ -54,7 +54,7 @@ static void GetIndexRelations(Oid main_relation_oid,
54
54
Relation * * index_rels );
55
55
56
56
static void CopyReadNewline (FILE * fp , int * newline );
57
- static char * CopyReadAttribute (FILE * fp , bool * isnull , char * delim , int * newline );
57
+ static char * CopyReadAttribute (FILE * fp , bool * isnull , char * delim , int * newline , char * null_print );
58
58
59
59
static void CopyAttributeOut (FILE * fp , char * string , char * delim );
60
60
static int CountTuples (Relation relation );
@@ -219,7 +219,7 @@ CopyDonePeek(FILE *fp, int c, int pickup)
219
219
220
220
void
221
221
DoCopy (char * relname , bool binary , bool oids , bool from , bool pipe ,
222
- char * filename , char * delim , int fileumask )
222
+ char * filename , char * delim , char * null_print , int fileumask )
223
223
{
224
224
/*----------------------------------------------------------------------------
225
225
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,
232
232
Iff <binary>, unload or reload in the binary format, as opposed to the
233
233
more wasteful but more robust and portable text format.
234
234
235
- If in the text format, delimit columns with delimiter <delim>.
235
+ If in the text format, delimit columns with delimiter <delim> and print
236
+ NULL values as <null_print>.
236
237
237
238
<fileumask> is the umask(2) setting to use while creating an output file.
238
239
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,
304
305
"reading. Errno = %s (%d)." ,
305
306
geteuid (), filename , strerror (errno ), errno );
306
307
}
307
- CopyFrom (rel , binary , oids , fp , delim );
308
+ CopyFrom (rel , binary , oids , fp , delim , null_print );
308
309
}
309
310
else
310
311
{ /* copy from database to file */
@@ -336,7 +337,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
336
337
"writing. Errno = %s (%d)." ,
337
338
geteuid (), filename , strerror (errno ), errno );
338
339
}
339
- CopyTo (rel , binary , oids , fp , delim );
340
+ CopyTo (rel , binary , oids , fp , delim , null_print );
340
341
}
341
342
if (!pipe )
342
343
{
@@ -362,7 +363,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
362
363
363
364
364
365
static void
365
- CopyTo (Relation rel , bool binary , bool oids , FILE * fp , char * delim )
366
+ CopyTo (Relation rel , bool binary , bool oids , FILE * fp , char * delim , char * null_print )
366
367
{
367
368
HeapTuple tuple ;
368
369
HeapScanDesc scandesc ;
@@ -449,7 +450,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
449
450
pfree (string );
450
451
}
451
452
else
452
- CopySendString ("\\N" , fp ); /* null indicator */
453
+ CopySendString (null_print , fp ); /* null indicator */
453
454
454
455
if (i == attr_count - 1 )
455
456
CopySendChar ('\n' , fp );
@@ -520,7 +521,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
520
521
}
521
522
522
523
static void
523
- CopyFrom (Relation rel , bool binary , bool oids , FILE * fp , char * delim )
524
+ CopyFrom (Relation rel , bool binary , bool oids , FILE * fp , char * delim , char * null_print )
524
525
{
525
526
HeapTuple tuple ;
526
527
AttrNumber attr_count ;
@@ -711,7 +712,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
711
712
lineno ++ ;
712
713
if (oids )
713
714
{
714
- string = CopyReadAttribute (fp , & isnull , delim , & newline );
715
+ string = CopyReadAttribute (fp , & isnull , delim , & newline , null_print );
715
716
if (string == NULL )
716
717
done = 1 ;
717
718
else
@@ -724,7 +725,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
724
725
}
725
726
for (i = 0 ; i < attr_count && !done ; i ++ )
726
727
{
727
- string = CopyReadAttribute (fp , & isnull , delim , & newline );
728
+ string = CopyReadAttribute (fp , & isnull , delim , & newline , null_print );
728
729
if (isnull )
729
730
{
730
731
values [i ] = PointerGetDatum (NULL );
@@ -1122,10 +1123,11 @@ CopyReadNewline(FILE *fp, int *newline)
1122
1123
*
1123
1124
* delim is the string of acceptable delimiter characters(s).
1124
1125
* *newline remembers whether we've seen a newline ending this tuple.
1126
+ * null_print says how NULL values are represented
1125
1127
*/
1126
1128
1127
1129
static char *
1128
- CopyReadAttribute (FILE * fp , bool * isnull , char * delim , int * newline )
1130
+ CopyReadAttribute (FILE * fp , bool * isnull , char * delim , int * newline , char * null_print )
1129
1131
{
1130
1132
StringInfoData attribute_buf ;
1131
1133
char c ;
@@ -1207,6 +1209,13 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
1207
1209
c = val & 0377 ;
1208
1210
}
1209
1211
break ;
1212
+ /* This is a special hack to parse `\N' as <backslash-N>
1213
+ rather then just 'N' to provide compatibility with
1214
+ the default NULL output. -- pe */
1215
+ case 'N' :
1216
+ appendStringInfoChar (& attribute_buf , '\\' );
1217
+ c = 'N' ;
1218
+ break ;
1210
1219
case 'b' :
1211
1220
c = '\b' ;
1212
1221
break ;
@@ -1225,9 +1234,6 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
1225
1234
case 'v' :
1226
1235
c = '\v' ;
1227
1236
break ;
1228
- case 'N' :
1229
- * isnull = (bool ) true;
1230
- break ;
1231
1237
case '.' :
1232
1238
c = CopyGetChar (fp );
1233
1239
if (c != '\n' )
@@ -1266,6 +1272,9 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
1266
1272
return cvt ;
1267
1273
}
1268
1274
#endif
1275
+ if (strcmp (attribute_buf .data , null_print )== 0 )
1276
+ * isnull = true;
1277
+
1269
1278
return attribute_buf .data ;
1270
1279
1271
1280
endOfFile :
0 commit comments