PostgreSQL Source Code git master
Loading...
Searching...
No Matches
copy.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include "access/sysattr.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/pg_authid.h"
#include "commands/copy.h"
#include "commands/defrem.h"
#include "executor/executor.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/miscnodes.h"
#include "optimizer/optimizer.h"
#include "parser/parse_coerce.h"
#include "parser/parse_collate.h"
#include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/rls.h"
Include dependency graph for copy.c:

Go to the source code of this file.

Functions

void DoCopy (ParseState *pstate, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
 
static int defGetCopyHeaderOption (DefElem *def, bool is_from)
 
static CopyOnErrorChoice defGetCopyOnErrorChoice (DefElem *def, ParseState *pstate, bool is_from)
 
static int64 defGetCopyRejectLimitOption (DefElem *def)
 
static CopyLogVerbosityChoice defGetCopyLogVerbosityChoice (DefElem *def, ParseState *pstate)
 
void ProcessCopyOptions (ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
 
ListCopyGetAttnums (TupleDesc tupDesc, Relation rel, List *attnamelist)
 

Function Documentation

◆ CopyGetAttnums()

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

Definition at line 1068 of file copy.c.

1069{
1070 List *attnums = NIL;
1071
1072 if (attnamelist == NIL)
1073 {
1074 /* Generate default column list */
1075 int attr_count = tupDesc->natts;
1076 int i;
1077
1078 for (i = 0; i < attr_count; i++)
1079 {
1080 CompactAttribute *attr = TupleDescCompactAttr(tupDesc, i);
1081
1082 if (attr->attisdropped || attr->attgenerated)
1083 continue;
1084 attnums = lappend_int(attnums, i + 1);
1085 }
1086 }
1087 else
1088 {
1089 /* Validate the user-supplied list and extract attnums */
1090 ListCell *l;
1091
1092 foreach(l, attnamelist)
1093 {
1094 char *name = strVal(lfirst(l));
1095 int attnum;
1096 int i;
1097
1098 /* Lookup column name */
1100 for (i = 0; i < tupDesc->natts; i++)
1101 {
1102 Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1103
1104 if (att->attisdropped)
1105 continue;
1106 if (namestrcmp(&(att->attname), name) == 0)
1107 {
1108 if (att->attgenerated)
1109 ereport(ERROR,
1111 errmsg("column \"%s\" is a generated column",
1112 name),
1113 errdetail("Generated columns cannot be used in COPY.")));
1114 attnum = att->attnum;
1115 break;
1116 }
1117 }
1119 {
1120 if (rel != NULL)
1121 ereport(ERROR,
1123 errmsg("column \"%s\" of relation \"%s\" does not exist",
1125 else
1126 ereport(ERROR,
1128 errmsg("column \"%s\" does not exist",
1129 name)));
1130 }
1131 /* Check for duplicates */
1132 if (list_member_int(attnums, attnum))
1133 ereport(ERROR,
1135 errmsg("column \"%s\" specified more than once",
1136 name)));
1137 attnums = lappend_int(attnums, attnum);
1138 }
1139 }
1140
1141 return attnums;
1142}
#define InvalidAttrNumber
Definition attnum.h:23
int errcode(int sqlerrcode)
Definition elog.c:874
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
int i
Definition isn.c:77
List * lappend_int(List *list, int datum)
Definition list.c:357
bool list_member_int(const List *list, int datum)
Definition list.c:702
int namestrcmp(Name name, const char *str)
Definition name.c:247
static char * errmsg
int16 attnum
FormData_pg_attribute * Form_pg_attribute
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
static int fb(int x)
#define RelationGetRelationName(relation)
Definition rel.h:550
bool attgenerated
Definition tupdesc.h:79
bool attisdropped
Definition tupdesc.h:78
Definition pg_list.h:54
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:195
#define strVal(v)
Definition value.h:82
const char * name

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

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

◆ defGetCopyHeaderOption()

static int defGetCopyHeaderOption ( DefElem def,
bool  is_from 
)
static

Definition at line 396 of file copy.c.

397{
398 int ival = COPY_HEADER_FALSE;
399
400 /*
401 * If no parameter value given, assume "true" is meant.
402 */
403 if (def->arg == NULL)
404 return COPY_HEADER_TRUE;
405
406 /*
407 * Allow an integer value greater than or equal to zero (integers
408 * specified as strings are also accepted, mainly for file_fdw foreign
409 * table options), "true", "false", "on", "off", or "match".
410 */
411 switch (nodeTag(def->arg))
412 {
413 case T_Integer:
414 ival = intVal(def->arg);
415 break;
416 default:
417 {
418 char *sval = defGetString(def);
419
420 /*
421 * The set of strings accepted here should match up with the
422 * grammar's opt_boolean_or_string production.
423 */
424 if (pg_strcasecmp(sval, "true") == 0)
425 return COPY_HEADER_TRUE;
426 if (pg_strcasecmp(sval, "false") == 0)
427 return COPY_HEADER_FALSE;
428 if (pg_strcasecmp(sval, "on") == 0)
429 return COPY_HEADER_TRUE;
430 if (pg_strcasecmp(sval, "off") == 0)
431 return COPY_HEADER_FALSE;
432 if (pg_strcasecmp(sval, "match") == 0)
433 {
434 if (!is_from)
437 errmsg("cannot use \"%s\" with HEADER in COPY TO",
438 sval)));
439 return COPY_HEADER_MATCH;
440 }
441 else
442 {
444
445 /* Check if the header is a valid integer */
446 ival = pg_strtoint32_safe(sval, (Node *) &escontext);
447 if (escontext.error_occurred)
450 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
451 second %s is the special value "match" for that option */
452 errmsg("%s requires a Boolean value, an integer "
453 "value greater than or equal to zero, "
454 "or the string \"%s\"",
455 def->defname, "match")));
456 }
457 }
458 break;
459 }
460
461 if (ival < 0)
464 errmsg("a negative integer value cannot be "
465 "specified for %s", def->defname)));
466
467 if (!is_from && ival > 1)
470 errmsg("cannot use multi-line header in COPY TO")));
471
472 return ival;
473}
char * defGetString(DefElem *def)
Definition define.c:34
#define COPY_HEADER_MATCH
Definition copy.h:26
#define COPY_HEADER_FALSE
Definition copy.h:27
#define COPY_HEADER_TRUE
Definition copy.h:28
#define nodeTag(nodeptr)
Definition nodes.h:139
int32 pg_strtoint32_safe(const char *s, Node *escontext)
Definition numutils.c:388
int pg_strcasecmp(const char *s1, const char *s2)
char * defname
Definition parsenodes.h:860
Node * arg
Definition parsenodes.h:861
Definition nodes.h:135
#define intVal(v)
Definition value.h:79

