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

1238 { \
1239 if (ptr > start) \
1240 CopySendData(cstate, start, ptr - start); \
1241 } while (0)

Typedef Documentation

◆ CopyDest

◆ CopyToStateData

Enumeration Type Documentation

◆ CopyDest

Enumerator
COPY_FILE 
COPY_FRONTEND 
COPY_CALLBACK 

Definition at line 47 of file copyto.c.

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

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

645{
646 CopyToState cstate;
647 bool pipe = (filename == NULL && data_dest_cb == NULL);
648 TupleDesc tupDesc;
649 int num_phys_attrs;
650 MemoryContext oldcontext;
651 const int progress_cols[] = {
654 };
655 int64 progress_vals[] = {
657 0
658 };
659 List *children = NIL;
660
661 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
662 {
663 if (rel->rd_rel->relkind == RELKIND_VIEW)
666 errmsg("cannot copy from view \"%s\"",
668 errhint("Try the COPY (SELECT ...) TO variant.")));
669 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
670 {
671 if (!RelationIsPopulated(rel))
674 errmsg("cannot copy from unpopulated materialized view \"%s\"",
676 errhint("Use the REFRESH MATERIALIZED VIEW command."));
677 }
678 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
681 errmsg("cannot copy from foreign table \"%s\"",
683 errhint("Try the COPY (SELECT ...) TO variant.")));
684 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
687 errmsg("cannot copy from sequence \"%s\"",
689 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
690 {
691 /*
692 * Collect OIDs of relation containing data, so that later
693 * DoCopyTo can copy the data from them.
694 */
696
697 foreach_oid(child, children)
698 {
699 char relkind = get_rel_relkind(child);
700
701 if (relkind == RELKIND_FOREIGN_TABLE)
702 {
703 char *relation_name = get_rel_name(child);
704
707 errmsg("cannot copy from foreign table \"%s\"", relation_name),
708 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
709 relation_name, RelationGetRelationName(rel)),
710 errhint("Try the COPY (SELECT ...) TO variant."));
711 }
712
713 /* Exclude tables with no data */
714 if (RELKIND_HAS_PARTITIONS(relkind))
715 children = foreach_delete_current(children, child);
716 }
717 }
718 else
721 errmsg("cannot copy from non-table relation \"%s\"",
723 }
724
725
726 /* Allocate workspace and zero all fields */
728
729 /*
730 * We allocate everything used by a cstate in a new memory context. This
731 * avoids memory leaks during repeated use of COPY in a query.
732 */
734 "COPY",
736
737 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
738
739 /* Extract options from the statement node tree */
740 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
741
742 /* Set format routine */
743 cstate->routine = CopyToGetRoutine(&cstate->opts);
744
745 /* Process the source/target relation or query */
746 if (rel)
747 {
749
750 cstate->rel = rel;
751
752 tupDesc = RelationGetDescr(cstate->rel);
753 cstate->partitions = children;
754 }
755 else
756 {
758 Query *query;
761
762 cstate->rel = NULL;
763 cstate->partitions = NIL;
764
765 /*
766 * Run parse analysis and rewrite. Note this also acquires sufficient
767 * locks on the source table(s).
768 */
770 pstate->p_sourcetext, NULL, 0,
771 NULL);
772
773 /* check that we got back something we can work with */
774 if (rewritten == NIL)
775 {
778 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
779 }
780 else if (list_length(rewritten) > 1)
781 {
782 ListCell *lc;
783
784 /* examine queries to determine which error message to issue */
785 foreach(lc, rewritten)
786 {
787 Query *q = lfirst_node(Query, lc);
788
789 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
792 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
793 if (q->querySource == QSRC_NON_INSTEAD_RULE)
796 errmsg("DO ALSO rules are not supported for COPY")));
797 }
798
801 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
802 }
803
804 query = linitial_node(Query, rewritten);
805
806 /* The grammar allows SELECT INTO, but we don't support that */
807 if (query->utilityStmt != NULL &&
811 errmsg("COPY (SELECT INTO) is not supported")));
812
813 /* The only other utility command we could see is NOTIFY */
814 if (query->utilityStmt != NULL)
817 errmsg("COPY query must not be a utility command")));
818
819 /*
820 * Similarly the grammar doesn't enforce the presence of a RETURNING
821 * clause, but this is required here.
822 */
823 if (query->commandType != CMD_SELECT &&
824 query->returningList == NIL)
825 {
826 Assert(query->commandType == CMD_INSERT ||
827 query->commandType == CMD_UPDATE ||
828 query->commandType == CMD_DELETE ||
829 query->commandType == CMD_MERGE);
830
833 errmsg("COPY query must have a RETURNING clause")));
834 }
835
836 /* plan the query */
837 plan = pg_plan_query(query, pstate->p_sourcetext,
839
840 /*
841 * With row-level security and a user using "COPY relation TO", we
842 * have to convert the "COPY relation TO" to a query-based COPY (eg:
843 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
844 * add in any RLS clauses.
845 *
846 * When this happens, we are passed in the relid of the originally
847 * found relation (which we have locked). As the planner will look up
848 * the relation again, we double-check here to make sure it found the
849 * same one that we have locked.
850 */
851 if (queryRelId != InvalidOid)
852 {
853 /*
854 * Note that with RLS involved there may be multiple relations,
855 * and while the one we need is almost certainly first, we don't
856 * make any guarantees of that in the planner, so check the whole
857 * list and make sure we find the original relation.
858 */
859 if (!list_member_oid(plan->relationOids, queryRelId))
862 errmsg("relation referenced by COPY statement has changed")));
863 }
864
865 /*
866 * Use a snapshot with an updated command ID to ensure this query sees
867 * results of any previously executed queries.
868 */
871
872 /* Create dest receiver for COPY OUT */
874 ((DR_copy *) dest)->cstate = cstate;
875
876 /* Create a QueryDesc requesting no output */
877 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
880 dest, NULL, NULL, 0);
881
882 /*
883 * Call ExecutorStart to prepare the plan for execution.
884 *
885 * ExecutorStart computes a result tupdesc for us
886 */
887 ExecutorStart(cstate->queryDesc, 0);
888
889 tupDesc = cstate->queryDesc->tupDesc;
890 }
891
892 /* Generate or convert list of attributes to process */
893 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
894
895 num_phys_attrs = tupDesc->natts;
896
897 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
898 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
899 if (cstate->opts.force_quote_all)
900 {
901 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
902 }
903 else if (cstate->opts.force_quote)
904 {
905 List *attnums;
906 ListCell *cur;
907
908 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
909
910 foreach(cur, attnums)
911 {
912 int attnum = lfirst_int(cur);
913 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
914
915 if (!list_member_int(cstate->attnumlist, attnum))
918 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
919 errmsg("%s column \"%s\" not referenced by COPY",
920 "FORCE_QUOTE", NameStr(attr->attname))));
921 cstate->opts.force_quote_flags[attnum - 1] = true;
922 }
923 }
924
925 /* Use client encoding when ENCODING option is not specified. */
926 if (cstate->opts.file_encoding < 0)
928 else
929 cstate->file_encoding = cstate->opts.file_encoding;
930
931 /*
932 * Set up encoding conversion info if the file and server encodings differ
933 * (see also pg_server_to_any).
934 */
935 if (cstate->file_encoding == GetDatabaseEncoding() ||
936 cstate->file_encoding == PG_SQL_ASCII)
937 cstate->need_transcoding = false;
938 else
939 cstate->need_transcoding = true;
940
941 /* See Multibyte encoding comment above */
943
944 cstate->copy_dest = COPY_FILE; /* default */
945
946 if (data_dest_cb)
947 {
949 cstate->copy_dest = COPY_CALLBACK;
950 cstate->data_dest_cb = data_dest_cb;
951 }
952 else if (pipe)
953 {
955
956 Assert(!is_program); /* the grammar does not allow this */
958 cstate->copy_file = stdout;
959 }
960 else
961 {
962 cstate->filename = pstrdup(filename);
963 cstate->is_program = is_program;
964
965 if (is_program)
966 {
968 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
969 if (cstate->copy_file == NULL)
972 errmsg("could not execute command \"%s\": %m",
973 cstate->filename)));
974 }
975 else
976 {
977 mode_t oumask; /* Pre-existing umask value */
978 struct stat st;
979
981
982 /*
983 * Prevent write to relative path ... too easy to shoot oneself in
984 * the foot by overwriting a database file ...
985 */
989 errmsg("relative path not allowed for COPY to file")));
990
992 PG_TRY();
993 {
994 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
995 }
996 PG_FINALLY();
997 {
998 umask(oumask);
999 }
1000 PG_END_TRY();
1001 if (cstate->copy_file == NULL)
1002 {
1003 /* copy errno because ereport subfunctions might change it */
1004 int save_errno = errno;
1005
1006 ereport(ERROR,
1008 errmsg("could not open file \"%s\" for writing: %m",
1009 cstate->filename),
1010 (save_errno == ENOENT || save_errno == EACCES) ?
1011 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1012 "You may want a client-side facility such as psql's \\copy.") : 0));
1013 }
1014
1015 if (fstat(fileno(cstate->copy_file), &st))
1016 ereport(ERROR,
1018 errmsg("could not stat file \"%s\": %m",
1019 cstate->filename)));
1020
1021 if (S_ISDIR(st.st_mode))
1022 ereport(ERROR,
1024 errmsg("\"%s\" is a directory", cstate->filename)));
1025 }
1026 }
1027
1028 /* initialize progress */
1030 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1032
1033 cstate->bytes_processed = 0;
1034
1035 MemoryContextSwitchTo(oldcontext);
1036
1037 return cstate;
1038}
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition copy.c:1010
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition copy.c:561
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:837
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
#define PG_BINARY_W
Definition c.h:1379
#define MemSet(start, val, len)
Definition c.h:1109
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition copyto.c:184
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition dest.c:113
@ DestRemote
Definition dest.h:89
@ DestCopyOut
Definition dest.h:95
struct cursor * cur
Definition ecpg.c:29
int errcode_for_file_access(void)
Definition elog.c:897
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define PG_TRY(...)
Definition elog.h: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:124
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 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:2148
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2223
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:1781
void * palloc0(Size size)
Definition mcxt.c:1417
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define IsA(nodeptr, _type_)
Definition nodes.h:164
@ CMD_MERGE
Definition nodes.h:279
@ CMD_INSERT
Definition nodes.h:277
@ CMD_DELETE
Definition nodes.h:278
@ CMD_UPDATE
Definition nodes.h:276
@ CMD_SELECT
Definition nodes.h:275
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
@ QSRC_NON_INSTEAD_RULE
Definition parsenodes.h:40
@ QSRC_QUAL_INSTEAD_RULE
Definition parsenodes.h:39
#define CURSOR_OPT_PARALLEL_OK
int16 attnum
FormData_pg_attribute * Form_pg_attribute
static char * filename
Definition pg_dumpall.c:133
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define lfirst_node(type, lc)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial_node(type, l)
Definition pg_list.h:181
#define NIL
Definition pg_list.h:68
#define 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:94
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:174
#define PROGRESS_COPY_TYPE_FILE
Definition progress.h:183
#define PROGRESS_COPY_COMMAND_TO
Definition progress.h:180
#define PROGRESS_COPY_TYPE
Definition progress.h:175
#define PROGRESS_COPY_TYPE_PROGRAM
Definition progress.h:184
#define PROGRESS_COPY_TYPE_CALLBACK
Definition progress.h:186
#define PROGRESS_COPY_TYPE_PIPE
Definition progress.h:185
#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:76
List * force_quote
Definition copy.h:75
bool * force_quote_flags
Definition copy.h:77
int file_encoding
Definition copy.h:60
MemoryContext copycontext
Definition copyto.c:98
Relation rel
Definition copyto.c:84
const CopyToRoutine * routine
Definition copyto.c:72
copy_data_dest_cb data_dest_cb
Definition copyto.c:89
bool encoding_embeds_ascii
Definition copyto.c:81
CopyDest copy_dest
Definition copyto.c:75
bool need_transcoding
Definition copyto.c:80
bool is_program
Definition copyto.c:88
FILE * copy_file
Definition copyto.c:76
int file_encoding
Definition copyto.c:79
CopyFormatOptions opts
Definition copyto.c:91
uint64 bytes_processed
Definition copyto.c:102
char * filename
Definition copyto.c:87
List * attnumlist
Definition copyto.c:86
QueryDesc * queryDesc
Definition copyto.c:85
List * partitions
Definition copyto.c:93
Definition pg_list.h:54
const char * p_sourcetext
Definition parse_node.h:210
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: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, 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 571 of file copyto.c.

