Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc3b7d2d

Browse files
committed
Allow \r and \r\n termination for COPY files.
Output \r\n termination on Win32.Disallow literal carriage return as a data value,backslash-carriage-return and \r still allowed.Doc changes already committed.
1 parent9c48cae commitc3b7d2d

File tree

1 file changed

+84
-11
lines changed

1 file changed

+84
-11
lines changed

‎src/backend/commands/copy.c

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.193 2003/04/1919:55:37 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.194 2003/04/1920:36:03 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -50,6 +50,13 @@
5050
#defineISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
5151
#defineOCTVALUE(c) ((c) - '0')
5252

53+
/* Default line termination */
54+
#ifndefWIN32
55+
#definePGEOL"\n"
56+
#else
57+
#definePGEOL"\r\n"
58+
#endif
59+
5360
/*
5461
* Represents the different source/dest cases we need to worry about at
5562
* the bottom level
@@ -71,9 +78,21 @@ typedef enum CopyReadResult
7178
END_OF_FILE
7279
}CopyReadResult;
7380

81+
/*
82+
*Represents the end-of-line terminator of the input
83+
*/
84+
typedefenumEolType
85+
{
86+
EOL_UNKNOWN,
87+
EOL_NL,
88+
EOL_CR,
89+
EOL_CRNL
90+
}EolType;
91+
92+
7493
/* non-export function prototypes */
7594
staticvoidCopyTo(Relationrel,List*attnumlist,boolbinary,booloids,
76-
char*delim,char*null_print);
95+
boolpipe,char*delim,char*null_print);
7796
staticvoidCopyFrom(Relationrel,List*attnumlist,boolbinary,booloids,
7897
char*delim,char*null_print);
7998
staticOidGetInputFunction(Oidtype);
@@ -82,7 +101,8 @@ static char *CopyReadAttribute(const char *delim, CopyReadResult *result);
82101
staticvoidCopyAttributeOut(char*string,char*delim);
83102
staticList*CopyGetAttnums(Relationrel,List*attnamelist);
84103

85-
staticconstcharBinarySignature[12]="PGBCOPY\n\377\r\n\0";
104+
/* The trailing null is part of the signature */
105+
staticconstcharBinarySignature[]="PGBCOPY\n\377\r\n";
86106

87107
/*
88108
* Static communication variables ... pretty grotty, but COPY has
@@ -94,6 +114,7 @@ static CopyDest copy_dest;
94114
staticFILE*copy_file;/* if copy_dest == COPY_FILE */
95115
staticStringInfocopy_msgbuf;/* if copy_dest == COPY_NEW_FE */
96116
staticboolfe_eof;/* true if detected end of copy data */
117+
staticEolTypeeol_type;
97118

98119
/*
99120
* These static variables are used to avoid incurring overhead for each
@@ -181,7 +202,10 @@ static void
181202
SendCopyEnd(boolbinary,boolpipe)
182203
{
183204
if (!binary)
184-
CopySendData("\\.\n",3);
205+
{
206+
CopySendString("\\.");
207+
CopySendString(!pipe ?PGEOL :"\n");
208+
}
185209
pq_endcopyout(false);
186210
}
187211

@@ -674,7 +698,7 @@ DoCopy(const CopyStmt *stmt)
674698
elog(ERROR,"COPY: %s is a directory",filename);
675699
}
676700
}
677-
CopyTo(rel,attnumlist,binary,oids,delim,null_print);
701+
CopyTo(rel,attnumlist,binary,oids,pipe,delim,null_print);
678702
}
679703

680704
if (!pipe)
@@ -697,7 +721,7 @@ DoCopy(const CopyStmt *stmt)
697721
* Copy from relation TO file.
698722
*/
699723
staticvoid
700-
CopyTo(Relationrel,List*attnumlist,boolbinary,booloids,
724+
CopyTo(Relationrel,List*attnumlist,boolbinary,booloids,boolpipe,
701725
char*delim,char*null_print)
702726
{
703727
HeapTupletuple;
@@ -762,7 +786,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
762786
int32tmp;
763787

764788
/* Signature */
765-
CopySendData((char*)BinarySignature,12);
789+
CopySendData((char*)BinarySignature,sizeof(BinarySignature));
766790
/* Integer layout field */
767791
tmp=0x01020304;
768792
CopySendData(&tmp,sizeof(int32));
@@ -895,7 +919,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
895919
}
896920

897921
if (!binary)
898-
CopySendChar('\n');
922+
CopySendString(!pipe ?PGEOL :"\n");
899923

900924
MemoryContextSwitchTo(oldcontext);
901925
}
@@ -1076,7 +1100,8 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
10761100

