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

1437 { \
1438 if (ptr > start) \
1439 CopySendData(cstate, start, ptr - start); \
1440 } 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 /*
1055 * Build a projected TupleDesc describing only the selected columns so
1056 * that composite_to_json() emits the right column names and types;
1057 * needed when an explicit column list was given (possibly with a
1058 * different column order) or when generated columns are excluded from
1059 * the output.
1060 */
1061 if (rel && (attnamelist != NIL ||
1062 list_length(cstate->attnumlist) < tupDesc->natts))
1063 {
1064 int natts = list_length(cstate->attnumlist);
1065 TupleDesc resultDesc;
1066
1067 resultDesc = CreateTemplateTupleDesc(natts);
1068
1069 foreach_int(attnum, cstate->attnumlist)
1070 {
1071 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1072
1073 TupleDescInitEntry(resultDesc,
1075 NameStr(attr->attname),
1076 attr->atttypid,
1077 attr->atttypmod,
1078 attr->attndims);
1079 }
1080
1081 TupleDescFinalize(resultDesc);
1082 cstate->tupDesc = BlessTupleDesc(resultDesc);
1083
1084 /*
1085 * Pre-allocate arrays for projecting selected column values into
1086 * sequential positions matching the custom TupleDesc.
1087 */
1088 cstate->json_projvalues = palloc_array(Datum, natts);
1089 cstate->json_projnulls = palloc_array(bool, natts);
1090 }
1091 }
1092
1093 num_phys_attrs = tupDesc->natts;
1094
1095 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
1096 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1097 if (cstate->opts.force_quote_all)
1098 {
1099 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
1100 }
1101 else if (cstate->opts.force_quote)
1102 {
1103 List *attnums;
1104 ListCell *cur;
1105
1106 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
1107
1108 foreach(cur, attnums)
1109 {
1110 int attnum = lfirst_int(cur);
1111 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1112
1113 if (!list_member_int(cstate->attnumlist, attnum))
1114 ereport(ERROR,
1116 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1117 errmsg("%s column \"%s\" not referenced by COPY",
1118 "FORCE_QUOTE", NameStr(attr->attname))));
1119 cstate->opts.force_quote_flags[attnum - 1] = true;
1120 }
1121 }
1122
1123 /* Use client encoding when ENCODING option is not specified. */
1124 if (cstate->opts.file_encoding < 0)
1126 else
1127 cstate->file_encoding = cstate->opts.file_encoding;
1128
1129 /*
1130 * Set up encoding conversion info if the file and server encodings differ
1131 * (see also pg_server_to_any).
1132 */
1133 if (cstate->file_encoding == GetDatabaseEncoding() ||
1134 cstate->file_encoding == PG_SQL_ASCII)
1135 cstate->need_transcoding = false;
1136 else
1137 cstate->need_transcoding = true;
1138
1139 /* See Multibyte encoding comment above */
1141
1142 cstate->copy_dest = COPY_FILE; /* default */
1143
1144 if (data_dest_cb)
1145 {
1147 cstate->copy_dest = COPY_CALLBACK;
1148 cstate->data_dest_cb = data_dest_cb;
1149 }
1150 else if (pipe)
1151 {
1153
1154 Assert(!is_program); /* the grammar does not allow this */
1156 cstate->copy_file = stdout;
1157 }
1158 else
1159 {
1160 cstate->filename = pstrdup(filename);
1161 cstate->is_program = is_program;
1162
1163 if (is_program)
1164 {
1166 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
1167 if (cstate->copy_file == NULL)
1168 ereport(ERROR,
1170 errmsg("could not execute command \"%s\": %m",
1171 cstate->filename)));
1172 }
1173 else
1174 {
1175 mode_t oumask; /* Pre-existing umask value */
1176 struct stat st;
1177
1179
1180 /*
1181 * Prevent write to relative path ... too easy to shoot oneself in
1182 * the foot by overwriting a database file ...
1183 */
1185 ereport(ERROR,
1187 errmsg("relative path not allowed for COPY to file")));
1188
1190 PG_TRY();
1191 {
1192 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
1193 }
1194 PG_FINALLY();
1195 {
1196 umask(oumask);
1197 }
1198 PG_END_TRY();
1199 if (cstate->copy_file == NULL)
1200 {
1201 /* copy errno because ereport subfunctions might change it */
1202 int save_errno = errno;
1203
1204 ereport(ERROR,
1206 errmsg("could not open file \"%s\" for writing: %m",
1207 cstate->filename),
1208 (save_errno == ENOENT || save_errno == EACCES) ?
1209 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1210 "You may want a client-side facility such as psql's \\copy.") : 0));
1211 }
1212
1213 if (fstat(fileno(cstate->copy_file), &st))
1214 ereport(ERROR,
1216 errmsg("could not stat file \"%s\": %m",
1217 cstate->filename)));
1218
1219 if (S_ISDIR(st.st_mode))
1220 ereport(ERROR,
1222 errmsg("\"%s\" is a directory", cstate->filename)));
1223 }
1224 }
1225
1226 /* initialize progress */
1228 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1230
1231 cstate->bytes_processed = 0;
1232
1233 MemoryContextSwitchTo(oldcontext);
1234
1235 return cstate;
1236}
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:894
#define Assert(condition)
Definition c.h:1002
int64_t int64
Definition c.h:680
#define PG_BINARY_W
Definition c.h:1448
#define MemSet(start, val, len)
Definition c.h:1166
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:162
@ CMD_MERGE
Definition nodes.h:277
@ CMD_INSERT
Definition nodes.h:275
@ CMD_DELETE
Definition nodes.h:276
@ CMD_UPDATE
Definition nodes.h:274
@ CMD_SELECT
Definition nodes.h:273
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:120
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:219
CmdType commandType
Definition parsenodes.h:124
Node * utilityStmt
Definition parsenodes.h:144
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 1722 of file copyto.c.

1723{
1724 pfree(self);
1725}
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 1694 of file copyto.c.

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

1714{
1715 /* no-op */
1716}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1685 of file copyto.c.

1686{
1687 /* no-op */
1688}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1596 of file copyto.c.

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

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

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

1419{
1420 MemoryContext oldcontext;
1421
1423 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1424
1425 /* Make sure the tuple is fully deconstructed */
1426 slot_getallattrs(slot);
1427
1428 cstate->routine->CopyToOneRow(cstate, slot);
1429
1430 MemoryContextSwitchTo(oldcontext);
1431}
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 1354 of file copyto.c.

1355{
1356 TupleTableSlot *slot;
1357 TableScanDesc scandesc;
1358 AttrMap *map = NULL;
1360
1361 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL,
1362 SO_NONE);
1363 slot = table_slot_create(rel, NULL);
1364
1365 /*
1366 * If we are exporting partition data here, we check if converting tuples
1367 * to the root table's rowtype, because a partition might have column
1368 * order different than its root table.
1369 */
1370 if (root_rel != NULL)
1371 {
1375 false);
1376 }
1377
1378 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1379 {
1380 TupleTableSlot *copyslot;
1381
1383
1384 if (map != NULL)
1385 copyslot = execute_attr_map_slot(map, slot, root_slot);
1386 else
1387 {
1388 /* Deconstruct the tuple */
1389 slot_getallattrs(slot);
1390 copyslot = slot;
1391 }
1392
1393 /* Format and send the data */
1394 CopyOneRowTo(cstate, copyslot);
1395
1396 /*
1397 * Increment the number of processed tuples, and report the progress.
1398 */
1400 ++(*processed));
1401 }
1402
1404
1405 if (root_slot != NULL)
1407
1408 if (map != NULL)
1409 free_attrmap(map);
1410
1411 table_endscan(scandesc);
1412}
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:682
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:683
#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:840
static void CopySendInt32(CopyToState cstate, int32 val)
Definition copyto.c:698
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1745
static struct @175 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:835
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:679
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:1596
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition copyto.c:1443
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 1731 of file copyto.c.

1732{
1733 DR_copy *self = palloc_object(DR_copy);
1734
1739 self->pub.mydest = DestCopyOut;
1740
1741 self->cstate = NULL; /* will be set later */
1742 self->processed = 0;
1743
1744 return (DestReceiver *) self;
1745}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1694
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1722
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1713
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1685
#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 1263 of file copyto.c.

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

1243{
1244 if (cstate->queryDesc != NULL)
1245 {
1246 /* Close down the query and free resources. */
1247 ExecutorFinish(cstate->queryDesc);
1248 ExecutorEnd(cstate->queryDesc);
1249 FreeQueryDesc(cstate->queryDesc);
1251 }
1252
1253 /* Clean up storage */
1254 EndCopy(cstate);
1255}
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:678
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().