PostgreSQL Source Code: src/backend/commands/copy.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
17#include <ctype.h>
19#include <sys/stat.h>
20
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61void
63 int stmt_location, int stmt_len,
65{
66 bool is_from = stmt->is_from;
67 bool pipe = (stmt->filename == NULL);
69 Oid relid;
71 Node *whereClause = NULL;
72
73
74
75
76
77 if (!pipe)
78 {
79 if (stmt->is_program)
80 {
83 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
84 errmsg("permission denied to COPY to or from an external program"),
85 errdetail("Only roles with privileges of the \"%s\" role may COPY to or from an external program.",
86 "pg_execute_server_program"),
87 errhint("Anyone can COPY to stdout or from stdin. "
88 "psql's \\copy command also works for anyone.")));
89 }
90 else
91 {
94 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
95 errmsg("permission denied to COPY from a file"),
96 errdetail("Only roles with privileges of the \"%s\" role may COPY from a file.",
97 "pg_read_server_files"),
98 errhint("Anyone can COPY to stdout or from stdin. "
99 "psql's \\copy command also works for anyone.")));
100
103 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
104 errmsg("permission denied to COPY to a file"),
105 errdetail("Only roles with privileges of the \"%s\" role may COPY to a file.",
106 "pg_write_server_files"),
107 errhint("Anyone can COPY to stdout or from stdin. "
108 "psql's \\copy command also works for anyone.")));
109 }
110 }
111
112 if (stmt->relation)
113 {
118 List *attnums;
120
122
123
125
127
129 NULL, false, false);
130
133
134 if (stmt->whereClause)
135 {
136
138
139
141
142
144
145
147
149
152 }
153
156 foreach(cur, attnums)
157 {
158 int attno;
160
163
165 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
183 {
189
190 if (is_from)
192 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
193 errmsg("COPY FROM not supported with row-level security"),
194 errhint("Use INSERT statements instead.")));
195
196
197
198
199
200
201
202
203
204
205
206
207
208 if (->attlist)
209 {
213
215 target->name = NULL;
217 target->val = (Node *) cr;
219
221 }
222 else
223 {
225
226 foreach(lc, stmt->attlist)
227 {
228
229
230
231
232
236
237
239 target->name = NULL;
241 target->val = (Node *) cr;
243
244
245 targetList = lappend(targetList, target);
246 }
247 }
248
249
250
251
252
253
254
257 -1);
258 from->inh = false;
259
260
262 select->targetList = targetList;
264
269
270
271
272
273
274
275
277 rel = NULL;
278 }
279 }
280 else
281 {
283
288
290 rel = NULL;
291 }
292
293 if (is_from)
294 {
296
298
299
302
304 stmt->filename, stmt->is_program,
305 NULL, stmt->attlist, stmt->options);
306 *processed = CopyFrom(cstate);
308 }
309 else
310 {
312
313 cstate = BeginCopyTo(pstate, rel, query, relid,
314 stmt->filename, stmt->is_program,
315 NULL, stmt->attlist, stmt->options);
316 *processed = DoCopyTo(cstate);
318 }
319
320 if (rel != NULL)
322}
323
324
325
326
327
330{
331
332
333
334 if (def->arg == NULL)
336
337
338
339
341 {
342 case T_Integer:
344 {
345 case 0:
347 case 1:
349 default:
350
351 break;
352 }
353 break;
354 default:
355 {
357
358
359
360
361
371 {
372 if (!is_from)
374 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
375 errmsg("cannot use \"%s\" with HEADER in COPY TO",
376 sval)));
378 }
379 }
380 break;
381 }
383 (errcode(ERRCODE_SYNTAX_ERROR),
384 errmsg("%s requires a Boolean value or \"match\"",
387}
388
389
390
391
394{
396
397 if (!is_from)
399 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
400
401
402 errmsg("COPY %s cannot be used with %s", "ON_ERROR", "COPY TO"),
404
405
406
407
412
414 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
415
416 errmsg("COPY %s \"%s\" not recognized", "ON_ERROR", sval),
419}
420
421
422
423
424
425
426
427
430{
431 int64 reject_limit;
432
433 if (def->arg == NULL)
435 (errcode(ERRCODE_SYNTAX_ERROR),
436 errmsg("%s requires a numeric value",
438 else if (nodeTag(def->arg) == T_String)
440 else
442
443 if (reject_limit <= 0)
445 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
446 errmsg("REJECT_LIMIT (%" PRId64 ") must be greater than zero",
447 reject_limit)));
448
449 return reject_limit;
450}
451
452
453
454
457{
458 char *sval;
459
460
461
462
470
472 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
473
474 errmsg("COPY %s \"%s\" not recognized", "LOG_VERBOSITY", sval),
477}
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495void
498 bool is_from,
500{
501 bool format_specified = false;
502 bool freeze_specified = false;
503 bool header_specified = false;
504 bool on_error_specified = false;
505 bool log_verbosity_specified = false;
506 bool reject_limit_specified = false;
508
509
510 if (opts_out == NULL)
512
514
515
517 {
519
520 if (strcmp(defel->defname, "format") == 0)
521 {
523
524 if (format_specified)
526 format_specified = true;
527 if (strcmp(fmt, "text") == 0)
528 ;
529 else if (strcmp(fmt, "csv") == 0)
531 else if (strcmp(fmt, "binary") == 0)
532 opts_out->binary = true;
533 else
535 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
536 errmsg("COPY format \"%s\" not recognized", fmt),
538 }
539 else if (strcmp(defel->defname, "freeze") == 0)
540 {
541 if (freeze_specified)
543 freeze_specified = true;
545 }
546 else if (strcmp(defel->defname, "delimiter") == 0)
547 {
548 if (opts_out->delim)
551 }
552 else if (strcmp(defel->defname, "null") == 0)
553 {
557 }
558 else if (strcmp(defel->defname, "default") == 0)
559 {
563 }
564 else if (strcmp(defel->defname, "header") == 0)
565 {
566 if (header_specified)
568 header_specified = true;
570 }
571 else if (strcmp(defel->defname, "quote") == 0)
572 {
573 if (opts_out->quote)
576 }
577 else if (strcmp(defel->defname, "escape") == 0)
578 {
579 if (opts_out->escape)
582 }
583 else if (strcmp(defel->defname, "force_quote") == 0)
584 {
591 else
593 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
594 errmsg("argument to option \"%s\" must be a list of column names",
597 }
598 else if (strcmp(defel->defname, "force_not_null") == 0)
599 {
606 else
608 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
609 errmsg("argument to option \"%s\" must be a list of column names",
612 }
613 else if (strcmp(defel->defname, "force_null") == 0)
614 {
621 else
623 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
624 errmsg("argument to option \"%s\" must be a list of column names",
627 }
628 else if (strcmp(defel->defname, "convert_selectively") == 0)
629 {
630
631
632
633
634
640 else
642 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
643 errmsg("argument to option \"%s\" must be a list of column names",
646 }
647 else if (strcmp(defel->defname, "encoding") == 0)
648 {
654 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
655 errmsg("argument to option \"%s\" must be a valid encoding name",
658 }
659 else if (strcmp(defel->defname, "on_error") == 0)
660 {
661 if (on_error_specified)
663 on_error_specified = true;
665 }
666 else if (strcmp(defel->defname, "log_verbosity") == 0)
667 {
668 if (log_verbosity_specified)
670 log_verbosity_specified = true;
672 }
673 else if (strcmp(defel->defname, "reject_limit") == 0)
674 {
675 if (reject_limit_specified)
677 reject_limit_specified = true;
679 }
680 else
682 (errcode(ERRCODE_SYNTAX_ERROR),
683 errmsg("option \"%s\" not recognized",
686 }
687
688
689
690
691
694 (errcode(ERRCODE_SYNTAX_ERROR),
695
696 errmsg("cannot specify %s in BINARY mode", "DELIMITER")));
697
700 (errcode(ERRCODE_SYNTAX_ERROR),
701 errmsg("cannot specify %s in BINARY mode", "NULL")));
702
705 (errcode(ERRCODE_SYNTAX_ERROR),
706 errmsg("cannot specify %s in BINARY mode", "DEFAULT")));
707
708
709 if (!opts_out->delim)
710 opts_out->delim = opts_out->csv_mode ? "," : "\t";
711
715
717 {
718 if (!opts_out->quote)
719 opts_out->quote = "\"";
720 if (!opts_out->escape)
722 }
723
724
725 if (strlen(opts_out->delim) != 1)
727 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
728 errmsg("COPY delimiter must be a single one-byte character")));
729
730
731 if (strchr(opts_out->delim, '\r') != NULL ||
732 strchr(opts_out->delim, '\n') != NULL)
734 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
735 errmsg("COPY delimiter cannot be newline or carriage return")));
736
737 if (strchr(opts_out->null_print, '\r') != NULL ||
738 strchr(opts_out->null_print, '\n') != NULL)
740 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
741 errmsg("COPY null representation cannot use newline or carriage return")));
742
744 {
746
747 if (strchr(opts_out->default_print, '\r') != NULL ||
750 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
751 errmsg("COPY default representation cannot use newline or carriage return")));
752 }
753
754
755
756
757
758
759
760
761
762
763
765 strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
766 opts_out->delim[0]) != NULL)
768 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
769 errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));
770
771
774 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
775
776 errmsg("cannot specify %s in BINARY mode", "HEADER")));
777
778
779 if (!opts_out->csv_mode && opts_out->quote != NULL)
781 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
782
783 errmsg("COPY %s requires CSV mode", "QUOTE")));
784
785 if (opts_out->csv_mode && strlen(opts_out->quote) != 1)
787 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
788 errmsg("COPY quote must be a single one-byte character")));
789
792 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
793 errmsg("COPY delimiter and quote must be different")));
794
795
798 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
799
800 errmsg("COPY %s requires CSV mode", "ESCAPE")));
801
802 if (opts_out->csv_mode && strlen(opts_out->escape) != 1)
804 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
805 errmsg("COPY escape must be a single one-byte character")));
806
807
810 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
811
812 errmsg("COPY %s requires CSV mode", "FORCE_QUOTE")));
815 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
816
817
818 errmsg("COPY %s cannot be used with %s", "FORCE_QUOTE",
819 "COPY FROM")));
820
821
825 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
826
827 errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
829 !is_from)
831 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
832
833
834 errmsg("COPY %s cannot be used with %s", "FORCE_NOT_NULL",
835 "COPY TO")));
836
837
841 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
842
843 errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
844
846 !is_from)
848 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
849
850
851 errmsg("COPY %s cannot be used with %s", "FORCE_NULL",
852 "COPY TO")));
853
854
855 if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL)
857 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
858
859 errmsg("COPY delimiter character must not appear in the %s specification",
860 "NULL")));
861
862
864 strchr(opts_out->null_print, opts_out->quote[0]) != NULL)
866 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
867
868 errmsg("CSV quote character must not appear in the %s specification",
869 "NULL")));
870
871
872 if (opts_out->freeze && !is_from)
874 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
875
876
877 errmsg("COPY %s cannot be used with %s", "FREEZE",
878 "COPY TO")));
879
881 {
882 if (!is_from)
884 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
885
886
887 errmsg("COPY %s cannot be used with %s", "DEFAULT",
888 "COPY TO")));
889
890
893 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
894
895 errmsg("COPY delimiter character must not appear in the %s specification",
896 "DEFAULT")));
897
898
902 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
903
904 errmsg("CSV quote character must not appear in the %s specification",
905 "DEFAULT")));
906
907
912 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
913 errmsg("NULL specification and DEFAULT specification cannot be the same")));
914 }
915
918 (errcode(ERRCODE_SYNTAX_ERROR),
919 errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
920
923 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
924
925
926 errmsg("COPY %s requires %s to be set to %s",
927 "REJECT_LIMIT", "ON_ERROR", "IGNORE")));
928}
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
946{
948
949 if (attnamelist == NIL)
950 {
951
952 int attr_count = tupDesc->natts;
953 int i;
954
955 for (i = 0; i < attr_count; i++)
956 {
958
960 continue;
962 }
963 }
964 else
965 {
966
968
969 foreach(l, attnamelist)
970 {
973 int i;
974
975
977 for (i = 0; i < tupDesc->natts; i++)
978 {
980
981 if (att->attisdropped)
982 continue;
984 {
985 if (att->attgenerated)
987 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
988 errmsg("column \"%s\" is a generated column",
990 errdetail("Generated columns cannot be used in COPY.")));
991 attnum = att->attnum;
992 break;
993 }
994 }
996 {
997 if (rel != NULL)
999 (errcode(ERRCODE_UNDEFINED_COLUMN),
1000 errmsg("column \"%s\" of relation \"%s\" does not exist",
1002 else
1004 (errcode(ERRCODE_UNDEFINED_COLUMN),
1005 errmsg("column \"%s\" does not exist",
1007 }
1008
1011 (errcode(ERRCODE_DUPLICATE_COLUMN),
1012 errmsg("column \"%s\" specified more than once",
1015 }
1016 }
1017
1018 return attnums;
1019}
bool has_privs_of_role(Oid member, Oid role)
#define InvalidAttrNumber
static CopyHeaderChoice defGetCopyHeaderChoice(DefElem *def, bool is_from)
void DoCopy(ParseState *pstate, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
static int64 defGetCopyRejectLimitOption(DefElem *def)
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
static CopyOnErrorChoice defGetCopyOnErrorChoice(DefElem *def, ParseState *pstate, bool is_from)
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
static CopyLogVerbosityChoice defGetCopyLogVerbosityChoice(DefElem *def, ParseState *pstate)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Node * eval_const_expressions(PlannerInfo *root, Node *node)
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)
uint64 CopyFrom(CopyFromState cstate)
void EndCopyFrom(CopyFromState cstate)
uint64 DoCopyTo(CopyToState cstate)
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)
char * defGetString(DefElem *def)
bool defGetBoolean(DefElem *def)
int64 defGetInt64(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
Assert(PointerIsAligned(start, uint64))
@ COPY_LOG_VERBOSITY_SILENT
@ COPY_LOG_VERBOSITY_VERBOSE
@ COPY_LOG_VERBOSITY_DEFAULT
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
bool list_member_int(const List *list, int datum)
char * get_namespace_name(Oid nspid)
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
List * make_ands_implicit(Expr *clause)
char * pstrdup(const char *in)
void * palloc0(Size size)
int namestrcmp(Name name, const char *str)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
int64 pg_strtoint64(const char *s)
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)
int parser_errposition(ParseState *pstate, int location)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
FormData_pg_attribute * Form_pg_attribute
#define lfirst_node(type, lc)
#define pg_char_to_encoding
int pg_strcasecmp(const char *s1, const char *s2)
Expr * canonicalize_qual(Expr *qual, bool is_check)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationGetNamespace(relation)
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
CopyLogVerbosityChoice log_verbosity
CopyOnErrorChoice on_error
CopyHeaderChoice header_line
RTEPermissionInfo * p_perminfo
#define FirstLowInvalidHeapAttributeNumber
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
void PreventCommandIfReadOnly(const char *cmdname)
#define select(n, r, w, e, timeout)