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 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 }
 

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 96 of file copy.h.

◆ copy_data_source_cb

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

Definition at line 95 of file copy.h.

◆ CopyFormatOptions

◆ CopyFromState

Definition at line 92 of file copy.h.

◆ CopyLogVerbosityChoice

◆ CopyOnErrorChoice

◆ CopyToState

Definition at line 93 of file copy.h.

Enumeration Type Documentation

◆ 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 1534 of file copyfrom.c.

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

644{
645 CopyToState cstate;
646 bool pipe = (filename == NULL && data_dest_cb == NULL);
647 TupleDesc tupDesc;
648 int num_phys_attrs;
649 MemoryContext oldcontext;
650 const int progress_cols[] = {
653 };
654 int64 progress_vals[] = {
656 0
657 };
658 List *children = NIL;
659
660 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
661 {
662 if (rel->rd_rel->relkind == RELKIND_VIEW)
665 errmsg("cannot copy from view \"%s\"",
667 errhint("Try the COPY (SELECT ...) TO variant.")));
668 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
669 {
670 if (!RelationIsPopulated(rel))
673 errmsg("cannot copy from unpopulated materialized view \"%s\"",
675 errhint("Use the REFRESH MATERIALIZED VIEW command."));
676 }
677 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
680 errmsg("cannot copy from foreign table \"%s\"",
682 errhint("Try the COPY (SELECT ...) TO variant.")));
683 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
686 errmsg("cannot copy from sequence \"%s\"",
688 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
689 {
690 /*
691 * Collect OIDs of relation containing data, so that later
692 * DoCopyTo can copy the data from them.
693 */
695
696 foreach_oid(child, children)
697 {
698 char relkind = get_rel_relkind(child);
699
700 if (relkind == RELKIND_FOREIGN_TABLE)
701 {
702 char *relation_name = get_rel_name(child);
703
706 errmsg("cannot copy from foreign table \"%s\"", relation_name),
707 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
708 relation_name, RelationGetRelationName(rel)),
709 errhint("Try the COPY (SELECT ...) TO variant."));
710 }
711
712 /* Exclude tables with no data */
713 if (RELKIND_HAS_PARTITIONS(relkind))
714 children = foreach_delete_current(children, child);
715 }
716 }
717 else
720 errmsg("cannot copy from non-table relation \"%s\"",
722 }
723
724
725 /* Allocate workspace and zero all fields */
727
728 /*
729 * We allocate everything used by a cstate in a new memory context. This
730 * avoids memory leaks during repeated use of COPY in a query.
731 */
733 "COPY",
735
736 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
737
738 /* Extract options from the statement node tree */
739 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
740
741 /* Set format routine */
742 cstate->routine = CopyToGetRoutine(&cstate->opts);
743
744 /* Process the source/target relation or query */
745 if (rel)
746 {
748
749 cstate->rel = rel;
750
751 tupDesc = RelationGetDescr(cstate->rel);
752 cstate->partitions = children;
753 }
754 else
755 {
757 Query *query;
760
761 cstate->rel = NULL;
762 cstate->partitions = NIL;
763
764 /*
765 * Run parse analysis and rewrite. Note this also acquires sufficient
766 * locks on the source table(s).
767 */
769 pstate->p_sourcetext, NULL, 0,
770 NULL);
771
772 /* check that we got back something we can work with */
773 if (rewritten == NIL)
774 {
777 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
778 }
779 else if (list_length(rewritten) > 1)
780 {
781 ListCell *lc;
782
783 /* examine queries to determine which error message to issue */
784 foreach(lc, rewritten)
785 {
786 Query *q = lfirst_node(Query, lc);
787
788 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
791 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
792 if (q->querySource == QSRC_NON_INSTEAD_RULE)
795 errmsg("DO ALSO rules are not supported for COPY")));
796 }
797
800 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
801 }
802
803 query = linitial_node(Query, rewritten);
804
805 /* The grammar allows SELECT INTO, but we don't support that */
806 if (query->utilityStmt != NULL &&
810 errmsg("COPY (SELECT INTO) is not supported")));
811
812 /* The only other utility command we could see is NOTIFY */
813 if (query->utilityStmt != NULL)
816 errmsg("COPY query must not be a utility command")));
817
818 /*
819 * Similarly the grammar doesn't enforce the presence of a RETURNING
820 * clause, but this is required here.
821 */
822 if (query->commandType != CMD_SELECT &&
823 query->returningList == NIL)
824 {
825 Assert(query->commandType == CMD_INSERT ||
826 query->commandType == CMD_UPDATE ||
827 query->commandType == CMD_DELETE ||
828 query->commandType == CMD_MERGE);
829
832 errmsg("COPY query must have a RETURNING clause")));
833 }
834
835 /* plan the query */
836 plan = pg_plan_query(query, pstate->p_sourcetext,
838
839 /*
840 * With row-level security and a user using "COPY relation TO", we
841 * have to convert the "COPY relation TO" to a query-based COPY (eg:
842 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
843 * add in any RLS clauses.
844 *
845 * When this happens, we are passed in the relid of the originally
846 * found relation (which we have locked). As the planner will look up
847 * the relation again, we double-check here to make sure it found the
848 * same one that we have locked.
849 */
850 if (queryRelId != InvalidOid)
851 {
852 /*
853 * Note that with RLS involved there may be multiple relations,
854 * and while the one we need is almost certainly first, we don't
855 * make any guarantees of that in the planner, so check the whole
856 * list and make sure we find the original relation.
857 */
858 if (!list_member_oid(plan->relationOids, queryRelId))
861 errmsg("relation referenced by COPY statement has changed")));
862 }
863
864 /*
865 * Use a snapshot with an updated command ID to ensure this query sees
866 * results of any previously executed queries.
867 */
870
871 /* Create dest receiver for COPY OUT */
873 ((DR_copy *) dest)->cstate = cstate;
874
875 /* Create a QueryDesc requesting no output */
876 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
879 dest, NULL, NULL, 0);
880
881 /*
882 * Call ExecutorStart to prepare the plan for execution.
883 *
884 * ExecutorStart computes a result tupdesc for us
885 */
886 ExecutorStart(cstate->queryDesc, 0);
887
888 tupDesc = cstate->queryDesc->tupDesc;
889 }
890
891 /* Generate or convert list of attributes to process */
892 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
893
894 num_phys_attrs = tupDesc->natts;
895
896 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
897 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
898 if (cstate->opts.force_quote_all)
899 {
900 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
901 }
902 else if (cstate->opts.force_quote)
903 {
904 List *attnums;
905 ListCell *cur;
906
907 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
908
909 foreach(cur, attnums)
910 {
911 int attnum = lfirst_int(cur);
912 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
913
914 if (!list_member_int(cstate->attnumlist, attnum))
917 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
918 errmsg("%s column \"%s\" not referenced by COPY",
919 "FORCE_QUOTE", NameStr(attr->attname))));
920 cstate->opts.force_quote_flags[attnum - 1] = true;
921 }
922 }
923
924 /* Use client encoding when ENCODING option is not specified. */
925 if (cstate->opts.file_encoding < 0)
927 else
928 cstate->file_encoding = cstate->opts.file_encoding;
929
930 /*
931 * Set up encoding conversion info if the file and server encodings differ
932 * (see also pg_server_to_any).
933 */
934 if (cstate->file_encoding == GetDatabaseEncoding() ||
935 cstate->file_encoding == PG_SQL_ASCII)
936 cstate->need_transcoding = false;
937 else
938 cstate->need_transcoding = true;
939
940 /* See Multibyte encoding comment above */
942
943 cstate->copy_dest = COPY_FILE; /* default */
944
945 if (data_dest_cb)
946 {
948 cstate->copy_dest = COPY_CALLBACK;
949 cstate->data_dest_cb = data_dest_cb;
950 }
951 else if (pipe)
952 {
954
955 Assert(!is_program); /* the grammar does not allow this */
957 cstate->copy_file = stdout;
958 }
959 else
960 {
961 cstate->filename = pstrdup(filename);
962 cstate->is_program = is_program;
963
964 if (is_program)
965 {
967 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
968 if (cstate->copy_file == NULL)
971 errmsg("could not execute command \"%s\": %m",
972 cstate->filename)));
973 }
974 else
975 {
976 mode_t oumask; /* Pre-existing umask value */
977 struct stat st;
978
980
981 /*
982 * Prevent write to relative path ... too easy to shoot oneself in
983 * the foot by overwriting a database file ...
984 */
988 errmsg("relative path not allowed for COPY to file")));
989
991 PG_TRY();
992 {
993 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
994 }
995 PG_FINALLY();
996 {
997 umask(oumask);
998 }
999 PG_END_TRY();
1000 if (cstate->copy_file == NULL)
1001 {
1002 /* copy errno because ereport subfunctions might change it */
1003 int save_errno = errno;
1004
1005 ereport(ERROR,
1007 errmsg("could not open file \"%s\" for writing: %m",
1008 cstate->filename),
1009 (save_errno == ENOENT || save_errno == EACCES) ?
1010 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1011 "You may want a client-side facility such as psql's \\copy.") : 0));
1012 }
1013
1014 if (fstat(fileno(cstate->copy_file), &st))
1015 ereport(ERROR,
1017 errmsg("could not stat file \"%s\": %m",
1018 cstate->filename)));
1019
1020 if (S_ISDIR(st.st_mode))
1021 ereport(ERROR,
1023 errmsg("\"%s\" is a directory", cstate->filename)));
1024 }
1025 }
1026
1027 /* initialize progress */
1029 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1031
1032 cstate->bytes_processed = 0;
1033
1034 MemoryContextSwitchTo(oldcontext);
1035
1036 return cstate;
1037}
#define PG_BINARY_W
Definition c.h:1340
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition copyto.c:183
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:122
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
#define AccessShareLock
Definition lockdefs.h:36
char * get_rel_name(Oid relid)
Definition lsyscache.c:2078
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2153
#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:391
#define foreach_oid(var, lst)
Definition pg_list.h:471
#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:886
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition postgres.c:669
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:174
#define RelationIsPopulated(relation)
Definition rel.h:686
void UpdateActiveSnapshotCommandId(void)
Definition snapmgr.c:744
void PushCopiedSnapshot(Snapshot snapshot)
Definition snapmgr.c:732
Snapshot GetActiveSnapshot(void)
Definition snapmgr.c:800
#define InvalidSnapshot
Definition snapshot.h:119
bool force_quote_all
Definition copy.h:76
List * force_quote
Definition copy.h:75
bool * force_quote_flags
Definition copy.h:77
MemoryContext copycontext
Definition copyto.c:97
Relation rel
Definition copyto.c:83
const CopyToRoutine * routine
Definition copyto.c:71
copy_data_dest_cb data_dest_cb
Definition copyto.c:88
bool encoding_embeds_ascii
Definition copyto.c:80
CopyDest copy_dest
Definition copyto.c:74
bool need_transcoding
Definition copyto.c:79
bool is_program
Definition copyto.c:87
FILE * copy_file
Definition copyto.c:75
int file_encoding
Definition copyto.c:78
CopyFormatOptions opts
Definition copyto.c:90
uint64 bytes_processed
Definition copyto.c:101
char * filename
Definition copyto.c:86
List * attnumlist
Definition copyto.c:85
QueryDesc * queryDesc
Definition copyto.c:84
List * partitions
Definition copyto.c:92
const char * p_sourcetext
Definition parse_node.h:191
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
#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, CopyToStateData::bytes_processed, CMD_DELETE, CMD_INSERT, CMD_MERGE, CMD_SELECT, CMD_UPDATE, Query::commandType, COPY_CALLBACK, CopyToStateData::copy_dest, COPY_FILE, CopyToStateData::copy_file, CopyToStateData::copycontext, CopyGetAttnums(), CopyToGetRoutine(), CreateDestReceiver(), CreateQueryDesc(), cur, CurrentMemoryContext, CURSOR_OPT_PARALLEL_OK, CopyToStateData::data_dest_cb, DestCopyOut, DestRemote, CopyToStateData::encoding_embeds_ascii, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg, ERROR, ExecutorStart(), fb(), CopyToStateData::file_encoding, CopyFormatOptions::file_encoding, CopyToStateData::filename, filename, find_all_inheritors(), CopyFormatOptions::force_quote, CopyFormatOptions::force_quote_all, CopyFormatOptions::force_quote_flags, foreach_delete_current, foreach_oid, fstat, get_rel_name(), get_rel_relkind(), GetActiveSnapshot(), GetDatabaseEncoding(), InvalidOid, InvalidSnapshot, is_absolute_path, CopyToStateData::is_program, IsA, lfirst_int, lfirst_node, linitial_node, list_length(), list_member_int(), list_member_oid(), MemoryContextSwitchTo(), MemSet, NameStr, TupleDescData::natts, CopyToStateData::need_transcoding, NIL, OpenPipeStream(), CopyToStateData::opts, ParseState::p_sourcetext, palloc0(), palloc0_object, CopyToStateData::partitions, pg_analyze_and_rewrite_fixedparams(), PG_BINARY_W, PG_ENCODING_IS_CLIENT_ONLY, PG_END_TRY, PG_FINALLY, pg_get_client_encoding(), pg_plan_query(), PG_SQL_ASCII, PG_TRY, pgstat_progress_start_command(), pgstat_progress_update_multi_param(), plan, ProcessCopyOptions(), PROGRESS_COMMAND_COPY, PROGRESS_COPY_COMMAND, PROGRESS_COPY_COMMAND_TO, PROGRESS_COPY_TYPE, PROGRESS_COPY_TYPE_CALLBACK, PROGRESS_COPY_TYPE_FILE, PROGRESS_COPY_TYPE_PIPE, PROGRESS_COPY_TYPE_PROGRAM, pstrdup(), PushCopiedSnapshot(), QSRC_NON_INSTEAD_RULE, QSRC_QUAL_INSTEAD_RULE, CopyToStateData::queryDesc, RelationData::rd_rel, CopyToStateData::rel, RelationGetDescr, RelationGetRelationName, RelationGetRelid, RelationIsPopulated, Query::returningList, CopyToStateData::routine, S_ISDIR, S_IWGRP, S_IWOTH, stat::st_mode, QueryDesc::tupDesc, TupleDescAttr(), UpdateActiveSnapshotCommandId(), Query::utilityStmt, and whereToSendOutput.

