PostgreSQL Source Code git master
Loading...
Searching...
No Matches
copyto.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include "access/table.h"
#include "access/tableam.h"
#include "access/tupconvert.h"
#include "catalog/pg_inherits.h"
#include "commands/copyapi.h"
#include "commands/progress.h"
#include "executor/execdesc.h"
#include "executor/executor.h"
#include "executor/tuptable.h"
#include "funcapi.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/json.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/snapmgr.h"
#include "utils/wait_event.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 CopyRelationTo (CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
 
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 CopyToJsonOneRow (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyToJsonEnd (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 CopyToRoutineJson
 
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
static int fb(int x)

Definition at line 1414 of file copyto.c.

1415 { \
1416 if (ptr > start) \
1417 CopySendData(cstate, start, ptr - start); \
1418 } while (0)

Typedef Documentation

◆ CopyDest

◆ CopyToStateData

Enumeration Type Documentation

◆ CopyDest

Enumerator
COPY_FILE 
COPY_FRONTEND 
COPY_CALLBACK 

Definition at line 49 of file copyto.c.

50{
51 COPY_FILE, /* to file (or a piped program) */
52 COPY_FRONTEND, /* to frontend */
53 COPY_CALLBACK, /* to callback function */
54} CopyDest;
CopyDest
Definition copyto.c:50
@ COPY_FILE
Definition copyto.c:51
@ COPY_CALLBACK
Definition copyto.c:53
@ COPY_FRONTEND
Definition copyto.c:52

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

778{
779 CopyToState cstate;
780 bool pipe = (filename == NULL && data_dest_cb == NULL);
781 TupleDesc tupDesc;
782 int num_phys_attrs;
783 MemoryContext oldcontext;
784 const int progress_cols[] = {
787 };
788 int64 progress_vals[] = {
790 0
791 };
792 List *children = NIL;
793
794 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
795 {
796 if (rel->rd_rel->relkind == RELKIND_VIEW)
799 errmsg("cannot copy from view \"%s\"",
801 errhint("Try the COPY (SELECT ...) TO variant.")));
802 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
803 {
804 if (!RelationIsPopulated(rel))
807 errmsg("cannot copy from unpopulated materialized view \"%s\"",
809 errhint("Use the REFRESH MATERIALIZED VIEW command."));
810 }
811 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
814 errmsg("cannot copy from foreign table \"%s\"",
816 errhint("Try the COPY (SELECT ...) TO variant.")));
817 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
820 errmsg("cannot copy from sequence \"%s\"",
822 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
823 {
824 /*
825 * Collect OIDs of relation containing data, so that later
826 * DoCopyTo can copy the data from them.
827 */
829
830 foreach_oid(child, children)
831 {
832 char relkind = get_rel_relkind(child);
833
834 if (relkind == RELKIND_FOREIGN_TABLE)
835 {
836 char *relation_name = get_rel_name(child);
837
840 errmsg("cannot copy from foreign table \"%s\"", relation_name),
841 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
842 relation_name, RelationGetRelationName(rel)),
843 errhint("Try the COPY (SELECT ...) TO variant."));
844 }
845
846 /* Exclude tables with no data */
847 if (RELKIND_HAS_PARTITIONS(relkind))
848 children = foreach_delete_current(children, child);
849 }
850 }
851 else
854 errmsg("cannot copy from non-table relation \"%s\"",
856 }
857
858
859 /* Allocate workspace and zero all fields */
861
862 /*
863 * We allocate everything used by a cstate in a new memory context. This
864 * avoids memory leaks during repeated use of COPY in a query.
865 */
867 "COPY",
869
870 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
871
872 /* Extract options from the statement node tree */
873 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
874
875 /* Set format routine */
876 cstate->routine = CopyToGetRoutine(&cstate->opts);
877
878 /* Process the source/target relation or query */
879 if (rel)
880 {
882
883 cstate->rel = rel;
884
885 tupDesc = RelationGetDescr(cstate->rel);
886 cstate->partitions = children;
887 cstate->tupDesc = tupDesc;
888 }
889 else
890 {
892 Query *query;
895
896 cstate->rel = NULL;
897 cstate->partitions = NIL;
898
899 /*
900 * Run parse analysis and rewrite. Note this also acquires sufficient
901 * locks on the source table(s).
902 */
904 pstate->p_sourcetext, NULL, 0,
905 NULL);
906
907 /* check that we got back something we can work with */
908 if (rewritten == NIL)
909 {
912 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
913 }
914 else if (list_length(rewritten) > 1)
915 {
916 ListCell *lc;
917
918 /* examine queries to determine which error message to issue */
919 foreach(lc, rewritten)
920 {
921 Query *q = lfirst_node(Query, lc);
922
923 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
926 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
927 if (q->querySource == QSRC_NON_INSTEAD_RULE)
930 errmsg("DO ALSO rules are not supported for COPY")));
931 }
932
935 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
936 }
937
938 query = linitial_node(Query, rewritten);
939
940 /* The grammar allows SELECT INTO, but we don't support that */
941 if (query->utilityStmt != NULL &&
945 errmsg("COPY (SELECT INTO) is not supported")));
946
947 /* The only other utility command we could see is NOTIFY */
948 if (query->utilityStmt != NULL)
951 errmsg("COPY query must not be a utility command")));
952
953 /*
954 * Similarly the grammar doesn't enforce the presence of a RETURNING
955 * clause, but this is required here.
956 */
957 if (query->commandType != CMD_SELECT &&
958 query->returningList == NIL)
959 {
960 Assert(query->commandType == CMD_INSERT ||
961 query->commandType == CMD_UPDATE ||
962 query->commandType == CMD_DELETE ||
963 query->commandType == CMD_MERGE);
964
967 errmsg("COPY query must have a RETURNING clause")));
968 }
969
970 /* plan the query */
971 plan = pg_plan_query(query, pstate->p_sourcetext,
973
974 /*
975 * With row-level security and a user using "COPY relation TO", we
976 * have to convert the "COPY relation TO" to a query-based COPY (eg:
977 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
978 * add in any RLS clauses.
979 *
980 * When this happens, we are passed in the relid of the originally
981 * found relation (which we have locked). As the planner will look up
982 * the relation again, we double-check here to make sure it found the
983 * same one that we have locked.
984 */
985 if (queryRelId != InvalidOid)
986 {
987 /*
988 * Note that with RLS involved there may be multiple relations,
989 * and while the one we need is almost certainly first, we don't
990 * make any guarantees of that in the planner, so check the whole
991 * list and make sure we find the original relation.
992 */
993 if (!list_member_oid(plan->relationOids, queryRelId))
996 errmsg("relation referenced by COPY statement has changed")));
997 }
998
999 /*
1000 * Use a snapshot with an updated command ID to ensure this query sees
1001 * results of any previously executed queries.
1002 */
1005
1006 /* Create dest receiver for COPY OUT */
1008 ((DR_copy *) dest)->cstate = cstate;
1009
1010 /* Create a QueryDesc requesting no output */
1011 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
1014 dest, NULL, NULL, 0);
1015
1016 /*
1017 * Call ExecutorStart to prepare the plan for execution.
1018 *
1019 * ExecutorStart computes a result tupdesc for us
1020 */
1021 ExecutorStart(cstate->queryDesc, 0);
1022
1023 tupDesc = cstate->queryDesc->tupDesc;
1024 tupDesc = BlessTupleDesc(tupDesc);
1025 cstate->tupDesc = tupDesc;
1026 }
1027
1028 /* Generate or convert list of attributes to process */
1029 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1030
1031 /* Set up JSON-specific state */
1032 if (cstate->opts.format == COPY_FORMAT_JSON)
1033 {
1034 cstate->json_buf = makeStringInfo();
1035
1036 if (attnamelist != NIL && rel)
1037 {
1038 int natts = list_length(cstate->attnumlist);
1039 TupleDesc resultDesc;
1040
1041 /*
1042 * Build a TupleDesc describing only the selected columns so that
1043 * composite_to_json() emits the right column names and types.
1044 */
1045 resultDesc = CreateTemplateTupleDesc(natts);
1046
1047 foreach_int(attnum, cstate->attnumlist)
1048 {
1049 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1050
1051 TupleDescInitEntry(resultDesc,
1053 NameStr(attr->attname),
1054 attr->atttypid,
1055 attr->atttypmod,
1056 attr->attndims);
1057 }
1058
1059 TupleDescFinalize(resultDesc);
1060 cstate->tupDesc = BlessTupleDesc(resultDesc);
1061
1062 /*
1063 * Pre-allocate arrays for projecting selected column values into
1064 * sequential positions matching the custom TupleDesc.
1065 */
1066 cstate->json_projvalues = palloc_array(Datum, natts);
1067 cstate->json_projnulls = palloc_array(bool, natts);
1068 }
1069 }
1070
1071 num_phys_attrs = tupDesc->natts;
1072
1073 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
1074 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1075 if (cstate->opts.force_quote_all)
1076 {
1077 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
1078 }
1079 else if (cstate->opts.force_quote)
1080 {
1081 List *attnums;
1082 ListCell *cur;
1083
1084 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
1085
1086 foreach(cur, attnums)
1087 {
1088 int attnum = lfirst_int(cur);
1089 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1090
1091 if (!list_member_int(cstate->attnumlist, attnum))
1092 ereport(ERROR,
1094 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1095 errmsg("%s column \"%s\" not referenced by COPY",
1096 "FORCE_QUOTE", NameStr(attr->attname))));
1097 cstate->opts.force_quote_flags[attnum - 1] = true;
1098 }
1099 }
1100
1101 /* Use client encoding when ENCODING option is not specified. */
1102 if (cstate->opts.file_encoding < 0)
1104 else
1105 cstate->file_encoding = cstate->opts.file_encoding;
1106
1107 /*
1108 * Set up encoding conversion info if the file and server encodings differ
1109 * (see also pg_server_to_any).
1110 */
1111 if (cstate->file_encoding == GetDatabaseEncoding() ||
1112 cstate->file_encoding == PG_SQL_ASCII)
1113 cstate->need_transcoding = false;
1114 else
1115 cstate->need_transcoding = true;
1116
1117 /* See Multibyte encoding comment above */
1119
1120 cstate->copy_dest = COPY_FILE; /* default */
1121
1122 if (data_dest_cb)
1123 {
1125 cstate->copy_dest = COPY_CALLBACK;
1126 cstate->data_dest_cb = data_dest_cb;
1127 }
1128 else if (pipe)
1129 {
1131
1132 Assert(!is_program); /* the grammar does not allow this */
1134 cstate->copy_file = stdout;
1135 }
1136 else
1137 {
1138 cstate->filename = pstrdup(filename);
1139 cstate->is_program = is_program;
1140
1141 if (is_program)
1142 {
1144 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
1145 if (cstate->copy_file == NULL)
1146 ereport(ERROR,
1148 errmsg("could not execute command \"%s\": %m",
1149 cstate->filename)));
1150 }
1151 else
1152 {
1153 mode_t oumask; /* Pre-existing umask value */
1154 struct stat st;
1155
1157
1158 /*
1159 * Prevent write to relative path ... too easy to shoot oneself in
1160 * the foot by overwriting a database file ...
1161 */
1163 ereport(ERROR,
1165 errmsg("relative path not allowed for COPY to file")));
1166
1168 PG_TRY();
1169 {
1170 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
1171 }
1172 PG_FINALLY();
1173 {
1174 umask(oumask);
1175 }
1176 PG_END_TRY();
1177 if (cstate->copy_file == NULL)
1178 {
1179 /* copy errno because ereport subfunctions might change it */
1180 int save_errno = errno;
1181
1182 ereport(ERROR,
1184 errmsg("could not open file \"%s\" for writing: %m",
1185 cstate->filename),
1186 (save_errno == ENOENT || save_errno == EACCES) ?
1187 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1188 "You may want a client-side facility such as psql's \\copy.") : 0));
1189 }
1190
1191 if (fstat(fileno(cstate->copy_file), &st))
1192 ereport(ERROR,
1194 errmsg("could not stat file \"%s\": %m",
1195 cstate->filename)));
1196
1197 if (S_ISDIR(st.st_mode))
1198 ereport(ERROR,
1200 errmsg("\"%s\" is a directory", cstate->filename)));
1201 }
1202 }
1203
1204 /* initialize progress */
1206 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1208
1209 cstate->bytes_processed = 0;
1210
1211 MemoryContextSwitchTo(oldcontext);
1212
1213 return cstate;
1214}
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition copy.c:1068
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition copy.c:581
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:835
#define Assert(condition)
Definition c.h:943
int64_t int64
Definition c.h:621
#define PG_BINARY_W
Definition c.h:1377
#define MemSet(start, val, len)
Definition c.h:1107
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition copyto.c:201
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:897
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define PG_TRY(...)
Definition elog.h:374
#define PG_END_TRY(...)
Definition elog.h:399
#define ERROR
Definition elog.h:40
#define PG_FINALLY(...)
Definition elog.h:391
#define ereport(elevel,...)
Definition elog.h:152
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition execMain.c:124
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
FILE * OpenPipeStream(const char *command, const char *mode)
Definition fd.c:2731
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define palloc0_object(type)
Definition fe_memutils.h:75
@ COPY_FORMAT_JSON
Definition copy.h:60
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
#define AccessShareLock
Definition lockdefs.h:36
char * get_rel_name(Oid relid)
Definition lsyscache.c:2148
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2223
int GetDatabaseEncoding(void)
Definition mbutils.c:1388
int pg_get_client_encoding(void)
Definition mbutils.c:345
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * palloc0(Size size)
Definition mcxt.c:1417
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define IsA(nodeptr, _type_)
Definition nodes.h:164
@ CMD_MERGE
Definition nodes.h:279
@ CMD_INSERT
Definition nodes.h:277
@ CMD_DELETE
Definition nodes.h:278
@ CMD_UPDATE
Definition nodes.h:276
@ CMD_SELECT
Definition nodes.h:275
static char * errmsg
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
int16 attnum
FormData_pg_attribute * Form_pg_attribute
static char * filename
Definition pg_dumpall.c:133
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#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 foreach_current_index(var_or_cell)
Definition pg_list.h:435
#define lfirst_int(lc)
Definition pg_list.h:173
#define foreach_delete_current(lst, var_or_cell)
Definition pg_list.h:423
#define foreach_oid(var, lst)
Definition pg_list.h:503
#define foreach_int(var, lst)
Definition pg_list.h:502
#define plan(x)
Definition pg_regress.c:164
@ PG_SQL_ASCII
Definition pg_wchar.h:76
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition pg_wchar.h:137
#define is_absolute_path(filename)
Definition port.h:104
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition postgres.c:898
CommandDest whereToSendOutput
Definition postgres.c:97
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition postgres.c:681
uint64_t Datum
Definition postgres.h:70
#define InvalidOid
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
Definition pquery.c:68
#define PROGRESS_COPY_COMMAND
Definition progress.h:177
#define PROGRESS_COPY_TYPE_FILE
Definition progress.h:186
#define PROGRESS_COPY_COMMAND_TO
Definition progress.h:183
#define PROGRESS_COPY_TYPE
Definition progress.h:178
#define PROGRESS_COPY_TYPE_PROGRAM
Definition progress.h:187
#define PROGRESS_COPY_TYPE_CALLBACK
Definition progress.h:189
#define PROGRESS_COPY_TYPE_PIPE
Definition progress.h:188
#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:744
void PushCopiedSnapshot(Snapshot snapshot)
Definition snapmgr.c:732
Snapshot GetActiveSnapshot(void)
Definition snapmgr.c:800
#define InvalidSnapshot
Definition snapshot.h:119
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
CopyFormat format
Definition copy.h:73
bool force_quote_all
Definition copy.h:86
List * force_quote
Definition copy.h:85
bool * force_quote_flags
Definition copy.h:87
int file_encoding
Definition copy.h:71
MemoryContext copycontext
Definition copyto.c:108
Relation rel
Definition copyto.c:86
Datum * json_projvalues
Definition copyto.c:96
const CopyToRoutine * routine
Definition copyto.c:74
copy_data_dest_cb data_dest_cb
Definition copyto.c:99
bool encoding_embeds_ascii
Definition copyto.c:83
CopyDest copy_dest
Definition copyto.c:77
bool need_transcoding
Definition copyto.c:82
bool is_program
Definition copyto.c:90
FILE * copy_file
Definition copyto.c:78
bool * json_projnulls
Definition copyto.c:98
int file_encoding
Definition copyto.c:81
CopyFormatOptions opts
Definition copyto.c:101
uint64 bytes_processed
Definition copyto.c:112
char * filename
Definition copyto.c:89
List * attnumlist
Definition copyto.c:88
QueryDesc * queryDesc
Definition copyto.c:87
TupleDesc tupDesc
Definition copyto.c:94
List * partitions
Definition copyto.c:103
StringInfo json_buf
Definition copyto.c:92
Definition pg_list.h:54
const char * p_sourcetext
Definition parse_node.h:214
TupleDesc tupDesc
Definition execdesc.h:49
List * returningList
Definition parsenodes.h:217
CmdType commandType
Definition parsenodes.h:121
Node * utilityStmt
Definition parsenodes.h:141
Form_pg_class rd_rel
Definition rel.h:111
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:511
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:900
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
#define S_IWOTH
Definition win32_port.h:306
#define S_ISDIR(m)
Definition win32_port.h:315
#define fstat
Definition win32_port.h:73
#define S_IWGRP
Definition win32_port.h:294