References DefElem::arg, COPY_HEADER_FALSE, COPY_HEADER_MATCH, COPY_HEADER_TRUE, defGetString(), DefElem::defname, ereport, errcode(), errmsg, ERROR, ErrorSaveContext::error_occurred, fb(), intVal, nodeTag, pg_strcasecmp(), and pg_strtoint32_safe().

Referenced by ProcessCopyOptions().

◆ defGetCopyLogVerbosityChoice()

static CopyLogVerbosityChoice defGetCopyLogVerbosityChoice ( DefElem def,
ParseState pstate 
)
static

Definition at line 541 of file copy.c.

542{
543 char *sval;
544
545 /*
546 * Allow "silent", "default", or "verbose" values.
547 */
548 sval = defGetString(def);
549 if (pg_strcasecmp(sval, "silent") == 0)
551 if (pg_strcasecmp(sval, "default") == 0)
553 if (pg_strcasecmp(sval, "verbose") == 0)
555
558 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR */
559 errmsg("COPY %s \"%s\" not recognized", "LOG_VERBOSITY", sval),
560 parser_errposition(pstate, def->location)));
561 return COPY_LOG_VERBOSITY_DEFAULT; /* keep compiler quiet */
562}
@ COPY_LOG_VERBOSITY_SILENT
Definition copy.h:46
@ COPY_LOG_VERBOSITY_VERBOSE
Definition copy.h:49
@ COPY_LOG_VERBOSITY_DEFAULT
Definition copy.h:47
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
ParseLoc location
Definition parsenodes.h:864

References COPY_LOG_VERBOSITY_DEFAULT, COPY_LOG_VERBOSITY_SILENT, COPY_LOG_VERBOSITY_VERBOSE, defGetString(), ereport, errcode(), errmsg, ERROR, fb(), DefElem::location, parser_errposition(), and pg_strcasecmp().

Referenced by ProcessCopyOptions().

◆ defGetCopyOnErrorChoice()

static CopyOnErrorChoice defGetCopyOnErrorChoice ( DefElem def,
ParseState pstate,
bool  is_from 
)
static

Definition at line 479 of file copy.c.

480{
481 char *sval = defGetString(def);
482
483 if (!is_from)
486 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
487 second %s is a COPY with direction, e.g. COPY TO */
488 errmsg("COPY %s cannot be used with %s", "ON_ERROR", "COPY TO"),
489 parser_errposition(pstate, def->location)));
490
491 if (pg_strcasecmp(sval, "stop") == 0)
492 return COPY_ON_ERROR_STOP;
493 if (pg_strcasecmp(sval, "ignore") == 0)
495 if (pg_strcasecmp(sval, "set_null") == 0)
497
500 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR */
501 errmsg("COPY %s \"%s\" not recognized", "ON_ERROR", sval),
502 parser_errposition(pstate, def->location)));
503 return COPY_ON_ERROR_STOP; /* keep compiler quiet */
504}
@ 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

