PostgreSQL Source Code  git master
copyto.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/tableam.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "commands/copy.h"
#include "commands/progress.h"
#include "executor/execdesc.h"
#include "executor/executor.h"
#include "executor/tuptable.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "optimizer/optimizer.h"
#include "pgstat.h"
#include "rewrite/rewriteHandler.h"
#include "storage/fd.h"
#include "tcop/tcopprot.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/partcache.h"
#include "utils/rel.h"
#include "utils/snapmgr.h"
Include dependency graph for copyto.c:

Go to the source code of this file.

Data Structures

struct  CopyToStateData
 
struct  DR_copy
 

Macros

#define DUMPSOFAR()
 

Typedefs

typedef enum CopyDest CopyDest
 
typedef struct CopyToStateData CopyToStateData
 

Enumerations

enum  CopyDest { COPY_FILE, COPY_OLD_FE, COPY_NEW_FE }
 

Functions

static void EndCopy (CopyToState cstate)
 
static void ClosePipeToProgram (CopyToState cstate)
 
static uint64 CopyTo (CopyToState cstate)
 
static void CopyOneRowTo (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyAttributeOutText (CopyToState cstate, char *string)
 
static void CopyAttributeOutCSV (CopyToState cstate, char *string, bool use_quote, bool single_attr)
 
static void SendCopyBegin (CopyToState cstate)
 
static void SendCopyEnd (CopyToState cstate)
 
static void CopySendData (CopyToState cstate, const void *databuf, int datasize)
 
static void CopySendString (CopyToState cstate, const char *str)
 
static void CopySendChar (CopyToState cstate, char c)
 
static void CopySendEndOfRow (CopyToState cstate)
 
static void CopySendInt32 (CopyToState cstate, int32 val)
 
static void CopySendInt16 (CopyToState cstate, int16 val)
 
CopyToState BeginCopyTo (ParseState *pstate, Relation rel, RawStmt *raw_query, Oid queryRelId, const char *filename, bool is_program, List *attnamelist, List *options)
 
uint64 DoCopyTo (CopyToState cstate)
 
void EndCopyTo (CopyToState cstate)
 
static void copy_dest_startup (DestReceiver *self, int operation, TupleDesc typeinfo)
 
static bool copy_dest_receive (TupleTableSlot *slot, DestReceiver *self)
 
static void copy_dest_shutdown (DestReceiver *self)
 
static void copy_dest_destroy (DestReceiver *self)
 
DestReceiverCreateCopyDestReceiver (void)
 

Variables

static const char BinarySignature [11] = "PGCOPY\n\377\r\n\0"
 

Macro Definition Documentation

◆ DUMPSOFAR

#define DUMPSOFAR ( )
Value:
do { \
if (ptr > start) \
CopySendData(cstate, start, ptr - start); \
} while (0)

Definition at line 1061 of file copyto.c.

Referenced by CopyAttributeOutCSV(), and CopyAttributeOutText().

Typedef Documentation

◆ CopyDest

typedef enum CopyDest CopyDest

◆ CopyToStateData

Enumeration Type Documentation

◆ CopyDest

enum CopyDest
Enumerator
COPY_FILE 
COPY_OLD_FE 
COPY_NEW_FE 

Definition at line 50 of file copyto.c.

51 {
52  COPY_FILE, /* to file (or a piped program) */
53  COPY_OLD_FE, /* to frontend (2.0 protocol) */
54  COPY_NEW_FE, /* to frontend (3.0 protocol) */
55 } CopyDest;
CopyDest
Definition: copyto.c:50

Function Documentation

◆ BeginCopyTo()

CopyToState BeginCopyTo ( ParseState pstate,
Relation  rel,
RawStmt raw_query,
Oid  queryRelId,
const char *  filename,
bool  is_program,
List attnamelist,
List options 
)

Definition at line 383 of file copyto.c.

References AllocateFile(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, attnum, CopyToStateData::attnumlist, CopyToStateData::bytes_processed, CMD_DELETE, CMD_INSERT, CMD_SELECT, CMD_UPDATE, Query::commandType, CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, CopyToStateData::copycontext, CopyGetAttnums(), copyObject, CreateDestReceiver(), CreateQueryDesc(), cur, CurrentMemoryContext, CURSOR_OPT_PARALLEL_OK, generate_unaccent_rules::dest, DestCopyOut, DestRemote, CopyToStateData::encoding_embeds_ascii, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, ExecutorStart(), CopyFormatOptions::file_encoding, CopyToStateData::file_encoding, CopyToStateData::filename, CopyFormatOptions::force_notnull, CopyFormatOptions::force_notnull_flags, CopyFormatOptions::force_null, CopyFormatOptions::force_null_flags, CopyFormatOptions::force_quote, CopyFormatOptions::force_quote_all, CopyFormatOptions::force_quote_flags, fstat, GetActiveSnapshot(), GetDatabaseEncoding(), i, InvalidOid, InvalidSnapshot, is_absolute_path, CopyToStateData::is_program, IsA, lfirst_int, lfirst_node, linitial_node, list_length(), list_member_int(), list_member_oid(), MemoryContextSwitchTo(), NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, NIL, OpenPipeStream(), CopyToStateData::opts, ParseState::p_sourcetext, palloc0(), pg_analyze_and_rewrite(), PG_BINARY_W, pg_database_encoding_max_length(), PG_ENCODING_IS_CLIENT_ONLY, PG_END_TRY, PG_FINALLY, pg_get_client_encoding(), pg_plan_query(), PG_TRY, pgstat_progress_start_command(), ProcessCopyOptions(), PROGRESS_COMMAND_COPY, pstrdup(), PushCopiedSnapshot(), QSRC_NON_INSTEAD_RULE, QSRC_QUAL_INSTEAD_RULE, CopyToStateData::queryDesc, Query::querySource, RelationData::rd_rel, CopyToStateData::rel, RelationGetDescr, RelationGetRelationName, RelationGetRelid, PlannedStmt::relationOids, Query::returningList, S_ISDIR, S_IWGRP, S_IWOTH, stat::st_mode, generate_unaccent_rules::stdout, QueryDesc::tupDesc, TupleDescAttr, UpdateActiveSnapshotCommandId(), Query::utilityStmt, and whereToSendOutput.

Referenced by DoCopy().

391 {
392  CopyToState cstate;
393  bool pipe = (filename == NULL);
394  TupleDesc tupDesc;
395  int num_phys_attrs;
396  MemoryContext oldcontext;
397 
398  if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
399  {
400  if (rel->rd_rel->relkind == RELKIND_VIEW)
401  ereport(ERROR,
402  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
403  errmsg("cannot copy from view \"%s\"",
405  errhint("Try the COPY (SELECT ...) TO variant.")));
406  else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
407  ereport(ERROR,
408  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
409  errmsg("cannot copy from materialized view \"%s\"",
411  errhint("Try the COPY (SELECT ...) TO variant.")));
412  else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
413  ereport(ERROR,
414  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
415  errmsg("cannot copy from foreign table \"%s\"",
417  errhint("Try the COPY (SELECT ...) TO variant.")));
418  else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
419  ereport(ERROR,
420  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
421  errmsg("cannot copy from sequence \"%s\"",
422  RelationGetRelationName(rel))));
423  else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
424  ereport(ERROR,
425  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
426  errmsg("cannot copy from partitioned table \"%s\"",
428  errhint("Try the COPY (SELECT ...) TO variant.")));
429  else
430  ereport(ERROR,
431  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
432  errmsg("cannot copy from non-table relation \"%s\"",
433  RelationGetRelationName(rel))));
434  }
435 
436 
437  /* Allocate workspace and zero all fields */
438  cstate = (CopyToStateData *) palloc0(sizeof(CopyToStateData));
439 
440  /*
441  * We allocate everything used by a cstate in a new memory context. This
442  * avoids memory leaks during repeated use of COPY in a query.
443  */
445  "COPY",
447 
448  oldcontext = MemoryContextSwitchTo(cstate->copycontext);
449 
450  /* Extract options from the statement node tree */
451  ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */, options);
452 
453  /* Process the source/target relation or query */
454  if (rel)
455  {
456  Assert(!raw_query);
457 
458  cstate->rel = rel;
459 
460  tupDesc = RelationGetDescr(cstate->rel);
461  }
462  else
463  {
464  List *rewritten;
465  Query *query;
466  PlannedStmt *plan;
468 
469  cstate->rel = NULL;
470 
471  /*
472  * Run parse analysis and rewrite. Note this also acquires sufficient
473  * locks on the source table(s).
474  *
475  * Because the parser and planner tend to scribble on their input, we
476  * make a preliminary copy of the source querytree. This prevents
477  * problems in the case that the COPY is in a portal or plpgsql
478  * function and is executed repeatedly. (See also the same hack in
479  * DECLARE CURSOR and PREPARE.) XXX FIXME someday.
480  */
481  rewritten = pg_analyze_and_rewrite(copyObject(raw_query),
482  pstate->p_sourcetext, NULL, 0,
483  NULL);
484 
485  /* check that we got back something we can work with */
486  if (rewritten == NIL)
487  {
488  ereport(ERROR,
489  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
490  errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
491  }
492  else if (list_length(rewritten) > 1)
493  {
494  ListCell *lc;
495 
496  /* examine queries to determine which error message to issue */
497  foreach(lc, rewritten)
498  {
499  Query *q = lfirst_node(Query, lc);
500 
502  ereport(ERROR,
503  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
504  errmsg("conditional DO INSTEAD rules are not supported for COPY")));
506  ereport(ERROR,
507  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
508  errmsg("DO ALSO rules are not supported for the COPY")));
509  }
510 
511  ereport(ERROR,
512  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
513  errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
514  }
515 
516  query = linitial_node(Query, rewritten);
517 
518  /* The grammar allows SELECT INTO, but we don't support that */
519  if (query->utilityStmt != NULL &&
521  ereport(ERROR,
522  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
523  errmsg("COPY (SELECT INTO) is not supported")));
524 
525  Assert(query->utilityStmt == NULL);
526 
527  /*
528  * Similarly the grammar doesn't enforce the presence of a RETURNING
529  * clause, but this is required here.
530  */
531  if (query->commandType != CMD_SELECT &&
532  query->returningList == NIL)
533  {
534  Assert(query->commandType == CMD_INSERT ||
535  query->commandType == CMD_UPDATE ||
536  query->commandType == CMD_DELETE);
537 
538  ereport(ERROR,
539  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
540  errmsg("COPY query must have a RETURNING clause")));
541  }
542 
543  /* plan the query */
544  plan = pg_plan_query(query, pstate->p_sourcetext,
545  CURSOR_OPT_PARALLEL_OK, NULL);
546 
547  /*
548  * With row level security and a user using "COPY relation TO", we
549  * have to convert the "COPY relation TO" to a query-based COPY (eg:
550  * "COPY (SELECT * FROM relation) TO"), to allow the rewriter to add
551  * in any RLS clauses.
552  *
553  * When this happens, we are passed in the relid of the originally
554  * found relation (which we have locked). As the planner will look up
555  * the relation again, we double-check here to make sure it found the
556  * same one that we have locked.
557  */
558  if (queryRelId != InvalidOid)
559  {
560  /*
561  * Note that with RLS involved there may be multiple relations,
562  * and while the one we need is almost certainly first, we don't
563  * make any guarantees of that in the planner, so check the whole
564  * list and make sure we find the original relation.
565  */
566  if (!list_member_oid(plan->relationOids, queryRelId))
567  ereport(ERROR,
568  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
569  errmsg("relation referenced by COPY statement has changed")));
570  }
571 
572  /*
573  * Use a snapshot with an updated command ID to ensure this query sees
574  * results of any previously executed queries.
575  */
578 
579  /* Create dest receiver for COPY OUT */
581  ((DR_copy *) dest)->cstate = cstate;
582 
583  /* Create a QueryDesc requesting no output */
584  cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
587  dest, NULL, NULL, 0);
588 
589  /*
590  * Call ExecutorStart to prepare the plan for execution.
591  *
592  * ExecutorStart computes a result tupdesc for us
593  */
594  ExecutorStart(cstate->queryDesc, 0);
595 
596  tupDesc = cstate->queryDesc->tupDesc;
597  }
598 
599  /* Generate or convert list of attributes to process */
600  cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
601 
602  num_phys_attrs = tupDesc->natts;
603 
604  /* Convert FORCE_QUOTE name list to per-column flags, check validity */
605  cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
606  if (cstate->opts.force_quote_all)
607  {
608  int i;
609 
610  for (i = 0; i < num_phys_attrs; i++)
611  cstate->opts.force_quote_flags[i] = true;
612  }
613  else if (cstate->opts.force_quote)
614  {
615  List *attnums;
616  ListCell *cur;
617 
618  attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
619 
620  foreach(cur, attnums)
621  {
622  int attnum = lfirst_int(cur);
623  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
624 
625  if (!list_member_int(cstate->attnumlist, attnum))
626  ereport(ERROR,
627  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
628  errmsg("FORCE_QUOTE column \"%s\" not referenced by COPY",
629  NameStr(attr->attname))));
630  cstate->opts.force_quote_flags[attnum - 1] = true;
631  }
632  }
633 
634  /* Convert FORCE_NOT_NULL name list to per-column flags, check validity */
635  cstate->opts.force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
636  if (cstate->opts.force_notnull)
637  {
638  List *attnums;
639  ListCell *cur;
640 
641  attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_notnull);
642 
643  foreach(cur, attnums)
644  {
645  int attnum = lfirst_int(cur);
646  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
647 
648  if (!list_member_int(cstate->attnumlist, attnum))
649  ereport(ERROR,
650  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
651  errmsg("FORCE_NOT_NULL column \"%s\" not referenced by COPY",
652  NameStr(attr->attname))));
653  cstate->opts.force_notnull_flags[attnum - 1] = true;
654  }
655  }
656 
657  /* Convert FORCE_NULL name list to per-column flags, check validity */
658  cstate->opts.force_null_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
659  if (cstate->opts.force_null)
660  {
661  List *attnums;
662  ListCell *cur;
663 
664  attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_null);
665 
666  foreach(cur, attnums)
667  {
668  int attnum = lfirst_int(cur);
669  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
670 
671  if (!list_member_int(cstate->attnumlist, attnum))
672  ereport(ERROR,
673  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
674  errmsg("FORCE_NULL column \"%s\" not referenced by COPY",
675  NameStr(attr->attname))));
676  cstate->opts.force_null_flags[attnum - 1] = true;
677  }
678  }
679 
680  /* Use client encoding when ENCODING option is not specified. */
681  if (cstate->opts.file_encoding < 0)
683  else
684  cstate->file_encoding = cstate->opts.file_encoding;
685 
686  /*
687  * Set up encoding conversion info. Even if the file and server encodings
688  * are the same, we must apply pg_any_to_server() to validate data in
689  * multibyte encodings.
690  */
691  cstate->need_transcoding =
692  (cstate->file_encoding != GetDatabaseEncoding() ||
694  /* See Multibyte encoding comment above */
696 
697  cstate->copy_dest = COPY_FILE; /* default */
698 
699  MemoryContextSwitchTo(oldcontext);
700 
701  if (pipe)
702  {
703  Assert(!is_program); /* the grammar does not allow this */
705  cstate->copy_file = stdout;
706  }
707  else
708  {
709  cstate->filename = pstrdup(filename);
710  cstate->is_program = is_program;
711 
712  if (is_program)
713  {
714  cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
715  if (cstate->copy_file == NULL)
716  ereport(ERROR,
718  errmsg("could not execute command \"%s\": %m",
719  cstate->filename)));
720  }
721  else
722  {
723  mode_t oumask; /* Pre-existing umask value */
724  struct stat st;
725 
726  /*
727  * Prevent write to relative path ... too easy to shoot oneself in
728  * the foot by overwriting a database file ...
729  */
731  ereport(ERROR,
732  (errcode(ERRCODE_INVALID_NAME),
733  errmsg("relative path not allowed for COPY to file")));
734 
735  oumask = umask(S_IWGRP | S_IWOTH);
736  PG_TRY();
737  {
738  cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
739  }
740  PG_FINALLY();
741  {
742  umask(oumask);
743  }
744  PG_END_TRY();
745  if (cstate->copy_file == NULL)
746  {
747  /* copy errno because ereport subfunctions might change it */
748  int save_errno = errno;
749 
750  ereport(ERROR,
752  errmsg("could not open file \"%s\" for writing: %m",
753  cstate->filename),
754  (save_errno == ENOENT || save_errno == EACCES) ?
755  errhint("COPY TO instructs the PostgreSQL server process to write a file. "
756  "You may want a client-side facility such as psql's \\copy.") : 0));
757  }
758 
759  if (fstat(fileno(cstate->copy_file), &st))
760  ereport(ERROR,
762  errmsg("could not stat file \"%s\": %m",
763  cstate->filename)));
764 
765  if (S_ISDIR(st.st_mode))
766  ereport(ERROR,
767  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
768  errmsg("\"%s\" is a directory", cstate->filename)));
769  }
770  }
771 
772  /* initialize progress */
774  cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
775  cstate->bytes_processed = 0;
776 
777  MemoryContextSwitchTo(oldcontext);
778 
779  return cstate;
780 }
int file_encoding
Definition: copyto.c:79
#define NIL
Definition: pg_list.h:65
void UpdateActiveSnapshotCommandId(void)
Definition: snapmgr.c:728
#define IsA(nodeptr, _type_)
Definition: nodes.h:579
#define AllocSetContextCreate
Definition: memutils.h:170
int errhint(const char *fmt,...)
Definition: elog.c:1162
Relation rel
Definition: copyto.c:84
bool need_transcoding
Definition: copyto.c:80
FILE * copy_file
Definition: copyto.c:76
#define RelationGetDescr(relation)
Definition: rel.h:483
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
Definition: pgstat.c:3457
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
List * relationOids
Definition: plannodes.h:80
char * pstrdup(const char *in)
Definition: mcxt.c:1187
bool * force_quote_flags
Definition: copy.h:44
#define S_IWOTH
Definition: win32_port.h:307
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:143
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:786
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:704
#define PG_BINARY_W
Definition: c.h:1262
uint64 bytes_processed
Definition: copyto.c:100
List * force_notnull
Definition: copy.h:45
bool force_quote_all
Definition: copy.h:43
Form_pg_class rd_rel
Definition: rel.h:110
List * pg_analyze_and_rewrite(RawStmt *parsetree, const char *query_string, Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition: postgres.c:677
Node * utilityStmt
Definition: parsenodes.h:120
#define linitial_node(type, l)
Definition: pg_list.h:177
bool is_program
Definition: copyto.c:88
QueryDesc * queryDesc
Definition: copyto.c:85
#define fstat
Definition: win32_port.h:274
List * attnumlist
Definition: copyto.c:86
#define ERROR
Definition: elog.h:45
#define lfirst_int(lc)
Definition: pg_list.h:170
MemoryContext copycontext
Definition: copyto.c:96
void PushCopiedSnapshot(Snapshot snapshot)
Definition: snapmgr.c:716
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
Definition: pquery.c:67
List * force_null
Definition: copy.h:47
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
#define lfirst_node(type, lc)
Definition: pg_list.h:172
bool list_member_int(const List *list, int datum)
Definition: list.c:669
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:113
int errcode_for_file_access(void)
Definition: elog.c:727
#define is_absolute_path(filename)
Definition: port.h:86
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2354
#define RelationGetRelationName(relation)
Definition: rel.h:491
#define S_IWGRP
Definition: win32_port.h:295
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
const char * p_sourcetext
Definition: parse_node.h:179
int file_encoding
Definition: copy.h:30
List * returningList
Definition: parsenodes.h:146
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2457
CopyDest copy_dest
Definition: copyto.c:75
TupleDesc tupDesc
Definition: execdesc.h:47
#define InvalidSnapshot
Definition: snapshot.h:123
#define PG_FINALLY()
Definition: elog.h:326
void * palloc0(Size size)
Definition: mcxt.c:981
List * force_quote
Definition: copy.h:42
int GetDatabaseEncoding(void)
Definition: mbutils.c:1151
int pg_get_client_encoding(void)
Definition: mbutils.c:336
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:155
CmdType commandType
Definition: parsenodes.h:112
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
QuerySource querySource
Definition: parsenodes.h:114
#define Assert(condition)
Definition: c.h:792
bool * force_null_flags
Definition: copy.h:48
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition: copy.c:686
static int list_length(const List *l)
Definition: pg_list.h:149
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1436
CopyFormatOptions opts
Definition: copyto.c:90
#define S_ISDIR(m)
Definition: win32_port.h:316
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition: pg_wchar.h:298
static char * filename
Definition: pg_dumpall.c:91
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2732
int errmsg(const char *fmt,...)
Definition: elog.c:915
int i
#define NameStr(name)
Definition: c.h:669
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams)
Definition: postgres.c:858
bool encoding_embeds_ascii
Definition: copyto.c:81
#define copyObject(obj)
Definition: nodes.h:644
CommandDest whereToSendOutput
Definition: postgres.c:92
char * filename
Definition: copyto.c:87
#define PG_TRY()
Definition: elog.h:309
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:457
#define PG_END_TRY()
Definition: elog.h:334
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition: copy.c:334
bool * force_notnull_flags
Definition: copy.h:46

