PostgreSQL Source Code git master
Loading...
Searching...
No Matches
copy.h File Reference
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "tcop/dest.h"
Include dependency graph for copy.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  CopyFormatOptions
 

Macros

#define COPY_HEADER_MATCH   -1
 
#define COPY_HEADER_FALSE   0
 
#define COPY_HEADER_TRUE   1
 

Typedefs

typedef enum CopyOnErrorChoice CopyOnErrorChoice
 
typedef enum CopyLogVerbosityChoice CopyLogVerbosityChoice
 
typedef enum CopyFormat CopyFormat
 
typedef struct CopyFormatOptions CopyFormatOptions
 
typedef struct CopyFromStateDataCopyFromState
 
typedef struct CopyToStateDataCopyToState
 
typedef int(* copy_data_source_cb) (void *outbuf, int minread, int maxread)
 
typedef void(* copy_data_dest_cb) (void *data, int len)
 

Enumerations

enum  CopyOnErrorChoice { COPY_ON_ERROR_STOP = 0 , COPY_ON_ERROR_IGNORE , COPY_ON_ERROR_SET_NULL }
 
enum  CopyLogVerbosityChoice { COPY_LOG_VERBOSITY_SILENT = -1 , COPY_LOG_VERBOSITY_DEFAULT = 0 , COPY_LOG_VERBOSITY_VERBOSE }
 
enum  CopyFormat { COPY_FORMAT_TEXT = 0 , COPY_FORMAT_BINARY , COPY_FORMAT_CSV , COPY_FORMAT_JSON }
 

Functions

void DoCopy (ParseState *pstate, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
 
void ProcessCopyOptions (ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
 
CopyFromState BeginCopyFrom (ParseState *pstate, Relation rel, Node *whereClause, const char *filename, bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options)
 
void EndCopyFrom (CopyFromState cstate)
 
bool NextCopyFrom (CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
 
bool NextCopyFromRawFields (CopyFromState cstate, char ***fields, int *nfields)
 
void CopyFromErrorCallback (void *arg)
 
charCopyLimitPrintoutLength (const char *str)
 
uint64 CopyFrom (CopyFromState cstate)
 
DestReceiverCreateCopyDestReceiver (void)
 
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)
 
ListCopyGetAttnums (TupleDesc tupDesc, Relation rel, List *attnamelist)
 

Macro Definition Documentation

◆ COPY_HEADER_FALSE

#define COPY_HEADER_FALSE   0

Definition at line 27 of file copy.h.

◆ COPY_HEADER_MATCH

#define COPY_HEADER_MATCH   -1

Definition at line 26 of file copy.h.

◆ COPY_HEADER_TRUE

#define COPY_HEADER_TRUE   1

Definition at line 28 of file copy.h.

Typedef Documentation

◆ copy_data_dest_cb

typedef void(* copy_data_dest_cb) (void *data, int len)

Definition at line 107 of file copy.h.

◆ copy_data_source_cb

typedef int(* copy_data_source_cb) (void *outbuf, int minread, int maxread)

Definition at line 106 of file copy.h.

◆ CopyFormat

◆ CopyFormatOptions

◆ CopyFromState

Definition at line 103 of file copy.h.

◆ CopyLogVerbosityChoice

◆ CopyOnErrorChoice

◆ CopyToState

Definition at line 104 of file copy.h.

Enumeration Type Documentation

◆ CopyFormat

Enumerator
COPY_FORMAT_TEXT 
COPY_FORMAT_BINARY 
COPY_FORMAT_CSV 
COPY_FORMAT_JSON 

Definition at line 55 of file copy.h.

56{
CopyFormat
Definition copy.h:56
@ COPY_FORMAT_CSV
Definition copy.h:59
@ COPY_FORMAT_JSON
Definition copy.h:60
@ COPY_FORMAT_BINARY
Definition copy.h:58
@ COPY_FORMAT_TEXT
Definition copy.h:57

◆ CopyLogVerbosityChoice

Enumerator
COPY_LOG_VERBOSITY_SILENT 
COPY_LOG_VERBOSITY_DEFAULT 
COPY_LOG_VERBOSITY_VERBOSE 

Definition at line 44 of file copy.h.

45{
46 COPY_LOG_VERBOSITY_SILENT = -1, /* logs none */
47 COPY_LOG_VERBOSITY_DEFAULT = 0, /* logs no additional messages. As this is
48 * the default, assign 0 */
49 COPY_LOG_VERBOSITY_VERBOSE, /* logs additional messages */
CopyLogVerbosityChoice
Definition copy.h:45
@ COPY_LOG_VERBOSITY_SILENT
Definition copy.h:46
@ COPY_LOG_VERBOSITY_VERBOSE
Definition copy.h:49
@ COPY_LOG_VERBOSITY_DEFAULT
Definition copy.h:47

◆ CopyOnErrorChoice

Enumerator
COPY_ON_ERROR_STOP 
COPY_ON_ERROR_IGNORE 
COPY_ON_ERROR_SET_NULL 

Definition at line 34 of file copy.h.

35{
36 COPY_ON_ERROR_STOP = 0, /* immediately throw errors, default */
37 COPY_ON_ERROR_IGNORE, /* ignore errors */
38 COPY_ON_ERROR_SET_NULL, /* set error field to null */
CopyOnErrorChoice
Definition copy.h:35
@ COPY_ON_ERROR_IGNORE
Definition copy.h:37
@ COPY_ON_ERROR_SET_NULL
Definition copy.h:38
@ COPY_ON_ERROR_STOP
Definition copy.h:36

Function Documentation

◆ BeginCopyFrom()

CopyFromState BeginCopyFrom ( ParseState pstate,
Relation  rel,
Node whereClause,
const char filename,
bool  is_program,
copy_data_source_cb  data_source_cb,
List attnamelist,
List options 
)
extern

Definition at line 1535 of file copyfrom.c.

1543{
1544 CopyFromState cstate;
1545 bool pipe = (filename == NULL);
1546 TupleDesc tupDesc;
1548 num_defaults;
1549 FmgrInfo *in_functions;
1550 Oid *typioparams;
1551 int *defmap;
1552 ExprState **defexprs;
1553 MemoryContext oldcontext;
1554 bool volatile_defexprs;
1555 const int progress_cols[] = {
1559 };
1560 int64 progress_vals[] = {
1562 0,
1563 0
1564 };
1565
1566 /* Allocate workspace and zero all fields */
1568
1569 /*
1570 * We allocate everything used by a cstate in a new memory context. This
1571 * avoids memory leaks during repeated use of COPY in a query.
1572 */
1574 "COPY",
1576
1577 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
1578
1579 /* Extract options from the statement node tree */
1580 ProcessCopyOptions(pstate, &cstate->opts, true /* is_from */ , options);
1581
1582 /* Set the format routine */
1583 cstate->routine = CopyFromGetRoutine(&cstate->opts);
1584
1585 /* Process the target relation */
1586 cstate->rel = rel;
1587
1588 tupDesc = RelationGetDescr(cstate->rel);
1589
1590 /* process common options or initialization */
1591
1592 /* Generate or convert list of attributes to process */
1593 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1594
1595 num_phys_attrs = tupDesc->natts;
1596
1597 /* Convert FORCE_NOT_NULL name list to per-column flags, check validity */
1598 cstate->opts.force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1599 if (cstate->opts.force_notnull_all)
1600 MemSet(cstate->opts.force_notnull_flags, true, num_phys_attrs * sizeof(bool));
1601 else if (cstate->opts.force_notnull)
1602 {
1603 List *attnums;
1604 ListCell *cur;
1605
1606 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_notnull);
1607
1608 foreach(cur, attnums)
1609 {
1610 int attnum = lfirst_int(cur);
1611 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1612
1613 if (!list_member_int(cstate->attnumlist, attnum))
1614 ereport(ERROR,
1616 /*- translator: first %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1617 errmsg("%s column \"%s\" not referenced by COPY",
1618 "FORCE_NOT_NULL", NameStr(attr->attname))));
1619 cstate->opts.force_notnull_flags[attnum - 1] = true;
1620 }
1621 }
1622
1623 /* Set up soft error handler for ON_ERROR */
1624 if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
1625 {
1628 cstate->escontext->error_occurred = false;
1629
1630 if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE ||
1632 cstate->escontext->details_wanted = false;
1633 }
1634 else
1635 cstate->escontext = NULL;
1636
1637 if (cstate->opts.on_error == COPY_ON_ERROR_SET_NULL)
1638 {
1639 int attr_count = list_length(cstate->attnumlist);
1640
1641 /*
1642 * When data type conversion fails and ON_ERROR is SET_NULL, we need
1643 * ensure that the input column allow null values. ExecConstraints()
1644 * will cover most of the cases, but it does not verify domain
1645 * constraints. Therefore, for constrained domains, the null value
1646 * check must be performed during the initial string-to-datum
1647 * conversion (see CopyFromTextLikeOneRow()).
1648 */
1650
1651 foreach_int(attno, cstate->attnumlist)
1652 {
1653 int i = foreach_current_index(attno);
1654
1655 Form_pg_attribute att = TupleDescAttr(tupDesc, attno - 1);
1656
1657 cstate->domain_with_constraint[i] = DomainHasConstraints(att->atttypid, NULL);
1658 }
1659 }
1660
1661 /* Convert FORCE_NULL name list to per-column flags, check validity */
1662 cstate->opts.force_null_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1663 if (cstate->opts.force_null_all)
1664 MemSet(cstate->opts.force_null_flags, true, num_phys_attrs * sizeof(bool));
1665 else if (cstate->opts.force_null)
1666 {
1667 List *attnums;
1668 ListCell *cur;
1669
1670 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_null);
1671
1672 foreach(cur, attnums)
1673 {
1674 int attnum = lfirst_int(cur);
1675 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1676
1677 if (!list_member_int(cstate->attnumlist, attnum))
1678 ereport(ERROR,
1680 /*- translator: first %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1681 errmsg("%s column \"%s\" not referenced by COPY",
1682 "FORCE_NULL", NameStr(attr->attname))));
1683 cstate->opts.force_null_flags[attnum - 1] = true;
1684 }
1685 }
1686
1687 /* Convert convert_selectively name list to per-column flags */
1688 if (cstate->opts.convert_selectively)
1689 {
1690 List *attnums;
1691 ListCell *cur;
1692
1693 cstate->convert_select_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1694
1695 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.convert_select);
1696
1697 foreach(cur, attnums)
1698 {
1699 int attnum = lfirst_int(cur);
1700 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1701
1702 if (!list_member_int(cstate->attnumlist, attnum))
1703 ereport(ERROR,
1705 errmsg_internal("selected column \"%s\" not referenced by COPY",
1706 NameStr(attr->attname))));
1707 cstate->convert_select_flags[attnum - 1] = true;
1708 }
1709 }
1710
1711 /* Use client encoding when ENCODING option is not specified. */
1712 if (cstate->opts.file_encoding < 0)
1714 else
1715 cstate->file_encoding = cstate->opts.file_encoding;
1716
1717 /*
1718 * Look up encoding conversion function.
1719 */
1720 if (cstate->file_encoding == GetDatabaseEncoding() ||
1721 cstate->file_encoding == PG_SQL_ASCII ||
1723 {
1724 cstate->need_transcoding = false;
1725 }
1726 else
1727 {
1728 cstate->need_transcoding = true;
1731 if (!OidIsValid(cstate->conversion_proc))
1732 ereport(ERROR,
1734 errmsg("default conversion function for encoding \"%s\" to \"%s\" does not exist",
1737 }
1738
1739 cstate->copy_src = COPY_FILE; /* default */
1740
1741 cstate->whereClause = whereClause;
1742
1743 /* Initialize state variables */
1744 cstate->eol_type = EOL_UNKNOWN;
1745 cstate->cur_relname = RelationGetRelationName(cstate->rel);
1746 cstate->cur_lineno = 0;
1747 cstate->cur_attname = NULL;
1748 cstate->cur_attval = NULL;
1749 cstate->relname_only = false;
1750 cstate->simd_enabled = true;
1751
1752 /*
1753 * Allocate buffers for the input pipeline.
1754 *
1755 * attribute_buf and raw_buf are used in both text and binary modes, but
1756 * input_buf and line_buf only in text mode.
1757 */
1758 cstate->raw_buf = palloc(RAW_BUF_SIZE + 1);
1759 cstate->raw_buf_index = cstate->raw_buf_len = 0;
1760 cstate->raw_reached_eof = false;
1761
1762 initStringInfo(&cstate->attribute_buf);
1763
1764 /* Assign range table and rteperminfos, we'll need them in CopyFrom. */
1765 if (pstate)
1766 {
1767 cstate->range_table = pstate->p_rtable;
1768 cstate->rteperminfos = pstate->p_rteperminfos;
1769 }
1770
1771 num_defaults = 0;
1772 volatile_defexprs = false;
1773
1774 /*
1775 * Pick up the required catalog information for each attribute in the
1776 * relation, including the input function, the element type (to pass to
1777 * the input function), and info about defaults and constraints. (Which
1778 * input function we use depends on text/binary format choice.)
1779 */
1780 in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1781 typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
1782 defmap = (int *) palloc(num_phys_attrs * sizeof(int));
1783 defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
1784
1785 for (int attnum = 1; attnum <= num_phys_attrs; attnum++)
1786 {
1787 Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1);
1788
1789 /* We don't need info for dropped attributes */
1790 if (att->attisdropped)
1791 continue;
1792
1793 /* Fetch the input function and typioparam info */
1794 cstate->routine->CopyFromInFunc(cstate, att->atttypid,
1795 &in_functions[attnum - 1],
1796 &typioparams[attnum - 1]);
1797
1798 /* Get default info if available */
1799 defexprs[attnum - 1] = NULL;
1800
1801 /*
1802 * We only need the default values for columns that do not appear in
1803 * the column list, unless the DEFAULT option was given. We never need
1804 * default values for generated columns.
1805 */
1806 if ((cstate->opts.default_print != NULL ||
1807 !list_member_int(cstate->attnumlist, attnum)) &&
1808 !att->attgenerated)
1809 {
1810 Expr *defexpr = (Expr *) build_column_default(cstate->rel,
1811 attnum);
1812
1813 if (defexpr != NULL)
1814 {
1815 /* Run the expression through planner */
1816 defexpr = expression_planner(defexpr);
1817
1818 /* Initialize executable expression in copycontext */
1819 defexprs[attnum - 1] = ExecInitExpr(defexpr, NULL);
1820
1821 /* if NOT copied from input */
1822 /* use default value if one exists */
1823 if (!list_member_int(cstate->attnumlist, attnum))
1824 {
1825 defmap[num_defaults] = attnum - 1;
1826 num_defaults++;
1827 }
1828
1829 /*
1830 * If a default expression looks at the table being loaded,
1831 * then it could give the wrong answer when using
1832 * multi-insert. Since database access can be dynamic this is
1833 * hard to test for exactly, so we use the much wider test of
1834 * whether the default expression is volatile. We allow for
1835 * the special case of when the default expression is the
1836 * nextval() of a sequence which in this specific case is
1837 * known to be safe for use with the multi-insert
1838 * optimization. Hence we use this special case function
1839 * checker rather than the standard check for
1840 * contain_volatile_functions(). Note also that we already
1841 * ran the expression through expression_planner().
1842 */
1843 if (!volatile_defexprs)
1844 volatile_defexprs = contain_volatile_functions_not_nextval((Node *) defexpr);
1845 }
1846 }
1847 }
1848
1849 cstate->defaults = (bool *) palloc0(tupDesc->natts * sizeof(bool));
1850
1851 /* initialize progress */
1853 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1854 cstate->bytes_processed = 0;
1855
1856 /* We keep those variables in cstate. */
1857 cstate->in_functions = in_functions;
1858 cstate->typioparams = typioparams;
1859 cstate->defmap = defmap;
1860 cstate->defexprs = defexprs;
1861 cstate->volatile_defexprs = volatile_defexprs;
1862 cstate->num_defaults = num_defaults;
1863 cstate->is_program = is_program;
1864
1865 if (data_source_cb)
1866 {
1868 cstate->copy_src = COPY_CALLBACK;
1869 cstate->data_source_cb = data_source_cb;
1870 }
1871 else if (pipe)
1872 {
1874 Assert(!is_program); /* the grammar does not allow this */
1876 ReceiveCopyBegin(cstate);
1877 else
1878 cstate->copy_file = stdin;
1879 }
1880 else
1881 {
1882 cstate->filename = pstrdup(filename);
1883
1884 if (cstate->is_program)
1885 {
1887 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R);
1888 if (cstate->copy_file == NULL)
1889 ereport(ERROR,
1891 errmsg("could not execute command \"%s\": %m",
1892 cstate->filename)));
1893 }
1894 else
1895 {
1896 struct stat st;
1897
1899 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R);
1900 if (cstate->copy_file == NULL)
1901 {
1902 /* copy errno because ereport subfunctions might change it */
1903 int save_errno = errno;
1904
1905 ereport(ERROR,
1907 errmsg("could not open file \"%s\" for reading: %m",
1908 cstate->filename),
1909 (save_errno == ENOENT || save_errno == EACCES) ?
1910 errhint("COPY FROM instructs the PostgreSQL server process to read a file. "
1911 "You may want a client-side facility such as psql's \\copy.") : 0));
1912 }
1913
1914 if (fstat(fileno(cstate->copy_file), &st))
1915 ereport(ERROR,
1917 errmsg("could not stat file \"%s\": %m",
1918 cstate->filename)));
1919
1920 if (S_ISDIR(st.st_mode))
1921 ereport(ERROR,
1923 errmsg("\"%s\" is a directory", cstate->filename)));
1924
1925 progress_vals[2] = st.st_size;
1926 }
1927 }
1928
1930
1931 cstate->routine->CopyFromStart(cstate, tupDesc);
1932
1933 MemoryContextSwitchTo(oldcontext);
1934
1935 return cstate;
1936}
int16 AttrNumber
Definition attnum.h:21
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition copy.c:1048
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 PG_BINARY_R
Definition c.h:1378
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
#define MemSet(start, val, len)
Definition c.h:1109
#define OidIsValid(objectId)
Definition c.h:860
bool contain_volatile_functions_not_nextval(Node *clause)
Definition clauses.c:684
static const CopyFromRoutine * CopyFromGetRoutine(const CopyFormatOptions *opts)
Definition copyfrom.c:158
@ EOL_UNKNOWN
#define RAW_BUF_SIZE
void ReceiveCopyBegin(CopyFromState cstate)
@ COPY_FILE
Definition copyto.c:51
@ COPY_CALLBACK
Definition copyto.c:53
@ DestRemote
Definition dest.h:89
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 int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition execExpr.c:143
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_array(type, count)
Definition fe_memutils.h:77
#define palloc0_object(type)
Definition fe_memutils.h:75
int i
Definition isn.c:77
bool list_member_int(const List *list, int datum)
Definition list.c:702
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
void * palloc(Size size)
Definition mcxt.c:1387
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
Definition namespace.c:4152
#define makeNode(_type_)
Definition nodes.h:161
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
int16 attnum
FormData_pg_attribute * Form_pg_attribute
static char * filename
Definition pg_dumpall.c:133
static int list_length(const List *l)
Definition pg_list.h:152
#define foreach_current_index(var_or_cell)
Definition pg_list.h:435
#define lfirst_int(lc)
Definition pg_list.h:173
#define foreach_int(var, lst)
Definition pg_list.h:502
@ PG_SQL_ASCII
Definition pg_wchar.h:226
#define pg_encoding_to_char
Definition pg_wchar.h:630
Expr * expression_planner(Expr *expr)
Definition planner.c:6826
CommandDest whereToSendOutput
Definition postgres.c:94
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define PROGRESS_COPY_COMMAND
Definition progress.h:174
#define PROGRESS_COPY_TYPE_FILE
Definition progress.h:183
#define PROGRESS_COPY_COMMAND_FROM
Definition progress.h:179
#define PROGRESS_COPY_TYPE
Definition progress.h:175
#define PROGRESS_COPY_TYPE_PROGRAM
Definition progress.h:184
#define PROGRESS_COPY_BYTES_TOTAL
Definition progress.h:171
#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
Node * build_column_default(Relation rel, int attrno)
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
bool force_notnull_all
Definition copy.h:89
bool convert_selectively
Definition copy.h:95
CopyOnErrorChoice on_error
Definition copy.h:96
List * force_null
Definition copy.h:92
List * convert_select
Definition copy.h:99
bool force_null_all
Definition copy.h:93
bool * force_notnull_flags
Definition copy.h:90
int file_encoding
Definition copy.h:71
bool * force_null_flags
Definition copy.h:94
char * default_print
Definition copy.h:80
List * force_notnull
Definition copy.h:88
void(* CopyFromInFunc)(CopyFromState cstate, Oid atttypid, FmgrInfo *finfo, Oid *typioparam)
Definition copyapi.h:74
void(* CopyFromStart)(CopyFromState cstate, TupleDesc tupDesc)
Definition copyapi.h:85
copy_data_source_cb data_source_cb
const struct CopyFromRoutine * routine
CopyFormatOptions opts
StringInfoData attribute_buf
MemoryContext copycontext
const char * cur_attval
const char * cur_attname
const char * cur_relname
ErrorSaveContext * escontext
Definition pg_list.h:54
Definition nodes.h:135
List * p_rteperminfos
Definition parse_node.h:212
List * p_rtable
Definition parse_node.h:211
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
bool DomainHasConstraints(Oid type_id, bool *has_volatile)
Definition typcache.c:1495
#define S_ISDIR(m)
Definition win32_port.h:315
#define fstat
Definition win32_port.h:73

References AllocateFile(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, attnum, CopyFromStateData::attnumlist, CopyFromStateData::attribute_buf, build_column_default(), CopyFromStateData::bytes_processed, contain_volatile_functions_not_nextval(), CopyFromStateData::conversion_proc, CopyFormatOptions::convert_select, CopyFromStateData::convert_select_flags, CopyFormatOptions::convert_selectively, COPY_CALLBACK, COPY_FILE, CopyFromStateData::copy_file, COPY_ON_ERROR_IGNORE, COPY_ON_ERROR_SET_NULL, COPY_ON_ERROR_STOP, CopyFromStateData::copy_src, CopyFromStateData::copycontext, CopyFromGetRoutine(), CopyFromRoutine::CopyFromInFunc, CopyFromRoutine::CopyFromStart, CopyGetAttnums(), cur, CopyFromStateData::cur_attname, CopyFromStateData::cur_attval, CopyFromStateData::cur_lineno, CopyFromStateData::cur_relname, CurrentMemoryContext, CopyFromStateData::data_source_cb, CopyFormatOptions::default_print, CopyFromStateData::defaults, CopyFromStateData::defexprs, CopyFromStateData::defmap, DestRemote, ErrorSaveContext::details_wanted, CopyFromStateData::domain_with_constraint, DomainHasConstraints(), CopyFromStateData::eol_type, EOL_UNKNOWN, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg, errmsg_internal(), ERROR, ErrorSaveContext::error_occurred, CopyFromStateData::escontext, ExecInitExpr(), expression_planner(), fb(), CopyFormatOptions::file_encoding, CopyFromStateData::file_encoding, filename, CopyFromStateData::filename, FindDefaultConversionProc(), CopyFormatOptions::force_notnull, CopyFormatOptions::force_notnull_all, CopyFormatOptions::force_notnull_flags, CopyFormatOptions::force_null, CopyFormatOptions::force_null_all, CopyFormatOptions::force_null_flags, foreach_current_index, foreach_int, fstat, GetDatabaseEncoding(), i, CopyFromStateData::in_functions, initStringInfo(), InvalidOid, CopyFromStateData::is_program, lfirst_int, list_length(), list_member_int(), makeNode, MemoryContextSwitchTo(), MemSet, NameStr, TupleDescData::natts, CopyFromStateData::need_transcoding, CopyFromStateData::num_defaults, OidIsValid, CopyFormatOptions::on_error, OpenPipeStream(), CopyFromStateData::opts, ParseState::p_rtable, ParseState::p_rteperminfos, palloc(), palloc0(), palloc0_array, palloc0_object, PG_BINARY_R, pg_encoding_to_char, pg_get_client_encoding(), PG_SQL_ASCII, pgstat_progress_start_command(), pgstat_progress_update_multi_param(), ProcessCopyOptions(), PROGRESS_COMMAND_COPY, PROGRESS_COPY_BYTES_TOTAL, PROGRESS_COPY_COMMAND, PROGRESS_COPY_COMMAND_FROM, PROGRESS_COPY_TYPE, PROGRESS_COPY_TYPE_CALLBACK, PROGRESS_COPY_TYPE_FILE, PROGRESS_COPY_TYPE_PIPE, PROGRESS_COPY_TYPE_PROGRAM, pstrdup(), CopyFromStateData::range_table, CopyFromStateData::raw_buf, CopyFromStateData::raw_buf_index, CopyFromStateData::raw_buf_len, RAW_BUF_SIZE, CopyFromStateData::raw_reached_eof, ReceiveCopyBegin(), CopyFromStateData::rel, RelationGetDescr, RelationGetRelationName, RelationGetRelid, CopyFromStateData::relname_only, CopyFromStateData::routine, CopyFromStateData::rteperminfos, S_ISDIR, CopyFromStateData::simd_enabled, stat::st_mode, stat::st_size, TupleDescAttr(), ErrorSaveContext::type, CopyFromStateData::typioparams, CopyFromStateData::volatile_defexprs, CopyFromStateData::whereClause, and whereToSendOutput.

Referenced by copy_table(), DoCopy(), file_acquire_sample_rows(), fileBeginForeignScan(), and fileReScanForeignScan().

◆ 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 
)
extern

Definition at line 769 of file copyto.c.

778{
779 CopyToState cstate;
780 bool pipe = (filename == NULL && data_dest_cb == NULL);
781 TupleDesc tupDesc;
782 int num_phys_attrs;
783 MemoryContext oldcontext;
784 const int progress_cols[] = {
787 };
788 int64 progress_vals[] = {
790 0
791 };
792 List *children = NIL;
793
794 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
795 {
796 if (rel->rd_rel->relkind == RELKIND_VIEW)
799 errmsg("cannot copy from view \"%s\"",
801 errhint("Try the COPY (SELECT ...) TO variant.")));
802 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
803 {
804 if (!RelationIsPopulated(rel))
807 errmsg("cannot copy from unpopulated materialized view \"%s\"",
809 errhint("Use the REFRESH MATERIALIZED VIEW command."));
810 }
811 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
814 errmsg("cannot copy from foreign table \"%s\"",
816 errhint("Try the COPY (SELECT ...) TO variant.")));
817 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
820 errmsg("cannot copy from sequence \"%s\"",
822 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
823 {
824 /*
825 * Collect OIDs of relation containing data, so that later
826 * DoCopyTo can copy the data from them.
827 */
829
830 foreach_oid(child, children)
831 {
832 char relkind = get_rel_relkind(child);
833
834 if (relkind == RELKIND_FOREIGN_TABLE)
835 {
836 char *relation_name = get_rel_name(child);
837
840 errmsg("cannot copy from foreign table \"%s\"", relation_name),
841 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
842 relation_name, RelationGetRelationName(rel)),
843 errhint("Try the COPY (SELECT ...) TO variant."));
844 }
845
846 /* Exclude tables with no data */
847 if (RELKIND_HAS_PARTITIONS(relkind))
848 children = foreach_delete_current(children, child);
849 }
850 }
851 else
854 errmsg("cannot copy from non-table relation \"%s\"",
856 }
857
858
859 /* Allocate workspace and zero all fields */
861
862 /*
863 * We allocate everything used by a cstate in a new memory context. This
864 * avoids memory leaks during repeated use of COPY in a query.
865 */
867 "COPY",
869
870 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
871
872 /* Extract options from the statement node tree */
873 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
874
875 /* Set format routine */
876 cstate->routine = CopyToGetRoutine(&cstate->opts);
877
878 /* Process the source/target relation or query */
879 if (rel)
880 {
882
883 cstate->rel = rel;
884
885 tupDesc = RelationGetDescr(cstate->rel);
886 cstate->partitions = children;
887 cstate->tupDesc = tupDesc;
888 }
889 else
890 {
892 Query *query;
895
896 cstate->rel = NULL;
897 cstate->partitions = NIL;
898
899 /*
900 * Run parse analysis and rewrite. Note this also acquires sufficient
901 * locks on the source table(s).
902 */
904 pstate->p_sourcetext, NULL, 0,
905 NULL);
906
907 /* check that we got back something we can work with */
908 if (rewritten == NIL)
909 {
912 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
913 }
914 else if (list_length(rewritten) > 1)
915 {
916 ListCell *lc;
917
918 /* examine queries to determine which error message to issue */
919 foreach(lc, rewritten)
920 {
921 Query *q = lfirst_node(Query, lc);
922
923 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
926 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
927 if (q->querySource == QSRC_NON_INSTEAD_RULE)
930 errmsg("DO ALSO rules are not supported for COPY")));
931 }
932
935 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
936 }
937
938 query = linitial_node(Query, rewritten);
939
940 /* The grammar allows SELECT INTO, but we don't support that */
941 if (query->utilityStmt != NULL &&
945 errmsg("COPY (SELECT INTO) is not supported")));
946
947 /* The only other utility command we could see is NOTIFY */
948 if (query->utilityStmt != NULL)
951 errmsg("COPY query must not be a utility command")));
952
953 /*
954 * Similarly the grammar doesn't enforce the presence of a RETURNING
955 * clause, but this is required here.
956 */
957 if (query->commandType != CMD_SELECT &&
958 query->returningList == NIL)
959 {
960 Assert(query->commandType == CMD_INSERT ||
961 query->commandType == CMD_UPDATE ||
962 query->commandType == CMD_DELETE ||
963 query->commandType == CMD_MERGE);
964
967 errmsg("COPY query must have a RETURNING clause")));
968 }
969
970 /* plan the query */
971 plan = pg_plan_query(query, pstate->p_sourcetext,
973
974 /*
975 * With row-level security and a user using "COPY relation TO", we
976 * have to convert the "COPY relation TO" to a query-based COPY (eg:
977 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
978 * add in any RLS clauses.
979 *
980 * When this happens, we are passed in the relid of the originally
981 * found relation (which we have locked). As the planner will look up
982 * the relation again, we double-check here to make sure it found the
983 * same one that we have locked.
984 */
985 if (queryRelId != InvalidOid)
986 {
987 /*
988 * Note that with RLS involved there may be multiple relations,
989 * and while the one we need is almost certainly first, we don't
990 * make any guarantees of that in the planner, so check the whole
991 * list and make sure we find the original relation.
992 */
993 if (!list_member_oid(plan->relationOids, queryRelId))
996 errmsg("relation referenced by COPY statement has changed")));
997 }
998
999 /*
1000 * Use a snapshot with an updated command ID to ensure this query sees
1001 * results of any previously executed queries.
1002 */
1005
1006 /* Create dest receiver for COPY OUT */
1008 ((DR_copy *) dest)->cstate = cstate;
1009
1010 /* Create a QueryDesc requesting no output */
1011 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
1014 dest, NULL, NULL, 0);
1015
1016 /*
1017 * Call ExecutorStart to prepare the plan for execution.
1018 *
1019 * ExecutorStart computes a result tupdesc for us
1020 */
1021 ExecutorStart(cstate->queryDesc, 0);
1022
1023 tupDesc = cstate->queryDesc->tupDesc;
1024 tupDesc = BlessTupleDesc(tupDesc);
1025 cstate->tupDesc = tupDesc;
1026 }
1027
1028 /* Generate or convert list of attributes to process */
1029 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1030
1031 /* Set up JSON-specific state */
1032 if (cstate->opts.format == COPY_FORMAT_JSON)
1033 {
1034 cstate->json_buf = makeStringInfo();
1035
1036 if (attnamelist != NIL && rel)
1037 {
1038 int natts = list_length(cstate->attnumlist);
1039 TupleDesc resultDesc;
1040
1041 /*
1042 * Build a TupleDesc describing only the selected columns so that
1043 * composite_to_json() emits the right column names and types.
1044 */
1045 resultDesc = CreateTemplateTupleDesc(natts);
1046
1047 foreach_int(attnum, cstate->attnumlist)
1048 {
1049 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1050
1051 TupleDescInitEntry(resultDesc,
1053 NameStr(attr->attname),
1054 attr->atttypid,
1055 attr->atttypmod,
1056 attr->attndims);
1057 }
1058
1059 TupleDescFinalize(resultDesc);
1060 cstate->tupDesc = BlessTupleDesc(resultDesc);
1061
1062 /*
1063 * Pre-allocate arrays for projecting selected column values into
1064 * sequential positions matching the custom TupleDesc.
1065 */
1066 cstate->json_projvalues = palloc_array(Datum, natts);
1067 cstate->json_projnulls = palloc_array(bool, natts);
1068 }
1069 }
1070
1071 num_phys_attrs = tupDesc->natts;
1072
1073 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
1074 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1075 if (cstate->opts.force_quote_all)
1076 {
1077 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
1078 }
1079 else if (cstate->opts.force_quote)
1080 {
1081 List *attnums;
1082 ListCell *cur;
1083
1084 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
1085
1086 foreach(cur, attnums)
1087 {
1088 int attnum = lfirst_int(cur);
1089 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1090
1091 if (!list_member_int(cstate->attnumlist, attnum))
1092 ereport(ERROR,
1094 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1095 errmsg("%s column \"%s\" not referenced by COPY",
1096 "FORCE_QUOTE", NameStr(attr->attname))));
1097 cstate->opts.force_quote_flags[attnum - 1] = true;
1098 }
1099 }
1100
1101 /* Use client encoding when ENCODING option is not specified. */
1102 if (cstate->opts.file_encoding < 0)
1104 else
1105 cstate->file_encoding = cstate->opts.file_encoding;
1106
1107 /*
1108 * Set up encoding conversion info if the file and server encodings differ
1109 * (see also pg_server_to_any).
1110 */
1111 if (cstate->file_encoding == GetDatabaseEncoding() ||
1112 cstate->file_encoding == PG_SQL_ASCII)
1113 cstate->need_transcoding = false;
1114 else
1115 cstate->need_transcoding = true;
1116
1117 /* See Multibyte encoding comment above */
1119
1120 cstate->copy_dest = COPY_FILE; /* default */
1121
1122 if (data_dest_cb)
1123 {
1125 cstate->copy_dest = COPY_CALLBACK;
1126 cstate->data_dest_cb = data_dest_cb;
1127 }
1128 else if (pipe)
1129 {
1131
1132 Assert(!is_program); /* the grammar does not allow this */
1134 cstate->copy_file = stdout;
1135 }
1136 else
1137 {
1138 cstate->filename = pstrdup(filename);
1139 cstate->is_program = is_program;
1140
1141 if (is_program)
1142 {
1144 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
1145 if (cstate->copy_file == NULL)
1146 ereport(ERROR,
1148 errmsg("could not execute command \"%s\": %m",
1149 cstate->filename)));
1150 }
1151 else
1152 {
1153 mode_t oumask; /* Pre-existing umask value */
1154 struct stat st;
1155
1157
1158 /*
1159 * Prevent write to relative path ... too easy to shoot oneself in
1160 * the foot by overwriting a database file ...
1161 */
1163 ereport(ERROR,
1165 errmsg("relative path not allowed for COPY to file")));
1166
1168 PG_TRY();
1169 {
1170 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
1171 }
1172 PG_FINALLY();
1173 {
1174 umask(oumask);
1175 }
1176 PG_END_TRY();
1177 if (cstate->copy_file == NULL)
1178 {
1179 /* copy errno because ereport subfunctions might change it */
1180 int save_errno = errno;
1181
1182 ereport(ERROR,
1184 errmsg("could not open file \"%s\" for writing: %m",
1185 cstate->filename),
1186 (save_errno == ENOENT || save_errno == EACCES) ?
1187 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1188 "You may want a client-side facility such as psql's \\copy.") : 0));
1189 }
1190
1191 if (fstat(fileno(cstate->copy_file), &st))
1192 ereport(ERROR,
1194 errmsg("could not stat file \"%s\": %m",
1195 cstate->filename)));
1196
1197 if (S_ISDIR(st.st_mode))
1198 ereport(ERROR,
1200 errmsg("\"%s\" is a directory", cstate->filename)));
1201 }
1202 }
1203
1204 /* initialize progress */
1206 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1208
1209 cstate->bytes_processed = 0;
1210
1211 MemoryContextSwitchTo(oldcontext);
1212
1213 return cstate;
1214}
#define PG_BINARY_W
Definition c.h:1379
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition copyto.c:201
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition dest.c:113
@ DestCopyOut
Definition dest.h:95
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 PG_FINALLY(...)
Definition elog.h:389
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition execMain.c:124
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define palloc_array(type, count)
Definition fe_memutils.h:76
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
#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
@ QSRC_NON_INSTEAD_RULE
Definition parsenodes.h:40
@ QSRC_QUAL_INSTEAD_RULE
Definition parsenodes.h:39
#define CURSOR_OPT_PARALLEL_OK
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define lfirst_node(type, lc)
Definition pg_list.h:176
#define linitial_node(type, l)
Definition pg_list.h:181
#define NIL
Definition pg_list.h:68
#define foreach_delete_current(lst, var_or_cell)
Definition pg_list.h:423
#define foreach_oid(var, lst)
Definition pg_list.h:503
#define plan(x)
Definition pg_regress.c:161
#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
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition postgres.c:670
uint64_t Datum
Definition postgres.h:70
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_TO
Definition progress.h:180
#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
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
CopyFormat format
Definition copy.h:73
bool force_quote_all
Definition copy.h:86
List * force_quote
Definition copy.h:85
bool * force_quote_flags
Definition copy.h:87
MemoryContext copycontext
Definition copyto.c:108
Relation rel
Definition copyto.c:86
Datum * json_projvalues
Definition copyto.c:96
const CopyToRoutine * routine
Definition copyto.c:74
copy_data_dest_cb data_dest_cb
Definition copyto.c:99
bool encoding_embeds_ascii
Definition copyto.c:83
CopyDest copy_dest
Definition copyto.c:77
bool need_transcoding
Definition copyto.c:82
bool is_program
Definition copyto.c:90
FILE * copy_file
Definition copyto.c:78
bool * json_projnulls
Definition copyto.c:98
int file_encoding
Definition copyto.c:81
CopyFormatOptions opts
Definition copyto.c:101
uint64 bytes_processed
Definition copyto.c:112
char * filename
Definition copyto.c:89
List * attnumlist
Definition copyto.c:88
QueryDesc * queryDesc
Definition copyto.c:87
TupleDesc tupDesc
Definition copyto.c:94
List * partitions
Definition copyto.c:103
StringInfo json_buf
Definition copyto.c:92
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
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:511
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:900
#define S_IWOTH
Definition win32_port.h:306
#define S_IWGRP
Definition win32_port.h:294

