/* This consumes the remainder of the buffer and breaks */ #define IF_NEED_REFILL_AND_EOF_BREAK(extralen) \ if (1) \
{ \ if (input_buf_ptr + (extralen) >= copy_buf_len && hit_eof) \
{ \ if (extralen) \
input_buf_ptr = copy_buf_len; /* consume the partial character */ \ /* backslash just before EOF, treat as data char */ \
result = true; \ break; \
} \
} else ((void) 0)
void
ReceiveCopyBegin(CopyFromState cstate)
{
StringInfoData buf; int natts = list_length(cstate->attnumlist);
int16 format = (cstate->opts.binary ? 1 : 0); int i;
pq_beginmessage(&buf, PqMsg_CopyInResponse);
pq_sendbyte(&buf, format); /* overall format */
pq_sendint16(&buf, natts); for (i = 0; i < natts; i++)
pq_sendint16(&buf, format); /* per-column formats */
pq_endmessage(&buf);
cstate->copy_src = COPY_FRONTEND;
cstate->fe_msgbuf = makeStringInfo(); /* We *must* flush here to ensure FE knows it can send. */
pq_flush();
}
/* *CopyGetDatareadsdatafromthesource(fileorfrontend) * *Weattempttoreadatleastminread,andatmostmaxread,bytesfrom *thesource.Theactualnumberofbytesreadisreturned;ifthisis *lessthanminread,EOFwasdetected. * *Note:whencopyingfromthefrontend,weexpectaproperEOFmarkper *protocol;ifthefrontendsimplydropstheconnection,weraiseerror. *ItseemsunwisetoallowtheCOPYINtocompletenormallyinthatcase. * *NB:nodataconversionisappliedhere.
*/ staticint
CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
{ int bytesread = 0;
switch (cstate->copy_src)
{ case COPY_FILE:
bytesread = fread(databuf, 1, maxread, cstate->copy_file); if (ferror(cstate->copy_file))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read from COPY file: %m"))); if (bytesread == 0)
cstate->raw_reached_eof = true; break; case COPY_FRONTEND: while (maxread > 0 && bytesread < minread && !cstate->raw_reached_eof)
{ int avail;
while (cstate->fe_msgbuf->cursor >= cstate->fe_msgbuf->len)
{ /* Try to receive another message */ int mtype; int maxmsglen;
readmessage:
HOLD_CANCEL_INTERRUPTS();
pq_startmsgread();
mtype = pq_getbyte(); if (mtype == EOF)
ereport(ERROR,
(errcode(ERRCODE_CONNECTION_FAILURE),
errmsg("unexpected EOF on client connection with an open transaction"))); /* Validate message type and set packet size limit */ switch (mtype)
{ case PqMsg_CopyData:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; break; case PqMsg_CopyDone: case PqMsg_CopyFail: case PqMsg_Flush: case PqMsg_Sync:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; break; default:
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("unexpected message type 0x%02X during COPY from stdin",
mtype)));
maxmsglen = 0; /* keep compiler quiet */ break;
} /* Now collect the message body */ if (pq_getmessage(cstate->fe_msgbuf, maxmsglen))
ereport(ERROR,
(errcode(ERRCODE_CONNECTION_FAILURE),
errmsg("unexpected EOF on client connection with an open transaction")));
RESUME_CANCEL_INTERRUPTS(); /* ... and process it */ switch (mtype)
{ case PqMsg_CopyData: break; case PqMsg_CopyDone: /* COPY IN correctly terminated by frontend */
cstate->raw_reached_eof = true; return bytesread; case PqMsg_CopyFail:
ereport(ERROR,
(errcode(ERRCODE_QUERY_CANCELED),
errmsg("COPY from stdin failed: %s",
pq_getmsgstring(cstate->fe_msgbuf)))); break; case PqMsg_Flush: case PqMsg_Sync:
/* only available for text or csv input */
Assert(!cstate->opts.binary);
/* on input check that the header line is correct if needed */ if (cstate->cur_lineno == 0 && cstate->opts.header_line)
{
ListCell *cur;
TupleDesc tupDesc;
if (cstate->opts.header_line == COPY_HEADER_MATCH)
{ int fldnum;
if (is_csv)
fldct = CopyReadAttributesCSV(cstate); else
fldct = CopyReadAttributesText(cstate);
if (fldct != list_length(cstate->attnumlist))
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("wrong number of fields in header line: got %d, expected %d",
fldct, list_length(cstate->attnumlist))));
colName = cstate->raw_fields[fldnum++]; if (colName == NULL)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("column name mismatch in header line field %d: got null value (\"%s\"), expected \"%s\"",
fldnum, cstate->opts.null_print, NameStr(attr->attname))));
if (namestrcmp(&attr->attname, colName) != 0)
{
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("column name mismatch in header line field %d: got \"%s\", expected \"%s\"",
fldnum, colName, NameStr(attr->attname))));
}
}
}
if (done) returnfalse;
}
cstate->cur_lineno++;
/* Actually read the line into memory here */
done = CopyReadLine(cstate, is_csv);
/* Implementation of the per-row callback for text format */ bool
CopyFromTextOneRow(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
{ return CopyFromTextLikeOneRow(cstate, econtext, values, nulls, false);
}
/* Implementation of the per-row callback for CSV format */ bool
CopyFromCSVOneRow(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
{ return CopyFromTextLikeOneRow(cstate, econtext, values, nulls, true);
}
/* read raw fields in the next line */ if (!NextCopyFromRawFieldsInternal(cstate, &field_strings, &fldct, is_csv)) returnfalse;
/* check for overflowing fields */ if (attr_count > 0 && fldct > attr_count)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("extra data after last expected column")));
fieldno = 0;
/* Loop to read the user attributes on the line. */
foreach(cur, cstate->attnumlist)
{ int attnum = lfirst_int(cur); int m = attnum - 1;
Form_pg_attribute att = TupleDescAttr(tupDesc, m);
if (fieldno >= fldct)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("missing data for column \"%s\"",
NameStr(att->attname))));
string = field_strings[fieldno++];
if (cstate->convert_select_flags &&
!cstate->convert_select_flags[m])
{ /* ignore input field, leaving column as NULL */ continue;
}
if (cstate->defaults[m])
{ /* We must have switched into the per-tuple memory context */
Assert(econtext != NULL);
Assert(CurrentMemoryContext == econtext->ecxt_per_tuple_memory);
attval = CopyLimitPrintoutLength(cstate->cur_attval);
ereport(NOTICE,
errmsg("skipping row due to data type incompatibility at line %" PRIu64 " for column \"%s\": \"%s\"",
cstate->cur_lineno,
cstate->cur_attname,
attval));
pfree(attval);
} else
ereport(NOTICE,
errmsg("skipping row due to data type incompatibility at line %" PRIu64 " for column \"%s\": null input",
cstate->cur_lineno,
cstate->cur_attname));
/* Parse data and transfer into line_buf */
result = CopyReadLineText(cstate, is_csv);
if (result)
{ /* *ReachedEOF.Inprotocolversion3,weshouldignoreanything *after\.uptotheprotocolendofcopydata.(XXXmaybebetter *nottotreat\.asspecial?)
*/ if (cstate->copy_src == COPY_FRONTEND)
{ int inbytes;
if (is_csv)
{
quotec = cstate->opts.quote[0];
escapec = cstate->opts.escape[0]; /* ignore special escape processing if it's the same as quotec */ if (quotec == escapec)
escapec = '\0';
}
/* *Ifwearecompletelyoutofdata,breakoutoftheloop, *reportingEOF.
*/ if (INPUT_BUF_BYTES(cstate) <= 0)
{
result = true; break;
}
need_data = false;
}
/* OK to fetch a character */
prev_raw_ptr = input_buf_ptr;
c = copy_input_buf[input_buf_ptr++];
if (is_csv)
{ /* *Ifcharacteris'\r',wemayneedtolookaheadbelow.Force *fetchofthenextcharacterifwedon'talreadyhaveit.We *needtodothisbeforechangingCSVstate,incase'\r'isalso *thequoteorescapecharacter.
*/ if (c == '\r')
{
IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
}
/* *Dealingwithquotesandescapeshereismildlytricky.Ifthe *quotecharisalsotheescapechar,there'snoproblem-we *justusethecharasatoggle.Iftheyaredifferent,weneed *toensurethatweonlytakeaccountofanescapeinsidea *quotedfieldandimmediatelyprecedingaquotechar,andnot *thesecondinanescape-escapesequence.
*/ if (in_quote && c == escapec)
last_was_esc = !last_was_esc; if (c == quotec && !last_was_esc)
in_quote = !in_quote; if (c != escapec)
last_was_esc = false;
/* *UpdatingthelinecountforembeddedCRand/orLFcharsis *necessarilyalittlefragile-thistestisprobablyaboutthe *bestwecando.(XXXit'sarguablewhetherweshoulddothis *atall---iscur_linenoaphysicalorlogicalcount?)
*/ if (in_quote && c == (cstate->eol_type == EOL_NL ? '\n' : '\r'))
cstate->cur_lineno++;
}
/* Process \r */ if (c == '\r' && (!is_csv || !in_quote))
{ /* Check for \r\n on first line, _and_ handle \r\n. */ if (cstate->eol_type == EOL_UNKNOWN ||
cstate->eol_type == EOL_CRNL)
{ /* *Ifneedmoredata,gobacktolooptoptoloadit. * *NotethatifweareatEOF,cwillwindupas'\0'because *oftheguaranteedpadofinput_buf.
*/
IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
/* get next char */
c = copy_input_buf[input_buf_ptr];
if (c == '\n')
{
input_buf_ptr++; /* eat newline */
cstate->eol_type = EOL_CRNL; /* in case not set yet */
} else
{ /* found \r, but no \n */ if (cstate->eol_type == EOL_CRNL)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
!is_csv ?
errmsg("literal carriage return found in data") :
errmsg("unquoted carriage return found in data"),
!is_csv ?
errhint("Use \"\\r\" to represent carriage return.") :
errhint("Use quoted CSV field to represent carriage return.")));
/* *ifwegothere,itisthefirstlineandwedidn'tfind *\n,sodon'tconsumethepeekedcharacter
*/
cstate->eol_type = EOL_CR;
}
} elseif (cstate->eol_type == EOL_NL)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
!is_csv ?
errmsg("literal carriage return found in data") :
errmsg("unquoted carriage return found in data"),
!is_csv ?
errhint("Use \"\\r\" to represent carriage return.") :
errhint("Use quoted CSV field to represent carriage return."))); /* If reach here, we have found the line terminator */ break;
}
/* Process \n */ if (c == '\n' && (!is_csv || !in_quote))
{ if (cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
!is_csv ?
errmsg("literal newline found in data") :
errmsg("unquoted newline found in data"),
!is_csv ?
errhint("Use \"\\n\" to represent newline.") :
errhint("Use quoted CSV field to represent newline.")));
cstate->eol_type = EOL_NL; /* in case not set yet */ /* If reach here, we have found the line terminator */ break;
}
if (c2 == '.')
{
input_buf_ptr++; /* consume the '.' */ if (cstate->eol_type == EOL_CRNL)
{ /* Get the next character */
IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); /* if hit_eof, c2 will become '\0' */
c2 = copy_input_buf[input_buf_ptr++];
if (c2 == '\n')
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("end-of-copy marker does not match previous newline style"))); elseif (c2 != '\r')
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("end-of-copy marker is not alone on its line")));
}
/* Get the next character */
IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); /* if hit_eof, c2 will become '\0' */
c2 = copy_input_buf[input_buf_ptr++];
if (c2 != '\r' && c2 != '\n')
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
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")));
/* *Ifthereisanydataonthislinebeforethe\.,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")));
/* *Weneedaspecialcaseforzero-columntables:checkthattheinput *lineisempty,andreturn.
*/ if (cstate->max_fields <= 0)
{ if (cstate->line_buf.len != 0)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("extra data after last expected column"))); return0;
}
/* set pointer variables for loop */
cur_ptr = cstate->line_buf.data;
line_end_ptr = cstate->line_buf.data + cstate->line_buf.len;
/* Outer loop iterates over fields */
fieldno = 0; for (;;)
{ bool found_delim = false; char *start_ptr; char *end_ptr; int input_len; bool saw_non_ascii = false;
/* Make sure there is enough space for the next value */ if (fieldno >= cstate->max_fields)
{
cstate->max_fields *= 2;
cstate->raw_fields =
repalloc(cstate->raw_fields, cstate->max_fields * sizeof(char *));
}
/* Remember start of field on both input and output sides */
start_ptr = cur_ptr;
cstate->raw_fields[fieldno] = output_ptr;
/* *Weneedaspecialcaseforzero-columntables:checkthattheinput *lineisempty,andreturn.
*/ if (cstate->max_fields <= 0)
{ if (cstate->line_buf.len != 0)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("extra data after last expected column"))); return0;
}
/* set pointer variables for loop */
cur_ptr = cstate->line_buf.data;
line_end_ptr = cstate->line_buf.data + cstate->line_buf.len;
/* Outer loop iterates over fields */
fieldno = 0; for (;;)
{ bool found_delim = false; bool saw_quote = false; char *start_ptr; char *end_ptr; int input_len;
/* Make sure there is enough space for the next value */ if (fieldno >= cstate->max_fields)
{
cstate->max_fields *= 2;
cstate->raw_fields =
repalloc(cstate->raw_fields, cstate->max_fields * sizeof(char *));
}
/* Remember start of field on both input and output sides */
start_ptr = cur_ptr;
cstate->raw_fields[fieldno] = output_ptr;
/* Not in quote */ for (;;)
{
end_ptr = cur_ptr; if (cur_ptr >= line_end_ptr) goto endfield;
c = *cur_ptr++; /* unquoted field delimiter */ if (c == delimc)
{
found_delim = true; goto endfield;
} /* start of quoted field (or part of field) */ if (c == quotec)
{
saw_quote = true; break;
} /* Add c to output string */
*output_ptr++ = c;
}
/* In quote */ for (;;)
{
end_ptr = cur_ptr; if (cur_ptr >= line_end_ptr)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("unterminated CSV quoted field")));
c = *cur_ptr++;
/* escape within a quoted field */ if (c == escapec)
{ /* *peekatthenextcharifavailable,andescapeitifit *isanescapecharoraquotechar
*/ if (cur_ptr < line_end_ptr)
{ char nextc = *cur_ptr;
/* Call the column type's binary input converter */
result = ReceiveFunctionCall(flinfo, &cstate->attribute_buf,
typioparam, typmod);
/* Trouble if it didn't eat the whole buffer */ if (cstate->attribute_buf.cursor != cstate->attribute_buf.len)
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("incorrect binary data format")));
*isnull = false; return result;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.28 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.