Referenced by DoCopy(), and test_copy_to_callback().

◆ CopyFrom()

uint64 CopyFrom ( CopyFromState  cstate)
extern

Definition at line 780 of file copyfrom.c.

781{
782 ResultRelInfo *resultRelInfo;
785 EState *estate = CreateExecutorState(); /* for ExecConstraints() */
786 ModifyTableState *mtstate;
787 ExprContext *econtext;
790
791 PartitionTupleRouting *proute = NULL;
792 ErrorContextCallback errcallback;
793 CommandId mycid = GetCurrentCommandId(true);
794 int ti_options = 0; /* start with default options for insert */
795 BulkInsertState bistate = NULL;
797 CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */
798 int64 processed = 0;
799 int64 excluded = 0;
802 bool leafpart_use_multi_insert = false;
803
804 Assert(cstate->rel);
805 Assert(list_length(cstate->range_table) == 1);
806
807 if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
808 Assert(cstate->escontext);
809
810 /*
811 * The target must be a plain, foreign, or partitioned relation, or have
812 * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only
813 * allowed on views, so we only hint about them in the view case.)
814 */
815 if (cstate->rel->rd_rel->relkind != RELKIND_RELATION &&
816 cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
817 cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
818 !(cstate->rel->trigdesc &&
820 {
821 if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
824 errmsg("cannot copy to view \"%s\"",
826 errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
827 else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW)
830 errmsg("cannot copy to materialized view \"%s\"",
831 RelationGetRelationName(cstate->rel))));
832 else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
835 errmsg("cannot copy to sequence \"%s\"",
836 RelationGetRelationName(cstate->rel))));
837 else
840 errmsg("cannot copy to non-table relation \"%s\"",
841 RelationGetRelationName(cstate->rel))));
842 }
843
844 /*
845 * If the target file is new-in-transaction, we assume that checking FSM
846 * for free space is a waste of time. This could possibly be wrong, but
847 * it's unlikely.
848 */
849 if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) &&
852 ti_options |= TABLE_INSERT_SKIP_FSM;
853
854 /*
855 * Optimize if new relation storage was created in this subxact or one of
856 * its committed children and we won't see those rows later as part of an
857 * earlier scan or command. The subxact test ensures that if this subxact
858 * aborts then the frozen rows won't be visible after xact cleanup. Note
859 * that the stronger test of exactly which subtransaction created it is
860 * crucial for correctness of this optimization. The test for an earlier
861 * scan or command tolerates false negatives. FREEZE causes other sessions
862 * to see rows they would not see under MVCC, and a false negative merely
863 * spreads that anomaly to the current session.
864 */
865 if (cstate->opts.freeze)
866 {
867 /*
868 * We currently disallow COPY FREEZE on partitioned tables. The
869 * reason for this is that we've simply not yet opened the partitions
870 * to determine if the optimization can be applied to them. We could
871 * go and open them all here, but doing so may be quite a costly
872 * overhead for small copies. In any case, we may just end up routing
873 * tuples to a small number of partitions. It seems better just to
874 * raise an ERROR for partitioned tables.
875 */
876 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
877 {
880 errmsg("cannot perform COPY FREEZE on a partitioned table")));
881 }
882
883 /* There's currently no support for COPY FREEZE on foreign tables. */
884 if (cstate->rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
887 errmsg("cannot perform COPY FREEZE on a foreign table")));
888
889 /*
890 * Tolerate one registration for the benefit of FirstXactSnapshot.
891 * Scan-bearing queries generally create at least two registrations,
892 * though relying on that is fragile, as is ignoring ActiveSnapshot.
893 * Clear CatalogSnapshot to avoid counting its registration. We'll
894 * still detect ongoing catalog scans, each of which separately
895 * registers the snapshot it uses.
896 */
901 errmsg("cannot perform COPY FREEZE because of prior transaction activity")));
902
907 errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction")));
908
909 ti_options |= TABLE_INSERT_FROZEN;
910 }
911
912 /*
913 * We need a ResultRelInfo so we can use the regular executor's
914 * index-entry-making machinery. (There used to be a huge amount of code
915 * here that basically duplicated execUtils.c ...)
916 */
917 ExecInitRangeTable(estate, cstate->range_table, cstate->rteperminfos,
920 ExecInitResultRelation(estate, resultRelInfo, 1);
921
922 /* Verify the named relation is a valid target for INSERT */
924
925 ExecOpenIndices(resultRelInfo, false);
926
927 /*
928 * Set up a ModifyTableState so we can let FDW(s) init themselves for
929 * foreign-table result relation(s).
930 */
931 mtstate = makeNode(ModifyTableState);
932 mtstate->ps.plan = NULL;
933 mtstate->ps.state = estate;
934 mtstate->operation = CMD_INSERT;
935 mtstate->mt_nrels = 1;
936 mtstate->resultRelInfo = resultRelInfo;
937 mtstate->rootResultRelInfo = resultRelInfo;
938
939 if (resultRelInfo->ri_FdwRoutine != NULL &&
940 resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
941 resultRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate,
942 resultRelInfo);
943
944 /*
945 * Also, if the named relation is a foreign table, determine if the FDW
946 * supports batch insert and determine the batch size (a FDW may support
947 * batching, but it may be disabled for the server/table).
948 *
949 * If the FDW does not support batching, we set the batch size to 1.
950 */
951 if (resultRelInfo->ri_FdwRoutine != NULL &&
954 resultRelInfo->ri_BatchSize =
955 resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize(resultRelInfo);
956 else
957 resultRelInfo->ri_BatchSize = 1;
958
959 Assert(resultRelInfo->ri_BatchSize >= 1);
960
961 /* Prepare to catch AFTER triggers. */
963
964 /*
965 * If there are any triggers with transition tables on the named relation,
966 * we need to be prepared to capture transition tuples.
967 *
968 * Because partition tuple routing would like to know about whether
969 * transition capture is active, we also set it in mtstate, which is
970 * passed to ExecFindPartition() below.
971 */
972 cstate->transition_capture = mtstate->mt_transition_capture =
974 RelationGetRelid(cstate->rel),
975 CMD_INSERT);
976
977 /*
978 * If the named relation is a partitioned table, initialize state for
979 * CopyFrom tuple routing.
980 */
981 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
982 proute = ExecSetupPartitionTupleRouting(estate, cstate->rel);
983
984 if (cstate->whereClause)
985 cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause),
986 &mtstate->ps);
987
988 /*
989 * It's generally more efficient to prepare a bunch of tuples for
990 * insertion, and insert them in one
991 * table_multi_insert()/ExecForeignBatchInsert() call, than call
992 * table_tuple_insert()/ExecForeignInsert() separately for every tuple.
993 * However, there are a number of reasons why we might not be able to do
994 * this. These are explained below.
995 */
996 if (resultRelInfo->ri_TrigDesc != NULL &&
997 (resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
998 resultRelInfo->ri_TrigDesc->trig_insert_instead_row))
999 {
1000 /*
1001 * Can't support multi-inserts when there are any BEFORE/INSTEAD OF
1002 * triggers on the table. Such triggers might query the table we're
1003 * inserting into and act differently if the tuples that have already
1004 * been processed and prepared for insertion are not there.
1005 */
1007 }
1008 else if (resultRelInfo->ri_FdwRoutine != NULL &&
1009 resultRelInfo->ri_BatchSize == 1)
1010 {
1011 /*
1012 * Can't support multi-inserts to a foreign table if the FDW does not
1013 * support batching, or it's disabled for the server or foreign table.
1014 */
1016 }
1017 else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL &&
1018 resultRelInfo->ri_TrigDesc->trig_insert_new_table)
1019 {
1020 /*
1021 * For partitioned tables we can't support multi-inserts when there
1022 * are any statement level insert triggers. It might be possible to
1023 * allow partitioned tables with such triggers in the future, but for
1024 * now, CopyMultiInsertInfoFlush expects that any after row insert and
1025 * statement level insert triggers are on the same relation.
1026 */
1028 }
1029 else if (cstate->volatile_defexprs)
1030 {
1031 /*
1032 * Can't support multi-inserts if there are any volatile default
1033 * expressions in the table. Similarly to the trigger case above,
1034 * such expressions may query the table we're inserting into.
1035 *
1036 * Note: It does not matter if any partitions have any volatile
1037 * default expressions as we use the defaults from the target of the
1038 * COPY command.
1039 */
1041 }
1042 else if (contain_volatile_functions(cstate->whereClause))
1043 {
1044 /*
1045 * Can't support multi-inserts if there are any volatile function
1046 * expressions in WHERE clause. Similarly to the trigger case above,
1047 * such expressions may query the table we're inserting into.
1048 *
1049 * Note: the whereClause was already preprocessed in DoCopy(), so it's
1050 * okay to use contain_volatile_functions() directly.
1051 */
1053 }
1054 else
1055 {
1056 /*
1057 * For partitioned tables, we may still be able to perform bulk
1058 * inserts. However, the possibility of this depends on which types
1059 * of triggers exist on the partition. We must disable bulk inserts
1060 * if the partition is a foreign table that can't use batching or it
1061 * has any before row insert or insert instead triggers (same as we
1062 * checked above for the parent table). Since the partition's
1063 * resultRelInfos are initialized only when we actually need to insert
1064 * the first tuple into them, we must have the intermediate insert
1065 * method of CIM_MULTI_CONDITIONAL to flag that we must later
1066 * determine if we can use bulk-inserts for the partition being
1067 * inserted into.
1068 */
1069 if (proute)
1071 else
1073
1074 CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate,
1075 estate, mycid, ti_options);
1076 }
1077
1078 /*
1079 * If not using batch mode (which allocates slots as needed) set up a
1080 * tuple slot too. When inserting into a partitioned table, we also need
1081 * one, even if we might batch insert, to read the tuple in the root
1082 * partition's form.
1083 */
1085 {
1087 &estate->es_tupleTable);
1088 bistate = GetBulkInsertState();
1089 }
1090
1091 has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1092 resultRelInfo->ri_TrigDesc->trig_insert_before_row);
1093
1094 has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1095 resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
1096
1097 /*
1098 * Check BEFORE STATEMENT insertion triggers. It's debatable whether we
1099 * should do this for COPY, since it's not really an "INSERT" statement as
1100 * such. However, executing these triggers maintains consistency with the
1101 * EACH ROW triggers that we already fire on COPY.
1102 */
1103 ExecBSInsertTriggers(estate, resultRelInfo);
1104
1105 econtext = GetPerTupleExprContext(estate);
1106
1107 /* Set up callback to identify error line number */
1108 errcallback.callback = CopyFromErrorCallback;
1109 errcallback.arg = cstate;
1110 errcallback.previous = error_context_stack;
1111 error_context_stack = &errcallback;
1112
1113 for (;;)
1114 {
1116 bool skip_tuple;
1117
1119
1120 /*
1121 * Reset the per-tuple exprcontext. We do this after every tuple, to
1122 * clean-up after expression evaluations etc.
1123 */
1125
1126 /* select slot to (initially) load row into */
1127 if (insertMethod == CIM_SINGLE || proute)
1128 {
1130 Assert(myslot != NULL);
1131 }
1132 else
1133 {
1134 Assert(resultRelInfo == target_resultRelInfo);
1136
1138 resultRelInfo);
1139 }
1140
1141 /*
1142 * Switch to per-tuple context before calling NextCopyFrom, which does
1143 * evaluate default expressions etc. and requires per-tuple context.
1144 */
1146
1148
1149 /* Directly store the values/nulls array in the slot */
1150 if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
1151 break;
1152
1153 if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE &&
1154 cstate->escontext->error_occurred)
1155 {
1156 /*
1157 * Soft error occurred, skip this tuple and just make
1158 * ErrorSaveContext ready for the next NextCopyFrom. Since we
1159 * don't set details_wanted and error_data is not to be filled,
1160 * just resetting error_occurred is enough.
1161 */
1162 cstate->escontext->error_occurred = false;
1163
1164 /* Report that this tuple was skipped by the ON_ERROR clause */
1166 cstate->num_errors);
1167
1168 if (cstate->opts.reject_limit > 0 &&
1169 cstate->num_errors > cstate->opts.reject_limit)
1170 ereport(ERROR,
1172 errmsg("skipped more than REJECT_LIMIT (%" PRId64 ") rows due to data type incompatibility",
1173 cstate->opts.reject_limit)));
1174
1175 /* Repeat NextCopyFrom() until no soft error occurs */
1176 continue;
1177 }
1178
1180
1181 /*
1182 * Constraints and where clause might reference the tableoid column,
1183 * so (re-)initialize tts_tableOid before evaluating them.
1184 */
1185 myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc);
1186
1187 /* Triggers and stuff need to be invoked in query context. */
1188 MemoryContextSwitchTo(oldcontext);
1189
1190 if (cstate->whereClause)
1191 {
1192 econtext->ecxt_scantuple = myslot;
1193 /* Skip items that don't match COPY's WHERE clause */
1194 if (!ExecQual(cstate->qualexpr, econtext))
1195 {
1196 /*
1197 * Report that this tuple was filtered out by the WHERE
1198 * clause.
1199 */
1201 ++excluded);
1202 continue;
1203 }
1204 }
1205
1206 /* Determine the partition to insert the tuple into */
1207 if (proute)
1208 {
1209 TupleConversionMap *map;
1210
1211 /*
1212 * Attempt to find a partition suitable for this tuple.
1213 * ExecFindPartition() will raise an error if none can be found or
1214 * if the found partition is not suitable for INSERTs.
1215 */
1216 resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo,
1217 proute, myslot, estate);
1218
1219 if (prevResultRelInfo != resultRelInfo)
1220 {
1221 /* Determine which triggers exist on this partition */
1222 has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1223 resultRelInfo->ri_TrigDesc->trig_insert_before_row);
1224
1225 has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1226 resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
1227
1228 /*
1229 * Disable multi-inserts when the partition has BEFORE/INSTEAD
1230 * OF triggers, or if the partition is a foreign table that
1231 * can't use batching.
1232 */
1236 (resultRelInfo->ri_FdwRoutine == NULL ||
1237 resultRelInfo->ri_BatchSize > 1);
1238
1239 /* Set the multi-insert buffer to use for this partition. */
1241 {
1242 if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL)
1244 resultRelInfo);
1245 }
1246 else if (insertMethod == CIM_MULTI_CONDITIONAL &&
1248 {
1249 /*
1250 * Flush pending inserts if this partition can't use
1251 * batching, so rows are visible to triggers etc.
1252 */
1254 resultRelInfo,
1255 &processed);
1256 }
1257
1258 if (bistate != NULL)
1260 prevResultRelInfo = resultRelInfo;
1261 }
1262
1263 /*
1264 * If we're capturing transition tuples, we might need to convert
1265 * from the partition rowtype to root rowtype. But if there are no
1266 * BEFORE triggers on the partition that could change the tuple,
1267 * we can just remember the original unconverted tuple to avoid a
1268 * needless round trip conversion.
1269 */
1270 if (cstate->transition_capture != NULL)
1273
1274 /*
1275 * We might need to convert from the root rowtype to the partition
1276 * rowtype.
1277 */
1278 map = ExecGetRootToChildMap(resultRelInfo, estate);
1280 {
1281 /* non batch insert */
1282 if (map != NULL)
1283 {
1284 TupleTableSlot *new_slot;
1285
1286 new_slot = resultRelInfo->ri_PartitionTupleSlot;
1287 myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
1288 }
1289 }
1290 else
1291 {
1292 /*
1293 * Prepare to queue up tuple for later batch insert into
1294 * current partition.
1295 */
1297
1298 /* no other path available for partitioned table */
1300
1302 resultRelInfo);
1303
1304 if (map != NULL)
1306 batchslot);
1307 else
1308 {
1309 /*
1310 * This looks more expensive than it is (Believe me, I
1311 * optimized it away. Twice.). The input is in virtual
1312 * form, and we'll materialize the slot below - for most
1313 * slot types the copy performs the work materialization
1314 * would later require anyway.
1315 */
1317 myslot = batchslot;
1318 }
1319 }
1320
1321 /* ensure that triggers etc see the right relation */
1322 myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1323 }
1324
1325 skip_tuple = false;
1326
1327 /* BEFORE ROW INSERT Triggers */
1329 {
1330 if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot))
1331 skip_tuple = true; /* "do nothing" */
1332 }
1333
1334 if (!skip_tuple)
1335 {
1336 /*
1337 * If there is an INSTEAD OF INSERT ROW trigger, let it handle the
1338 * tuple. Otherwise, proceed with inserting the tuple into the
1339 * table or foreign table.
1340 */
1342 {
1343 ExecIRInsertTriggers(estate, resultRelInfo, myslot);
1344 }
1345 else
1346 {
1347 /* Compute stored generated columns */
1348 if (resultRelInfo->ri_RelationDesc->rd_att->constr &&
1350 ExecComputeStoredGenerated(resultRelInfo, estate, myslot,
1351 CMD_INSERT);
1352
1353 /*
1354 * If the target is a plain table, check the constraints of
1355 * the tuple.
1356 */
1357 if (resultRelInfo->ri_FdwRoutine == NULL &&
1358 resultRelInfo->ri_RelationDesc->rd_att->constr)
1359 ExecConstraints(resultRelInfo, myslot, estate);
1360
1361 /*
1362 * Also check the tuple against the partition constraint, if
1363 * there is one; except that if we got here via tuple-routing,
1364 * we don't need to if there's no BR trigger defined on the
1365 * partition.
1366 */
1367 if (resultRelInfo->ri_RelationDesc->rd_rel->relispartition &&
1368 (proute == NULL || has_before_insert_row_trig))
1369 ExecPartitionCheck(resultRelInfo, myslot, estate, true);
1370
1371 /* Store the slot in the multi-insert buffer, when enabled. */
1373 {
1374 /*
1375 * The slot previously might point into the per-tuple
1376 * context. For batching it needs to be longer lived.
1377 */
1379
1380 /* Add this tuple to the tuple buffer */
1382 resultRelInfo, myslot,
1383 cstate->line_buf.len,
1384 cstate->cur_lineno);
1385
1386 /*
1387 * If enough inserts have queued up, then flush all
1388 * buffers out to their tables.
1389 */
1392 resultRelInfo,
1393 &processed);
1394
1395 /*
1396 * We delay updating the row counter and progress of the
1397 * COPY command until after writing the tuples stored in
1398 * the buffer out to the table, as in single insert mode.
1399 * See CopyMultiInsertBufferFlush().
1400 */
1401 continue; /* next tuple please */
1402 }
1403 else
1404 {
1406
1407 /* OK, store the tuple */
1408 if (resultRelInfo->ri_FdwRoutine != NULL)
1409 {
1410 myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate,
1411 resultRelInfo,
1412 myslot,
1413 NULL);
1414
1415 if (myslot == NULL) /* "do nothing" */
1416 continue; /* next tuple please */
1417
1418 /*
1419 * AFTER ROW Triggers might reference the tableoid
1420 * column, so (re-)initialize tts_tableOid before
1421 * evaluating them.
1422 */
1423 myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1424 }
1425 else
1426 {
1427 /* OK, store the tuple and create index entries for it */
1428 table_tuple_insert(resultRelInfo->ri_RelationDesc,
1429 myslot, mycid, ti_options, bistate);
1430
1431 if (resultRelInfo->ri_NumIndices > 0)
1432 recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
1433 estate, 0,
1434 myslot, NIL,
1435 NULL);
1436 }
1437
1438 /* AFTER ROW INSERT Triggers */
1439 ExecARInsertTriggers(estate, resultRelInfo, myslot,
1441
1443 }
1444 }
1445
1446 /*
1447 * We count only tuples not suppressed by a BEFORE INSERT trigger
1448 * or FDW; this is the same definition used by nodeModifyTable.c
1449 * for counting tuples inserted by an INSERT command. Update
1450 * progress of the COPY command as well.
1451 */
1453 ++processed);
1454 }
1455 }
1456
1457 /* Flush any remaining buffered tuples */
1458 if (insertMethod != CIM_SINGLE)
1459 {
1462 }
1463
1464 /* Done, clean up */
1465 error_context_stack = errcallback.previous;
1466
1467 if (cstate->num_errors > 0 &&
1469 {
1470 if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE)
1472 errmsg_plural("%" PRIu64 " row was skipped due to data type incompatibility",
1473 "%" PRIu64 " rows were skipped due to data type incompatibility",
1474 cstate->num_errors,
1475 cstate->num_errors));
1476 else if (cstate->opts.on_error == COPY_ON_ERROR_SET_NULL)
1478 errmsg_plural("in %" PRIu64 " row, columns were set to null due to data type incompatibility",
1479 "in %" PRIu64 " rows, columns were set to null due to data type incompatibility",
1480 cstate->num_errors,
1481 cstate->num_errors));
1482 }
1483
1484 if (bistate != NULL)
1485 FreeBulkInsertState(bistate);
1486
1487 MemoryContextSwitchTo(oldcontext);
1488
1489 /* Execute AFTER STATEMENT insertion triggers */
1491
1492 /* Handle queued AFTER triggers */
1493 AfterTriggerEndQuery(estate);
1494
1495 ExecResetTupleTable(estate->es_tupleTable, false);
1496
1497 /* Allow the FDW to shut down */
1498 if (target_resultRelInfo->ri_FdwRoutine != NULL &&
1499 target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
1500 target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate,
1502
1503 /* Tear down the multi-insert buffer data */
1504 if (insertMethod != CIM_SINGLE)
1506
1507 /* Close all the partitioned tables, leaf partitions, and their indices */
1508 if (proute)
1509 ExecCleanupTupleRouting(mtstate, proute);
1510
1511 /* Close the result relations, including any trigger target relations */
1514
1515 FreeExecutorState(estate);
1516
1517 return processed;
1518}
void pgstat_progress_update_param(int index, int64 val)
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
#define InvalidSubTransactionId
Definition c.h:705
uint32 CommandId
Definition c.h:713
bool contain_volatile_functions(Node *clause)
Definition clauses.c:547
static void CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition copyfrom.c:381
static TupleTableSlot * CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition copyfrom.c:736
static void CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, CopyFromState cstate, EState *estate, CommandId mycid, int ti_options)
Definition copyfrom.c:401
static void CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri, int64 *processed)
Definition copyfrom.c:663
static void CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, TupleTableSlot *slot, int tuplen, uint64 lineno)
Definition copyfrom.c:757
static void CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo)
Definition copyfrom.c:717
static bool CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo)
Definition copyfrom.c:426
static bool CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo)
Definition copyfrom.c:438
void CopyFromErrorCallback(void *arg)
Definition copyfrom.c:255
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:229
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:1054
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition execMain.c:1860
void ExecCloseResultRelations(EState *estate)
Definition execMain.c:1579
void ExecCloseRangeTableRelations(EState *estate)
Definition execMain.c:1639
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition execMain.c:1984
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:1326
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos, Bitmapset *unpruned_relids)
Definition execUtils.c:773
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
Definition execUtils.c:880
void FreeExecutorState(EState *estate)
Definition execUtils.c:192
EState * CreateExecutorState(void)
Definition execUtils.c:88
#define ResetPerTupleExprContext(estate)
Definition executor.h:665
#define GetPerTupleExprContext(estate)
Definition executor.h:656
#define GetPerTupleMemoryContext(estate)
Definition executor.h:661
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition executor.h:519
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
Definition heapam.c:2104
BulkInsertState GetBulkInsertState(void)
Definition heapam.c:2075
void FreeBulkInsertState(BulkInsertState bistate)
Definition heapam.c:2092
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:1171
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition progress.h:166
#define PROGRESS_COPY_TUPLES_EXCLUDED
Definition progress.h:167
#define PROGRESS_COPY_TUPLES_SKIPPED
Definition progress.h:170
bool ThereAreNoPriorRegisteredSnapshots(void)
Definition snapmgr.c:1626
void InvalidateCatalogSnapshot(void)
Definition snapmgr.c:455
CopyLogVerbosityChoice log_verbosity
Definition copy.h:86
int64 reject_limit
Definition copy.h:87
StringInfoData line_buf
TransitionCaptureState * transition_capture
List * es_tupleTable
Definition execnodes.h:715
struct ErrorContextCallback * previous
Definition elog.h:297
void(* callback)(void *arg)
Definition elog.h:298
TupleTableSlot * ecxt_scantuple
Definition execnodes.h:275
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:1411
ResultRelInfo * rootResultRelInfo
Definition execnodes.h:1419
struct TransitionCaptureState * mt_transition_capture
Definition execnodes.h:1445
Plan * plan
Definition execnodes.h:1168
EState * state
Definition execnodes.h:1170
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:622
Relation ri_RelationDesc
Definition execnodes.h:483
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition execnodes.h:625
TriggerDesc * ri_TrigDesc
Definition execnodes.h:518
struct FdwRoutine * ri_FdwRoutine
Definition execnodes.h:536
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:141
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:4957
void ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
Definition trigger.c:2401
bool ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition trigger.c:2465
bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition trigger.c:2569
void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture)
Definition trigger.c:2543
void ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
Definition trigger.c:2452
void AfterTriggerEndQuery(EState *estate)
Definition trigger.c:5135
void AfterTriggerBeginQuery(void)
Definition trigger.c:5115
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:457
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition tuptable.h:524
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition tuptable.h:475
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 255 of file copyfrom.c.

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

