📄 copy.c
字号:
pfree(elements); pfree(typmod); } /* comments in execUtils.c */ if (has_index) { for (i = 0; i < n_indices; i++) { if (index_rels[i] == NULL) continue; if ((index_rels[i])->rd_rel->relam != BTREE_AM_OID && (index_rels[i])->rd_rel->relam != HASH_AM_OID) UnlockRelation(index_rels[i], AccessExclusiveLock); index_close(index_rels[i]); } } heap_close(rel);}static OidGetOutputFunction(Oid type){ HeapTuple typeTuple; typeTuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(type), 0, 0, 0); if (HeapTupleIsValid(typeTuple)) return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput; elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type); return InvalidOid;}static OidGetTypeElement(Oid type){ HeapTuple typeTuple; typeTuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(type), 0, 0, 0); if (HeapTupleIsValid(typeTuple)) return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem; elog(ERROR, "GetOutputFunction: Cache lookup of type %d failed", type); return InvalidOid;}static OidGetInputFunction(Oid type){ HeapTuple typeTuple; typeTuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(type), 0, 0, 0); if (HeapTupleIsValid(typeTuple)) return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typinput; elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type); return InvalidOid;}static OidIsTypeByVal(Oid type){ HeapTuple typeTuple; typeTuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(type), 0, 0, 0); if (HeapTupleIsValid(typeTuple)) return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval; elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type); return InvalidOid;}/* * Given the OID of a relation, return an array of index relation descriptors * and the number of index relations. These relation descriptors are open * using heap_open(). * * Space for the array itself is palloc'ed. */typedef struct rel_list{ Oid index_rel_oid; struct rel_list *next;} RelationList;static voidGetIndexRelations(Oid main_relation_oid, int *n_indices, Relation **index_rels){ RelationList *head, *scan; Relation pg_index_rel; HeapScanDesc scandesc; Oid index_relation_oid; HeapTuple tuple; TupleDesc tupDesc; int i; bool isnull; pg_index_rel = heap_openr(IndexRelationName); scandesc = heap_beginscan(pg_index_rel, 0, SnapshotNow, 0, NULL); tupDesc = RelationGetDescr(pg_index_rel); *n_indices = 0; head = (RelationList *) palloc(sizeof(RelationList)); scan = head; head->next = NULL; while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0))) { index_relation_oid = (Oid) DatumGetInt32(heap_getattr(tuple, 2, tupDesc, &isnull)); if (index_relation_oid == main_relation_oid) { scan->index_rel_oid = (Oid) DatumGetInt32(heap_getattr(tuple, Anum_pg_index_indexrelid, tupDesc, &isnull)); (*n_indices)++; scan->next = (RelationList *) palloc(sizeof(RelationList)); scan = scan->next; } } heap_endscan(scandesc); heap_close(pg_index_rel); /* We cannot trust to relhasindex of the main_relation now, so... */ if (*n_indices == 0) return; *index_rels = (Relation *) palloc(*n_indices * sizeof(Relation)); for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next) { (*index_rels)[i] = index_open(scan->index_rel_oid); /* comments in execUtils.c */ if ((*index_rels)[i] != NULL && ((*index_rels)[i])->rd_rel->relam != BTREE_AM_OID && ((*index_rels)[i])->rd_rel->relam != HASH_AM_OID) LockRelation((*index_rels)[i], AccessExclusiveLock); } for (i = 0, scan = head; i < *n_indices + 1; i++) { scan = head->next; pfree(head); head = scan; }}#define EXT_ATTLEN (5 * BLCKSZ)/* returns 1 is c is in s*/static boolinString(char c, char *s){ int i; if (s) { i = 0; while (s[i] != '\0') { if (s[i] == c) return 1; i++; } } return 0;}#ifdef COPY_PATCH/* * Reads input from fp until an end of line is seen. */static voidCopyReadNewline(FILE *fp, int *newline){ if (!*newline) { elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored", lineno); while (!CopyGetEof(fp) && (CopyGetChar(fp) != '\n')); } *newline = 0;}#endif/* * Reads input from fp until eof is seen. If we are reading from standard * input, AND we see a dot on a line by itself (a dot followed immediately * by a newline), we exit as if we saw eof. This is so that copy pipelines * can be used as standard input. */static char *#ifdef COPY_PATCHCopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)#elseCopyReadAttribute(FILE *fp, bool *isnull, char *delim)#endif{ static char attribute[EXT_ATTLEN]; char c; int done = 0; int i = 0;#ifdef MULTIBYTE int mblen; int encoding; unsigned char s[2]; int j;#endif#ifdef MULTIBYTE encoding = pg_get_client_encoding(); s[1] = 0;#endif#ifdef COPY_PATCH /* if last delimiter was a newline return a NULL attribute */ if (*newline) { *isnull = (bool) true; return NULL; }#endif *isnull = (bool) false; /* set default */ if (CopyGetEof(fp)) return NULL; while (!done) { c = CopyGetChar(fp); if (CopyGetEof(fp)) return NULL; else if (c == '\\') { c = CopyGetChar(fp); if (CopyGetEof(fp)) return NULL; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int val; val = VALUE(c); c = CopyPeekChar(fp); if (ISOCTAL(c)) { val = (val << 3) + VALUE(c); CopyDonePeek(fp, c, 1); /* Pick up the * character! */ c = CopyPeekChar(fp); if (ISOCTAL(c)) { CopyDonePeek(fp, c, 1); /* pick up! */ val = (val << 3) + VALUE(c); } else { if (CopyGetEof(fp)) { CopyDonePeek(fp, c, 1); /* pick up */ return NULL; } CopyDonePeek(fp, c, 0); /* Return to stream! */ } } else { if (CopyGetEof(fp)) return NULL; CopyDonePeek(fp, c, 0); /* Return to stream! */ } c = val & 0377; } break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case 'N': attribute[0] = '\0'; /* just to be safe */ *isnull = (bool) true; break; case '.': c = CopyGetChar(fp); if (c != '\n') elog(ERROR, "CopyReadAttribute - end of record marker corrupted. line: %d", lineno); return NULL; break; } } else if (inString(c, delim) || c == '\n') {#ifdef COPY_PATCH if (c == '\n') *newline = 1;#endif done = 1; } if (!done) attribute[i++] = c;#ifdef MULTIBYTE s[0] = c; mblen = pg_encoding_mblen(encoding, s); mblen--; for (j = 0; j < mblen; j++) { c = CopyGetChar(fp); if (CopyGetEof(fp)) return NULL; attribute[i++] = c; }#endif if (i == EXT_ATTLEN - 1) elog(ERROR, "CopyReadAttribute - attribute length too long. line: %d", lineno); } attribute[i] = '\0';#ifdef MULTIBYTE return (pg_client_to_server((unsigned char *) attribute, strlen(attribute)));#else return &attribute[0];#endif}static voidCopyAttributeOut(FILE *fp, char *server_string, char *delim, int is_array){ char *string; char c;#ifdef MULTIBYTE int mblen; int encoding; int i;#endif#ifdef MULTIBYTE string = pg_server_to_client(server_string, strlen(server_string)); encoding = pg_get_client_encoding();#else string = server_string;#endif#ifdef MULTIBYTE for (; (mblen = pg_encoding_mblen(encoding, string)) && ((c = *string) != '\0'); string += mblen)#else for (; (c = *string) != '\0'; string++)#endif { if (c == delim[0] || c == '\n' || (c == '\\' && !is_array)) CopySendChar('\\', fp); else if (c == '\\' && is_array) { if (*(string + 1) == '\\') { /* translate \\ to \\\\ */ CopySendChar('\\', fp); CopySendChar('\\', fp); CopySendChar('\\', fp); string++; } else if (*(string + 1) == '"') { /* translate \" to \\\" */ CopySendChar('\\', fp); CopySendChar('\\', fp); } }#ifdef MULTIBYTE for (i = 0; i < mblen; i++) CopySendChar(*(string + i), fp);#else CopySendChar(*string, fp);#endif }}/* * Returns the number of tuples in a relation. Unfortunately, currently * must do a scan of the entire relation to determine this. * * relation is expected to be an open relation descriptor. */static intCountTuples(Relation relation){ HeapScanDesc scandesc; HeapTuple tuple; int i; scandesc = heap_beginscan(relation, 0, QuerySnapshot, 0, NULL); i = 0; while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0))) i++; heap_endscan(scandesc); return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -