PostgreSQL Source Code git master
copyto.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include "access/tableam.h"
#include "commands/copyapi.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 "pgstat.h"
#include "storage/fd.h"
#include "tcop/tcopprot.h"
#include "utils/lsyscache.h"
#include "utils/memutils.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_FRONTEND , COPY_CALLBACK }
 

Functions

static void EndCopy (CopyToState cstate)
 
static void ClosePipeToProgram (CopyToState cstate)
 
static void CopyOneRowTo (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyAttributeOutText (CopyToState cstate, const char *string)
 
static void CopyAttributeOutCSV (CopyToState cstate, const char *string, bool use_quote)
 
static void CopyToTextLikeStart (CopyToState cstate, TupleDesc tupDesc)
 
static void CopyToTextLikeOutFunc (CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
 
static void CopyToTextOneRow (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyToCSVOneRow (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyToTextLikeOneRow (CopyToState cstate, TupleTableSlot *slot, bool is_csv)
 
static void CopyToTextLikeEnd (CopyToState cstate)
 
static void CopyToBinaryStart (CopyToState cstate, TupleDesc tupDesc)
 
static void CopyToBinaryOutFunc (CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
 
static void CopyToBinaryOneRow (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyToBinaryEnd (CopyToState cstate)
 
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 CopySendTextLikeEndOfRow (CopyToState cstate)
 
static void CopySendInt32 (CopyToState cstate, int32 val)
 
static void CopySendInt16 (CopyToState cstate, int16 val)
 
static const CopyToRoutineCopyToGetRoutine (const CopyFormatOptions *opts)
 
CopyToState BeginCopyTo (ParseState *pstate, Relation rel, RawStmt *raw_query, Oid queryRelId, const char *filename, bool is_program, copy_data_dest_cb data_dest_cb, List *attnamelist, List *options)
 
void EndCopyTo (CopyToState cstate)
 
uint64 DoCopyTo (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"
 
static const CopyToRoutine CopyToRoutineText
 
static const CopyToRoutine CopyToRoutineCSV
 
static const CopyToRoutine CopyToRoutineBinary
 

Macro Definition Documentation

◆ DUMPSOFAR

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

Definition at line 1138 of file copyto.c.

Typedef Documentation

◆ CopyDest

typedef enum CopyDest CopyDest

◆ CopyToStateData

Enumeration Type Documentation

◆ CopyDest

enum CopyDest
Enumerator
COPY_FILE 
COPY_FRONTEND 
COPY_CALLBACK 

Definition at line 43 of file copyto.c.

44{
45 COPY_FILE, /* to file (or a piped program) */
46 COPY_FRONTEND, /* to frontend */
47 COPY_CALLBACK, /* to callback function */
48} CopyDest;
CopyDest
Definition: copyto.c:44
@ COPY_FILE
Definition: copyto.c:45
@ COPY_CALLBACK
Definition: copyto.c:47
@ COPY_FRONTEND
Definition: copyto.c:46

Function Documentation

◆ BeginCopyTo()

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

Definition at line 623 of file copyto.c.

632{
633 CopyToState cstate;
634 bool pipe = (filename == NULL && data_dest_cb == NULL);
635 TupleDesc tupDesc;
636 int num_phys_attrs;
637 MemoryContext oldcontext;
638 const int progress_cols[] = {
641 };
642 int64 progress_vals[] = {
644 0
645 };
646
647 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
648 {
649 if (rel->rd_rel->relkind == RELKIND_VIEW)
651 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
652 errmsg("cannot copy from view \"%s\"",
654 errhint("Try the COPY (SELECT ...) TO variant.")));
655 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
657 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
658 errmsg("cannot copy from materialized view \"%s\"",
660 errhint("Try the COPY (SELECT ...) TO variant.")));
661 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
663 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
664 errmsg("cannot copy from foreign table \"%s\"",
666 errhint("Try the COPY (SELECT ...) TO variant.")));
667 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
669 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
670 errmsg("cannot copy from sequence \"%s\"",
672 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
674 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
675 errmsg("cannot copy from partitioned table \"%s\"",
677 errhint("Try the COPY (SELECT ...) TO variant.")));
678 else
680 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
681 errmsg("cannot copy from non-table relation \"%s\"",
683 }
684
685
686 /* Allocate workspace and zero all fields */
687 cstate = (CopyToStateData *) palloc0(sizeof(CopyToStateData));
688
689 /*
690 * We allocate everything used by a cstate in a new memory context. This
691 * avoids memory leaks during repeated use of COPY in a query.
692 */
694 "COPY",
696
697 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
698
699 /* Extract options from the statement node tree */
700 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
701
702 /* Set format routine */
703 cstate->routine = CopyToGetRoutine(&cstate->opts);
704
705 /* Process the source/target relation or query */
706 if (rel)
707 {
708 Assert(!raw_query);
709
710 cstate->rel = rel;
711
712 tupDesc = RelationGetDescr(cstate->rel);
713 }
714 else
715 {
716 List *rewritten;
717 Query *query;
720
721 cstate->rel = NULL;
722
723 /*
724 * Run parse analysis and rewrite. Note this also acquires sufficient
725 * locks on the source table(s).
726 */
727 rewritten = pg_analyze_and_rewrite_fixedparams(raw_query,
728 pstate->p_sourcetext, NULL, 0,
729 NULL);
730
731 /* check that we got back something we can work with */
732 if (rewritten == NIL)
733 {
735 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
736 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
737 }
738 else if (list_length(rewritten) > 1)
739 {
740 ListCell *lc;
741
742 /* examine queries to determine which error message to issue */
743 foreach(lc, rewritten)
744 {
745 Query *q = lfirst_node(Query, lc);
746
747 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
749 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
750 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
751 if (q->querySource == QSRC_NON_INSTEAD_RULE)
753 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
754 errmsg("DO ALSO rules are not supported for COPY")));
755 }
756
758 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
759 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
760 }
761
762 query = linitial_node(Query, rewritten);
763
764 /* The grammar allows SELECT INTO, but we don't support that */
765 if (query->utilityStmt != NULL &&
768 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
769 errmsg("COPY (SELECT INTO) is not supported")));
770
771 /* The only other utility command we could see is NOTIFY */
772 if (query->utilityStmt != NULL)
774 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
775 errmsg("COPY query must not be a utility command")));
776
777 /*
778 * Similarly the grammar doesn't enforce the presence of a RETURNING
779 * clause, but this is required here.
780 */
781 if (query->commandType != CMD_SELECT &&
782 query->returningList == NIL)
783 {
784 Assert(query->commandType == CMD_INSERT ||
785 query->commandType == CMD_UPDATE ||
786 query->commandType == CMD_DELETE ||
787 query->commandType == CMD_MERGE);
788
790 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
791 errmsg("COPY query must have a RETURNING clause")));
792 }
793
794 /* plan the query */
795 plan = pg_plan_query(query, pstate->p_sourcetext,
797
798 /*
799 * With row-level security and a user using "COPY relation TO", we
800 * have to convert the "COPY relation TO" to a query-based COPY (eg:
801 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
802 * add in any RLS clauses.
803 *
804 * When this happens, we are passed in the relid of the originally
805 * found relation (which we have locked). As the planner will look up
806 * the relation again, we double-check here to make sure it found the
807 * same one that we have locked.
808 */
809 if (queryRelId != InvalidOid)
810 {
811 /*
812 * Note that with RLS involved there may be multiple relations,
813 * and while the one we need is almost certainly first, we don't
814 * make any guarantees of that in the planner, so check the whole
815 * list and make sure we find the original relation.
816 */
817 if (!list_member_oid(plan->relationOids, queryRelId))
819 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
820 errmsg("relation referenced by COPY statement has changed")));
821 }
822
823 /*
824 * Use a snapshot with an updated command ID to ensure this query sees
825 * results of any previously executed queries.
826 */
829
830 /* Create dest receiver for COPY OUT */
832 ((DR_copy *) dest)->cstate = cstate;
833
834 /* Create a QueryDesc requesting no output */
835 cstate->queryDesc = CreateQueryDesc(plan, NULL, pstate->p_sourcetext,
838 dest, NULL, NULL, 0);
839
840 /*
841 * Call ExecutorStart to prepare the plan for execution.
842 *
843 * ExecutorStart computes a result tupdesc for us
844 */
845 if (!ExecutorStart(cstate->queryDesc, 0))
846 elog(ERROR, "ExecutorStart() failed unexpectedly");
847
848 tupDesc = cstate->queryDesc->tupDesc;
849 }
850
851 /* Generate or convert list of attributes to process */
852 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
853
854 num_phys_attrs = tupDesc->natts;
855
856 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
857 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
858 if (cstate->opts.force_quote_all)
859 {
860 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
861 }
862 else if (cstate->opts.force_quote)
863 {
864 List *attnums;
865 ListCell *cur;
866
867 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
868
869 foreach(cur, attnums)
870 {
871 int attnum = lfirst_int(cur);
872 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
873
874 if (!list_member_int(cstate->attnumlist, attnum))
876 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
877 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
878 errmsg("%s column \"%s\" not referenced by COPY",
879 "FORCE_QUOTE", NameStr(attr->attname))));
880 cstate->opts.force_quote_flags[attnum - 1] = true;
881 }
882 }
883
884 /* Use client encoding when ENCODING option is not specified. */
885 if (cstate->opts.file_encoding < 0)
887 else
888 cstate->file_encoding = cstate->opts.file_encoding;
889
890 /*
891 * Set up encoding conversion info if the file and server encodings differ
892 * (see also pg_server_to_any).
893 */
894 if (cstate->file_encoding == GetDatabaseEncoding() ||
895 cstate->file_encoding == PG_SQL_ASCII)
896 cstate->need_transcoding = false;
897 else
898 cstate->need_transcoding = true;
899
900 /* See Multibyte encoding comment above */
902
903 cstate->copy_dest = COPY_FILE; /* default */
904
905 if (data_dest_cb)
906 {
907 progress_vals[1] = PROGRESS_COPY_TYPE_CALLBACK;
908 cstate->copy_dest = COPY_CALLBACK;
909 cstate->data_dest_cb = data_dest_cb;
910 }
911 else if (pipe)
912 {
913 progress_vals[1] = PROGRESS_COPY_TYPE_PIPE;
914
915 Assert(!is_program); /* the grammar does not allow this */
917 cstate->copy_file = stdout;
918 }
919 else
920 {
921 cstate->filename = pstrdup(filename);
922 cstate->is_program = is_program;
923
924 if (is_program)
925 {
926 progress_vals[1] = PROGRESS_COPY_TYPE_PROGRAM;
927 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
928 if (cstate->copy_file == NULL)
931 errmsg("could not execute command \"%s\": %m",
932 cstate->filename)));
933 }
934 else
935 {
936 mode_t oumask; /* Pre-existing umask value */
937 struct stat st;
938
939 progress_vals[1] = PROGRESS_COPY_TYPE_FILE;
940
941 /*
942 * Prevent write to relative path ... too easy to shoot oneself in
943 * the foot by overwriting a database file ...
944 */
947 (errcode(ERRCODE_INVALID_NAME),
948 errmsg("relative path not allowed for COPY to file")));
949
950 oumask = umask(S_IWGRP | S_IWOTH);
951 PG_TRY();
952 {
953 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
954 }
955 PG_FINALLY();
956 {
957 umask(oumask);
958 }
959 PG_END_TRY();
960 if (cstate->copy_file == NULL)
961 {
962 /* copy errno because ereport subfunctions might change it */
963 int save_errno = errno;
964
967 errmsg("could not open file \"%s\" for writing: %m",
968 cstate->filename),
969 (save_errno == ENOENT || save_errno == EACCES) ?
970 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
971 "You may want a client-side facility such as psql's \\copy.") : 0));
972 }
973
974 if (fstat(fileno(cstate->copy_file), &st))
977 errmsg("could not stat file \"%s\": %m",
978 cstate->filename)));
979
980 if (S_ISDIR(st.st_mode))
982 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
983 errmsg("\"%s\" is a directory", cstate->filename)));
984 }
985 }
986
987 /* initialize progress */
989 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
990 pgstat_progress_update_multi_param(2, progress_cols, progress_vals);
991
992 cstate->bytes_processed = 0;
993
994 MemoryContextSwitchTo(oldcontext);
995
996 return cstate;
997}
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition: copy.c:945
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition: copy.c:496
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
@ PROGRESS_COMMAND_COPY
#define NameStr(name)
Definition: c.h:717
int64_t int64
Definition: c.h:499
#define PG_BINARY_W
Definition: c.h:1247
#define MemSet(start, val, len)
Definition: c.h:991
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition: copyto.c:177
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:113
@ DestRemote
Definition: dest.h:89
@ DestCopyOut
Definition: dest.h:95
struct cursor * cur
Definition: ecpg.c:29
int errcode_for_file_access(void)
Definition: elog.c:876
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define PG_FINALLY(...)
Definition: elog.h:388
#define ereport(elevel,...)
Definition: elog.h:149
bool ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:125
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2708
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2605
Assert(PointerIsAligned(start, uint64))
bool list_member_int(const List *list, int datum)
Definition: list.c:702
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
int pg_get_client_encoding(void)
Definition: mbutils.c:336
char * pstrdup(const char *in)
Definition: mcxt.c:1699
void * palloc0(Size size)
Definition: mcxt.c:1347
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define IsA(nodeptr, _type_)
Definition: nodes.h:160
@ CMD_MERGE
Definition: nodes.h:271
@ CMD_INSERT
Definition: nodes.h:269
@ CMD_DELETE
Definition: nodes.h:270
@ CMD_UPDATE
Definition: nodes.h:268
@ CMD_SELECT
Definition: nodes.h:267
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
@ QSRC_NON_INSTEAD_RULE
Definition: parsenodes.h:40
@ QSRC_QUAL_INSTEAD_RULE
Definition: parsenodes.h:39
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:3378
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static char * filename
Definition: pg_dumpall.c:124
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial_node(type, l)
Definition: pg_list.h:181
#define NIL
Definition: pg_list.h:68
#define lfirst_int(lc)
Definition: pg_list.h:173
#define plan(x)
Definition: pg_regress.c:161
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition: pg_wchar.h:284
#define is_absolute_path(filename)
Definition: port.h:104
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams)
Definition: postgres.c:882
CommandDest whereToSendOutput
Definition: postgres.c:91
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition: postgres.c:665
#define InvalidOid
Definition: postgres_ext.h:37
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, CachedPlan *cplan, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
Definition: pquery.c:72
#define PROGRESS_COPY_COMMAND
Definition: progress.h:146
#define PROGRESS_COPY_TYPE_FILE
Definition: progress.h:155
#define PROGRESS_COPY_COMMAND_TO
Definition: progress.h:152
#define PROGRESS_COPY_TYPE
Definition: progress.h:147
#define PROGRESS_COPY_TYPE_PROGRAM
Definition: progress.h:156
#define PROGRESS_COPY_TYPE_CALLBACK
Definition: progress.h:158
#define PROGRESS_COPY_TYPE_PIPE
Definition: progress.h:157
#define RelationGetRelid(relation)
Definition: rel.h:512
#define RelationGetDescr(relation)
Definition: rel.h:538
#define RelationGetRelationName(relation)
Definition: rel.h:546
void UpdateActiveSnapshotCommandId(void)
Definition: snapmgr.c:731
void PushCopiedSnapshot(Snapshot snapshot)
Definition: snapmgr.c:719
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:787
#define InvalidSnapshot
Definition: snapshot.h:119
bool force_quote_all
Definition: copy.h:77
List * force_quote
Definition: copy.h:76
bool * force_quote_flags
Definition: copy.h:78
int file_encoding
Definition: copy.h:62
MemoryContext copycontext
Definition: copyto.c:93
Relation rel
Definition: copyto.c:80
const CopyToRoutine * routine
Definition: copyto.c:68
copy_data_dest_cb data_dest_cb
Definition: copyto.c:85
bool encoding_embeds_ascii
Definition: copyto.c:77
CopyDest copy_dest
Definition: copyto.c:71
bool need_transcoding
Definition: copyto.c:76
bool is_program
Definition: copyto.c:84
FILE * copy_file
Definition: copyto.c:72
int file_encoding
Definition: copyto.c:75
CopyFormatOptions opts
Definition: copyto.c:87
uint64 bytes_processed
Definition: copyto.c:97
char * filename
Definition: copyto.c:83
List * attnumlist
Definition: copyto.c:82
QueryDesc * queryDesc
Definition: copyto.c:81
Definition: pg_list.h:54
const char * p_sourcetext
Definition: parse_node.h:209
TupleDesc tupDesc
Definition: execdesc.h:48
List * returningList
Definition: parsenodes.h:209
CmdType commandType
Definition: parsenodes.h:121
Node * utilityStmt
Definition: parsenodes.h:136
Form_pg_class rd_rel
Definition: rel.h:111
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:154
#define S_IWOTH
Definition: win32_port.h:306
#define S_ISDIR(m)
Definition: win32_port.h:315
#define fstat
Definition: win32_port.h:273
#define S_IWGRP
Definition: win32_port.h:294