References AccessShareLock, AllocateFile(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, attnum, CopyToStateData::attnumlist, BlessTupleDesc(), 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, COPY_FORMAT_JSON, CopyToStateData::copycontext, CopyGetAttnums(), CopyToGetRoutine(), CreateDestReceiver(), CreateQueryDesc(), CreateTemplateTupleDesc(), cur, CurrentMemoryContext, CURSOR_OPT_PARALLEL_OK, CopyToStateData::data_dest_cb, DestCopyOut, DestRemote, CopyToStateData::encoding_embeds_ascii, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg, ERROR, ExecutorStart(), fb(), CopyToStateData::file_encoding, CopyFormatOptions::file_encoding, CopyToStateData::filename, filename, find_all_inheritors(), CopyFormatOptions::force_quote, CopyFormatOptions::force_quote_all, CopyFormatOptions::force_quote_flags, foreach_current_index, foreach_delete_current, foreach_int, foreach_oid, CopyFormatOptions::format, fstat, get_rel_name(), get_rel_relkind(), GetActiveSnapshot(), GetDatabaseEncoding(), InvalidOid, InvalidSnapshot, is_absolute_path, CopyToStateData::is_program, IsA, CopyToStateData::json_buf, CopyToStateData::json_projnulls, CopyToStateData::json_projvalues, lfirst_int, lfirst_node, linitial_node, list_length(), list_member_int(), list_member_oid(), makeStringInfo(), MemoryContextSwitchTo(), MemSet, NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, NIL, OpenPipeStream(), CopyToStateData::opts, ParseState::p_sourcetext, palloc0(), palloc0_object, palloc_array, CopyToStateData::partitions, 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, CopyToStateData::tupDesc, QueryDesc::tupDesc, TupleDescAttr(), TupleDescFinalize(), TupleDescInitEntry(), UpdateActiveSnapshotCommandId(), Query::utilityStmt, and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ ClosePipeToProgram()

static void ClosePipeToProgram ( CopyToState  cstate)
static

Definition at line 704 of file copyto.c.

705{
706 int pclose_rc;
707
708 Assert(cstate->is_program);
709
711 if (pclose_rc == -1)
714 errmsg("could not close pipe to external command: %m")));
715 else if (pclose_rc != 0)
716 {
719 errmsg("program \"%s\" failed",
720 cstate->filename),
722 }
723}
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int ClosePipeStream(FILE *file)
Definition fd.c:3039
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, fb(), 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 1700 of file copyto.c.

1701{
1702 pfree(self);
1703}
void pfree(void *pointer)
Definition mcxt.c:1616

References pfree().

Referenced by CreateCopyDestReceiver().

◆ copy_dest_receive()

static bool copy_dest_receive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 1672 of file copyto.c.

1673{
1674 DR_copy *myState = (DR_copy *) self;
1675 CopyToState cstate = myState->cstate;
1676
1677 /* Send the data */
1678 CopyOneRowTo(cstate, slot);
1679
1680 /* Increment the number of processed tuples, and report the progress */
1682 ++myState->processed);
1683
1684 return true;
1685}
void pgstat_progress_update_param(int index, int64 val)
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:1396
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition progress.h:175

References CopyOneRowTo(), fb(), pgstat_progress_update_param(), and PROGRESS_COPY_TUPLES_PROCESSED.

Referenced by CreateCopyDestReceiver().

◆ copy_dest_shutdown()

static void copy_dest_shutdown ( DestReceiver self)
static

Definition at line 1691 of file copyto.c.

1692{
1693 /* no-op */
1694}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1663 of file copyto.c.

1664{
1665 /* no-op */
1666}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1574 of file copyto.c.

1576{
1577 const char *ptr;
1578 const char *start;
1579 char c;
1580 char delimc = cstate->opts.delim[0];
1581 char quotec = cstate->opts.quote[0];
1582 char escapec = cstate->opts.escape[0];
1583 bool single_attr = (list_length(cstate->attnumlist) == 1);
1584
1585 /* force quoting if it matches null_print (before conversion!) */
1586 if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1587 use_quote = true;
1588
1589 if (cstate->need_transcoding)
1590 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1591 else
1592 ptr = string;
1593
1594 /*
1595 * Make a preliminary pass to discover if it needs quoting
1596 */
1597 if (!use_quote)
1598 {
1599 /*
1600 * Quote '\.' if it appears alone on a line, so that it will not be
1601 * interpreted as an end-of-data marker. (PG 18 and up will not
1602 * interpret '\.' in CSV that way, except in embedded-in-SQL data; but
1603 * we want the data to be loadable by older versions too. Also, this
1604 * avoids breaking clients that are still using PQgetline().)
1605 */
1606 if (single_attr && strcmp(ptr, "\\.") == 0)
1607 use_quote = true;
1608 else
1609 {
1610 const char *tptr = ptr;
1611
1612 while ((c = *tptr) != '\0')
1613 {
1614 if (c == delimc || c == quotec || c == '\n' || c == '\r')
1615 {
1616 use_quote = true;
1617 break;
1618 }
1619 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1621 else
1622 tptr++;
1623 }
1624 }
1625 }
1626
1627 if (use_quote)
1628 {
1629 CopySendChar(cstate, quotec);
1630
1631 /*
1632 * We adopt the same optimization strategy as in CopyAttributeOutText
1633 */
1634 start = ptr;
1635 while ((c = *ptr) != '\0')
1636 {
1637 if (c == quotec || c == escapec)
1638 {
1639 DUMPSOFAR();
1640 CopySendChar(cstate, escapec);
1641 start = ptr; /* we include char in next run */
1642 }
1643 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1644 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1645 else
1646 ptr++;
1647 }
1648 DUMPSOFAR();
1649
1650 CopySendChar(cstate, quotec);
1651 }
1652 else
1653 {
1654 /* If it doesn't need quoting, we can just dump it as-is */
1655 CopySendString(cstate, ptr);
1656 }
1657}
#define IS_HIGHBIT_SET(ch)
Definition c.h:1244
#define DUMPSOFAR()
Definition copyto.c:1414
static void CopySendChar(CopyToState cstate, char c)
Definition copyto.c:579
static void CopySendString(CopyToState cstate, const char *str)
Definition copyto.c:573
char * pg_server_to_any(const char *s, int len, int encoding)
Definition mbutils.c:760
char * c
char string[11]
char * quote
Definition copy.h:83
char * escape
Definition copy.h:84
char * null_print
Definition copy.h:77
char * delim
Definition copy.h:82
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition wchar.c:1934

References CopyToStateData::attnumlist, CopySendChar(), CopySendString(), CopyFormatOptions::delim, DUMPSOFAR, CopyToStateData::encoding_embeds_ascii, CopyFormatOptions::escape, fb(), 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 1421 of file copyto.c.

1422{
1423 const char *ptr;
1424 const char *start;
1425 char c;
1426 char delimc = cstate->opts.delim[0];
1427
1428 if (cstate->need_transcoding)
1429 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1430 else
1431 ptr = string;
1432
1433 /*
1434 * We have to grovel through the string searching for control characters
1435 * and instances of the delimiter character. In most cases, though, these
1436 * are infrequent. To avoid overhead from calling CopySendData once per
1437 * character, we dump out all characters between escaped characters in a
1438 * single call. The loop invariant is that the data from "start" to "ptr"
1439 * can be sent literally, but hasn't yet been.
1440 *
1441 * We can skip pg_encoding_mblen() overhead when encoding is safe, because
1442 * in valid backend encodings, extra bytes of a multibyte character never
1443 * look like ASCII. This loop is sufficiently performance-critical that
1444 * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
1445 * of the normal safe-encoding path.
1446 */
1447 if (cstate->encoding_embeds_ascii)
1448 {
1449 start = ptr;
1450 while ((c = *ptr) != '\0')
1451 {
1452 if ((unsigned char) c < (unsigned char) 0x20)
1453 {
1454 /*
1455 * \r and \n must be escaped, the others are traditional. We
1456 * prefer to dump these using the C-like notation, rather than
1457 * a backslash and the literal character, because it makes the
1458 * dump file a bit more proof against Microsoftish data
1459 * mangling.
1460 */
1461 switch (c)
1462 {
1463 case '\b':
1464 c = 'b';
1465 break;
1466 case '\f':
1467 c = 'f';
1468 break;
1469 case '\n':
1470 c = 'n';
1471 break;
1472 case '\r':
1473 c = 'r';
1474 break;
1475 case '\t':
1476 c = 't';
1477 break;
1478 case '\v':
1479 c = 'v';
1480 break;
1481 default:
1482 /* If it's the delimiter, must backslash it */
1483 if (c == delimc)
1484 break;
1485 /* All ASCII control chars are length 1 */
1486 ptr++;
1487 continue; /* fall to end of loop */
1488 }
1489 /* if we get here, we need to convert the control char */
1490 DUMPSOFAR();
1491 CopySendChar(cstate, '\\');
1492 CopySendChar(cstate, c);
1493 start = ++ptr; /* do not include char in next run */
1494 }
1495 else if (c == '\\' || c == delimc)
1496 {
1497 DUMPSOFAR();
1498 CopySendChar(cstate, '\\');
1499 start = ptr++; /* we include char in next run */
1500 }
1501 else if (IS_HIGHBIT_SET(c))
1502 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1503 else
1504 ptr++;
1505 }
1506 }
1507 else
1508 {
1509 start = ptr;
1510 while ((c = *ptr) != '\0')
1511 {
1512 if ((unsigned char) c < (unsigned char) 0x20)
1513 {
1514 /*
1515 * \r and \n must be escaped, the others are traditional. We
1516 * prefer to dump these using the C-like notation, rather than
1517 * a backslash and the literal character, because it makes the
1518 * dump file a bit more proof against Microsoftish data
1519 * mangling.
1520 */
1521 switch (c)
1522 {
1523 case '\b':
1524 c = 'b';
1525 break;
1526 case '\f':
1527 c = 'f';
1528 break;
1529 case '\n':
1530 c = 'n';
1531 break;
1532 case '\r':
1533 c = 'r';
1534 break;
1535 case '\t':
1536 c = 't';
1537 break;
1538 case '\v':
1539 c = 'v';
1540 break;
1541 default:
1542 /* If it's the delimiter, must backslash it */
1543 if (c == delimc)
1544 break;
1545 /* All ASCII control chars are length 1 */
1546 ptr++;
1547 continue; /* fall to end of loop */
1548 }
1549 /* if we get here, we need to convert the control char */
1550 DUMPSOFAR();
1551 CopySendChar(cstate, '\\');
1552 CopySendChar(cstate, c);
1553 start = ++ptr; /* do not include char in next run */
1554 }
1555 else if (c == '\\' || c == delimc)
1556 {
1557 DUMPSOFAR();
1558 CopySendChar(cstate, '\\');
1559 start = ptr++; /* we include char in next run */
1560 }
1561 else
1562 ptr++;
1563 }
1564 }
1565
1566 DUMPSOFAR();
1567}

References CopySendChar(), CopyFormatOptions::delim, DUMPSOFAR, CopyToStateData::encoding_embeds_ascii, fb(), 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 1396 of file copyto.c.

1397{
1398 MemoryContext oldcontext;
1399
1401 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1402
1403 /* Make sure the tuple is fully deconstructed */
1404 slot_getallattrs(slot);
1405
1406 cstate->routine->CopyToOneRow(cstate, slot);
1407
1408 MemoryContextSwitchTo(oldcontext);
1409}
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
void(* CopyToOneRow)(CopyToState cstate, TupleTableSlot *slot)
Definition copyapi.h:49
MemoryContext rowcontext
Definition copyto.c:111
static void slot_getallattrs(TupleTableSlot *slot)
Definition tuptable.h:390

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

Referenced by copy_dest_receive(), and CopyRelationTo().

◆ CopyRelationTo()

static void CopyRelationTo ( CopyToState  cstate,
Relation  rel,
Relation  root_rel,
uint64 processed 
)
static

Definition at line 1332 of file copyto.c.

1333{
1334 TupleTableSlot *slot;
1335 TableScanDesc scandesc;
1336 AttrMap *map = NULL;
1338
1339 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL,
1340 SO_NONE);
1341 slot = table_slot_create(rel, NULL);
1342
1343 /*
1344 * If we are exporting partition data here, we check if converting tuples
1345 * to the root table's rowtype, because a partition might have column
1346 * order different than its root table.
1347 */
1348 if (root_rel != NULL)
1349 {
1352 RelationGetDescr(rel),
1353 false);
1354 }
1355
1356 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1357 {
1358 TupleTableSlot *copyslot;
1359
1361
1362 if (map != NULL)
1363 copyslot = execute_attr_map_slot(map, slot, root_slot);
1364 else
1365 {
1366 /* Deconstruct the tuple */
1367 slot_getallattrs(slot);
1368 copyslot = slot;
1369 }
1370
1371 /* Format and send the data */
1372 CopyOneRowTo(cstate, copyslot);
1373
1374 /*
1375 * Increment the number of processed tuples, and report the progress.
1376 */
1378 ++(*processed));
1379 }
1380
1382
1383 if (root_slot != NULL)
1385
1386 if (map != NULL)
1387 free_attrmap(map);
1388
1389 table_endscan(scandesc);
1390}
void free_attrmap(AttrMap *map)
Definition attmap.c:56
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
Definition attmap.c:261
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
@ ForwardScanDirection
Definition sdir.h:28
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92
@ SO_NONE
Definition tableam.h:49
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1061
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, uint32 flags)
Definition tableam.h:943
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:1096
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition tupconvert.c:193

References build_attrmap_by_name_if_req(), CHECK_FOR_INTERRUPTS, CopyOneRowTo(), ExecDropSingleTupleTableSlot(), execute_attr_map_slot(), fb(), ForwardScanDirection, free_attrmap(), GetActiveSnapshot(), pgstat_progress_update_param(), PROGRESS_COPY_TUPLES_PROCESSED, RelationGetDescr, slot_getallattrs(), SO_NONE, table_beginscan(), table_endscan(), table_scan_getnextslot(), and table_slot_create().

Referenced by DoCopyTo().

◆ CopySendChar()

static void CopySendChar ( CopyToState  cstate,
char  c 
)
static

◆ CopySendData()

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

Definition at line 567 of file copyto.c.

568{
570}
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition stringinfo.c:281

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

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

◆ CopySendEndOfRow()

static void CopySendEndOfRow ( CopyToState  cstate)
static

Definition at line 585 of file copyto.c.

586{
587 StringInfo fe_msgbuf = cstate->fe_msgbuf;
588
589 switch (cstate->copy_dest)
590 {
591 case COPY_FILE:
593 if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
594 cstate->copy_file) != 1 ||
595 ferror(cstate->copy_file))
596 {
597 if (cstate->is_program)
598 {
599 if (errno == EPIPE)
600 {
601 /*
602 * The pipe will be closed automatically on error at
603 * the end of transaction, but we might get a better
604 * error message from the subprocess' exit code than
605 * just "Broken Pipe"
606 */
607 ClosePipeToProgram(cstate);
608
609 /*
610 * If ClosePipeToProgram() didn't throw an error, the
611 * program terminated normally, but closed the pipe
612 * first. Restore errno, and throw an error.
613 */
614 errno = EPIPE;
615 }
618 errmsg("could not write to COPY program: %m")));
619 }
620 else
623 errmsg("could not write to COPY file: %m")));
624 }
626 break;
627 case COPY_FRONTEND:
628 /* Dump the accumulated row as one CopyData message */
629 (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
630 break;
631 case COPY_CALLBACK:
632 cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
633 break;
634 }
635
636 /* Update the progress */
637 cstate->bytes_processed += fe_msgbuf->len;
639
640 resetStringInfo(fe_msgbuf);
641}
static void ClosePipeToProgram(CopyToState cstate)
Definition copyto.c:704
#define pq_putmessage(msgtype, s, len)
Definition libpq.h:52
#define PROGRESS_COPY_BYTES_PROCESSED
Definition progress.h:173
#define PqMsg_CopyData
Definition protocol.h:65
void resetStringInfo(StringInfo str)
Definition stringinfo.c:126
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:67
static void pgstat_report_wait_end(void)
Definition wait_event.h:83

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, fb(), CopyToStateData::fe_msgbuf, CopyToStateData::is_program, StringInfoData::len, pgstat_progress_update_param(), pgstat_report_wait_end(), pgstat_report_wait_start(), 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 692 of file copyto.c.

693{
694 uint16 buf;
695
696 buf = pg_hton16((uint16) val);
697 CopySendData(cstate, &buf, sizeof(buf));
698}
uint16_t uint16
Definition c.h:623
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition copyto.c:567
long val
Definition informix.c:689
#define pg_hton16(x)
Definition pg_bswap.h:120
static char buf[DEFAULT_XLOG_SEG_SIZE]

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

Referenced by CopyToBinaryEnd(), and CopyToBinaryOneRow().

◆ CopySendInt32()

static void CopySendInt32 ( CopyToState  cstate,
int32  val 
)
inlinestatic

Definition at line 680 of file copyto.c.

681{
682 uint32 buf;
683
684 buf = pg_hton32((uint32) val);
685 CopySendData(cstate, &buf, sizeof(buf));
686}
uint32_t uint32
Definition c.h:624
#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 573 of file copyto.c.

574{
576}
const char * str

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

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

◆ CopySendTextLikeEndOfRow()

static void CopySendTextLikeEndOfRow ( CopyToState  cstate)
inlinestatic

Definition at line 648 of file copyto.c.

649{
650 switch (cstate->copy_dest)
651 {
652 case COPY_FILE:
653 /* Default line termination depends on platform */
654#ifndef WIN32
655 CopySendChar(cstate, '\n');
656#else
657 CopySendString(cstate, "\r\n");
658#endif
659 break;
660 case COPY_FRONTEND:
661 /* The FE/BE protocol uses \n as newline for all platforms */
662 CopySendChar(cstate, '\n');
663 break;
664 default:
665 break;
666 }
667
668 /* Now take the actions related to the end of a row */
669 CopySendEndOfRow(cstate);
670}
static void CopySendEndOfRow(CopyToState cstate)
Definition copyto.c:585

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

Referenced by CopyToJsonEnd(), CopyToJsonOneRow(), CopyToTextLikeOneRow(), and CopyToTextLikeStart().

◆ CopyToBinaryEnd()

static void CopyToBinaryEnd ( CopyToState  cstate)
static

Definition at line 504 of file copyto.c.

505{
506 /* Generate trailer for a binary copy */
507 CopySendInt16(cstate, -1);
508 /* Need to flush out the trailer */
509 CopySendEndOfRow(cstate);
510}
static void CopySendInt16(CopyToState cstate, int16 val)
Definition copyto.c:692

References CopySendEndOfRow(), and CopySendInt16().

◆ CopyToBinaryOneRow()

static void CopyToBinaryOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 471 of file copyto.c.

472{
473 FmgrInfo *out_functions = cstate->out_functions;
474
475 /* Binary per-tuple header */
476 CopySendInt16(cstate, list_length(cstate->attnumlist));
477
479 {
480 Datum value = slot->tts_values[attnum - 1];
481 bool isnull = slot->tts_isnull[attnum - 1];
482
483 if (isnull)
484 {
485 CopySendInt32(cstate, -1);
486 }
487 else
488 {
490
491 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
492 value);
496 }
497 }
498
499 CopySendEndOfRow(cstate);
500}
#define VARHDRSZ
Definition c.h:781
static void CopySendInt32(CopyToState cstate, int32 val)
Definition copyto.c:680
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1745
static struct @177 value
FmgrInfo * out_functions
Definition copyto.c:110
bool * tts_isnull
Definition tuptable.h:133
Datum * tts_values
Definition tuptable.h:131
Definition c.h:776
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA(const void *PTR)
Definition varatt.h:305

References attnum, CopyToStateData::attnumlist, CopySendData(), CopySendEndOfRow(), CopySendInt16(), CopySendInt32(), fb(), 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 459 of file copyto.c.

460{
462 bool is_varlena;
463
464 /* Set output function for an attribute */
466 fmgr_info(func_oid, finfo);
467}
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition lsyscache.c:3195
unsigned int Oid

References fb(), fmgr_info(), and getTypeBinaryOutputInfo().

◆ CopyToBinaryStart()

static void CopyToBinaryStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 440 of file copyto.c.

441{
442 int32 tmp;
443
444 /* Signature */
445 CopySendData(cstate, BinarySignature, 11);
446 /* Flags field */
447 tmp = 0;
448 CopySendInt32(cstate, tmp);
449 /* No header extension */
450 tmp = 0;
451 CopySendInt32(cstate, tmp);
452}
int32_t int32
Definition c.h:620
static const char BinarySignature[11]
Definition copyto.c:124

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

◆ CopyToCSVOneRow()

static void CopyToCSVOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 289 of file copyto.c.

290{
291 CopyToTextLikeOneRow(cstate, slot, true);
292}
static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv)
Definition copyto.c:301

References CopyToTextLikeOneRow().

◆ CopyToGetRoutine()

static const CopyToRoutine * CopyToGetRoutine ( const CopyFormatOptions opts)
static

Definition at line 201 of file copyto.c.

202{
203 if (opts->format == COPY_FORMAT_CSV)
204 return &CopyToRoutineCSV;
205 else if (opts->format == COPY_FORMAT_BINARY)
206 return &CopyToRoutineBinary;
207 else if (opts->format == COPY_FORMAT_JSON)
208 return &CopyToRoutineJson;
209
210 /* default is text */
211 return &CopyToRoutineText;
212}
static const CopyToRoutine CopyToRoutineCSV
Definition copyto.c:176
static const CopyToRoutine CopyToRoutineText
Definition copyto.c:168
static const CopyToRoutine CopyToRoutineJson
Definition copyto.c:184
static const CopyToRoutine CopyToRoutineBinary
Definition copyto.c:192
@ COPY_FORMAT_CSV
Definition copy.h:59
@ COPY_FORMAT_BINARY
Definition copy.h:58
static AmcheckOptions opts
Definition pg_amcheck.c:112

References COPY_FORMAT_BINARY, COPY_FORMAT_CSV, COPY_FORMAT_JSON, CopyToRoutineBinary, CopyToRoutineCSV, CopyToRoutineJson, CopyToRoutineText, and opts.

Referenced by BeginCopyTo().

◆ CopyToJsonEnd()

static void CopyToJsonEnd ( CopyToState  cstate)
static

Definition at line 348 of file copyto.c.

349{
350 if (cstate->opts.force_array)
351 {
352 CopySendChar(cstate, ']');
354 }
355}
static void CopySendTextLikeEndOfRow(CopyToState cstate)
Definition copyto.c:648
bool force_array
Definition copy.h:91

References CopySendChar(), CopySendTextLikeEndOfRow(), CopyFormatOptions::force_array, and CopyToStateData::opts.

◆ CopyToJsonOneRow()

static void CopyToJsonOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 359 of file copyto.c.

360{
362
363 resetStringInfo(cstate->json_buf);
364
365 if (cstate->json_projvalues != NULL)
366 {
367 /*
368 * Column list case: project selected column values into sequential
369 * positions matching the custom TupleDesc, then form a new tuple.
370 */
372 int i = 0;
373
375 {
376 cstate->json_projvalues[i] = slot->tts_values[attnum - 1];
377 cstate->json_projnulls[i] = slot->tts_isnull[attnum - 1];
378 i++;
379 }
380
381 tup = heap_form_tuple(cstate->tupDesc,
382 cstate->json_projvalues,
383 cstate->json_projnulls);
384
385 /*
386 * heap_form_tuple already stamps the datum-length, type-id, and
387 * type-mod fields on t_data, so we can use it directly as a composite
388 * Datum without the extra pallocmemcpy that heap_copy_tuple_as_datum
389 * would do. Any TOAST pointers in the projected values will be
390 * detoasted by the per-column output functions called from
391 * composite_to_json.
392 */
394 }
395 else
396 {
397 /*
398 * Full table or query without column list. For queries, the slot's
399 * TupleDesc may carry RECORDOID, which is not registered in the type
400 * cache and would cause composite_to_json's lookup_rowtype_tupdesc
401 * call to fail. Build a HeapTuple stamped with the blessed
402 * descriptor so the type can be looked up correctly.
403 */
404 if (!cstate->rel && slot->tts_tupleDescriptor->tdtypeid == RECORDOID)
405 {
407 slot->tts_values,
408 slot->tts_isnull);
409
411 }
412 else
414 }
415
416 composite_to_json(rowdata, cstate->json_buf, false);
417
418 if (cstate->opts.force_array)
419 {
420 if (cstate->json_row_delim_needed)
421 CopySendChar(cstate, ',');
422 else
423 {
424 /* first row needs no delimiter */
425 CopySendChar(cstate, ' ');
426 cstate->json_row_delim_needed = true;
427 }
428 }
429
430 CopySendData(cstate, cstate->json_buf->data, cstate->json_buf->len);
431
433}
Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1025
int i
Definition isn.c:77
void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
Definition json.c:521
bool json_row_delim_needed
Definition copyto.c:91
TupleDesc tts_tupleDescriptor
Definition tuptable.h:129

References attnum, CopyToStateData::attnumlist, composite_to_json(), CopySendChar(), CopySendData(), CopySendTextLikeEndOfRow(), StringInfoData::data, ExecFetchSlotHeapTupleDatum(), fb(), CopyFormatOptions::force_array, foreach_int, heap_form_tuple(), HeapTupleGetDatum(), i, CopyToStateData::json_buf, CopyToStateData::json_projnulls, CopyToStateData::json_projvalues, CopyToStateData::json_row_delim_needed, StringInfoData::len, CopyToStateData::opts, CopyToStateData::rel, resetStringInfo(), TupleDescData::tdtypeid, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, and CopyToStateData::tupDesc.

◆ CopyToTextLikeEnd()

static void CopyToTextLikeEnd ( CopyToState  cstate)
static

Definition at line 341 of file copyto.c.

342{
343 /* Nothing to do here */
344}

◆ CopyToTextLikeOneRow()

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

Definition at line 301 of file copyto.c.

304{
305 bool need_delim = false;
306 FmgrInfo *out_functions = cstate->out_functions;
307
309 {
310 Datum value = slot->tts_values[attnum - 1];
311 bool isnull = slot->tts_isnull[attnum - 1];
312
313 if (need_delim)
314 CopySendChar(cstate, cstate->opts.delim[0]);
315 need_delim = true;
316
317 if (isnull)
318 {
319 CopySendString(cstate, cstate->opts.null_print_client);
320 }
321 else
322 {
323 char *string;
324
325 string = OutputFunctionCall(&out_functions[attnum - 1],
326 value);
327
328 if (is_csv)
329 CopyAttributeOutCSV(cstate, string,
330 cstate->opts.force_quote_flags[attnum - 1]);
331 else
332 CopyAttributeOutText(cstate, string);
333 }
334 }
335
337}
static void CopyAttributeOutCSV(CopyToState cstate, const char *string, bool use_quote)
Definition copyto.c:1574
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition copyto.c:1421
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1684
char * null_print_client
Definition copy.h:79

References attnum, CopyToStateData::attnumlist, CopyAttributeOutCSV(), CopyAttributeOutText(), CopySendChar(), CopySendString(), CopySendTextLikeEndOfRow(), CopyFormatOptions::delim, fb(), 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 270 of file copyto.c.

271{
273 bool is_varlena;
274
275 /* Set output function for an attribute */
277 fmgr_info(func_oid, finfo);
278}
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3129

References fb(), fmgr_info(), and getTypeOutputInfo().

◆ CopyToTextLikeStart()

static void CopyToTextLikeStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 216 of file copyto.c.

217{
218 /*
219 * For non-binary copy, we need to convert null_print to file encoding,
220 * because it will be sent directly with CopySendString.
221 */
222 if (cstate->need_transcoding)
224 cstate->opts.null_print_len,
225 cstate->file_encoding);
226
227 /* if a header has been requested send the line */
228 if (cstate->opts.header_line == COPY_HEADER_TRUE)
229 {
230 ListCell *cur;
231 bool hdr_delim = false;
232
234
235 foreach(cur, cstate->attnumlist)
236 {
237 int attnum = lfirst_int(cur);
238 char *colname;
239
240 if (hdr_delim)
241 CopySendChar(cstate, cstate->opts.delim[0]);
242 hdr_delim = true;
243
244 colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
245
246 if (cstate->opts.format == COPY_FORMAT_CSV)
247 CopyAttributeOutCSV(cstate, colname, false);
248 else
249 CopyAttributeOutText(cstate, colname);
250 }
251
253 }
254
255 /*
256 * If FORCE_ARRAY has been specified, send the opening bracket.
257 */
258 if (cstate->opts.format == COPY_FORMAT_JSON && cstate->opts.force_array)
259 {
260 CopySendChar(cstate, '[');
262 }
263}
#define COPY_HEADER_TRUE
Definition copy.h:28
NameData attname
int header_line
Definition copy.h:75
int null_print_len
Definition copy.h:78

References Assert, attname, attnum, CopyToStateData::attnumlist, COPY_FORMAT_CSV, COPY_FORMAT_JSON, COPY_HEADER_TRUE, CopyAttributeOutCSV(), CopyAttributeOutText(), CopySendChar(), CopySendTextLikeEndOfRow(), cur, CopyFormatOptions::delim, fb(), CopyToStateData::file_encoding, CopyFormatOptions::force_array, CopyFormatOptions::format, 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 282 of file copyto.c.

283{
284 CopyToTextLikeOneRow(cstate, slot, false);
285}

References CopyToTextLikeOneRow().

◆ CreateCopyDestReceiver()

DestReceiver * CreateCopyDestReceiver ( void  )

Definition at line 1709 of file copyto.c.

1710{
1711 DR_copy *self = palloc_object(DR_copy);
1712
1717 self->pub.mydest = DestCopyOut;
1718
1719 self->cstate = NULL; /* will be set later */
1720 self->processed = 0;
1721
1722 return (DestReceiver *) self;
1723}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1672
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1700
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1691
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1663
#define palloc_object(type)
Definition fe_memutils.h:74
CopyToState cstate
Definition copyto.c:119
DestReceiver pub
Definition copyto.c:118
uint64 processed
Definition copyto.c:120
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, fb(), _DestReceiver::mydest, palloc_object, 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 1241 of file copyto.c.

1242{
1243 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1244 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1245 TupleDesc tupDesc;
1246 int num_phys_attrs;
1247 ListCell *cur;
1248 uint64 processed = 0;
1249
1250 if (fe_copy)
1251 SendCopyBegin(cstate);
1252
1253 if (cstate->rel)
1254 tupDesc = RelationGetDescr(cstate->rel);
1255 else
1256 tupDesc = cstate->queryDesc->tupDesc;
1257 num_phys_attrs = tupDesc->natts;
1258 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1259
1260 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1261 cstate->fe_msgbuf = makeStringInfo();
1262
1263 /* Get info about the columns we need to process. */
1264 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1265 foreach(cur, cstate->attnumlist)
1266 {
1267 int attnum = lfirst_int(cur);
1268 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1269
1270 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1271 &cstate->out_functions[attnum - 1]);
1272 }
1273
1274 /*
1275 * Create a temporary memory context that we can reset once per row to
1276 * recover palloc'd memory. This avoids any problems with leaks inside
1277 * datatype output routines, and should be faster than retail pfree's
1278 * anyway. (We don't need a whole econtext as CopyFrom does.)
1279 */
1281 "COPY TO",
1283
1284 cstate->routine->CopyToStart(cstate, tupDesc);
1285
1286 if (cstate->rel)
1287 {
1288 /*
1289 * If COPY TO source table is a partitioned table, then open each
1290 * partition and process each individual partition.
1291 */
1292 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1293 {
1294 foreach_oid(child, cstate->partitions)
1295 {
1297
1298 /* We already got the lock in BeginCopyTo */
1299 scan_rel = table_open(child, NoLock);
1300 CopyRelationTo(cstate, scan_rel, cstate->rel, &processed);
1302 }
1303 }
1304 else
1305 CopyRelationTo(cstate, cstate->rel, NULL, &processed);
1306 }
1307 else
1308 {
1309 /* run the plan --- the dest receiver will send tuples */
1311 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1312 }
1313
1314 cstate->routine->CopyToEnd(cstate);
1315
1317
1318 if (fe_copy)
1319 SendCopyEnd(cstate);
1320
1321 return processed;
1322}
uint64_t uint64
Definition c.h:625
static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
Definition copyto.c:1332
static void SendCopyBegin(CopyToState cstate)
Definition copyto.c:517
static void SendCopyEnd(CopyToState cstate)
Definition copyto.c:548
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition execMain.c:308
#define NoLock
Definition lockdefs.h:34
void * palloc(Size size)
Definition mcxt.c:1387
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
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:41
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, attnum, CopyToStateData::attnumlist, CopyRelationTo(), CopyToRoutine::CopyToEnd, CopyToRoutine::CopyToOutFunc, CopyToRoutine::CopyToStart, cur, CurrentMemoryContext, CopyToStateData::data_dest_cb, QueryDesc::dest, DestRemote, ExecutorRun(), fb(), CopyToStateData::fe_msgbuf, CopyToStateData::filename, foreach_oid, ForwardScanDirection, lfirst_int, makeStringInfo(), MemoryContextDelete(), TupleDescData::natts, NoLock, CopyFormatOptions::null_print, CopyFormatOptions::null_print_client, CopyToStateData::opts, CopyToStateData::out_functions, palloc(), CopyToStateData::partitions, CopyToStateData::queryDesc, RelationData::rd_rel, CopyToStateData::rel, RelationGetDescr, CopyToStateData::routine, CopyToStateData::rowcontext, SendCopyBegin(), SendCopyEnd(), table_close(), table_open(), QueryDesc::tupDesc, TupleDescAttr(), and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ EndCopy()

static void EndCopy ( CopyToState  cstate)
static

Definition at line 729 of file copyto.c.

730{
731 if (cstate->is_program)
732 {
733 ClosePipeToProgram(cstate);
734 }
735 else
736 {
737 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
740 errmsg("could not close file \"%s\": %m",
741 cstate->filename)));
742 }
743
745
747
748 if (cstate->partitions)
749 list_free(cstate->partitions);
750
751 pfree(cstate);
752}
void pgstat_progress_end_command(void)
int FreeFile(FILE *file)
Definition fd.c:2827
void list_free(List *list)
Definition list.c:1546

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

Referenced by EndCopyTo().

◆ EndCopyTo()

void EndCopyTo ( CopyToState  cstate)

Definition at line 1220 of file copyto.c.

1221{
1222 if (cstate->queryDesc != NULL)
1223 {
1224 /* Close down the query and free resources. */
1225 ExecutorFinish(cstate->queryDesc);
1226 ExecutorEnd(cstate->queryDesc);
1227 FreeQueryDesc(cstate->queryDesc);
1229 }
1230
1231 /* Clean up storage */
1232 EndCopy(cstate);
1233}
static void EndCopy(CopyToState cstate)
Definition copyto.c:729
void ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:477
void ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:417
void FreeQueryDesc(QueryDesc *qdesc)
Definition pquery.c:107
void PopActiveSnapshot(void)
Definition snapmgr.c:775

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

Referenced by DoCopy(), and test_copy_to_callback().

◆ SendCopyBegin()

static void SendCopyBegin ( CopyToState  cstate)
static

Definition at line 517 of file copyto.c.

518{
520 int natts = list_length(cstate->attnumlist);
521 int16 format = (cstate->opts.format == COPY_FORMAT_BINARY ? 1 : 0);
522 int i;
523
525 pq_sendbyte(&buf, format); /* overall format */
526 if (cstate->opts.format != COPY_FORMAT_JSON)
527 {
528 pq_sendint16(&buf, natts);
529 for (i = 0; i < natts; i++)
530 pq_sendint16(&buf, format); /* per-column formats */
531 }
532 else
533 {
534 /*
535 * For JSON format, report one text-format column. Each CopyData
536 * message contains one complete JSON object, not individual column
537 * values, so the per-column count is always 1.
538 */
539 pq_sendint16(&buf, 1);
540 pq_sendint16(&buf, 0);
541 }
542
544 cstate->copy_dest = COPY_FRONTEND;
545}
int16_t int16
Definition c.h:619
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

References CopyToStateData::attnumlist, buf, CopyToStateData::copy_dest, COPY_FORMAT_BINARY, COPY_FORMAT_JSON, COPY_FRONTEND, format, CopyFormatOptions::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 548 of file copyto.c.

549{
550 /* Shouldn't have any unsent data */
551 Assert(cstate->fe_msgbuf->len == 0);
552 /* Send Copy Done message */
554}
void pq_putemptymessage(char msgtype)
Definition pqformat.c:387
#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 124 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:459
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:471
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:440
static void CopyToBinaryEnd(CopyToState cstate)
Definition copyto.c:504

Definition at line 192 of file copyto.c.

192 {
193 .CopyToStart = CopyToBinaryStart,
194 .CopyToOutFunc = CopyToBinaryOutFunc,
195 .CopyToOneRow = CopyToBinaryOneRow,
196 .CopyToEnd = CopyToBinaryEnd,
197};

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:341
static void CopyToTextLikeOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition copyto.c:270
static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:216
static void CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:289

Definition at line 176 of file copyto.c.

176 {
177 .CopyToStart = CopyToTextLikeStart,
178 .CopyToOutFunc = CopyToTextLikeOutFunc,
179 .CopyToOneRow = CopyToCSVOneRow,
180 .CopyToEnd = CopyToTextLikeEnd,
181};

Referenced by CopyToGetRoutine().

◆ CopyToRoutineJson

const CopyToRoutine CopyToRoutineJson
static
Initial value:
= {
.CopyToStart = CopyToTextLikeStart,
.CopyToOutFunc = CopyToTextLikeOutFunc,
.CopyToOneRow = CopyToJsonOneRow,
.CopyToEnd = CopyToJsonEnd,
}
static void CopyToJsonOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:359
static void CopyToJsonEnd(CopyToState cstate)
Definition copyto.c:348

Definition at line 184 of file copyto.c.

184 {
185 .CopyToStart = CopyToTextLikeStart,
186 .CopyToOutFunc = CopyToTextLikeOutFunc,
187 .CopyToOneRow = CopyToJsonOneRow,
188 .CopyToEnd = CopyToJsonEnd,
189};

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

Definition at line 168 of file copyto.c.

168 {
169 .CopyToStart = CopyToTextLikeStart,
170 .CopyToOutFunc = CopyToTextLikeOutFunc,
171 .CopyToOneRow = CopyToTextOneRow,
172 .CopyToEnd = CopyToTextLikeEnd,
173};

Referenced by CopyToGetRoutine().