Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge the latest trunk changes into uri branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | uri |
Files: | files | file ages | folders |
SHA1: |
7fdd0786c7e0d66baf3aba4485128e16 |
User & Date: | dan 2011-05-02 17:41:01.076 |
Context
2011-05-03
| ||
10:22 | Change the supported URI options to "mode" and "cache". (check-in: 0a694a0b27 user: dan tags: uri) | |
2011-05-02
| ||
17:41 | Merge the latest trunk changes into uri branch. (check-in: 7fdd0786c7 user: dan tags: uri) | |
2011-04-27
| ||
19:54 | In windows, ignore ERROR_NOT_LOCKED when calling the read-lock removal routine. (check-in: f55156c519 user: drh tags: trunk) | |
2011-04-23
| ||
19:06 | Test that it is now possible to use different VFSs for two databases attached to a single handle. (check-in: 2af51f856c user: dan tags: uri) | |
Changes
Changes to src/func.c.
︙ | ︙ | |||
769 770 771 772 773 774 775 776 777 778 779 780 781 782 | sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); /* IMP: R-24470-31136 This function is an SQL wrapper around the ** sqlite3_sourceid() C interface. */ sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); } /* ** Implementation of the sqlite_compileoption_used() function. ** The result is an integer that identifies if the compiler option ** was used to build SQLite. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS | > > > > > > > > > > > > > > > | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 | sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); /* IMP: R-24470-31136 This function is an SQL wrapper around the ** sqlite3_sourceid() C interface. */ sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); } /* ** Implementation of the sqlite_log() function. This is a wrapper around ** sqlite3_log(). The return value is NULL. The function exists purely for ** its side-effects. */ static void errlogFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ UNUSED_PARAMETER(argc); UNUSED_PARAMETER(context); sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); } /* ** Implementation of the sqlite_compileoption_used() function. ** The result is an integer that identifies if the compiler option ** was used to build SQLite. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS |
︙ | ︙ | |||
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | /* FUNCTION(ifnull, 2, 0, 0, ifnullFunc ), */ {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0}, FUNCTION(random, 0, 0, 0, randomFunc ), FUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ FUNCTION(quote, 1, 0, 0, quoteFunc ), FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), FUNCTION(changes, 0, 0, 0, changes ), | > | 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | /* FUNCTION(ifnull, 2, 0, 0, ifnullFunc ), */ {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0}, FUNCTION(random, 0, 0, 0, randomFunc ), FUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ FUNCTION(quote, 1, 0, 0, quoteFunc ), FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), FUNCTION(changes, 0, 0, 0, changes ), |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 | return 0; /* pDestIdx has no corresponding index in pSrc */ } } #ifndef SQLITE_OMIT_CHECK if( pDest->pCheck && sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif /* If we get this far, it means either: ** ** * We can always do the transfer if the table contains an ** an integer primary key ** | > > > > > > > > > > > > | 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 | return 0; /* pDestIdx has no corresponding index in pSrc */ } } #ifndef SQLITE_OMIT_CHECK if( pDest->pCheck && sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif #ifndef SQLITE_OMIT_FOREIGN_KEY /* Disallow the transfer optimization if the destination table constains ** any foreign key constraints. This is more restrictive than necessary. ** But the main beneficiary of the transfer optimization is the VACUUM ** command, and the VACUUM command disables foreign key constraints. So ** the extra complication to make this rule less restrictive is probably ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] */ if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ return 0; } #endif /* If we get this far, it means either: ** ** * We can always do the transfer if the table contains an ** an integer primary key ** |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | ** testing and debugging only. */ #if SQLITE_THREADSAFE #define threadid pthread_self() #else #define threadid 0 #endif /* ** Many system calls are accessed through pointer-to-functions so that ** they may be overridden at runtime to facilitate fault injection during ** testing and sandboxing. The following array holds the names and pointers ** to all overrideable system calls. */ static struct unix_syscall { const char *zName; /* Name of the sytem call */ sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ sqlite3_syscall_ptr pDefault; /* Default value */ } aSyscall[] = { | > > > > > > > > > > > > | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | ** testing and debugging only. */ #if SQLITE_THREADSAFE #define threadid pthread_self() #else #define threadid 0 #endif /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). ** The difference is important when using a pointer to the function. ** ** The safest way to deal with the problem is to always use this wrapper ** which always has the same well-defined interface. */ static int posixOpen(const char *zFile, int flags, int mode){ return open(zFile, flags, mode); } /* ** Many system calls are accessed through pointer-to-functions so that ** they may be overridden at runtime to facilitate fault injection during ** testing and sandboxing. The following array holds the names and pointers ** to all overrideable system calls. */ static struct unix_syscall { const char *zName; /* Name of the sytem call */ sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ sqlite3_syscall_ptr pDefault; /* Default value */ } aSyscall[] = { { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, #define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) { "close", (sqlite3_syscall_ptr)close, 0 }, #define osClose ((int(*)(int))aSyscall[1].pCurrent) { "access", (sqlite3_syscall_ptr)access, 0 }, #define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
282 283 284 285 286 287 288 | return zFilenameUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from malloc(). */ | | | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | return zFilenameUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from malloc(). */ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ char *zFilenameMbcs; WCHAR *zTmpWide; zTmpWide = utf8ToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); #endif } | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); #endif } if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){ pFile->lastErrno = GetLastError(); winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath); } return res; } /* |
︙ | ︙ | |||
2000 2001 2002 2003 2004 2005 2006 | void *zConverted = 0; if( isNT() ){ zConverted = utf8ToUnicode(zFilename); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ | | | 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 | void *zConverted = 0; if( isNT() ){ zConverted = utf8ToUnicode(zFilename); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); #endif } /* caller will handle out of memory */ return zConverted; } /* |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2925 2926 2927 2928 2929 2930 2931 | mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ /* Compilers may complain that mem1.u.i is potentially uninitialized. ** We could initialize it, as shown here, to silence those complaints. | | | 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 | mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ /* Compilers may complain that mem1.u.i is potentially uninitialized. ** We could initialize it, as shown here, to silence those complaints. ** But in fact, mem1.u.i will never actually be used uninitialized, and doing ** the unnecessary initialization has a measurable negative performance ** impact, since this routine is a very high runner. And so, we choose ** to ignore the compiler warnings and leave this variable uninitialized. */ /* mem1.u.i = 0; // not needed, here to silence compiler warning */ idx1 = getVarint32(aKey1, szHdr1); |
︙ | ︙ |
Changes to test/insert4.test.
︙ | ︙ | |||
321 322 323 324 325 326 327 328 329 | DROP TABLE t6b; CREATE TABLE t6b(x CHECK( x COLLATE nocase <>'abc' )); } catchsql { INSERT INTO t6b SELECT * FROM t6a; } } {1 {constraint failed}} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | DROP TABLE t6b; CREATE TABLE t6b(x CHECK( x COLLATE nocase <>'abc' )); } catchsql { INSERT INTO t6b SELECT * FROM t6a; } } {1 {constraint failed}} # Ticket [6284df89debdfa61db8073e062908af0c9b6118e] # Disable the xfer optimization if the destination table contains # a foreign key constraint # ifcapable foreignkey { do_test insert4-7.1 { set ::sqlite3_xferopt_count 0 execsql { CREATE TABLE t7a(x INTEGER PRIMARY KEY); INSERT INTO t7a VALUES(123); CREATE TABLE t7b(y INTEGER REFERENCES t7a); CREATE TABLE t7c(z INT); INSERT INTO t7c VALUES(234); INSERT INTO t7b SELECT * FROM t7c; SELECT * FROM t7b; } } {234} do_test insert4-7.2 { set ::sqlite3_xferopt_count } {1} do_test insert4-7.3 { set ::sqlite3_xferopt_count 0 execsql { DELETE FROM t7b; PRAGMA foreign_keys=ON; } catchsql { INSERT INTO t7b SELECT * FROM t7c; } } {1 {foreign key constraint failed}} do_test insert4-7.4 { execsql {SELECT * FROM t7b} } {} do_test insert4-7.5 { set ::sqlite3_xferopt_count } {0} do_test insert4-7.6 { set ::sqlite3_xferopt_count 0 execsql { DELETE FROM t7b; DELETE FROM t7c; INSERT INTO t7c VALUES(123); INSERT INTO t7b SELECT * FROM t7c; SELECT * FROM t7b; } } {123} do_test insert4-7.7 { set ::sqlite3_xferopt_count } {0} do_test insert4-7.7 { set ::sqlite3_xferopt_count 0 execsql { PRAGMA foreign_keys=OFF; DELETE FROM t7b; INSERT INTO t7b SELECT * FROM t7c; SELECT * FROM t7b; } } {123} do_test insert4-7.8 { set ::sqlite3_xferopt_count } {1} } finish_test |
Added tool/getlock.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | /* ** This utility program looks at an SQLite database and determines whether ** or not it is locked, the kind of lock, and who is holding this lock. ** ** This only works on unix when the posix advisory locking method is used ** (which is the default on unix) and when the PENDING_BYTE is in its ** usual place. */ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> static void usage(const char *argv0){ fprintf(stderr, "Usage: %s database\n", argv0); exit(1); } /* Check for a conflicting lock. If one is found, print an this ** on standard output using the format string given and return 1. ** If there are no conflicting locks, return 0. */ static int isLocked( int h, /* File descriptor to check */ int type, /* F_RDLCK or F_WRLCK */ unsigned int iOfst, /* First byte of the lock */ unsigned int iCnt, /* Number of bytes in the lock range */ const char *zType /* Type of lock */ ){ struct flock lk; memset(&lk, 0, sizeof(lk)); lk.l_type = type; lk.l_whence = SEEK_SET; lk.l_start = iOfst; lk.l_len = iCnt; if( fcntl(h, F_GETLK, &lk)==(-1) ){ fprintf(stderr, "fcntl(%d) failed: errno=%d\n", h, errno); exit(1); } if( lk.l_type==F_UNLCK ) return 0; printf("%s lock held by %d\n", zType, (int)lk.l_pid); return 1; } /* ** Location of locking bytes in the database file */ #define PENDING_BYTE (0x40000000) #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 /* ** Lock locations for shared-memory locks used by WAL mode. */ #define SHM_BASE 120 #define SHM_WRITE SHM_BASE #define SHM_CHECKPOINT (SHM_BASE+1) #define SHM_RECOVER (SHM_BASE+2) #define SHM_READ_FIRST (SHM_BASE+3) #define SHM_READ_SIZE 5 int main(int argc, char **argv){ int hDb; /* File descriptor for the open database file */ int hShm; /* File descriptor for WAL shared-memory file */ char *zShm; /* Name of the shared-memory file for WAL mode */ ssize_t got; /* Bytes read from header */ int isWal; /* True if in WAL mode */ int nName; /* Length of filename */ unsigned char aHdr[100]; /* Database header */ int nLock = 0; /* Number of locks held */ int i; /* Loop counter */ if( argc!=2 ) usage(argv[0]); hDb = open(argv[1], O_RDONLY, 0); if( hDb<0 ){ fprintf(stderr, "cannot open %s\n", argv[1]); return 1; } /* Make sure we are dealing with an database file */ got = read(hDb, aHdr, 100); if( got!=100 || memcmp(aHdr, "SQLite format 3",16)!=0 ){ fprintf(stderr, "not an SQLite database: %s\n", argv[1]); exit(1); } /* First check for an exclusive lock */ if( isLocked(hDb, F_RDLCK, SHARED_FIRST, SHARED_SIZE, "EXCLUSIVE") ){ return 0; } isWal = aHdr[18]==2; if( isWal==0 ){ /* Rollback mode */ if( isLocked(hDb, F_RDLCK, PENDING_BYTE, 1, "PENDING") ) return 0; if( isLocked(hDb, F_RDLCK, RESERVED_BYTE, 1, "RESERVED") ) return 0; if( isLocked(hDb, F_WRLCK, SHARED_FIRST, SHARED_SIZE, "SHARED") ){ return 0; } }else{ /* WAL mode */ nName = (int)strlen(argv[1]); zShm = malloc( nName + 100 ); if( zShm==0 ){ fprintf(stderr, "out of memory\n"); exit(1); } memcpy(zShm, argv[1], nName); memcpy(&zShm[nName], "-shm", 5); hShm = open(zShm, O_RDONLY, 0); if( hShm<0 ){ fprintf(stderr, "cannot open %s\n", zShm); return 1; } if( isLocked(hShm, F_RDLCK, SHM_RECOVER, 1, "WAL-RECOVERY") ){ return 0; } nLock += isLocked(hShm, F_RDLCK, SHM_CHECKPOINT, 1, "WAL-CHECKPOINT"); nLock += isLocked(hShm, F_RDLCK, SHM_WRITE, 1, "WAL-WRITE"); for(i=0; i<SHM_READ_SIZE; i++){ nLock += isLocked(hShm, F_WRLCK, SHM_READ_FIRST+i, 1, "WAL-READ"); } } if( nLock==0 ){ printf("file is not locked\n"); } return 0; } |
Changes to tool/shell1.test.
︙ | ︙ | |||
707 708 709 710 711 712 713 714 | catchcmd "test.db" ".timer OFF" } {0 {}} do_test shell1-3.27.4 { # too many arguments catchcmd "test.db" ".timer OFF BAD" } {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} puts "CLI tests completed successfully" | > > > > > | 707 708 709 710 711 712 713 714 715 716 717 718 719 | catchcmd "test.db" ".timer OFF" } {0 {}} do_test shell1-3.27.4 { # too many arguments catchcmd "test.db" ".timer OFF BAD" } {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} do_test shell1-3-28.1 { catchcmd test.db \ ".log stdout\nSELECT coalesce(sqlite_log(123,'hello'),'456');" } "0 {(123) hello\n456}" puts "CLI tests completed successfully" |