◆ ClosePipeToProgram()

static void ClosePipeToProgram ( CopyToState  cstate)
static

Definition at line 333 of file copyto.c.

References Assert, ClosePipeStream(), CopyToStateData::copy_file, ereport, errcode(), errcode_for_file_access(), errdetail_internal(), errmsg(), ERROR, CopyToStateData::filename, CopyToStateData::is_program, and wait_result_to_str().

Referenced by CopySendEndOfRow(), and EndCopy().

334 {
335  int pclose_rc;
336 
337  Assert(cstate->is_program);
338 
339  pclose_rc = ClosePipeStream(cstate->copy_file);
340  if (pclose_rc == -1)
341  ereport(ERROR,
343  errmsg("could not close pipe to external command: %m")));
344  else if (pclose_rc != 0)
345  {
346  ereport(ERROR,
347  (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
348  errmsg("program \"%s\" failed",
349  cstate->filename),
350  errdetail_internal("%s", wait_result_to_str(pclose_rc))));
351  }
352 }
FILE * copy_file
Definition: copyto.c:76
int errcode(int sqlerrcode)
Definition: elog.c:704
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:32
bool is_program
Definition: copyto.c:88
int ClosePipeStream(FILE *file)
Definition: fd.c:2763
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1075
#define ERROR
Definition: elog.h:45
int errcode_for_file_access(void)
Definition: elog.c:727
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:792
int errmsg(const char *fmt,...)
Definition: elog.c:915
char * filename
Definition: copyto.c:87

