copy.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:30k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * copy.c
  4.  *
  5.  * Copyright (c) 1994, Regents of the University of California
  6.  *
  7.  *
  8.  * IDENTIFICATION
  9.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/commands/copy.c,v 1.81 1999/07/03 00:32:39 momjian Exp $
  10.  *
  11.  *-------------------------------------------------------------------------
  12.  */
  13. #include <string.h>
  14. #include <unistd.h>
  15. #include <postgres.h>
  16. #include <access/heapam.h>
  17. #include <tcop/dest.h>
  18. #include <fmgr.h>
  19. #include <miscadmin.h>
  20. #include <utils/builtins.h>
  21. #include <utils/acl.h>
  22. #include <sys/stat.h>
  23. #include <catalog/pg_index.h>
  24. #include <utils/syscache.h>
  25. #include <utils/memutils.h>
  26. #include <executor/executor.h>
  27. #include <access/transam.h>
  28. #include <catalog/index.h>
  29. #include <access/genam.h>
  30. #include <catalog/pg_type.h>
  31. #include <catalog/catname.h>
  32. #include <catalog/pg_shadow.h>
  33. #include <commands/copy.h>
  34. #include "commands/trigger.h"
  35. #include <storage/fd.h>
  36. #include <libpq/libpq.h>
  37. #ifdef MULTIBYTE
  38. #include "mb/pg_wchar.h"
  39. #endif
  40. #define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
  41. #define VALUE(c) ((c) - '0')
  42. /* non-export function prototypes */
  43. static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
  44. static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
  45. static Oid GetOutputFunction(Oid type);
  46. static Oid GetTypeElement(Oid type);
  47. static Oid GetInputFunction(Oid type);
  48. static Oid IsTypeByVal(Oid type);
  49. static void GetIndexRelations(Oid main_relation_oid,
  50.   int *n_indices,
  51.   Relation **index_rels);
  52. #ifdef COPY_PATCH
  53. static void CopyReadNewline(FILE *fp, int *newline);
  54. static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline);
  55. #else
  56. static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim);
  57. #endif
  58. static void CopyAttributeOut(FILE *fp, char *string, char *delim, int is_array);
  59. static int CountTuples(Relation relation);
  60. static int lineno;
  61. /*
  62.  * Internal communications functions
  63.  */
  64. static void CopySendData(void *databuf, int datasize, FILE *fp);
  65. static void CopySendString(char *str, FILE *fp);
  66. static void CopySendChar(char c, FILE *fp);
  67. static void CopyGetData(void *databuf, int datasize, FILE *fp);
  68. static int CopyGetChar(FILE *fp);
  69. static int CopyGetEof(FILE *fp);
  70. static int CopyPeekChar(FILE *fp);
  71. static void CopyDonePeek(FILE *fp, int c, int pickup);
  72. /*
  73.  * CopySendData sends output data either to the file
  74.  * specified by fp or, if fp is NULL, using the standard
  75.  * backend->frontend functions
  76.  *
  77.  * CopySendString does the same for null-terminated strings
  78.  * CopySendChar does the same for single characters
  79.  *
  80.  * NB: no data conversion is applied by these functions
  81.  */
  82. static void
  83. CopySendData(void *databuf, int datasize, FILE *fp)
  84. {
  85. if (!fp)
  86. pq_putbytes((char *) databuf, datasize);
  87. else
  88. fwrite(databuf, datasize, 1, fp);
  89. }
  90. static void
  91. CopySendString(char *str, FILE *fp)
  92. {
  93. CopySendData(str, strlen(str), fp);
  94. }
  95. static void
  96. CopySendChar(char c, FILE *fp)
  97. {
  98. CopySendData(&c, 1, fp);
  99. }
  100. /*
  101.  * CopyGetData reads output data either from the file
  102.  * specified by fp or, if fp is NULL, using the standard
  103.  * backend->frontend functions
  104.  *
  105.  * CopyGetChar does the same for single characters
  106.  * CopyGetEof checks if it's EOF on the input
  107.  *
  108.  * NB: no data conversion is applied by these functions
  109.  */
  110. static void
  111. CopyGetData(void *databuf, int datasize, FILE *fp)
  112. {
  113. if (!fp)
  114. pq_getbytes((char *) databuf, datasize);
  115. else
  116. fread(databuf, datasize, 1, fp);
  117. }
  118. static int
  119. CopyGetChar(FILE *fp)
  120. {
  121. if (!fp)
  122. {
  123. unsigned char ch;
  124. if (pq_getbytes((char *) &ch, 1))
  125. return EOF;
  126. return ch;
  127. }
  128. else
  129. return getc(fp);
  130. }
  131. static int
  132. CopyGetEof(FILE *fp)
  133. {
  134. if (!fp)
  135. return 0; /* Never return EOF when talking to
  136.  * frontend ? */
  137. else
  138. return feof(fp);
  139. }
  140. /*
  141.  * CopyPeekChar reads a byte in "peekable" mode.
  142.  * after each call to CopyPeekChar, a call to CopyDonePeek _must_
  143.  * follow.
  144.  * CopyDonePeek will either take the peeked char off the steam
  145.  * (if pickup is != 0) or leave it on the stream (if pickup == 0)
  146.  */
  147. static int
  148. CopyPeekChar(FILE *fp)
  149. {
  150. if (!fp)
  151. return pq_peekbyte();
  152. else
  153. return getc(fp);
  154. }
  155. static void
  156. CopyDonePeek(FILE *fp, int c, int pickup)
  157. {
  158. if (!fp)
  159. {
  160. if (pickup)
  161. {
  162. /*
  163.  * We want to pick it up - just receive again into dummy
  164.  * buffer
  165.  */
  166. char c;
  167. pq_getbytes(&c, 1);
  168. }
  169. /* If we didn't want to pick it up, just leave it where it sits */
  170. }
  171. else
  172. {
  173. if (!pickup)
  174. {
  175. /* We don't want to pick it up - so put it back in there */
  176. ungetc(c, fp);
  177. }
  178. /* If we wanted to pick it up, it's already there */
  179. }
  180. }
  181. /*
  182.  *  DoCopy executes a the SQL COPY statement.
  183.  */
  184. void
  185. DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
  186.    char *filename, char *delim)
  187. {
  188. /*----------------------------------------------------------------------------
  189.   Either unload or reload contents of class <relname>, depending on <from>.
  190.   If <pipe> is false, transfer is between the class and the file named
  191.   <filename>.  Otherwise, transfer is between the class and our regular
  192.   input/output stream. The latter could be either stdin/stdout or a
  193.   socket, depending on whether we're running under Postmaster control.
  194.   Iff <binary>, unload or reload in the binary format, as opposed to the
  195.   more wasteful but more robust and portable text format.
  196.   If in the text format, delimit columns with delimiter <delim>.
  197.   When loading in the text format from an input stream (as opposed to
  198.   a file), recognize a "." on a line by itself as EOF. Also recognize
  199.   a stream EOF.  When unloading in the text format to an output stream,
  200.   write a "." on a line by itself at the end of the data.
  201.   Iff <oids>, unload or reload the format that includes OID information.
  202.   Do not allow a Postgres user without superuser privilege to read from
  203.   or write to a file.
  204.   Do not allow the copy if user doesn't have proper permission to access
  205.   the class.
  206. ----------------------------------------------------------------------------*/
  207. FILE    *fp;
  208. Relation rel;
  209. extern char *UserName; /* defined in global.c */
  210. const AclMode required_access = from ? ACL_WR : ACL_RD;
  211. int result;
  212. rel = heap_openr(relname);
  213. if (rel == NULL)
  214. elog(ERROR, "COPY command failed.  Class %s "
  215.  "does not exist.", relname);
  216. result = pg_aclcheck(relname, UserName, required_access);
  217. if (result != ACLCHECK_OK)
  218. elog(ERROR, "%s: %s", relname, aclcheck_error_strings[result]);
  219. /* Above should not return */
  220. else if (!superuser() && !pipe)
  221. elog(ERROR, "You must have Postgres superuser privilege to do a COPY "
  222.  "directly to or from a file.  Anyone can COPY to stdout or "
  223.  "from stdin.  Psql's \copy command also works for anyone.");
  224. /* Above should not return. */
  225. else
  226. {
  227. if (from)
  228. { /* copy from file to database */
  229. if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
  230. elog(ERROR, "You can't change sequence relation %s", relname);
  231. if (pipe)
  232. {
  233. if (IsUnderPostmaster)
  234. {
  235. ReceiveCopyBegin();
  236. fp = NULL;
  237. }
  238. else
  239. fp = stdin;
  240. }
  241. else
  242. {
  243. #ifndef __CYGWIN32__
  244. fp = AllocateFile(filename, "r");
  245. #else
  246. fp = AllocateFile(filename, "rb");
  247. #endif
  248. if (fp == NULL)
  249. elog(ERROR, "COPY command, running in backend with "
  250.  "effective uid %d, could not open file '%s' for "
  251.  "reading.  Errno = %s (%d).",
  252.  geteuid(), filename, strerror(errno), errno);
  253. }
  254. CopyFrom(rel, binary, oids, fp, delim);
  255. }
  256. else
  257. { /* copy from database to file */
  258. if (pipe)
  259. {
  260. if (IsUnderPostmaster)
  261. {
  262. SendCopyBegin();
  263. pq_startcopyout();
  264. fp = NULL;
  265. }
  266. else
  267. fp = stdout;
  268. }
  269. else
  270. {
  271. mode_t oumask; /* Pre-existing umask value */
  272. oumask = umask((mode_t) 0);
  273. #ifndef __CYGWIN32__
  274. fp = AllocateFile(filename, "w");
  275. #else
  276. fp = AllocateFile(filename, "wb");
  277. #endif
  278. umask(oumask);
  279. if (fp == NULL)
  280. elog(ERROR, "COPY command, running in backend with "
  281.  "effective uid %d, could not open file '%s' for "
  282.  "writing.  Errno = %s (%d).",
  283.  geteuid(), filename, strerror(errno), errno);
  284. }
  285. CopyTo(rel, binary, oids, fp, delim);
  286. }
  287. if (!pipe)
  288. {
  289. FreeFile(fp);
  290. }
  291. else if (!from)
  292. {
  293. if (!binary)
  294. CopySendData("\.n", 3, fp);
  295. if (IsUnderPostmaster)
  296. pq_endcopyout(false);
  297. }
  298. }
  299. }
  300. static void
  301. CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
  302. {
  303. HeapTuple tuple;
  304. HeapScanDesc scandesc;
  305. int32 attr_count,
  306. i;
  307. Form_pg_attribute *attr;
  308. FmgrInfo   *out_functions;
  309. Oid out_func_oid;
  310. Oid    *elements;
  311. int32    *typmod;
  312. Datum value;
  313. bool isnull; /* The attribute we are copying is null */
  314. char    *nulls;
  315. /*
  316.  * <nulls> is a (dynamically allocated) array with one character per
  317.  * attribute in the instance being copied. nulls[I-1] is 'n' if
  318.  * Attribute Number I is null, and ' ' otherwise.
  319.  *
  320.  * <nulls> is meaningful only if we are doing a binary copy.
  321.  */
  322. char    *string;
  323. int32 ntuples;
  324. TupleDesc tupDesc;
  325. scandesc = heap_beginscan(rel, 0, QuerySnapshot, 0, NULL);
  326. attr_count = rel->rd_att->natts;
  327. attr = rel->rd_att->attrs;
  328. tupDesc = rel->rd_att;
  329. if (!binary)
  330. {
  331. out_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo));
  332. elements = (Oid *) palloc(attr_count * sizeof(Oid));
  333. typmod = (int32 *) palloc(attr_count * sizeof(int32));
  334. for (i = 0; i < attr_count; i++)
  335. {
  336. out_func_oid = (Oid) GetOutputFunction(attr[i]->atttypid);
  337. fmgr_info(out_func_oid, &out_functions[i]);
  338. elements[i] = GetTypeElement(attr[i]->atttypid);
  339. typmod[i] = attr[i]->atttypmod;
  340. }
  341. nulls = NULL; /* meaningless, but compiler doesn't know
  342.  * that */
  343. }
  344. else
  345. {
  346. elements = NULL;
  347. typmod = NULL;
  348. out_functions = NULL;
  349. nulls = (char *) palloc(attr_count);
  350. for (i = 0; i < attr_count; i++)
  351. nulls[i] = ' ';
  352. /* XXX expensive */
  353. ntuples = CountTuples(rel);
  354. CopySendData(&ntuples, sizeof(int32), fp);
  355. }
  356. while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0)))
  357. {
  358. if (oids && !binary)
  359. {
  360. CopySendString(oidout(tuple->t_data->t_oid), fp);
  361. CopySendChar(delim[0], fp);
  362. }
  363. for (i = 0; i < attr_count; i++)
  364. {
  365. value = heap_getattr(tuple, i + 1, tupDesc, &isnull);
  366. if (!binary)
  367. {
  368. if (!isnull)
  369. {
  370. string = (char *) (*fmgr_faddr(&out_functions[i]))
  371. (value, elements[i], typmod[i]);
  372. CopyAttributeOut(fp, string, delim, attr[i]->attnelems);
  373. pfree(string);
  374. }
  375. else
  376. CopySendString("\N", fp); /* null indicator */
  377. if (i == attr_count - 1)
  378. CopySendChar('n', fp);
  379. else
  380. {
  381. /*
  382.  * when copying out, only use the first char of the
  383.  * delim string
  384.  */
  385. CopySendChar(delim[0], fp);
  386. }
  387. }
  388. else
  389. {
  390. /*
  391.  * only interesting thing heap_getattr tells us in this
  392.  * case is if we have a null attribute or not.
  393.  */
  394. if (isnull)
  395. nulls[i] = 'n';
  396. }
  397. }
  398. if (binary)
  399. {
  400. int32 null_ct = 0,
  401. length;
  402. for (i = 0; i < attr_count; i++)
  403. {
  404. if (nulls[i] == 'n')
  405. null_ct++;
  406. }
  407. length = tuple->t_len - tuple->t_data->t_hoff;
  408. CopySendData(&length, sizeof(int32), fp);
  409. if (oids)
  410. CopySendData((char *) &tuple->t_data->t_oid, sizeof(int32), fp);
  411. CopySendData(&null_ct, sizeof(int32), fp);
  412. if (null_ct > 0)
  413. {
  414. for (i = 0; i < attr_count; i++)
  415. {
  416. if (nulls[i] == 'n')
  417. {
  418. CopySendData(&i, sizeof(int32), fp);
  419. nulls[i] = ' ';
  420. }
  421. }
  422. }
  423. CopySendData((char *) tuple->t_data + tuple->t_data->t_hoff,
  424.  length, fp);
  425. }
  426. }
  427. heap_endscan(scandesc);
  428. if (binary)
  429. pfree(nulls);
  430. else
  431. {
  432. pfree(out_functions);
  433. pfree(elements);
  434. pfree(typmod);
  435. }
  436. heap_close(rel);
  437. }
  438. static void
  439. CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
  440. {
  441. HeapTuple tuple;
  442. AttrNumber attr_count;
  443. Form_pg_attribute *attr;
  444. FmgrInfo   *in_functions;
  445. int i;
  446. Oid in_func_oid;
  447. Datum    *values;
  448. char    *nulls,
  449.    *index_nulls;
  450. bool    *byval;
  451. bool isnull;
  452. bool has_index;
  453. int done = 0;
  454. char    *string = NULL,
  455.    *ptr;
  456. Relation   *index_rels;
  457. int32 len,
  458. null_ct,
  459. null_id;
  460. int32 ntuples,
  461. tuples_read = 0;
  462. bool reading_to_eof = true;
  463. Oid    *elements;
  464. int32    *typmod;
  465. FuncIndexInfo *finfo,
  466.   **finfoP = NULL;
  467. TupleDesc  *itupdescArr;
  468. HeapTuple pgIndexTup;
  469. Form_pg_index *pgIndexP = NULL;
  470. int    *indexNatts = NULL;
  471. char    *predString;
  472. Node   **indexPred = NULL;
  473. TupleDesc rtupdesc;
  474. ExprContext *econtext = NULL;
  475. EState    *estate = makeNode(EState); /* for ExecConstraints() */
  476. #ifndef OMIT_PARTIAL_INDEX
  477. TupleTable tupleTable;
  478. TupleTableSlot *slot = NULL;
  479. #endif
  480. int natts;
  481. AttrNumber *attnumP;
  482. Datum    *idatum;
  483. int n_indices;
  484. InsertIndexResult indexRes;
  485. TupleDesc tupDesc;
  486. Oid loaded_oid;
  487. bool skip_tuple = false;
  488. tupDesc = RelationGetDescr(rel);
  489. attr = tupDesc->attrs;
  490. attr_count = tupDesc->natts;
  491. has_index = false;
  492. /*
  493.  * This may be a scalar or a functional index. We initialize all
  494.  * kinds of arrays here to avoid doing extra work at every tuple copy.
  495.  */
  496. if (rel->rd_rel->relhasindex)
  497. {
  498. GetIndexRelations(RelationGetRelid(rel), &n_indices, &index_rels);
  499. if (n_indices > 0)
  500. {
  501. has_index = true;
  502. itupdescArr = (TupleDesc *) palloc(n_indices * sizeof(TupleDesc));
  503. pgIndexP = (Form_pg_index *) palloc(n_indices * sizeof(Form_pg_index));
  504. indexNatts = (int *) palloc(n_indices * sizeof(int));
  505. finfo = (FuncIndexInfo *) palloc(n_indices * sizeof(FuncIndexInfo));
  506. finfoP = (FuncIndexInfo **) palloc(n_indices * sizeof(FuncIndexInfo *));
  507. indexPred = (Node **) palloc(n_indices * sizeof(Node *));
  508. econtext = NULL;
  509. for (i = 0; i < n_indices; i++)
  510. {
  511. itupdescArr[i] = RelationGetDescr(index_rels[i]);
  512. pgIndexTup = SearchSysCacheTuple(INDEXRELID,
  513.    ObjectIdGetDatum(RelationGetRelid(index_rels[i])),
  514.  0, 0, 0);
  515. Assert(pgIndexTup);
  516. pgIndexP[i] = (Form_pg_index) GETSTRUCT(pgIndexTup);
  517. for (attnumP = &(pgIndexP[i]->indkey[0]), natts = 0;
  518.  natts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;
  519.  attnumP++, natts++);
  520. if (pgIndexP[i]->indproc != InvalidOid)
  521. {
  522. FIgetnArgs(&finfo[i]) = natts;
  523. natts = 1;
  524. FIgetProcOid(&finfo[i]) = pgIndexP[i]->indproc;
  525. *(FIgetname(&finfo[i])) = '';
  526. finfoP[i] = &finfo[i];
  527. }
  528. else
  529. finfoP[i] = (FuncIndexInfo *) NULL;
  530. indexNatts[i] = natts;
  531. if (VARSIZE(&pgIndexP[i]->indpred) != 0)
  532. {
  533. predString = fmgr(F_TEXTOUT, &pgIndexP[i]->indpred);
  534. indexPred[i] = stringToNode(predString);
  535. pfree(predString);
  536. /* make dummy ExprContext for use by ExecQual */
  537. if (econtext == NULL)
  538. {
  539. #ifndef OMIT_PARTIAL_INDEX
  540. tupleTable = ExecCreateTupleTable(1);
  541. slot = ExecAllocTableSlot(tupleTable);
  542. econtext = makeNode(ExprContext);
  543. econtext->ecxt_scantuple = slot;
  544. rtupdesc = RelationGetDescr(rel);
  545. slot->ttc_tupleDescriptor = rtupdesc;
  546. /*
  547.  * There's no buffer associated with heap tuples
  548.  * here, so I set the slot's buffer to NULL.
  549.  * Currently, it appears that the only way a
  550.  * buffer could be needed would be if the partial
  551.  * index predicate referred to the "lock" system
  552.  * attribute.  If it did, then heap_getattr would
  553.  * call HeapTupleGetRuleLock, which uses the
  554.  * buffer's descriptor to get the relation id.
  555.  * Rather than try to fix this, I'll just disallow
  556.  * partial indexes on "lock", which wouldn't be
  557.  * useful anyway. --Nels, Nov '92
  558.  */
  559. /* SetSlotBuffer(slot, (Buffer) NULL); */
  560. /* SetSlotShouldFree(slot, false); */
  561. slot->ttc_buffer = (Buffer) NULL;
  562. slot->ttc_shouldFree = false;
  563. #endif  /* OMIT_PARTIAL_INDEX */
  564. }
  565. }
  566. else
  567. indexPred[i] = NULL;
  568. }
  569. }
  570. }
  571. if (!binary)
  572. {
  573. in_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo));
  574. elements = (Oid *) palloc(attr_count * sizeof(Oid));
  575. typmod = (int32 *) palloc(attr_count * sizeof(int32));
  576. for (i = 0; i < attr_count; i++)
  577. {
  578. in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
  579. fmgr_info(in_func_oid, &in_functions[i]);
  580. elements[i] = GetTypeElement(attr[i]->atttypid);
  581. typmod[i] = attr[i]->atttypmod;
  582. }
  583. }
  584. else
  585. {
  586. in_functions = NULL;
  587. elements = NULL;
  588. typmod = NULL;
  589. CopyGetData(&ntuples, sizeof(int32), fp);
  590. if (ntuples != 0)
  591. reading_to_eof = false;
  592. }
  593. values = (Datum *) palloc(sizeof(Datum) * attr_count);
  594. nulls = (char *) palloc(attr_count);
  595. index_nulls = (char *) palloc(attr_count);
  596. idatum = (Datum *) palloc(sizeof(Datum) * attr_count);
  597. byval = (bool *) palloc(attr_count * sizeof(bool));
  598. for (i = 0; i < attr_count; i++)
  599. {
  600. nulls[i] = ' ';
  601. index_nulls[i] = ' ';
  602. byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
  603. }
  604. lineno = 0;
  605. while (!done)
  606. {
  607. if (!binary)
  608. {
  609. #ifdef COPY_PATCH
  610. int newline = 0;
  611. #endif
  612. lineno++;
  613. if (oids)
  614. {
  615. #ifdef COPY_PATCH
  616. string = CopyReadAttribute(fp, &isnull, delim, &newline);
  617. #else
  618. string = CopyReadAttribute(fp, &isnull, delim);
  619. #endif
  620. if (string == NULL)
  621. done = 1;
  622. else
  623. {
  624. loaded_oid = oidin(string);
  625. if (loaded_oid < BootstrapObjectIdData)
  626. elog(ERROR, "COPY TEXT: Invalid Oid. line: %d", lineno);
  627. }
  628. }
  629. for (i = 0; i < attr_count && !done; i++)
  630. {
  631. #ifdef COPY_PATCH
  632. string = CopyReadAttribute(fp, &isnull, delim, &newline);
  633. #else
  634. string = CopyReadAttribute(fp, &isnull, delim);
  635. #endif
  636. if (isnull)
  637. {
  638. values[i] = PointerGetDatum(NULL);
  639. nulls[i] = 'n';
  640. }
  641. else if (string == NULL)
  642. done = 1;
  643. else
  644. {
  645. values[i] = (Datum) (*fmgr_faddr(&in_functions[i])) (string,
  646.  elements[i],
  647.   typmod[i]);
  648. /*
  649.  * Sanity check - by reference attributes cannot
  650.  * return NULL
  651.  */
  652. if (!PointerIsValid(values[i]) &&
  653. !(rel->rd_att->attrs[i]->attbyval))
  654. elog(ERROR, "copy from line %d: Bad file format", lineno);
  655. }
  656. }
  657. #ifdef COPY_PATCH
  658. if (!done)
  659. CopyReadNewline(fp, &newline);
  660. #endif
  661. }
  662. else
  663. { /* binary */
  664. CopyGetData(&len, sizeof(int32), fp);
  665. if (CopyGetEof(fp))
  666. done = 1;
  667. else
  668. {
  669. if (oids)
  670. {
  671. CopyGetData(&loaded_oid, sizeof(int32), fp);
  672. if (loaded_oid < BootstrapObjectIdData)
  673. elog(ERROR, "COPY BINARY: Invalid Oid line: %d", lineno);
  674. }
  675. CopyGetData(&null_ct, sizeof(int32), fp);
  676. if (null_ct > 0)
  677. {
  678. for (i = 0; i < null_ct; i++)
  679. {
  680. CopyGetData(&null_id, sizeof(int32), fp);
  681. nulls[null_id] = 'n';
  682. }
  683. }
  684. string = (char *) palloc(len);
  685. CopyGetData(string, len, fp);
  686. ptr = string;
  687. for (i = 0; i < attr_count; i++)
  688. {
  689. if (byval[i] && nulls[i] != 'n')
  690. {
  691. switch (attr[i]->attlen)
  692. {
  693. case sizeof(char):
  694. values[i] = (Datum) *(unsigned char *) ptr;
  695. ptr += sizeof(char);
  696. break;
  697. case sizeof(short):
  698. ptr = (char *) SHORTALIGN(ptr);
  699. values[i] = (Datum) *(unsigned short *) ptr;
  700. ptr += sizeof(short);
  701. break;
  702. case sizeof(int32):
  703. ptr = (char *) INTALIGN(ptr);
  704. values[i] = (Datum) *(uint32 *) ptr;
  705. ptr += sizeof(int32);
  706. break;
  707. default:
  708. elog(ERROR, "COPY BINARY: impossible size! line: %d", lineno);
  709. break;
  710. }
  711. }
  712. else if (nulls[i] != 'n')
  713. {
  714. ptr = (char *) att_align(ptr, attr[i]->attlen, attr[i]->attalign);
  715. values[i] = (Datum) ptr;
  716. ptr = att_addlength(ptr, attr[i]->attlen, ptr);
  717. }
  718. }
  719. }
  720. }
  721. if (done)
  722. continue;
  723. /*
  724.  * Does it have any sence ? - vadim 12/14/96
  725.  *
  726.  * tupDesc = CreateTupleDesc(attr_count, attr);
  727.  */
  728. tuple = heap_formtuple(tupDesc, values, nulls);
  729. if (oids)
  730. tuple->t_data->t_oid = loaded_oid;
  731. skip_tuple = false;
  732. /* BEFORE ROW INSERT Triggers */
  733. if (rel->trigdesc &&
  734. rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
  735. {
  736. HeapTuple newtuple;
  737. newtuple = ExecBRInsertTriggers(rel, tuple);
  738. if (newtuple == NULL) /* "do nothing" */
  739. skip_tuple = true;
  740. else if (newtuple != tuple) /* modified by Trigger(s) */
  741. {
  742. pfree(tuple);
  743. tuple = newtuple;
  744. }
  745. }
  746. if (!skip_tuple)
  747. {
  748. /* ----------------
  749.  * Check the constraints of a tuple
  750.  * ----------------
  751.  */
  752. if (rel->rd_att->constr)
  753. ExecConstraints("CopyFrom", rel, tuple, estate);
  754. heap_insert(rel, tuple);
  755. if (has_index)
  756. {
  757. for (i = 0; i < n_indices; i++)
  758. {
  759. if (indexPred[i] != NULL)
  760. {
  761. #ifndef OMIT_PARTIAL_INDEX
  762. /*
  763.  * if tuple doesn't satisfy predicate, don't
  764.  * update index
  765.  */
  766. slot->val = tuple;
  767. /* SetSlotContents(slot, tuple); */
  768. if (ExecQual((List *) indexPred[i], econtext) == false)
  769. continue;
  770. #endif  /* OMIT_PARTIAL_INDEX */
  771. }
  772. FormIndexDatum(indexNatts[i],
  773. (AttrNumber *) &(pgIndexP[i]->indkey[0]),
  774.    tuple,
  775.    tupDesc,
  776.    idatum,
  777.    index_nulls,
  778.    finfoP[i]);
  779. indexRes = index_insert(index_rels[i], idatum, index_nulls,
  780. &(tuple->t_self), rel);
  781. if (indexRes)
  782. pfree(indexRes);
  783. }
  784. }
  785. /* AFTER ROW INSERT Triggers */
  786. if (rel->trigdesc &&
  787. rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
  788. ExecARInsertTriggers(rel, tuple);
  789. }
  790. if (binary)
  791. pfree(string);
  792. for (i = 0; i < attr_count; i++)
  793. {
  794. if (!byval[i] && nulls[i] != 'n')
  795. {
  796. if (!binary)
  797. pfree((void *) values[i]);
  798. }
  799. else if (nulls[i] == 'n')
  800. nulls[i] = ' ';
  801. }
  802. pfree(tuple);
  803. tuples_read++;
  804. if (!reading_to_eof && ntuples == tuples_read)
  805. done = true;
  806. }
  807. pfree(values);
  808. pfree(nulls);
  809. pfree(index_nulls);
  810. pfree(idatum);
  811. pfree(byval);
  812. if (!binary)
  813. {
  814. pfree(in_functions);
  815. pfree(elements);
  816. pfree(typmod);
  817. }
  818. /* comments in execUtils.c */
  819. if (has_index)
  820. {
  821. for (i = 0; i < n_indices; i++)
  822. {
  823. if (index_rels[i] == NULL)
  824. continue;
  825. if ((index_rels[i])->rd_rel->relam != BTREE_AM_OID &&
  826. (index_rels[i])->rd_rel->relam != HASH_AM_OID)
  827. UnlockRelation(index_rels[i], AccessExclusiveLock);
  828. index_close(index_rels[i]);
  829. }
  830. }
  831. heap_close(rel);
  832. }
  833. static Oid
  834. GetOutputFunction(Oid type)
  835. {
  836. HeapTuple typeTuple;
  837. typeTuple = SearchSysCacheTuple(TYPOID,
  838. ObjectIdGetDatum(type),
  839. 0, 0, 0);
  840. if (HeapTupleIsValid(typeTuple))
  841. return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput;
  842. elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
  843. return InvalidOid;
  844. }
  845. static Oid
  846. GetTypeElement(Oid type)
  847. {
  848. HeapTuple typeTuple;
  849. typeTuple = SearchSysCacheTuple(TYPOID,
  850. ObjectIdGetDatum(type),
  851. 0, 0, 0);
  852. if (HeapTupleIsValid(typeTuple))
  853. return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
  854. elog(ERROR, "GetOutputFunction: Cache lookup of type %d failed", type);
  855. return InvalidOid;
  856. }
  857. static Oid
  858. GetInputFunction(Oid type)
  859. {
  860. HeapTuple typeTuple;
  861. typeTuple = SearchSysCacheTuple(TYPOID,
  862. ObjectIdGetDatum(type),
  863. 0, 0, 0);
  864. if (HeapTupleIsValid(typeTuple))
  865. return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typinput;
  866. elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
  867. return InvalidOid;
  868. }
  869. static Oid
  870. IsTypeByVal(Oid type)
  871. {
  872. HeapTuple typeTuple;
  873. typeTuple = SearchSysCacheTuple(TYPOID,
  874. ObjectIdGetDatum(type),
  875. 0, 0, 0);
  876. if (HeapTupleIsValid(typeTuple))
  877. return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval;
  878. elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
  879. return InvalidOid;
  880. }
  881. /*
  882.  * Given the OID of a relation, return an array of index relation descriptors
  883.  * and the number of index relations.  These relation descriptors are open
  884.  * using heap_open().
  885.  *
  886.  * Space for the array itself is palloc'ed.
  887.  */
  888. typedef struct rel_list
  889. {
  890. Oid index_rel_oid;
  891. struct rel_list *next;
  892. } RelationList;
  893. static void
  894. GetIndexRelations(Oid main_relation_oid,
  895.   int *n_indices,
  896.   Relation **index_rels)
  897. {
  898. RelationList *head,
  899.    *scan;
  900. Relation pg_index_rel;
  901. HeapScanDesc scandesc;
  902. Oid index_relation_oid;
  903. HeapTuple tuple;
  904. TupleDesc tupDesc;
  905. int i;
  906. bool isnull;
  907. pg_index_rel = heap_openr(IndexRelationName);
  908. scandesc = heap_beginscan(pg_index_rel, 0, SnapshotNow, 0, NULL);
  909. tupDesc = RelationGetDescr(pg_index_rel);
  910. *n_indices = 0;
  911. head = (RelationList *) palloc(sizeof(RelationList));
  912. scan = head;
  913. head->next = NULL;
  914. while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0)))
  915. {
  916. index_relation_oid = (Oid) DatumGetInt32(heap_getattr(tuple, 2,
  917.   tupDesc, &isnull));
  918. if (index_relation_oid == main_relation_oid)
  919. {
  920. scan->index_rel_oid = (Oid) DatumGetInt32(heap_getattr(tuple,
  921. Anum_pg_index_indexrelid,
  922.   tupDesc, &isnull));
  923. (*n_indices)++;
  924. scan->next = (RelationList *) palloc(sizeof(RelationList));
  925. scan = scan->next;
  926. }
  927. }
  928. heap_endscan(scandesc);
  929. heap_close(pg_index_rel);
  930. /* We cannot trust to relhasindex of the main_relation now, so... */
  931. if (*n_indices == 0)
  932. return;
  933. *index_rels = (Relation *) palloc(*n_indices * sizeof(Relation));
  934. for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next)
  935. {
  936. (*index_rels)[i] = index_open(scan->index_rel_oid);
  937. /* comments in execUtils.c */
  938. if ((*index_rels)[i] != NULL &&
  939. ((*index_rels)[i])->rd_rel->relam != BTREE_AM_OID &&
  940. ((*index_rels)[i])->rd_rel->relam != HASH_AM_OID)
  941. LockRelation((*index_rels)[i], AccessExclusiveLock);
  942. }
  943. for (i = 0, scan = head; i < *n_indices + 1; i++)
  944. {
  945. scan = head->next;
  946. pfree(head);
  947. head = scan;
  948. }
  949. }
  950. #define EXT_ATTLEN (5 * BLCKSZ)
  951. /*
  952.    returns 1 is c is in s
  953. */
  954. static bool
  955. inString(char c, char *s)
  956. {
  957. int i;
  958. if (s)
  959. {
  960. i = 0;
  961. while (s[i] != '')
  962. {
  963. if (s[i] == c)
  964. return 1;
  965. i++;
  966. }
  967. }
  968. return 0;
  969. }
  970. #ifdef COPY_PATCH
  971. /*
  972.  * Reads input from fp until an end of line is seen.
  973.  */
  974. static void
  975. CopyReadNewline(FILE *fp, int *newline)
  976. {
  977. if (!*newline)
  978. {
  979. elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored", lineno);
  980. while (!CopyGetEof(fp) && (CopyGetChar(fp) != 'n'));
  981. }
  982. *newline = 0;
  983. }
  984. #endif
  985. /*
  986.  * Reads input from fp until eof is seen.  If we are reading from standard
  987.  * input, AND we see a dot on a line by itself (a dot followed immediately
  988.  * by a newline), we exit as if we saw eof.  This is so that copy pipelines
  989.  * can be used as standard input.
  990.  */
  991. static char *
  992. #ifdef COPY_PATCH
  993. CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
  994. #else
  995. CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
  996. #endif
  997. {
  998. static char attribute[EXT_ATTLEN];
  999. char c;
  1000. int done = 0;
  1001. int i = 0;
  1002. #ifdef MULTIBYTE
  1003. int mblen;
  1004. int encoding;
  1005. unsigned char s[2];
  1006. int j;
  1007. #endif
  1008. #ifdef MULTIBYTE
  1009. encoding = pg_get_client_encoding();
  1010. s[1] = 0;
  1011. #endif
  1012. #ifdef COPY_PATCH
  1013. /* if last delimiter was a newline return a NULL attribute */
  1014. if (*newline)
  1015. {
  1016. *isnull = (bool) true;
  1017. return NULL;
  1018. }
  1019. #endif
  1020. *isnull = (bool) false; /* set default */
  1021. if (CopyGetEof(fp))
  1022. return NULL;
  1023. while (!done)
  1024. {
  1025. c = CopyGetChar(fp);
  1026. if (CopyGetEof(fp))
  1027. return NULL;
  1028. else if (c == '\')
  1029. {
  1030. c = CopyGetChar(fp);
  1031. if (CopyGetEof(fp))
  1032. return NULL;
  1033. switch (c)
  1034. {
  1035. case '0':
  1036. case '1':
  1037. case '2':
  1038. case '3':
  1039. case '4':
  1040. case '5':
  1041. case '6':
  1042. case '7':
  1043. {
  1044. int val;
  1045. val = VALUE(c);
  1046. c = CopyPeekChar(fp);
  1047. if (ISOCTAL(c))
  1048. {
  1049. val = (val << 3) + VALUE(c);
  1050. CopyDonePeek(fp, c, 1); /* Pick up the
  1051.  * character! */
  1052. c = CopyPeekChar(fp);
  1053. if (ISOCTAL(c))
  1054. {
  1055. CopyDonePeek(fp, c, 1); /* pick up! */
  1056. val = (val << 3) + VALUE(c);
  1057. }
  1058. else
  1059. {
  1060. if (CopyGetEof(fp))
  1061. {
  1062. CopyDonePeek(fp, c, 1); /* pick up */
  1063. return NULL;
  1064. }
  1065. CopyDonePeek(fp, c, 0); /* Return to stream! */
  1066. }
  1067. }
  1068. else
  1069. {
  1070. if (CopyGetEof(fp))
  1071. return NULL;
  1072. CopyDonePeek(fp, c, 0); /* Return to stream! */
  1073. }
  1074. c = val & 0377;
  1075. }
  1076. break;
  1077. case 'b':
  1078. c = 'b';
  1079. break;
  1080. case 'f':
  1081. c = 'f';
  1082. break;
  1083. case 'n':
  1084. c = 'n';
  1085. break;
  1086. case 'r':
  1087. c = 'r';
  1088. break;
  1089. case 't':
  1090. c = 't';
  1091. break;
  1092. case 'v':
  1093. c = 'v';
  1094. break;
  1095. case 'N':
  1096. attribute[0] = ''; /* just to be safe */
  1097. *isnull = (bool) true;
  1098. break;
  1099. case '.':
  1100. c = CopyGetChar(fp);
  1101. if (c != 'n')
  1102. elog(ERROR, "CopyReadAttribute - end of record marker corrupted. line: %d", lineno);
  1103. return NULL;
  1104. break;
  1105. }
  1106. }
  1107. else if (inString(c, delim) || c == 'n')
  1108. {
  1109. #ifdef COPY_PATCH
  1110. if (c == 'n')
  1111. *newline = 1;
  1112. #endif
  1113. done = 1;
  1114. }
  1115. if (!done)
  1116. attribute[i++] = c;
  1117. #ifdef MULTIBYTE
  1118. s[0] = c;
  1119. mblen = pg_encoding_mblen(encoding, s);
  1120. mblen--;
  1121. for (j = 0; j < mblen; j++)
  1122. {
  1123. c = CopyGetChar(fp);
  1124. if (CopyGetEof(fp))
  1125. return NULL;
  1126. attribute[i++] = c;
  1127. }
  1128. #endif
  1129. if (i == EXT_ATTLEN - 1)
  1130. elog(ERROR, "CopyReadAttribute - attribute length too long. line: %d", lineno);
  1131. }
  1132. attribute[i] = '';
  1133. #ifdef MULTIBYTE
  1134. return (pg_client_to_server((unsigned char *) attribute, strlen(attribute)));
  1135. #else
  1136. return &attribute[0];
  1137. #endif
  1138. }
  1139. static void
  1140. CopyAttributeOut(FILE *fp, char *server_string, char *delim, int is_array)
  1141. {
  1142. char    *string;
  1143. char c;
  1144. #ifdef MULTIBYTE
  1145. int mblen;
  1146. int encoding;
  1147. int i;
  1148. #endif
  1149. #ifdef MULTIBYTE
  1150. string = pg_server_to_client(server_string, strlen(server_string));
  1151. encoding = pg_get_client_encoding();
  1152. #else
  1153. string = server_string;
  1154. #endif
  1155. #ifdef MULTIBYTE
  1156. for (; (mblen = pg_encoding_mblen(encoding, string)) &&
  1157.  ((c = *string) != ''); string += mblen)
  1158. #else
  1159. for (; (c = *string) != ''; string++)
  1160. #endif
  1161. {
  1162. if (c == delim[0] || c == 'n' ||
  1163. (c == '\' && !is_array))
  1164. CopySendChar('\', fp);
  1165. else if (c == '\' && is_array)
  1166. {
  1167. if (*(string + 1) == '\')
  1168. {
  1169. /* translate \ to \\ */
  1170. CopySendChar('\', fp);
  1171. CopySendChar('\', fp);
  1172. CopySendChar('\', fp);
  1173. string++;
  1174. }
  1175. else if (*(string + 1) == '"')
  1176. {
  1177. /* translate " to \" */
  1178. CopySendChar('\', fp);
  1179. CopySendChar('\', fp);
  1180. }
  1181. }
  1182. #ifdef MULTIBYTE
  1183. for (i = 0; i < mblen; i++)
  1184. CopySendChar(*(string + i), fp);
  1185. #else
  1186. CopySendChar(*string, fp);
  1187. #endif
  1188. }
  1189. }
  1190. /*
  1191.  * Returns the number of tuples in a relation. Unfortunately, currently
  1192.  * must do a scan of the entire relation to determine this.
  1193.  *
  1194.  * relation is expected to be an open relation descriptor.
  1195.  */
  1196. static int
  1197. CountTuples(Relation relation)
  1198. {
  1199. HeapScanDesc scandesc;
  1200. HeapTuple tuple;
  1201. int i;
  1202. scandesc = heap_beginscan(relation, 0, QuerySnapshot, 0, NULL);
  1203. i = 0;
  1204. while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0)))
  1205. i++;
  1206. heap_endscan(scandesc);
  1207. return i;
  1208. }