References AllocateFile(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), attnum, CopyToStateData::attnumlist, CopyToStateData::bytes_processed, CMD_DELETE, CMD_INSERT, CMD_MERGE, CMD_SELECT, CMD_UPDATE, Query::commandType, COPY_CALLBACK, CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, CopyToStateData::copycontext, CopyGetAttnums(), CopyToGetRoutine(), CreateDestReceiver(), CreateQueryDesc(), cur, CurrentMemoryContext, CURSOR_OPT_PARALLEL_OK, CopyToStateData::data_dest_cb, generate_unaccent_rules::dest, DestCopyOut, DestRemote, elog, CopyToStateData::encoding_embeds_ascii, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, ExecutorStart(), CopyToStateData::file_encoding, CopyFormatOptions::file_encoding, CopyToStateData::filename, filename, CopyFormatOptions::force_quote, CopyFormatOptions::force_quote_all, CopyFormatOptions::force_quote_flags, fstat, GetActiveSnapshot(), GetDatabaseEncoding(), InvalidOid, InvalidSnapshot, is_absolute_path, CopyToStateData::is_program, IsA, lfirst_int, lfirst_node, linitial_node, list_length(), list_member_int(), list_member_oid(), MemoryContextSwitchTo(), MemSet, NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, NIL, OpenPipeStream(), CopyToStateData::opts, ParseState::p_sourcetext, palloc0(), pg_analyze_and_rewrite_fixedparams(), PG_BINARY_W, PG_ENCODING_IS_CLIENT_ONLY, PG_END_TRY, PG_FINALLY, pg_get_client_encoding(), pg_plan_query(), PG_SQL_ASCII, PG_TRY, pgstat_progress_start_command(), pgstat_progress_update_multi_param(), plan, ProcessCopyOptions(), PROGRESS_COMMAND_COPY, PROGRESS_COPY_COMMAND, PROGRESS_COPY_COMMAND_TO, PROGRESS_COPY_TYPE, PROGRESS_COPY_TYPE_CALLBACK, PROGRESS_COPY_TYPE_FILE, PROGRESS_COPY_TYPE_PIPE, PROGRESS_COPY_TYPE_PROGRAM, pstrdup(), PushCopiedSnapshot(), QSRC_NON_INSTEAD_RULE, QSRC_QUAL_INSTEAD_RULE, CopyToStateData::queryDesc, RelationData::rd_rel, CopyToStateData::rel, RelationGetDescr, RelationGetRelationName, RelationGetRelid, Query::returningList, CopyToStateData::routine, S_ISDIR, S_IWGRP, S_IWOTH, stat::st_mode, generate_unaccent_rules::stdout, QueryDesc::tupDesc, TupleDescAttr(), UpdateActiveSnapshotCommandId(), Query::utilityStmt, and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ ClosePipeToProgram()