◆ copy_dest_destroy()

static void copy_dest_destroy ( DestReceiver self)
static

Definition at line 1342 of file copyto.c.

References pfree().

Referenced by CreateCopyDestReceiver().

1343 {
1344  pfree(self);
1345 }
void pfree(void *pointer)
Definition: mcxt.c:1057

◆ copy_dest_receive()

static bool copy_dest_receive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 1315 of file copyto.c.

References CopyOneRowTo(), DR_copy::cstate, pgstat_progress_update_param(), DR_copy::processed, and PROGRESS_COPY_LINES_PROCESSED.

Referenced by CreateCopyDestReceiver().

1316 {
1317  DR_copy *myState = (DR_copy *) self;
1318  CopyToState cstate = myState->cstate;
1319 
1320  /* Send the data */
1321  CopyOneRowTo(cstate, slot);
1322 
1323  /* Increment amount of processed tuples and update the progress */
1325 
1326  return true;
1327 }
void pgstat_progress_update_param(int index, int64 val)
Definition: pgstat.c:3478
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:987
CopyToState cstate
Definition: copyto.c:108
#define PROGRESS_COPY_LINES_PROCESSED
Definition: progress.h:139
uint64 processed
Definition: copyto.c:109

◆ copy_dest_shutdown()

static void copy_dest_shutdown ( DestReceiver self)
static

