Index: src/backend/commands/copy.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/copy.c,v retrieving revision 1.254.2.1 diff -c -c -r1.254.2.1 copy.c *** src/backend/commands/copy.c 22 Nov 2005 18:23:07 -0000 1.254.2.1 --- src/backend/commands/copy.c 27 Dec 2005 01:38:22 -0000 *************** *** 2338,2343 **** --- 2338,2344 ---- bool need_data; bool hit_eof; char s[2]; + bool first_char_in_line = true; bool in_quote = false, last_was_esc = false; char quotec = cstate->quote[0]; *************** *** 2531,2537 **** /* * In CSV mode, we only recognize \. at start of line */ ! if (c == '\\' && cstate->line_buf.len == 0) { char c2; --- 2532,2538 ---- /* * In CSV mode, we only recognize \. at start of line */ ! if (c == '\\' && first_char_in_line) { char c2; *************** *** 2577,2589 **** /* if hit_eof, c2 will become '\0' */ c2 = copy_raw_buf[raw_buf_ptr++]; if (c2 == '\n') ! ereport(ERROR, ! (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), ! errmsg("end-of-copy marker does not match previous newline style"))); if (c2 != '\r') ! ereport(ERROR, ! (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), ! errmsg("end-of-copy marker corrupt"))); } if (raw_buf_ptr >= copy_buf_len && !hit_eof) { --- 2578,2592 ---- /* if hit_eof, c2 will become '\0' */ c2 = copy_raw_buf[raw_buf_ptr++]; if (c2 == '\n') ! { ! raw_buf_ptr = prev_raw_ptr + 1; ! goto not_end_of_copy; ! } if (c2 != '\r') ! { ! raw_buf_ptr = prev_raw_ptr + 1; ! goto not_end_of_copy; ! } } if (raw_buf_ptr >= copy_buf_len && !hit_eof) { *************** *** 2594,2609 **** /* if hit_eof, c2 will become '\0' */ c2 = copy_raw_buf[raw_buf_ptr++]; if (c2 != '\r' && c2 != '\n') ! ereport(ERROR, ! (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), ! errmsg("end-of-copy marker corrupt"))); 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. --- 2597,2612 ---- /* if hit_eof, c2 will become '\0' */ c2 = copy_raw_buf[raw_buf_ptr++]; if (c2 != '\r' && c2 != '\n') ! { ! raw_buf_ptr = prev_raw_ptr + 1; ! goto not_end_of_copy; ! } 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. *************** *** 2618,2628 **** } /* ! * Do we need to be careful about trailing bytes of multibyte ! * characters? (See note above about client_only_encoding) ! * ! * We assume here that pg_encoding_mblen only looks at the first byte ! * of the character! */ if (cstate->client_only_encoding) { --- 2621,2635 ---- } /* ! * This label is for CSV cases where \. appears at the start of a line, ! * but there is more text after it, meaning it was a data value. ! * We are more strict for \. in CSV mode because \. could be a data ! * value, while in non-CSV mode, \. cannot be a data value. ! */ ! not_end_of_copy: ! ! /* ! * Process all bytes of a multi-byte character as a group. */ if (cstate->client_only_encoding) { *************** *** 2645,2650 **** --- 2652,2658 ---- } raw_buf_ptr += mblen - 1; } + first_char_in_line = false; } /* end of outer loop */ /*