static void ClosePipeToProgram ( CopyToState  cstate)
static

Definition at line 562 of file copyto.c.

563{
564 int pclose_rc;
565
566 Assert(cstate->is_program);
567
568 pclose_rc = ClosePipeStream(cstate->copy_file);
569 if (pclose_rc == -1)
572 errmsg("could not close pipe to external command: %m")));
573 else if (pclose_rc != 0)
574 {
576 (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
577 errmsg("program \"%s\" failed",
578 cstate->filename),
579 errdetail_internal("%s", wait_result_to_str(pclose_rc))));
580 }
581}
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
int ClosePipeStream(FILE *file)
Definition: fd.c:3013
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33

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().

◆ copy_dest_destroy()

static void copy_dest_destroy ( DestReceiver self)
static

Definition at line 1424 of file copyto.c.

1425{
1426 pfree(self);
1427}
void pfree(void *pointer)
Definition: mcxt.c:1524

References pfree().

Referenced by CreateCopyDestReceiver().

◆ copy_dest_receive()

static bool copy_dest_receive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 1396 of file copyto.c.

1397{
1398 DR_copy *myState = (DR_copy *) self;
1399 CopyToState cstate = myState->cstate;
1400
1401 /* Send the data */
1402 CopyOneRowTo(cstate, slot);
1403
1404 /* Increment the number of processed tuples, and report the progress */
1406 ++myState->processed);
1407
1408 return true;
1409}
void pgstat_progress_update_param(int index, int64 val)
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:1120
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition: progress.h:144
CopyToState cstate
Definition: copyto.c:104
uint64 processed
Definition: copyto.c:105

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

Referenced by CreateCopyDestReceiver().

◆ copy_dest_shutdown()

static void copy_dest_shutdown ( DestReceiver self)
static

Definition at line 1415 of file copyto.c.

1416{
1417 /* no-op */
1418}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1387 of file copyto.c.

1388{
1389 /* no-op */
1390}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1298 of file copyto.c.

1300{
1301 const char *ptr;
1302 const char *start;
1303 char c;
1304 char delimc = cstate->opts.delim[0];
1305 char quotec = cstate->opts.quote[0];
1306 char escapec = cstate->opts.escape[0];
1307 bool single_attr = (list_length(cstate->attnumlist) == 1);
1308
1309 /* force quoting if it matches null_print (before conversion!) */
1310 if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1311 use_quote = true;
1312
1313 if (cstate->need_transcoding)
1314 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1315 else
1316 ptr = string;
1317
1318 /*
1319 * Make a preliminary pass to discover if it needs quoting
1320 */
1321 if (!use_quote)
1322 {
1323 /*
1324 * Quote '\.' if it appears alone on a line, so that it will not be
1325 * interpreted as an end-of-data marker. (PG 18 and up will not
1326 * interpret '\.' in CSV that way, except in embedded-in-SQL data; but
1327 * we want the data to be loadable by older versions too. Also, this
1328 * avoids breaking clients that are still using PQgetline().)
1329 */
1330 if (single_attr && strcmp(ptr, "\\.") == 0)
1331 use_quote = true;
1332 else
1333 {
1334 const char *tptr = ptr;
1335
1336 while ((c = *tptr) != '\0')
1337 {
1338 if (c == delimc || c == quotec || c == '\n' || c == '\r')
1339 {
1340 use_quote = true;
1341 break;
1342 }
1343 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1344 tptr += pg_encoding_mblen(cstate->file_encoding, tptr);
1345 else
1346 tptr++;
1347 }
1348 }
1349 }
1350
1351 if (use_quote)
1352 {
1353 CopySendChar(cstate, quotec);
1354
1355 /*
1356 * We adopt the same optimization strategy as in CopyAttributeOutText
1357 */
1358 start = ptr;
1359 while ((c = *ptr) != '\0')
1360 {
1361 if (c == quotec || c == escapec)
1362 {
1363 DUMPSOFAR();
1364 CopySendChar(cstate, escapec);
1365 start = ptr; /* we include char in next run */
1366 }
1367 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1368 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1369 else
1370 ptr++;
1371 }
1372 DUMPSOFAR();
1373
1374 CopySendChar(cstate, quotec);
1375 }
1376 else
1377 {
1378 /* If it doesn't need quoting, we can just dump it as-is */
1379 CopySendString(cstate, ptr);
1380 }
1381}
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1126
#define DUMPSOFAR()
Definition: copyto.c:1138
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:439
static void CopySendString(CopyToState cstate, const char *str)
Definition: copyto.c:433
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:749
char * c
char string[11]
Definition: preproc-type.c:52
char * quote
Definition: copy.h:74
char * escape
Definition: copy.h:75
char * null_print
Definition: copy.h:68
char * delim
Definition: copy.h:73
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition: wchar.c:2116

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

Referenced by CopyToTextLikeOneRow(), and CopyToTextLikeStart().

◆ CopyAttributeOutText()

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

Definition at line 1145 of file copyto.c.

1146{
1147 const char *ptr;
1148 const char *start;
1149 char c;
1150 char delimc = cstate->opts.delim[0];
1151
1152 if (cstate->need_transcoding)
1153 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1154 else
1155 ptr = string;
1156
1157 /*
1158 * We have to grovel through the string searching for control characters
1159 * and instances of the delimiter character. In most cases, though, these
1160 * are infrequent. To avoid overhead from calling CopySendData once per
1161 * character, we dump out all characters between escaped characters in a
1162 * single call. The loop invariant is that the data from "start" to "ptr"
1163 * can be sent literally, but hasn't yet been.
1164 *
1165 * We can skip pg_encoding_mblen() overhead when encoding is safe, because
1166 * in valid backend encodings, extra bytes of a multibyte character never
1167 * look like ASCII. This loop is sufficiently performance-critical that
1168 * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
1169 * of the normal safe-encoding path.
1170 */
1171 if (cstate->encoding_embeds_ascii)
1172 {
1173 start = ptr;
1174 while ((c = *ptr) != '\0')
1175 {
1176 if ((unsigned char) c < (unsigned char) 0x20)
1177 {
1178 /*
1179 * \r and \n must be escaped, the others are traditional. We
1180 * prefer to dump these using the C-like notation, rather than
1181 * a backslash and the literal character, because it makes the
1182 * dump file a bit more proof against Microsoftish data
1183 * mangling.
1184 */
1185 switch (c)
1186 {
1187 case '\b':
1188 c = 'b';
1189 break;
1190 case '\f':
1191 c = 'f';
1192 break;
1193 case '\n':
1194 c = 'n';
1195 break;
1196 case '\r':
1197 c = 'r';
1198 break;
1199 case '\t':
1200 c = 't';
1201 break;
1202 case '\v':
1203 c = 'v';
1204 break;
1205 default:
1206 /* If it's the delimiter, must backslash it */
1207 if (c == delimc)
1208 break;
1209 /* All ASCII control chars are length 1 */
1210 ptr++;
1211 continue; /* fall to end of loop */
1212 }
1213 /* if we get here, we need to convert the control char */
1214 DUMPSOFAR();
1215 CopySendChar(cstate, '\\');
1216 CopySendChar(cstate, c);
1217 start = ++ptr; /* do not include char in next run */
1218 }
1219 else if (c == '\\' || c == delimc)
1220 {
1221 DUMPSOFAR();
1222 CopySendChar(cstate, '\\');
1223 start = ptr++; /* we include char in next run */
1224 }
1225 else if (IS_HIGHBIT_SET(c))
1226 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1227 else
1228 ptr++;
1229 }
1230 }
1231 else
1232 {
1233 start = ptr;
1234 while ((c = *ptr) != '\0')
1235 {
1236 if ((unsigned char) c < (unsigned char) 0x20)
1237 {
1238 /*
1239 * \r and \n must be escaped, the others are traditional. We
1240 * prefer to dump these using the C-like notation, rather than
1241 * a backslash and the literal character, because it makes the
1242 * dump file a bit more proof against Microsoftish data
1243 * mangling.
1244 */
1245 switch (c)
1246 {
1247 case '\b':
1248 c = 'b';
1249 break;
1250 case '\f':
1251 c = 'f';
1252 break;
1253 case '\n':
1254 c = 'n';
1255 break;
1256 case '\r':
1257 c = 'r';
1258 break;
1259 case '\t':
1260 c = 't';
1261 break;
1262 case '\v':
1263 c = 'v';
1264 break;
1265 default:
1266 /* If it's the delimiter, must backslash it */
1267 if (c == delimc)
1268 break;
1269 /* All ASCII control chars are length 1 */
1270 ptr++;
1271 continue; /* fall to end of loop */
1272 }
1273 /* if we get here, we need to convert the control char */
1274 DUMPSOFAR();
1275 CopySendChar(cstate, '\\');
1276 CopySendChar(cstate, c);
1277 start = ++ptr; /* do not include char in next run */
1278 }
1279 else if (c == '\\' || c == delimc)
1280 {
1281 DUMPSOFAR();
1282 CopySendChar(cstate, '\\');
1283 start = ptr++; /* we include char in next run */
1284 }
1285 else
1286 ptr++;
1287 }
1288 }
1289
1290 DUMPSOFAR();
1291}

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