Definition at line 1333 of file copyto.c.

Referenced by CreateCopyDestReceiver().

1334 {
1335  /* no-op */
1336 }

◆ copy_dest_startup()

static void copy_dest_startup ( DestReceiver self,
int  operation,
TupleDesc  typeinfo 
)
static

Definition at line 1306 of file copyto.c.

Referenced by CreateCopyDestReceiver().

1307 {
1308  /* no-op */
1309 }

◆ CopyAttributeOutCSV()

static void CopyAttributeOutCSV ( CopyToState  cstate,
char *  string,
bool  use_quote,
bool  single_attr 
)
static

Definition at line 1221 of file copyto.c.

References CopySendChar(), CopySendString(), CopyFormatOptions::delim, DUMPSOFAR, CopyToStateData::encoding_embeds_ascii, CopyFormatOptions::escape, CopyToStateData::file_encoding, IS_HIGHBIT_SET, CopyToStateData::need_transcoding, CopyFormatOptions::null_print, CopyToStateData::opts, pg_encoding_mblen(), pg_server_to_any(), and CopyFormatOptions::quote.

Referenced by CopyOneRowTo(), and CopyTo().

1223 {
1224  char *ptr;
1225  char *start;
1226  char c;
1227  char delimc = cstate->opts.delim[0];
1228  char quotec = cstate->opts.quote[0];
1229  char escapec = cstate->opts.escape[0];
1230 
1231  /* force quoting if it matches null_print (before conversion!) */
1232  if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1233  use_quote = true;
1234 
1235  if (cstate->need_transcoding)
1236  ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1237  else
1238  ptr = string;
1239 
1240  /*
1241  * Make a preliminary pass to discover if it needs quoting
1242  */
1243  if (!use_quote)
1244  {
1245  /*
1246  * Because '\.' can be a data value, quote it if it appears alone on a
1247  * line so it is not interpreted as the end-of-data marker.
1248  */
1249  if (single_attr && strcmp(ptr, "\\.") == 0)
1250  use_quote = true;
1251  else
1252  {
1253  char *tptr = ptr;
1254 
1255  while ((c = *tptr) != '\0')
1256  {
1257  if (c == delimc || c == quotec || c == '\n' || c == '\r')
1258  {
1259  use_quote = true;
1260  break;
1261  }
1262  if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1263  tptr += pg_encoding_mblen(cstate->file_encoding, tptr);
1264  else
1265  tptr++;
1266  }
1267  }
1268  }
1269 
1270  if (use_quote)
1271  {
1272  CopySendChar(cstate, quotec);
1273 
1274  /*
1275  * We adopt the same optimization strategy as in CopyAttributeOutText
1276  */
1277  start = ptr;
1278  while ((c = *ptr) != '\0')
1279  {
1280  if (c == quotec || c == escapec)
1281  {
1282  DUMPSOFAR();
1283  CopySendChar(cstate, escapec);
1284  start = ptr; /* we include char in next run */
1285  }
1286  if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1287  ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1288  else
1289  ptr++;
1290  }
1291  DUMPSOFAR();
1292 
1293  CopySendChar(cstate, quotec);
1294  }
1295  else
1296  {
1297  /* If it doesn't need quoting, we can just dump it as-is */
1298  CopySendString(cstate, ptr);
1299  }
1300 }
int file_encoding
Definition: copyto.c:79
bool need_transcoding
Definition: copyto.c:80
char * null_print
Definition: copy.h:36
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:692
char * quote
Definition: copy.h:40
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1144
char * c
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition: wchar.c:1554
char string[11]
Definition: preproc-type.c:46
static void CopySendString(CopyToState cstate, const char *str)
Definition: copyto.c:209
char * delim
Definition: copy.h:39
#define DUMPSOFAR()
Definition: copyto.c:1061
CopyFormatOptions opts
Definition: copyto.c:90
char * escape
Definition: copy.h:41
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:215
bool encoding_embeds_ascii
Definition: copyto.c:81

◆ CopyAttributeOutText()

static void CopyAttributeOutText ( CopyToState  cstate,
char *  string 
)
static

Definition at line 1068 of file copyto.c.

References CopySendChar(), CopyFormatOptions::delim, DUMPSOFAR, CopyToStateData::encoding_embeds_ascii, CopyToStateData::file_encoding, IS_HIGHBIT_SET, CopyToStateData::need_transcoding, CopyToStateData::opts, pg_encoding_mblen(), and pg_server_to_any().

Referenced by CopyOneRowTo().

1069 {
1070  char *ptr;
1071  char *start;
1072  char c;
1073  char delimc = cstate->opts.delim[0];
1074 
1075  if (cstate->need_transcoding)
1076  ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1077  else
1078  ptr = string;
1079 
1080  /*
1081  * We have to grovel through the string searching for control characters
1082  * and instances of the delimiter character. In most cases, though, these
1083  * are infrequent. To avoid overhead from calling CopySendData once per
1084  * character, we dump out all characters between escaped characters in a
1085  * single call. The loop invariant is that the data from "start" to "ptr"
1086  * can be sent literally, but hasn't yet been.
1087  *
1088  * We can skip pg_encoding_mblen() overhead when encoding is safe, because
1089  * in valid backend encodings, extra bytes of a multibyte character never
1090  * look like ASCII. This loop is sufficiently performance-critical that
1091  * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
1092  * of the normal safe-encoding path.
1093  */
1094  if (cstate->encoding_embeds_ascii)
1095  {
1096  start = ptr;
1097  while ((c = *ptr) != '\0')
1098  {
1099  if ((unsigned char) c < (unsigned char) 0x20)
1100  {
1101  /*
1102  * \r and \n must be escaped, the others are traditional. We
1103  * prefer to dump these using the C-like notation, rather than
1104  * a backslash and the literal character, because it makes the
1105  * dump file a bit more proof against Microsoftish data
1106  * mangling.
1107  */
1108  switch (c)
1109  {
1110  case '\b':
1111  c = 'b';
1112  break;
1113  case '\f':
1114  c = 'f';
1115  break;
1116  case '\n':
1117  c = 'n';
1118  break;
1119  case '\r':
1120  c = 'r';
1121  break;
1122  case '\t':
1123  c = 't';
1124  break;
1125  case '\v':
1126  c = 'v';
1127  break;
1128  default:
1129  /* If it's the delimiter, must backslash it */
1130  if (c == delimc)
1131  break;
1132  /* All ASCII control chars are length 1 */
1133  ptr++;
1134  continue; /* fall to end of loop */
1135  }
1136  /* if we get here, we need to convert the control char */
1137  DUMPSOFAR();
1138  CopySendChar(cstate, '\\');
1139  CopySendChar(cstate, c);
1140  start = ++ptr; /* do not include char in next run */
1141  }
1142  else if (c == '\\' || c == delimc)
1143  {
1144  DUMPSOFAR();
1145  CopySendChar(cstate, '\\');
1146  start = ptr++; /* we include char in next run */
1147  }
1148  else if (IS_HIGHBIT_SET(c))
1149  ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1150  else
1151  ptr++;
1152  }
1153  }
1154  else
1155  {
1156  start = ptr;
1157  while ((c = *ptr) != '\0')
1158  {
1159  if ((unsigned char) c < (unsigned char) 0x20)
1160  {
1161  /*
1162  * \r and \n must be escaped, the others are traditional. We
1163  * prefer to dump these using the C-like notation, rather than
1164  * a backslash and the literal character, because it makes the
1165  * dump file a bit more proof against Microsoftish data
1166  * mangling.
1167  */
1168  switch (c)
1169  {
1170  case '\b':
1171  c = 'b';
1172  break;
1173  case '\f':
1174  c = 'f';
1175  break;
1176  case '\n':
1177  c = 'n';
1178  break;
1179  case '\r':
1180  c = 'r';
1181  break;
1182  case '\t':
1183  c = 't';
1184  break;
1185  case '\v':
1186  c = 'v';
1187  break;
1188  default:
1189  /* If it's the delimiter, must backslash it */
1190  if (c == delimc)
1191  break;
1192  /* All ASCII control chars are length 1 */
1193  ptr++;
1194  continue; /* fall to end of loop */
1195  }
1196  /* if we get here, we need to convert the control char */
1197  DUMPSOFAR();
1198  CopySendChar(cstate, '\\');
1199  CopySendChar(cstate, c);
1200  start = ++ptr; /* do not include char in next run */
1201  }
1202  else if (c == '\\' || c == delimc)
1203  {
1204  DUMPSOFAR();
1205  CopySendChar(cstate, '\\');
1206  start = ptr++; /* we include char in next run */
1207  }
1208  else
1209  ptr++;
1210  }
1211  }
1212 
1213  DUMPSOFAR();
1214 }
int file_encoding
Definition: copyto.c:79
bool need_transcoding
Definition: copyto.c:80
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:692
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1144
char * c
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition: wchar.c:1554
char string[11]
Definition: preproc-type.c:46
char * delim
Definition: copy.h:39
#define DUMPSOFAR()
Definition: copyto.c:1061
CopyFormatOptions opts
Definition: copyto.c:90
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:215
bool encoding_embeds_ascii
Definition: copyto.c:81

◆ CopyOneRowTo()

static void CopyOneRowTo ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 987 of file copyto.c.

References attnum, CopyToStateData::attnumlist, CopyFormatOptions::binary, CopyAttributeOutCSV(), CopyAttributeOutText(), CopySendChar(), CopySendData(), CopySendEndOfRow(), CopySendInt16(), CopySendInt32(), CopySendString(), CopyFormatOptions::csv_mode, cur, CopyFormatOptions::delim, CopyFormatOptions::force_quote_flags, lfirst_int, list_length(), MemoryContextReset(), MemoryContextSwitchTo(), CopyFormatOptions::null_print_client, CopyToStateData::opts, CopyToStateData::out_functions, OutputFunctionCall(), CopyToStateData::rowcontext, SendFunctionCall(), slot_getallattrs(), TupleTableSlot::tts_isnull, TupleTableSlot::tts_values, value, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by copy_dest_receive(), and CopyTo().

988 {
989  bool need_delim = false;
990  FmgrInfo *out_functions = cstate->out_functions;
991  MemoryContext oldcontext;
992  ListCell *cur;
993  char *string;
994 
996  oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
997 
998  if (cstate->opts.binary)
999  {
1000  /* Binary per-tuple header */
1001  CopySendInt16(cstate, list_length(cstate->attnumlist));
1002  }
1003 
1004  /* Make sure the tuple is fully deconstructed */
1005  slot_getallattrs(slot);
1006 
1007  foreach(cur, cstate->attnumlist)
1008  {
1009  int attnum = lfirst_int(cur);
1010  Datum value = slot->tts_values[attnum - 1];
1011  bool isnull = slot->tts_isnull[attnum - 1];
1012 
1013  if (!cstate->opts.binary)
1014  {
1015  if (need_delim)
1016  CopySendChar(cstate, cstate->opts.delim[0]);
1017  need_delim = true;
1018  }
1019 
1020  if (isnull)
1021  {
1022  if (!cstate->opts.binary)
1023  CopySendString(cstate, cstate->opts.null_print_client);
1024  else
1025  CopySendInt32(cstate, -1);
1026  }
1027  else
1028  {
1029  if (!cstate->opts.binary)
1030  {
1031  string = OutputFunctionCall(&out_functions[attnum - 1],
1032  value);
1033  if (cstate->opts.csv_mode)
1034  CopyAttributeOutCSV(cstate, string,
1035  cstate->opts.force_quote_flags[attnum - 1],
1036  list_length(cstate->attnumlist) == 1);
1037  else
1038  CopyAttributeOutText(cstate, string);
1039  }
1040  else
1041  {
1042  bytea *outputbytes;
1043 
1044  outputbytes = SendFunctionCall(&out_functions[attnum - 1],
1045  value);
1046  CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);
1047  CopySendData(cstate, VARDATA(outputbytes),
1048  VARSIZE(outputbytes) - VARHDRSZ);
1049  }
1050  }
1051  }
1052 
1053  CopySendEndOfRow(cstate);
1054 
1055  MemoryContextSwitchTo(oldcontext);
1056 }
Definition: fmgr.h:56
#define VARDATA(PTR)
Definition: postgres.h:302
static void CopyAttributeOutCSV(CopyToState cstate, char *string, bool use_quote, bool single_attr)
Definition: copyto.c:1221
FmgrInfo * out_functions
Definition: copyto.c:98
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:615
bool * force_quote_flags
Definition: copy.h:44
static struct @144 value
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static void CopySendInt16(CopyToState cstate, int16 val)
Definition: copyto.c:321
struct cursor * cur
Definition: ecpg.c:28
char * null_print_client
Definition: copy.h:38
Datum * tts_values
Definition: tuptable.h:126
MemoryContext rowcontext
Definition: copyto.c:99
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:137
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1576
List * attnumlist
Definition: copyto.c:86
#define lfirst_int(lc)
Definition: pg_list.h:170
bool binary
Definition: copy.h:32
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:354
bool csv_mode
Definition: copy.h:34
bool * tts_isnull
Definition: tuptable.h:128
char string[11]
Definition: preproc-type.c:46
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1637
static void CopySendString(CopyToState cstate, const char *str)
Definition: copyto.c:209
static void CopySendInt32(CopyToState cstate, int32 val)
Definition: copyto.c:309
uintptr_t Datum
Definition: postgres.h:367
char * delim
Definition: copy.h:39
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:203
int16 attnum
Definition: pg_attribute.h:79
static int list_length(const List *l)
Definition: pg_list.h:149
static void CopyAttributeOutText(CopyToState cstate, char *string)
Definition: copyto.c:1068
CopyFormatOptions opts
Definition: copyto.c:90
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:215
Definition: c.h:609
static void CopySendEndOfRow(CopyToState cstate)
Definition: copyto.c:221

◆ CopySendChar()

static void CopySendChar ( CopyToState  cstate,
char  c 
)
static

Definition at line 215 of file copyto.c.

References appendStringInfoCharMacro, and CopyToStateData::fe_msgbuf.

Referenced by CopyAttributeOutCSV(), CopyAttributeOutText(), CopyOneRowTo(), CopySendEndOfRow(), and CopyTo().

216 {
218 }
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128
char * c
StringInfo fe_msgbuf
Definition: copyto.c:77

◆ CopySendData()

static void CopySendData ( CopyToState  cstate,
const void *  databuf,
int  datasize 
)
static

Definition at line 203 of file copyto.c.

References appendBinaryStringInfo(), and CopyToStateData::fe_msgbuf.

Referenced by CopyOneRowTo(), CopySendInt16(), CopySendInt32(), CopyTo(), and SendCopyEnd().

204 {
205  appendBinaryStringInfo(cstate->fe_msgbuf, databuf, datasize);
206 }
StringInfo fe_msgbuf
Definition: copyto.c:77
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ CopySendEndOfRow()

static void CopySendEndOfRow ( CopyToState  cstate)
static

Definition at line 221 of file copyto.c.

References CopyFormatOptions::binary, CopyToStateData::bytes_processed, ClosePipeToProgram(), CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, COPY_NEW_FE, COPY_OLD_FE, CopySendChar(), CopySendString(), StringInfoData::data, ereport, errcode(), errcode_for_file_access(), errmsg(), ERROR, FATAL, CopyToStateData::fe_msgbuf, CopyToStateData::is_program, StringInfoData::len, CopyToStateData::opts, pgstat_progress_update_param(), pq_putbytes(), pq_putmessage, PROGRESS_COPY_BYTES_PROCESSED, and resetStringInfo().

Referenced by CopyOneRowTo(), CopyTo(), and SendCopyEnd().

222 {
223  StringInfo fe_msgbuf = cstate->fe_msgbuf;
224 
225  switch (cstate->copy_dest)
226  {
227  case COPY_FILE:
228  if (!cstate->opts.binary)
229  {
230  /* Default line termination depends on platform */
231 #ifndef WIN32
232  CopySendChar(cstate, '\n');
233 #else
234  CopySendString(cstate, "\r\n");
235 #endif
236  }
237 
238  if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
239  cstate->copy_file) != 1 ||
240  ferror(cstate->copy_file))
241  {
242  if (cstate->is_program)
243  {
244  if (errno == EPIPE)
245  {
246  /*
247  * The pipe will be closed automatically on error at
248  * the end of transaction, but we might get a better
249  * error message from the subprocess' exit code than
250  * just "Broken Pipe"
251  */
252  ClosePipeToProgram(cstate);
253 
254  /*
255  * If ClosePipeToProgram() didn't throw an error, the
256  * program terminated normally, but closed the pipe
257  * first. Restore errno, and throw an error.
258  */
259  errno = EPIPE;
260  }
261  ereport(ERROR,
263  errmsg("could not write to COPY program: %m")));
264  }
265  else
266  ereport(ERROR,
268  errmsg("could not write to COPY file: %m")));
269  }
270  break;
271  case COPY_OLD_FE:
272  /* The FE/BE protocol uses \n as newline for all platforms */
273  if (!cstate->opts.binary)
274  CopySendChar(cstate, '\n');
275 
276  if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len))
277  {
278  /* no hope of recovering connection sync, so FATAL */
279  ereport(FATAL,
280  (errcode(ERRCODE_CONNECTION_FAILURE),
281  errmsg("connection lost during COPY to stdout")));
282  }
283  break;
284  case COPY_NEW_FE:
285  /* The FE/BE protocol uses \n as newline for all platforms */
286  if (!cstate->opts.binary)
287  CopySendChar(cstate, '\n');
288 
289  /* Dump the accumulated row as one CopyData message */
290  (void) pq_putmessage('d', fe_msgbuf->data, fe_msgbuf->len);
291  break;
292  }
293 
294  /* Update the progress */
295  cstate->bytes_processed += fe_msgbuf->len;
297 
298  resetStringInfo(fe_msgbuf);
299 }
FILE * copy_file
Definition: copyto.c:76
void pgstat_progress_update_param(int index, int64 val)
Definition: pgstat.c:3478
int errcode(int sqlerrcode)
Definition: elog.c:704
uint64 bytes_processed
Definition: copyto.c:100
bool is_program
Definition: copyto.c:88
#define ERROR
Definition: elog.h:45
#define FATAL
Definition: elog.h:54
bool binary
Definition: copy.h:32
static void ClosePipeToProgram(CopyToState cstate)
Definition: copyto.c:333
int errcode_for_file_access(void)
Definition: elog.c:727
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
static void CopySendString(CopyToState cstate, const char *str)
Definition: copyto.c:209
CopyDest copy_dest
Definition: copyto.c:75
StringInfo fe_msgbuf
Definition: copyto.c:77
#define ereport(elevel,...)
Definition: elog.h:155
CopyFormatOptions opts
Definition: copyto.c:90
int errmsg(const char *fmt,...)
Definition: elog.c:915
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:215
#define PROGRESS_COPY_BYTES_PROCESSED
Definition: progress.h:137
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:42
int pq_putbytes(const char *s, size_t len)
Definition: pqcomm.c:1352

◆ CopySendInt16()

static void CopySendInt16 ( CopyToState  cstate,
int16  val 
)
inlinestatic

Definition at line 321 of file copyto.c.

References buf, CopySendData(), and pg_hton16.

Referenced by CopyOneRowTo(), and CopyTo().

322 {
323  uint16 buf;
324 
325  buf = pg_hton16((uint16) val);
326  CopySendData(cstate, &buf, sizeof(buf));
327 }
#define pg_hton16(x)
Definition: pg_bswap.h:120
unsigned short uint16
Definition: c.h:428
static char * buf
Definition: pg_test_fsync.c:68
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:203
long val
Definition: informix.c:664

◆ CopySendInt32()

static void CopySendInt32 ( CopyToState  cstate,
int32  val 
)
inlinestatic

Definition at line 309 of file copyto.c.

References buf, CopySendData(), and pg_hton32.

Referenced by CopyOneRowTo(), and CopyTo().

310 {
311  uint32 buf;
312 
313  buf = pg_hton32((uint32) val);
314  CopySendData(cstate, &buf, sizeof(buf));
315 }
#define pg_hton32(x)
Definition: pg_bswap.h:121
static char * buf
Definition: pg_test_fsync.c:68
unsigned int uint32
Definition: c.h:429
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:203
long val
Definition: informix.c:664

◆ CopySendString()

static void CopySendString ( CopyToState  cstate,
const char *  str 
)
static

Definition at line 209 of file copyto.c.

References appendBinaryStringInfo(), and CopyToStateData::fe_msgbuf.

Referenced by CopyAttributeOutCSV(), CopyOneRowTo(), and CopySendEndOfRow().

210 {
211  appendBinaryStringInfo(cstate->fe_msgbuf, str, strlen(str));
212 }
StringInfo fe_msgbuf
Definition: copyto.c:77
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ CopyTo()

static uint64 CopyTo ( CopyToState  cstate)
static

Definition at line 841 of file copyto.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, attname, attnum, CopyToStateData::attnumlist, CopyFormatOptions::binary, BinarySignature, CHECK_FOR_INTERRUPTS, CopyAttributeOutCSV(), CopyOneRowTo(), CopySendChar(), CopySendData(), CopySendEndOfRow(), CopySendInt16(), CopySendInt32(), cur, CurrentMemoryContext, CopyFormatOptions::delim, QueryDesc::dest, ExecDropSingleTupleTableSlot(), ExecutorRun(), CopyToStateData::fe_msgbuf, CopyToStateData::file_encoding, fmgr_info(), ForwardScanDirection, GetActiveSnapshot(), getTypeBinaryOutputInfo(), getTypeOutputInfo(), CopyFormatOptions::header_line, lfirst_int, list_length(), makeStringInfo(), MemoryContextDelete(), NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, CopyFormatOptions::null_print, CopyFormatOptions::null_print_client, CopyFormatOptions::null_print_len, CopyToStateData::opts, CopyToStateData::out_functions, palloc(), pg_server_to_any(), pgstat_progress_update_param(), PROGRESS_COPY_LINES_PROCESSED, CopyToStateData::queryDesc, CopyToStateData::rel, RelationGetDescr, CopyToStateData::rowcontext, slot_getallattrs(), table_beginscan(), table_endscan(), table_scan_getnextslot(), table_slot_create(), QueryDesc::tupDesc, and TupleDescAttr.