References arg, CopyFormatOptions::binary, CopyLimitPrintoutLength(), CopyFromStateData::cur_attname, CopyFromStateData::cur_attval, CopyFromStateData::cur_lineno, CopyFromStateData::cur_relname, StringInfoData::data, errcontext, fb(), 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 1010 of file copy.c.

1011{
1012 List *attnums = NIL;
1013
1014 if (attnamelist == NIL)
1015 {
1016 /* Generate default column list */
1017 int attr_count = tupDesc->natts;
1018 int i;
1019
1020 for (i = 0; i < attr_count; i++)
1021 {
1022 CompactAttribute *attr = TupleDescCompactAttr(tupDesc, i);
1023
1024 if (attr->attisdropped || attr->attgenerated)
1025 continue;
1026 attnums = lappend_int(attnums, i + 1);
1027 }
1028 }
1029 else
1030 {
1031 /* Validate the user-supplied list and extract attnums */
1032 ListCell *l;
1033
1034 foreach(l, attnamelist)
1035 {
1036 char *name = strVal(lfirst(l));
1037 int attnum;
1038 int i;
1039
1040 /* Lookup column name */
1042 for (i = 0; i < tupDesc->natts; i++)
1043 {
1045
1046 if (att->attisdropped)
1047 continue;
1048 if (namestrcmp(&(att->attname), name) == 0)
1049 {
1050 if (att->attgenerated)
1051 ereport(ERROR,
1053 errmsg("column \"%s\" is a generated column",
1054 name),
1055 errdetail("Generated columns cannot be used in COPY.")));
1056 attnum = att->attnum;
1057 break;
1058 }
1059 }
1061 {
1062 if (rel != NULL)
1063 ereport(ERROR,
1065 errmsg("column \"%s\" of relation \"%s\" does not exist",
1067 else
1068 ereport(ERROR,
1070 errmsg("column \"%s\" does not exist",
1071 name)));
1072 }
1073 /* Check for duplicates */
1074 if (list_member_int(attnums, attnum))
1075 ereport(ERROR,
1077 errmsg("column \"%s\" specified more than once",
1078 name)));
1079 attnums = lappend_int(attnums, attnum);
1080 }
1081 }
1082
1083 return attnums;
1084}
#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:78
bool attisdropped
Definition tupdesc.h:77
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:175
#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 334 of file copyfrom.c.

335{
336#define MAX_COPY_DATA_DISPLAY 100
337
338 int slen = strlen(str);
339 int len;
340 char *res;
341
342 /* Fast path if definitely okay */
344 return pstrdup(str);
345
346 /* Apply encoding-dependent truncation */
348
349 /*
350 * Truncate, and add "..." to show we truncated the input.
351 */
352 res = (char *) palloc(len + 4);
353 memcpy(res, str, len);
354 strcpy(res + len, "...");
355
356 return res;
357}
#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 1531 of file copyto.c.

1532{
1533 DR_copy *self = palloc_object(DR_copy);
1534
1539 self->pub.mydest = DestCopyOut;
1540
1541 self->cstate = NULL; /* will be set later */
1542 self->processed = 0;
1543
1544 return (DestReceiver *) self;
1545}
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1494
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1522
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1513
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1485
#define palloc_object(type)
Definition fe_memutils.h:74
CopyToState cstate
Definition copyto.c:108
DestReceiver pub
Definition copyto.c:107
uint64 processed
Definition copyto.c:109
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:5298
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:2267
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:1534
uint64 CopyFrom(CopyFromState cstate)
Definition copyfrom.c:780
void EndCopyFrom(CopyFromState cstate)
Definition copyfrom.c:1940
uint64 DoCopyTo(CopyToState cstate)
Definition copyto.c:1064
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:635
void EndCopyTo(CopyToState cstate)
Definition copyto.c:1043
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
Definition execMain.c:582
#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:903
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3518
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:120
@ 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:212
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:406
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 1064 of file copyto.c.

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