References AccessShareLock, AllocateFile(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, attnum, CopyToStateData::attnumlist, BlessTupleDesc(), CopyToStateData::bytes_processed, CMD_DELETE, CMD_INSERT, CMD_MERGE, CMD_SELECT, CMD_UPDATE, Query::commandType, COPY_CALLBACK, CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, COPY_FORMAT_JSON, CopyToStateData::copycontext, CopyGetAttnums(), CopyToGetRoutine(), CreateDestReceiver(), CreateQueryDesc(), CreateTemplateTupleDesc(), cur, CurrentMemoryContext, CURSOR_OPT_PARALLEL_OK, CopyToStateData::data_dest_cb, DestCopyOut, DestRemote, CopyToStateData::encoding_embeds_ascii, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg, ERROR, ExecutorStart(), fb(), CopyToStateData::file_encoding, CopyFormatOptions::file_encoding, CopyToStateData::filename, filename, find_all_inheritors(), CopyFormatOptions::force_quote, CopyFormatOptions::force_quote_all, CopyFormatOptions::force_quote_flags, foreach_current_index, foreach_delete_current, foreach_int, foreach_oid, CopyFormatOptions::format, fstat, get_rel_name(), get_rel_relkind(), GetActiveSnapshot(), GetDatabaseEncoding(), InvalidOid, InvalidSnapshot, is_absolute_path, CopyToStateData::is_program, IsA, CopyToStateData::json_buf, CopyToStateData::json_projnulls, CopyToStateData::json_projvalues, lfirst_int, lfirst_node, linitial_node, list_length(), list_member_int(), list_member_oid(), makeStringInfo(), MemoryContextSwitchTo(), MemSet, NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, NIL, OpenPipeStream(), CopyToStateData::opts, ParseState::p_sourcetext, palloc0(), palloc0_object, palloc_array, CopyToStateData::partitions, pg_analyze_and_rewrite_fixedparams(), PG_BINARY_W, PG_ENCODING_IS_CLIENT_ONLY, PG_END_TRY, PG_FINALLY, pg_get_client_encoding(), pg_plan_query(), PG_SQL_ASCII, PG_TRY, pgstat_progress_start_command(), pgstat_progress_update_multi_param(), plan, ProcessCopyOptions(), PROGRESS_COMMAND_COPY, PROGRESS_COPY_COMMAND, PROGRESS_COPY_COMMAND_TO, PROGRESS_COPY_TYPE, PROGRESS_COPY_TYPE_CALLBACK, PROGRESS_COPY_TYPE_FILE, PROGRESS_COPY_TYPE_PIPE, PROGRESS_COPY_TYPE_PROGRAM, pstrdup(), PushCopiedSnapshot(), QSRC_NON_INSTEAD_RULE, QSRC_QUAL_INSTEAD_RULE, CopyToStateData::queryDesc, RelationData::rd_rel, CopyToStateData::rel, RelationGetDescr, RelationGetRelationName, RelationGetRelid, RelationIsPopulated, Query::returningList, CopyToStateData::routine, S_ISDIR, S_IWGRP, S_IWOTH, stat::st_mode, CopyToStateData::tupDesc, QueryDesc::tupDesc, TupleDescAttr(), TupleDescFinalize(), TupleDescInitEntry(), UpdateActiveSnapshotCommandId(), Query::utilityStmt, and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ CopyFrom()

uint64 CopyFrom ( CopyFromState  cstate)
extern

Definition at line 781 of file copyfrom.c.

782{
783 ResultRelInfo *resultRelInfo;
786 EState *estate = CreateExecutorState(); /* for ExecConstraints() */
787 ModifyTableState *mtstate;
788 ExprContext *econtext;
791
792 PartitionTupleRouting *proute = NULL;
793 ErrorContextCallback errcallback;
794 CommandId mycid = GetCurrentCommandId(true);
795 int ti_options = 0; /* start with default options for insert */
796 BulkInsertState bistate = NULL;
798 CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */
799 int64 processed = 0;
800 int64 excluded = 0;
803 bool leafpart_use_multi_insert = false;
804
805 Assert(cstate->rel);
806 Assert(list_length(cstate->range_table) == 1);
807
808 if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
809 Assert(cstate->escontext);
810
811 /*
812 * The target must be a plain, foreign, or partitioned relation, or have
813 * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only
814 * allowed on views, so we only hint about them in the view case.)
815 */
816 if (cstate->rel->rd_rel->relkind != RELKIND_RELATION &&
817 cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
818 cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
819 !(cstate->rel->trigdesc &&
821 {
822 if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
825 errmsg("cannot copy to view \"%s\"",
827 errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
828 else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW)
831 errmsg("cannot copy to materialized view \"%s\"",
832 RelationGetRelationName(cstate->rel))));
833 else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
836 errmsg("cannot copy to sequence \"%s\"",
837 RelationGetRelationName(cstate->rel))));
838 else
841 errmsg("cannot copy to non-table relation \"%s\"",
842 RelationGetRelationName(cstate->rel))));
843 }
844
845 /*
846 * If the target file is new-in-transaction, we assume that checking FSM
847 * for free space is a waste of time. This could possibly be wrong, but
848 * it's unlikely.
849 */
850 if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) &&
853 ti_options |= TABLE_INSERT_SKIP_FSM;
854
855 /*
856 * Optimize if new relation storage was created in this subxact or one of
857 * its committed children and we won't see those rows later as part of an
858 * earlier scan or command. The subxact test ensures that if this subxact
859 * aborts then the frozen rows won't be visible after xact cleanup. Note
860 * that the stronger test of exactly which subtransaction created it is
861 * crucial for correctness of this optimization. The test for an earlier
862 * scan or command tolerates false negatives. FREEZE causes other sessions
863 * to see rows they would not see under MVCC, and a false negative merely
864 * spreads that anomaly to the current session.
865 */
866 if (cstate->opts.freeze)
867 {
868 /*
869 * We currently disallow COPY FREEZE on partitioned tables. The
870 * reason for this is that we've simply not yet opened the partitions
871 * to determine if the optimization can be applied to them. We could
872 * go and open them all here, but doing so may be quite a costly
873 * overhead for small copies. In any case, we may just end up routing
874 * tuples to a small number of partitions. It seems better just to
875 * raise an ERROR for partitioned tables.
876 */
877 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
878 {
881 errmsg("cannot perform COPY FREEZE on a partitioned table")));
882 }
883
884 /* There's currently no support for COPY FREEZE on foreign tables. */
885 if (cstate->rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
888 errmsg("cannot perform COPY FREEZE on a foreign table")));
889
890 /*
891 * Tolerate one registration for the benefit of FirstXactSnapshot.
892 * Scan-bearing queries generally create at least two registrations,
893 * though relying on that is fragile, as is ignoring ActiveSnapshot.
894 * Clear CatalogSnapshot to avoid counting its registration. We'll
895 * still detect ongoing catalog scans, each of which separately
896 * registers the snapshot it uses.
897 */
902 errmsg("cannot perform COPY FREEZE because of prior transaction activity")));
903
908 errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction")));
909
910 ti_options |= TABLE_INSERT_FROZEN;
911 }
912
913 /*
914 * We need a ResultRelInfo so we can use the regular executor's
915 * index-entry-making machinery. (There used to be a huge amount of code
916 * here that basically duplicated execUtils.c ...)
917 */
918 ExecInitRangeTable(estate, cstate->range_table, cstate->rteperminfos,
921 ExecInitResultRelation(estate, resultRelInfo, 1);
922
923 /* Verify the named relation is a valid target for INSERT */
925
926 ExecOpenIndices(resultRelInfo, false);
927
928 /*
929 * Set up a ModifyTableState so we can let FDW(s) init themselves for
930 * foreign-table result relation(s).
931 */
932 mtstate = makeNode(ModifyTableState);
933 mtstate->ps.plan = NULL;
934 mtstate->ps.state = estate;
935 mtstate->operation = CMD_INSERT;
936 mtstate->mt_nrels = 1;
937 mtstate->resultRelInfo = resultRelInfo;
938 mtstate->rootResultRelInfo = resultRelInfo;
939
940 if (resultRelInfo->ri_FdwRoutine != NULL &&
941 resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
942 resultRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate,
943 resultRelInfo);
944
945 /*
946 * Also, if the named relation is a foreign table, determine if the FDW
947 * supports batch insert and determine the batch size (a FDW may support
948 * batching, but it may be disabled for the server/table).
949 *
950 * If the FDW does not support batching, we set the batch size to 1.
951 */
952 if (resultRelInfo->ri_FdwRoutine != NULL &&
955 resultRelInfo->ri_BatchSize =
956 resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize(resultRelInfo);
957 else
958 resultRelInfo->ri_BatchSize = 1;
959
960 Assert(resultRelInfo->ri_BatchSize >= 1);
961
962 /* Prepare to catch AFTER triggers. */
964
965 /*
966 * If there are any triggers with transition tables on the named relation,
967 * we need to be prepared to capture transition tuples.
968 *
969 * Because partition tuple routing would like to know about whether
970 * transition capture is active, we also set it in mtstate, which is
971 * passed to ExecFindPartition() below.
972 */
973 cstate->transition_capture = mtstate->mt_transition_capture =
975 RelationGetRelid(cstate->rel),
976 CMD_INSERT);
977
978 /*
979 * If the named relation is a partitioned table, initialize state for
980 * CopyFrom tuple routing.
981 */
982 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
983 proute = ExecSetupPartitionTupleRouting(estate, cstate->rel);
984
985 if (cstate->whereClause)
986 cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause),
987 &mtstate->ps);
988
989 /*
990 * It's generally more efficient to prepare a bunch of tuples for
991 * insertion, and insert them in one
992 * table_multi_insert()/ExecForeignBatchInsert() call, than call
993 * table_tuple_insert()/ExecForeignInsert() separately for every tuple.
994 * However, there are a number of reasons why we might not be able to do
995 * this. These are explained below.
996 */
997 if (resultRelInfo->ri_TrigDesc != NULL &&
998 (resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
999 resultRelInfo->ri_TrigDesc->trig_insert_instead_row))
1000 {
1001 /*
1002 * Can't support multi-inserts when there are any BEFORE/INSTEAD OF
1003 * triggers on the table. Such triggers might query the table we're
1004 * inserting into and act differently if the tuples that have already
1005 * been processed and prepared for insertion are not there.
1006 */
1008 }
1009 else if (resultRelInfo->ri_FdwRoutine != NULL &&
1010 resultRelInfo->ri_BatchSize == 1)
1011 {
1012 /*
1013 * Can't support multi-inserts to a foreign table if the FDW does not
1014 * support batching, or it's disabled for the server or foreign table.
1015 */
1017 }
1018 else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL &&
1019 resultRelInfo->ri_TrigDesc->trig_insert_new_table)
1020 {
1021 /*
1022 * For partitioned tables we can't support multi-inserts when there
1023 * are any statement level insert triggers. It might be possible to
1024 * allow partitioned tables with such triggers in the future, but for
1025 * now, CopyMultiInsertInfoFlush expects that any after row insert and
1026 * statement level insert triggers are on the same relation.
1027 */
1029 }
1030 else if (cstate->volatile_defexprs)
1031 {
1032 /*
1033 * Can't support multi-inserts if there are any volatile default
1034 * expressions in the table. Similarly to the trigger case above,
1035 * such expressions may query the table we're inserting into.
1036 *
1037 * Note: It does not matter if any partitions have any volatile
1038 * default expressions as we use the defaults from the target of the
1039 * COPY command.
1040 */
1042 }
1043 else if (contain_volatile_functions(cstate->whereClause))
1044 {
1045 /*
1046 * Can't support multi-inserts if there are any volatile function
1047 * expressions in WHERE clause. Similarly to the trigger case above,
1048 * such expressions may query the table we're inserting into.
1049 *
1050 * Note: the whereClause was already preprocessed in DoCopy(), so it's
1051 * okay to use contain_volatile_functions() directly.
1052 */
1054 }
1055 else
1056 {
1057 /*
1058 * For partitioned tables, we may still be able to perform bulk
1059 * inserts. However, the possibility of this depends on which types
1060 * of triggers exist on the partition. We must disable bulk inserts
1061 * if the partition is a foreign table that can't use batching or it
1062 * has any before row insert or insert instead triggers (same as we
1063 * checked above for the parent table). Since the partition's
1064 * resultRelInfos are initialized only when we actually need to insert
1065 * the first tuple into them, we must have the intermediate insert
1066 * method of CIM_MULTI_CONDITIONAL to flag that we must later
1067 * determine if we can use bulk-inserts for the partition being
1068 * inserted into.
1069 */
1070 if (proute)
1072 else
1074
1075 CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate,
1076 estate, mycid, ti_options);
1077 }
1078
1079 /*
1080 * If not using batch mode (which allocates slots as needed) set up a
1081 * tuple slot too. When inserting into a partitioned table, we also need
1082 * one, even if we might batch insert, to read the tuple in the root
1083 * partition's form.
1084 */
1086 {
1088 &estate->es_tupleTable);
1089 bistate = GetBulkInsertState();
1090 }
1091
1092 has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1093 resultRelInfo->ri_TrigDesc->trig_insert_before_row);
1094
1095 has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1096 resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
1097
1098 /*
1099 * Check BEFORE STATEMENT insertion triggers. It's debatable whether we
1100 * should do this for COPY, since it's not really an "INSERT" statement as
1101 * such. However, executing these triggers maintains consistency with the
1102 * EACH ROW triggers that we already fire on COPY.
1103 */
1104 ExecBSInsertTriggers(estate, resultRelInfo);
1105
1106 econtext = GetPerTupleExprContext(estate);
1107
1108 /* Set up callback to identify error line number */
1109 errcallback.callback = CopyFromErrorCallback;
1110 errcallback.arg = cstate;
1111 errcallback.previous = error_context_stack;
1112 error_context_stack = &errcallback;
1113
1114 for (;;)
1115 {
1117 bool skip_tuple;
1118
1120
1121 /*
1122 * Reset the per-tuple exprcontext. We do this after every tuple, to
1123 * clean-up after expression evaluations etc.
1124 */
1126
1127 /* select slot to (initially) load row into */
1128 if (insertMethod == CIM_SINGLE || proute)
1129 {
1131 Assert(myslot != NULL);
1132 }
1133 else
1134 {
1135 Assert(resultRelInfo == target_resultRelInfo);
1137
1139 resultRelInfo);
1140 }
1141
1142 /*
1143 * Switch to per-tuple context before calling NextCopyFrom, which does
1144 * evaluate default expressions etc. and requires per-tuple context.
1145 */
1147
1149
1150 /* Directly store the values/nulls array in the slot */
1151 if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
1152 break;
1153
1154 if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE &&
1155 cstate->escontext->error_occurred)
1156 {
1157 /*
1158 * Soft error occurred, skip this tuple and just make
1159 * ErrorSaveContext ready for the next NextCopyFrom. Since we
1160 * don't set details_wanted and error_data is not to be filled,
1161 * just resetting error_occurred is enough.
1162 */
1163 cstate->escontext->error_occurred = false;
1164
1165 /* Report that this tuple was skipped by the ON_ERROR clause */
1167 cstate->num_errors);
1168
1169 if (cstate->opts.reject_limit > 0 &&
1170 cstate->num_errors > cstate->opts.reject_limit)
1171 ereport(ERROR,
1173 errmsg("skipped more than REJECT_LIMIT (%" PRId64 ") rows due to data type incompatibility",
1174 cstate->opts.reject_limit)));
1175
1176 /* Repeat NextCopyFrom() until no soft error occurs */
1177 continue;
1178 }
1179
1181
1182 /*
1183 * Constraints and where clause might reference the tableoid column,
1184 * so (re-)initialize tts_tableOid before evaluating them.
1185 */
1186 myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc);
1187
1188 /* Triggers and stuff need to be invoked in query context. */
1189 MemoryContextSwitchTo(oldcontext);
1190
1191 if (cstate->whereClause)
1192 {
1193 econtext->ecxt_scantuple = myslot;
1194 /* Skip items that don't match COPY's WHERE clause */
1195 if (!ExecQual(cstate->qualexpr, econtext))
1196 {
1197 /*
1198 * Report that this tuple was filtered out by the WHERE
1199 * clause.
1200 */
1202 ++excluded);
1203 continue;
1204 }
1205 }
1206
1207 /* Determine the partition to insert the tuple into */
1208 if (proute)
1209 {
1210 TupleConversionMap *map;
1211
1212 /*
1213 * Attempt to find a partition suitable for this tuple.
1214 * ExecFindPartition() will raise an error if none can be found or
1215 * if the found partition is not suitable for INSERTs.
1216 */
1217 resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo,
1218 proute, myslot, estate);
1219
1220 if (prevResultRelInfo != resultRelInfo)
1221 {
1222 /* Determine which triggers exist on this partition */
1223 has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1224 resultRelInfo->ri_TrigDesc->trig_insert_before_row);
1225
1226 has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1227 resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
1228
1229 /*
1230 * Disable multi-inserts when the partition has BEFORE/INSTEAD
1231 * OF triggers, or if the partition is a foreign table that
1232 * can't use batching.
1233 */
1237 (resultRelInfo->ri_FdwRoutine == NULL ||
1238 resultRelInfo->ri_BatchSize > 1);
1239
1240 /* Set the multi-insert buffer to use for this partition. */
1242 {
1243 if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL)
1245 resultRelInfo);
1246 }
1247 else if (insertMethod == CIM_MULTI_CONDITIONAL &&
1249 {
1250 /*
1251 * Flush pending inserts if this partition can't use
1252 * batching, so rows are visible to triggers etc.
1253 */
1255 resultRelInfo,
1256 &processed);
1257 }
1258
1259 if (bistate != NULL)
1261 prevResultRelInfo = resultRelInfo;
1262 }
1263
1264 /*
1265 * If we're capturing transition tuples, we might need to convert
1266 * from the partition rowtype to root rowtype. But if there are no
1267 * BEFORE triggers on the partition that could change the tuple,
1268 * we can just remember the original unconverted tuple to avoid a
1269 * needless round trip conversion.
1270 */
1271 if (cstate->transition_capture != NULL)
1274
1275 /*
1276 * We might need to convert from the root rowtype to the partition
1277 * rowtype.
1278 */
1279 map = ExecGetRootToChildMap(resultRelInfo, estate);
1281 {
1282 /* non batch insert */
1283 if (map != NULL)
1284 {
1285 TupleTableSlot *new_slot;
1286
1287 new_slot = resultRelInfo->ri_PartitionTupleSlot;
1288 myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
1289 }
1290 }
1291 else
1292 {
1293 /*
1294 * Prepare to queue up tuple for later batch insert into
1295 * current partition.
1296 */
1298
1299 /* no other path available for partitioned table */
1301
1303 resultRelInfo);
1304
1305 if (map != NULL)
1307 batchslot);
1308 else
1309 {
1310 /*
1311 * This looks more expensive than it is (Believe me, I
1312 * optimized it away. Twice.). The input is in virtual
1313 * form, and we'll materialize the slot below - for most
1314 * slot types the copy performs the work materialization
1315 * would later require anyway.
1316 */
1318 myslot = batchslot;
1319 }
1320 }
1321
1322 /* ensure that triggers etc see the right relation */
1323 myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1324 }
1325
1326 skip_tuple = false;
1327
1328 /* BEFORE ROW INSERT Triggers */
1330 {
1331 if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot))
1332 skip_tuple = true; /* "do nothing" */
1333 }
1334
1335 if (!skip_tuple)
1336 {
1337 /*
1338 * If there is an INSTEAD OF INSERT ROW trigger, let it handle the
1339 * tuple. Otherwise, proceed with inserting the tuple into the
1340 * table or foreign table.
1341 */
1343 {
1344 ExecIRInsertTriggers(estate, resultRelInfo, myslot);
1345 }
1346 else
1347 {
1348 /* Compute stored generated columns */
1349 if (resultRelInfo->ri_RelationDesc->rd_att->constr &&
1351 ExecComputeStoredGenerated(resultRelInfo, estate, myslot,
1352 CMD_INSERT);
1353
1354 /*
1355 * If the target is a plain table, check the constraints of
1356 * the tuple.
1357 */
1358 if (resultRelInfo->ri_FdwRoutine == NULL &&
1359 resultRelInfo->ri_RelationDesc->rd_att->constr)
1360 ExecConstraints(resultRelInfo, myslot, estate);
1361
1362 /*
1363 * Also check the tuple against the partition constraint, if
1364 * there is one; except that if we got here via tuple-routing,
1365 * we don't need to if there's no BR trigger defined on the
1366 * partition.
1367 */
1368 if (resultRelInfo->ri_RelationDesc->rd_rel->relispartition &&
1369 (proute == NULL || has_before_insert_row_trig))
1370 ExecPartitionCheck(resultRelInfo, myslot, estate, true);
1371
1372 /* Store the slot in the multi-insert buffer, when enabled. */
1374 {
1375 /*
1376 * The slot previously might point into the per-tuple
1377 * context. For batching it needs to be longer lived.
1378 */
1380
1381 /* Add this tuple to the tuple buffer */
1383 resultRelInfo, myslot,
1384 cstate->line_buf.len,
1385 cstate->cur_lineno);
1386
1387 /*
1388 * If enough inserts have queued up, then flush all
1389 * buffers out to their tables.
1390 */
1393 resultRelInfo,
1394 &processed);
1395
1396 /*
1397 * We delay updating the row counter and progress of the
1398 * COPY command until after writing the tuples stored in
1399 * the buffer out to the table, as in single insert mode.
1400 * See CopyMultiInsertBufferFlush().
1401 */
1402 continue; /* next tuple please */
1403 }
1404 else
1405 {
1407
1408 /* OK, store the tuple */
1409 if (resultRelInfo->ri_FdwRoutine != NULL)
1410 {
1411 myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate,
1412 resultRelInfo,
1413 myslot,
1414 NULL);
1415
1416 if (myslot == NULL) /* "do nothing" */
1417 continue; /* next tuple please */
1418
1419 /*
1420 * AFTER ROW Triggers might reference the tableoid
1421 * column, so (re-)initialize tts_tableOid before
1422 * evaluating them.
1423 */
1424 myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1425 }
1426 else
1427 {
1428 /* OK, store the tuple and create index entries for it */
1429 table_tuple_insert(resultRelInfo->ri_RelationDesc,
1430 myslot, mycid, ti_options, bistate);
1431
1432 if (resultRelInfo->ri_NumIndices > 0)
1433 recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
1434 estate, 0,
1435 myslot, NIL,
1436 NULL);
1437 }
1438
1439 /* AFTER ROW INSERT Triggers */
1440 ExecARInsertTriggers(estate, resultRelInfo, myslot,
1442
1444 }
1445 }
1446
1447 /*
1448 * We count only tuples not suppressed by a BEFORE INSERT trigger
1449 * or FDW; this is the same definition used by nodeModifyTable.c
1450 * for counting tuples inserted by an INSERT command. Update
1451 * progress of the COPY command as well.
1452 */
1454 ++processed);
1455 }
1456 }
1457
1458 /* Flush any remaining buffered tuples */
1459 if (insertMethod != CIM_SINGLE)
1460 {
1463 }
1464
1465 /* Done, clean up */
1466 error_context_stack = errcallback.previous;
1467
1468 if (cstate->num_errors > 0 &&
1470 {
1471 if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE)
1473 errmsg_plural("%" PRIu64 " row was skipped due to data type incompatibility",
1474 "%" PRIu64 " rows were skipped due to data type incompatibility",
1475 cstate->num_errors,
1476 cstate->num_errors));
1477 else if (cstate->opts.on_error == COPY_ON_ERROR_SET_NULL)
1479 errmsg_plural("in %" PRIu64 " row, columns were set to null due to data type incompatibility",
1480 "in %" PRIu64 " rows, columns were set to null due to data type incompatibility",
1481 cstate->num_errors,
1482 cstate->num_errors));
1483 }
1484
1485 if (bistate != NULL)
1486 FreeBulkInsertState(bistate);
1487
1488 MemoryContextSwitchTo(oldcontext);
1489
1490 /* Execute AFTER STATEMENT insertion triggers */
1492
1493 /* Handle queued AFTER triggers */
1494 AfterTriggerEndQuery(estate);
1495
1496 ExecResetTupleTable(estate->es_tupleTable, false);
1497
1498 /* Allow the FDW to shut down */
1499 if (target_resultRelInfo->ri_FdwRoutine != NULL &&
1500 target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
1501 target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate,
1503
1504 /* Tear down the multi-insert buffer data */
1505 if (insertMethod != CIM_SINGLE)
1507
1508 /* Close all the partitioned tables, leaf partitions, and their indices */
1509 if (proute)
1510 ExecCleanupTupleRouting(mtstate, proute);
1511
1512 /* Close the result relations, including any trigger target relations */
1515
1516 FreeExecutorState(estate);
1517
1518 return processed;
1519}
void pgstat_progress_update_param(int index, int64 val)
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
#define InvalidSubTransactionId
Definition c.h:744
uint32 CommandId
Definition c.h:752
bool contain_volatile_functions(Node *clause)
Definition clauses.c:549
static void CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition copyfrom.c:382
static TupleTableSlot * CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition copyfrom.c:737
static void CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, CopyFromState cstate, EState *estate, CommandId mycid, int ti_options)
Definition copyfrom.c:402
static void CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri, int64 *processed)
Definition copyfrom.c:664
static void CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, TupleTableSlot *slot, int tuplen, uint64 lineno)
Definition copyfrom.c:758
static void CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo)
Definition copyfrom.c:718
static bool CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo)
Definition copyfrom.c:427
static bool CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo)
Definition copyfrom.c:439
void CopyFromErrorCallback(void *arg)
Definition copyfrom.c:256
CopyInsertMethod
@ CIM_SINGLE
@ CIM_MULTI_CONDITIONAL
@ CIM_MULTI
bool NextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
ErrorContextCallback * error_context_stack
Definition elog.c:99
int int int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define NOTICE
Definition elog.h:35
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition execExpr.c:250
List * ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, EState *estate, bits32 flags, TupleTableSlot *slot, List *arbiterIndexes, bool *specConflict)
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, OnConflictAction onConflictAction, List *mergeActions)
Definition execMain.c:1056
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition execMain.c:1875
void ExecCloseResultRelations(EState *estate)
Definition execMain.c:1594
void ExecCloseRangeTableRelations(EState *estate)
Definition execMain.c:1654
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition execMain.c:1999
PartitionTupleRouting * ExecSetupPartitionTupleRouting(EState *estate, Relation rel)
ResultRelInfo * ExecFindPartition(ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)
void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute)
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
Definition execUtils.c:1331
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos, Bitmapset *unpruned_relids)
Definition execUtils.c:778
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
Definition execUtils.c:885
void FreeExecutorState(EState *estate)
Definition execUtils.c:197
EState * CreateExecutorState(void)
Definition execUtils.c:90
#define ResetPerTupleExprContext(estate)
Definition executor.h:669
#define GetPerTupleExprContext(estate)
Definition executor.h:660
#define GetPerTupleMemoryContext(estate)
Definition executor.h:665
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition executor.h:522
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
Definition heapam.c:2114
BulkInsertState GetBulkInsertState(void)
Definition heapam.c:2085
void FreeBulkInsertState(BulkInsertState bistate)
Definition heapam.c:2102
void list_free(List *list)
Definition list.c:1546
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
void ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot, CmdType cmdtype)
@ ONCONFLICT_NONE
Definition nodes.h:428
#define castNode(_type_, nodeptr)
Definition nodes.h:182
bool ThereAreNoReadyPortals(void)
Definition portalmem.c:1173
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition progress.h:172
#define PROGRESS_COPY_TUPLES_EXCLUDED
Definition progress.h:173
#define PROGRESS_COPY_TUPLES_SKIPPED
Definition progress.h:176
bool ThereAreNoPriorRegisteredSnapshots(void)
Definition snapmgr.c:1626
void InvalidateCatalogSnapshot(void)
Definition snapmgr.c:455
CopyLogVerbosityChoice log_verbosity
Definition copy.h:97
int64 reject_limit
Definition copy.h:98
StringInfoData line_buf
TransitionCaptureState * transition_capture
List * es_tupleTable
Definition execnodes.h:724
struct ErrorContextCallback * previous
Definition elog.h:297
void(* callback)(void *arg)
Definition elog.h:298
TupleTableSlot * ecxt_scantuple
Definition execnodes.h:284
BeginForeignInsert_function BeginForeignInsert
Definition fdwapi.h:238
ExecForeignInsert_function ExecForeignInsert
Definition fdwapi.h:232
ExecForeignBatchInsert_function ExecForeignBatchInsert
Definition fdwapi.h:233
GetForeignModifyBatchSize_function GetForeignModifyBatchSize
Definition fdwapi.h:234
ResultRelInfo * resultRelInfo
Definition execnodes.h:1420
ResultRelInfo * rootResultRelInfo
Definition execnodes.h:1428
struct TransitionCaptureState * mt_transition_capture
Definition execnodes.h:1454
Plan * plan
Definition execnodes.h:1177
EState * state
Definition execnodes.h:1179
SubTransactionId rd_firstRelfilelocatorSubid
Definition rel.h:106
TriggerDesc * trigdesc
Definition rel.h:117
TupleDesc rd_att
Definition rel.h:112
SubTransactionId rd_newRelfilelocatorSubid
Definition rel.h:104
SubTransactionId rd_createSubid
Definition rel.h:103
TupleTableSlot * ri_PartitionTupleSlot
Definition execnodes.h:631
Relation ri_RelationDesc
Definition execnodes.h:492
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition execnodes.h:634
TriggerDesc * ri_TrigDesc
Definition execnodes.h:527
struct FdwRoutine * ri_FdwRoutine
Definition execnodes.h:545
TupleTableSlot * tcs_original_insert_tuple
Definition trigger.h:76
bool trig_insert_instead_row
Definition reltrigger.h:58
bool trig_insert_new_table
Definition reltrigger.h:75
bool trig_insert_before_row
Definition reltrigger.h:56
bool has_generated_stored
Definition tupdesc.h:46
AttrMap * attrMap
Definition tupconvert.h:28
TupleConstr * constr
Definition tupdesc.h:159
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92
#define TABLE_INSERT_FROZEN
Definition tableam.h:260
#define TABLE_INSERT_SKIP_FSM
Definition tableam.h:259
static void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, int options, BulkInsertStateData *bistate)
Definition tableam.h:1388
TransitionCaptureState * MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType)
Definition trigger.c:4959
void ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
Definition trigger.c:2403
bool ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition trigger.c:2467
bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition trigger.c:2571
void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture)
Definition trigger.c:2545
void ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
Definition trigger.c:2454
void AfterTriggerEndQuery(EState *estate)
Definition trigger.c:5137
void AfterTriggerBeginQuery(void)
Definition trigger.c:5117
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition tupconvert.c:193
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition tuptable.h:543
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition tuptable.h:494
SubTransactionId GetCurrentSubTransactionId(void)
Definition xact.c:793
CommandId GetCurrentCommandId(bool used)
Definition xact.c:831

