|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.195 2003/04/22 00:08:06 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.196 2003/04/24 21:16:42 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -100,13 +100,13 @@ static const char BinarySignature[12] = "PGBCOPY\n\377\r\n\0";
|
100 | 100 | * Static communication variables ... pretty grotty, but COPY has
|
101 | 101 | * never been reentrant...
|
102 | 102 | */
|
103 |
| -intcopy_lineno=0;/* exported for use by elog() -- dz */ |
104 |
| - |
105 | 103 | staticCopyDestcopy_dest;
|
106 | 104 | staticFILE*copy_file;/* if copy_dest == COPY_FILE */
|
107 | 105 | staticStringInfocopy_msgbuf;/* if copy_dest == COPY_NEW_FE */
|
108 | 106 | staticboolfe_eof;/* true if detected end of copy data */
|
109 |
| -staticEolTypeeol_type; |
| 107 | +staticEolTypeeol_type;/* EOL type of input */ |
| 108 | +staticintcopy_lineno;/* line number for error messages */ |
| 109 | + |
110 | 110 |
|
111 | 111 | /*
|
112 | 112 | * These static variables are used to avoid incurring overhead for each
|
@@ -1000,6 +1000,16 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
|
1000 | 1000 | }
|
1001 | 1001 |
|
1002 | 1002 |
|
| 1003 | +/* |
| 1004 | + * error context callback for COPY FROM |
| 1005 | + */ |
| 1006 | +staticvoid |
| 1007 | +copy_in_error_callback(void*arg) |
| 1008 | +{ |
| 1009 | +errcontext("COPY FROM, line %d",copy_lineno); |
| 1010 | +} |
| 1011 | + |
| 1012 | + |
1003 | 1013 | /*
|
1004 | 1014 | * Copy FROM file to relation.
|
1005 | 1015 | */
|
@@ -1032,6 +1042,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
1032 | 1042 | ExprState**defexprs;/* array of default att expressions */
|
1033 | 1043 | ExprContext*econtext;/* used for ExecEvalExpr for default atts */
|
1034 | 1044 | MemoryContextoldcontext=CurrentMemoryContext;
|
| 1045 | +ErrorContextCallbackerrcontext; |
1035 | 1046 |
|
1036 | 1047 | tupDesc=RelationGetDescr(rel);
|
1037 | 1048 | attr=tupDesc->attrs;
|
@@ -1188,16 +1199,22 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
1188 | 1199 | values= (Datum*)palloc(num_phys_attrs*sizeof(Datum));
|
1189 | 1200 | nulls= (char*)palloc(num_phys_attrs*sizeof(char));
|
1190 | 1201 |
|
1191 |
| -/* Initialize static variables */ |
1192 |
| -copy_lineno=0; |
1193 |
| -eol_type=EOL_UNKNOWN; |
1194 |
| -fe_eof= false; |
1195 |
| - |
1196 | 1202 | /* Make room for a PARAM_EXEC value for domain constraint checks */
|
1197 | 1203 | if (hasConstraints)
|
1198 | 1204 | econtext->ecxt_param_exec_vals= (ParamExecData*)
|
1199 | 1205 | palloc0(sizeof(ParamExecData));
|
1200 | 1206 |
|
| 1207 | +/* Initialize static variables */ |
| 1208 | +fe_eof= false; |
| 1209 | +eol_type=EOL_UNKNOWN; |
| 1210 | +copy_lineno=0; |
| 1211 | + |
| 1212 | +/* Set up callback to identify error line number */ |
| 1213 | +errcontext.callback=copy_in_error_callback; |
| 1214 | +errcontext.arg=NULL; |
| 1215 | +errcontext.previous=error_context_stack; |
| 1216 | +error_context_stack=&errcontext; |
| 1217 | + |
1201 | 1218 | while (!done)
|
1202 | 1219 | {
|
1203 | 1220 | boolskip_tuple;
|
@@ -1502,7 +1519,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
1502 | 1519 | /*
|
1503 | 1520 | * Done, clean up
|
1504 | 1521 | */
|
1505 |
| -copy_lineno=0; |
| 1522 | +error_context_stack=errcontext.previous; |
1506 | 1523 |
|
1507 | 1524 | MemoryContextSwitchTo(oldcontext);
|
1508 | 1525 |
|
|