References COPY_ON_ERROR_IGNORE, COPY_ON_ERROR_SET_NULL, COPY_ON_ERROR_STOP, defGetString(), ereport, errcode(), errmsg, ERROR, fb(), DefElem::location, parser_errposition(), and pg_strcasecmp().

Referenced by ProcessCopyOptions().

◆ defGetCopyRejectLimitOption()

static int64 defGetCopyRejectLimitOption ( DefElem def)
static

Definition at line 514 of file copy.c.

515{
516 int64 reject_limit;
517
518 if (def->arg == NULL)
521 errmsg("%s requires a numeric value",
522 def->defname)));
523 else if (IsA(def->arg, String))
524 reject_limit = pg_strtoint64(strVal(def->arg));
525 else
526 reject_limit = defGetInt64(def);
527
528 if (reject_limit <= 0)
531 errmsg("REJECT_LIMIT (%" PRId64 ") must be greater than zero",
532 reject_limit)));
533
534 return reject_limit;
535}
int64_t int64
Definition c.h:621
int64 defGetInt64(DefElem *def)
Definition define.c:172
#define IsA(nodeptr, _type_)
Definition nodes.h:164
int64 pg_strtoint64(const char *s)
Definition numutils.c:643
Definition value.h:64

References DefElem::arg, defGetInt64(), DefElem::defname, ereport, errcode(), errmsg, ERROR, fb(), IsA, pg_strtoint64(), and strVal.

Referenced by ProcessCopyOptions().