572{
573 int pclose_rc;
574
575 Assert(cstate->is_program);
576
578 if (pclose_rc == -1)
581 errmsg("could not close pipe to external command: %m")));
582 else if (pclose_rc != 0)
583 {
586 errmsg("program \"%s\" failed",
587 cstate->filename),
589 }
590}
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 1523 of file copyto.c.

1524{
1525 pfree(self);
1526}
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 1495 of file copyto.c.

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

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

1515{
1516 /* no-op */
1517}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1486 of file copyto.c.

1487{
1488 /* no-op */
1489}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1397 of file copyto.c.

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

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

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

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

1220{
1221 MemoryContext oldcontext;
1222
1224 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1225
1226 /* Make sure the tuple is fully deconstructed */
1227 slot_getallattrs(slot);
1228
1229 cstate->routine->CopyToOneRow(cstate, slot);
1230
1231 MemoryContextSwitchTo(oldcontext);
1232}
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
void(* CopyToOneRow)(CopyToState cstate, TupleTableSlot *slot)
Definition copyapi.h:49
MemoryContext rowcontext
Definition copyto.c:101
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 1156 of file copyto.c.

1157{
1158 TupleTableSlot *slot;
1159 TableScanDesc scandesc;
1160 AttrMap *map = NULL;
1162
1163 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL);
1164 slot = table_slot_create(rel, NULL);
1165
1166 /*
1167 * If we are exporting partition data here, we check if converting tuples
1168 * to the root table's rowtype, because a partition might have column
1169 * order different than its root table.
1170 */
1171 if (root_rel != NULL)
1172 {
1175 RelationGetDescr(rel),
1176 false);
1177 }
1178
1179 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1180 {
1181 TupleTableSlot *copyslot;
1182
1184
1185 if (map != NULL)
1186 copyslot = execute_attr_map_slot(map, slot, root_slot);
1187 else
1188 {
1189 /* Deconstruct the tuple */
1190 slot_getallattrs(slot);
1191 copyslot = slot;
1192 }
1193
1194 /* Format and send the data */
1195 CopyOneRowTo(cstate, copyslot);
1196
1197 /*
1198 * Increment the number of processed tuples, and report the progress.
1199 */
1201 ++(*processed));
1202 }
1203
1205
1206 if (root_slot != NULL)
1208
1209 if (map != NULL)
1210 free_attrmap(map);
1211
1212 table_endscan(scandesc);
1213}
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:1004
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:1039
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key)
Definition tableam.h:896
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 446 of file copyto.c.

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

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

435{
437}
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 452 of file copyto.c.

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

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

560{
561 uint16 buf;
562
563 buf = pg_hton16((uint16) val);
564 CopySendData(cstate, &buf, sizeof(buf));
565}
uint16_t uint16
Definition c.h:617
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition copyto.c:434
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 547 of file copyto.c.

548{
549 uint32 buf;
550
551 buf = pg_hton32((uint32) val);
552 CopySendData(cstate, &buf, sizeof(buf));
553}
uint32_t uint32
Definition c.h:618
#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 440 of file copyto.c.

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

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

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

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

References CopySendEndOfRow(), and CopySendInt16().

◆ CopyToBinaryOneRow()

static void CopyToBinaryOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 352 of file copyto.c.

353{
354 FmgrInfo *out_functions = cstate->out_functions;
355
356 /* Binary per-tuple header */
357 CopySendInt16(cstate, list_length(cstate->attnumlist));
358
360 {
361 Datum value = slot->tts_values[attnum - 1];
362 bool isnull = slot->tts_isnull[attnum - 1];
363
364 if (isnull)
365 {
366 CopySendInt32(cstate, -1);
367 }
368 else
369 {
371
372 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
373 value);
377 }
378 }
379
380 CopySendEndOfRow(cstate);
381}
#define VARHDRSZ
Definition c.h:783
static void CopySendInt32(CopyToState cstate, int32 val)
Definition copyto.c:547
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1745
static struct @174 value
#define foreach_int(var, lst)
Definition pg_list.h:470
uint64_t Datum
Definition postgres.h:70
FmgrInfo * out_functions
Definition copyto.c:100
bool * tts_isnull
Definition tuptable.h:133
Datum * tts_values
Definition tuptable.h:131
Definition c.h:778
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 340 of file copyto.c.

341{
343 bool is_varlena;
344
345 /* Set output function for an attribute */
347 fmgr_info(func_oid, finfo);
348}
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition lsyscache.c:3195
unsigned int Oid

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

◆ CopyToBinaryStart()

static void CopyToBinaryStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 321 of file copyto.c.

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

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

◆ CopyToCSVOneRow()

static void CopyToCSVOneRow ( CopyToState  cstate,
TupleTableSlot slot 
)
static

Definition at line 259 of file copyto.c.

260{
261 CopyToTextLikeOneRow(cstate, slot, true);
262}
static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv)
Definition copyto.c:271

References CopyToTextLikeOneRow().

◆ CopyToGetRoutine()

static const CopyToRoutine * CopyToGetRoutine ( const CopyFormatOptions opts)
static

Definition at line 184 of file copyto.c.

185{
186 if (opts->csv_mode)
187 return &CopyToRoutineCSV;
188 else if (opts->binary)
189 return &CopyToRoutineBinary;
190
191 /* default is text */
192 return &CopyToRoutineText;
193}
static const CopyToRoutine CopyToRoutineCSV
Definition copyto.c:167
static const CopyToRoutine CopyToRoutineText
Definition copyto.c:159
static const CopyToRoutine CopyToRoutineBinary
Definition copyto.c:175
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 311 of file copyto.c.

