PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 1141 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)
656 {
657 if (!RelationIsPopulated(rel))
659 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
660 errmsg("cannot copy from unpopulated materialized view \"%s\"",
662 errhint("Use the REFRESH MATERIALIZED VIEW command."));
663 }
664 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
666 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
667 errmsg("cannot copy from foreign table \"%s\"",
669 errhint("Try the COPY (SELECT ...) TO variant.")));
670 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
672 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
673 errmsg("cannot copy from sequence \"%s\"",
675 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
677 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
678 errmsg("cannot copy from partitioned table \"%s\"",
680 errhint("Try the COPY (SELECT ...) TO variant.")));
681 else
683 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
684 errmsg("cannot copy from non-table relation \"%s\"",
686 }
687
688
689 /* Allocate workspace and zero all fields */
690 cstate = (CopyToStateData *) palloc0(sizeof(CopyToStateData));
691
692 /*
693 * We allocate everything used by a cstate in a new memory context. This
694 * avoids memory leaks during repeated use of COPY in a query.
695 */
697 "COPY",
699
700 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
701
702 /* Extract options from the statement node tree */
703 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
704
705 /* Set format routine */
706 cstate->routine = CopyToGetRoutine(&cstate->opts);
707
708 /* Process the source/target relation or query */
709 if (rel)
710 {
711 Assert(!raw_query);
712
713 cstate->rel = rel;
714
715 tupDesc = RelationGetDescr(cstate->rel);
716 }
717 else
718 {
719 List *rewritten;
720 Query *query;
723
724 cstate->rel = NULL;
725
726 /*
727 * Run parse analysis and rewrite. Note this also acquires sufficient
728 * locks on the source table(s).
729 */
730 rewritten = pg_analyze_and_rewrite_fixedparams(raw_query,
731 pstate->p_sourcetext, NULL, 0,
732 NULL);
733
734 /* check that we got back something we can work with */
735 if (rewritten == NIL)
736 {
738 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
739 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
740 }
741 else if (list_length(rewritten) > 1)
742 {
743 ListCell *lc;
744
745 /* examine queries to determine which error message to issue */
746 foreach(lc, rewritten)
747 {
748 Query *q = lfirst_node(Query, lc);
749
750 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
752 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
753 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
754 if (q->querySource == QSRC_NON_INSTEAD_RULE)
756 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
757 errmsg("DO ALSO rules are not supported for COPY")));
758 }
759
761 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
762 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
763 }
764
765 query = linitial_node(Query, rewritten);
766
767 /* The grammar allows SELECT INTO, but we don't support that */
768 if (query->utilityStmt != NULL &&
771 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
772 errmsg("COPY (SELECT INTO) is not supported")));
773
774 /* The only other utility command we could see is NOTIFY */
775 if (query->utilityStmt != NULL)
777 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
778 errmsg("COPY query must not be a utility command")));
779
780 /*
781 * Similarly the grammar doesn't enforce the presence of a RETURNING
782 * clause, but this is required here.
783 */
784 if (query->commandType != CMD_SELECT &&
785 query->returningList == NIL)
786 {
787 Assert(query->commandType == CMD_INSERT ||
788 query->commandType == CMD_UPDATE ||
789 query->commandType == CMD_DELETE ||
790 query->commandType == CMD_MERGE);
791
793 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
794 errmsg("COPY query must have a RETURNING clause")));
795 }
796
797 /* plan the query */
798 plan = pg_plan_query(query, pstate->p_sourcetext,
800
801 /*
802 * With row-level security and a user using "COPY relation TO", we
803 * have to convert the "COPY relation TO" to a query-based COPY (eg:
804 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
805 * add in any RLS clauses.
806 *
807 * When this happens, we are passed in the relid of the originally
808 * found relation (which we have locked). As the planner will look up
809 * the relation again, we double-check here to make sure it found the
810 * same one that we have locked.
811 */
812 if (queryRelId != InvalidOid)
813 {
814 /*
815 * Note that with RLS involved there may be multiple relations,
816 * and while the one we need is almost certainly first, we don't
817 * make any guarantees of that in the planner, so check the whole
818 * list and make sure we find the original relation.
819 */
820 if (!list_member_oid(plan->relationOids, queryRelId))
822 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
823 errmsg("relation referenced by COPY statement has changed")));
824 }
825
826 /*
827 * Use a snapshot with an updated command ID to ensure this query sees
828 * results of any previously executed queries.
829 */
832
833 /* Create dest receiver for COPY OUT */
835 ((DR_copy *) dest)->cstate = cstate;
836
837 /* Create a QueryDesc requesting no output */
838 cstate->queryDesc = CreateQueryDesc(plan, NULL, pstate->p_sourcetext,
841 dest, NULL, NULL, 0);
842
843 /*
844 * Call ExecutorStart to prepare the plan for execution.
845 *
846 * ExecutorStart computes a result tupdesc for us
847 */
848 if (!ExecutorStart(cstate->queryDesc, 0))
849 elog(ERROR, "ExecutorStart() failed unexpectedly");
850
851 tupDesc = cstate->queryDesc->tupDesc;
852 }
853
854 /* Generate or convert list of attributes to process */
855 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
856
857 num_phys_attrs = tupDesc->natts;
858
859 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
860 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
861 if (cstate->opts.force_quote_all)
862 {
863 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
864 }
865 else if (cstate->opts.force_quote)
866 {
867 List *attnums;
868 ListCell *cur;
869
870 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
871
872 foreach(cur, attnums)
873 {
874 int attnum = lfirst_int(cur);
875 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
876
877 if (!list_member_int(cstate->attnumlist, attnum))
879 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
880 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
881 errmsg("%s column \"%s\" not referenced by COPY",
882 "FORCE_QUOTE", NameStr(attr->attname))));
883 cstate->opts.force_quote_flags[attnum - 1] = true;
884 }
885 }
886
887 /* Use client encoding when ENCODING option is not specified. */
888 if (cstate->opts.file_encoding < 0)
890 else
891 cstate->file_encoding = cstate->opts.file_encoding;
892
893 /*
894 * Set up encoding conversion info if the file and server encodings differ
895 * (see also pg_server_to_any).
896 */
897 if (cstate->file_encoding == GetDatabaseEncoding() ||
898 cstate->file_encoding == PG_SQL_ASCII)
899 cstate->need_transcoding = false;
900 else
901 cstate->need_transcoding = true;
902
903 /* See Multibyte encoding comment above */
905
906 cstate->copy_dest = COPY_FILE; /* default */
907
908 if (data_dest_cb)
909 {
910 progress_vals[1] = PROGRESS_COPY_TYPE_CALLBACK;
911 cstate->copy_dest = COPY_CALLBACK;
912 cstate->data_dest_cb = data_dest_cb;
913 }
914 else if (pipe)
915 {
916 progress_vals[1] = PROGRESS_COPY_TYPE_PIPE;
917
918 Assert(!is_program); /* the grammar does not allow this */
920 cstate->copy_file = stdout;
921 }
922 else
923 {
924 cstate->filename = pstrdup(filename);
925 cstate->is_program = is_program;
926
927 if (is_program)
928 {
929 progress_vals[1] = PROGRESS_COPY_TYPE_PROGRAM;
930 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
931 if (cstate->copy_file == NULL)
934 errmsg("could not execute command \"%s\": %m",
935 cstate->filename)));
936 }
937 else
938 {
939 mode_t oumask; /* Pre-existing umask value */
940 struct stat st;
941
942 progress_vals[1] = PROGRESS_COPY_TYPE_FILE;
943
944 /*
945 * Prevent write to relative path ... too easy to shoot oneself in
946 * the foot by overwriting a database file ...
947 */
950 (errcode(ERRCODE_INVALID_NAME),
951 errmsg("relative path not allowed for COPY to file")));
952
953 oumask = umask(S_IWGRP | S_IWOTH);
954 PG_TRY();
955 {
956 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
957 }
958 PG_FINALLY();
959 {
960 umask(oumask);
961 }
962 PG_END_TRY();
963 if (cstate->copy_file == NULL)
964 {
965 /* copy errno because ereport subfunctions might change it */
966 int save_errno = errno;
967
970 errmsg("could not open file \"%s\" for writing: %m",
971 cstate->filename),
972 (save_errno == ENOENT || save_errno == EACCES) ?
973 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
974 "You may want a client-side facility such as psql's \\copy.") : 0));
975 }
976
977 if (fstat(fileno(cstate->copy_file), &st))
980 errmsg("could not stat file \"%s\": %m",
981 cstate->filename)));
982
983 if (S_ISDIR(st.st_mode))
985 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
986 errmsg("\"%s\" is a directory", cstate->filename)));
987 }
988 }
989
990 /* initialize progress */
992 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
993 pgstat_progress_update_multi_param(2, progress_cols, progress_vals);
994
995 cstate->bytes_processed = 0;
996
997 MemoryContextSwitchTo(oldcontext);
998
999 return cstate;
1000}
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:877
int errhint(const char *fmt,...)
Definition: elog.c:1318
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#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:128
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2747
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2644
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:2325
void * palloc0(Size size)
Definition: mcxt.c:1973
MemoryContext CurrentMemoryContext
Definition: mcxt.c:159
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
@ CMD_MERGE
Definition: nodes.h:275
@ CMD_INSERT
Definition: nodes.h:273
@ CMD_DELETE
Definition: nodes.h:274
@ CMD_UPDATE
Definition: nodes.h:272
@ CMD_SELECT
Definition: nodes.h:271
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:3385
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
static char * filename
Definition: pg_dumpall.c:123
#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:35
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:516
#define RelationGetDescr(relation)
Definition: rel.h:542
#define RelationGetRelationName(relation)
Definition: rel.h:550
#define RelationIsPopulated(relation)
Definition: rel.h:688
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:160
#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, RelationIsPopulated, 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:1231
int ClosePipeStream(FILE *file)
Definition: fd.c:3055
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 1427 of file copyto.c.

1428{
1429 pfree(self);
1430}
void pfree(void *pointer)
Definition: mcxt.c:2150

References pfree().

Referenced by CreateCopyDestReceiver().

◆ copy_dest_receive()

static bool copy_dest_receive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 1399 of file copyto.c.

1400{
1401 DR_copy *myState = (DR_copy *) self;
1402 CopyToState cstate = myState->cstate;
1403
1404 /* Send the data */
1405 CopyOneRowTo(cstate, slot);
1406
1407 /* Increment the number of processed tuples, and report the progress */
1409 ++myState->processed);
1410
1411 return true;
1412}
void pgstat_progress_update_param(int index, int64 val)
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:1123
#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 1418 of file copyto.c.

1419{
1420 /* no-op */
1421}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1390 of file copyto.c.

1391{
1392 /* no-op */
1393}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1301 of file copyto.c.

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

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

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 1123 of file copyto.c.

1124{
1125 MemoryContext oldcontext;
1126
1128 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1129
1130 /* Make sure the tuple is fully deconstructed */
1131 slot_getallattrs(slot);
1132
1133 cstate->routine->CopyToOneRow(cstate, slot);
1134
1135 MemoryContextSwitchTo(oldcontext);
1136}
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:414
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:372

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:3113
unsigned int Oid
Definition: postgres_ext.h:30

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:1301
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition: copyto.c:1148
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:3047

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 1436 of file copyto.c.

1437{
1438 DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
1439
1444 self->pub.mydest = DestCopyOut;
1445
1446 self->cstate = NULL; /* will be set later */
1447 self->processed = 0;
1448
1449 return (DestReceiver *) self;
1450}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copyto.c:1399
static void copy_dest_destroy(DestReceiver *self)
Definition: copyto.c:1427
static void copy_dest_shutdown(DestReceiver *self)
Definition: copyto.c:1418
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copyto.c:1390
void * palloc(Size size)
Definition: mcxt.c:1943
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 1027 of file copyto.c.

1028{
1029 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1030 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1031 TupleDesc tupDesc;
1032 int num_phys_attrs;
1033 ListCell *cur;
1034 uint64 processed;
1035
1036 if (fe_copy)
1037 SendCopyBegin(cstate);
1038
1039 if (cstate->rel)
1040 tupDesc = RelationGetDescr(cstate->rel);
1041 else
1042 tupDesc = cstate->queryDesc->tupDesc;
1043 num_phys_attrs = tupDesc->natts;
1044 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1045
1046 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1047 cstate->fe_msgbuf = makeStringInfo();
1048
1049 /* Get info about the columns we need to process. */
1050 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1051 foreach(cur, cstate->attnumlist)
1052 {
1053 int attnum = lfirst_int(cur);
1054 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1055
1056 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1057 &cstate->out_functions[attnum - 1]);
1058 }
1059
1060 /*
1061 * Create a temporary memory context that we can reset once per row to
1062 * recover palloc'd memory. This avoids any problems with leaks inside
1063 * datatype output routines, and should be faster than retail pfree's
1064 * anyway. (We don't need a whole econtext as CopyFrom does.)
1065 */
1067 "COPY TO",
1069
1070 cstate->routine->CopyToStart(cstate, tupDesc);
1071
1072 if (cstate->rel)
1073 {
1074 TupleTableSlot *slot;
1075 TableScanDesc scandesc;
1076
1077 scandesc = table_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL);
1078 slot = table_slot_create(cstate->rel, NULL);
1079
1080 processed = 0;
1081 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1082 {
1084
1085 /* Deconstruct the tuple ... */
1086 slot_getallattrs(slot);
1087
1088 /* Format and send the data */
1089 CopyOneRowTo(cstate, slot);
1090
1091 /*
1092 * Increment the number of processed tuples, and report the
1093 * progress.
1094 */
1096 ++processed);
1097 }
1098
1100 table_endscan(scandesc);
1101 }
1102 else
1103 {
1104 /* run the plan --- the dest receiver will send tuples */
1106 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1107 }
1108
1109 cstate->routine->CopyToEnd(cstate);
1110
1112
1113 if (fe_copy)
1114 SendCopyEnd(cstate);
1115
1116 return processed;
1117}
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:365
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1443
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:485
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
@ 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:870
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:979
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:1015

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:2843

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 1006 of file copyto.c.

1007{
1008 if (cstate->queryDesc != NULL)
1009 {
1010 /* Close down the query and free resources. */
1011 ExecutorFinish(cstate->queryDesc);
1012 ExecutorEnd(cstate->queryDesc);
1013 FreeQueryDesc(cstate->queryDesc);
1015 }
1016
1017 /* Clean up storage */
1018 EndCopy(cstate);
1019}
static void EndCopy(CopyToState cstate)
Definition: copyto.c:587
void ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:538
void ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:475
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:77
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().