◆ DoCopy()

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

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 * Identify all columns used in the WHERE clause's expression. If
154 * there's a whole-row reference, replace it with a range of all
155 * the user columns (caution: that'll include dropped columns).
156 */
157 pull_varattnos(whereClause, 1, &expr_attrs);
159 {
164 }
165
166 /* Now we can scan each column needed in the WHERE clause */
167 i = -1;
168 while ((i = bms_next_member(expr_attrs, i)) >= 0)
169 {
172
173 Assert(attno != 0); /* removed above */
174
175 /*
176 * Prohibit system columns in the WHERE clause. They won't
177 * have been filled yet when the filtering happens. (We could
178 * allow tableoid, but right now it isn't really useful: it
179 * will read as the target table's OID. Any conceivable use
180 * for such a WHERE clause would probably wish it to read as
181 * the target partition's OID, which is not known yet.
182 * Disallow it to keep flexibility to change that sometime.)
183 */
184 if (attno < 0)
187 errmsg("system columns are not supported in COPY FROM WHERE conditions"),
188 errdetail("Column \"%s\" is a system column.",
189 get_attname(RelationGetRelid(rel), attno, false)));
190
191 /*
192 * Prohibit generated columns in the WHERE clause. Stored
193 * generated columns are not yet computed when the filtering
194 * happens. Virtual generated columns could probably work (we
195 * would need to expand them somewhere around here), but for
196 * now we keep them consistent with the stored variant.
197 */
198 att = TupleDescAttr(RelationGetDescr(rel), attno - 1);
199 if (att->attgenerated && !att->attisdropped)
202 errmsg("generated columns are not supported in COPY FROM WHERE conditions"),
203 errdetail("Column \"%s\" is a generated column.",
204 get_attname(RelationGetRelid(rel), attno, false)));
205 }
206
207 /* Reduce WHERE clause to standard list-of-AND-terms form */
208 whereClause = eval_const_expressions(NULL, whereClause);
209
210 whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
211 whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
212 }
213
214 tupDesc = RelationGetDescr(rel);
215 attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist);
216 foreach(cur, attnums)
217 {
218 int attno;
219 Bitmapset **bms;
220
222 bms = is_from ? &perminfo->insertedCols : &perminfo->selectedCols;
223
224 *bms = bms_add_member(*bms, attno);
225 }
227
228 /*
229 * Permission check for row security policies.
230 *
231 * check_enable_rls will ereport(ERROR) if the user has requested
232 * something invalid and will otherwise indicate if we should enable
233 * RLS (returns RLS_ENABLED) or not for this COPY statement.
234 *
235 * If the relation has a row security policy and we are to apply it
236 * then perform a "query" copy and allow the normal query processing
237 * to handle the policies.
238 *
239 * If RLS is not enabled for this, then just fall through to the
240 * normal non-filtering relation handling.
241 */
242 if (check_enable_rls(relid, InvalidOid, false) == RLS_ENABLED)
243 {
245 ColumnRef *cr;
246 ResTarget *target;
247 RangeVar *from;
248 List *targetList = NIL;
249
250 if (is_from)
253 errmsg("COPY FROM not supported with row-level security"),
254 errhint("Use INSERT statements instead.")));
255
256 /*
257 * Build target list
258 *
259 * If no columns are specified in the attribute list of the COPY
260 * command, then the target list is 'all' columns. Therefore, '*'
261 * should be used as the target list for the resulting SELECT
262 * statement.
263 *
264 * In the case that columns are specified in the attribute list,
265 * create a ColumnRef and ResTarget for each column and add them
266 * to the target list for the resulting SELECT statement.
267 */
268 if (!stmt->attlist)
269 {
271 cr->fields = list_make1(makeNode(A_Star));
272 cr->location = -1;
273
274 target = makeNode(ResTarget);
275 target->name = NULL;
276 target->indirection = NIL;
277 target->val = (Node *) cr;
278 target->location = -1;
279
280 targetList = list_make1(target);
281 }
282 else
283 {
284 ListCell *lc;
285
286 foreach(lc, stmt->attlist)
287 {
288 /*
289 * Build the ColumnRef for each column. The ColumnRef
290 * 'fields' property is a String node that corresponds to
291 * the column name respectively.
292 */
294 cr->fields = list_make1(lfirst(lc));
295 cr->location = -1;
296
297 /* Build the ResTarget and add the ColumnRef to it. */
298 target = makeNode(ResTarget);
299 target->name = NULL;
300 target->indirection = NIL;
301 target->val = (Node *) cr;
302 target->location = -1;
303
304 /* Add each column to the SELECT statement's target list */
305 targetList = lappend(targetList, target);
306 }
307 }
308
309 /*
310 * Build RangeVar for from clause, fully qualified based on the
311 * relation which we have opened and locked. Use "ONLY" so that
312 * COPY retrieves rows from only the target table not any
313 * inheritance children, the same as when RLS doesn't apply.
314 *
315 * However, when copying data from a partitioned table, we don't
316 * use "ONLY", since we need to retrieve rows from its descendant
317 * tables too.
318 */
321 -1);
322 from->inh = (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
323
324 /* Build query */
326 select->targetList = targetList;
327 select->fromClause = list_make1(from);
328
329 query = makeNode(RawStmt);
330 query->stmt = (Node *) select;
331 query->stmt_location = stmt_location;
332 query->stmt_len = stmt_len;
333
334 /*
335 * Close the relation for now, but keep the lock on it to prevent
336 * changes between now and when we start the query-based COPY.
337 *
338 * We'll reopen it later as part of the query-based COPY.
339 */
340 table_close(rel, NoLock);
341 rel = NULL;
342 }
343 }
344 else
345 {
346 Assert(stmt->query);
347
348 query = makeNode(RawStmt);
349 query->stmt = stmt->query;
350 query->stmt_location = stmt_location;
351 query->stmt_len = stmt_len;
352
353 relid = InvalidOid;
354 rel = NULL;
355 }
356
357 if (is_from)
358 {
359 CopyFromState cstate;
360
361 Assert(rel);
362
363 /* check read-only transaction and parallel mode */
364 if (XactReadOnly && !rel->rd_islocaltemp)
365 PreventCommandIfReadOnly("COPY FROM");
366
367 cstate = BeginCopyFrom(pstate, rel, whereClause,
368 stmt->filename, stmt->is_program,
369 NULL, stmt->attlist, stmt->options);
370 *processed = CopyFrom(cstate); /* copy from file to database */
371 EndCopyFrom(cstate);
372 }
373 else
374 {
375 CopyToState cstate;
376
377 cstate = BeginCopyTo(pstate, rel, query, relid,
378 stmt->filename, stmt->is_program,
379 NULL, stmt->attlist, stmt->options);
380 *processed = DoCopyTo(cstate); /* copy from database to file */
381 EndCopyTo(cstate);
382 }
383
384 if (rel != NULL)
385 table_close(rel, NoLock);
386}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
int16 AttrNumber
Definition attnum.h:21
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition copy.c:1068
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
#define Assert(condition)
Definition c.h:943
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition clauses.c:2498
CopyFromState BeginCopyFrom(ParseState *pstate, Relation rel, Node *whereClause, const char *filename, bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options)
Definition copyfrom.c:1535
uint64 CopyFrom(CopyFromState cstate)
Definition copyfrom.c:781
void EndCopyFrom(CopyFromState cstate)
Definition copyfrom.c:1942
uint64 DoCopyTo(CopyToState cstate)
Definition copyto.c:1241
CopyToState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *raw_query, Oid queryRelId, const char *filename, bool is_program, copy_data_dest_cb data_dest_cb, List *attnamelist, List *options)
Definition copyto.c:769
void EndCopyTo(CopyToState cstate)
Definition copyto.c:1220
struct cursor * cur
Definition ecpg.c:29
int errhint(const char *fmt,...) pg_attribute_printf(1
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
Definition execMain.c:593
#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 AccessShareLock
Definition lockdefs.h:36
#define RowExclusiveLock
Definition lockdefs.h:38
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:946
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3588
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition makefuncs.c:473
List * make_ands_implicit(Expr *clause)
Definition makefuncs.c:810
char * pstrdup(const char *in)
Definition mcxt.c:1781
Oid GetUserId(void)
Definition miscinit.c:470
#define makeNode(_type_)
Definition nodes.h:161
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition parse_expr.c:121
@ EXPR_KIND_COPY_WHERE
Definition parse_node.h:83
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 lfirst_int(lc)
Definition pg_list.h:173
#define list_make1(x1)
Definition pg_list.h:244
#define InvalidOid
unsigned int Oid
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition prepqual.c:293
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationGetDescr(relation)
Definition rel.h:542
#define RelationGetNumberOfAttributes(relation)
Definition rel.h:522
#define RelationGetNamespace(relation)
Definition rel.h:557
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition rls.c:52
@ RLS_ENABLED
Definition rls.h:45
List * p_rtable
Definition parse_node.h:215
bool inh
Definition primnodes.h:87
ParseLoc stmt_location
ParseLoc stmt_len
Node * stmt
bool rd_islocaltemp
Definition rel.h:61
Form_pg_class rd_rel
Definition rel.h:111
Node * val
Definition parsenodes.h:550
ParseLoc location
Definition parsenodes.h:551
List * indirection
Definition parsenodes.h:549
char * name
Definition parsenodes.h:548
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition table.c:83
void PreventCommandIfReadOnly(const char *cmdname)
Definition utility.c:409
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
Definition var.c:296
#define select(n, r, w, e, timeout)
Definition win32_port.h:500
bool XactReadOnly
Definition xact.c:84

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

Referenced by standard_ProcessUtility().

◆ ProcessCopyOptions()

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

Definition at line 581 of file copy.c.

585{
586 bool format_specified = false;
587 bool freeze_specified = false;
588 bool header_specified = false;
589 bool on_error_specified = false;
590 bool log_verbosity_specified = false;
591 bool reject_limit_specified = false;
592 bool force_array_specified = false;
594
595 /* Support external use for option sanity checking */
596 if (opts_out == NULL)
598
599 opts_out->file_encoding = -1;
600 /* default format */
601 opts_out->format = COPY_FORMAT_TEXT;
602
603 /* Extract options from the statement node tree */
604 foreach(option, options)
605 {
607
608 if (strcmp(defel->defname, "format") == 0)
609 {
610 char *fmt = defGetString(defel);
611
614 format_specified = true;
615 if (strcmp(fmt, "text") == 0)
616 opts_out->format = COPY_FORMAT_TEXT;
617 else if (strcmp(fmt, "csv") == 0)
618 opts_out->format = COPY_FORMAT_CSV;
619 else if (strcmp(fmt, "binary") == 0)
621 else if (strcmp(fmt, "json") == 0)
622 opts_out->format = COPY_FORMAT_JSON;
623 else
626 errmsg("COPY format \"%s\" not recognized", fmt),
627 parser_errposition(pstate, defel->location)));
628 }
629 else if (strcmp(defel->defname, "freeze") == 0)
630 {
633 freeze_specified = true;
634 opts_out->freeze = defGetBoolean(defel);
635 }
636 else if (strcmp(defel->defname, "delimiter") == 0)
637 {
638 if (opts_out->delim)
640 opts_out->delim = defGetString(defel);
641 }
642 else if (strcmp(defel->defname, "null") == 0)
643 {
644 if (opts_out->null_print)
646 opts_out->null_print = defGetString(defel);
647 }
648 else if (strcmp(defel->defname, "default") == 0)
649 {
650 if (opts_out->default_print)
652 opts_out->default_print = defGetString(defel);
653 }
654 else if (strcmp(defel->defname, "header") == 0)
655 {
658 header_specified = true;
659 opts_out->header_line = defGetCopyHeaderOption(defel, is_from);
660 }
661 else if (strcmp(defel->defname, "quote") == 0)
662 {
663 if (opts_out->quote)
665 opts_out->quote = defGetString(defel);
666 }
667 else if (strcmp(defel->defname, "escape") == 0)
668 {
669 if (opts_out->escape)
671 opts_out->escape = defGetString(defel);
672 }
673 else if (strcmp(defel->defname, "force_quote") == 0)
674 {
675 if (opts_out->force_quote || opts_out->force_quote_all)
677 if (defel->arg && IsA(defel->arg, A_Star))
678 opts_out->force_quote_all = true;
679 else if (defel->arg && IsA(defel->arg, List))
680 opts_out->force_quote = castNode(List, defel->arg);
681 else
684 errmsg("argument to option \"%s\" must be a list of column names",
685 defel->defname),
686 parser_errposition(pstate, defel->location)));
687 }
688 else if (strcmp(defel->defname, "force_not_null") == 0)
689 {
690 if (opts_out->force_notnull || opts_out->force_notnull_all)
692 if (defel->arg && IsA(defel->arg, A_Star))
693 opts_out->force_notnull_all = true;
694 else if (defel->arg && IsA(defel->arg, List))
695 opts_out->force_notnull = castNode(List, defel->arg);
696 else
699 errmsg("argument to option \"%s\" must be a list of column names",
700 defel->defname),
701 parser_errposition(pstate, defel->location)));
702 }
703 else if (strcmp(defel->defname, "force_null") == 0)
704 {
705 if (opts_out->force_null || opts_out->force_null_all)
707 if (defel->arg && IsA(defel->arg, A_Star))
708 opts_out->force_null_all = true;
709 else if (defel->arg && IsA(defel->arg, List))
710 opts_out->force_null = castNode(List, defel->arg);
711 else
714 errmsg("argument to option \"%s\" must be a list of column names",
715 defel->defname),
716 parser_errposition(pstate, defel->location)));
717 }
718 else if (strcmp(defel->defname, "convert_selectively") == 0)
719 {
720 /*
721 * Undocumented, not-accessible-from-SQL option: convert only the
722 * named columns to binary form, storing the rest as NULLs. It's
723 * allowed for the column list to be NIL.
724 */
725 if (opts_out->convert_selectively)
727 opts_out->convert_selectively = true;
728 if (defel->arg == NULL || IsA(defel->arg, List))
729 opts_out->convert_select = castNode(List, defel->arg);
730 else
733 errmsg("argument to option \"%s\" must be a list of column names",
734 defel->defname),
735 parser_errposition(pstate, defel->location)));
736 }
737 else if (strcmp(defel->defname, "encoding") == 0)
738 {
739 if (opts_out->file_encoding >= 0)
742 if (opts_out->file_encoding < 0)
745 errmsg("argument to option \"%s\" must be a valid encoding name",
746 defel->defname),
747 parser_errposition(pstate, defel->location)));
748 }
749 else if (strcmp(defel->defname, "force_array") == 0)
750 {
754 opts_out->force_array = defGetBoolean(defel);
755 }
756 else if (strcmp(defel->defname, "on_error") == 0)
757 {
760 on_error_specified = true;
761 opts_out->on_error = defGetCopyOnErrorChoice(defel, pstate, is_from);
762 }
763 else if (strcmp(defel->defname, "log_verbosity") == 0)
764 {
768 opts_out->log_verbosity = defGetCopyLogVerbosityChoice(defel, pstate);
769 }
770 else if (strcmp(defel->defname, "reject_limit") == 0)
771 {
776 }
777 else
780 errmsg("option \"%s\" not recognized",
781 defel->defname),
782 parser_errposition(pstate, defel->location)));
783 }
784
785 /*
786 * Check for incompatible options (must do these three before inserting
787 * defaults)
788 */
789 if (opts_out->delim &&
790 (opts_out->format == COPY_FORMAT_BINARY ||
791 opts_out->format == COPY_FORMAT_JSON))
795 ? errmsg("cannot specify %s in BINARY mode", "DELIMITER")
796 : errmsg("cannot specify %s in JSON mode", "DELIMITER"));
797
798 if (opts_out->null_print &&
799 (opts_out->format == COPY_FORMAT_BINARY ||
800 opts_out->format == COPY_FORMAT_JSON))
804 ? errmsg("cannot specify %s in BINARY mode", "NULL")
805 : errmsg("cannot specify %s in JSON mode", "NULL"));
806
807 if (opts_out->default_print &&
808 (opts_out->format == COPY_FORMAT_BINARY ||
809 opts_out->format == COPY_FORMAT_JSON))
813 ? errmsg("cannot specify %s in BINARY mode", "DEFAULT")
814 : errmsg("cannot specify %s in JSON mode", "DEFAULT"));
815
816 /* Set defaults for omitted options */
817 if (!opts_out->delim)
818 opts_out->delim = (opts_out->format == COPY_FORMAT_CSV) ? "," : "\t";
819
820 if (!opts_out->null_print)
821 opts_out->null_print = (opts_out->format == COPY_FORMAT_CSV) ? "" : "\\N";
822 opts_out->null_print_len = strlen(opts_out->null_print);
823
824 if (opts_out->format == COPY_FORMAT_CSV)
825 {
826 if (!opts_out->quote)
827 opts_out->quote = "\"";
828 if (!opts_out->escape)
829 opts_out->escape = opts_out->quote;
830 }
831
832 /* Only single-byte delimiter strings are supported. */
833 if (strlen(opts_out->delim) != 1)
836 errmsg("COPY delimiter must be a single one-byte character")));
837
838 /* Disallow end-of-line characters */
839 if (strchr(opts_out->delim, '\r') != NULL ||
840 strchr(opts_out->delim, '\n') != NULL)
843 errmsg("COPY delimiter cannot be newline or carriage return")));
844
845 if (strchr(opts_out->null_print, '\r') != NULL ||
846 strchr(opts_out->null_print, '\n') != NULL)
849 errmsg("COPY null representation cannot use newline or carriage return")));
850
851 if (opts_out->default_print)
852 {
853 opts_out->default_print_len = strlen(opts_out->default_print);
854
855 if (strchr(opts_out->default_print, '\r') != NULL ||
856 strchr(opts_out->default_print, '\n') != NULL)
859 errmsg("COPY default representation cannot use newline or carriage return")));
860 }
861
862 /*
863 * Disallow unsafe delimiter characters in non-CSV mode. We can't allow
864 * backslash because it would be ambiguous. We can't allow the other
865 * cases because data characters matching the delimiter must be
866 * backslashed, and certain backslash combinations are interpreted
867 * non-literally by COPY IN. Disallowing all lower case ASCII letters is
868 * more than strictly necessary, but seems best for consistency and
869 * future-proofing. Likewise we disallow all digits though only octal
870 * digits are actually dangerous.
871 */
872 if (opts_out->format != COPY_FORMAT_CSV &&
873 strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
874 opts_out->delim[0]) != NULL)
877 errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));
878
879 /* Check header */
880 if (opts_out->header_line != COPY_HEADER_FALSE &&
881 (opts_out->format == COPY_FORMAT_BINARY ||
882 opts_out->format == COPY_FORMAT_JSON))
885 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
887 ? errmsg("cannot specify %s in BINARY mode", "HEADER")
888 : errmsg("cannot specify %s in JSON mode", "HEADER"));
889
890 /* Check quote */
891 if (opts_out->format != COPY_FORMAT_CSV && opts_out->quote != NULL)
894 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
895 errmsg("COPY %s requires CSV mode", "QUOTE")));
896
897 if (opts_out->format == COPY_FORMAT_CSV && strlen(opts_out->quote) != 1)
900 errmsg("COPY quote must be a single one-byte character")));
901
902 if (opts_out->format == COPY_FORMAT_CSV && opts_out->delim[0] == opts_out->quote[0])
905 errmsg("COPY delimiter and quote must be different")));
906
907 /* Check escape */
908 if (opts_out->format != COPY_FORMAT_CSV && opts_out->escape != NULL)
911 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
912 errmsg("COPY %s requires CSV mode", "ESCAPE")));
913
914 if (opts_out->format == COPY_FORMAT_CSV && strlen(opts_out->escape) != 1)
917 errmsg("COPY escape must be a single one-byte character")));
918
919 /* Check force_quote */
920 if (opts_out->format != COPY_FORMAT_CSV && (opts_out->force_quote || opts_out->force_quote_all))
923 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
924 errmsg("COPY %s requires CSV mode", "FORCE_QUOTE")));
925 if ((opts_out->force_quote || opts_out->force_quote_all) && is_from)
928 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
929 second %s is a COPY with direction, e.g. COPY TO */
930 errmsg("COPY %s cannot be used with %s", "FORCE_QUOTE",
931 "COPY FROM")));
932
933 /* Check force_notnull */
934 if (opts_out->format != COPY_FORMAT_CSV && (opts_out->force_notnull != NIL ||
935 opts_out->force_notnull_all))
938 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
939 errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
940 if ((opts_out->force_notnull != NIL || opts_out->force_notnull_all) &&
941 !is_from)
944 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
945 second %s is a COPY with direction, e.g. COPY TO */
946 errmsg("COPY %s cannot be used with %s", "FORCE_NOT_NULL",
947 "COPY TO")));
948
949 /* Check force_null */
950 if (opts_out->format != COPY_FORMAT_CSV && (opts_out->force_null != NIL ||
951 opts_out->force_null_all))
954 /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
955 errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
956
957 if ((opts_out->force_null != NIL || opts_out->force_null_all) &&
958 !is_from)
961 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
962 second %s is a COPY with direction, e.g. COPY TO */
963 errmsg("COPY %s cannot be used with %s", "FORCE_NULL",
964 "COPY TO")));
965
966 /* Don't allow the delimiter to appear in the null string. */
967 if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL)
970 /*- translator: %s is the name of a COPY option, e.g. NULL */
971 errmsg("COPY delimiter character must not appear in the %s specification",
972 "NULL")));
973
974 /* Don't allow the CSV quote char to appear in the null string. */
975 if (opts_out->format == COPY_FORMAT_CSV &&
976 strchr(opts_out->null_print, opts_out->quote[0]) != NULL)
979 /*- translator: %s is the name of a COPY option, e.g. NULL */
980 errmsg("CSV quote character must not appear in the %s specification",
981 "NULL")));
982
983 /* Check freeze */
984 if (opts_out->freeze && !is_from)
987 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
988 second %s is a COPY with direction, e.g. COPY TO */
989 errmsg("COPY %s cannot be used with %s", "FREEZE",
990 "COPY TO")));
991
992 /* Check json format */
993 if (opts_out->format == COPY_FORMAT_JSON && is_from)
996 errmsg("COPY %s is not supported for %s", "FORMAT JSON", "COPY FROM"));
997
998 if (opts_out->format != COPY_FORMAT_JSON && opts_out->force_array)
1001 errmsg("COPY %s can only be used with JSON mode", "FORCE_ARRAY"));
1002
1003 if (opts_out->default_print)
1004 {
1005 if (!is_from)
1006 ereport(ERROR,
1008 /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
1009 second %s is a COPY with direction, e.g. COPY TO */
1010 errmsg("COPY %s cannot be used with %s", "DEFAULT",
1011 "COPY TO")));
1012
1013 /* Don't allow the delimiter to appear in the default string. */
1014 if (strchr(opts_out->default_print, opts_out->delim[0]) != NULL)
1015 ereport(ERROR,
1017 /*- translator: %s is the name of a COPY option, e.g. NULL */
1018 errmsg("COPY delimiter character must not appear in the %s specification",
1019 "DEFAULT")));
1020
1021 /* Don't allow the CSV quote char to appear in the default string. */
1022 if (opts_out->format == COPY_FORMAT_CSV &&
1023 strchr(opts_out->default_print, opts_out->quote[0]) != NULL)
1024 ereport(ERROR,
1026 /*- translator: %s is the name of a COPY option, e.g. NULL */
1027 errmsg("CSV quote character must not appear in the %s specification",
1028 "DEFAULT")));
1029
1030 /* Don't allow the NULL and DEFAULT string to be the same */
1031 if (opts_out->null_print_len == opts_out->default_print_len &&
1032 strncmp(opts_out->null_print, opts_out->default_print,
1033 opts_out->null_print_len) == 0)
1034 ereport(ERROR,
1036 errmsg("NULL specification and DEFAULT specification cannot be the same")));
1037 }
1038 /* Check on_error */
1039 if (opts_out->format == COPY_FORMAT_BINARY && opts_out->on_error != COPY_ON_ERROR_STOP)
1040 ereport(ERROR,
1042 errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
1043
1044 if (opts_out->reject_limit && opts_out->on_error != COPY_ON_ERROR_IGNORE)
1045 ereport(ERROR,
1047 /*- translator: first and second %s are the names of COPY option, e.g.
1048 * ON_ERROR, third is the value of the COPY option, e.g. IGNORE */
1049 errmsg("COPY %s requires %s to be set to %s",
1050 "REJECT_LIMIT", "ON_ERROR", "IGNORE")));
1051}
static int defGetCopyHeaderOption(DefElem *def, bool is_from)
Definition copy.c:396
static int64 defGetCopyRejectLimitOption(DefElem *def)
Definition copy.c:514
static CopyOnErrorChoice defGetCopyOnErrorChoice(DefElem *def, ParseState *pstate, bool is_from)
Definition copy.c:479
static CopyLogVerbosityChoice defGetCopyLogVerbosityChoice(DefElem *def, ParseState *pstate)
Definition copy.c:541
bool defGetBoolean(DefElem *def)
Definition define.c:93
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
#define palloc0_object(type)
Definition fe_memutils.h:75
@ COPY_FORMAT_CSV
Definition copy.h:59
@ COPY_FORMAT_JSON
Definition copy.h:60
@ COPY_FORMAT_BINARY
Definition copy.h:58
@ COPY_FORMAT_TEXT
Definition copy.h:57
#define castNode(_type_, nodeptr)
Definition nodes.h:182
#define lfirst_node(type, lc)
Definition pg_list.h:176
#define pg_char_to_encoding
Definition pg_wchar.h:482

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

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