1941{
1942 /* Invoke the end callback */
1943 cstate->routine->CopyFromEnd(cstate);
1944
1945 /* No COPY FROM related resources except memory. */
1946 if (cstate->is_program)
1947 {
1948 ClosePipeFromProgram(cstate);
1949 }
1950 else
1951 {
1952 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
1953 ereport(ERROR,
1955 errmsg("could not close file \"%s\": %m",
1956 cstate->filename)));
1957 }
1958
1960
1962 pfree(cstate);
1963}
void pgstat_progress_end_command(void)
static void ClosePipeFromProgram(CopyFromState cstate)
Definition copyfrom.c:1969
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 1043 of file copyto.c.

1044{
1045 if (cstate->queryDesc != NULL)
1046 {
1047 /* Close down the query and free resources. */
1048 ExecutorFinish(cstate->queryDesc);
1049 ExecutorEnd(cstate->queryDesc);
1050 FreeQueryDesc(cstate->queryDesc);
1052 }
1053
1054 /* Clean up storage */
1055 EndCopy(cstate);
1056}
static void EndCopy(CopyToState cstate)
Definition copyto.c:595
void ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:466
void ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:406
void FreeQueryDesc(QueryDesc *qdesc)
Definition pquery.c:106
void PopActiveSnapshot(void)
Definition snapmgr.c:775

