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 (stmt->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)