Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for ticket #71: Correctly handle CR and CRLF line terminators in the input files for the COPY command. (CVS 694) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
be1315755ef801b5ec07f469134e0d33 |
User & Date: | drh 2002-07-30 17:20:40.000 |
Context
2002-07-30
| ||
17:42 | Fix for ticket #111: Update the documentation to explain that you may not start a transaction in one thread and complete it in another thread under Linux Threads where each thread has its own process ID. (CVS 695) (check-in: 0b0c0492cc user: drh tags: trunk) | |
17:20 | Fix for ticket #71: Correctly handle CR and CRLF line terminators in the input files for the COPY command. (CVS 694) (check-in: be1315755e user: drh tags: trunk) | |
2002-07-21
| ||
23:09 | UPDATE triggers on TEMP tables were broken. (CVS 693) (check-in: c080ed01ea user: danielk1977 tags: trunk) | |
Changes
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.34 2002/07/30 17:20:40 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** The version of the SQLite library. |
︙ | ︙ | |||
380 381 382 383 384 385 386 387 388 389 390 391 392 393 | const char *sqlFormat, /* printf-style format string for the SQL */ char ***resultp, /* Result written to a char *[] that this points to */ int *nrow, /* Number of result rows written here */ int *ncolumn, /* Number of result columns written here */ char **errmsg, /* Error msg written here */ va_list ap /* Arguments to the format string */ ); /* ** Windows systems should call this routine to free memory that ** is returned in the in the errmsg parameter of sqlite_open() when ** SQLite is a DLL. For some reason, it does not work to call free() ** directly. */ | > | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | const char *sqlFormat, /* printf-style format string for the SQL */ char ***resultp, /* Result written to a char *[] that this points to */ int *nrow, /* Number of result rows written here */ int *ncolumn, /* Number of result columns written here */ char **errmsg, /* Error msg written here */ va_list ap /* Arguments to the format string */ ); char *sqlite_mprintf(const char*,...); /* ** Windows systems should call this routine to free memory that ** is returned in the in the errmsg parameter of sqlite_open() when ** SQLite is a DLL. For some reason, it does not work to call free() ** directly. */ |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.141 2002/07/30 17:20:40 drh Exp $ */ #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" #include <stdio.h> |
︙ | ︙ | |||
908 909 910 911 912 913 914 | int sqliteExprAnalyzeAggregates(Parse*, Expr*); Vdbe *sqliteGetVdbe(Parse*); int sqliteRandomByte(void); int sqliteRandomInteger(void); void sqliteBeginTransaction(Parse*, int); void sqliteCommitTransaction(Parse*); void sqliteRollbackTransaction(Parse*); | < | 908 909 910 911 912 913 914 915 916 917 918 919 920 921 | int sqliteExprAnalyzeAggregates(Parse*, Expr*); Vdbe *sqliteGetVdbe(Parse*); int sqliteRandomByte(void); int sqliteRandomInteger(void); void sqliteBeginTransaction(Parse*, int); void sqliteCommitTransaction(Parse*); void sqliteRollbackTransaction(Parse*); int sqliteExprIsConstant(Expr*); int sqliteExprIsInteger(Expr*, int*); int sqliteIsRowid(const char*); void sqliteGenerateRowDelete(sqlite*, Vdbe*, Table*, int, int); void sqliteGenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*); void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int); void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.166 2002/07/30 17:20:40 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_MoveTo or the OP_Next opcode. The test |
︙ | ︙ | |||
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | ** with NDEBUG=1, the VERIFY() code is omitted. */ #ifdef NDEBUG # define VERIFY(X) #else # define VERIFY(X) X #endif /* ** Execute the program in the VDBE. ** ** If an error occurs, an error message is written to memory obtained ** from sqliteMalloc() and *pzErrMsg is made to point to that memory. ** The return parameter is the number of errors. | > > > > > > > > > > > > > > > > > > > > > > > > > > | 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 | ** with NDEBUG=1, the VERIFY() code is omitted. */ #ifdef NDEBUG # define VERIFY(X) #else # define VERIFY(X) X #endif /* ** The following routine works like a replacement for the standard ** library routine fgets(). The difference is in how end-of-line (EOL) ** is handled. Standard fgets() uses LF for EOL under unix, CRLF ** under windows, and CR under mac. This routine accepts any of these ** character sequences as an EOL mark. The EOL mark is replaced by ** a single LF character in zBuf. */ static char *vdbe_fgets(char *zBuf, int nBuf, FILE *in){ int i, c; for(i=0; i<nBuf-1 && (c=getc(in))!=EOF; i++){ zBuf[i] = c; if( c=='\r' || c=='\n' ){ if( c=='\r' ){ zBuf[i] = '\n'; c = getc(in); if( c!=EOF && c!='\n' ) ungetc(c, in); } i++; break; } } zBuf[i] = 0; return i>0 ? zBuf : 0; } /* ** Execute the program in the VDBE. ** ** If an error occurs, an error message is written to memory obtained ** from sqliteMalloc() and *pzErrMsg is made to point to that memory. ** The return parameter is the number of errors. |
︙ | ︙ | |||
4466 4467 4468 4469 4470 4471 4472 | p->nLineAlloc = 0; sqliteFree(p->zLine); p->zLine = 0; goto no_mem; } p->zLine = zLine; } | | | 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 | p->nLineAlloc = 0; sqliteFree(p->zLine); p->zLine = 0; goto no_mem; } p->zLine = zLine; } if( vdbe_fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){ eol = 1; p->zLine[n] = 0; }else{ int c; while( (c = p->zLine[n])!=0 ){ if( c=='\\' ){ if( p->zLine[n+1]==0 ) break; |
︙ | ︙ |
Changes to test/copy.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the COPY statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the COPY statement. # # $Id: copy.test,v 1.12 2002/07/30 17:20:41 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a file of data from which to copy. # set f [open data1.txt w] |
︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 | puts $f "11 | 22 | 33" puts $f "22 | 33 | 11" close $f set f [open data5.txt w] puts $f "11|22|33" puts $f "22|33|11" close $f # Try to COPY into a non-existant table. # do_test copy-1.1 { set v [catch {execsql {COPY test1 FROM 'data1.txt'}} msg] lappend v $msg } {1 {no such table: test1}} | > > > > > > > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | puts $f "11 | 22 | 33" puts $f "22 | 33 | 11" close $f set f [open data5.txt w] puts $f "11|22|33" puts $f "22|33|11" close $f set f [open dataX.txt w] puts -nonewline $f "11|22|33\r" puts -nonewline $f "22|33|44\r\n" puts -nonewline $f "33|44|55\n" puts -nonewline $f "44|55|66\r" puts -nonewline $f "55|66|77\r\n" puts -nonewline $f "66|77|88\n" close $f # Try to COPY into a non-existant table. # do_test copy-1.1 { set v [catch {execsql {COPY test1 FROM 'data1.txt'}} msg] lappend v $msg } {1 {no such table: test1}} |
︙ | ︙ | |||
222 223 224 225 226 227 228 | } {2} do_test copy-5.7 { execsql { COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|'; } } {0} | > > > > > > > > > | | > | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | } {2} do_test copy-5.7 { execsql { COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|'; } } {0} do_test copy-6.1 { execsql { PRAGMA count_changes=off; CREATE TABLE t2(a,b,c); COPY t2 FROM 'dataX.txt' USING DELIMITERS '|'; SELECT * FROM t2; } } {11 22 33 22 33 44 33 44 55 44 55 66 55 66 77 66 77 88} integrity_check copy-7.1 # Cleanup # file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt \ data6.txt dataX.txt finish_test |