References AfterTriggerBeginQuery(), AfterTriggerEndQuery(), ErrorContextCallback::arg, Assert, TupleConversionMap::attrMap, FdwRoutine::BeginForeignInsert, bms_make_singleton(), ErrorContextCallback::callback, castNode, CHECK_FOR_INTERRUPTS, CheckValidResultRel(), CIM_MULTI, CIM_MULTI_CONDITIONAL, CIM_SINGLE, CMD_INSERT, TupleDescData::constr, contain_volatile_functions(), COPY_LOG_VERBOSITY_DEFAULT, COPY_ON_ERROR_IGNORE, COPY_ON_ERROR_SET_NULL, COPY_ON_ERROR_STOP, CopyFromErrorCallback(), CopyMultiInsertInfoCleanup(), CopyMultiInsertInfoFlush(), CopyMultiInsertInfoInit(), CopyMultiInsertInfoIsEmpty(), CopyMultiInsertInfoIsFull(), CopyMultiInsertInfoNextFreeSlot(), CopyMultiInsertInfoSetupBuffer(), CopyMultiInsertInfoStore(), CreateExecutorState(), CopyFromStateData::cur_lineno, CurrentMemoryContext, ExprContext::ecxt_scantuple, ereport, errcode(), errhint(), errmsg, errmsg_plural(), ERROR, error_context_stack, ErrorSaveContext::error_occurred, EState::es_tupleTable, CopyFromStateData::escontext, ExecARInsertTriggers(), ExecASInsertTriggers(), ExecBRInsertTriggers(), ExecBSInsertTriggers(), ExecCleanupTupleRouting(), ExecClearTuple(), ExecCloseRangeTableRelations(), ExecCloseResultRelations(), ExecComputeStoredGenerated(), ExecConstraints(), ExecCopySlot(), ExecFindPartition(), FdwRoutine::ExecForeignBatchInsert, FdwRoutine::ExecForeignInsert, ExecGetRootToChildMap(), ExecInitQual(), ExecInitRangeTable(), ExecInitResultRelation(), ExecInsertIndexTuples(), ExecIRInsertTriggers(), ExecMaterializeSlot(), ExecOpenIndices(), ExecPartitionCheck(), ExecQual(), ExecResetTupleTable(), ExecSetupPartitionTupleRouting(), ExecStoreVirtualTuple(), execute_attr_map_slot(), fb(), FreeBulkInsertState(), FreeExecutorState(), CopyFormatOptions::freeze, GetBulkInsertState(), GetCurrentCommandId(), GetCurrentSubTransactionId(), FdwRoutine::GetForeignModifyBatchSize, GetPerTupleExprContext, GetPerTupleMemoryContext, TupleConstr::has_generated_stored, InvalidateCatalogSnapshot(), InvalidSubTransactionId, StringInfoData::len, CopyFromStateData::line_buf, list_free(), list_length(), CopyFormatOptions::log_verbosity, makeNode, MakeTransitionCaptureState(), MemoryContextSwitchTo(), ModifyTableState::mt_nrels, ModifyTableState::mt_transition_capture, NextCopyFrom(), NIL, NOTICE, CopyFromStateData::num_errors, CopyFormatOptions::on_error, ONCONFLICT_NONE, ModifyTableState::operation, CopyFromStateData::opts, pgstat_progress_update_param(), PlanState::plan, ErrorContextCallback::previous, PROGRESS_COPY_TUPLES_EXCLUDED, PROGRESS_COPY_TUPLES_PROCESSED, PROGRESS_COPY_TUPLES_SKIPPED, ModifyTableState::ps, CopyFromStateData::qualexpr, CopyFromStateData::range_table, RelationData::rd_att, RelationData::rd_createSubid, RelationData::rd_firstRelfilelocatorSubid, RelationData::rd_newRelfilelocatorSubid, RelationData::rd_rel, CopyFormatOptions::reject_limit, CopyFromStateData::rel, RelationGetRelationName, RelationGetRelid, ReleaseBulkInsertStatePin(), ResetPerTupleExprContext, ModifyTableState::resultRelInfo, ResultRelInfo::ri_BatchSize, ResultRelInfo::ri_CopyMultiInsertBuffer, ResultRelInfo::ri_FdwRoutine, ResultRelInfo::ri_NumIndices, ResultRelInfo::ri_PartitionTupleSlot, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_TrigDesc, ModifyTableState::rootResultRelInfo, CopyFromStateData::rteperminfos, PlanState::state, TABLE_INSERT_FROZEN, TABLE_INSERT_SKIP_FSM, table_slot_create(), table_tuple_insert(), TransitionCaptureState::tcs_original_insert_tuple, ThereAreNoPriorRegisteredSnapshots(), ThereAreNoReadyPortals(), CopyFromStateData::transition_capture, TriggerDesc::trig_insert_before_row, TriggerDesc::trig_insert_instead_row, TriggerDesc::trig_insert_new_table, RelationData::trigdesc, CopyFromStateData::volatile_defexprs, and CopyFromStateData::whereClause.