312{
313 /* Nothing to do here */
314}

◆ CopyToTextLikeOneRow()

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

Definition at line 271 of file copyto.c.

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

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

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

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

◆ CopyToTextLikeStart()

static void CopyToTextLikeStart ( CopyToState  cstate,
TupleDesc  tupDesc 
)
static

Definition at line 197 of file copyto.c.

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

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

253{
254 CopyToTextLikeOneRow(cstate, slot, false);
255}

References CopyToTextLikeOneRow().

◆ CreateCopyDestReceiver()

DestReceiver * CreateCopyDestReceiver ( void  )

Definition at line 1532 of file copyto.c.

1533{
1534 DR_copy *self = palloc_object(DR_copy);
1535
1540 self->pub.mydest = DestCopyOut;
1541
1542 self->cstate = NULL; /* will be set later */
1543 self->processed = 0;
1544
1545 return (DestReceiver *) self;
1546}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1495
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1523
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1514
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1486
#define palloc_object(type)
Definition fe_memutils.h:74
CopyToState cstate
Definition copyto.c:109
DestReceiver pub
Definition copyto.c:108
uint64 processed
Definition copyto.c:110
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 1065 of file copyto.c.

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

597{
598 if (cstate->is_program)
599 {
600 ClosePipeToProgram(cstate);
601 }
602 else
603 {
604 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
607 errmsg("could not close file \"%s\": %m",
608 cstate->filename)));
609 }
610
612
614
615 if (cstate->partitions)
616 list_free(cstate->partitions);
617
618 pfree(cstate);
619}
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 1044 of file copyto.c.

1045{
1046 if (cstate->queryDesc != NULL)
1047 {
1048 /* Close down the query and free resources. */
1049 ExecutorFinish(cstate->queryDesc);
1050 ExecutorEnd(cstate->queryDesc);
1051 FreeQueryDesc(cstate->queryDesc);
1053 }
1054
1055 /* Clean up storage */
1056 EndCopy(cstate);
1057}
static void EndCopy(CopyToState cstate)
Definition copyto.c:596
void ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:468
void ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:408
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 398 of file copyto.c.

399{
401 int natts = list_length(cstate->attnumlist);
402 int16 format = (cstate->opts.binary ? 1 : 0);
403 int i;
404
406 pq_sendbyte(&buf, format); /* overall format */
407 pq_sendint16(&buf, natts);
408 for (i = 0; i < natts; i++)
409 pq_sendint16(&buf, format); /* per-column formats */
411 cstate->copy_dest = COPY_FRONTEND;
412}
int16_t int16
Definition c.h:613
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 415 of file copyto.c.

416{
417 /* Shouldn't have any unsent data */
418 Assert(cstate->fe_msgbuf->len == 0);
419 /* Send Copy Done message */
421}
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 114 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:340
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:352
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:321
static void CopyToBinaryEnd(CopyToState cstate)
Definition copyto.c:385

Definition at line 175 of file copyto.c.

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

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

Definition at line 167 of file copyto.c.

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

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

Definition at line 159 of file copyto.c.

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

Referenced by CopyToGetRoutine().