Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge in all trunk changes up through the 3.7.17 release. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | nextgen-query-plan-exp |
Files: | files | file ages | folders |
SHA1: |
14ab6675e5eab3761256a06dad23d2b1 |
User & Date: | drh 2013-05-20 15:14:42.009 |
Context
2013-05-21
| ||
15:52 | Work toward improving the NGQP's ability to optimize out ORDER BY clauses. (check-in: 67367f1e1f user: drh tags: nextgen-query-plan-exp) | |
2013-05-20
| ||
15:14 | Merge in all trunk changes up through the 3.7.17 release. (check-in: 14ab6675e5 user: drh tags: nextgen-query-plan-exp) | |
00:56 | Version 3.7.17 (check-in: 118a3b3569 user: drh tags: trunk, release, version-3.7.17) | |
2013-05-14
| ||
15:31 | First attempt to get ORDER BY optimization working in NGQP. (check-in: 9fe2029255 user: drh tags: nextgen-query-plan-exp) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
407 408 409 410 411 412 413 414 415 416 417 418 419 420 | $(TOP)/src/build.c \ $(TOP)/src/ctime.c \ $(TOP)/src/date.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ $(TOP)/src/insert.c \ $(TOP)/src/wal.c \ $(TOP)/src/mem5.c \ $(TOP)/src/os.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ $(TOP)/src/pragma.c \ $(TOP)/src/prepare.c \ | > | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | $(TOP)/src/build.c \ $(TOP)/src/ctime.c \ $(TOP)/src/date.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ $(TOP)/src/insert.c \ $(TOP)/src/wal.c \ $(TOP)/src/main.c \ $(TOP)/src/mem5.c \ $(TOP)/src/os.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ $(TOP)/src/pragma.c \ $(TOP)/src/prepare.c \ |
︙ | ︙ | |||
865 866 867 868 869 870 871 | fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c fts3_tokenizer1.lo: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c | | | | 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 | fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c fts3_tokenizer1.lo: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c fts3_tokenize_vtab.lo: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c fts3_unicode.lo: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c fts3_unicode2.lo: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
728 729 730 731 732 733 734 735 736 737 738 739 740 741 | $(TOP)\src\build.c \ $(TOP)\src\ctime.c \ $(TOP)\src\date.c \ $(TOP)\src\expr.c \ $(TOP)\src\func.c \ $(TOP)\src\insert.c \ $(TOP)\src\wal.c \ $(TOP)\src\mem5.c \ $(TOP)\src\os.c \ $(TOP)\src\os_unix.c \ $(TOP)\src\os_win.c \ $(TOP)\src\pager.c \ $(TOP)\src\pragma.c \ $(TOP)\src\prepare.c \ | > | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | $(TOP)\src\build.c \ $(TOP)\src\ctime.c \ $(TOP)\src\date.c \ $(TOP)\src\expr.c \ $(TOP)\src\func.c \ $(TOP)\src\insert.c \ $(TOP)\src\wal.c \ $(TOP)\src\main.c \ $(TOP)\src\mem5.c \ $(TOP)\src\os.c \ $(TOP)\src\os_unix.c \ $(TOP)\src\os_win.c \ $(TOP)\src\pager.c \ $(TOP)\src\pragma.c \ $(TOP)\src\prepare.c \ |
︙ | ︙ |
Changes to ext/misc/amatch.c.
︙ | ︙ | |||
160 161 162 163 164 165 166 167 168 169 170 171 172 173 | SQLITE_EXTENSION_INIT1 #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdio.h> #include <ctype.h> /* ** Forward declaration of objects used by this implementation */ typedef struct amatch_vtab amatch_vtab; typedef struct amatch_cursor amatch_cursor; typedef struct amatch_rule amatch_rule; typedef struct amatch_word amatch_word; | > > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | SQLITE_EXTENSION_INIT1 #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Forward declaration of objects used by this implementation */ typedef struct amatch_vtab amatch_vtab; typedef struct amatch_cursor amatch_cursor; typedef struct amatch_rule amatch_rule; typedef struct amatch_word amatch_word; |
︙ | ︙ | |||
1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 | 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0 /* xRollbackTo */ }; /* ** Register the amatch virtual table */ #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_amatch_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Not used */ rc = sqlite3_create_module(db, "approximate_match", &amatchModule, 0); return rc; } | > > > > | 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0 /* xRollbackTo */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Register the amatch virtual table */ #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_amatch_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Not used */ #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "approximate_match", &amatchModule, 0); #endif /* SQLITE_OMIT_VIRTUALTABLE */ return rc; } |
Changes to ext/misc/closure.c.
︙ | ︙ | |||
144 145 146 147 148 149 150 151 152 153 154 155 156 157 | SQLITE_EXTENSION_INIT1 #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdio.h> #include <ctype.h> /* ** Forward declaration of objects used by this implementation */ typedef struct closure_vtab closure_vtab; typedef struct closure_cursor closure_cursor; typedef struct closure_queue closure_queue; typedef struct closure_avl closure_avl; | > > | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | SQLITE_EXTENSION_INIT1 #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Forward declaration of objects used by this implementation */ typedef struct closure_vtab closure_vtab; typedef struct closure_cursor closure_cursor; typedef struct closure_queue closure_queue; typedef struct closure_avl closure_avl; |
︙ | ︙ | |||
289 290 291 292 293 294 295 | p = p->pUp; } if( p && pPrev==0 ){ p = closureAvlFirst(p->pAfter); } return p; } | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | p = p->pUp; } if( p && pPrev==0 ){ p = closureAvlFirst(p->pAfter); } return p; } /* Insert a new node pNew. Return NULL on success. If the key is not ** unique, then do not perform the insert but instead leave pNew unchanged ** and return a pointer to an existing node with the same key. */ static closure_avl *closureAvlInsert( closure_avl **ppHead, /* Head of the tree */ closure_avl *pNew /* New node to be inserted */ |
︙ | ︙ | |||
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 | 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0 /* xRollbackTo */ }; /* ** Register the closure virtual table */ #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_closure_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; rc = sqlite3_create_module(db, "transitive_closure", &closureModule, 0); return rc; } | > > > > | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 | 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0 /* xRollbackTo */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Register the closure virtual table */ #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_closure_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "transitive_closure", &closureModule, 0); #endif /* SQLITE_OMIT_VIRTUALTABLE */ return rc; } |
Changes to ext/misc/fuzzer.c.
︙ | ︙ | |||
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 | int sqlite3_fuzzer_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); rc = sqlite3_create_module(db, "fuzzer", &fuzzerModule, 0); return rc; } | > > | 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 | int sqlite3_fuzzer_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "fuzzer", &fuzzerModule, 0); #endif return rc; } |
Added ext/misc/rot13.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 | /* ** 2013-05-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 SQLite extension implements a rot13() function and a rot13 ** collating sequence. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> /* ** Perform rot13 encoding on a single ASCII character. */ static unsigned char rot13(unsigned char c){ if( c>='a' && c<='z' ){ c += 13; if( c>'z' ) c -= 26; }else if( c>='A' && c<='Z' ){ c += 13; if( c>'Z' ) c -= 26; } return c; } /* ** Implementation of the rot13() function. ** ** Rotate ASCII alphabetic characters by 13 character positions. ** Non-ASCII characters are unchanged. rot13(rot13(X)) should always ** equal X. */ static void rot13func( sqlite3_context *context, int argc, sqlite3_value **argv ){ const unsigned char *zIn; int nIn; unsigned char *zOut; char *zToFree = 0; int i; char zTemp[100]; assert( argc==1 ); if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; zIn = (const unsigned char*)sqlite3_value_text(argv[0]); nIn = sqlite3_value_bytes(argv[0]); if( nIn<sizeof(zTemp)-1 ){ zOut = zTemp; }else{ zOut = zToFree = sqlite3_malloc( nIn+1 ); if( zOut==0 ){ sqlite3_result_error_nomem(context); return; } } for(i=0; i<nIn; i++) zOut[i] = rot13(zIn[i]); zOut[i] = 0; sqlite3_result_text(context, (char*)zOut, i, SQLITE_TRANSIENT); sqlite3_free(zToFree); } /* ** Implement the rot13 collating sequence so that if ** ** x=y COLLATE rot13 ** ** Then ** ** rot13(x)=rot13(y) COLLATE binary */ static int rot13CollFunc( void *notUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ const char *zA = (const char*)pKey1; const char *zB = (const char*)pKey2; int i, x; for(i=0; i<nKey1 && i<nKey2; i++){ x = (int)rot13(zA[i]) - (int)rot13(zB[i]); if( x!=0 ) return x; } return nKey1 - nKey2; } #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_rot_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ rc = sqlite3_create_function(db, "rot13", 1, SQLITE_UTF8, 0, rot13func, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc); } return rc; } |
Changes to ext/misc/spellfix.c.
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # define ALWAYS(X) 1 # define NEVER(X) 0 typedef unsigned char u8; typedef unsigned short u16; # include <ctype.h> #endif /* ** Character classes for ASCII characters: ** ** 0 '' Silent letters: H W ** 1 'A' Any vowel: A E I O U (Y) ** 2 'B' A bilabeal stop or fricative: B F P V W ** 3 'C' Other fricatives or back stops: C G J K Q S X Z | > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # define ALWAYS(X) 1 # define NEVER(X) 0 typedef unsigned char u8; typedef unsigned short u16; # include <ctype.h> #endif #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Character classes for ASCII characters: ** ** 0 '' Silent letters: H W ** 1 'A' Any vowel: A E I O U (Y) ** 2 'B' A bilabeal stop or fricative: B F P V W ** 3 'C' Other fricatives or back stops: C G J K Q S X Z |
︙ | ︙ | |||
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 | for(i=0; i<sizeof(translit)/sizeof(translit[0])-1; i++){ assert( translit[i].cFrom<translit[i+1].cFrom ); } return rc; } /* ** Extension load function. */ #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_spellfix_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); return spellfix1Register(db); } | > > > > > | 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 | for(i=0; i<sizeof(translit)/sizeof(translit[0])-1; i++){ assert( translit[i].cFrom<translit[i+1].cFrom ); } return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Extension load function. */ #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_spellfix_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE return spellfix1Register(db); #endif return SQLITE_OK; } |
Changes to main.mk.
︙ | ︙ | |||
289 290 291 292 293 294 295 296 297 298 299 300 301 302 | $(TOP)/src/btree.c \ $(TOP)/src/build.c \ $(TOP)/src/date.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ $(TOP)/src/insert.c \ $(TOP)/src/wal.c \ $(TOP)/src/mem5.c \ $(TOP)/src/os.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ $(TOP)/src/pragma.c \ $(TOP)/src/prepare.c \ | > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | $(TOP)/src/btree.c \ $(TOP)/src/build.c \ $(TOP)/src/date.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ $(TOP)/src/insert.c \ $(TOP)/src/wal.c \ $(TOP)/src/main.c \ $(TOP)/src/mem5.c \ $(TOP)/src/os.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ $(TOP)/src/pragma.c \ $(TOP)/src/prepare.c \ |
︙ | ︙ |
Changes to mptest/crash01.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 | INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1; SELECT count(*) FROM t1; --match 64 SELECT avg(length(b)) FROM t1; --match 1500.0 --sleep 2 UPDATE t1 SET b='x'||a||'y'; | | | | | | | 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 | INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1; SELECT count(*) FROM t1; --match 64 SELECT avg(length(b)) FROM t1; --match 1500.0 --sleep 2 UPDATE t1 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t1; --match 247 SELECT a FROM t1 WHERE b='x17y'; --match 17 CREATE INDEX t1b ON t1(b); SELECT a FROM t1 WHERE b='x17y'; --match 17 SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; --match 29 28 27 26 25 --end --wait 1 --task 2 CREATE TABLE t2(a INTEGER PRIMARY KEY, b); INSERT INTO t2 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t2; --match 247 SELECT a FROM t2 WHERE b='x17y'; --match 17 CREATE INDEX t2b ON t2(b); SELECT a FROM t2 WHERE b='x17y'; --match 17 SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; --match 29 28 27 26 25 --end --task 3 CREATE TABLE t3(a INTEGER PRIMARY KEY, b); INSERT INTO t3 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t3; --match 247 SELECT a FROM t3 WHERE b='x17y'; --match 17 CREATE INDEX t3b ON t3(b); SELECT a FROM t3 WHERE b='x17y'; --match 17 SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; --match 29 28 27 26 25 --end --task 4 CREATE TABLE t4(a INTEGER PRIMARY KEY, b); INSERT INTO t4 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t4; --match 247 SELECT a FROM t4 WHERE b='x17y'; --match 17 CREATE INDEX t4b ON t4(b); SELECT a FROM t4 WHERE b='x17y'; --match 17 SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; --match 29 28 27 26 25 --end --task 5 CREATE TABLE t5(a INTEGER PRIMARY KEY, b); INSERT INTO t5 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t5; --match 247 SELECT a FROM t5 WHERE b='x17y'; --match 17 CREATE INDEX t5b ON t5(b); SELECT a FROM t5 WHERE b='x17y'; --match 17 SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; |
︙ | ︙ |
Changes to mptest/multiwrite01.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 | INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1; SELECT count(*) FROM t1; --match 64 SELECT avg(length(b)) FROM t1; --match 1500.0 --sleep 2 UPDATE t1 SET b='x'||a||'y'; | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1; SELECT count(*) FROM t1; --match 64 SELECT avg(length(b)) FROM t1; --match 1500.0 --sleep 2 UPDATE t1 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t1; --match 247 SELECT a FROM t1 WHERE b='x17y'; --match 17 CREATE INDEX t1b ON t1(b); SELECT a FROM t1 WHERE b='x17y'; --match 17 SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; |
︙ | ︙ | |||
50 51 52 53 54 55 56 | INSERT INTO t2 SELECT a+32, randomblob(1500) FROM t2; SELECT count(*) FROM t2; --match 64 SELECT avg(length(b)) FROM t2; --match 1500.0 --sleep 2 UPDATE t2 SET b='x'||a||'y'; | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | INSERT INTO t2 SELECT a+32, randomblob(1500) FROM t2; SELECT count(*) FROM t2; --match 64 SELECT avg(length(b)) FROM t2; --match 1500.0 --sleep 2 UPDATE t2 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t2; --match 247 SELECT a FROM t2 WHERE b='x17y'; --match 17 CREATE INDEX t2b ON t2(b); SELECT a FROM t2 WHERE b='x17y'; --match 17 SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; |
︙ | ︙ | |||
81 82 83 84 85 86 87 | INSERT INTO t3 SELECT a+32, randomblob(1500) FROM t3; SELECT count(*) FROM t3; --match 64 SELECT avg(length(b)) FROM t3; --match 1500.0 --sleep 2 UPDATE t3 SET b='x'||a||'y'; | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | INSERT INTO t3 SELECT a+32, randomblob(1500) FROM t3; SELECT count(*) FROM t3; --match 64 SELECT avg(length(b)) FROM t3; --match 1500.0 --sleep 2 UPDATE t3 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t3; --match 247 SELECT a FROM t3 WHERE b='x17y'; --match 17 CREATE INDEX t3b ON t3(b); SELECT a FROM t3 WHERE b='x17y'; --match 17 SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; |
︙ | ︙ | |||
112 113 114 115 116 117 118 | INSERT INTO t4 SELECT a+32, randomblob(1500) FROM t4; SELECT count(*) FROM t4; --match 64 SELECT avg(length(b)) FROM t4; --match 1500.0 --sleep 2 UPDATE t4 SET b='x'||a||'y'; | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | INSERT INTO t4 SELECT a+32, randomblob(1500) FROM t4; SELECT count(*) FROM t4; --match 64 SELECT avg(length(b)) FROM t4; --match 1500.0 --sleep 2 UPDATE t4 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t4; --match 247 SELECT a FROM t4 WHERE b='x17y'; --match 17 CREATE INDEX t4b ON t4(b); SELECT a FROM t4 WHERE b='x17y'; --match 17 SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; |
︙ | ︙ | |||
143 144 145 146 147 148 149 | INSERT INTO t5 SELECT a+32, randomblob(1500) FROM t5; SELECT count(*) FROM t5; --match 64 SELECT avg(length(b)) FROM t5; --match 1500.0 --sleep 2 UPDATE t5 SET b='x'||a||'y'; | | | | | | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | INSERT INTO t5 SELECT a+32, randomblob(1500) FROM t5; SELECT count(*) FROM t5; --match 64 SELECT avg(length(b)) FROM t5; --match 1500.0 --sleep 2 UPDATE t5 SET b='x'||a||'y'; SELECT sum(length(b)) FROM t5; --match 247 SELECT a FROM t5 WHERE b='x17y'; --match 17 CREATE INDEX t5b ON t5(b); SELECT a FROM t5 WHERE b='x17y'; --match 17 SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5; --match 29 28 27 26 25 --end --wait all SELECT count(*), sum(length(b)) FROM t1; --match 64 247 SELECT count(*), sum(length(b)) FROM t2; --match 64 247 SELECT count(*), sum(length(b)) FROM t3; --match 64 247 SELECT count(*), sum(length(b)) FROM t4; --match 64 247 SELECT count(*), sum(length(b)) FROM t5; --match 64 247 --task 1 SELECT t1.a FROM t1, t2 WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y') ORDER BY t1.a LIMIT 4 --match 33 34 35 36 |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 | page1_init_failed: releasePage(pPage1); pBt->pPage1 = 0; return rc; } /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then ** this routine unrefs the first page of the database file which ** has the effect of releasing the read lock. ** ** If there is a transaction in progress, this routine is a no-op. */ static void unlockBtreeIfUnused(BtShared *pBt){ assert( sqlite3_mutex_held(pBt->mutex) ); | > > > > > > > > > > > > > > > > > > > > > > > | | 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 | page1_init_failed: releasePage(pPage1); pBt->pPage1 = 0; return rc; } #ifndef NDEBUG /* ** Return the number of cursors open on pBt. This is for use ** in assert() expressions, so it is only compiled if NDEBUG is not ** defined. ** ** Only write cursors are counted if wrOnly is true. If wrOnly is ** false then all cursors are counted. ** ** For the purposes of this routine, a cursor is any cursor that ** is capable of reading or writing to the databse. Cursors that ** have been tripped into the CURSOR_FAULT state are not counted. */ static int countValidCursors(BtShared *pBt, int wrOnly){ BtCursor *pCur; int r = 0; for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; } return r; } #endif /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then ** this routine unrefs the first page of the database file which ** has the effect of releasing the read lock. ** ** If there is a transaction in progress, this routine is a no-op. */ static void unlockBtreeIfUnused(BtShared *pBt){ assert( sqlite3_mutex_held(pBt->mutex) ); assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ assert( pBt->pPage1->aData ); assert( sqlite3PagerRefcount(pBt->pPager)==1 ); assert( pBt->pPage1->aData ); releasePage(pBt->pPage1); pBt->pPage1 = 0; } |
︙ | ︙ | |||
3251 3252 3253 3254 3255 3256 3257 | static void btreeEndTransaction(Btree *p){ BtShared *pBt = p->pBt; assert( sqlite3BtreeHoldsMutex(p) ); #ifndef SQLITE_OMIT_AUTOVACUUM pBt->bDoTruncate = 0; #endif | < | 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 | static void btreeEndTransaction(Btree *p){ BtShared *pBt = p->pBt; assert( sqlite3BtreeHoldsMutex(p) ); #ifndef SQLITE_OMIT_AUTOVACUUM pBt->bDoTruncate = 0; #endif if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ /* If there are other active statements that belong to this database ** handle, downgrade to a read-only transaction. The other statements ** may still be reading from the database. */ downgradeAllSharedCacheTableLocks(p); p->inTrans = TRANS_READ; }else{ |
︙ | ︙ | |||
3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 | assert( pBt->nTransaction>0 ); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } pBt->inTransaction = TRANS_READ; } btreeEndTransaction(p); sqlite3BtreeLeave(p); return SQLITE_OK; } | > | 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 | assert( pBt->nTransaction>0 ); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); } btreeEndTransaction(p); sqlite3BtreeLeave(p); return SQLITE_OK; } |
︙ | ︙ | |||
3347 3348 3349 3350 3351 3352 3353 | if( rc==SQLITE_OK ){ rc = sqlite3BtreeCommitPhaseTwo(p, 0); } sqlite3BtreeLeave(p); return rc; } | < < < < < < < < < < < < < < < < < < < < < | 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 | if( rc==SQLITE_OK ){ rc = sqlite3BtreeCommitPhaseTwo(p, 0); } sqlite3BtreeLeave(p); return rc; } /* ** This routine sets the state to CURSOR_FAULT and the error ** code to errCode for every cursor on BtShared that pBtree ** references. ** ** Every cursor is tripped, including cursors that belong ** to other database connections that happen to be sharing |
︙ | ︙ | |||
3447 3448 3449 3450 3451 3452 3453 | int nPage = get4byte(28+(u8*)pPage1->aData); testcase( nPage==0 ); if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); testcase( pBt->nPage!=nPage ); pBt->nPage = nPage; releasePage(pPage1); } | | > | 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 | int nPage = get4byte(28+(u8*)pPage1->aData); testcase( nPage==0 ); if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); testcase( pBt->nPage!=nPage ); pBt->nPage = nPage; releasePage(pPage1); } assert( countValidCursors(pBt, 1)==0 ); pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); } btreeEndTransaction(p); sqlite3BtreeLeave(p); return rc; } |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
2655 2656 2657 2658 2659 2660 2661 | /* Figure out how many bytes of space are required to store explicitly ** specified collation sequence names. */ for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr ){ | | < | < | 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 | /* Figure out how many bytes of space are required to store explicitly ** specified collation sequence names. */ for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr ){ assert( pExpr->op==TK_COLLATE ); nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); } } /* ** Allocate the index structure. */ nName = sqlite3Strlen30(zName); |
︙ | ︙ | |||
2719 2720 2721 2722 2723 2724 2725 | ** same column more than once cannot be an error because that would ** break backwards compatibility - it needs to be a warning. */ for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; | < | < < > | | < < | 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 | ** same column more than once cannot be an error because that would ** break backwards compatibility - it needs to be a warning. */ for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; char *zColl; /* Collation sequence name */ for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; } if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); pParse->checkSchema = 1; goto exit_create_index; } pIndex->aiColumn[i] = j; if( pListItem->pExpr ){ int nColl; assert( pListItem->pExpr->op==TK_COLLATE ); zColl = pListItem->pExpr->u.zToken; nColl = sqlite3Strlen30(zColl) + 1; assert( nExtra>=nColl ); memcpy(zExtra, zColl, nColl); zColl = zExtra; zExtra += nColl; nExtra -= nColl; }else{ zColl = pTab->aCol[j].zColl; if( !zColl ) zColl = "BINARY"; } if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; } pIndex->azColl[i] = zColl; requestedSortOrder = pListItem->sortOrder & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
112 113 114 115 116 117 118 | int op = p->op; if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; } assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); if( op==TK_COLLATE ){ | < < < < | < | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | int op = p->op; if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; } assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); if( op==TK_COLLATE ){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } if( p->pTab!=0 && (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER) ){ /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
897 898 899 900 901 902 903 904 905 906 907 908 909 910 | } /* If we reach this point, it means that the database connection has ** closed all sqlite3_stmt and sqlite3_backup objects and has been ** passed to sqlite3_close (meaning that it is a zombie). Therefore, ** go ahead and free all resources. */ /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); /* Close all database connections */ for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; | > > > > > > | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 | } /* If we reach this point, it means that the database connection has ** closed all sqlite3_stmt and sqlite3_backup objects and has been ** passed to sqlite3_close (meaning that it is a zombie). Therefore, ** go ahead and free all resources. */ /* If a transaction is open, roll it back. This also ensures that if ** any database schemas have been modified by an uncommitted transaction ** they are reset. And that the required b-tree mutex is held to make ** the pager rollback and schema reset an atomic operation. */ sqlite3RollbackAll(db, SQLITE_OK); /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); /* Close all database connections */ for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; |
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 | ** attempts to use that cursor. */ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int i; int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); for(i=0; i<db->nDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ if( sqlite3BtreeIsInTrans(p) ){ inTrans = 1; } sqlite3BtreeRollback(p, tripCode); db->aDb[i].inTrans = 0; } } sqlite3VtabRollback(db); sqlite3EndBenignMalloc(); if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ sqlite3ExpirePreparedStatements(db); sqlite3ResetAllSchemasOfConnection(db); } /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ db->xRollbackCallback(db->pRollbackArg); | > > > > > > > > > > | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 | ** attempts to use that cursor. */ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int i; int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). ** This is important in case the transaction being rolled back has ** modified the database schema. If the b-tree mutexes are not taken ** here, then another shared-cache connection might sneak in between ** the database rollback and schema reset, which can cause false ** corruption reports in some cases. */ sqlite3BtreeEnterAll(db); for(i=0; i<db->nDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ if( sqlite3BtreeIsInTrans(p) ){ inTrans = 1; } sqlite3BtreeRollback(p, tripCode); db->aDb[i].inTrans = 0; } } sqlite3VtabRollback(db); sqlite3EndBenignMalloc(); if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ sqlite3ExpirePreparedStatements(db); sqlite3ResetAllSchemasOfConnection(db); } sqlite3BtreeLeaveAll(db); /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ db->xRollbackCallback(db->pRollbackArg); |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
5149 5150 5151 5152 5153 5154 5155 | assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; pNew->ctrlFlags = (u8)ctrlFlags; | | | 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 | assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; pNew->ctrlFlags = (u8)ctrlFlags; pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), "psow", SQLITE_POWERSAFE_OVERWRITE) ){ pNew->ctrlFlags |= UNIXFILE_PSOW; } if( strcmp(pVfs->zName,"unix-excl")==0 ){ pNew->ctrlFlags |= UNIXFILE_EXCL; } |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
2933 2934 2935 2936 2937 2938 2939 | */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } | < < > > | 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 | */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } /* ** Windows will only let you create file view mappings ** on allocation size granularity boundaries. ** During sqlite3_os_init() we do a GetSystemInfo() ** to get the granularity size. */ SYSTEM_INFO winSysInfo; #ifndef SQLITE_OMIT_WAL /* ** Helper functions to obtain and relinquish the global mutex. The ** global mutex is used to protect the winLockInfo objects used by ** this file, all of which may be shared by multiple threads. ** ** Function winShmMutexHeld() is used to assert() that the global mutex |
︙ | ︙ | |||
4242 4243 4244 4245 4246 4247 4248 | pFile->lastErrno = NO_ERROR; pFile->zPath = zName; #if SQLITE_MAX_MMAP_SIZE>0 pFile->hMap = NULL; pFile->pMapRegion = 0; pFile->mmapSize = 0; pFile->mmapSizeActual = 0; | | | 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 | pFile->lastErrno = NO_ERROR; pFile->zPath = zName; #if SQLITE_MAX_MMAP_SIZE>0 pFile->hMap = NULL; pFile->pMapRegion = 0; pFile->mmapSize = 0; pFile->mmapSizeActual = 0; pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; #endif OpenCounter(+1); return rc; } /* |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
1155 1156 1157 1158 1159 1160 1161 | ** expressions in the WHERE clause (etc.) can refer to expressions by ** aliases in the result set. ** ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ sNC.pEList = p->pEList; | < > | 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 | ** expressions in the WHERE clause (etc.) can refer to expressions by ** aliases in the result set. ** ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ sNC.pEList = p->pEList; sNC.ncFlags |= NC_AsMaybe; if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; sNC.ncFlags &= ~NC_AsMaybe; /* The ORDER BY and GROUP BY clauses may not refer to terms in ** outer queries */ sNC.pNext = 0; |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
676 677 678 679 680 681 682 683 684 685 686 687 688 689 | return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite3_close(db); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } /* ** Implementation of the x_coalesce() function. ** Return the first argument non-NULL argument. */ static void t1_ifnullFunc( sqlite3_context *context, | > > > > > > > > > > > > > > > > > > > > > > > > | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite3_close(db); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } /* ** Usage: sqlite3_close_v2 DB ** ** Closes the database opened by sqlite3_open. */ static int sqlite_test_close_v2( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite3 *db; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite3_close_v2(db); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } /* ** Implementation of the x_coalesce() function. ** Return the first argument non-NULL argument. */ static void t1_ifnullFunc( sqlite3_context *context, |
︙ | ︙ | |||
6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 | { "sqlite3_exec_hex", (Tcl_CmdProc*)test_exec_hex }, { "sqlite3_exec", (Tcl_CmdProc*)test_exec }, { "sqlite3_exec_nr", (Tcl_CmdProc*)test_exec_nr }, #ifndef SQLITE_OMIT_GET_TABLE { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, #endif { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, { "sqlite3_key", (Tcl_CmdProc*)test_key }, | > | 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 | { "sqlite3_exec_hex", (Tcl_CmdProc*)test_exec_hex }, { "sqlite3_exec", (Tcl_CmdProc*)test_exec }, { "sqlite3_exec_nr", (Tcl_CmdProc*)test_exec_nr }, #ifndef SQLITE_OMIT_GET_TABLE { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, #endif { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, { "sqlite3_key", (Tcl_CmdProc*)test_key }, |
︙ | ︙ |
Changes to src/test_syscall.c.
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 | ** Return true if the named system call exists. Or false otherwise. ** ** test_syscall list ** Return a list of all system calls. The list is constructed using ** the xNextSystemCall() VFS method. */ #include "sqlite3.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> | > < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ** Return true if the named system call exists. Or false otherwise. ** ** test_syscall list ** Return a list of all system calls. The list is constructed using ** the xNextSystemCall() VFS method. */ #include "sqliteInt.h" #include "sqlite3.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> #if SQLITE_OS_UNIX /* From main.c */ extern const char *sqlite3ErrName(int); #include <sys/mman.h> #include <sys/types.h> |
︙ | ︙ |
Changes to src/vdbetrace.c.
︙ | ︙ | |||
138 139 140 141 142 143 144 | sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); pVar = &utf8; } #endif nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT | | | | | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); pVar = &utf8; } #endif nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ nOut = SQLITE_TRACE_SIZE_LIMIT; while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); #endif #ifndef SQLITE_OMIT_UTF16 if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); #endif }else if( pVar->flags & MEM_Zero ){ sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); }else{ int nOut; /* Number of bytes of the blob to include in output */ assert( pVar->flags & MEM_Blob ); sqlite3StrAccumAppend(&out, "x'", 2); nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; #endif for(i=0; i<nOut; i++){ sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); } sqlite3StrAccumAppend(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); #endif } } } return sqlite3StrAccumFinish(&out); } |
︙ | ︙ |
Changes to test/btreefault.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # module. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set testprefix btreefault do_test 1-pre1 { execsql { PRAGMA auto_vacuum = incremental; PRAGMA journal_mode = DELETE; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(randomblob(1000), randomblob(100)); | > > > > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # module. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set testprefix btreefault # This test will not work with an in-memory journal, as the database will # become corrupt if an error is injected into a transaction after it starts # writing data out to the db file. if {[permutation]=="inmemory_journal"} { finish_test return } do_test 1-pre1 { execsql { PRAGMA auto_vacuum = incremental; PRAGMA journal_mode = DELETE; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(randomblob(1000), randomblob(100)); |
︙ | ︙ |
Added test/close.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | # 2013 May 14 # # 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. # #*********************************************************************** # # Test some specific circumstances to do with shared cache mode. # set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix close do_execsql_test 1.0 { CREATE TABLE t1(x); INSERT INTO t1 VALUES('one'); INSERT INTO t1 VALUES('two'); INSERT INTO t1 VALUES('three'); } db close do_test 1.1 { set DB [sqlite3_open test.db] sqlite3_close_v2 $DB } {SQLITE_OK} do_test 1.2.1 { set DB [sqlite3_open test.db] set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy] sqlite3_close_v2 $DB } {SQLITE_OK} do_test 1.2.2 { sqlite3_finalize $STMT } {SQLITE_OK} do_test 1.3.1 { set DB [sqlite3_open test.db] set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy] sqlite3_step $STMT sqlite3_close_v2 $DB } {SQLITE_OK} do_test 1.3.2 { sqlite3_column_text $STMT 0 } {one} do_test 1.3.3 { sqlite3_finalize $STMT } {SQLITE_OK} do_test 1.4.1 { set DB [sqlite3_open test.db] set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy] sqlite3_step $STMT sqlite3_close_v2 $DB } {SQLITE_OK} do_test 1.4.2 { list [sqlite3_step $STMT] [sqlite3_column_text $STMT 0] } {SQLITE_ROW two} do_test 1.4.3 { list [catch { sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 dummy } msg] $msg } {1 {(21) library routine called out of sequence}} do_test 1.4.4 { sqlite3_finalize $STMT } {SQLITE_OK} finish_test |
Changes to test/closure01.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #*********************************************************************** # # Test cases for transitive_closure virtual table. set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix closure01 load_static_extension db closure do_execsql_test 1.0 { BEGIN; CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER); CREATE INDEX t1y ON t1(y); | > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #*********************************************************************** # # Test cases for transitive_closure virtual table. set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix closure01 ifcapable !vtab { finish_test ; return } load_static_extension db closure do_execsql_test 1.0 { BEGIN; CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER); CREATE INDEX t1y ON t1(y); |
︙ | ︙ |
Changes to test/collate3.test.
︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 | CREATE INDEX collate3i1 ON collate3t1(c1 COLLATE garbage); } } {1 {no such collation sequence: garbage}} execsql { DROP TABLE collate3t1; } # # Create a table with a default collation sequence, then close # and re-open the database without re-registering the collation # sequence. Then make sure the library stops us from using # the collation sequence in: # * an explicitly collated ORDER BY | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | CREATE INDEX collate3i1 ON collate3t1(c1 COLLATE garbage); } } {1 {no such collation sequence: garbage}} execsql { DROP TABLE collate3t1; } proc caseless {a b} { string compare -nocase $a $b } do_test collate3-1.4 { db collate caseless caseless execsql { CREATE TABLE t1(a COLLATE caseless); INSERT INTO t1 VALUES('Abc2'); INSERT INTO t1 VALUES('abc1'); INSERT INTO t1 VALUES('aBc3'); } execsql { SELECT * FROM t1 ORDER BY a } } {abc1 Abc2 aBc3} do_test collate3-1.5 { db close sqlite3 db test.db catchsql { SELECT * FROM t1 ORDER BY a } } {1 {no such collation sequence: caseless}} do_test collate3-1.6.1 { db collate caseless caseless execsql { CREATE INDEX i1 ON t1(a) } execsql { SELECT * FROM t1 ORDER BY a } } {abc1 Abc2 aBc3} do_test collate3-1.6.2 { db close sqlite3 db test.db catchsql { SELECT * FROM t1 ORDER BY a } } {1 {no such collation sequence: caseless}} do_test collate3-1.6.3 { db close sqlite3 db test.db catchsql { PRAGMA integrity_check } } {1 {no such collation sequence: caseless}} do_test collate3-1.6.4 { db close sqlite3 db test.db catchsql { REINDEX } } {1 {no such collation sequence: caseless}} do_test collate3-1.7.1 { db collate caseless caseless execsql { DROP TABLE t1; CREATE TABLE t1(a); CREATE INDEX i1 ON t1(a COLLATE caseless); INSERT INTO t1 VALUES('Abc2'); INSERT INTO t1 VALUES('abc1'); INSERT INTO t1 VALUES('aBc3'); SELECT * FROM t1 ORDER BY a COLLATE caseless; } } {abc1 Abc2 aBc3} do_test collate3-1.7.2 { db close sqlite3 db test.db catchsql { SELECT * FROM t1 ORDER BY a COLLATE caseless} } {1 {no such collation sequence: caseless}} do_test collate3-1.7.4 { db close sqlite3 db test.db catchsql { REINDEX } } {1 {no such collation sequence: caseless}} do_test collate3-1.7.3 { db close sqlite3 db test.db catchsql { PRAGMA integrity_check } } {1 {no such collation sequence: caseless}} do_test collate3-1.7.4 { db close sqlite3 db test.db catchsql { REINDEX } } {1 {no such collation sequence: caseless}} do_test collate3-1.7.5 { db close sqlite3 db test.db db collate caseless caseless catchsql { PRAGMA integrity_check } } {0 ok} proc needed {nm} { db collate caseless caseless } do_test collate3-1.7.6 { db close sqlite3 db test.db db collation_needed needed catchsql { PRAGMA integrity_check } } {0 ok} do_test collate3-1.8 { execsql { DROP TABLE t1 } } {} # # Create a table with a default collation sequence, then close # and re-open the database without re-registering the collation # sequence. Then make sure the library stops us from using # the collation sequence in: # * an explicitly collated ORDER BY |
︙ | ︙ |
Changes to test/io.test.
︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 585 586 587 588 589 | db close sqlite3_simulate_device -char atomic forcedelete test.db sqlite3 db test.db -vfs devsym execsql { PRAGMA mmap_size = 0; PRAGMA page_size = 1024; CREATE TABLE t1(x); CREATE TABLE t2(x); CREATE TABLE t3(x); CREATE INDEX i3 ON t3(x); INSERT INTO t3 VALUES(randomblob(100)); INSERT INTO t3 SELECT randomblob(100) FROM t3; INSERT INTO t3 SELECT randomblob(100) FROM t3; | > | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | db close sqlite3_simulate_device -char atomic forcedelete test.db sqlite3 db test.db -vfs devsym execsql { PRAGMA mmap_size = 0; PRAGMA page_size = 1024; PRAGMA cache_size = 2000; CREATE TABLE t1(x); CREATE TABLE t2(x); CREATE TABLE t3(x); CREATE INDEX i3 ON t3(x); INSERT INTO t3 VALUES(randomblob(100)); INSERT INTO t3 SELECT randomblob(100) FROM t3; INSERT INTO t3 SELECT randomblob(100) FROM t3; |
︙ | ︙ | |||
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 | COMMIT; } 2 { BEGIN; INSERT INTO t1 VALUES('123'); COMMIT; } } { db_restore sqlite3 db test.db -vfs devsym execsql { PRAGMA mmap_size = 0; SELECT x FROM t3 ORDER BY rowid; SELECT x FROM t3 ORDER BY x; } do_execsql_test 6.2.$tn.1 { PRAGMA integrity_check } {ok} do_execsql_test 6.2.$tn.2 $sql | > > > > > > | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | COMMIT; } 2 { BEGIN; INSERT INTO t1 VALUES('123'); COMMIT; } } { # These tests don't work with memsubsys1, as it causes the effective page # cache size to become too small to hold the entire db in memory. if {[permutation] == "memsubsys1"} continue db_restore sqlite3 db test.db -vfs devsym execsql { PRAGMA cache_size = 2000; PRAGMA mmap_size = 0; SELECT x FROM t3 ORDER BY rowid; SELECT x FROM t3 ORDER BY x; } do_execsql_test 6.2.$tn.1 { PRAGMA integrity_check } {ok} do_execsql_test 6.2.$tn.2 $sql |
︙ | ︙ |
Changes to test/mmap1.test.
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 1.3 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 0} 1.4 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 67108864 } 1.5 { PRAGMA mmap_size = 53248 } 150 {PRAGMA mmap_size = 67108864 } 1.6 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 67108864 } } { do_multiclient_test tn { sql1 {PRAGMA page_size=1024} sql1 $mmap_size sql2 $c2init code2 [register_rblob_code db2 0] sql2 { | > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 1.3 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 0} 1.4 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 67108864 } 1.5 { PRAGMA mmap_size = 53248 } 150 {PRAGMA mmap_size = 67108864 } 1.6 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 67108864 } } { do_multiclient_test tn { sql1 {PRAGMA cache_size=2000} sql2 {PRAGMA cache_size=2000} sql1 {PRAGMA page_size=1024} sql1 $mmap_size sql2 $c2init code2 [register_rblob_code db2 0] sql2 { |
︙ | ︙ | |||
125 126 127 128 129 130 131 | } {67108864 wal 0 103 103} do_execsql_test 2.2 { PRAGMA auto_vacuum; SELECT count(*) FROM t1; } {1 32} | > | | | | | | | | | | | | | | | > | | > | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | } {67108864 wal 0 103 103} do_execsql_test 2.2 { PRAGMA auto_vacuum; SELECT count(*) FROM t1; } {1 32} if {[permutation] != "inmemory_journal"} { do_test 2.3 { sqlite3 db2 test.db db2 func rblob rblob db2 eval { DELETE FROM t1 WHERE (rowid%4); PRAGMA wal_checkpoint; } db2 eval { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 SELECT count(*) FROM t1; } } {16} do_execsql_test 2.4 { PRAGMA wal_checkpoint; } {0 24 24} db2 close } reset_db execsql { PRAGMA mmap_size = 67108864; } db func rblob rblob do_execsql_test 3.1 { PRAGMA auto_vacuum = 1; CREATE TABLE t1(a, b, UNIQUE(a, b)); INSERT INTO t1 VALUES(rblob(500), rblob(500)); INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2 |
︙ | ︙ | |||
172 173 174 175 176 177 178 179 180 181 182 183 184 185 | } {8} #------------------------------------------------------------------------- # Ensure that existing cursors using xFetch() pages see changes made # to rows using the incrblob API. # reset_db set aaa [string repeat a 400] set bbb [string repeat b 400] set ccc [string repeat c 400] set ddd [string repeat d 400] set eee [string repeat e 400] do_execsql_test 4.1 { | > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | } {8} #------------------------------------------------------------------------- # Ensure that existing cursors using xFetch() pages see changes made # to rows using the incrblob API. # reset_db execsql { PRAGMA mmap_size = 67108864; } set aaa [string repeat a 400] set bbb [string repeat b 400] set ccc [string repeat c 400] set ddd [string repeat d 400] set eee [string repeat e 400] do_execsql_test 4.1 { |
︙ | ︙ | |||
221 222 223 224 225 226 227 228 229 230 231 232 233 234 | #------------------------------------------------------------------------- # Ensure that existing cursors holding xFetch() references are not # confused if those pages are moved to make way for the root page of a # new table or index. # reset_db do_execsql_test 5.1 { PRAGMA auto_vacuum = 2; PRAGMA page_size = 1024; CREATE TABLE t1(x); INSERT INTO t1 VALUES($aaa); INSERT INTO t1 VALUES($bbb); INSERT INTO t1 VALUES($ccc); | > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | #------------------------------------------------------------------------- # Ensure that existing cursors holding xFetch() references are not # confused if those pages are moved to make way for the root page of a # new table or index. # reset_db execsql { PRAGMA mmap_size = 67108864; } do_execsql_test 5.1 { PRAGMA auto_vacuum = 2; PRAGMA page_size = 1024; CREATE TABLE t1(x); INSERT INTO t1 VALUES($aaa); INSERT INTO t1 VALUES($bbb); INSERT INTO t1 VALUES($ccc); |
︙ | ︙ |
Changes to test/mmap2.test.
︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | foreach syscall {mmap mremap} { test_syscall uninstall if {[catch {test_syscall install $syscall}]} continue for {set i 1} {$i < 20} {incr i} { reset_db test_syscall fault $i 1 test_syscall errno $syscall ENOMEM set ::log "" do_execsql_test 1.$syscall.$i.1 { CREATE TABLE t1(a, b, UNIQUE(a, b)); | > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | foreach syscall {mmap mremap} { test_syscall uninstall if {[catch {test_syscall install $syscall}]} continue for {set i 1} {$i < 20} {incr i} { reset_db execsql { PRAGMA mmap_size = 8000000 } test_syscall fault $i 1 test_syscall errno $syscall ENOMEM set ::log "" do_execsql_test 1.$syscall.$i.1 { CREATE TABLE t1(a, b, UNIQUE(a, b)); |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
239 240 241 242 243 244 245 246 247 248 | lappend ::testsuitelist xxx #------------------------------------------------------------------------- # Define the permutation test suites: # # Run some tests using pre-allocated page and scratch blocks. # test_suite "memsubsys1" -description { Tests using pre-allocated page and scratch blocks } -files [ | > > > > | | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | lappend ::testsuitelist xxx #------------------------------------------------------------------------- # Define the permutation test suites: # # Run some tests using pre-allocated page and scratch blocks. # # mmap1.test is excluded because a good number of its tests depend on # the page-cache being larger than the database. But this permutation # causes the effective limit on the page-cache to be just 24 pages. # test_suite "memsubsys1" -description { Tests using pre-allocated page and scratch blocks } -files [ test_set $::allquicktests -exclude ioerr5.test malloc5.test mmap1.test ] -initialize { catch {db close} sqlite3_shutdown sqlite3_config_pagecache 4096 24 sqlite3_config_scratch 25000 1 sqlite3_initialize autoinstall_test_functions |
︙ | ︙ |
Added test/sharedA.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | # 2013 May 14 # # 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. # #*********************************************************************** # # Test some specific circumstances to do with shared cache mode. # set testdir [file dirname $argv0] source $testdir/tester.tcl if {[run_thread_tests]==0} { finish_test ; return } db close set ::testprefix sharedA set ::enable_shared_cache [sqlite3_enable_shared_cache 1] #------------------------------------------------------------------------- # do_test 0.1 { sqlite3 db1 test.db sqlite3 db2 test.db db1 eval { CREATE TABLE t1(x); INSERT INTO t1 VALUES(randomblob(100)); INSERT INTO t1 SELECT randomblob(100) FROM t1; INSERT INTO t1 SELECT randomblob(100) FROM t1; INSERT INTO t1 SELECT randomblob(100) FROM t1; INSERT INTO t1 SELECT randomblob(100) FROM t1; INSERT INTO t1 SELECT randomblob(100) FROM t1; INSERT INTO t1 SELECT randomblob(100) FROM t1; CREATE INDEX i1 ON t1(x); } db1 eval { BEGIN; DROP INDEX i1; } db2 close db1 eval { INSERT INTO t1 SELECT randomblob(100) FROM t1; ROLLBACK; PRAGMA integrity_check; } } {ok} db1 close forcedelete test.db #------------------------------------------------------------------------- # do_test 1.1 { sqlite3 db1 test.db sqlite3 db2 test.db db2 eval { CREATE TABLE t1(x); INSERT INTO t1 VALUES(123); } db1 eval { SELECT * FROM t1; CREATE INDEX i1 ON t1(x); } } {123} do_test 1.2 { db2 eval { SELECT * FROM t1 ORDER BY x; } db1 eval { BEGIN; DROP INDEX i1; } db1 close db2 eval { SELECT * FROM t1 ORDER BY x; } } {123} do_test 1.3 { db2 close } {} #------------------------------------------------------------------------- # # sqlite3RollbackAll() loops through all attached b-trees and rolls # back each one separately. Then if the SQLITE_InternChanges flag is # set, it resets the schema. Both of the above steps must be done # while holding a mutex, otherwise another thread might slip in and # try to use the new schema with the old data. # # The following sequence of tests attempt to verify that the actions # taken by sqlite3RollbackAll() are thread-atomic (that they cannot be # interrupted by a separate thread.) # # Note that a TCL interpreter can only be used within the thread in which # it was originally created (because it uses thread-local-storage). # The tvfs callbacks must therefore only run on the main thread. # There is some trickery in the read_callback procedure to ensure that # this is the case. # testvfs tvfs # Set up two databases and two database connections. # # db1: main(test.db), two(test2.db) # db2: main(test.db) # # The cache for test.db is shared between db1 and db2. # do_test 2.1 { forcedelete test.db test.db2 sqlite3 db1 test.db -vfs tvfs db1 eval { ATTACH 'test.db2' AS two } db1 eval { CREATE TABLE t1(x); INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); CREATE TABLE two.t2(x); INSERT INTO t2 SELECT * FROM t1; } sqlite3 db2 test.db -vfs tvfs db2 eval { SELECT * FROM t1 } } {1 2 3} # Create a prepared statement on db2 that will attempt a schema change # in test.db. Meanwhile, start a transaction on db1 that changes # the schema of test.db and that creates a rollback journal on test2.db # do_test 2.2 { set ::STMT [sqlite3_prepare db2 "CREATE INDEX i1 ON t1(x)" -1 tail] db1 eval { BEGIN; CREATE INDEX i1 ON t1(x); INSERT INTO t2 VALUES('value!'); } } {} # Set up a callback that will cause db2 to try to execute its # schema change when db1 accesses the journal file of test2.db. # # This callback will be invoked after the content of test.db has # be rolled back but before the schema has been reset. If the # sqlite3RollbackAll() operation is not thread-atomic, then the # db2 statement in the callback will see old content with the newer # schema, which is wrong. # tvfs filter xRead tvfs script read_callback unset -nocomplain ::some_time_laster unset -nocomplain ::thread_result proc read_callback {call file args} { if {[string match *test.db2-journal $file]} { tvfs filter {} ;# Ensure that tvfs callbacks to do run on the # child thread sqlthread spawn ::thread_result [subst -nocommands { sqlite3_step $::STMT set rc [sqlite3_finalize $::STMT] }] after 1000 { set ::some_time_later 1 } vwait ::some_time_later } } do_test 2.3 { db1 eval ROLLBACK } {} # Verify that the db2 statement invoked by the callback detected the # schema change. # if {[info exists ::thread_result]==0} { vwait ::thread_result } do_test 2.4 { list $::thread_result [sqlite3_errmsg db2] } {SQLITE_SCHEMA {database schema has changed}} db1 close db2 close tvfs delete sqlite3_enable_shared_cache $::enable_shared_cache finish_test |
Changes to test/wal.test.
︙ | ︙ | |||
1508 1509 1510 1511 1512 1513 1514 | do_test wal-23.3 { db close set ::log [list] faultsim_restore_and_reopen execsql { SELECT * FROM t1 } } {1 2 3 4} | < | | 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 | do_test wal-23.3 { db close set ::log [list] faultsim_restore_and_reopen execsql { SELECT * FROM t1 } } {1 2 3 4} do_test wal-23.4 { set ::log } [list SQLITE_NOTICE_RECOVER_WAL \ "recovered 2 frames from WAL file $walfile"] ifcapable autovacuum { # This block tests that if the size of a database is reduced by a # transaction (because of an incremental or auto-vacuum), that no # data is written to the WAL file for the truncated pages as part # of the commit. e.g. if a transaction reduces the size of a database |
︙ | ︙ |
Changes to test/where8.test.
︙ | ︙ | |||
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | } } {1 1 2 2 3 3 4 2 4 4 0 0} do_test where8-3.21.1 { execsql_status { SELECT a, d FROM t1, ((t2)) AS t3 WHERE (a=d OR b=e) AND a<5 ORDER BY a } } {1 1 2 2 3 3 4 2 4 4 0 0} do_test where8-3.21.2 { execsql_status { SELECT a, d FROM t1, ((SELECT * FROM t2)) AS t3 WHERE (a=d OR b=e) AND a<5 ORDER BY a } } {1 1 2 2 3 3 4 2 4 4 0 0} do_test where8-3.22 { execsql_status { SELECT a, d FROM ((((((t1))), (((t2)))))) WHERE (a=d OR b=e) AND a<5 ORDER BY a } } {1 1 2 2 3 3 4 2 4 4 0 0} do_test where8-3.23 { execsql_status { SELECT * FROM ((SELECT * FROM t2)) AS t3; } } {1 {} I 2 four IV 3 {} IX 4 sixteen XVI 5 {} XXV 6 thirtysix XXXVI 7 fortynine XLIX 8 sixtyeight LXIV 9 eightyone LXXXIX 10 {} C 9 0} #----------------------------------------------------------------------- # The following tests - where8-4.* - verify that adding or removing # indexes does not change the results returned by various queries. # do_test where8-4.1 { execsql { | > > > > | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | } } {1 1 2 2 3 3 4 2 4 4 0 0} do_test where8-3.21.1 { execsql_status { SELECT a, d FROM t1, ((t2)) AS t3 WHERE (a=d OR b=e) AND a<5 ORDER BY a } } {1 1 2 2 3 3 4 2 4 4 0 0} if {[permutation] != "no_optimization"} { do_test where8-3.21.2 { execsql_status { SELECT a, d FROM t1, ((SELECT * FROM t2)) AS t3 WHERE (a=d OR b=e) AND a<5 ORDER BY a } } {1 1 2 2 3 3 4 2 4 4 0 0} } do_test where8-3.22 { execsql_status { SELECT a, d FROM ((((((t1))), (((t2)))))) WHERE (a=d OR b=e) AND a<5 ORDER BY a } } {1 1 2 2 3 3 4 2 4 4 0 0} if {[permutation] != "no_optimization"} { do_test where8-3.23 { execsql_status { SELECT * FROM ((SELECT * FROM t2)) AS t3; } } {1 {} I 2 four IV 3 {} IX 4 sixteen XVI 5 {} XXV 6 thirtysix XXXVI 7 fortynine XLIX 8 sixtyeight LXIV 9 eightyone LXXXIX 10 {} C 9 0} } #----------------------------------------------------------------------- # The following tests - where8-4.* - verify that adding or removing # indexes does not change the results returned by various queries. # do_test where8-4.1 { execsql { |
︙ | ︙ |