Referenced by copy_table(), and DoCopy().

◆ CopyFromErrorCallback()

void CopyFromErrorCallback ( void arg)
extern

Definition at line 256 of file copyfrom.c.

257{
259
260 if (cstate->relname_only)
261 {
262 errcontext("COPY %s",
263 cstate->cur_relname);
264 return;
265 }
266 if (cstate->opts.format == COPY_FORMAT_BINARY)
267 {
268 /* can't usefully display the data */
269 if (cstate->cur_attname)
270 errcontext("COPY %s, line %" PRIu64 ", column %s",
271 cstate->cur_relname,
272 cstate->cur_lineno,
273 cstate->cur_attname);
274 else
275 errcontext("COPY %s, line %" PRIu64,
276 cstate->cur_relname,
277 cstate->cur_lineno);
278 }
279 else
280 {
281 if (cstate->cur_attname && cstate->cur_attval)
282 {
283 /* error is relevant to a particular column */
284 char *attval;
285
287 errcontext("COPY %s, line %" PRIu64 ", column %s: \"%s\"",
288 cstate->cur_relname,
289 cstate->cur_lineno,
290 cstate->cur_attname,
291 attval);
292 pfree(attval);
293 }
294 else if (cstate->cur_attname)
295 {
296 /* error is relevant to a particular column, value is NULL */
297 errcontext("COPY %s, line %" PRIu64 ", column %s: null input",
298 cstate->cur_relname,
299 cstate->cur_lineno,
300 cstate->cur_attname);
301 }
302 else
303 {
304 /*
305 * Error is relevant to a particular line.
306 *
307 * If line_buf still contains the correct line, print it.
308 */
309 if (cstate->line_buf_valid)
310 {
311 char *lineval;
312
314 errcontext("COPY %s, line %" PRIu64 ": \"%s\"",
315 cstate->cur_relname,
316 cstate->cur_lineno, lineval);
317 pfree(lineval);
318 }
319 else
320 {
321 errcontext("COPY %s, line %" PRIu64,
322 cstate->cur_relname,
323 cstate->cur_lineno);
324 }
325 }
326 }
327}
char * CopyLimitPrintoutLength(const char *str)
Definition copyfrom.c:335
Datum arg
Definition elog.c:1322
#define errcontext
Definition elog.h:198
struct CopyFromStateData * CopyFromState
Definition copy.h:103
void pfree(void *pointer)
Definition mcxt.c:1616

References arg, COPY_FORMAT_BINARY, CopyLimitPrintoutLength(), CopyFromStateData::cur_attname, CopyFromStateData::cur_attval, CopyFromStateData::cur_lineno, CopyFromStateData::cur_relname, StringInfoData::data, errcontext, fb(), CopyFormatOptions::format, CopyFromStateData::line_buf, CopyFromStateData::line_buf_valid, CopyFromStateData::opts, pfree(), and CopyFromStateData::relname_only.

Referenced by CopyFrom(), file_acquire_sample_rows(), and fileIterateForeignScan().

◆ CopyGetAttnums()

List * CopyGetAttnums ( TupleDesc  tupDesc,
Relation  rel,
List attnamelist 
)
extern

Definition at line 1048 of file copy.c.

1049{
1050 List *attnums = NIL;
1051
1052 if (attnamelist == NIL)
1053 {
1054 /* Generate default column list */
1055 int attr_count = tupDesc->natts;
1056 int i;
1057
1058 for (i = 0; i < attr_count; i++)
1059 {
1060 CompactAttribute *attr = TupleDescCompactAttr(tupDesc, i);
1061
1062 if (attr->attisdropped || attr->attgenerated)
1063 continue;
1064 attnums = lappend_int(attnums, i + 1);
1065 }
1066 }
1067 else
1068 {
1069 /* Validate the user-supplied list and extract attnums */
1070 ListCell *l;
1071
1072 foreach(l, attnamelist)
1073 {
1074 char *name = strVal(lfirst(l));
1075 int attnum;
1076 int i;
1077
1078 /* Lookup column name */
1080 for (i = 0; i < tupDesc->natts; i++)
1081 {
1083
1084 if (att->attisdropped)
1085 continue;
1086 if (namestrcmp(&(att->attname), name) == 0)
1087 {
1088 if (att->attgenerated)
1089 ereport(ERROR,
1091 errmsg("column \"%s\" is a generated column",
1092 name),
1093 errdetail("Generated columns cannot be used in COPY.")));
1094 attnum = att->attnum;
1095 break;
1096 }
1097 }
1099 {
1100 if (rel != NULL)
1101 ereport(ERROR,
1103 errmsg("column \"%s\" of relation \"%s\" does not exist",
1105 else
1106 ereport(ERROR,
1108 errmsg("column \"%s\" does not exist",
1109 name)));
1110 }
1111 /* Check for duplicates */
1112 if (list_member_int(attnums, attnum))
1113 ereport(ERROR,
1115 errmsg("column \"%s\" specified more than once",
1116 name)));
1117 attnums = lappend_int(attnums, attnum);
1118 }
1119 }
1120
1121 return attnums;
1122}
#define InvalidAttrNumber
Definition attnum.h:23
List * lappend_int(List *list, int datum)
Definition list.c:357
int namestrcmp(Name name, const char *str)
Definition name.c:247
#define lfirst(lc)
Definition pg_list.h:172
bool attgenerated
Definition tupdesc.h:79
bool attisdropped
Definition tupdesc.h:78
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:195
#define strVal(v)
Definition value.h:82
const char * name

References CompactAttribute::attgenerated, CompactAttribute::attisdropped, attnum, ereport, errcode(), errdetail(), errmsg, ERROR, fb(), i, InvalidAttrNumber, lappend_int(), lfirst, list_member_int(), name, namestrcmp(), TupleDescData::natts, NIL, RelationGetRelationName, strVal, TupleDescAttr(), and TupleDescCompactAttr().

Referenced by BeginCopyFrom(), BeginCopyTo(), and DoCopy().

◆ CopyLimitPrintoutLength()

char * CopyLimitPrintoutLength ( const char str)
extern

Definition at line 335 of file copyfrom.c.

336{
337#define MAX_COPY_DATA_DISPLAY 100
338
339 int slen = strlen(str);
340 int len;
341 char *res;
342
343 /* Fast path if definitely okay */
345 return pstrdup(str);
346
347 /* Apply encoding-dependent truncation */
349
350 /*
351 * Truncate, and add "..." to show we truncated the input.
352 */
353 res = (char *) palloc(len + 4);
354 memcpy(res, str, len);
355 strcpy(res + len, "...");
356
357 return res;
358}
#define MAX_COPY_DATA_DISPLAY
const char * str
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition mbutils.c:1211
const void size_t len

References fb(), len, MAX_COPY_DATA_DISPLAY, palloc(), pg_mbcliplen(), pstrdup(), and str.

Referenced by CopyFromErrorCallback(), and CopyFromTextLikeOneRow().

◆ CreateCopyDestReceiver()

DestReceiver * CreateCopyDestReceiver ( void  )
extern

Definition at line 1708 of file copyto.c.

1709{
1710 DR_copy *self = palloc_object(DR_copy);
1711
1716 self->pub.mydest = DestCopyOut;
1717
1718 self->cstate = NULL; /* will be set later */
1719 self->processed = 0;
1720
1721 return (DestReceiver *) self;
1722}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1671
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1699
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1690
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1662
#define palloc_object(type)
Definition fe_memutils.h:74
CopyToState cstate
Definition copyto.c:119
DestReceiver pub
Definition copyto.c:118
uint64 processed
Definition copyto.c:120
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition dest.h:121
void(* rShutdown)(DestReceiver *self)
Definition dest.h:124
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition dest.h:118
void(* rDestroy)(DestReceiver *self)
Definition dest.h:126
CommandDest mydest
Definition dest.h:128

References copy_dest_destroy(), copy_dest_receive(), copy_dest_shutdown(), copy_dest_startup(), DR_copy::cstate, DestCopyOut, fb(), _DestReceiver::mydest, palloc_object, DR_copy::processed, DR_copy::pub, _DestReceiver::rDestroy, _DestReceiver::receiveSlot, _DestReceiver::rShutdown, and _DestReceiver::rStartup.

Referenced by CreateDestReceiver().

◆ DoCopy()

void DoCopy ( ParseState pstate,
const CopyStmt stmt,
int  stmt_location,
int  stmt_len,
uint64 processed 
)
extern

Definition at line 63 of file copy.c.

66{
67 bool is_from = stmt->is_from;
68 bool pipe = (stmt->filename == NULL);
69 Relation rel;
70 Oid relid;
71 RawStmt *query = NULL;
72 Node *whereClause = NULL;
73
74 /*
75 * Disallow COPY to/from file or program except to users with the
76 * appropriate role.
77 */
78 if (!pipe)
79 {
80 if (stmt->is_program)
81 {
85 errmsg("permission denied to COPY to or from an external program"),
86 errdetail("Only roles with privileges of the \"%s\" role may COPY to or from an external program.",
87 "pg_execute_server_program"),
88 errhint("Anyone can COPY to stdout or from stdin. "
89 "psql's \\copy command also works for anyone.")));
90 }
91 else
92 {
96 errmsg("permission denied to COPY from a file"),
97 errdetail("Only roles with privileges of the \"%s\" role may COPY from a file.",
98 "pg_read_server_files"),
99 errhint("Anyone can COPY to stdout or from stdin. "
100 "psql's \\copy command also works for anyone.")));
101
105 errmsg("permission denied to COPY to a file"),
106 errdetail("Only roles with privileges of the \"%s\" role may COPY to a file.",
107 "pg_write_server_files"),
108 errhint("Anyone can COPY to stdout or from stdin. "
109 "psql's \\copy command also works for anyone.")));
110 }
111 }
112
113 if (stmt->relation)
114 {
115 LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
118 TupleDesc tupDesc;
119 List *attnums;
120 ListCell *cur;
121
122 Assert(!stmt->query);
123
124 /* Open and lock the relation, using the appropriate lock type. */
125 rel = table_openrv(stmt->relation, lockmode);
126
127 relid = RelationGetRelid(rel);
128
129 nsitem = addRangeTableEntryForRelation(pstate, rel, lockmode,
130 NULL, false, false);
131
132 perminfo = nsitem->p_perminfo;
133 perminfo->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
134
135 if (stmt->whereClause)
136 {
138 int i;
139
140 /* add nsitem to query namespace */
141 addNSItemToQuery(pstate, nsitem, false, true, true);
142
143 /* Transform the raw expression tree */
144 whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE);
145
146 /* Make sure it yields a boolean result. */
147 whereClause = coerce_to_boolean(pstate, whereClause, "WHERE");
148
149 /* we have to fix its collations too */
150 assign_expr_collations(pstate, whereClause);
151
152 /*
153 * Examine all the columns in the WHERE clause expression. When
154 * the whole-row reference is present, examine all the columns of
155 * the table.
156 */
157 pull_varattnos(whereClause, 1, &expr_attrs);
159 {
164 }
165
166 i = -1;
167 while ((i = bms_next_member(expr_attrs, i)) >= 0)
168 {
170
171 Assert(attno != 0);
172
173 /*
174 * Prohibit generated columns in the WHERE clause. Stored
175 * generated columns are not yet computed when the filtering
176 * happens. Virtual generated columns could probably work (we
177 * would need to expand them somewhere around here), but for
178 * now we keep them consistent with the stored variant.
179 */
180 if (TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated)
183 errmsg("generated columns are not supported in COPY FROM WHERE conditions"),
184 errdetail("Column \"%s\" is a generated column.",
185 get_attname(RelationGetRelid(rel), attno, false)));
186 }
187
188 whereClause = eval_const_expressions(NULL, whereClause);
189
190 whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
191 whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
192 }
193
194 tupDesc = RelationGetDescr(rel);
195 attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist);
196 foreach(cur, attnums)
197 {
198 int attno;
199 Bitmapset **bms;
200
202 bms = is_from ? &perminfo->insertedCols : &perminfo->selectedCols;
203
204 *bms = bms_add_member(*bms, attno);
205 }
207
208 /*
209 * Permission check for row security policies.
210 *
211 * check_enable_rls will ereport(ERROR) if the user has requested
212 * something invalid and will otherwise indicate if we should enable
213 * RLS (returns RLS_ENABLED) or not for this COPY statement.
214 *
215 * If the relation has a row security policy and we are to apply it
216 * then perform a "query" copy and allow the normal query processing
217 * to handle the policies.
218 *
219 * If RLS is not enabled for this, then just fall through to the
220 * normal non-filtering relation handling.
221 */
222 if (check_enable_rls(relid, InvalidOid, false) == RLS_ENABLED)
223 {
225 ColumnRef *cr;
226 ResTarget *target;
227 RangeVar *from;
228 List *targetList = NIL;
229
230 if (is_from)
233 errmsg("COPY FROM not supported with row-level security"),
234 errhint("Use INSERT statements instead.")));
235
236 /*
237 * Build target list
238 *
239 * If no columns are specified in the attribute list of the COPY
240 * command, then the target list is 'all' columns. Therefore, '*'
241 * should be used as the target list for the resulting SELECT
242 * statement.
243 *
244 * In the case that columns are specified in the attribute list,
245 * create a ColumnRef and ResTarget for each column and add them
246 * to the target list for the resulting SELECT statement.
247 */
248 if (!stmt->attlist)
249 {
251 cr->fields = list_make1(makeNode(A_Star));
252 cr->location = -1;
253
254 target = makeNode(ResTarget);
255 target->name = NULL;
256 target->indirection = NIL;
257 target->val = (Node *) cr;
258 target->location = -1;
259
260 targetList = list_make1(target);
261 }
262 else
263 {
264 ListCell *lc;
265
266 foreach(lc, stmt->attlist)
267 {
268 /*
269 * Build the ColumnRef for each column. The ColumnRef
270 * 'fields' property is a String node that corresponds to
271 * the column name respectively.
272 */
274 cr->fields = list_make1(lfirst(lc));
275 cr->location = -1;
276
277 /* Build the ResTarget and add the ColumnRef to it. */
278 target = makeNode(ResTarget);
279 target->name = NULL;
280 target->indirection = NIL;
281 target->val = (Node *) cr;
282 target->location = -1;
283
284 /* Add each column to the SELECT statement's target list */
285 targetList = lappend(targetList, target);
286 }
287 }
288
289 /*
290 * Build RangeVar for from clause, fully qualified based on the
291 * relation which we have opened and locked. Use "ONLY" so that
292 * COPY retrieves rows from only the target table not any
293 * inheritance children, the same as when RLS doesn't apply.
294 *
295 * However, when copying data from a partitioned table, we don't
296 * use "ONLY", since we need to retrieve rows from its descendant
297 * tables too.
298 */
301 -1);
302 from->inh = (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
303
304 /* Build query */
306 select->targetList = targetList;
307 select->fromClause = list_make1(from);
308
309 query = makeNode(RawStmt);
310 query->stmt = (Node *) select;
311 query->stmt_location = stmt_location;
312 query->stmt_len = stmt_len;
313
314 /*
315 * Close the relation for now, but keep the lock on it to prevent
316 * changes between now and when we start the query-based COPY.
317 *
318 * We'll reopen it later as part of the query-based COPY.
319 */
320 table_close(rel, NoLock);
321 rel = NULL;
322 }
323 }
324 else
325 {
326 Assert(stmt->query);
327
328 query = makeNode(RawStmt);
329 query->stmt = stmt->query;
330 query->stmt_location = stmt_location;
331 query->stmt_len = stmt_len;
332
333 relid = InvalidOid;
334 rel = NULL;
335 }
336
337 if (is_from)
338 {
339 CopyFromState cstate;
340
341 Assert(rel);
342
343 /* check read-only transaction and parallel mode */
344 if (XactReadOnly && !rel->rd_islocaltemp)
345 PreventCommandIfReadOnly("COPY FROM");
346
347 cstate = BeginCopyFrom(pstate, rel, whereClause,
348 stmt->filename, stmt->is_program,
349 NULL, stmt->attlist, stmt->options);
350 *processed = CopyFrom(cstate); /* copy from file to database */
351 EndCopyFrom(cstate);
352 }
353 else
354 {
355 CopyToState cstate;
356
357 cstate = BeginCopyTo(pstate, rel, query, relid,
358 stmt->filename, stmt->is_program,
359 NULL, stmt->attlist, stmt->options);
360 *processed = DoCopyTo(cstate); /* copy from database to file */
361 EndCopyTo(cstate);
362 }
363
364 if (rel != NULL)
365 table_close(rel, NoLock);
366}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
int bms_next_member(const Bitmapset *a, int prevbit)
Definition bitmapset.c:1290
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition bitmapset.c:1003
Bitmapset * bms_del_member(Bitmapset *a, int x)
Definition bitmapset.c:852
bool bms_is_member(int x, const Bitmapset *a)
Definition bitmapset.c:510
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:799
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition clauses.c:2498
CopyFromState BeginCopyFrom(ParseState *pstate, Relation rel, Node *whereClause, const char *filename, bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options)
Definition copyfrom.c:1535
uint64 CopyFrom(CopyFromState cstate)
Definition copyfrom.c:781
void EndCopyFrom(CopyFromState cstate)
Definition copyfrom.c:1942
uint64 DoCopyTo(CopyToState cstate)
Definition copyto.c:1241
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 copyto.c:769
void EndCopyTo(CopyToState cstate)
Definition copyto.c:1220
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
Definition execMain.c:584
#define stmt
List * lappend(List *list, void *datum)
Definition list.c:339
int LOCKMODE
Definition lockdefs.h:26
#define NoLock
Definition lockdefs.h:34
#define RowExclusiveLock
Definition lockdefs.h:38
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:946
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3588
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition makefuncs.c:473
List * make_ands_implicit(Expr *clause)
Definition makefuncs.c:810
Oid GetUserId(void)
Definition miscinit.c:470
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition parse_expr.c:121
@ EXPR_KIND_COPY_WHERE
Definition parse_node.h:82
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, LOCKMODE lockmode, Alias *alias, bool inh, bool inFromCl)
#define ACL_INSERT
Definition parsenodes.h:76
#define ACL_SELECT
Definition parsenodes.h:77
#define list_make1(x1)
Definition pg_list.h:244
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition prepqual.c:293
#define RelationGetNumberOfAttributes(relation)
Definition rel.h:520
#define RelationGetNamespace(relation)
Definition rel.h:555
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition rls.c:52
@ RLS_ENABLED
Definition rls.h:45
bool inh
Definition primnodes.h:87
ParseLoc stmt_location
ParseLoc stmt_len
Node * stmt
bool rd_islocaltemp
Definition rel.h:61
Node * val
Definition parsenodes.h:547
ParseLoc location
Definition parsenodes.h:548
List * indirection
Definition parsenodes.h:546
char * name
Definition parsenodes.h:545
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition table.c:83
void PreventCommandIfReadOnly(const char *cmdname)
Definition utility.c:409
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
Definition var.c:296
#define select(n, r, w, e, timeout)
Definition win32_port.h:500
bool XactReadOnly
Definition xact.c:84

References AccessShareLock, ACL_INSERT, ACL_SELECT, addNSItemToQuery(), addRangeTableEntryForRelation(), Assert, assign_expr_collations(), BeginCopyFrom(), BeginCopyTo(), bms_add_member(), bms_add_range(), bms_del_member(), bms_is_member(), bms_next_member(), canonicalize_qual(), check_enable_rls(), coerce_to_boolean(), CopyFrom(), CopyGetAttnums(), cur, DoCopyTo(), EndCopyFrom(), EndCopyTo(), ereport, errcode(), errdetail(), errhint(), errmsg, ERROR, eval_const_expressions(), ExecCheckPermissions(), EXPR_KIND_COPY_WHERE, fb(), FirstLowInvalidHeapAttributeNumber, get_attname(), get_namespace_name(), GetUserId(), has_privs_of_role(), i, ResTarget::indirection, RangeVar::inh, InvalidOid, lappend(), lfirst, lfirst_int, list_make1, ResTarget::location, make_ands_implicit(), makeNode, makeRangeVar(), ResTarget::name, NIL, NoLock, ParseState::p_rtable, PreventCommandIfReadOnly(), pstrdup(), pull_varattnos(), RelationData::rd_islocaltemp, RelationData::rd_rel, RelationGetDescr, RelationGetNamespace, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, RLS_ENABLED, RowExclusiveLock, select, RawStmt::stmt, stmt, RawStmt::stmt_len, RawStmt::stmt_location, table_close(), table_openrv(), transformExpr(), TupleDescAttr(), ResTarget::val, and XactReadOnly.

Referenced by standard_ProcessUtility().

◆ DoCopyTo()

uint64 DoCopyTo ( CopyToState  cstate)
extern

Definition at line 1241 of file copyto.c.

1242{
1243 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1244 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1245 TupleDesc tupDesc;
1246 int num_phys_attrs;
1247 ListCell *cur;
1248 uint64 processed = 0;
1249
1250 if (fe_copy)
1251 SendCopyBegin(cstate);
1252
1253 if (cstate->rel)
1254 tupDesc = RelationGetDescr(cstate->rel);
1255 else
1256 tupDesc = cstate->queryDesc->tupDesc;
1257 num_phys_attrs = tupDesc->natts;
1258 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1259
1260 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1261 cstate->fe_msgbuf = makeStringInfo();
1262
1263 /* Get info about the columns we need to process. */
1264 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1265 foreach(cur, cstate->attnumlist)
1266 {
1267 int attnum = lfirst_int(cur);
1268 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1269
1270 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1271 &cstate->out_functions[attnum - 1]);
1272 }
1273
1274 /*
1275 * Create a temporary memory context that we can reset once per row to
1276 * recover palloc'd memory. This avoids any problems with leaks inside
1277 * datatype output routines, and should be faster than retail pfree's
1278 * anyway. (We don't need a whole econtext as CopyFrom does.)
1279 */
1281 "COPY TO",
1283
1284 cstate->routine->CopyToStart(cstate, tupDesc);
1285
1286 if (cstate->rel)
1287 {
1288 /*
1289 * If COPY TO source table is a partitioned table, then open each
1290 * partition and process each individual partition.
1291 */
1292 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1293 {
1294 foreach_oid(child, cstate->partitions)
1295 {
1297
1298 /* We already got the lock in BeginCopyTo */
1299 scan_rel = table_open(child, NoLock);
1300 CopyRelationTo(cstate, scan_rel, cstate->rel, &processed);
1302 }
1303 }
1304 else
1305 CopyRelationTo(cstate, cstate->rel, NULL, &processed);
1306 }
1307 else
1308 {
1309 /* run the plan --- the dest receiver will send tuples */
1311 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1312 }
1313
1314 cstate->routine->CopyToEnd(cstate);
1315
1317
1318 if (fe_copy)
1319 SendCopyEnd(cstate);
1320
1321 return processed;
1322}
uint64_t uint64
Definition c.h:619
static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
Definition copyto.c:1332
static void SendCopyBegin(CopyToState cstate)
Definition copyto.c:517
static void SendCopyEnd(CopyToState cstate)
Definition copyto.c:548
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition execMain.c:299
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
@ ForwardScanDirection
Definition sdir.h:28
char * null_print
Definition copy.h:77
char * null_print_client
Definition copy.h:79
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
FmgrInfo * out_functions
Definition copyto.c:110
MemoryContext rowcontext
Definition copyto.c:111
StringInfo fe_msgbuf
Definition copyto.c:79
DestReceiver * dest
Definition execdesc.h:41
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().

◆ EndCopyFrom()

void EndCopyFrom ( CopyFromState  cstate)
extern

Definition at line 1942 of file copyfrom.c.

1943{
1944 /* Invoke the end callback */
1945 cstate->routine->CopyFromEnd(cstate);
1946
1947 /* No COPY FROM related resources except memory. */
1948 if (cstate->is_program)
1949 {
1950 ClosePipeFromProgram(cstate);
1951 }
1952 else
1953 {
1954 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
1955 ereport(ERROR,
1957 errmsg("could not close file \"%s\": %m",
1958 cstate->filename)));
1959 }
1960
1962
1964 pfree(cstate);
1965}
void pgstat_progress_end_command(void)
static void ClosePipeFromProgram(CopyFromState cstate)
Definition copyfrom.c:1971
int FreeFile(FILE *file)
Definition fd.c:2827
void(* CopyFromEnd)(CopyFromState cstate)
Definition copyapi.h:102

References ClosePipeFromProgram(), CopyFromStateData::copy_file, CopyFromStateData::copycontext, CopyFromRoutine::CopyFromEnd, ereport, errcode_for_file_access(), errmsg, ERROR, fb(), CopyFromStateData::filename, FreeFile(), CopyFromStateData::is_program, MemoryContextDelete(), pfree(), pgstat_progress_end_command(), and CopyFromStateData::routine.

Referenced by DoCopy(), file_acquire_sample_rows(), fileEndForeignScan(), and fileReScanForeignScan().

◆ EndCopyTo()

void EndCopyTo ( CopyToState  cstate)
extern

Definition at line 1220 of file copyto.c.

1221{
1222 if (cstate->queryDesc != NULL)
1223 {
1224 /* Close down the query and free resources. */
1225 ExecutorFinish(cstate->queryDesc);
1226 ExecutorEnd(cstate->queryDesc);
1227 FreeQueryDesc(cstate->queryDesc);
1229 }
1230
1231 /* Clean up storage */
1232 EndCopy(cstate);
1233}
static void EndCopy(CopyToState cstate)
Definition copyto.c:729
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().

◆ NextCopyFrom()

bool NextCopyFrom ( CopyFromState  cstate,
ExprContext econtext,
Datum values,
bool nulls 
)
extern

Definition at line 887 of file copyfromparse.c.

889{
890 TupleDesc tupDesc;
892 num_defaults = cstate->num_defaults;
893 int i;
894 int *defmap = cstate->defmap;
895 ExprState **defexprs = cstate->defexprs;
896
897 tupDesc = RelationGetDescr(cstate->rel);
898 num_phys_attrs = tupDesc->natts;
899
900 /* Initialize all values for row to NULL */
901 MemSet(values, 0, num_phys_attrs * sizeof(Datum));
902 MemSet(nulls, true, num_phys_attrs * sizeof(bool));
903 MemSet(cstate->defaults, false, num_phys_attrs * sizeof(bool));
904
905 /* Get one row from source */
906 if (!cstate->routine->CopyFromOneRow(cstate, econtext, values, nulls))
907 return false;
908
909 /*
910 * Now compute and insert any defaults available for the columns not
911 * provided by the input data. Anything not processed here or above will
912 * remain NULL.
913 */
914 for (i = 0; i < num_defaults; i++)
915 {
916 /*
917 * The caller must supply econtext and have switched into the
918 * per-tuple memory context in it.
919 */
920 Assert(econtext != NULL);
922
923 values[defmap[i]] = ExecEvalExpr(defexprs[defmap[i]], econtext,
924 &nulls[defmap[i]]);
925 }
926
927 return true;
928}
static Datum values[MAXATTR]
Definition bootstrap.c:188
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition executor.h:396
bool(* CopyFromOneRow)(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
Definition copyapi.h:96
MemoryContext ecxt_per_tuple_memory
Definition execnodes.h:292

References Assert, CopyFromRoutine::CopyFromOneRow, CurrentMemoryContext, CopyFromStateData::defaults, CopyFromStateData::defexprs, CopyFromStateData::defmap, ExprContext::ecxt_per_tuple_memory, ExecEvalExpr(), fb(), i, MemSet, TupleDescData::natts, CopyFromStateData::num_defaults, CopyFromStateData::rel, RelationGetDescr, CopyFromStateData::routine, and values.

Referenced by CopyFrom(), file_acquire_sample_rows(), and fileIterateForeignScan().

◆ NextCopyFromRawFields()

bool NextCopyFromRawFields ( CopyFromState  cstate,
char ***  fields,
int nfields 
)
extern

Definition at line 753 of file copyfromparse.c.

754{
755 return NextCopyFromRawFieldsInternal(cstate, fields, nfields,
756 cstate->opts.format == COPY_FORMAT_CSV);
757}
static pg_attribute_always_inline bool NextCopyFromRawFieldsInternal(CopyFromState cstate, char ***fields, int *nfields, bool is_csv)

References COPY_FORMAT_CSV, CopyFormatOptions::format, NextCopyFromRawFieldsInternal(), and CopyFromStateData::opts.

◆ ProcessCopyOptions()

void ProcessCopyOptions ( ParseState pstate,
CopyFormatOptions opts_out,
bool  is_from,
List options 
)
extern

Definition at line 561 of file copy.c.

565{
566 bool format_specified = false;
567 bool freeze_specified = false;
568 bool header_specified = false;
569 bool on_error_specified = false;
570 bool log_verbosity_specified = false;
571 bool reject_limit_specified = false;
572 bool force_array_specified = false;
574
575 /* Support external use for option sanity checking */
576 if (opts_out == NULL)
578
579 opts_out->file_encoding = -1;
580 /* default format */
581 opts_out->format = COPY_FORMAT_TEXT;
582
583 /* Extract options from the statement node tree */
584 foreach(option, options)
585 {
587
588 if (strcmp(defel->defname, "format") == 0)
589 {
590 char *fmt = defGetString(defel);
591
594 format_specified = true;
595 if (strcmp(fmt, "text") == 0)
596 opts_out->format = COPY_FORMAT_TEXT;
597 else if (strcmp(fmt, "csv") == 0)
598 opts_out->format = COPY_FORMAT_CSV;
599 else if (strcmp(fmt, "binary") == 0)
601 else if (strcmp(fmt, "json") == 0)
602 opts_out->format = COPY_FORMAT_JSON;
603 else
606 errmsg("COPY format \"%s\" not recognized", fmt),
607 parser_errposition(pstate, defel->location)));
608 }
609 else if (strcmp(defel->defname, "freeze") == 0)
610 {
613 freeze_specified = true;
614 opts_out->freeze = defGetBoolean(defel);
615 }
616 else if (strcmp(defel->defname, "delimiter") == 0)
617 {
618 if (opts_out->delim)
620 opts_out->delim = defGetString(defel);
621 }
622 else if (strcmp(defel->defname, "null") == 0)
623 {
624 if (opts_out->null_print)
626 opts_out->null_print = defGetString(defel);
627 }
628 else if (strcmp(defel->defname, "default") == 0)
629 {
630 if (opts_out->default_print)
632 opts_out->default_print = defGetString(defel);
633 }
634 else if (strcmp(defel->defname, "header") == 0)
635 {
638 header_specified = true;
639 opts_out->header_line = defGetCopyHeaderOption(defel, is_from);
640 }
641 else if (strcmp(defel->defname, "quote") == 0)
642 {
643 if (opts_out->quote)
645 opts_out->quote = defGetString(defel);
646 }
647 else if (strcmp(defel->defname, "escape") == 0)
648 {
649 if (opts_out->escape)
651 opts_out->escape = defGetString(defel);
652 }
653 else if (strcmp(defel->defname, "force_quote") == 0)
654 {
655 if (opts_out->force_quote || opts_out->force_quote_all)
657 if (defel->arg && IsA(defel->arg, A_Star))
658 opts_out->force_quote_all = true;
659 else if (defel->arg && IsA(defel->arg, List))
660 opts_out->force_quote = castNode(List, defel->arg);
661 else
664 errmsg("argument to option \"%s\" must be a list of column names",
665 defel->defname),
666 parser_errposition(pstate, defel->location)));
667 }
668 else if (strcmp(defel->defname, "force_not_null") == 0)
669 {
670 if (opts_out->force_notnull || opts_out->force_notnull_all)
672 if (defel->arg && IsA(defel->arg, A_Star))
673 opts_out->force_notnull_all = true;
674 else if (defel->arg && IsA(defel->arg, List))
675 opts_out->force_notnull = castNode(List, defel->arg);
676 else
679 errmsg("argument to option \"%s\" must be a list of column names",
680 defel->defname),
681 parser_errposition(pstate, defel->location)));
682 }
683 else if (strcmp(defel->defname, "force_null") == 0)
684 {
685 if (opts_out->force_null || opts_out->force_null_all)
687 if (defel->arg && IsA(defel->arg, A_Star))
688 opts_out->force_null_all = true;
689 else if (defel->arg && IsA(defel->arg, List))
690 opts_out->force_null = castNode(List, defel->arg);
691 else
694 errmsg("argument to option \"%s\" must be a list of column names",
695 defel->defname),
696 parser_errposition(pstate, defel->location)));
697 }
698 else if (strcmp(defel->defname, "convert_selectively") == 0)
699 {
700 /*
701 * Undocumented, not-accessible-from-SQL option: convert only the
702 * named columns to binary form, storing the rest as NULLs. It's
703 * allowed for the column list to be NIL.
704 */
705 if (opts_out->convert_selectively)
707 opts_out->convert_selectively = true;
708 if (defel->arg == NULL || IsA(defel->arg, List))
709 opts_out->convert_select = castNode(List, defel->arg);
710 else
713 errmsg("argument to option \"%s\" must be a list of column names",
714 defel->defname),
715 parser_errposition(pstate, defel->location)));
716 }
717 else if (strcmp(defel->defname, "encoding") == 0)
718 {
719 if (opts_out->file_encoding >= 0)
722 if (opts_out->file_encoding < 0)
725 errmsg("argument to option \"%s\" must be a valid encoding name",
726 defel->defname),
727 parser_errposition(pstate, defel->location)));
728 }
729 else if (strcmp(defel->defname, "force_array") == 0)
730 {
734 opts_out->force_array = defGetBoolean(defel);
735 }
736 else if (strcmp(defel->defname, "on_error") == 0)
737 {
740 on_error_specified = true;
741 opts_out->on_error = defGetCopyOnErrorChoice(defel, pstate, is_from);
742 }
743 else if (strcmp(defel->defname, "log_verbosity") == 0)
744 {
748 opts_out->log_verbosity = defGetCopyLogVerbosityChoice(defel, pstate);
749 }
750 else if (strcmp(defel->defname, "reject_limit") == 0)
751 {
756 }
757 else
760 errmsg("option \"%s\" not recognized",
761 defel->defname),
762 parser_errposition(pstate, defel->location)));
763 }
764
765 /*
766 * Check for incompatible options (must do these three before inserting
767 * defaults)
768 */
769 if (opts_out->delim &&
770 (opts_out->format == COPY_FORMAT_BINARY ||
771 opts_out->format == COPY_FORMAT_JSON))
775 ? errmsg("cannot specify %s in BINARY mode", "DELIMITER")
776 : errmsg("cannot specify %s in JSON mode", "DELIMITER"));
777
778 if (opts_out->null_print &&
779 (opts_out->format == COPY_FORMAT_BINARY ||
780 opts_out->format == COPY_FORMAT_JSON))
784 ? errmsg("cannot specify %s in BINARY mode", "NULL")
785 : errmsg("cannot specify %s in JSON mode", "NULL"));
786
787 if (opts_out->default_print &&
788 (opts_out->format == COPY_FORMAT_BINARY ||
789 opts_out->format == COPY_FORMAT_JSON))
793 ? errmsg("cannot specify %s in BINARY mode", "DEFAULT")
794 : errmsg("cannot specify %s in JSON mode", "DEFAULT"));
795
796 /* Set defaults for omitted options */
797 if (!opts_out->delim)
798 opts_out->delim = (opts_out->format == COPY_FORMAT_CSV) ? "," : "\t";
799
800 if (!opts_out->null_print)
801 opts_out->null_print = (opts_out->format == COPY_FORMAT_CSV) ? "" : "\\N";
802 opts_out->null_print_len = strlen(opts_out->null_print);
803
804 if (opts_out->format == COPY_FORMAT_CSV)
805 {
806 if (!opts_out->quote)
807 opts_out->quote = "\"";
808 if (!opts_out->escape)
809 opts_out->escape = opts_out->quote;
810 }
811
812 /* Only single-byte delimiter strings are supported. */
813 if (strlen(opts_out->delim) != 1)
816 errmsg("COPY delimiter must be a single one-byte character")));
817
818 /* Disallow end-of-line characters */
819 if (strchr(opts_out->delim, '\r') != NULL ||
820 strchr(opts_out->delim, '\n') != NULL)
823 errmsg("COPY delimiter cannot be newline or carriage return")));
824
825 if (strchr(opts_out->null_print, '\r') != NULL ||
826 strchr(opts_out->null_print, '\n') != NULL)
829 errmsg("COPY null representation cannot use newline or carriage return")));
830
831 if (opts_out->default_print)
832 {
833 opts_out->default_print_len = strlen(opts_out->default_print);
834
835 if (strchr(opts_out->default_print, '\r') != NULL ||
836 strchr(opts_out->default_print, '\n') != NULL)
839 errmsg("COPY default representation cannot use newline or carriage return")));
840 }
841
842 /*
843 * Disallow unsafe delimiter characters in non-CSV mode. We can't allow
844 * backslash because it would be ambiguous. We can't allow the other
845 * cases because data characters matching the delimiter must be
846 * backslashed, and certain backslash combinations are interpreted
847 * non-literally by COPY IN. Disallowing all lower case ASCII letters is
848 * more than strictly necessary, but seems best for consistency and
849 * future-proofing. Likewise we disallow all digits though only octal
850 * digits are actually dangerous.
851 */
852 if (opts_out->format != COPY_FORMAT_CSV &&
853 strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
854 opts_out->delim[0]) != NULL)
857 errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));
858
859 /* Check header */
860 if (opts_out->header_line != COPY_HEADER_FALSE &&
861 (opts_out->format == COPY_FORMAT_BINARY ||
862 opts_out->format == COPY_FORMAT_JSON))
865 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
867 ? errmsg("cannot specify %s in BINARY mode", "HEADER")
868 : errmsg("cannot specify %s in JSON mode", "HEADER"));
869
870 /* Check quote */
871 if (opts_out->format != COPY_FORMAT_CSV && opts_out->quote != NULL)
874 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
875 errmsg("COPY %s requires CSV mode", "QUOTE")));
876
877 if (opts_out->format == COPY_FORMAT_CSV && strlen(opts_out->quote) != 1)
880 errmsg("COPY quote must be a single one-byte character")));
881
882 if (opts_out->format == COPY_FORMAT_CSV && opts_out->delim[0] == opts_out->quote[0])
885 errmsg("COPY delimiter and quote must be different")));
886
887 /* Check escape */
888 if (opts_out->format != COPY_FORMAT_CSV && opts_out->escape != NULL)
891 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
892 errmsg("COPY %s requires CSV mode", "ESCAPE")));
893
894 if (opts_out->format == COPY_FORMAT_CSV && strlen(opts_out->escape) != 1)
897 errmsg("COPY escape must be a single one-byte character")));
898
899 /* Check force_quote */
900 if (opts_out->format != COPY_FORMAT_CSV && (opts_out->force_quote || opts_out->force_quote_all))
903 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
904 errmsg("COPY %s requires CSV mode", "FORCE_QUOTE")));
905 if ((opts_out->force_quote || opts_out->force_quote_all) && is_from)
908 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
909 second %s is a COPY with direction, e.g. COPY TO */
910 errmsg("COPY %s cannot be used with %s", "FORCE_QUOTE",
911 "COPY FROM")));
912
913 /* Check force_notnull */
914 if (opts_out->format != COPY_FORMAT_CSV && (opts_out->force_notnull != NIL ||
915 opts_out->force_notnull_all))
918 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
919 errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
920 if ((opts_out->force_notnull != NIL || opts_out->force_notnull_all) &&
921 !is_from)
924 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
925 second %s is a COPY with direction, e.g. COPY TO */
926 errmsg("COPY %s cannot be used with %s", "FORCE_NOT_NULL",
927 "COPY TO")));
928
929 /* Check force_null */
930 if (opts_out->format != COPY_FORMAT_CSV && (opts_out->force_null != NIL ||
931 opts_out->force_null_all))
934 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
935 errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
936
937 if ((opts_out->force_null != NIL || opts_out->force_null_all) &&
938 !is_from)
941 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
942 second %s is a COPY with direction, e.g. COPY TO */
943 errmsg("COPY %s cannot be used with %s", "FORCE_NULL",
944 "COPY TO")));
945
946 /* Don't allow the delimiter to appear in the null string. */
947 if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL)
950 /*- translator: %s is the name of a COPY option, e.g. NULL */
951 errmsg("COPY delimiter character must not appear in the %s specification",
952 "NULL")));
953
954 /* Don't allow the CSV quote char to appear in the null string. */
955 if (opts_out->format == COPY_FORMAT_CSV &&
956 strchr(opts_out->null_print, opts_out->quote[0]) != NULL)
959 /*- translator: %s is the name of a COPY option, e.g. NULL */
960 errmsg("CSV quote character must not appear in the %s specification",
961 "NULL")));
962
963 /* Check freeze */
964 if (opts_out->freeze && !is_from)
967 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
968 second %s is a COPY with direction, e.g. COPY TO */
969 errmsg("COPY %s cannot be used with %s", "FREEZE",
970 "COPY TO")));
971
972 /* Check json format */
973 if (opts_out->format == COPY_FORMAT_JSON && is_from)
976 errmsg("COPY %s is not supported for %s", "FORMAT JSON", "COPY FROM"));
977
978 if (opts_out->format != COPY_FORMAT_JSON && opts_out->force_array)
981 errmsg("COPY %s can only be used with JSON mode", "FORCE_ARRAY"));
982
983 if (opts_out->default_print)
984 {
985 if (!is_from)
988 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
989 second %s is a COPY with direction, e.g. COPY TO */
990 errmsg("COPY %s cannot be used with %s", "DEFAULT",
991 "COPY TO")));
992
993 /* Don't allow the delimiter to appear in the default string. */
994 if (strchr(opts_out->default_print, opts_out->delim[0]) != NULL)
997 /*- translator: %s is the name of a COPY option, e.g. NULL */
998 errmsg("COPY delimiter character must not appear in the %s specification",
999 "DEFAULT")));
1000
1001 /* Don't allow the CSV quote char to appear in the default string. */
1002 if (opts_out->format == COPY_FORMAT_CSV &&
1003 strchr(opts_out->default_print, opts_out->quote[0]) != NULL)
1004 ereport(ERROR,
1006 /*- translator: %s is the name of a COPY option, e.g. NULL */
1007 errmsg("CSV quote character must not appear in the %s specification",
1008 "DEFAULT")));
1009
1010 /* Don't allow the NULL and DEFAULT string to be the same */
1011 if (opts_out->null_print_len == opts_out->default_print_len &&
1012 strncmp(opts_out->null_print, opts_out->default_print,
1013 opts_out->null_print_len) == 0)
1014 ereport(ERROR,
1016 errmsg("NULL specification and DEFAULT specification cannot be the same")));
1017 }
1018 /* Check on_error */
1019 if (opts_out->format == COPY_FORMAT_BINARY && opts_out->on_error != COPY_ON_ERROR_STOP)
1020 ereport(ERROR,
1022 errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
1023
1024 if (opts_out->reject_limit && opts_out->on_error != COPY_ON_ERROR_IGNORE)
1025 ereport(ERROR,
1027 /*- translator: first and second %s are the names of COPY option, e.g.
1028 * ON_ERROR, third is the value of the COPY option, e.g. IGNORE */
1029 errmsg("COPY %s requires %s to be set to %s",
1030 "REJECT_LIMIT", "ON_ERROR", "IGNORE")));
1031}
static int defGetCopyHeaderOption(DefElem *def, bool is_from)
Definition copy.c:376
static int64 defGetCopyRejectLimitOption(DefElem *def)
Definition copy.c:494
static CopyOnErrorChoice defGetCopyOnErrorChoice(DefElem *def, ParseState *pstate, bool is_from)
Definition copy.c:459
static CopyLogVerbosityChoice defGetCopyLogVerbosityChoice(DefElem *def, ParseState *pstate)
Definition copy.c:521
char * defGetString(DefElem *def)
Definition define.c:34
bool defGetBoolean(DefElem *def)
Definition define.c:93
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
#define COPY_HEADER_FALSE
Definition copy.h:27
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
#define pg_char_to_encoding
Definition pg_wchar.h:629

References castNode, COPY_FORMAT_BINARY, COPY_FORMAT_CSV, COPY_FORMAT_JSON, COPY_FORMAT_TEXT, COPY_HEADER_FALSE, COPY_ON_ERROR_IGNORE, COPY_ON_ERROR_STOP, defGetBoolean(), defGetCopyHeaderOption(), defGetCopyLogVerbosityChoice(), defGetCopyOnErrorChoice(), defGetCopyRejectLimitOption(), defGetString(), ereport, errcode(), errmsg, ERROR, errorConflictingDefElem(), fb(), IsA, lfirst_node, NIL, palloc0_object, parser_errposition(), and pg_char_to_encoding.

Referenced by BeginCopyFrom(), BeginCopyTo(), and file_fdw_validator().