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 {
137 int i;
138
139
141
142
144
145
147
148
150
151
152
153
154
155
158 {
163 }
164
165 i = -1;
167 {
169
171
172
173
174
175
176
177
178
181 errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
182 errmsg("generated columns are not supported in COPY FROM WHERE conditions"),
183 errdetail("Column \"%s\" is a generated column.",
185 }
186
188
191 }
192
195 foreach(cur, attnums)
196 {
197 int attno;
199
202
204 }
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
222 {
228
229 if (is_from)
231 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
232 errmsg("COPY FROM not supported with row-level security"),
233 errhint("Use INSERT statements instead.")));
234
235
236
237
238
239
240
241
242
243
244
245
246
247 if (->attlist)
248 {
252
254 target->name = NULL;
256 target->val = (Node *) cr;
258
260 }
261 else
262 {
264
265 foreach(lc, stmt->attlist)
266 {
267
268
269
270
271
275
276
278 target->name = NULL;
280 target->val = (Node *) cr;
282
283
284 targetList = lappend(targetList, target);
285 }
286 }
287
288
289
290
291
292
293
294
295
296
297
300 -1);
301 from->inh = (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
302
303
305 select->targetList = targetList;
307
312
313
314
315
316
317
318
320 rel = NULL;
321 }
322 }
323 else
324 {
326
331
333 rel = NULL;
334 }
335
336 if (is_from)
337 {
339
341
342
345
347 stmt->filename, stmt->is_program,
348 NULL, stmt->attlist, stmt->options);
349 *processed = CopyFrom(cstate);
351 }
352 else
353 {
355
356 cstate = BeginCopyTo(pstate, rel, query, relid,
357 stmt->filename, stmt->is_program,
358 NULL, stmt->attlist, stmt->options);
359 *processed = DoCopyTo(cstate);
361 }
362
363 if (rel != NULL)
365}
366
367
368
369
370
371
372
373static int
375{
376
377
378
379 if (def->arg == NULL)
381
382
383
384
385
387 {
388 case T_Integer:
389 {
391
392 if (ival < 0)
394 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
395 errmsg("a negative integer value cannot be "
396 "specified for %s", def->defname)));
397
398 if (!is_from && ival > 1)
400 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
401 errmsg("cannot use multi-line header in COPY TO")));
402
403 return ival;
404 }
405 break;
406 default:
407 {
409
410
411
412
413
423 {
424 if (!is_from)
426 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
427 errmsg("cannot use \"%s\" with HEADER in COPY TO",
428 sval)));
430 }
431 }
432 break;
433 }
435 (errcode(ERRCODE_SYNTAX_ERROR),
436 errmsg("%s requires a Boolean value, a non-negative integer, "
437 "or the string \"match\"",
440}
441
442
443
444
447{
449
450 if (!is_from)
452 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
453
454
455 errmsg("COPY %s cannot be used with %s", "ON_ERROR", "COPY TO"),
457
458
459
460
465
467 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
468
469 errmsg("COPY %s \"%s\" not recognized", "ON_ERROR", sval),
472}
473
474
475
476
477
478
479
480
483{
484 int64 reject_limit;
485
486 if (def->arg == NULL)
488 (errcode(ERRCODE_SYNTAX_ERROR),
489 errmsg("%s requires a numeric value",
491 else if (nodeTag(def->arg) == T_String)
493 else
495
496 if (reject_limit <= 0)
498 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
499 errmsg("REJECT_LIMIT (%" PRId64 ") must be greater than zero",
500 reject_limit)));
501
502 return reject_limit;
503}
504
505
506
507
510{
511 char *sval;
512
513
514
515
523
525 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
526
527 errmsg("COPY %s \"%s\" not recognized", "LOG_VERBOSITY", sval),
530}
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548void
551 bool is_from,
553{
554 bool format_specified = false;
555 bool freeze_specified = false;
556 bool header_specified = false;
557 bool on_error_specified = false;
558 bool log_verbosity_specified = false;
559 bool reject_limit_specified = false;
561
562
563 if (opts_out == NULL)
565
567
568
570 {
572
573 if (strcmp(defel->defname, "format") == 0)
574 {
576
577 if (format_specified)
579 format_specified = true;
580 if (strcmp(fmt, "text") == 0)
581 ;
582 else if (strcmp(fmt, "csv") == 0)
584 else if (strcmp(fmt, "binary") == 0)
585 opts_out->binary = true;
586 else
588 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
589 errmsg("COPY format \"%s\" not recognized", fmt),
591 }
592 else if (strcmp(defel->defname, "freeze") == 0)
593 {
594 if (freeze_specified)
596 freeze_specified = true;
598 }
599 else if (strcmp(defel->defname, "delimiter") == 0)
600 {
601 if (opts_out->delim)
604 }
605 else if (strcmp(defel->defname, "null") == 0)
606 {
610 }
611 else if (strcmp(defel->defname, "default") == 0)
612 {
616 }
617 else if (strcmp(defel->defname, "header") == 0)
618 {
619 if (header_specified)
621 header_specified = true;
623 }
624 else if (strcmp(defel->defname, "quote") == 0)
625 {
626 if (opts_out->quote)
629 }
630 else if (strcmp(defel->defname, "escape") == 0)
631 {
632 if (opts_out->escape)
635 }
636 else if (strcmp(defel->defname, "force_quote") == 0)
637 {
644 else
646 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
647 errmsg("argument to option \"%s\" must be a list of column names",
650 }
651 else if (strcmp(defel->defname, "force_not_null") == 0)
652 {
659 else
661 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
662 errmsg("argument to option \"%s\" must be a list of column names",
665 }
666 else if (strcmp(defel->defname, "force_null") == 0)
667 {
674 else
676 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
677 errmsg("argument to option \"%s\" must be a list of column names",
680 }
681 else if (strcmp(defel->defname, "convert_selectively") == 0)
682 {
683
684
685
686
687
693 else
695 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
696 errmsg("argument to option \"%s\" must be a list of column names",
699 }
700 else if (strcmp(defel->defname, "encoding") == 0)
701 {
707 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
708 errmsg("argument to option \"%s\" must be a valid encoding name",
711 }
712 else if (strcmp(defel->defname, "on_error") == 0)
713 {
714 if (on_error_specified)
716 on_error_specified = true;
718 }
719 else if (strcmp(defel->defname, "log_verbosity") == 0)
720 {
721 if (log_verbosity_specified)
723 log_verbosity_specified = true;
725 }
726 else if (strcmp(defel->defname, "reject_limit") == 0)
727 {
728 if (reject_limit_specified)
730 reject_limit_specified = true;
732 }
733 else
735 (errcode(ERRCODE_SYNTAX_ERROR),
736 errmsg("option \"%s\" not recognized",
739 }
740
741
742
743
744
747 (errcode(ERRCODE_SYNTAX_ERROR),
748
749 errmsg("cannot specify %s in BINARY mode", "DELIMITER")));
750
753 (errcode(ERRCODE_SYNTAX_ERROR),
754 errmsg("cannot specify %s in BINARY mode", "NULL")));
755
758 (errcode(ERRCODE_SYNTAX_ERROR),
759 errmsg("cannot specify %s in BINARY mode", "DEFAULT")));
760
761
762 if (!opts_out->delim)
763 opts_out->delim = opts_out->csv_mode ? "," : "\t";
764
768
770 {
771 if (!opts_out->quote)
772 opts_out->quote = "\"";
773 if (!opts_out->escape)
775 }
776
777
778 if (strlen(opts_out->delim) != 1)
780 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
781 errmsg("COPY delimiter must be a single one-byte character")));
782
783
784 if (strchr(opts_out->delim, '\r') != NULL ||
785 strchr(opts_out->delim, '\n') != NULL)
787 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
788 errmsg("COPY delimiter cannot be newline or carriage return")));
789
790 if (strchr(opts_out->null_print, '\r') != NULL ||
791 strchr(opts_out->null_print, '\n') != NULL)
793 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
794 errmsg("COPY null representation cannot use newline or carriage return")));
795
797 {
799
800 if (strchr(opts_out->default_print, '\r') != NULL ||
803 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
804 errmsg("COPY default representation cannot use newline or carriage return")));
805 }
806
807
808
809
810
811
812
813
814
815
816
818 strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
819 opts_out->delim[0]) != NULL)
821 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
822 errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));
823
824
827 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
828
829 errmsg("cannot specify %s in BINARY mode", "HEADER")));
830
831
832 if (!opts_out->csv_mode && opts_out->quote != NULL)
834 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
835
836 errmsg("COPY %s requires CSV mode", "QUOTE")));
837
838 if (opts_out->csv_mode && strlen(opts_out->quote) != 1)
840 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
841 errmsg("COPY quote must be a single one-byte character")));
842
845 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
846 errmsg("COPY delimiter and quote must be different")));
847
848
851 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
852
853 errmsg("COPY %s requires CSV mode", "ESCAPE")));
854
855 if (opts_out->csv_mode && strlen(opts_out->escape) != 1)
857 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
858 errmsg("COPY escape must be a single one-byte character")));
859
860
863 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
864
865 errmsg("COPY %s requires CSV mode", "FORCE_QUOTE")));
868 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
869
870
871 errmsg("COPY %s cannot be used with %s", "FORCE_QUOTE",
872 "COPY FROM")));
873
874
878 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
879
880 errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
882 !is_from)
884 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
885
886
887 errmsg("COPY %s cannot be used with %s", "FORCE_NOT_NULL",
888 "COPY TO")));
889
890
894 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
895
896 errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
897
899 !is_from)
901 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
902
903
904 errmsg("COPY %s cannot be used with %s", "FORCE_NULL",
905 "COPY TO")));
906
907
908 if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL)
910 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
911
912 errmsg("COPY delimiter character must not appear in the %s specification",
913 "NULL")));
914
915
917 strchr(opts_out->null_print, opts_out->quote[0]) != NULL)
919 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
920
921 errmsg("CSV quote character must not appear in the %s specification",
922 "NULL")));
923
924
925 if (opts_out->freeze && !is_from)
927 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
928
929
930 errmsg("COPY %s cannot be used with %s", "FREEZE",
931 "COPY TO")));
932
934 {
935 if (!is_from)
937 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
938
939
940 errmsg("COPY %s cannot be used with %s", "DEFAULT",
941 "COPY TO")));
942
943
946 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
947
948 errmsg("COPY delimiter character must not appear in the %s specification",
949 "DEFAULT")));
950
951
955 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
956
957 errmsg("CSV quote character must not appear in the %s specification",
958 "DEFAULT")));
959
960
965 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
966 errmsg("NULL specification and DEFAULT specification cannot be the same")));
967 }
968
971 (errcode(ERRCODE_SYNTAX_ERROR),
972 errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
973
976 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
977
978
979 errmsg("COPY %s requires %s to be set to %s",
980 "REJECT_LIMIT", "ON_ERROR", "IGNORE")));
981}
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
999{
1001
1002 if (attnamelist == NIL)
1003 {
1004
1005 int attr_count = tupDesc->natts;
1006 int i;
1007
1008 for (i = 0; i < attr_count; i++)
1009 {
1011
1013 continue;
1015 }
1016 }
1017 else
1018 {
1019
1021
1022 foreach(l, attnamelist)
1023 {
1026 int i;
1027
1028
1030 for (i = 0; i < tupDesc->natts; i++)
1031 {
1033
1034 if (att->attisdropped)
1035 continue;
1037 {
1038 if (att->attgenerated)
1040 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1041 errmsg("column \"%s\" is a generated column",
1043 errdetail("Generated columns cannot be used in COPY.")));
1044 attnum = att->attnum;
1045 break;
1046 }
1047 }
1049 {
1050 if (rel != NULL)
1052 (errcode(ERRCODE_UNDEFINED_COLUMN),
1053 errmsg("column \"%s\" of relation \"%s\" does not exist",
1055 else
1057 (errcode(ERRCODE_UNDEFINED_COLUMN),
1058 errmsg("column \"%s\" does not exist",
1060 }
1061
1064 (errcode(ERRCODE_DUPLICATE_COLUMN),
1065 errmsg("column \"%s\" specified more than once",
1068 }
1069 }
1070
1071 return attnums;
1072}
bool has_privs_of_role(Oid member, Oid role)
#define InvalidAttrNumber
void DoCopy(ParseState *pstate, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
static int defGetCopyHeaderOption(DefElem *def, bool is_from)
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)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Bitmapset * bms_del_member(Bitmapset *a, int x)
bool bms_is_member(int x, const Bitmapset *a)
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)
#define palloc0_object(type)
Assert(PointerIsAligned(start, uint64))
@ COPY_LOG_VERBOSITY_SILENT
@ COPY_LOG_VERBOSITY_VERBOSE
@ COPY_LOG_VERBOSITY_DEFAULT
#define COPY_HEADER_MATCH
#define COPY_HEADER_FALSE
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
bool list_member_int(const List *list, int datum)
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
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)
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 RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
#define RelationGetNamespace(relation)
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
CopyLogVerbosityChoice log_verbosity
CopyOnErrorChoice on_error
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)
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
#define select(n, r, w, e, timeout)