Referenced by CopyToTextLikeOneRow(), and CopyToTextLikeStart().

◆ CopyOneRowTo()

static void CopyOneRowTo ( CopyToState  cstate,
TupleTableSlot slot 
)
inlinestatic

Definition at line 1120 of file copyto.c.

1121{
1122 MemoryContext oldcontext;
1123
1125 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1126
1127 /* Make sure the tuple is fully deconstructed */
1128 slot_getallattrs(slot);
1129
1130 cstate->routine->CopyToOneRow(cstate, slot);
1131
1132 MemoryContextSwitchTo(oldcontext);
1133}
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
void(* CopyToOneRow)(CopyToState cstate, TupleTableSlot *slot)
Definition: copyapi.h:49
MemoryContext rowcontext
Definition: copyto.c:96
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:368

References CopyToRoutine::CopyToOneRow, MemoryContextReset(), MemoryContextSwitchTo(), CopyToStateData::routine, CopyToStateData::rowcontext, and slot_getallattrs().

Referenced by copy_dest_receive(), and DoCopyTo().

◆ CopySendChar()

static void CopySendChar ( CopyToState  cstate,
char  c 
)
static

Definition at line 439 of file copyto.c.

440{
442}
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:231
StringInfo fe_msgbuf
Definition: copyto.c:73

References appendStringInfoCharMacro, and CopyToStateData::fe_msgbuf.

Referenced by CopyAttributeOutCSV(), CopyAttributeOutText(), CopySendTextLikeEndOfRow(), CopyToTextLikeOneRow(), and CopyToTextLikeStart().

◆ CopySendData()

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

Definition at line 427 of file copyto.c.

428{
429 appendBinaryStringInfo(cstate->fe_msgbuf, databuf, datasize);
430}
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281

References appendBinaryStringInfo(), and CopyToStateData::fe_msgbuf.

Referenced by CopySendInt16(), CopySendInt32(), CopyToBinaryOneRow(), and CopyToBinaryStart().

◆ CopySendEndOfRow()

static void CopySendEndOfRow ( CopyToState  cstate)
static

Definition at line 445 of file copyto.c.

446{
447 StringInfo fe_msgbuf = cstate->fe_msgbuf;
448
449 switch (cstate->copy_dest)
450 {
451 case COPY_FILE:
452 if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
453 cstate->copy_file) != 1 ||
454 ferror(cstate->copy_file))
455 {
456 if (cstate->is_program)
457 {
458 if (errno == EPIPE)
459 {
460 /*
461 * The pipe will be closed automatically on error at
462 * the end of transaction, but we might get a better
463 * error message from the subprocess' exit code than
464 * just "Broken Pipe"
465 */
466 ClosePipeToProgram(cstate);
467
468 /*
469 * If ClosePipeToProgram() didn't throw an error, the
470 * program terminated normally, but closed the pipe
471 * first. Restore errno, and throw an error.
472 */
473 errno = EPIPE;
474 }
477 errmsg("could not write to COPY program: %m")));
478 }
479 else
482 errmsg("could not write to COPY file: %m")));
483 }
484 break;
485 case COPY_FRONTEND:
486 /* Dump the accumulated row as one CopyData message */
487 (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
488 break;
489 case COPY_CALLBACK:
490 cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
491 break;
492 }
493
494 /* Update the progress */
495 cstate->bytes_processed += fe_msgbuf->len;
497
498 resetStringInfo(fe_msgbuf);
499}
static void ClosePipeToProgram(CopyToState cstate)
Definition: copyto.c:562
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:49
#define PROGRESS_COPY_BYTES_PROCESSED
Definition: progress.h:142
#define PqMsg_CopyData
Definition: protocol.h:65
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:126

References CopyToStateData::bytes_processed, ClosePipeToProgram(), COPY_CALLBACK, CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, COPY_FRONTEND, StringInfoData::data, CopyToStateData::data_dest_cb, ereport, errcode_for_file_access(), errmsg(), ERROR, CopyToStateData::fe_msgbuf, CopyToStateData::is_program, StringInfoData::len, pgstat_progress_update_param(), pq_putmessage, PqMsg_CopyData, PROGRESS_COPY_BYTES_PROCESSED, and resetStringInfo().

Referenced by CopySendTextLikeEndOfRow(), CopyToBinaryEnd(), and CopyToBinaryOneRow().

◆ CopySendInt16()

static void CopySendInt16 ( CopyToState  cstate,
int16  val 
)
inlinestatic

Definition at line 550 of file copyto.c.

551{
552 uint16 buf;
553
554 buf = pg_hton16((uint16) val);
555 CopySendData(cstate, &buf, sizeof(buf));
556}
uint16_t uint16
Definition: c.h:501
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:427
long val
Definition: informix.c:689
#define pg_hton16(x)
Definition: pg_bswap.h:120
static char * buf
Definition: pg_test_fsync.c:72

References buf, CopySendData(), pg_hton16, and val.

Referenced by CopyToBinaryEnd(), and CopyToBinaryOneRow().

◆ CopySendInt32()

static void CopySendInt32 ( CopyToState  cstate,
int32  val 
)
inlinestatic

Definition at line 538 of file copyto.c.

539{
540 uint32 buf;
541
542 buf = pg_hton32((uint32) val);
543 CopySendData(cstate, &buf, sizeof(buf));
544}
uint32_t uint32
Definition: c.h:502
#define pg_hton32(x)
Definition: pg_bswap.h:121

References buf, CopySendData(), pg_hton32, and val.

Referenced by CopyToBinaryOneRow(), and CopyToBinaryStart().

◆ CopySendString()

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

Definition at line 433 of file copyto.c.

434{
435 appendBinaryStringInfo(cstate->fe_msgbuf, str, strlen(str));
436}
const char * str

References appendBinaryStringInfo(), CopyToStateData::fe_msgbuf, and str.

