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

1236 { \
1237 if (ptr > start) \
1238 CopySendData(cstate, start, ptr - start); \
1239 } 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 634 of file copyto.c.

643{
644 CopyToState cstate;
645 bool pipe = (filename == NULL && data_dest_cb == NULL);
646 TupleDesc tupDesc;
647 int num_phys_attrs;
648 MemoryContext oldcontext;
649 const int progress_cols[] = {
652 };
653 int64 progress_vals[] = {
655 0
656 };
657 List *children = NIL;
658
659 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
660 {
661 if (rel->rd_rel->relkind == RELKIND_VIEW)
664 errmsg("cannot copy from view \"%s\"",
666 errhint("Try the COPY (SELECT ...) TO variant.")));
667 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
668 {
669 if (!RelationIsPopulated(rel))
672 errmsg("cannot copy from unpopulated materialized view \"%s\"",
674 errhint("Use the REFRESH MATERIALIZED VIEW command."));
675 }
676 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
679 errmsg("cannot copy from foreign table \"%s\"",
681 errhint("Try the COPY (SELECT ...) TO variant.")));
682 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
685 errmsg("cannot copy from sequence \"%s\"",
687 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
688 {
689 /*
690 * Collect OIDs of relation containing data, so that later
691 * DoCopyTo can copy the data from them.
692 */
694
695 foreach_oid(child, children)
696 {
697 char relkind = get_rel_relkind(child);
698
699 if (relkind == RELKIND_FOREIGN_TABLE)
700 {
701 char *relation_name = get_rel_name(child);
702
705 errmsg("cannot copy from foreign table \"%s\"", relation_name),
706 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
707 relation_name, RelationGetRelationName(rel)),
708 errhint("Try the COPY (SELECT ...) TO variant."));
709 }
710
711 /* Exclude tables with no data */
712 if (RELKIND_HAS_PARTITIONS(relkind))
713 children = foreach_delete_current(children, child);
714 }
715 }
716 else
719 errmsg("cannot copy from non-table relation \"%s\"",
721 }
722
723
724 /* Allocate workspace and zero all fields */
726
727 /*
728 * We allocate everything used by a cstate in a new memory context. This
729 * avoids memory leaks during repeated use of COPY in a query.
730 */
732 "COPY",
734
735 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
736
737 /* Extract options from the statement node tree */
738 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
739
740 /* Set format routine */
741 cstate->routine = CopyToGetRoutine(&cstate->opts);
742
743 /* Process the source/target relation or query */
744 if (rel)
745 {
747
748 cstate->rel = rel;
749
750 tupDesc = RelationGetDescr(cstate->rel);
751 cstate->partitions = children;
752 }
753 else
754 {
756 Query *query;
759
760 cstate->rel = NULL;
761 cstate->partitions = NIL;
762
763 /*
764 * Run parse analysis and rewrite. Note this also acquires sufficient
765 * locks on the source table(s).
766 */
768 pstate->p_sourcetext, NULL, 0,
769 NULL);
770
771 /* check that we got back something we can work with */
772 if (rewritten == NIL)
773 {
776 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
777 }
778 else if (list_length(rewritten) > 1)
779 {
780 ListCell *lc;
781
782 /* examine queries to determine which error message to issue */
783 foreach(lc, rewritten)
784 {
785 Query *q = lfirst_node(Query, lc);
786
787 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
790 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
791 if (q->querySource == QSRC_NON_INSTEAD_RULE)
794 errmsg("DO ALSO rules are not supported for COPY")));
795 }
796
799 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
800 }
801
802 query = linitial_node(Query, rewritten);
803
804 /* The grammar allows SELECT INTO, but we don't support that */
805 if (query->utilityStmt != NULL &&
809 errmsg("COPY (SELECT INTO) is not supported")));
810
811 /* The only other utility command we could see is NOTIFY */
812 if (query->utilityStmt != NULL)
815 errmsg("COPY query must not be a utility command")));
816
817 /*
818 * Similarly the grammar doesn't enforce the presence of a RETURNING
819 * clause, but this is required here.
820 */
821 if (query->commandType != CMD_SELECT &&
822 query->returningList == NIL)
823 {
824 Assert(query->commandType == CMD_INSERT ||
825 query->commandType == CMD_UPDATE ||
826 query->commandType == CMD_DELETE ||
827 query->commandType == CMD_MERGE);
828
831 errmsg("COPY query must have a RETURNING clause")));
832 }
833
834 /* plan the query */
835 plan = pg_plan_query(query, pstate->p_sourcetext,
837
838 /*
839 * With row-level security and a user using "COPY relation TO", we
840 * have to convert the "COPY relation TO" to a query-based COPY (eg:
841 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
842 * add in any RLS clauses.
843 *
844 * When this happens, we are passed in the relid of the originally
845 * found relation (which we have locked). As the planner will look up
846 * the relation again, we double-check here to make sure it found the
847 * same one that we have locked.
848 */
849 if (queryRelId != InvalidOid)
850 {
851 /*
852 * Note that with RLS involved there may be multiple relations,
853 * and while the one we need is almost certainly first, we don't
854 * make any guarantees of that in the planner, so check the whole
855 * list and make sure we find the original relation.
856 */
857 if (!list_member_oid(plan->relationOids, queryRelId))
860 errmsg("relation referenced by COPY statement has changed")));
861 }
862
863 /*
864 * Use a snapshot with an updated command ID to ensure this query sees
865 * results of any previously executed queries.
866 */
869
870 /* Create dest receiver for COPY OUT */
872 ((DR_copy *) dest)->cstate = cstate;
873
874 /* Create a QueryDesc requesting no output */
875 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
878 dest, NULL, NULL, 0);
879
880 /*
881 * Call ExecutorStart to prepare the plan for execution.
882 *
883 * ExecutorStart computes a result tupdesc for us
884 */
885 ExecutorStart(cstate->queryDesc, 0);
886
887 tupDesc = cstate->queryDesc->tupDesc;
888 }
889
890 /* Generate or convert list of attributes to process */
891 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
892
893 num_phys_attrs = tupDesc->natts;
894
895 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
896 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
897 if (cstate->opts.force_quote_all)
898 {
899 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
900 }
901 else if (cstate->opts.force_quote)
902 {
903 List *attnums;
904 ListCell *cur;
905
906 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
907
908 foreach(cur, attnums)
909 {
910 int attnum = lfirst_int(cur);
911 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
912
913 if (!list_member_int(cstate->attnumlist, attnum))
916 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
917 errmsg("%s column \"%s\" not referenced by COPY",
918 "FORCE_QUOTE", NameStr(attr->attname))));
919 cstate->opts.force_quote_flags[attnum - 1] = true;
920 }
921 }
922
923 /* Use client encoding when ENCODING option is not specified. */
924 if (cstate->opts.file_encoding < 0)
926 else
927 cstate->file_encoding = cstate->opts.file_encoding;
928
929 /*
930 * Set up encoding conversion info if the file and server encodings differ
931 * (see also pg_server_to_any).
932 */
933 if (cstate->file_encoding == GetDatabaseEncoding() ||
934 cstate->file_encoding == PG_SQL_ASCII)
935 cstate->need_transcoding = false;
936 else
937 cstate->need_transcoding = true;
938
939 /* See Multibyte encoding comment above */
941
942 cstate->copy_dest = COPY_FILE; /* default */
943
944 if (data_dest_cb)
945 {
947 cstate->copy_dest = COPY_CALLBACK;
948 cstate->data_dest_cb = data_dest_cb;
949 }
950 else if (pipe)
951 {
953
954 Assert(!is_program); /* the grammar does not allow this */
956 cstate->copy_file = stdout;
957 }
958 else
959 {
960 cstate->filename = pstrdup(filename);
961 cstate->is_program = is_program;
962
963 if (is_program)
964 {
966 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
967 if (cstate->copy_file == NULL)
970 errmsg("could not execute command \"%s\": %m",
971 cstate->filename)));
972 }
973 else
974 {
975 mode_t oumask; /* Pre-existing umask value */
976 struct stat st;
977
979
980 /*
981 * Prevent write to relative path ... too easy to shoot oneself in
982 * the foot by overwriting a database file ...
983 */
987 errmsg("relative path not allowed for COPY to file")));
988
990 PG_TRY();
991 {
992 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
993 }
994 PG_FINALLY();
995 {
996 umask(oumask);
997 }
998 PG_END_TRY();
999 if (cstate->copy_file == NULL)
1000 {
1001 /* copy errno because ereport subfunctions might change it */
1002 int save_errno = errno;
1003
1004 ereport(ERROR,
1006 errmsg("could not open file \"%s\" for writing: %m",
1007 cstate->filename),
1008 (save_errno == ENOENT || save_errno == EACCES) ?
1009 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1010 "You may want a client-side facility such as psql's \\copy.") : 0));
1011 }
1012
1013 if (fstat(fileno(cstate->copy_file), &st))
1014 ereport(ERROR,
1016 errmsg("could not stat file \"%s\": %m",
1017 cstate->filename)));
1018
1019 if (S_ISDIR(st.st_mode))
1020 ereport(ERROR,
1022 errmsg("\"%s\" is a directory", cstate->filename)));
1023 }
1024 }
1025
1026 /* initialize progress */
1028 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1030
1031 cstate->bytes_processed = 0;
1032
1033 MemoryContextSwitchTo(oldcontext);
1034
1035 return cstate;
1036}
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:2730
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2627
#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:886
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:669
#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 569 of file copyto.c.

570{
571 int pclose_rc;
572
573 Assert(cstate->is_program);
574
576 if (pclose_rc == -1)
579 errmsg("could not close pipe to external command: %m")));
580 else if (pclose_rc != 0)
581 {
584 errmsg("program \"%s\" failed",
585 cstate->filename),
587 }
588}
int errdetail_internal(const char *fmt,...)
Definition elog.c:1243
int ClosePipeStream(FILE *file)
Definition fd.c:3038
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 1521 of file copyto.c.

1522{
1523 pfree(self);
1524}
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 1493 of file copyto.c.

1494{
1495 DR_copy *myState = (DR_copy *) self;
1496 CopyToState cstate = myState->cstate;
1497
1498 /* Send the data */
1499 CopyOneRowTo(cstate, slot);
1500
1501 /* Increment the number of processed tuples, and report the progress */
1503 ++myState->processed);
1504
1505 return true;
1506}
void pgstat_progress_update_param(int index, int64 val)
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:1217
#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 1512 of file copyto.c.

1513{
1514 /* no-op */
1515}

Referenced by CreateCopyDestReceiver().

◆ copy_dest_startup()

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

Definition at line 1484 of file copyto.c.

1485{
1486 /* no-op */
1487}

Referenced by CreateCopyDestReceiver().

◆ CopyAttributeOutCSV()

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

Definition at line 1395 of file copyto.c.

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

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

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

1218{
1219 MemoryContext oldcontext;
1220
1222 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1223
1224 /* Make sure the tuple is fully deconstructed */
1225 slot_getallattrs(slot);
1226
1227 cstate->routine->CopyToOneRow(cstate, slot);
1228
1229 MemoryContextSwitchTo(oldcontext);
1230}
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 1154 of file copyto.c.

1155{
1156 TupleTableSlot *slot;
1157 TableScanDesc scandesc;
1158 AttrMap *map = NULL;
1160
1161 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL);
1162 slot = table_slot_create(rel, NULL);
1163
1164 /*
1165 * If we are exporting partition data here, we check if converting tuples
1166 * to the root table's rowtype, because a partition might have column
1167 * order different than its root table.
1168 */
1169 if (root_rel != NULL)
1170 {
1173 RelationGetDescr(rel),
1174 false);
1175 }
1176
1177 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1178 {
1179 TupleTableSlot *copyslot;
1180
1182
1183 if (map != NULL)
1184 copyslot = execute_attr_map_slot(map, slot, root_slot);
1185 else
1186 {
1187 /* Deconstruct the tuple */
1188 slot_getallattrs(slot);
1189 copyslot = slot;
1190 }
1191
1192 /* Format and send the data */
1193 CopyOneRowTo(cstate, copyslot);
1194
1195 /*
1196 * Increment the number of processed tuples, and report the progress.
1197 */
1199 ++(*processed));
1200 }
1201
1203
1204 if (root_slot != NULL)
1206
1207 if (map != NULL)
1208 free_attrmap(map);
1209
1210 table_endscan(scandesc);
1211}
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:
458 if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
459 cstate->copy_file) != 1 ||
460 ferror(cstate->copy_file))
461 {
462 if (cstate->is_program)
463 {
464 if (errno == EPIPE)
465 {
466 /*
467 * The pipe will be closed automatically on error at
468 * the end of transaction, but we might get a better
469 * error message from the subprocess' exit code than
470 * just "Broken Pipe"
471 */
472 ClosePipeToProgram(cstate);
473
474 /*
475 * If ClosePipeToProgram() didn't throw an error, the
476 * program terminated normally, but closed the pipe
477 * first. Restore errno, and throw an error.
478 */
479 errno = EPIPE;
480 }
483 errmsg("could not write to COPY program: %m")));
484 }
485 else
488 errmsg("could not write to COPY file: %m")));
489 }
491 break;
492 case COPY_FRONTEND:
493 /* Dump the accumulated row as one CopyData message */
494 (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
495 break;
496 case COPY_CALLBACK:
497 cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
498 break;
499 }
500
501 /* Update the progress */
502 cstate->bytes_processed += fe_msgbuf->len;
504
505 resetStringInfo(fe_msgbuf);
506}
static void ClosePipeToProgram(CopyToState cstate)
Definition copyto.c:569
#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
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 557 of file copyto.c.

558{
559 uint16 buf;
560
561 buf = pg_hton16((uint16) val);
562 CopySendData(cstate, &buf, sizeof(buf));
563}
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 545 of file copyto.c.

546{
547 uint32 buf;
548
549 buf = pg_hton32((uint32) val);
550 CopySendData(cstate, &buf, sizeof(buf));
551}
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 513 of file copyto.c.

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

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:545
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:1395
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition copyto.c:1242
static void CopySendTextLikeEndOfRow(CopyToState cstate)
Definition copyto.c:513
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 1530 of file copyto.c.

1531{
1532 DR_copy *self = palloc_object(DR_copy);
1533
1538 self->pub.mydest = DestCopyOut;
1539
1540 self->cstate = NULL; /* will be set later */
1541 self->processed = 0;
1542
1543 return (DestReceiver *) self;
1544}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1493
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1521
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1512
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1484
#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 1063 of file copyto.c.

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

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

1043{
1044 if (cstate->queryDesc != NULL)
1045 {
1046 /* Close down the query and free resources. */
1047 ExecutorFinish(cstate->queryDesc);
1048 ExecutorEnd(cstate->queryDesc);
1049 FreeQueryDesc(cstate->queryDesc);
1051 }
1052
1053 /* Clean up storage */
1054 EndCopy(cstate);
1055}
static void EndCopy(CopyToState cstate)
Definition copyto.c:594
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().