10771101
/* Signature */
10781102
CopyGetData(readSig,12);
1079-
if (CopyGetEof()||memcmp(readSig,BinarySignature,12)!=0)
1103+
if (CopyGetEof()||memcmp(readSig,BinarySignature,
1104+
sizeof(BinarySignature))!=0)
10801105
elog(ERROR,"COPY BINARY: file signature not recognized");
10811106
/* Integer layout field */
10821107
CopyGetData(&tmp,sizeof(int32));
@@ -1108,6 +1133,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
11081133

11091134
/* Initialize static variables */
11101135
copy_lineno=0;
1136+
eol_type=EOL_UNKNOWN;
11111137
fe_eof= false;
11121138

11131139
/* Make room for a PARAM_EXEC value for domain constraint checks */
@@ -1520,8 +1546,44 @@ CopyReadAttribute(const char *delim, CopyReadResult *result)
15201546
*result=END_OF_FILE;
15211547
gotocopy_eof;
15221548
}
1549+
if (c=='\r')
1550+
{
1551+
if (eol_type==EOL_NL)
1552+
elog(ERROR,"CopyReadAttribute: Literal carriage return data value\n"
1553+
"found in input that has newline termination; use \\r");
1554+
1555+
/*Check for \r\n on first line, _and_ handle \r\n. */
1556+
if (copy_lineno==1||eol_type==EOL_CRNL)
1557+
{
1558+
intc2=CopyPeekChar();
1559+
if (c2=='\n')
1560+
{
1561+
CopyDonePeek(c2, true);/* eat newline */
1562+
eol_type=EOL_CRNL;
1563+
}
1564+
else
1565+
{
1566+
/* found \r, but no \n */
1567+
if (eol_type==EOL_CRNL)
1568+
elog(ERROR,"CopyReadAttribute: Literal carriage return data value\n"
1569+
"found in input that has carriage return/newline termination; use \\r");
1570+
/* if we got here, it is the first line and we didn't get \n, so put it back */
1571+
CopyDonePeek(c2, false);
1572+
eol_type=EOL_CR;
1573+
}
1574+
}
1575+
*result=END_OF_LINE;
1576+
break;
1577+
}
15231578
if (c=='\n')
15241579
{
1580+
if (eol_type==EOL_CRNL)
1581+
elog(ERROR,"CopyReadAttribute: Literal newline data value found in input\n"
1582+
"that has carriage return/newline termination; use \\n");
1583+
if (eol_type==EOL_CR)
1584+
elog(ERROR,"CopyReadAttribute: Literal newline data value found in input\n"
1585+
"that has carriage return termination; use \\n");
1586+
eol_type=EOL_NL;
15251587
*result=END_OF_LINE;
15261588
break;
15271589
}
@@ -1611,9 +1673,20 @@ CopyReadAttribute(const char *delim, CopyReadResult *result)
16111673
c='\v';
16121674
break;
16131675
case'.':
1676+
if (eol_type==EOL_CRNL)
1677+
{
1678+
c=CopyGetChar();
1679+
if (c=='\n')
1680+
elog(ERROR,"CopyReadAttribute: end-of-copy termination does not match previous input");
1681+
if (c!='\r')
1682+
elog(ERROR,"CopyReadAttribute: end-of-copy marker corrupt");
1683+
}
16141684
c=CopyGetChar();
1615-
if (c!='\n')
1616-
elog(ERROR,"CopyReadAttribute: end of record marker corrupted");
1685+
if (c!='\r'&&c!='\n')
1686+
elog(ERROR,"CopyReadAttribute: end-of-copy marker corrupt");
1687+
if (((eol_type==EOL_NL||eol_type==EOL_CRNL)&&c!='\n')||
1688+
(eol_type==EOL_CR&&c!='\r'))
1689+
elog(ERROR,"CopyReadAttribute: end-of-copy termination does not match previous input");
16171690
/*
16181691
* In protocol version 3, we should ignore anything after
16191692
* \. up to the protocol end of copy data. (XXX maybe

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp