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

1433 { \
1434 if (ptr > start) \
1435 CopySendData(cstate, start, ptr - start); \
1436 } 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 787 of file copyto.c.

796{
797 CopyToState cstate;
798 bool pipe = (filename == NULL && data_dest_cb == NULL);
799 TupleDesc tupDesc;
800 int num_phys_attrs;
801 MemoryContext oldcontext;
802 const int progress_cols[] = {
805 };
806 int64 progress_vals[] = {
808 0
809 };
810 List *children = NIL;
811
812 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
813 {
814 if (rel->rd_rel->relkind == RELKIND_VIEW)
817 errmsg("cannot copy from view \"%s\"",
819 errhint("Try the COPY (SELECT ...) TO variant.")));
820 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
821 {
822 if (!RelationIsPopulated(rel))
825 errmsg("cannot copy from unpopulated materialized view \"%s\"",
827 errhint("Use the REFRESH MATERIALIZED VIEW command."));
828 }
829 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
832 errmsg("cannot copy from foreign table \"%s\"",
834 errhint("Try the COPY (SELECT ...) TO variant.")));
835 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
838 errmsg("cannot copy from sequence \"%s\"",
840 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
841 {
842 /*
843 * Collect OIDs of relation containing data, so that later
844 * DoCopyTo can copy the data from them.
845 */
847
848 foreach_oid(child, children)
849 {
850 char relkind = get_rel_relkind(child);
851
852 if (relkind == RELKIND_FOREIGN_TABLE)
853 {
854 char *relation_name = get_rel_name(child);
855
858 errmsg("cannot copy from foreign table \"%s\"", relation_name),
859 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
860 relation_name, RelationGetRelationName(rel)),
861 errhint("Try the COPY (SELECT ...) TO variant."));
862 }
863
864 /* Exclude tables with no data */
865 if (RELKIND_HAS_PARTITIONS(relkind))
866 children = foreach_delete_current(children, child);
867 }
868 }
869 else
872 errmsg("cannot copy from non-table relation \"%s\"",
874 }
875
876
877 /* Allocate workspace and zero all fields */
879
880 /*
881 * We allocate everything used by a cstate in a new memory context. This
882 * avoids memory leaks during repeated use of COPY in a query.
883 */
885 "COPY",
887
888 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
889
890 /* Extract options from the statement node tree */
891 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
892
893 /* Set format routine */
894 cstate->routine = CopyToGetRoutine(&cstate->opts);
895
896 /* Process the source/target relation or query */
897 if (rel)
898 {
900
901 cstate->rel = rel;
902
903 tupDesc = RelationGetDescr(cstate->rel);
904 cstate->partitions = children;
905 cstate->tupDesc = tupDesc;
906 }
907 else
908 {
910 Query *query;
913
914 cstate->rel = NULL;
915 cstate->partitions = NIL;
916
917 /*
918 * Run parse analysis and rewrite. Note this also acquires sufficient
919 * locks on the source table(s).
920 */
922 pstate->p_sourcetext, NULL, 0,
923 NULL);
924
925 /* check that we got back something we can work with */
926 if (rewritten == NIL)
927 {
930 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
931 }
932 else if (list_length(rewritten) > 1)
933 {
934 ListCell *lc;
935
936 /* examine queries to determine which error message to issue */
937 foreach(lc, rewritten)
938 {
939 Query *q = lfirst_node(Query, lc);
940
941 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
944 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
945 if (q->querySource == QSRC_NON_INSTEAD_RULE)
948 errmsg("DO ALSO rules are not supported for COPY")));
949 }
950
953 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
954 }
955
956 query = linitial_node(Query, rewritten);
957
958 /* The grammar allows SELECT INTO, but we don't support that */
959 if (query->utilityStmt != NULL &&
963 errmsg("COPY (SELECT INTO) is not supported")));
964
965 /* The only other utility command we could see is NOTIFY */
966 if (query->utilityStmt != NULL)
969 errmsg("COPY query must not be a utility command")));
970
971 /*
972 * Similarly the grammar doesn't enforce the presence of a RETURNING
973 * clause, but this is required here.
974 */
975 if (query->commandType != CMD_SELECT &&
976 query->returningList == NIL)
977 {
978 Assert(query->commandType == CMD_INSERT ||
979 query->commandType == CMD_UPDATE ||
980 query->commandType == CMD_DELETE ||
981 query->commandType == CMD_MERGE);
982
985 errmsg("COPY query must have a RETURNING clause")));
986 }
987
988 /* plan the query */
989 plan = pg_plan_query(query, pstate->p_sourcetext,
991
992 /*
993 * With row-level security and a user using "COPY relation TO", we
994 * have to convert the "COPY relation TO" to a query-based COPY (eg:
995 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
996 * add in any RLS clauses.
997 *
998 * When this happens, we are passed in the relid of the originally
999 * found relation (which we have locked). As the planner will look up
1000 * the relation again, we double-check here to make sure it found the
1001 * same one that we have locked.
1002 */
1003 if (queryRelId != InvalidOid)
1004 {
1005 /*
1006 * Note that with RLS involved there may be multiple relations,
1007 * and while the one we need is almost certainly first, we don't
1008 * make any guarantees of that in the planner, so check the whole
1009 * list and make sure we find the original relation.
1010 */
1011 if (!list_member_oid(plan->relationOids, queryRelId))
1012 ereport(ERROR,
1014 errmsg("relation referenced by COPY statement has changed")));
1015 }
1016
1017 /*
1018 * Use a snapshot with an updated command ID to ensure this query sees
1019 * results of any previously executed queries.
1020 */
1023
1024 /* Create dest receiver for COPY OUT */
1026 ((DR_copy *) dest)->cstate = cstate;
1027
1028 /* Create a QueryDesc requesting no output */
1029 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
1032 dest, NULL, NULL, 0);
1033
1034 /*
1035 * Call ExecutorStart to prepare the plan for execution.
1036 *
1037 * ExecutorStart computes a result tupdesc for us
1038 */
1039 ExecutorStart(cstate->queryDesc, 0);
1040
1041 tupDesc = cstate->queryDesc->tupDesc;
1042 tupDesc = BlessTupleDesc(tupDesc);
1043 cstate->tupDesc = tupDesc;
1044 }
1045
1046 /* Generate or convert list of attributes to process */
1047 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1048
1049 /* Set up JSON-specific state */
1050 if (cstate->opts.format == COPY_FORMAT_JSON)
1051 {
1052 cstate->json_buf = makeStringInfo();
1053
1054 if (rel && list_length(cstate->attnumlist) < tupDesc->natts)
1055 {
1056 int natts = list_length(cstate->attnumlist);
1057 TupleDesc resultDesc;
1058
1059 /*
1060 * Build a TupleDesc describing only the selected columns so that
1061 * composite_to_json() emits the right column names and types.
1062 */
1063 resultDesc = CreateTemplateTupleDesc(natts);
1064
1065 foreach_int(attnum, cstate->attnumlist)
1066 {
1067 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1068
1069 TupleDescInitEntry(resultDesc,
1071 NameStr(attr->attname),
1072 attr->atttypid,
1073 attr->atttypmod,
1074 attr->attndims);
1075 }
1076
1077 TupleDescFinalize(resultDesc);
1078 cstate->tupDesc = BlessTupleDesc(resultDesc);
1079
1080 /*
1081 * Pre-allocate arrays for projecting selected column values into
1082 * sequential positions matching the custom TupleDesc.
1083 */
1084 cstate->json_projvalues = palloc_array(Datum, natts);
1085 cstate->json_projnulls = palloc_array(bool, natts);
1086 }
1087 }
1088
1089 num_phys_attrs = tupDesc->natts;
1090
1091 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
1092 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1093 if (cstate->opts.force_quote_all)
1094 {
1095 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
1096 }
1097 else if (cstate->opts.force_quote)
1098 {
1099 List *attnums;
1100 ListCell *cur;
1101
1102 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
1103
1104 foreach(cur, attnums)
1105 {
1106 int attnum = lfirst_int(cur);
1107 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1108
1109 if (!list_member_int(cstate->attnumlist, attnum))
1110 ereport(ERROR,
1112 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1113 errmsg("%s column \"%s\" not referenced by COPY",
1114 "FORCE_QUOTE", NameStr(attr->attname))));
1115 cstate->opts.force_quote_flags[attnum - 1] = true;
1116 }
1117 }
1118
1119 /* Use client encoding when ENCODING option is not specified. */
1120 if (cstate->opts.file_encoding < 0)
1122 else
1123 cstate->file_encoding = cstate->opts.file_encoding;
1124
1125 /*
1126 * Set up encoding conversion info if the file and server encodings differ
1127 * (see also pg_server_to_any).
1128 */
1129 if (cstate->file_encoding == GetDatabaseEncoding() ||
1130 cstate->file_encoding == PG_SQL_ASCII)
1131 cstate->need_transcoding = false;
1132 else
1133 cstate->need_transcoding = true;
1134
1135 /* See Multibyte encoding comment above */
1137
1138 cstate->copy_dest = COPY_FILE; /* default */
1139
1140 if (data_dest_cb)
1141 {
1143 cstate->copy_dest = COPY_CALLBACK;
1144 cstate->data_dest_cb = data_dest_cb;
1145 }
1146 else if (pipe)
1147 {
1149
1150 Assert(!is_program); /* the grammar does not allow this */
1152 cstate->copy_file = stdout;
1153 }
1154 else
1155 {
1156 cstate->filename = pstrdup(filename);
1157 cstate->is_program = is_program;
1158
1159 if (is_program)
1160 {
1162 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
1163 if (cstate->copy_file == NULL)
1164 ereport(ERROR,
1166 errmsg("could not execute command \"%s\": %m",
1167 cstate->filename)));
1168 }
1169 else
1170 {
1171 mode_t oumask; /* Pre-existing umask value */
1172 struct stat st;
1173
1175
1176 /*
1177 * Prevent write to relative path ... too easy to shoot oneself in
1178 * the foot by overwriting a database file ...
1179 */
1181 ereport(ERROR,
1183 errmsg("relative path not allowed for COPY to file")));
1184
1186 PG_TRY();
1187 {
1188 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
1189 }
1190 PG_FINALLY();
1191 {
1192 umask(oumask);
1193 }
1194 PG_END_TRY();
1195 if (cstate->copy_file == NULL)
1196 {
1197 /* copy errno because ereport subfunctions might change it */
1198 int save_errno = errno;
1199
1200 ereport(ERROR,
1202 errmsg("could not open file \"%s\" for writing: %m",
1203 cstate->filename),
1204 (save_errno == ENOENT || save_errno == EACCES) ?
1205 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1206 "You may want a client-side facility such as psql's \\copy.") : 0));
1207 }
1208
1209 if (fstat(fileno(cstate->copy_file), &st))
1210 ereport(ERROR,
1212 errmsg("could not stat file \"%s\": %m",
1213 cstate->filename)));
1214
1215 if (S_ISDIR(st.st_mode))
1216 ereport(ERROR,
1218 errmsg("\"%s\" is a directory", cstate->filename)));
1219 }
1220 }
1221
1222 /* initialize progress */
1224 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1226
1227 cstate->bytes_processed = 0;
1228
1229 MemoryContextSwitchTo(oldcontext);
1230
1231 return cstate;
1232}
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:1389
#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:898
int errcode(int sqlerrcode)
Definition elog.c:875
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:91
#define palloc0_object(type)
Definition fe_memutils.h:90
@ 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:2234
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2309
int GetDatabaseEncoding(void)
Definition mbutils.c:1389
int pg_get_client_encoding(void)
Definition mbutils.c:345
char * pstrdup(const char *in)
Definition mcxt.c:1910
void * palloc0(Size size)
Definition mcxt.c:1420
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
#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:138
@ 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:105
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition postgres.c:899
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:682
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:697
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:909
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 722 of file copyto.c.

723{
724 int pclose_rc;
725
726 Assert(cstate->is_program);
727
729 if (pclose_rc == -1)
732 errmsg("could not close pipe to external command: %m")));
733 else if (pclose_rc != 0)
734 {
737 errmsg("program \"%s\" failed",
738 cstate->filename),
740 }
741}
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 1718 of file copyto.c.

1719{
1720 pfree(self);
1721}
void pfree(void *pointer)
Definition mcxt.c:1619

References pfree().

Referenced by CreateCopyDestReceiver().

◆ copy_dest_receive()

static bool copy_dest_receive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 1690 of file copyto.c.

1691{
1692 DR_copy *myState = (DR_copy *) self;
1693 CopyToState cstate = myState->cstate;
1694
1695 /* Send the data */
1696 CopyOneRowTo(cstate, slot);
1697
1698 /* Increment the number of processed tuples, and report the progress */
1700 ++myState->processed);
1701
1702 return true;
1703}
void pgstat_progress_update_param(int index, int64 val)
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:1414
#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 1709 of file copyto.c.

1710{
1711 /* no-op */
1712}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1681 of file copyto.c.

1682{
1683 /* no-op */
1684}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1592 of file copyto.c.

1594{
1595 const char *ptr;
1596 const char *start;
1597 char c;
1598 char delimc = cstate->opts.delim[0];
1599 char quotec = cstate->opts.quote[0];
1600 char escapec = cstate->opts.escape[0];
1601 bool single_attr = (list_length(cstate->attnumlist) == 1);
1602
1603 /* force quoting if it matches null_print (before conversion!) */
1604 if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1605 use_quote = true;
1606
1607 if (cstate->need_transcoding)
1608 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1609 else
1610 ptr = string;
1611
1612 /*
1613 * Make a preliminary pass to discover if it needs quoting
1614 */
1615 if (!use_quote)
1616 {
1617 /*
1618 * Quote '\.' if it appears alone on a line, so that it will not be
1619 * interpreted as an end-of-data marker. (PG 18 and up will not
1620 * interpret '\.' in CSV that way, except in embedded-in-SQL data; but
1621 * we want the data to be loadable by older versions too. Also, this
1622 * avoids breaking clients that are still using PQgetline().)
1623 */
1624 if (single_attr && strcmp(ptr, "\\.") == 0)
1625 use_quote = true;
1626 else
1627 {
1628 const char *tptr = ptr;
1629
1630 while ((c = *tptr) != '\0')
1631 {
1632 if (c == delimc || c == quotec || c == '\n' || c == '\r')
1633 {
1634 use_quote = true;
1635 break;
1636 }
1637 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1639 else
1640 tptr++;
1641 }
1642 }
1643 }
1644
1645 if (use_quote)
1646 {
1647 CopySendChar(cstate, quotec);
1648
1649 /*
1650 * We adopt the same optimization strategy as in CopyAttributeOutText
1651 */
1652 start = ptr;
1653 while ((c = *ptr) != '\0')
1654 {
1655 if (c == quotec || c == escapec)
1656 {
1657 DUMPSOFAR();
1658 CopySendChar(cstate, escapec);
1659 start = ptr; /* we include char in next run */
1660 }
1661 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1662 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1663 else
1664 ptr++;
1665 }
1666 DUMPSOFAR();
1667
1668 CopySendChar(cstate, quotec);
1669 }
1670 else
1671 {
1672 /* If it doesn't need quoting, we can just dump it as-is */
1673 CopySendString(cstate, ptr);
1674 }
1675}
#define IS_HIGHBIT_SET(ch)
Definition c.h:1244
#define DUMPSOFAR()
Definition copyto.c:1432
static void CopySendChar(CopyToState cstate, char c)
Definition copyto.c:597
static void CopySendString(CopyToState cstate, const char *str)
Definition copyto.c:591
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:1935

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

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

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

1415{
1416 MemoryContext oldcontext;
1417
1419 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1420
1421 /* Make sure the tuple is fully deconstructed */
1422 slot_getallattrs(slot);
1423
1424 cstate->routine->CopyToOneRow(cstate, slot);
1425
1426 MemoryContextSwitchTo(oldcontext);
1427}
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:406
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 1350 of file copyto.c.

1351{
1352 TupleTableSlot *slot;
1353 TableScanDesc scandesc;
1354 AttrMap *map = NULL;
1356
1357 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL,
1358 SO_NONE);
1359 slot = table_slot_create(rel, NULL);
1360
1361 /*
1362 * If we are exporting partition data here, we check if converting tuples
1363 * to the root table's rowtype, because a partition might have column
1364 * order different than its root table.
1365 */
1366 if (root_rel != NULL)
1367 {
1371 false);
1372 }
1373
1374 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1375 {
1376 TupleTableSlot *copyslot;
1377
1379
1380 if (map != NULL)
1381 copyslot = execute_attr_map_slot(map, slot, root_slot);
1382 else
1383 {
1384 /* Deconstruct the tuple */
1385 slot_getallattrs(slot);
1386 copyslot = slot;
1387 }
1388
1389 /* Format and send the data */
1390 CopyOneRowTo(cstate, copyslot);
1391
1392 /*
1393 * Increment the number of processed tuples, and report the progress.
1394 */
1396 ++(*processed));
1397 }
1398
1400
1401 if (root_slot != NULL)
1403
1404 if (map != NULL)
1405 free_attrmap(map);
1406
1407 table_endscan(scandesc);
1408}
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 585 of file copyto.c.

586{
588}
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 603 of file copyto.c.

604{
605 StringInfo fe_msgbuf = cstate->fe_msgbuf;
606
607 switch (cstate->copy_dest)
608 {
609 case COPY_FILE:
611 if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
612 cstate->copy_file) != 1 ||
613 ferror(cstate->copy_file))
614 {
615 if (cstate->is_program)
616 {
617 if (errno == EPIPE)
618 {
619 /*
620 * The pipe will be closed automatically on error at
621 * the end of transaction, but we might get a better
622 * error message from the subprocess' exit code than
623 * just "Broken Pipe"
624 */
625 ClosePipeToProgram(cstate);
626
627 /*
628 * If ClosePipeToProgram() didn't throw an error, the
629 * program terminated normally, but closed the pipe
630 * first. Restore errno, and throw an error.
631 */
632 errno = EPIPE;
633 }
636 errmsg("could not write to COPY program: %m")));
637 }
638 else
641 errmsg("could not write to COPY file: %m")));
642 }
644 break;
645 case COPY_FRONTEND:
646 /* Dump the accumulated row as one CopyData message */
647 (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
648 break;
649 case COPY_CALLBACK:
650 cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
651 break;
652 }
653
654 /* Update the progress */
655 cstate->bytes_processed += fe_msgbuf->len;
657
658 resetStringInfo(fe_msgbuf);
659}
static void ClosePipeToProgram(CopyToState cstate)
Definition copyto.c:722
#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 710 of file copyto.c.