Referenced by DoCopyTo().

842 {
843  TupleDesc tupDesc;
844  int num_phys_attrs;
845  ListCell *cur;
846  uint64 processed;
847 
848  if (cstate->rel)
849  tupDesc = RelationGetDescr(cstate->rel);
850  else
851  tupDesc = cstate->queryDesc->tupDesc;
852  num_phys_attrs = tupDesc->natts;
853  cstate->opts.null_print_client = cstate->opts.null_print; /* default */
854 
855  /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
856  cstate->fe_msgbuf = makeStringInfo();
857 
858  /* Get info about the columns we need to process. */
859  cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
860  foreach(cur, cstate->attnumlist)
861  {
862  int attnum = lfirst_int(cur);
863  Oid out_func_oid;
864  bool isvarlena;
865  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
866 
867  if (cstate->opts.binary)
868  getTypeBinaryOutputInfo(attr->atttypid,
869  &out_func_oid,
870  &isvarlena);
871  else
872  getTypeOutputInfo(attr->atttypid,
873  &out_func_oid,
874  &isvarlena);
875  fmgr_info(out_func_oid, &cstate->out_functions[attnum - 1]);
876  }
877 
878  /*
879  * Create a temporary memory context that we can reset once per row to
880  * recover palloc'd memory. This avoids any problems with leaks inside
881  * datatype output routines, and should be faster than retail pfree's
882  * anyway. (We don't need a whole econtext as CopyFrom does.)
883  */
885  "COPY TO",
887 
888  if (cstate->opts.binary)
889  {
890  /* Generate header for a binary copy */
891  int32 tmp;
892 
893  /* Signature */
894  CopySendData(cstate, BinarySignature, 11);
895  /* Flags field */
896  tmp = 0;
897  CopySendInt32(cstate, tmp);
898  /* No header extension */
899  tmp = 0;
900  CopySendInt32(cstate, tmp);
901  }
902  else
903  {
904  /*
905  * For non-binary copy, we need to convert null_print to file
906  * encoding, because it will be sent directly with CopySendString.
907  */
908  if (cstate->need_transcoding)
910  cstate->opts.null_print_len,
911  cstate->file_encoding);
912 
913  /* if a header has been requested send the line */
914  if (cstate->opts.header_line)
915  {
916  bool hdr_delim = false;
917 
918  foreach(cur, cstate->attnumlist)
919  {
920  int attnum = lfirst_int(cur);
921  char *colname;
922 
923  if (hdr_delim)
924  CopySendChar(cstate, cstate->opts.delim[0]);
925  hdr_delim = true;
926 
927  colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
928 
929  CopyAttributeOutCSV(cstate, colname, false,
930  list_length(cstate->attnumlist) == 1);
931  }
932 
933  CopySendEndOfRow(cstate);
934  }
935  }
936 
937  if (cstate->rel)
938  {
939  TupleTableSlot *slot;
940  TableScanDesc scandesc;
941 
942  scandesc = table_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL);
943  slot = table_slot_create(cstate->rel, NULL);
944 
945  processed = 0;
946  while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
947  {
949 
950  /* Deconstruct the tuple ... */
951  slot_getallattrs(slot);
952 
953  /* Format and send the data */
954  CopyOneRowTo(cstate, slot);
955 
956  /* Increment amount of processed tuples and update the progress */
958  }
959 
961  table_endscan(scandesc);
962  }
963  else
964  {
965  /* run the plan --- the dest receiver will send tuples */
966  ExecutorRun(cstate->queryDesc, ForwardScanDirection, 0L, true);
967  processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
968  }
969 
970  if (cstate->opts.binary)
971  {
972  /* Generate trailer for a binary copy */
973  CopySendInt16(cstate, -1);
974  /* Need to flush out the trailer */
975  CopySendEndOfRow(cstate);
976  }
977 
979 
980  return processed;
981 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:91
int file_encoding
Definition: copyto.c:79
Definition: fmgr.h:56
int null_print_len
Definition: copy.h:37
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:212
#define AllocSetContextCreate
Definition: memutils.h:170
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2827
Relation rel
Definition: copyto.c:84
static void CopyAttributeOutCSV(CopyToState cstate, char *string, bool use_quote, bool single_attr)
Definition: copyto.c:1221
bool need_transcoding
Definition: copyto.c:80
FmgrInfo * out_functions
Definition: copyto.c:98
#define RelationGetDescr(relation)
Definition: rel.h:483
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
void pgstat_progress_update_param(int index, int64 val)
Definition: pgstat.c:3478
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:786
static void CopySendInt16(CopyToState cstate, int16 val)
Definition: copyto.c:321
struct cursor * cur
Definition: ecpg.c:28
char * null_print_client
Definition: copy.h:38
MemoryContext rowcontext
Definition: copyto.c:99
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:1003
unsigned int Oid
Definition: postgres_ext.h:31
char * null_print
Definition: copy.h:36
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:692
signed int int32
Definition: c.h:417
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:987
QueryDesc * queryDesc
Definition: copyto.c:85
List * attnumlist
Definition: copyto.c:86
NameData attname
Definition: pg_attribute.h:40
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key)
Definition: tableam.h:854
#define lfirst_int(lc)
Definition: pg_list.h:170
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
Definition: execMain.c:301
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
bool binary
Definition: copy.h:32
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:354
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
bool header_line
Definition: copy.h:35
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void CopySendInt32(CopyToState cstate, int32 val)
Definition: copyto.c:309
TupleDesc tupDesc
Definition: execdesc.h:47
StringInfo fe_msgbuf
Definition: copyto.c:77
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition: lsyscache.c:2893
char * delim
Definition: copy.h:39
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:203
int16 attnum
Definition: pg_attribute.h:79
static const char BinarySignature[11]
Definition: copyto.c:113
static int list_length(const List *l)
Definition: pg_list.h:149
CopyFormatOptions opts
Definition: copyto.c:90
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:962
DestReceiver * dest
Definition: execdesc.h:41
void * palloc(Size size)
Definition: mcxt.c:950
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:215
#define NameStr(name)
Definition: c.h:669
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
static void CopySendEndOfRow(CopyToState cstate)
Definition: copyto.c:221
#define PROGRESS_COPY_LINES_PROCESSED
Definition: progress.h:139

◆ CreateCopyDestReceiver()

DestReceiver* CreateCopyDestReceiver ( void  )

Definition at line 1351 of file copyto.c.

References copy_dest_destroy(), copy_dest_receive(), copy_dest_shutdown(), copy_dest_startup(), DestCopyOut, and palloc().

Referenced by CreateDestReceiver().

1352 {
1353  DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
1354 
1355  self->pub.receiveSlot = copy_dest_receive;
1356  self->pub.rStartup = copy_dest_startup;
1357  self->pub.rShutdown = copy_dest_shutdown;
1358  self->pub.rDestroy = copy_dest_destroy;
1359  self->pub.mydest = DestCopyOut;
1360 
1361  self->cstate = NULL; /* will be set later */
1362  self->processed = 0;
1363 
1364  return (DestReceiver *) self;
1365 }
static void copy_dest_destroy(DestReceiver *self)
Definition: copyto.c:1342
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copyto.c:1315
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copyto.c:1306
void * palloc(Size size)
Definition: mcxt.c:950
static void copy_dest_shutdown(DestReceiver *self)
Definition: copyto.c:1333

◆ DoCopyTo()

uint64 DoCopyTo ( CopyToState  cstate)

Definition at line 787 of file copyto.c.

References CopyTo(), DestRemote, CopyToStateData::filename, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pq_endcopyout, SendCopyBegin(), SendCopyEnd(), and whereToSendOutput.

Referenced by DoCopy().

788 {
789  bool pipe = (cstate->filename == NULL);
790  bool fe_copy = (pipe && whereToSendOutput == DestRemote);
791  uint64 processed;
792 
793  PG_TRY();
794  {
795  if (fe_copy)
796  SendCopyBegin(cstate);
797 
798  processed = CopyTo(cstate);
799 
800  if (fe_copy)
801  SendCopyEnd(cstate);
802  }
803  PG_CATCH();
804  {
805  /*
806  * Make sure we turn off old-style COPY OUT mode upon error. It is
807  * okay to do this in all cases, since it does nothing if the mode is
808  * not on.
809  */
810  pq_endcopyout(true);
811  PG_RE_THROW();
812  }
813  PG_END_TRY();
814 
815  return processed;
816 }
static void SendCopyEnd(CopyToState cstate)
Definition: copyto.c:174
static void SendCopyBegin(CopyToState cstate)
Definition: copyto.c:141
#define PG_CATCH()
Definition: elog.h:319
#define pq_endcopyout(errorAbort)
Definition: libpq.h:47
#define PG_RE_THROW()
Definition: elog.h:350
CommandDest whereToSendOutput
Definition: postgres.c:92
char * filename
Definition: copyto.c:87
#define PG_TRY()
Definition: elog.h:309
static uint64 CopyTo(CopyToState cstate)
Definition: copyto.c:841
#define PG_END_TRY()
Definition: elog.h:334

◆ EndCopy()

static void EndCopy ( CopyToState  cstate)
static

Definition at line 358 of file copyto.c.

References ClosePipeToProgram(), CopyToStateData::copy_file, CopyToStateData::copycontext, ereport, errcode_for_file_access(), errmsg(), ERROR, CopyToStateData::filename, FreeFile(), CopyToStateData::is_program, MemoryContextDelete(), pfree(), and pgstat_progress_end_command().

Referenced by EndCopyTo().

359 {
360  if (cstate->is_program)
361  {
362  ClosePipeToProgram(cstate);
363  }
364  else
365  {
366  if (cstate->filename != NULL && FreeFile(cstate->copy_file))
367  ereport(ERROR,
369  errmsg("could not close file \"%s\": %m",
370  cstate->filename)));
371  }
372 
374 
376  pfree(cstate);
377 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:212
FILE * copy_file
Definition: copyto.c:76
bool is_program
Definition: copyto.c:88
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ERROR
Definition: elog.h:45
MemoryContext copycontext
Definition: copyto.c:96
static void ClosePipeToProgram(CopyToState cstate)
Definition: copyto.c:333
int errcode_for_file_access(void)
Definition: elog.c:727
void pgstat_progress_end_command(void)
Definition: pgstat.c:3529
#define ereport(elevel,...)
Definition: elog.h:155
int FreeFile(FILE *file)
Definition: fd.c:2553
int errmsg(const char *fmt,...)
Definition: elog.c:915
char * filename
Definition: copyto.c:87

◆ EndCopyTo()

void EndCopyTo ( CopyToState  cstate)

Definition at line 822 of file copyto.c.

References EndCopy(), ExecutorEnd(), ExecutorFinish(), FreeQueryDesc(), PopActiveSnapshot(), and CopyToStateData::queryDesc.

Referenced by DoCopy().

823 {
824  if (cstate->queryDesc != NULL)
825  {
826  /* Close down the query and free resources. */
827  ExecutorFinish(cstate->queryDesc);
828  ExecutorEnd(cstate->queryDesc);
829  FreeQueryDesc(cstate->queryDesc);
831  }
832 
833  /* Clean up storage */
834  EndCopy(cstate);
835 }
void FreeQueryDesc(QueryDesc *qdesc)
Definition: pquery.c:105
void PopActiveSnapshot(void)
Definition: snapmgr.c:759
static void EndCopy(CopyToState cstate)
Definition: copyto.c:358
QueryDesc * queryDesc
Definition: copyto.c:85
void ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:462
void ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:402

◆ SendCopyBegin()

static void SendCopyBegin ( CopyToState  cstate)
static

Definition at line 141 of file copyto.c.

References CopyToStateData::attnumlist, CopyFormatOptions::binary, buf, CopyToStateData::copy_dest, COPY_NEW_FE, COPY_OLD_FE, ereport, errcode(), errmsg(), ERROR, format, FrontendProtocol, i, list_length(), CopyToStateData::opts, PG_PROTOCOL_MAJOR, pq_beginmessage(), pq_endmessage(), pq_putemptymessage(), pq_sendbyte(), pq_sendint16(), and pq_startcopyout.

Referenced by DoCopyTo().

142 {
144  {
145  /* new way */
147  int natts = list_length(cstate->attnumlist);
148  int16 format = (cstate->opts.binary ? 1 : 0);
149  int i;
150 
151  pq_beginmessage(&buf, 'H');
152  pq_sendbyte(&buf, format); /* overall format */
153  pq_sendint16(&buf, natts);
154  for (i = 0; i < natts; i++)
155  pq_sendint16(&buf, format); /* per-column formats */
156  pq_endmessage(&buf);
157  cstate->copy_dest = COPY_NEW_FE;
158  }
159  else
160  {
161  /* old way */
162  if (cstate->opts.binary)
163  ereport(ERROR,
164  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
165  errmsg("COPY BINARY is not supported to stdout or from stdin")));
166  pq_putemptymessage('H');
167  /* grottiness needed for old COPY OUT protocol */
168  pq_startcopyout();
169  cstate->copy_dest = COPY_OLD_FE;
170  }
171 }
signed short int16
Definition: c.h:416
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137
int errcode(int sqlerrcode)
Definition: elog.c:704
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:390
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:113
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:87
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:161
#define pq_startcopyout()
Definition: libpq.h:46
List * attnumlist
Definition: copyto.c:86
#define ERROR
Definition: elog.h:45
bool binary
Definition: copy.h:32
static char * buf
Definition: pg_test_fsync.c:68
CopyDest copy_dest
Definition: copyto.c:75
#define ereport(elevel,...)
Definition: elog.h:155
static int list_length(const List *l)
Definition: pg_list.h:149
CopyFormatOptions opts
Definition: copyto.c:90
int errmsg(const char *fmt,...)
Definition: elog.c:915
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:298
int i
static char format
ProtocolVersion FrontendProtocol
Definition: globals.c:28

◆ SendCopyEnd()

static void SendCopyEnd ( CopyToState  cstate)
static

Definition at line 174 of file copyto.c.

References Assert, CopyToStateData::copy_dest, COPY_NEW_FE, CopySendData(), CopySendEndOfRow(), CopyToStateData::fe_msgbuf, StringInfoData::len, pq_endcopyout, and pq_putemptymessage().

Referenced by DoCopyTo().

175 {
176  if (cstate->copy_dest == COPY_NEW_FE)
177  {
178  /* Shouldn't have any unsent data */
179  Assert(cstate->fe_msgbuf->len == 0);
180  /* Send Copy Done message */
181  pq_putemptymessage('c');
182  }
183  else
184  {
185  CopySendData(cstate, "\\.", 2);
186  /* Need to flush out the trailer (this also appends a newline) */
187  CopySendEndOfRow(cstate);
188  pq_endcopyout(false);
189  }
190 }
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:390
CopyDest copy_dest
Definition: copyto.c:75
StringInfo fe_msgbuf
Definition: copyto.c:77
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:203
#define Assert(condition)
Definition: c.h:792
#define pq_endcopyout(errorAbort)
Definition: libpq.h:47
static void CopySendEndOfRow(CopyToState cstate)
Definition: copyto.c:221

Variable Documentation

◆ BinarySignature

const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"
static

Definition at line 113 of file copyto.c.

Referenced by CopyTo().