Referenced by CopyAttributeOutCSV(), CopySendTextLikeEndOfRow(), and CopyToTextLikeOneRow().

◆ CopySendTextLikeEndOfRow()

static void CopySendTextLikeEndOfRow ( CopyToState  cstate)
inlinestatic

Definition at line 506 of file copyto.c.

507{
508 switch (cstate->copy_dest)
509 {
510 case COPY_FILE:
511 /* Default line termination depends on platform */
512#ifndef WIN32
513 CopySendChar(cstate, '\n');
514#else
515 CopySendString(cstate, "\r\n");
516#endif
517 break;
518 case COPY_FRONTEND:
519 /* The FE/BE protocol uses \n as newline for all platforms */
520 CopySendChar(cstate, '\n');
521 break;
522 default:
523 break;
524 }
525
526 /* Now take the actions related to the end of a row */
527 CopySendEndOfRow(cstate);
528}
static void CopySendEndOfRow(CopyToState cstate)
Definition: copyto.c:445

References CopyToStateData::copy_dest, COPY_FILE, COPY_FRONTEND, CopySendChar(), CopySendEndOfRow(), and CopySendString().

Referenced by CopyToTextLikeOneRow(), and CopyToTextLikeStart().

◆ CopyToBinaryEnd()

static void CopyToBinaryEnd ( CopyToState  cstate)
static

Definition at line 378 of file copyto.c.

379{
380 /* Generate trailer for a binary copy */
381 CopySendInt16(cstate, -1);
382 /* Need to flush out the trailer */
383 CopySendEndOfRow(cstate);
384}
static void CopySendInt16(CopyToState cstate, int16 val)
Definition: copyto.c:550

References CopySendEndOfRow(), and CopySendInt16().

◆ CopyToBinaryOneRow()

static void CopyToBinaryOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 345 of file copyto.c.

346{
347 FmgrInfo *out_functions = cstate->out_functions;
348
349 /* Binary per-tuple header */
350 CopySendInt16(cstate, list_length(cstate->attnumlist));
351
353 {
354 Datum value = slot->tts_values[attnum - 1];
355 bool isnull = slot->tts_isnull[attnum - 1];
356
357 if (isnull)
358 {
359 CopySendInt32(cstate, -1);
360 }
361 else
362 {
363 bytea *outputbytes;
364
365 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
366 value);
367 CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);
368 CopySendData(cstate, VARDATA(outputbytes),
369 VARSIZE(outputbytes) - VARHDRSZ);
370 }
371 }
372
373 CopySendEndOfRow(cstate);
374}
#define VARHDRSZ
Definition: c.h:663
static void CopySendInt32(CopyToState cstate, int32 val)
Definition: copyto.c:538
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1744
static struct @165 value
#define foreach_int(var, lst)
Definition: pg_list.h:470
uintptr_t Datum
Definition: postgres.h:69
FmgrInfo * out_functions
Definition: copyto.c:95
Definition: fmgr.h:57
bool * tts_isnull
Definition: tuptable.h:127
Datum * tts_values
Definition: tuptable.h:125
Definition: c.h:658
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARSIZE(PTR)
Definition: varatt.h:279

References attnum, CopyToStateData::attnumlist, CopySendData(), CopySendEndOfRow(), CopySendInt16(), CopySendInt32(), foreach_int, list_length(), CopyToStateData::out_functions, SendFunctionCall(), TupleTableSlot::tts_isnull, TupleTableSlot::tts_values, value, VARDATA, VARHDRSZ, and VARSIZE.

◆ CopyToBinaryOutFunc()

static void CopyToBinaryOutFunc ( CopyToState  cstate,
Oid  atttypid,
FmgrInfo finfo 
)
static

Definition at line 333 of file copyto.c.

334{
335 Oid func_oid;
336 bool is_varlena;
337
338 /* Set output function for an attribute */
339 getTypeBinaryOutputInfo(atttypid, &func_oid, &is_varlena);
340 fmgr_info(func_oid, finfo);
341}
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition: lsyscache.c:3056
unsigned int Oid
Definition: postgres_ext.h:32

References fmgr_info(), and getTypeBinaryOutputInfo().

◆ CopyToBinaryStart()

static void CopyToBinaryStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 314 of file copyto.c.

315{
316 int32 tmp;
317
318 /* Signature */
319 CopySendData(cstate, BinarySignature, 11);
320 /* Flags field */
321 tmp = 0;
322 CopySendInt32(cstate, tmp);
323 /* No header extension */
324 tmp = 0;
325 CopySendInt32(cstate, tmp);
326}
int32_t int32
Definition: c.h:498
static const char BinarySignature[11]
Definition: copyto.c:109

References BinarySignature, CopySendData(), and CopySendInt32().

◆ CopyToCSVOneRow()

static void CopyToCSVOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 252 of file copyto.c.

253{
254 CopyToTextLikeOneRow(cstate, slot, true);
255}
static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv)
Definition: copyto.c:264

References CopyToTextLikeOneRow().

◆ CopyToGetRoutine()

static const CopyToRoutine * CopyToGetRoutine ( const CopyFormatOptions opts)
static

Definition at line 177 of file copyto.c.

178{
179 if (opts->csv_mode)
180 return &CopyToRoutineCSV;
181 else if (opts->binary)
182 return &CopyToRoutineBinary;
183
184 /* default is text */
185 return &CopyToRoutineText;
186}
static const CopyToRoutine CopyToRoutineCSV
Definition: copyto.c:160
static const CopyToRoutine CopyToRoutineText
Definition: copyto.c:152
static const CopyToRoutine CopyToRoutineBinary
Definition: copyto.c:168
static AmcheckOptions opts
Definition: pg_amcheck.c:112

References CopyToRoutineBinary, CopyToRoutineCSV, CopyToRoutineText, and opts.

Referenced by BeginCopyTo().

◆ CopyToTextLikeEnd()

static void CopyToTextLikeEnd ( CopyToState  cstate)
static

Definition at line 304 of file copyto.c.

305{
306 /* Nothing to do here */
307}

◆ CopyToTextLikeOneRow()

static pg_attribute_always_inline void CopyToTextLikeOneRow ( CopyToState  cstate,
TupleTableSlot slot,
bool  is_csv 
)
static

Definition at line 264 of file copyto.c.

267{
268 bool need_delim = false;
269 FmgrInfo *out_functions = cstate->out_functions;
270
272 {
273 Datum value = slot->tts_values[attnum - 1];
274 bool isnull = slot->tts_isnull[attnum - 1];
275
276 if (need_delim)
277 CopySendChar(cstate, cstate->opts.delim[0]);
278 need_delim = true;
279
280 if (isnull)
281 {
282 CopySendString(cstate, cstate->opts.null_print_client);
283 }
284 else
285 {
286 char *string;
287
288 string = OutputFunctionCall(&out_functions[attnum - 1],
289 value);
290
291 if (is_csv)
292 CopyAttributeOutCSV(cstate, string,
293 cstate->opts.force_quote_flags[attnum - 1]);
294 else
295 CopyAttributeOutText(cstate, string);
296 }
297 }
298
300}
static void CopyAttributeOutCSV(CopyToState cstate, const char *string, bool use_quote)
Definition: copyto.c:1298
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition: copyto.c:1145
static void CopySendTextLikeEndOfRow(CopyToState cstate)
Definition: copyto.c:506
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
char * null_print_client
Definition: copy.h:70

References attnum, CopyToStateData::attnumlist, CopyAttributeOutCSV(), CopyAttributeOutText(), CopySendChar(), CopySendString(), CopySendTextLikeEndOfRow(), CopyFormatOptions::delim, CopyFormatOptions::force_quote_flags, foreach_int, CopyFormatOptions::null_print_client, CopyToStateData::opts, CopyToStateData::out_functions, OutputFunctionCall(), TupleTableSlot::tts_isnull, TupleTableSlot::tts_values, and value.

Referenced by CopyToCSVOneRow(), and CopyToTextOneRow().

◆ CopyToTextLikeOutFunc()

static void CopyToTextLikeOutFunc ( CopyToState  cstate,
Oid  atttypid,
FmgrInfo finfo 
)
static

Definition at line 233 of file copyto.c.

234{
235 Oid func_oid;
236 bool is_varlena;
237
238 /* Set output function for an attribute */
239 getTypeOutputInfo(atttypid, &func_oid, &is_varlena);
240 fmgr_info(func_oid, finfo);
241}
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2990

References fmgr_info(), and getTypeOutputInfo().

◆ CopyToTextLikeStart()

static void CopyToTextLikeStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 190 of file copyto.c.

191{
192 /*
193 * For non-binary copy, we need to convert null_print to file encoding,
194 * because it will be sent directly with CopySendString.
195 */
196 if (cstate->need_transcoding)
198 cstate->opts.null_print_len,
199 cstate->file_encoding);
200
201 /* if a header has been requested send the line */
202 if (cstate->opts.header_line)
203 {
204 ListCell *cur;
205 bool hdr_delim = false;
206
207 foreach(cur, cstate->attnumlist)
208 {
209 int attnum = lfirst_int(cur);
210 char *colname;
211
212 if (hdr_delim)
213 CopySendChar(cstate, cstate->opts.delim[0]);
214 hdr_delim = true;
215
216 colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
217
218 if (cstate->opts.csv_mode)
219 CopyAttributeOutCSV(cstate, colname, false);
220 else
221 CopyAttributeOutText(cstate, colname);
222 }
223
225 }
226}
NameData attname
Definition: pg_attribute.h:41
int null_print_len
Definition: copy.h:69
CopyHeaderChoice header_line
Definition: copy.h:67
bool csv_mode
Definition: copy.h:66

References attname, attnum, CopyToStateData::attnumlist, CopyAttributeOutCSV(), CopyAttributeOutText(), CopySendChar(), CopySendTextLikeEndOfRow(), CopyFormatOptions::csv_mode, cur, CopyFormatOptions::delim, CopyToStateData::file_encoding, CopyFormatOptions::header_line, lfirst_int, NameStr, CopyToStateData::need_transcoding, CopyFormatOptions::null_print, CopyFormatOptions::null_print_client, CopyFormatOptions::null_print_len, CopyToStateData::opts, pg_server_to_any(), and TupleDescAttr().

◆ CopyToTextOneRow()

static void CopyToTextOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 245 of file copyto.c.

246{
247 CopyToTextLikeOneRow(cstate, slot, false);
248}

References CopyToTextLikeOneRow().

◆ CreateCopyDestReceiver()

DestReceiver * CreateCopyDestReceiver ( void  )

Definition at line 1433 of file copyto.c.

1434{
1435 DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
1436
1441 self->pub.mydest = DestCopyOut;
1442
1443 self->cstate = NULL; /* will be set later */
1444 self->processed = 0;
1445
1446 return (DestReceiver *) self;
1447}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copyto.c:1396
static void copy_dest_destroy(DestReceiver *self)
Definition: copyto.c:1424
static void copy_dest_shutdown(DestReceiver *self)
Definition: copyto.c:1415
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copyto.c:1387
void * palloc(Size size)
Definition: mcxt.c:1317
DestReceiver pub
Definition: copyto.c:103
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
void(* rDestroy)(DestReceiver *self)
Definition: dest.h:126
CommandDest mydest
Definition: dest.h:128

References copy_dest_destroy(), copy_dest_receive(), copy_dest_shutdown(), copy_dest_startup(), DR_copy::cstate, DestCopyOut, _DestReceiver::mydest, palloc(), DR_copy::processed, DR_copy::pub, _DestReceiver::rDestroy, _DestReceiver::receiveSlot, _DestReceiver::rShutdown, and _DestReceiver::rStartup.

Referenced by CreateDestReceiver().

◆ DoCopyTo()

uint64 DoCopyTo ( CopyToState  cstate)

Definition at line 1024 of file copyto.c.