711{
712 uint16 buf;
713
714 buf = pg_hton16((uint16) val);
715 CopySendData(cstate, &buf, sizeof(buf));
716}
uint16_t uint16
Definition c.h:623
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition copyto.c:585
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 698 of file copyto.c.

699{
700 uint32 buf;
701
702 buf = pg_hton32((uint32) val);
703 CopySendData(cstate, &buf, sizeof(buf));
704}
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 591 of file copyto.c.

592{
594}
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 666 of file copyto.c.

667{
668 switch (cstate->copy_dest)
669 {
670 case COPY_FILE:
671 /* Default line termination depends on platform */
672#ifndef WIN32
673 CopySendChar(cstate, '\n');
674#else
675 CopySendString(cstate, "\r\n");
676#endif
677 break;
678 case COPY_FRONTEND:
679 /* The FE/BE protocol uses \n as newline for all platforms */
680 CopySendChar(cstate, '\n');
681 break;
682 default:
683 break;
684 }
685
686 /* Now take the actions related to the end of a row */
687 CopySendEndOfRow(cstate);
688}
static void CopySendEndOfRow(CopyToState cstate)
Definition copyto.c:603

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

523{
524 /* Generate trailer for a binary copy */
525 CopySendInt16(cstate, -1);
526 /* Need to flush out the trailer */
527 CopySendEndOfRow(cstate);
528}
static void CopySendInt16(CopyToState cstate, int16 val)
Definition copyto.c:710

References CopySendEndOfRow(), and CopySendInt16().

◆ CopyToBinaryOneRow()

static void CopyToBinaryOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 489 of file copyto.c.

490{
491 FmgrInfo *out_functions = cstate->out_functions;
492
493 /* Binary per-tuple header */
494 CopySendInt16(cstate, list_length(cstate->attnumlist));
495
497 {
498 Datum value = slot->tts_values[attnum - 1];
499 bool isnull = slot->tts_isnull[attnum - 1];
500
501 if (isnull)
502 {
503 CopySendInt32(cstate, -1);
504 }
505 else
506 {
508
509 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
510 value);
514 }
515 }
516
517 CopySendEndOfRow(cstate);
518}
#define VARHDRSZ
Definition c.h:781
static void CopySendInt32(CopyToState cstate, int32 val)
Definition copyto.c:698
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 477 of file copyto.c.

478{
480 bool is_varlena;
481
482 /* Set output function for an attribute */
484 fmgr_info(func_oid, finfo);
485}
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition lsyscache.c:3281
unsigned int Oid

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

◆ CopyToBinaryStart()

static void CopyToBinaryStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 458 of file copyto.c.

459{
460 int32 tmp;
461
462 /* Signature */
463 CopySendData(cstate, BinarySignature, 11);
464 /* Flags field */
465 tmp = 0;
466 CopySendInt32(cstate, tmp);
467 /* No header extension */
468 tmp = 0;
469 CopySendInt32(cstate, tmp);
470}
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:666
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 /*
431 * Convert the JSON output to the target encoding if needed. Unlike the
432 * text and CSV paths which convert per-attribute via CopyAttributeOut*,
433 * composite_to_json() emits the whole row as one buffer, so we transcode
434 * it here in a single call before sending.
435 */
436 if (cstate->need_transcoding)
437 {
438 char *converted;
439
441 cstate->json_buf->len,
442 cstate->file_encoding);
444 if (converted != cstate->json_buf->data)
446 }
447 else
448 CopySendData(cstate, cstate->json_buf->data, cstate->json_buf->len);
449
451}
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(), CopyToStateData::file_encoding, 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::need_transcoding, CopyToStateData::opts, pfree(), pg_server_to_any(), 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:1592
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition copyto.c:1439
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:3215

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

1728{
1729 DR_copy *self = palloc_object(DR_copy);
1730
1735 self->pub.mydest = DestCopyOut;
1736
1737 self->cstate = NULL; /* will be set later */
1738 self->processed = 0;
1739
1740 return (DestReceiver *) self;
1741}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1690
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1718
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1709
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1681
#define palloc_object(type)
Definition fe_memutils.h:89
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 1259 of file copyto.c.

1260{
1261 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1262 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1263 TupleDesc tupDesc;
1264 int num_phys_attrs;
1265 ListCell *cur;
1266 uint64 processed = 0;
1267
1268 if (fe_copy)
1269 SendCopyBegin(cstate);
1270
1271 if (cstate->rel)
1272 tupDesc = RelationGetDescr(cstate->rel);
1273 else
1274 tupDesc = cstate->queryDesc->tupDesc;
1275 num_phys_attrs = tupDesc->natts;
1276 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1277
1278 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1279 cstate->fe_msgbuf = makeStringInfo();
1280
1281 /* Get info about the columns we need to process. */
1282 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1283 foreach(cur, cstate->attnumlist)
1284 {
1285 int attnum = lfirst_int(cur);
1286 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1287
1288 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1289 &cstate->out_functions[attnum - 1]);
1290 }
1291
1292 /*
1293 * Create a temporary memory context that we can reset once per row to
1294 * recover palloc'd memory. This avoids any problems with leaks inside
1295 * datatype output routines, and should be faster than retail pfree's
1296 * anyway. (We don't need a whole econtext as CopyFrom does.)
1297 */
1299 "COPY TO",
1301
1302 cstate->routine->CopyToStart(cstate, tupDesc);
1303
1304 if (cstate->rel)
1305 {
1306 /*
1307 * If COPY TO source table is a partitioned table, then open each
1308 * partition and process each individual partition.
1309 */
1310 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1311 {
1312 foreach_oid(child, cstate->partitions)
1313 {
1315
1316 /* We already got the lock in BeginCopyTo */
1317 scan_rel = table_open(child, NoLock);
1318 CopyRelationTo(cstate, scan_rel, cstate->rel, &processed);
1320 }
1321 }
1322 else
1323 CopyRelationTo(cstate, cstate->rel, NULL, &processed);
1324 }
1325 else
1326 {
1327 /* run the plan --- the dest receiver will send tuples */
1329 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1330 }
1331
1332 cstate->routine->CopyToEnd(cstate);
1333
1335
1336 if (fe_copy)
1337 SendCopyEnd(cstate);
1338
1339 return processed;
1340}
uint64_t uint64
Definition c.h:625
static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
Definition copyto.c:1350
static void SendCopyBegin(CopyToState cstate)
Definition copyto.c:535
static void SendCopyEnd(CopyToState cstate)
Definition copyto.c:566
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:1390
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
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 747 of file copyto.c.

748{
749 if (cstate->is_program)
750 {
751 ClosePipeToProgram(cstate);
752 }
753 else
754 {
755 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
758 errmsg("could not close file \"%s\": %m",
759 cstate->filename)));
760 }
761
763
765
766 if (cstate->partitions)
767 list_free(cstate->partitions);
768
769 pfree(cstate);
770}
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 1238 of file copyto.c.

1239{
1240 if (cstate->queryDesc != NULL)
1241 {
1242 /* Close down the query and free resources. */
1243 ExecutorFinish(cstate->queryDesc);
1244 ExecutorEnd(cstate->queryDesc);
1245 FreeQueryDesc(cstate->queryDesc);
1247 }
1248
1249 /* Clean up storage */
1250 EndCopy(cstate);
1251}
static void EndCopy(CopyToState cstate)
Definition copyto.c:747
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 535 of file copyto.c.

536{
538 int natts = list_length(cstate->attnumlist);
539 int16 format = (cstate->opts.format == COPY_FORMAT_BINARY ? 1 : 0);
540 int i;
541
543 pq_sendbyte(&buf, format); /* overall format */
544 if (cstate->opts.format != COPY_FORMAT_JSON)
545 {
546 pq_sendint16(&buf, natts);
547 for (i = 0; i < natts; i++)
548 pq_sendint16(&buf, format); /* per-column formats */
549 }
550 else
551 {
552 /*
553 * For JSON format, report one text-format column. Each CopyData
554 * message contains one complete JSON object, not individual column
555 * values, so the per-column count is always 1.
556 */
557 pq_sendint16(&buf, 1);
558 pq_sendint16(&buf, 0);
559 }
560
562 cstate->copy_dest = COPY_FRONTEND;
563}
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 566 of file copyto.c.

567{
568 /* Shouldn't have any unsent data */
569 Assert(cstate->fe_msgbuf->len == 0);
570 /* Send Copy Done message */
572}
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:477
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:489
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:458
static void CopyToBinaryEnd(CopyToState cstate)
Definition copyto.c:522

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