diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c index a280efe23f9..654fecb1b14 100644 --- a/src/backend/commands/copyfromparse.c +++ b/src/backend/commands/copyfromparse.c @@ -1403,7 +1403,7 @@ CopyReadLineText(CopyFromState cstate) else if (c2 != '\r') ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), - errmsg("end-of-copy marker corrupt"))); + errmsg("end-of-copy marker is not alone on its line"))); } /* Get the next character */ @@ -1414,25 +1414,27 @@ CopyReadLineText(CopyFromState cstate) if (c2 != '\r' && c2 != '\n') ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), - errmsg("end-of-copy marker corrupt"))); + errmsg("end-of-copy marker is not alone on its line"))); if ((cstate->eol_type == EOL_NL && c2 != '\n') || (cstate->eol_type == EOL_CRNL && c2 != '\n') || (cstate->eol_type == EOL_CR && c2 != '\r')) - { ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), errmsg("end-of-copy marker does not match previous newline style"))); - } /* - * Transfer only the data before the \. into line_buf, then - * discard the data and the \. sequence. + * If there is any data on this line before the \., complain. + */ + if (cstate->line_buf.len > 0 || + prev_raw_ptr > cstate->input_buf_index) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("end-of-copy marker is not alone on its line"))); + + /* + * Discard the \. and newline, then report EOF. */ - if (prev_raw_ptr > cstate->input_buf_index) - appendBinaryStringInfo(&cstate->line_buf, - cstate->input_buf + cstate->input_buf_index, - prev_raw_ptr - cstate->input_buf_index); cstate->input_buf_index = input_buf_ptr; result = true; /* report EOF */ break; diff --git a/src/test/regress/expected/copy.out b/src/test/regress/expected/copy.out index 174fe056033..f554d42c84c 100644 --- a/src/test/regress/expected/copy.out +++ b/src/test/regress/expected/copy.out @@ -50,6 +50,19 @@ select test from copytest2 order by test collate "C"; line2 (3 rows) +-- in text mode, \. must be alone on its line +truncate copytest2; +copy copytest2(test) from stdin; +ERROR: end-of-copy marker is not alone on its line +CONTEXT: COPY copytest2, line 3 +copy copytest2(test) from stdin; +ERROR: end-of-copy marker is not alone on its line +CONTEXT: COPY copytest2, line 3 +select test from copytest2; + test +------ +(0 rows) + -- test header line feature create temp table copytest3 ( c1 int, diff --git a/src/test/regress/sql/copy.sql b/src/test/regress/sql/copy.sql index 8ed7922ab49..f1699b66b04 100644 --- a/src/test/regress/sql/copy.sql +++ b/src/test/regress/sql/copy.sql @@ -50,6 +50,22 @@ truncate copytest2; copy copytest2(test) from :'filename' csv; select test from copytest2 order by test collate "C"; +-- in text mode, \. must be alone on its line +truncate copytest2; +copy copytest2(test) from stdin; +line1 +line2 +foo\. +line3 +\. +copy copytest2(test) from stdin; +line4 +line5 +\.foo +line6 +\. +select test from copytest2; + -- test header line feature