1025{
1026 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1027 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1028 TupleDesc tupDesc;
1029 int num_phys_attrs;
1030 ListCell *cur;
1031 uint64 processed;
1032
1033 if (fe_copy)
1034 SendCopyBegin(cstate);
1035
1036 if (cstate->rel)
1037 tupDesc = RelationGetDescr(cstate->rel);
1038 else
1039 tupDesc = cstate->queryDesc->tupDesc;
1040 num_phys_attrs = tupDesc->natts;
1041 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1042
1043 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1044 cstate->fe_msgbuf = makeStringInfo();
1045
1046 /* Get info about the columns we need to process. */
1047 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1048 foreach(cur, cstate->attnumlist)
1049 {
1050 int attnum = lfirst_int(cur);
1051 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1052
1053 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1054 &cstate->out_functions[attnum - 1]);
1055 }
1056
1057 /*
1058 * Create a temporary memory context that we can reset once per row to
1059 * recover palloc'd memory. This avoids any problems with leaks inside
1060 * datatype output routines, and should be faster than retail pfree's
1061 * anyway. (We don't need a whole econtext as CopyFrom does.)
1062 */
1064 "COPY TO",
1066
1067 cstate->routine->CopyToStart(cstate, tupDesc);
1068
1069 if (cstate->rel)
1070 {
1071 TupleTableSlot *slot;
1072 TableScanDesc scandesc;
1073
1074 scandesc = table_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL);
1075 slot = table_slot_create(cstate->rel, NULL);
1076
1077 processed = 0;
1078 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1079 {
1081
1082 /* Deconstruct the tuple ... */
1083 slot_getallattrs(slot);
1084
1085 /* Format and send the data */
1086 CopyOneRowTo(cstate, slot);
1087
1088 /*
1089 * Increment the number of processed tuples, and report the
1090 * progress.
1091 */
1093 ++processed);
1094 }
1095
1097 table_endscan(scandesc);
1098 }
1099 else
1100 {
1101 /* run the plan --- the dest receiver will send tuples */
1103 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1104 }
1105
1106 cstate->routine->CopyToEnd(cstate);
1107
1109
1110 if (fe_copy)
1111 SendCopyEnd(cstate);
1112
1113 return processed;
1114}
uint64_t uint64
Definition: c.h:503
static void SendCopyBegin(CopyToState cstate)
Definition: copyto.c:391
static void SendCopyEnd(CopyToState cstate)
Definition: copyto.c:408
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition: execMain.c:362
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1441
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
@ ForwardScanDirection
Definition: sdir.h:28
StringInfo makeStringInfo(void)
Definition: stringinfo.c:72
void(* CopyToOutFunc)(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition: copyapi.h:34
void(* CopyToEnd)(CopyToState cstate)
Definition: copyapi.h:54
void(* CopyToStart)(CopyToState cstate, TupleDesc tupDesc)
Definition: copyapi.h:44
DestReceiver * dest
Definition: execdesc.h:42
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:92
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key)
Definition: tableam.h:877
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:989
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:1025

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, attnum, CopyToStateData::attnumlist, CHECK_FOR_INTERRUPTS, CopyOneRowTo(), CopyToRoutine::CopyToEnd, CopyToRoutine::CopyToOutFunc, CopyToRoutine::CopyToStart, cur, CurrentMemoryContext, CopyToStateData::data_dest_cb, QueryDesc::dest, DestRemote, ExecDropSingleTupleTableSlot(), ExecutorRun(), CopyToStateData::fe_msgbuf, CopyToStateData::filename, ForwardScanDirection, GetActiveSnapshot(), lfirst_int, makeStringInfo(), MemoryContextDelete(), TupleDescData::natts, CopyFormatOptions::null_print, CopyFormatOptions::null_print_client, CopyToStateData::opts, CopyToStateData::out_functions, palloc(), pgstat_progress_update_param(), PROGRESS_COPY_TUPLES_PROCESSED, CopyToStateData::queryDesc, CopyToStateData::rel, RelationGetDescr, CopyToStateData::routine, CopyToStateData::rowcontext, SendCopyBegin(), SendCopyEnd(), slot_getallattrs(), table_beginscan(), table_endscan(), table_scan_getnextslot(), table_slot_create(), QueryDesc::tupDesc, TupleDescAttr(), and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ EndCopy()

static void EndCopy ( CopyToState  cstate)
static

Definition at line 587 of file copyto.c.

588{
589 if (cstate->is_program)
590 {
591 ClosePipeToProgram(cstate);
592 }
593 else
594 {
595 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
598 errmsg("could not close file \"%s\": %m",
599 cstate->filename)));
600 }
601
603
605 pfree(cstate);
606}
void pgstat_progress_end_command(void)
int FreeFile(FILE *file)
Definition: fd.c:2803

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().

◆ EndCopyTo()

void EndCopyTo ( CopyToState  cstate)

Definition at line 1003 of file copyto.c.

1004{
1005 if (cstate->queryDesc != NULL)
1006 {
1007 /* Close down the query and free resources. */
1008 ExecutorFinish(cstate->queryDesc);
1009 ExecutorEnd(cstate->queryDesc);
1010 FreeQueryDesc(cstate->queryDesc);
1012 }
1013
1014 /* Clean up storage */
1015 EndCopy(cstate);
1016}
static void EndCopy(CopyToState cstate)
Definition: copyto.c:587
void ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:535
void ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:472
void FreeQueryDesc(QueryDesc *qdesc)
Definition: pquery.c:112
void PopActiveSnapshot(void)
Definition: snapmgr.c:762

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

Referenced by DoCopy(), and test_copy_to_callback().

◆ SendCopyBegin()

static void SendCopyBegin ( CopyToState  cstate)
static

Definition at line 391 of file copyto.c.

392{
394 int natts = list_length(cstate->attnumlist);
395 int16 format = (cstate->opts.binary ? 1 : 0);
396 int i;
397
399 pq_sendbyte(&buf, format); /* overall format */
400 pq_sendint16(&buf, natts);
401 for (i = 0; i < natts; i++)
402 pq_sendint16(&buf, format); /* per-column formats */
404 cstate->copy_dest = COPY_FRONTEND;
405}
int16_t int16
Definition: c.h:497
int i
Definition: isn.c:74
static char format
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:296
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:88
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:160
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:136
#define PqMsg_CopyOutResponse
Definition: protocol.h:46
bool binary
Definition: copy.h:64

References CopyToStateData::attnumlist, CopyFormatOptions::binary, buf, CopyToStateData::copy_dest, COPY_FRONTEND, format, i, list_length(), CopyToStateData::opts, pq_beginmessage(), pq_endmessage(), pq_sendbyte(), pq_sendint16(), and PqMsg_CopyOutResponse.

Referenced by DoCopyTo().

◆ SendCopyEnd()

static void SendCopyEnd ( CopyToState  cstate)
static

Definition at line 408 of file copyto.c.

409{
410 /* Shouldn't have any unsent data */
411 Assert(cstate->fe_msgbuf->len == 0);
412 /* Send Copy Done message */
414}
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:388
#define PqMsg_CopyDone
Definition: protocol.h:64

References Assert(), CopyToStateData::fe_msgbuf, StringInfoData::len, pq_putemptymessage(), and PqMsg_CopyDone.

Referenced by DoCopyTo().

Variable Documentation

◆ BinarySignature

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

Definition at line 109 of file copyto.c.

Referenced by CopyToBinaryStart().

◆ CopyToRoutineBinary

const CopyToRoutine CopyToRoutineBinary
static
Initial value:
= {
.CopyToStart = CopyToBinaryStart,
.CopyToOutFunc = CopyToBinaryOutFunc,
.CopyToOneRow = CopyToBinaryOneRow,
.CopyToEnd = CopyToBinaryEnd,
}
static void CopyToBinaryOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition: copyto.c:333
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:345
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition: copyto.c:314
static void CopyToBinaryEnd(CopyToState cstate)
Definition: copyto.c:378

Definition at line 168 of file copyto.c.

Referenced by CopyToGetRoutine().

◆ CopyToRoutineCSV

const CopyToRoutine CopyToRoutineCSV
static
Initial value:
= {
.CopyToStart = CopyToTextLikeStart,
.CopyToOutFunc = CopyToTextLikeOutFunc,
.CopyToOneRow = CopyToCSVOneRow,
.CopyToEnd = CopyToTextLikeEnd,
}
static void CopyToTextLikeEnd(CopyToState cstate)
Definition: copyto.c:304
static void CopyToTextLikeOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition: copyto.c:233
static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc)
Definition: copyto.c:190
static void CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:252

Definition at line 160 of file copyto.c.

Referenced by CopyToGetRoutine().

◆ CopyToRoutineText

const CopyToRoutine CopyToRoutineText
static
Initial value:
= {
.CopyToStart = CopyToTextLikeStart,
.CopyToOutFunc = CopyToTextLikeOutFunc,
.CopyToOneRow = CopyToTextOneRow,
.CopyToEnd = CopyToTextLikeEnd,
}
static void CopyToTextOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:245

Definition at line 152 of file copyto.c.

Referenced by CopyToGetRoutine().