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 "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 "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "tcop/tcopprot.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/snapmgr.h"
Include dependency graph for copyto.c:

Go to the source code of this file.

Data Structures

struct  CopyToStateData
 
struct  DR_copy
 

Macros

#define DUMPSOFAR()
 

Typedefs

typedef enum CopyDest CopyDest
 
typedef struct CopyToStateData CopyToStateData
 

Enumerations

enum  CopyDest { COPY_FILE , COPY_FRONTEND , COPY_CALLBACK }
 

Functions

static void EndCopy (CopyToState cstate)
 
static void ClosePipeToProgram (CopyToState cstate)
 
static void CopyOneRowTo (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyAttributeOutText (CopyToState cstate, const char *string)
 
static void CopyAttributeOutCSV (CopyToState cstate, const char *string, bool use_quote)
 
static void 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 CopyToBinaryStart (CopyToState cstate, TupleDesc tupDesc)
 
static void CopyToBinaryOutFunc (CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
 
static void CopyToBinaryOneRow (CopyToState cstate, TupleTableSlot *slot)
 
static void CopyToBinaryEnd (CopyToState cstate)
 
static void SendCopyBegin (CopyToState cstate)
 
static void SendCopyEnd (CopyToState cstate)
 
static void CopySendData (CopyToState cstate, const void *databuf, int datasize)
 
static void CopySendString (CopyToState cstate, const char *str)
 
static void CopySendChar (CopyToState cstate, char c)
 
static void CopySendEndOfRow (CopyToState cstate)
 
static void CopySendTextLikeEndOfRow (CopyToState cstate)
 
static void CopySendInt32 (CopyToState cstate, int32 val)
 
static void CopySendInt16 (CopyToState cstate, int16 val)
 
static const CopyToRoutineCopyToGetRoutine (const CopyFormatOptions *opts)
 
CopyToState BeginCopyTo (ParseState *pstate, Relation rel, RawStmt *raw_query, Oid queryRelId, const char *filename, bool is_program, copy_data_dest_cb data_dest_cb, List *attnamelist, List *options)
 
void EndCopyTo (CopyToState cstate)
 
uint64 DoCopyTo (CopyToState cstate)
 
static void copy_dest_startup (DestReceiver *self, int operation, TupleDesc typeinfo)
 
static bool copy_dest_receive (TupleTableSlot *slot, DestReceiver *self)
 
static void copy_dest_shutdown (DestReceiver *self)
 
static void copy_dest_destroy (DestReceiver *self)
 
DestReceiverCreateCopyDestReceiver (void)
 

Variables

static const char BinarySignature [11] = "PGCOPY\n\377\r\n\0"
 
static const CopyToRoutine CopyToRoutineText
 
static const CopyToRoutine CopyToRoutineCSV
 
static const CopyToRoutine CopyToRoutineBinary
 

Macro Definition Documentation

◆ DUMPSOFAR

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

Definition at line 1233 of file copyto.c.

1234 { \
1235 if (ptr > start) \
1236 CopySendData(cstate, start, ptr - start); \
1237 } while (0)

Typedef Documentation

◆ CopyDest

◆ CopyToStateData

Enumeration Type Documentation

◆ CopyDest

Enumerator
COPY_FILE 
COPY_FRONTEND 
COPY_CALLBACK 

Definition at line 45 of file copyto.c.

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

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

641{
642 CopyToState cstate;
643 bool pipe = (filename == NULL && data_dest_cb == NULL);
644 TupleDesc tupDesc;
645 int num_phys_attrs;
646 MemoryContext oldcontext;
647 const int progress_cols[] = {
650 };
651 int64 progress_vals[] = {
653 0
654 };
655 List *children = NIL;
656
657 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
658 {
659 if (rel->rd_rel->relkind == RELKIND_VIEW)
662 errmsg("cannot copy from view \"%s\"",
664 errhint("Try the COPY (SELECT ...) TO variant.")));
665 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
666 {
667 if (!RelationIsPopulated(rel))
670 errmsg("cannot copy from unpopulated materialized view \"%s\"",
672 errhint("Use the REFRESH MATERIALIZED VIEW command."));
673 }
674 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
677 errmsg("cannot copy from foreign table \"%s\"",
679 errhint("Try the COPY (SELECT ...) TO variant.")));
680 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
683 errmsg("cannot copy from sequence \"%s\"",
685 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
686 {
687 /*
688 * Collect OIDs of relation containing data, so that later
689 * DoCopyTo can copy the data from them.
690 */
692
693 foreach_oid(child, children)
694 {
695 char relkind = get_rel_relkind(child);
696
697 if (relkind == RELKIND_FOREIGN_TABLE)
698 {
699 char *relation_name = get_rel_name(child);
700
703 errmsg("cannot copy from foreign table \"%s\"", relation_name),
704 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
705 relation_name, RelationGetRelationName(rel)),
706 errhint("Try the COPY (SELECT ...) TO variant."));
707 }
708
709 /* Exclude tables with no data */
710 if (RELKIND_HAS_PARTITIONS(relkind))
711 children = foreach_delete_current(children, child);
712 }
713 }
714 else
717 errmsg("cannot copy from non-table relation \"%s\"",
719 }
720
721
722 /* Allocate workspace and zero all fields */
724
725 /*
726 * We allocate everything used by a cstate in a new memory context. This
727 * avoids memory leaks during repeated use of COPY in a query.
728 */
730 "COPY",
732
733 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
734
735 /* Extract options from the statement node tree */
736 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
737
738 /* Set format routine */
739 cstate->routine = CopyToGetRoutine(&cstate->opts);
740
741 /* Process the source/target relation or query */
742 if (rel)
743 {
745
746 cstate->rel = rel;
747
748 tupDesc = RelationGetDescr(cstate->rel);
749 cstate->partitions = children;
750 }
751 else
752 {
754 Query *query;
757
758 cstate->rel = NULL;
759 cstate->partitions = NIL;
760
761 /*
762 * Run parse analysis and rewrite. Note this also acquires sufficient
763 * locks on the source table(s).
764 */
766 pstate->p_sourcetext, NULL, 0,
767 NULL);
768
769 /* check that we got back something we can work with */
770 if (rewritten == NIL)
771 {
774 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
775 }
776 else if (list_length(rewritten) > 1)
777 {
778 ListCell *lc;
779
780 /* examine queries to determine which error message to issue */
781 foreach(lc, rewritten)
782 {
783 Query *q = lfirst_node(Query, lc);
784
785 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
788 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
789 if (q->querySource == QSRC_NON_INSTEAD_RULE)
792 errmsg("DO ALSO rules are not supported for COPY")));
793 }
794
797 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
798 }
799
800 query = linitial_node(Query, rewritten);
801
802 /* The grammar allows SELECT INTO, but we don't support that */
803 if (query->utilityStmt != NULL &&
807 errmsg("COPY (SELECT INTO) is not supported")));
808
809 /* The only other utility command we could see is NOTIFY */
810 if (query->utilityStmt != NULL)
813 errmsg("COPY query must not be a utility command")));
814
815 /*
816 * Similarly the grammar doesn't enforce the presence of a RETURNING
817 * clause, but this is required here.
818 */
819 if (query->commandType != CMD_SELECT &&
820 query->returningList == NIL)
821 {
822 Assert(query->commandType == CMD_INSERT ||
823 query->commandType == CMD_UPDATE ||
824 query->commandType == CMD_DELETE ||
825 query->commandType == CMD_MERGE);
826
829 errmsg("COPY query must have a RETURNING clause")));
830 }
831
832 /* plan the query */
833 plan = pg_plan_query(query, pstate->p_sourcetext,
835
836 /*
837 * With row-level security and a user using "COPY relation TO", we
838 * have to convert the "COPY relation TO" to a query-based COPY (eg:
839 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
840 * add in any RLS clauses.
841 *
842 * When this happens, we are passed in the relid of the originally
843 * found relation (which we have locked). As the planner will look up
844 * the relation again, we double-check here to make sure it found the
845 * same one that we have locked.
846 */
847 if (queryRelId != InvalidOid)
848 {
849 /*
850 * Note that with RLS involved there may be multiple relations,
851 * and while the one we need is almost certainly first, we don't
852 * make any guarantees of that in the planner, so check the whole
853 * list and make sure we find the original relation.
854 */
855 if (!list_member_oid(plan->relationOids, queryRelId))
858 errmsg("relation referenced by COPY statement has changed")));
859 }
860
861 /*
862 * Use a snapshot with an updated command ID to ensure this query sees
863 * results of any previously executed queries.
864 */
867
868 /* Create dest receiver for COPY OUT */
870 ((DR_copy *) dest)->cstate = cstate;
871
872 /* Create a QueryDesc requesting no output */
873 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
876 dest, NULL, NULL, 0);
877
878 /*
879 * Call ExecutorStart to prepare the plan for execution.
880 *
881 * ExecutorStart computes a result tupdesc for us
882 */
883 ExecutorStart(cstate->queryDesc, 0);
884
885 tupDesc = cstate->queryDesc->tupDesc;
886 }
887
888 /* Generate or convert list of attributes to process */
889 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
890
891 num_phys_attrs = tupDesc->natts;
892
893 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
894 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
895 if (cstate->opts.force_quote_all)
896 {
897 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
898 }
899 else if (cstate->opts.force_quote)
900 {
901 List *attnums;
902 ListCell *cur;
903
904 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
905
906 foreach(cur, attnums)
907 {
908 int attnum = lfirst_int(cur);
909 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
910
911 if (!list_member_int(cstate->attnumlist, attnum))
914 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
915 errmsg("%s column \"%s\" not referenced by COPY",
916 "FORCE_QUOTE", NameStr(attr->attname))));
917 cstate->opts.force_quote_flags[attnum - 1] = true;
918 }
919 }
920
921 /* Use client encoding when ENCODING option is not specified. */
922 if (cstate->opts.file_encoding < 0)
924 else
925 cstate->file_encoding = cstate->opts.file_encoding;
926
927 /*
928 * Set up encoding conversion info if the file and server encodings differ
929 * (see also pg_server_to_any).
930 */
931 if (cstate->file_encoding == GetDatabaseEncoding() ||
932 cstate->file_encoding == PG_SQL_ASCII)
933 cstate->need_transcoding = false;
934 else
935 cstate->need_transcoding = true;
936
937 /* See Multibyte encoding comment above */
939
940 cstate->copy_dest = COPY_FILE; /* default */
941
942 if (data_dest_cb)
943 {
945 cstate->copy_dest = COPY_CALLBACK;
946 cstate->data_dest_cb = data_dest_cb;
947 }
948 else if (pipe)
949 {
951
952 Assert(!is_program); /* the grammar does not allow this */
954 cstate->copy_file = stdout;
955 }
956 else
957 {
958 cstate->filename = pstrdup(filename);
959 cstate->is_program = is_program;
960
961 if (is_program)
962 {
964 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
965 if (cstate->copy_file == NULL)
968 errmsg("could not execute command \"%s\": %m",
969 cstate->filename)));
970 }
971 else
972 {
973 mode_t oumask; /* Pre-existing umask value */
974 struct stat st;
975
977
978 /*
979 * Prevent write to relative path ... too easy to shoot oneself in
980 * the foot by overwriting a database file ...
981 */
985 errmsg("relative path not allowed for COPY to file")));
986
988 PG_TRY();
989 {
990 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
991 }
992 PG_FINALLY();
993 {
994 umask(oumask);
995 }
996 PG_END_TRY();
997 if (cstate->copy_file == NULL)
998 {
999 /* copy errno because ereport subfunctions might change it */
1000 int save_errno = errno;
1001
1002 ereport(ERROR,
1004 errmsg("could not open file \"%s\" for writing: %m",
1005 cstate->filename),
1006 (save_errno == ENOENT || save_errno == EACCES) ?
1007 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1008 "You may want a client-side facility such as psql's \\copy.") : 0));
1009 }
1010
1011 if (fstat(fileno(cstate->copy_file), &st))
1012 ereport(ERROR,
1014 errmsg("could not stat file \"%s\": %m",
1015 cstate->filename)));
1016
1017 if (S_ISDIR(st.st_mode))
1018 ereport(ERROR,
1020 errmsg("\"%s\" is a directory", cstate->filename)));
1021 }
1022 }
1023
1024 /* initialize progress */
1026 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1028
1029 cstate->bytes_processed = 0;
1030
1031 MemoryContextSwitchTo(oldcontext);
1032
1033 return cstate;
1034}
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition copy.c:1011
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition copy.c:562
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:765
#define Assert(condition)
Definition c.h:873
int64_t int64
Definition c.h:543
#define PG_BINARY_W
Definition c.h:1290
#define MemSet(start, val, len)
Definition c.h:1013
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition copyto.c:182
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:886
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define PG_TRY(...)
Definition elog.h:372
#define PG_END_TRY(...)
Definition elog.h:397
#define ERROR
Definition elog.h:39
#define PG_FINALLY(...)
Definition elog.h:389
#define ereport(elevel,...)
Definition elog.h:150
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition execMain.c:122
FILE * OpenPipeStream(const char *command, const char *mode)
Definition fd.c:2727
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2624
#define palloc0_object(type)
Definition fe_memutils.h:75
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:2078
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2153
int GetDatabaseEncoding(void)
Definition mbutils.c:1264
int pg_get_client_encoding(void)
Definition mbutils.c:337
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * palloc0(Size size)
Definition mcxt.c:1417
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define IsA(nodeptr, _type_)
Definition nodes.h:164
@ CMD_MERGE
Definition nodes.h:279
@ CMD_INSERT
Definition nodes.h:277
@ CMD_DELETE
Definition nodes.h:278
@ CMD_UPDATE
Definition nodes.h:276
@ CMD_SELECT
Definition nodes.h:275
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
@ QSRC_NON_INSTEAD_RULE
Definition parsenodes.h:40
@ QSRC_QUAL_INSTEAD_RULE
Definition parsenodes.h:39
#define CURSOR_OPT_PARALLEL_OK
int16 attnum
FormData_pg_attribute * Form_pg_attribute
static char * filename
Definition pg_dumpall.c: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 lfirst_int(lc)
Definition pg_list.h:173
#define foreach_delete_current(lst, var_or_cell)
Definition pg_list.h:391
#define foreach_oid(var, lst)
Definition pg_list.h:471
#define plan(x)
Definition pg_regress.c:161
@ PG_SQL_ASCII
Definition pg_wchar.h:226
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition pg_wchar.h:284
#define is_absolute_path(filename)
Definition port.h:104
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition postgres.c:887
CommandDest whereToSendOutput
Definition postgres.c:92
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition postgres.c:670
#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:168
#define PROGRESS_COPY_TYPE_FILE
Definition progress.h:177
#define PROGRESS_COPY_COMMAND_TO
Definition progress.h:174
#define PROGRESS_COPY_TYPE
Definition progress.h:169
#define PROGRESS_COPY_TYPE_PROGRAM
Definition progress.h:178
#define PROGRESS_COPY_TYPE_CALLBACK
Definition progress.h:180
#define PROGRESS_COPY_TYPE_PIPE
Definition progress.h:179
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationGetDescr(relation)
Definition rel.h:540
#define RelationGetRelationName(relation)
Definition rel.h:548
#define RelationIsPopulated(relation)
Definition rel.h:686
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
bool force_quote_all
Definition copy.h:75
List * force_quote
Definition copy.h:74
bool * force_quote_flags
Definition copy.h:76
int file_encoding
Definition copy.h:59
MemoryContext copycontext
Definition copyto.c:96
Relation rel
Definition copyto.c:82
const CopyToRoutine * routine
Definition copyto.c:70
copy_data_dest_cb data_dest_cb
Definition copyto.c:87
bool encoding_embeds_ascii
Definition copyto.c:79
CopyDest copy_dest
Definition copyto.c:73
bool need_transcoding
Definition copyto.c:78
bool is_program
Definition copyto.c:86
FILE * copy_file
Definition copyto.c:74
int file_encoding
Definition copyto.c:77
CopyFormatOptions opts
Definition copyto.c:89
uint64 bytes_processed
Definition copyto.c:100
char * filename
Definition copyto.c:85
List * attnumlist
Definition copyto.c:84
QueryDesc * queryDesc
Definition copyto.c:83
List * partitions
Definition copyto.c:91
Definition pg_list.h:54
const char * p_sourcetext
Definition parse_node.h:195
TupleDesc tupDesc
Definition execdesc.h:47
List * returningList
Definition parsenodes.h:214
CmdType commandType
Definition parsenodes.h:121
Node * utilityStmt
Definition parsenodes.h:141
Form_pg_class rd_rel
Definition rel.h:111
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:160
#define S_IWOTH
Definition win32_port.h:306
#define S_ISDIR(m)
Definition win32_port.h:315
#define fstat
Definition win32_port.h:73
#define S_IWGRP
Definition win32_port.h:294

References AccessShareLock, AllocateFile(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, attnum, CopyToStateData::attnumlist, CopyToStateData::bytes_processed, CMD_DELETE, CMD_INSERT, CMD_MERGE, CMD_SELECT, CMD_UPDATE, Query::commandType, COPY_CALLBACK, CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, CopyToStateData::copycontext, CopyGetAttnums(), CopyToGetRoutine(), CreateDestReceiver(), CreateQueryDesc(), cur, CurrentMemoryContext, CURSOR_OPT_PARALLEL_OK, CopyToStateData::data_dest_cb, 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_delete_current, foreach_oid, fstat, get_rel_name(), get_rel_relkind(), GetActiveSnapshot(), GetDatabaseEncoding(), InvalidOid, InvalidSnapshot, is_absolute_path, CopyToStateData::is_program, IsA, lfirst_int, lfirst_node, linitial_node, list_length(), list_member_int(), list_member_oid(), MemoryContextSwitchTo(), MemSet, NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, NIL, OpenPipeStream(), CopyToStateData::opts, ParseState::p_sourcetext, palloc0(), palloc0_object, 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, QueryDesc::tupDesc, TupleDescAttr(), UpdateActiveSnapshotCommandId(), Query::utilityStmt, and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ ClosePipeToProgram()

static void ClosePipeToProgram ( CopyToState  cstate)
static

Definition at line 567 of file copyto.c.

568{
569 int pclose_rc;
570
571 Assert(cstate->is_program);
572
574 if (pclose_rc == -1)
577 errmsg("could not close pipe to external command: %m")));
578 else if (pclose_rc != 0)
579 {
582 errmsg("program \"%s\" failed",
583 cstate->filename),
585 }
586}
int errdetail_internal(const char *fmt,...)
Definition elog.c:1243
int ClosePipeStream(FILE *file)
Definition fd.c:3035
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 1519 of file copyto.c.

1520{
1521 pfree(self);
1522}
void pfree(void *pointer)
Definition mcxt.c:1616

References pfree().

Referenced by CreateCopyDestReceiver().

◆ copy_dest_receive()

static bool copy_dest_receive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 1491 of file copyto.c.

1492{
1493 DR_copy *myState = (DR_copy *) self;
1494 CopyToState cstate = myState->cstate;
1495
1496 /* Send the data */
1497 CopyOneRowTo(cstate, slot);
1498
1499 /* Increment the number of processed tuples, and report the progress */
1501 ++myState->processed);
1502
1503 return true;
1504}
void pgstat_progress_update_param(int index, int64 val)
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:1215
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition progress.h:166

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

1511{
1512 /* no-op */
1513}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1482 of file copyto.c.

1483{
1484 /* no-op */
1485}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1393 of file copyto.c.

1395{
1396 const char *ptr;
1397 const char *start;
1398 char c;
1399 char delimc = cstate->opts.delim[0];
1400 char quotec = cstate->opts.quote[0];
1401 char escapec = cstate->opts.escape[0];
1402 bool single_attr = (list_length(cstate->attnumlist) == 1);
1403
1404 /* force quoting if it matches null_print (before conversion!) */
1405 if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1406 use_quote = true;
1407
1408 if (cstate->need_transcoding)
1409 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1410 else
1411 ptr = string;
1412
1413 /*
1414 * Make a preliminary pass to discover if it needs quoting
1415 */
1416 if (!use_quote)
1417 {
1418 /*
1419 * Quote '\.' if it appears alone on a line, so that it will not be
1420 * interpreted as an end-of-data marker. (PG 18 and up will not
1421 * interpret '\.' in CSV that way, except in embedded-in-SQL data; but
1422 * we want the data to be loadable by older versions too. Also, this
1423 * avoids breaking clients that are still using PQgetline().)
1424 */
1425 if (single_attr && strcmp(ptr, "\\.") == 0)
1426 use_quote = true;
1427 else
1428 {
1429 const char *tptr = ptr;
1430
1431 while ((c = *tptr) != '\0')
1432 {
1433 if (c == delimc || c == quotec || c == '\n' || c == '\r')
1434 {
1435 use_quote = true;
1436 break;
1437 }
1438 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1440 else
1441 tptr++;
1442 }
1443 }
1444 }
1445
1446 if (use_quote)
1447 {
1448 CopySendChar(cstate, quotec);
1449
1450 /*
1451 * We adopt the same optimization strategy as in CopyAttributeOutText
1452 */
1453 start = ptr;
1454 while ((c = *ptr) != '\0')
1455 {
1456 if (c == quotec || c == escapec)
1457 {
1458 DUMPSOFAR();
1459 CopySendChar(cstate, escapec);
1460 start = ptr; /* we include char in next run */
1461 }
1462 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1463 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1464 else
1465 ptr++;
1466 }
1467 DUMPSOFAR();
1468
1469 CopySendChar(cstate, quotec);
1470 }
1471 else
1472 {
1473 /* If it doesn't need quoting, we can just dump it as-is */
1474 CopySendString(cstate, ptr);
1475 }
1476}
#define IS_HIGHBIT_SET(ch)
Definition c.h:1150
#define DUMPSOFAR()
Definition copyto.c:1233
static void CopySendChar(CopyToState cstate, char c)
Definition copyto.c:444
static void CopySendString(CopyToState cstate, const char *str)
Definition copyto.c:438
char * pg_server_to_any(const char *s, int len, int encoding)
Definition mbutils.c:752
char * c
char string[11]
char * quote
Definition copy.h:72
char * escape
Definition copy.h:73
char * null_print
Definition copy.h:66
char * delim
Definition copy.h:71
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition wchar.c:2135

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

1241{
1242 const char *ptr;
1243 const char *start;
1244 char c;
1245 char delimc = cstate->opts.delim[0];
1246
1247 if (cstate->need_transcoding)
1248 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1249 else
1250 ptr = string;
1251
1252 /*
1253 * We have to grovel through the string searching for control characters
1254 * and instances of the delimiter character. In most cases, though, these
1255 * are infrequent. To avoid overhead from calling CopySendData once per
1256 * character, we dump out all characters between escaped characters in a
1257 * single call. The loop invariant is that the data from "start" to "ptr"
1258 * can be sent literally, but hasn't yet been.
1259 *
1260 * We can skip pg_encoding_mblen() overhead when encoding is safe, because
1261 * in valid backend encodings, extra bytes of a multibyte character never
1262 * look like ASCII. This loop is sufficiently performance-critical that
1263 * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
1264 * of the normal safe-encoding path.
1265 */
1266 if (cstate->encoding_embeds_ascii)
1267 {
1268 start = ptr;
1269 while ((c = *ptr) != '\0')
1270 {
1271 if ((unsigned char) c < (unsigned char) 0x20)
1272 {
1273 /*
1274 * \r and \n must be escaped, the others are traditional. We
1275 * prefer to dump these using the C-like notation, rather than
1276 * a backslash and the literal character, because it makes the
1277 * dump file a bit more proof against Microsoftish data
1278 * mangling.
1279 */
1280 switch (c)
1281 {
1282 case '\b':
1283 c = 'b';
1284 break;
1285 case '\f':
1286 c = 'f';
1287 break;
1288 case '\n':
1289 c = 'n';
1290 break;
1291 case '\r':
1292 c = 'r';
1293 break;
1294 case '\t':
1295 c = 't';
1296 break;
1297 case '\v':
1298 c = 'v';
1299 break;
1300 default:
1301 /* If it's the delimiter, must backslash it */
1302 if (c == delimc)
1303 break;
1304 /* All ASCII control chars are length 1 */
1305 ptr++;
1306 continue; /* fall to end of loop */
1307 }
1308 /* if we get here, we need to convert the control char */
1309 DUMPSOFAR();
1310 CopySendChar(cstate, '\\');
1311 CopySendChar(cstate, c);
1312 start = ++ptr; /* do not include char in next run */
1313 }
1314 else if (c == '\\' || c == delimc)
1315 {
1316 DUMPSOFAR();
1317 CopySendChar(cstate, '\\');
1318 start = ptr++; /* we include char in next run */
1319 }
1320 else if (IS_HIGHBIT_SET(c))
1321 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1322 else
1323 ptr++;
1324 }
1325 }
1326 else
1327 {
1328 start = ptr;
1329 while ((c = *ptr) != '\0')
1330 {
1331 if ((unsigned char) c < (unsigned char) 0x20)
1332 {
1333 /*
1334 * \r and \n must be escaped, the others are traditional. We
1335 * prefer to dump these using the C-like notation, rather than
1336 * a backslash and the literal character, because it makes the
1337 * dump file a bit more proof against Microsoftish data
1338 * mangling.
1339 */
1340 switch (c)
1341 {
1342 case '\b':
1343 c = 'b';
1344 break;
1345 case '\f':
1346 c = 'f';
1347 break;
1348 case '\n':
1349 c = 'n';
1350 break;
1351 case '\r':
1352 c = 'r';
1353 break;
1354 case '\t':
1355 c = 't';
1356 break;
1357 case '\v':
1358 c = 'v';
1359 break;
1360 default:
1361 /* If it's the delimiter, must backslash it */
1362 if (c == delimc)
1363 break;
1364 /* All ASCII control chars are length 1 */
1365 ptr++;
1366 continue; /* fall to end of loop */
1367 }
1368 /* if we get here, we need to convert the control char */
1369 DUMPSOFAR();
1370 CopySendChar(cstate, '\\');
1371 CopySendChar(cstate, c);
1372 start = ++ptr; /* do not include char in next run */
1373 }
1374 else if (c == '\\' || c == delimc)
1375 {
1376 DUMPSOFAR();
1377 CopySendChar(cstate, '\\');
1378 start = ptr++; /* we include char in next run */
1379 }
1380 else
1381 ptr++;
1382 }
1383 }
1384
1385 DUMPSOFAR();
1386}

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

1216{
1217 MemoryContext oldcontext;
1218
1220 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1221
1222 /* Make sure the tuple is fully deconstructed */
1223 slot_getallattrs(slot);
1224
1225 cstate->routine->CopyToOneRow(cstate, slot);
1226
1227 MemoryContextSwitchTo(oldcontext);
1228}
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
void(* CopyToOneRow)(CopyToState cstate, TupleTableSlot *slot)
Definition copyapi.h:49
MemoryContext rowcontext
Definition copyto.c:99
static void slot_getallattrs(TupleTableSlot *slot)
Definition tuptable.h:371

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

1153{
1154 TupleTableSlot *slot;
1155 TableScanDesc scandesc;
1156 AttrMap *map = NULL;
1158
1159 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL);
1160 slot = table_slot_create(rel, NULL);
1161
1162 /*
1163 * If we are exporting partition data here, we check if converting tuples
1164 * to the root table's rowtype, because a partition might have column
1165 * order different than its root table.
1166 */
1167 if (root_rel != NULL)
1168 {
1171 RelationGetDescr(rel),
1172 false);
1173 }
1174
1175 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1176 {
1177 TupleTableSlot *copyslot;
1178
1180
1181 if (map != NULL)
1182 copyslot = execute_attr_map_slot(map, slot, root_slot);
1183 else
1184 {
1185 /* Deconstruct the tuple */
1186 slot_getallattrs(slot);
1187 copyslot = slot;
1188 }
1189
1190 /* Format and send the data */
1191 CopyOneRowTo(cstate, copyslot);
1192
1193 /*
1194 * Increment the number of processed tuples, and report the progress.
1195 */
1197 ++(*processed));
1198 }
1199
1201
1202 if (root_slot != NULL)
1204
1205 if (map != NULL)
1206 free_attrmap(map);
1207
1208 table_endscan(scandesc);
1209}
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:123
@ ForwardScanDirection
Definition sdir.h:28
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1005
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:1040
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key)
Definition tableam.h:897
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(), table_beginscan(), table_endscan(), table_scan_getnextslot(), and table_slot_create().

Referenced by DoCopyTo().

◆ CopySendChar()

static void CopySendChar ( CopyToState  cstate,
char  c 
)
static

Definition at line 444 of file copyto.c.

445{
447}
#define appendStringInfoCharMacro(str, ch)
Definition stringinfo.h:231
StringInfo fe_msgbuf
Definition copyto.c:75

References appendStringInfoCharMacro, and CopyToStateData::fe_msgbuf.

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

◆ CopySendData()

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

Definition at line 432 of file copyto.c.

433{
435}
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(), and CopyToBinaryStart().

◆ CopySendEndOfRow()

static void CopySendEndOfRow ( CopyToState  cstate)
static

Definition at line 450 of file copyto.c.

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

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

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

◆ CopySendInt16()

static void CopySendInt16 ( CopyToState  cstate,
int16  val 
)
inlinestatic

Definition at line 555 of file copyto.c.

556{
557 uint16 buf;
558
559 buf = pg_hton16((uint16) val);
560 CopySendData(cstate, &buf, sizeof(buf));
561}
uint16_t uint16
Definition c.h:545
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition copyto.c:432
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 543 of file copyto.c.

544{
545 uint32 buf;
546
547 buf = pg_hton32((uint32) val);
548 CopySendData(cstate, &buf, sizeof(buf));
549}
uint32_t uint32
Definition c.h:546
#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 438 of file copyto.c.

439{
441}
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 511 of file copyto.c.

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

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

Referenced by CopyToTextLikeOneRow(), and CopyToTextLikeStart().

◆ CopyToBinaryEnd()

static void CopyToBinaryEnd ( CopyToState  cstate)
static

Definition at line 383 of file copyto.c.

384{
385 /* Generate trailer for a binary copy */
386 CopySendInt16(cstate, -1);
387 /* Need to flush out the trailer */
388 CopySendEndOfRow(cstate);
389}
static void CopySendInt16(CopyToState cstate, int16 val)
Definition copyto.c:555

References CopySendEndOfRow(), and CopySendInt16().

◆ CopyToBinaryOneRow()

static void CopyToBinaryOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 350 of file copyto.c.

351{
352 FmgrInfo *out_functions = cstate->out_functions;
353
354 /* Binary per-tuple header */
355 CopySendInt16(cstate, list_length(cstate->attnumlist));
356
358 {
359 Datum value = slot->tts_values[attnum - 1];
360 bool isnull = slot->tts_isnull[attnum - 1];
361
362 if (isnull)
363 {
364 CopySendInt32(cstate, -1);
365 }
366 else
367 {
369
370 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
371 value);
375 }
376 }
377
378 CopySendEndOfRow(cstate);
379}
#define VARHDRSZ
Definition c.h:711
static void CopySendInt32(CopyToState cstate, int32 val)
Definition copyto.c:543
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1744
static struct @172 value
#define foreach_int(var, lst)
Definition pg_list.h:470
uint64_t Datum
Definition postgres.h:70
FmgrInfo * out_functions
Definition copyto.c:98
bool * tts_isnull
Definition tuptable.h:126
Datum * tts_values
Definition tuptable.h:124
Definition c.h:706
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 338 of file copyto.c.

339{
341 bool is_varlena;
342
343 /* Set output function for an attribute */
345 fmgr_info(func_oid, finfo);
346}
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:128
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition lsyscache.c:3123
unsigned int Oid

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

◆ CopyToBinaryStart()

static void CopyToBinaryStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 319 of file copyto.c.

320{
321 int32 tmp;
322
323 /* Signature */
324 CopySendData(cstate, BinarySignature, 11);
325 /* Flags field */
326 tmp = 0;
327 CopySendInt32(cstate, tmp);
328 /* No header extension */
329 tmp = 0;
330 CopySendInt32(cstate, tmp);
331}
int32_t int32
Definition c.h:542
static const char BinarySignature[11]
Definition copyto.c:112

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

◆ CopyToCSVOneRow()

static void CopyToCSVOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 257 of file copyto.c.

258{
259 CopyToTextLikeOneRow(cstate, slot, true);
260}
static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv)
Definition copyto.c:269

References CopyToTextLikeOneRow().

◆ CopyToGetRoutine()

static const CopyToRoutine * CopyToGetRoutine ( const CopyFormatOptions opts)
static

Definition at line 182 of file copyto.c.

183{
184 if (opts->csv_mode)
185 return &CopyToRoutineCSV;
186 else if (opts->binary)
187 return &CopyToRoutineBinary;
188
189 /* default is text */
190 return &CopyToRoutineText;
191}
static const CopyToRoutine CopyToRoutineCSV
Definition copyto.c:165
static const CopyToRoutine CopyToRoutineText
Definition copyto.c:157
static const CopyToRoutine CopyToRoutineBinary
Definition copyto.c:173
static AmcheckOptions opts
Definition pg_amcheck.c:112

References CopyToRoutineBinary, CopyToRoutineCSV, CopyToRoutineText, and opts.

Referenced by BeginCopyTo().

◆ CopyToTextLikeEnd()

static void CopyToTextLikeEnd ( CopyToState  cstate)
static

Definition at line 309 of file copyto.c.

310{
311 /* Nothing to do here */
312}

◆ CopyToTextLikeOneRow()

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

Definition at line 269 of file copyto.c.

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

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

239{
241 bool is_varlena;
242
243 /* Set output function for an attribute */
245 fmgr_info(func_oid, finfo);
246}
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3057

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

◆ CopyToTextLikeStart()

static void CopyToTextLikeStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 195 of file copyto.c.

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

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

◆ CopyToTextOneRow()

static void CopyToTextOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 250 of file copyto.c.

251{
252 CopyToTextLikeOneRow(cstate, slot, false);
253}

References CopyToTextLikeOneRow().

◆ CreateCopyDestReceiver()

DestReceiver * CreateCopyDestReceiver ( void  )

Definition at line 1528 of file copyto.c.

1529{
1530 DR_copy *self = palloc_object(DR_copy);
1531
1536 self->pub.mydest = DestCopyOut;
1537
1538 self->cstate = NULL; /* will be set later */
1539 self->processed = 0;
1540
1541 return (DestReceiver *) self;
1542}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1491
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1519
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1510
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1482
#define palloc_object(type)
Definition fe_memutils.h:74
CopyToState cstate
Definition copyto.c:107
DestReceiver pub
Definition copyto.c:106
uint64 processed
Definition copyto.c:108
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 1061 of file copyto.c.

1062{
1063 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1064 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1065 TupleDesc tupDesc;
1066 int num_phys_attrs;
1067 ListCell *cur;
1068 uint64 processed = 0;
1069
1070 if (fe_copy)
1071 SendCopyBegin(cstate);
1072
1073 if (cstate->rel)
1074 tupDesc = RelationGetDescr(cstate->rel);
1075 else
1076 tupDesc = cstate->queryDesc->tupDesc;
1077 num_phys_attrs = tupDesc->natts;
1078 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1079
1080 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1081 cstate->fe_msgbuf = makeStringInfo();
1082
1083 /* Get info about the columns we need to process. */
1084 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1085 foreach(cur, cstate->attnumlist)
1086 {
1087 int attnum = lfirst_int(cur);
1088 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1089
1090 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1091 &cstate->out_functions[attnum - 1]);
1092 }
1093
1094 /*
1095 * Create a temporary memory context that we can reset once per row to
1096 * recover palloc'd memory. This avoids any problems with leaks inside
1097 * datatype output routines, and should be faster than retail pfree's
1098 * anyway. (We don't need a whole econtext as CopyFrom does.)
1099 */
1101 "COPY TO",
1103
1104 cstate->routine->CopyToStart(cstate, tupDesc);
1105
1106 if (cstate->rel)
1107 {
1108 /*
1109 * If COPY TO source table is a partitioned table, then open each
1110 * partition and process each individual partition.
1111 */
1112 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1113 {
1114 foreach_oid(child, cstate->partitions)
1115 {
1117
1118 /* We already got the lock in BeginCopyTo */
1119 scan_rel = table_open(child, NoLock);
1120 CopyRelationTo(cstate, scan_rel, cstate->rel, &processed);
1122 }
1123 }
1124 else
1125 CopyRelationTo(cstate, cstate->rel, NULL, &processed);
1126 }
1127 else
1128 {
1129 /* run the plan --- the dest receiver will send tuples */
1131 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1132 }
1133
1134 cstate->routine->CopyToEnd(cstate);
1135
1137
1138 if (fe_copy)
1139 SendCopyEnd(cstate);
1140
1141 return processed;
1142}
uint64_t uint64
Definition c.h:547
static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
Definition copyto.c:1152
static void SendCopyBegin(CopyToState cstate)
Definition copyto.c:396
static void SendCopyEnd(CopyToState cstate)
Definition copyto.c:413
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition execMain.c:297
#define NoLock
Definition lockdefs.h:34
void * palloc(Size size)
Definition mcxt.c:1387
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
void(* CopyToOutFunc)(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition copyapi.h:34
void(* CopyToEnd)(CopyToState cstate)
Definition copyapi.h:54
void(* CopyToStart)(CopyToState cstate, TupleDesc tupDesc)
Definition copyapi.h:44
DestReceiver * dest
Definition execdesc.h: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 592 of file copyto.c.

593{
594 if (cstate->is_program)
595 {
596 ClosePipeToProgram(cstate);
597 }
598 else
599 {
600 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
603 errmsg("could not close file \"%s\": %m",
604 cstate->filename)));
605 }
606
608
610
611 if (cstate->partitions)
612 list_free(cstate->partitions);
613
614 pfree(cstate);
615}
void pgstat_progress_end_command(void)
int FreeFile(FILE *file)
Definition fd.c:2823
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 1040 of file copyto.c.

1041{
1042 if (cstate->queryDesc != NULL)
1043 {
1044 /* Close down the query and free resources. */
1045 ExecutorFinish(cstate->queryDesc);
1046 ExecutorEnd(cstate->queryDesc);
1047 FreeQueryDesc(cstate->queryDesc);
1049 }
1050
1051 /* Clean up storage */
1052 EndCopy(cstate);
1053}
static void EndCopy(CopyToState cstate)
Definition copyto.c:592
void ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:466
void ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:406
void FreeQueryDesc(QueryDesc *qdesc)
Definition pquery.c:106
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 396 of file copyto.c.

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

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

Referenced by DoCopyTo().

◆ SendCopyEnd()

static void SendCopyEnd ( CopyToState  cstate)
static

Definition at line 413 of file copyto.c.

414{
415 /* Shouldn't have any unsent data */
416 Assert(cstate->fe_msgbuf->len == 0);
417 /* Send Copy Done message */
419}
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 112 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:338
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:350
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:319
static void CopyToBinaryEnd(CopyToState cstate)
Definition copyto.c:383

Definition at line 173 of file copyto.c.

173 {
174 .CopyToStart = CopyToBinaryStart,
175 .CopyToOutFunc = CopyToBinaryOutFunc,
176 .CopyToOneRow = CopyToBinaryOneRow,
177 .CopyToEnd = CopyToBinaryEnd,
178};

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

Definition at line 165 of file copyto.c.

165 {
166 .CopyToStart = CopyToTextLikeStart,
167 .CopyToOutFunc = CopyToTextLikeOutFunc,
168 .CopyToOneRow = CopyToCSVOneRow,
169 .CopyToEnd = CopyToTextLikeEnd,
170};

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

Definition at line 157 of file copyto.c.

157 {
158 .CopyToStart = CopyToTextLikeStart,
159 .CopyToOutFunc = CopyToTextLikeOutFunc,
160 .CopyToOneRow = CopyToTextOneRow,
161 .CopyToEnd = CopyToTextLikeEnd,
162};

Referenced by CopyToGetRoutine().