References EndCopy(), ExecutorEnd(), ExecutorFinish(), fb(), FreeQueryDesc(), PopActiveSnapshot(), and CopyToStateData::queryDesc.

Referenced by DoCopy(), and test_copy_to_callback().

◆ NextCopyFrom()

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

Definition at line 884 of file copyfromparse.c.

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

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 751 of file copyfromparse.c.

752{
753 return NextCopyFromRawFieldsInternal(cstate, fields, nfields,
754 cstate->opts.csv_mode);
755}
static pg_attribute_always_inline bool NextCopyFromRawFieldsInternal(CopyFromState cstate, char ***fields, int *nfields, bool is_csv)
bool csv_mode
Definition copy.h:64

References CopyFormatOptions::csv_mode, 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;
573
574 /* Support external use for option sanity checking */
575 if (opts_out == NULL)
577
578 opts_out->file_encoding = -1;
579
580 /* Extract options from the statement node tree */
581 foreach(option, options)
582 {
584
585 if (strcmp(defel->defname, "format") == 0)
586 {
587 char *fmt = defGetString(defel);
588
591 format_specified = true;
592 if (strcmp(fmt, "text") == 0)
593 /* default format */ ;
594 else if (strcmp(fmt, "csv") == 0)
595 opts_out->csv_mode = true;
596 else if (strcmp(fmt, "binary") == 0)
597 opts_out->binary = true;
598 else
601 errmsg("COPY format \"%s\" not recognized", fmt),
602 parser_errposition(pstate, defel->location)));
603 }
604 else if (strcmp(defel->defname, "freeze") == 0)
605 {
608 freeze_specified = true;
609 opts_out->freeze = defGetBoolean(defel);
610 }
611 else if (strcmp(defel->defname, "delimiter") == 0)
612 {
613 if (opts_out->delim)
615 opts_out->delim = defGetString(defel);
616 }
617 else if (strcmp(defel->defname, "null") == 0)
618 {
619 if (opts_out->null_print)
621 opts_out->null_print = defGetString(defel);
622 }
623 else if (strcmp(defel->defname, "default") == 0)
624 {
625 if (opts_out->default_print)
627 opts_out->default_print = defGetString(defel);
628 }
629 else if (strcmp(defel->defname, "header") == 0)
630 {
633 header_specified = true;
634 opts_out->header_line = defGetCopyHeaderOption(defel, is_from);
635 }
636 else if (strcmp(defel->defname, "quote") == 0)
637 {
638 if (opts_out->quote)
640 opts_out->quote = defGetString(defel);
641 }
642 else if (strcmp(defel->defname, "escape") == 0)
643 {
644 if (opts_out->escape)
646 opts_out->escape = defGetString(defel);
647 }
648 else if (strcmp(defel->defname, "force_quote") == 0)
649 {
650 if (opts_out->force_quote || opts_out->force_quote_all)
652 if (defel->arg && IsA(defel->arg, A_Star))
653 opts_out->force_quote_all = true;
654 else if (defel->arg && IsA(defel->arg, List))
655 opts_out->force_quote = castNode(List, defel->arg);
656 else
659 errmsg("argument to option \"%s\" must be a list of column names",
660 defel->defname),
661 parser_errposition(pstate, defel->location)));
662 }
663 else if (strcmp(defel->defname, "force_not_null") == 0)
664 {
665 if (opts_out->force_notnull || opts_out->force_notnull_all)
667 if (defel->arg && IsA(defel->arg, A_Star))
668 opts_out->force_notnull_all = true;
669 else if (defel->arg && IsA(defel->arg, List))
670 opts_out->force_notnull = castNode(List, defel->arg);
671 else
674 errmsg("argument to option \"%s\" must be a list of column names",
675 defel->defname),
676 parser_errposition(pstate, defel->location)));
677 }
678 else if (strcmp(defel->defname, "force_null") == 0)
679 {
680 if (opts_out->force_null || opts_out->force_null_all)
682 if (defel->arg && IsA(defel->arg, A_Star))
683 opts_out->force_null_all = true;
684 else if (defel->arg && IsA(defel->arg, List))
685 opts_out->force_null = castNode(List, defel->arg);
686 else
689 errmsg("argument to option \"%s\" must be a list of column names",
690 defel->defname),
691 parser_errposition(pstate, defel->location)));
692 }
693 else if (strcmp(defel->defname, "convert_selectively") == 0)
694 {
695 /*
696 * Undocumented, not-accessible-from-SQL option: convert only the
697 * named columns to binary form, storing the rest as NULLs. It's
698 * allowed for the column list to be NIL.
699 */
700 if (opts_out->convert_selectively)
702 opts_out->convert_selectively = true;
703 if (defel->arg == NULL || IsA(defel->arg, List))
704 opts_out->convert_select = castNode(List, defel->arg);
705 else
708 errmsg("argument to option \"%s\" must be a list of column names",
709 defel->defname),
710 parser_errposition(pstate, defel->location)));
711 }
712 else if (strcmp(defel->defname, "encoding") == 0)
713 {
714 if (opts_out->file_encoding >= 0)
717 if (opts_out->file_encoding < 0)
720 errmsg("argument to option \"%s\" must be a valid encoding name",
721 defel->defname),
722 parser_errposition(pstate, defel->location)));
723 }
724 else if (strcmp(defel->defname, "on_error") == 0)
725 {
728 on_error_specified = true;
729 opts_out->on_error = defGetCopyOnErrorChoice(defel, pstate, is_from);
730 }
731 else if (strcmp(defel->defname, "log_verbosity") == 0)
732 {
736 opts_out->log_verbosity = defGetCopyLogVerbosityChoice(defel, pstate);
737 }
738 else if (strcmp(defel->defname, "reject_limit") == 0)
739 {
744 }
745 else
748 errmsg("option \"%s\" not recognized",
749 defel->defname),
750 parser_errposition(pstate, defel->location)));
751 }
752
753 /*
754 * Check for incompatible options (must do these three before inserting
755 * defaults)
756 */
757 if (opts_out->binary && opts_out->delim)
760 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
761 errmsg("cannot specify %s in BINARY mode", "DELIMITER")));
762
763 if (opts_out->binary && opts_out->null_print)
766 errmsg("cannot specify %s in BINARY mode", "NULL")));
767
768 if (opts_out->binary && opts_out->default_print)
771 errmsg("cannot specify %s in BINARY mode", "DEFAULT")));
772
773 /* Set defaults for omitted options */
774 if (!opts_out->delim)
775 opts_out->delim = opts_out->csv_mode ? "," : "\t";
776
777 if (!opts_out->null_print)
778 opts_out->null_print = opts_out->csv_mode ? "" : "\\N";
779 opts_out->null_print_len = strlen(opts_out->null_print);
780
781 if (opts_out->csv_mode)
782 {
783 if (!opts_out->quote)
784 opts_out->quote = "\"";
785 if (!opts_out->escape)
786 opts_out->escape = opts_out->quote;
787 }
788
789 /* Only single-byte delimiter strings are supported. */
790 if (strlen(opts_out->delim) != 1)
793 errmsg("COPY delimiter must be a single one-byte character")));
794
795 /* Disallow end-of-line characters */
796 if (strchr(opts_out->delim, '\r') != NULL ||
797 strchr(opts_out->delim, '\n') != NULL)
800 errmsg("COPY delimiter cannot be newline or carriage return")));
801
802 if (strchr(opts_out->null_print, '\r') != NULL ||
803 strchr(opts_out->null_print, '\n') != NULL)
806 errmsg("COPY null representation cannot use newline or carriage return")));
807
808 if (opts_out->default_print)
809 {
810 opts_out->default_print_len = strlen(opts_out->default_print);
811
812 if (strchr(opts_out->default_print, '\r') != NULL ||
813 strchr(opts_out->default_print, '\n') != NULL)
816 errmsg("COPY default representation cannot use newline or carriage return")));
817 }
818
819 /*
820 * Disallow unsafe delimiter characters in non-CSV mode. We can't allow
821 * backslash because it would be ambiguous. We can't allow the other
822 * cases because data characters matching the delimiter must be
823 * backslashed, and certain backslash combinations are interpreted
824 * non-literally by COPY IN. Disallowing all lower case ASCII letters is
825 * more than strictly necessary, but seems best for consistency and
826 * future-proofing. Likewise we disallow all digits though only octal
827 * digits are actually dangerous.
828 */
829 if (!opts_out->csv_mode &&
830 strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
831 opts_out->delim[0]) != NULL)
834 errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));
835
836 /* Check header */
837 if (opts_out->binary && opts_out->header_line != COPY_HEADER_FALSE)
840 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
841 errmsg("cannot specify %s in BINARY mode", "HEADER")));
842
843 /* Check quote */
844 if (!opts_out->csv_mode && opts_out->quote != NULL)
847 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
848 errmsg("COPY %s requires CSV mode", "QUOTE")));
849
850 if (opts_out->csv_mode && strlen(opts_out->quote) != 1)
853 errmsg("COPY quote must be a single one-byte character")));
854
855 if (opts_out->csv_mode && opts_out->delim[0] == opts_out->quote[0])
858 errmsg("COPY delimiter and quote must be different")));
859
860 /* Check escape */
861 if (!opts_out->csv_mode && opts_out->escape != NULL)
864 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
865 errmsg("COPY %s requires CSV mode", "ESCAPE")));
866
867 if (opts_out->csv_mode && strlen(opts_out->escape) != 1)
870 errmsg("COPY escape must be a single one-byte character")));
871
872 /* Check force_quote */
873 if (!opts_out->csv_mode && (opts_out->force_quote || opts_out->force_quote_all))
876 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
877 errmsg("COPY %s requires CSV mode", "FORCE_QUOTE")));
878 if ((opts_out->force_quote || opts_out->force_quote_all) && is_from)
881 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
882 second %s is a COPY with direction, e.g. COPY TO */
883 errmsg("COPY %s cannot be used with %s", "FORCE_QUOTE",
884 "COPY FROM")));
885
886 /* Check force_notnull */
887 if (!opts_out->csv_mode && (opts_out->force_notnull != NIL ||
888 opts_out->force_notnull_all))
891 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
892 errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
893 if ((opts_out->force_notnull != NIL || opts_out->force_notnull_all) &&
894 !is_from)
897 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
898 second %s is a COPY with direction, e.g. COPY TO */
899 errmsg("COPY %s cannot be used with %s", "FORCE_NOT_NULL",
900 "COPY TO")));
901
902 /* Check force_null */
903 if (!opts_out->csv_mode && (opts_out->force_null != NIL ||
904 opts_out->force_null_all))
907 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
908 errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
909
910 if ((opts_out->force_null != NIL || opts_out->force_null_all) &&
911 !is_from)
914 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
915 second %s is a COPY with direction, e.g. COPY TO */
916 errmsg("COPY %s cannot be used with %s", "FORCE_NULL",
917 "COPY TO")));
918
919 /* Don't allow the delimiter to appear in the null string. */
920 if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL)
923 /*- translator: %s is the name of a COPY option, e.g. NULL */
924 errmsg("COPY delimiter character must not appear in the %s specification",
925 "NULL")));
926
927 /* Don't allow the CSV quote char to appear in the null string. */
928 if (opts_out->csv_mode &&
929 strchr(opts_out->null_print, opts_out->quote[0]) != NULL)
932 /*- translator: %s is the name of a COPY option, e.g. NULL */
933 errmsg("CSV quote character must not appear in the %s specification",
934 "NULL")));
935
936 /* Check freeze */
937 if (opts_out->freeze && !is_from)
940 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
941 second %s is a COPY with direction, e.g. COPY TO */
942 errmsg("COPY %s cannot be used with %s", "FREEZE",
943 "COPY TO")));
944
945 if (opts_out->default_print)
946 {
947 if (!is_from)
950 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
951 second %s is a COPY with direction, e.g. COPY TO */
952 errmsg("COPY %s cannot be used with %s", "DEFAULT",
953 "COPY TO")));
954
955 /* Don't allow the delimiter to appear in the default string. */
956 if (strchr(opts_out->default_print, opts_out->delim[0]) != NULL)
959 /*- translator: %s is the name of a COPY option, e.g. NULL */
960 errmsg("COPY delimiter character must not appear in the %s specification",
961 "DEFAULT")));
962
963 /* Don't allow the CSV quote char to appear in the default string. */
964 if (opts_out->csv_mode &&
965 strchr(opts_out->default_print, opts_out->quote[0]) != NULL)
968 /*- translator: %s is the name of a COPY option, e.g. NULL */
969 errmsg("CSV quote character must not appear in the %s specification",
970 "DEFAULT")));
971
972 /* Don't allow the NULL and DEFAULT string to be the same */
973 if (opts_out->null_print_len == opts_out->default_print_len &&
974 strncmp(opts_out->null_print, opts_out->default_print,
975 opts_out->null_print_len) == 0)
978 errmsg("NULL specification and DEFAULT specification cannot be the same")));
979 }
980 /* Check on_error */
981 if (opts_out->binary && opts_out->on_error != COPY_ON_ERROR_STOP)
984 errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
985
986 if (opts_out->reject_limit && opts_out->on_error != COPY_ON_ERROR_IGNORE)
989 /*- translator: first and second %s are the names of COPY option, e.g.
990 * ON_ERROR, third is the value of the COPY option, e.g. IGNORE */
991 errmsg("COPY %s requires %s to be set to %s",
992 "REJECT_LIMIT", "ON_ERROR", "IGNORE")));
993}
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_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().